From nobody Sun Jan 25 12:00:41 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=1769175481; cv=none; d=zohomail.com; s=zohoarc; b=bZGL4fzt7uNz9fGqDLrBoMstBCdvQXQramKp3+R801ecrWIBjd95M+9heLAxZLfmOEGFM1iBJS1hkvFyygLY2OY+3ecADOQh7vno54V5zYfOVLbbOi+1+sBGPls30YdKyGIMbWwcXNNjyboOXOMUOzM/YpNtyYOZm88bZ0K8b00= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1769175481; 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=BAtm62fhLx1uG7vveB8VtaURJIMP510EtTUSPkSvI/E=; b=lCcS2ZCrOjKtKk5UsAOpCw3gDRGBofOkFW62aWx/WcvlHqFw59nUcYthsl9hpvXDqhBA6Jq+oKHhmsA6uaPm7nCIqcR64/KsBDoi1F9W53y8UiZQdPGaIau4S7tp9Z+xAiY/2/bN4UGFyMBTOjy2sINCMrE/5n+BAWcX1pNK7nQ= 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 1769175481475424.3423622139609; Fri, 23 Jan 2026 05:38:01 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vjHKl-0007q3-Uk; Fri, 23 Jan 2026 08:36:19 -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 1vjHKV-0007fM-3b for qemu-devel@nongnu.org; Fri, 23 Jan 2026 08:36:06 -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 1vjHKR-0004eG-43 for qemu-devel@nongnu.org; Fri, 23 Jan 2026 08:36:02 -0500 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id E1C5960010; Fri, 23 Jan 2026 13:35:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 760F9C4CEF1; Fri, 23 Jan 2026 13:35:57 +0000 (UTC) Received: from localhost ([::1]) by mail.kernel.org with esmtp (Exim 4.99.1) (envelope-from ) id 1vjHKK-000000063K7-0NUl; Fri, 23 Jan 2026 14:35:55 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1769175357; bh=EmQeFY0Ph0iY+ei/fVP2lTzsVgetZHcMU/ameqRXywY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FknLJb34Jfz6cXQYDQPhyJTsZmbkWaPmqWu0TfwxOO7NNHx0h0vsiSBVeNagIIUft e6XyhmJCLGI+mIUI8Zvt+3OTioCI9lCeAJ3zhNDO5qg9PMSpZJS9OV4ze0VfJAIRNj l34hy84iwSn5JE6mwVLbJdsk/b3qG7r7gvOf8VAhaBeGqTMNqntTJ44qlOtwpDUHG/ kGXiBshnfnmCebRYGxZuQYZ6OFXbH46bBRowyqyyMwAtYUMbVs9A257jc3l1WwflE2 7ksa12GCya3Rvjr0mtsHjxhhGziyGIEUeiJy0X2BykQRvMj1FpD/cgiyMB9BoLorne MDBE1rVEOIfGw== From: Mauro Carvalho Chehab To: "Michael S. Tsirkin" Cc: Mauro Carvalho Chehab , qemu-devel@nongnu.org, Cleber Rosa , John Snow , Jonathan Cameron Subject: [PATCH v2 09/13] scripts/ghes_inject: add a handler for PCI/PCI-X bus error Date: Fri, 23 Jan 2026 14:35:23 +0100 Message-ID: <35c61dd959e8d2687fa282c44471a9de5ef50ad5.1769175070.git.mchehab+huawei@kernel.org> 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 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.079, 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: 1769175482486158500 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/pci_bus_error.py | 146 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 scripts/pci_bus_error.py diff --git a/MAINTAINERS b/MAINTAINERS index a970c47dd089..1e62064a8672 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/pci_bus_error.py F: scripts/qmp_helper.py =20 ppc4xx diff --git a/scripts/ghes_inject.py b/scripts/ghes_inject.py index 6ac917d0b5db..be2384a59b3e 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 pci_bus_error import PciBusError =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) + PciBusError(subparsers) =20 args =3D parser.parse_args() if "func" in args: diff --git a/scripts/pci_bus_error.py b/scripts/pci_bus_error.py new file mode 100644 index 000000000000..5abfdf11c868 --- /dev/null +++ b/scripts/pci_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 PciBusError: + """ + 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("pci-bus", + description=3D"Generate PCI/PCI-X b= us error CPER") + g_pci =3D parser.add_argument_group("PCI/PCI-X bus error") + + valid_bits =3D ",".join(self.valid_bits.keys()) + bus_command_bits =3D ",".join(self.bus_command_bits.keys()) + + g_pci.add_argument("-v", "--valid", + help=3Df"Valid bits: {valid_bits}") + g_pci.add_argument("-s", "--error-status", + type=3Dlambda x: int(x, 0), + help=3D"Error Status") + g_pci.add_argument("-t", "--error-type", + type=3Dlambda x: int(x, 0), + help=3D"Error type") + g_pci.add_argument("-b", "--bus-number", + type=3Dlambda x: int(x, 0), + help=3D"Bus number") + g_pci.add_argument("-S", "--segment-number", + type=3Dlambda x: int(x, 0), + help=3D"Segment number") + g_pci.add_argument("-a", "--bus-address", + type=3Dlambda x: int(x, 0), + help=3D"Bus address") + g_pci.add_argument("-d", "--bus-data", + type=3Dlambda x: int(x, 0), + help=3D"Bus data") + g_pci.add_argument("-c", "--bus-command", + help=3Df"bus-command: {bus_command_bits}") + g_pci.add_argument("-r", "--bus-requestor", + type=3Dlambda x: int(x, 0), + help=3D"Bus requestor ID") + g_pci.add_argument("-C", "--bus-completer", + type=3Dlambda x: int(x, 0), + help=3D"Bus completer ID") + g_pci.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