From nobody Mon Feb 9 10:33:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1768994826; cv=none; d=zohomail.com; s=zohoarc; b=RkZGqWJ18Z0gIofLLXnsHrqHigxDiHJpuvvygj+r32he1BuWtXYoU++Wuc6ve7uGGoInSov0DiaVrEKDL3s36e0jQeqRjwnnMRUMl021Asnp7fOIgwLwiant87pNmnqA5qA1PJ3GV7tXH6QCxF8R4WJu+TZeil2GyQz7me5wsHw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768994826; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=j1VX8NTsmcC7VHxAXOG3RAIXbPbO+HOv1gt0PF2dWmg=; b=RZnfpn1k36smAmCqVmDXN4nlOwhizDycHHd4738faQ8iOYYMogf5eKMZbx8ajUM7k55BZI6YOO9ayprHVJoTt9JUVYG4+19kZNK1FEcXLf9hspOrnW6rDFh83M/XJJ91RPAYGZmigGEM8ZSIAkfj/N27nrUg7y9ht049fS8OsSc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1768994826809658.2556808203519; Wed, 21 Jan 2026 03:27:06 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1viWLa-0003DJ-E4; Wed, 21 Jan 2026 06:26:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1viWLH-0002ty-9g for qemu-devel@nongnu.org; Wed, 21 Jan 2026 06:25:43 -0500 Received: from tor.source.kernel.org ([2600:3c04:e001:324:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1viWLC-0007ow-LY for qemu-devel@nongnu.org; Wed, 21 Jan 2026 06:25:42 -0500 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id 90E2D60129; Wed, 21 Jan 2026 11:25:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 066B9C4AF0D; Wed, 21 Jan 2026 11:25:25 +0000 (UTC) Received: from mchehab by mail.kernel.org with local (Exim 4.99) (envelope-from ) id 1viWKx-00000003gJq-0vJd; Wed, 21 Jan 2026 12:25:23 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1768994725; bh=Hu2Nuwxl05GDxOG3ScOICaIXDI/9+rYXUfgkR+kkZQ0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=foVDdA/RGyJ26rskWO1o7EhNbpjRdT4l9uFLHC32ADEP4xwzjJ2cmedJ0otawVa7I m+F6llD7hKcRahu/n6914X2lpS6YIj0cR+ZWtdQZzyohyCcRLOMmj62lhssOGunnPj cRHhP5Wq2p7kc8jZrsdoxYI0GTtovmGY3qBbd3R6iGCdfbSsYuZ3nU2ZWLDD+ufRyL DRyQOTb04ssAnIfZCv8kN799PRW58GcSDSoHphv+HglIS5j8Ici2mhKg6MxPWrI1ky 86oXIOiu200WZMUwKcamuIwvO9J6rjZjX2GgVn0bILP3wH+NuJXsjkGB7APagmyabl CHumBI6JwX9VQ== From: Mauro Carvalho Chehab To: Michael S Tsirkin Cc: Jonathan Cameron , Shiju Jose , qemu-devel@nongnu.org, Igor Mammedov , Mauro Carvalho Chehab , Cleber Rosa , John Snow Subject: [PATCH 09/13] scripts/ghes_inject: add a handler for PCIe bus error Date: Wed, 21 Jan 2026 12:25:17 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2600:3c04:e001:324:0:1991:8:25; envelope-from=mchehab+huawei@kernel.org; helo=tor.source.kernel.org X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.087, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1768994828681154100 Add a logic to do PCIe BUS error injection. On Linux Kernel, despite CPER_SEC_PCI_X_BUS macro is defined for such event, ghes.c doesn't implement support for it yet: [16950.077494] {26}[Hardware Error]: Hardware error from APEI Generic Hardw= are Error Source: 1 [16950.077866] {26}[Hardware Error]: event severity: recoverable [16950.078118] {26}[Hardware Error]: Error 0, type: recoverable [16950.078444] {26}[Hardware Error]: section type: unknown, c5753963-3b84= -4095-bf78-eddad3f9c9dd [16950.078800] {26}[Hardware Error]: section length: 0x48 [16950.079069] {26}[Hardware Error]: 00000000: 00000000 00000000 00000000= 00000000 ................ [16950.079442] {26}[Hardware Error]: 00000010: 00000001 00000000 00000000= 00000000 ................ [16950.079811] {26}[Hardware Error]: 00000020: 00000000 00000000 00000000= 00000000 ................ [16950.080181] {26}[Hardware Error]: 00000030: 00000000 00000000 00000000= 00000000 ................ [16950.080538] {26}[Hardware Error]: 00000040: 00000000 00000000 = ........ Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Jonathan Cameron --- MAINTAINERS | 1 + scripts/ghes_inject.py | 2 + scripts/pcie_bus_error.py | 146 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 scripts/pcie_bus_error.py diff --git a/MAINTAINERS b/MAINTAINERS index a970c47dd089..48067a618523 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2228,6 +2228,7 @@ F: qapi/acpi-hest.json F: scripts/ghes_decode.py F: scripts/ghes_inject.py F: scripts/arm_processor_error.py +F: scripts/pcie_bus_error.py F: scripts/qmp_helper.py =20 ppc4xx diff --git a/scripts/ghes_inject.py b/scripts/ghes_inject.py index 6ac917d0b5db..29a6a57508cd 100755 --- a/scripts/ghes_inject.py +++ b/scripts/ghes_inject.py @@ -12,6 +12,7 @@ import sys =20 from arm_processor_error import ArmProcessorEinj +from pcie_bus_error import PcieBusError =20 EINJ_DESC =3D """ Handle ACPI GHESv2 error injection logic QEMU QMP interface. @@ -40,6 +41,7 @@ def main(): subparsers =3D parser.add_subparsers() =20 ArmProcessorEinj(subparsers) + PcieBusError(subparsers) =20 args =3D parser.parse_args() if "func" in args: diff --git a/scripts/pcie_bus_error.py b/scripts/pcie_bus_error.py new file mode 100644 index 000000000000..e8285b5dcc84 --- /dev/null +++ b/scripts/pcie_bus_error.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +# +# pylint: disable=3DC0114,R0903 +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2024 Mauro Carvalho Chehab + +from qmp_helper import qmp, util, cper_guid + +class PcieBusError: + """ + Implements PCI Express bus error injection via GHES + """ + + def __init__(self, subparsers): + """Initialize the error injection class and add subparser""" + + # Valid values + self.valid_bits =3D { + "status": util.bit(0), + "type": util.bit(1), + "bus-id": util.bit(2), + "bus-addr": util.bit(3), + "bus-data": util.bit(4), + "command": util.bit(5), + "requestor-id": util.bit(6), + "completer-id": util.bit(7), + "target-id": util.bit(8), + } + + self.bus_command_bits =3D { + "pci": 0, # Bit 56 is zero + "pci-x": util.bit(56) + } + + self.data =3D bytearray() + + parser =3D subparsers.add_parser("pcie-bus", + description=3D"Generate PCIe bus er= ror CPER") + g_pcie =3D parser.add_argument_group("PCIe bus error") + + valid_bits =3D ",".join(self.valid_bits.keys()) + bus_command_bits =3D ",".join(self.bus_command_bits.keys()) + + g_pcie.add_argument("-v", "--valid", + help=3Df"Valid bits: {valid_bits}") + g_pcie.add_argument("-s", "--error-status", + type=3Dlambda x: int(x, 0), + help=3D"Error Status") + g_pcie.add_argument("-t", "--error-type", + type=3Dlambda x: int(x, 0), + help=3D"Error type") + g_pcie.add_argument("-b", "--bus-number", + type=3Dlambda x: int(x, 0), + help=3D"Bus number") + g_pcie.add_argument("-S", "--segment-number", + type=3Dlambda x: int(x, 0), + help=3D"Segment number") + g_pcie.add_argument("-a", "--bus-address", + type=3Dlambda x: int(x, 0), + help=3D"Bus address") + g_pcie.add_argument("-d", "--bus-data", + type=3Dlambda x: int(x, 0), + help=3D"Bus data") + g_pcie.add_argument("-c", "--bus-command", + help=3Df"bus-command: {bus_command_bits}") + g_pcie.add_argument("-r", "--bus-requestor", + type=3Dlambda x: int(x, 0), + help=3D"Bus requestor ID") + g_pcie.add_argument("-C", "--bus-completer", + type=3Dlambda x: int(x, 0), + help=3D"Bus completer ID") + g_pcie.add_argument("-i", "--target-id", + type=3Dlambda x: int(x, 0), + help=3D"Target ID") + + parser.set_defaults(func=3Dself.send_cper) + + def send_cper(self, args): + """Parse subcommand arguments and send a CPER via QMP""" + + qmp_cmd =3D qmp(args.host, args.port, args.debug) + + cper =3D {} + arg =3D vars(args) + + # Handle global parameters + if args.valid: + valid_init =3D False + cper["valid"] =3D util.get_choice(name=3D"valid", + value=3Dargs.valid, + choices=3Dself.valid_bits) + else: + cper["valid"] =3D 0 + valid_init =3D True + + if args.bus_command: + cper["bus-command"] =3D util.get_choice(name=3D"bus-command", + value=3Dargs.bus_comma= nd, + choices=3Dself.bus_com= mand_bits) + if valid_init: + if args.error_status: + cper["valid"] |=3D self.valid_bits["status"] + + if args.error_type: + cper["valid"] |=3D self.valid_bits["type"] + + if args.bus_number and args.bus_segment: + cper["valid"] |=3D self.valid_bits["bus-id"] + + if args.bus_address: + cper["valid"] |=3D self.valid_bits["bus-address"] + + if args.bus_data: + cper["valid"] |=3D self.valid_bits["bus-data"] + + if args.bus_requestor: + cper["valid"] |=3D self.valid_bits["requestor-id"] + + if args.bus_completer: + cper["valid"] |=3D self.valid_bits["completer-id"] + + if args.target_id: + cper["valid"] |=3D self.valid_bits["target-id"] + + util.data_add(self.data, cper["valid"], 8) + util.data_add(self.data, arg.get("error-status", 0), 8) + util.data_add(self.data, arg.get("error-type", util.bit(0)), 2) + + # Bus ID + util.data_add(self.data, arg.get("bus-number", 0), 1) + util.data_add(self.data, arg.get("segment-number", 0), 1) + + # Reserved + util.data_add(self.data, 0, 4) + + util.data_add(self.data, arg.get("bus-address", 0), 8) + util.data_add(self.data, arg.get("bus-data", 0), 8) + + util.data_add(self.data, cper.get("bus-command", 0), 8) + + util.data_add(self.data, arg.get("bus-requestor", 0), 8) + util.data_add(self.data, arg.get("bus-completer", 0), 8) + util.data_add(self.data, arg.get("target-id", 0), 8) + + return qmp_cmd.send_cper(cper_guid.CPER_PCI_BUS, self.data) --=20 2.52.0