From nobody Sun Jul 26 11:04:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; 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=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1783079592; cv=none; d=zohomail.com; s=zohoarc; b=U9E6qAk8BvIVJPyAjl7R5tLM7nnDgbUt3MrvCpvUX+2NVrOfG1DFKn3UZqcYxWMde5BrihhsPvwMgJUaumNZYuf1amlV8IBaSINv73SBINVIZQT8r4s07mlnb8ybaGKaLxO1qBpD60eTPhbmXyOeyERheXGpeFYSpSG/FFRo8X0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783079592; 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=pPNeRrQvTETcJUHcK/BtXEhLoMCf4EeaiAodSbDfzzc=; b=nWCHxkBl3cO5GBdneQ8X/eJTdsTI+9AqtViGqvmYSoxfulujAx/zJdk8FoDm7qk7yx/jFotsshUdCgEmkvT3UYD9bIYObK8pgVnrBc5ALSnQrMVPBfKd1W3e8myESnkhXS61+OIy6T7HoSGhYjvfne57/ME08eWb9HFifOXJu/Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; 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=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783079592729538.7583039783875; Fri, 3 Jul 2026 04:53:12 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfcRN-0006Ij-Ar; Fri, 03 Jul 2026 07:52:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfbqo-0006h8-JI for qemu-devel@nongnu.org; Fri, 03 Jul 2026 07:14:30 -0400 Received: from mgamail.intel.com ([198.175.65.10]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfbqm-0002t6-Qa for qemu-devel@nongnu.org; Fri, 03 Jul 2026 07:14:30 -0400 Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2026 04:14:28 -0700 Received: from gsd-build.iind.intel.com ([10.190.229.141]) by orviesa002.jf.intel.com with ESMTP; 03 Jul 2026 04:14:25 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1783077268; x=1814613268; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5oq3h0wAuSdjvI+aiUhD//734EhYHcUFlqvOLdEstWI=; b=mLL4RMRsu2p26eivKYPAzw+nlJAsIf1kph1AdNnyfW2sMhFEwjzCssYP lG8DIAkE2RJ1UwRvdygl8+/WOQrqYFufe1gMRRojby+IFOkrfOQMFp12t mZ92aovrcFMpPt32pcGUtJW3LaC5WHGglYNwfaniOIgSnJRZ6U98IO7Bp 9gtG4gyViNltV8ISCIgho1bP6mq/fCsJUk5mfKoIUQMs3041QwWi9WLNd 48fY9PYFGJ7BQSeOZvp5yVEaPzatnnUwYwgDwUHlW3gfwLz9FlkWzmISX yMuWdTp8h4qYvh+uf9erqdvGayoB+raBW3ys1YsQSUQITG02+JGpJa7nu Q==; X-CSE-ConnectionGUID: uLCNKLl/T+CC7qh19BVCvg== X-CSE-MsgGUID: ziEGeCxVQK+39lsztFRy1A== X-IronPort-AV: E=McAfee;i="6800,10657,11835"; a="101251120" X-IronPort-AV: E=Sophos;i="6.25,145,1779174000"; d="scan'208";a="101251120" X-CSE-ConnectionGUID: UDTM+zDBS/GIE9Rjmsxywg== X-CSE-MsgGUID: KgzJml9RRSOiTv0FohR6cw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,145,1779174000"; d="scan'208";a="283181207" From: Satyanarayana K V P To: qemu-devel@nongnu.org Cc: Satyanarayana K V P , =?UTF-8?q?Micha=C5=82=20Winiarski?= , Michal Wajdeczko , Matthew Brost , Alex Williamson , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Subject: [RFC 1/1] vfio/pci: Forward AER errors to guest optionally Date: Fri, 3 Jul 2026 11:13:59 +0000 Message-ID: <20260703111357.3206071-4-satyanarayana.k.v.p@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260703111357.3206071-3-satyanarayana.k.v.p@intel.com> References: <20260703111357.3206071-3-satyanarayana.k.v.p@intel.com> 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=lists1p.gnu.org; Received-SPF: pass client-ip=198.175.65.10; envelope-from=satyanarayana.k.v.p@intel.com; helo=mgamail.intel.com X-Spam_score_int: -47 X-Spam_score: -4.8 X-Spam_bar: ---- X-Spam_report: (-4.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 03 Jul 2026 07:52:14 -0400 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 @intel.com) X-ZM-MESSAGEID: 1783079596451158500 Currently QEMU unconditionally stops VM upon receiving any unrecoverable error from the device. This prevents recovery of the device within the guest. Upon receiving the AER error from device, an error is injected to guest if the device supports AER. If the device does not support AER, check whether the upstream PCIe bridge supports it and forward the error to the bridge. The error forward is gated with an optional extension parameter and can be enabled with -device vfio-pci,host=3D,...,x-forward-aer=3Don Signed-off-by: Satyanarayana K V P Cc: Micha=C5=82 Winiarski Cc: Michal Wajdeczko Cc: Matthew Brost Cc: Alex Williamson Cc: C=C3=A9dric Le Goater --- hw/vfio/pci.c | 80 ++++++++++++++++++++++++++++++++++++++++++++------- hw/vfio/pci.h | 1 + 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 9c06b25e63..1913d18ff5 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -2628,6 +2628,14 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev) pcie_add_capability(pdev, cap_id, cap_ver, next, size); } break; + case PCI_EXT_CAP_ID_ERR: + if (pcie_aer_init(pdev, cap_ver, next, size, &err) < 0) { + warn_report_err(err); + err =3D NULL; + /* Mark capability as absent on failure to initialize */ + pdev->exp.aer_cap =3D 0; + } + break; /* * VFIO kernel does not expose the PASID CAP today. We may synthes= ize * one later through IOMMUFD APIs. If VFIO ever starts exposing it, @@ -3124,26 +3132,68 @@ void vfio_pci_put_device(VFIOPCIDevice *vdev) g_free(vdev->msix); } =20 -static void vfio_err_notifier_handler(void *opaque) +static void vfio_err_notify_guest(VFIOPCIDevice *vdev) { - VFIOPCIDevice *vdev =3D opaque; + PCIDevice *pdev =3D PCI_DEVICE(vdev); + PCIDevice *pbridge_dev; + PCIEAERErr aer_err =3D { + .status =3D PCI_ERR_UNC_MALF_TLP, + .flags =3D 0, + }; + int ret; =20 - if (!event_notifier_test_and_clear(&vdev->err_notifier)) { - return; + if (!vdev->forward_aer) { + error_report("%s(%s)" + "Unrecoverable error detected and could not notify gu= est. " + "Please collect any data possible and then kill the g= uest", + __func__, vdev->vbasedev.name); + goto vm_stop_out; } =20 /* - * TBD. Retrieve the error details and decide what action - * needs to be taken. One of the actions could be to pass - * the error to the guest and have the guest driver recover - * from the error. This requires that PCIe capabilities be - * exposed to the guest. For now, we just terminate the - * guest to contain the error. + * If the device does not have AER capability and still configured to + * forward error to guest, try to find a PCIe bridge with AER capabili= ty and + * forward the error to it. If neither the device nor the PCIe bridge = supports + * AER, the VM is immediately stopped when the error is reported. */ + if (!pdev->exp.aer_cap) { + pbridge_dev =3D pci_bridge_get_device(pci_get_bus(pdev)); + if (pbridge_dev && pbridge_dev->exp.aer_cap) { + warn_report("Forwarding error to PCIe bridge due to lack of AE= R capability on device"); + pdev =3D pbridge_dev; + } else { + error_report("%s(%s) No AER capable device is found, stopping = VM", + __func__, vdev->vbasedev.name); + goto vm_stop_out; + } + } + + aer_err.source_id =3D pci_requester_id(pdev); + + ret =3D pcie_aer_inject_error(pdev, &aer_err); + if (ret < 0) { + error_report("%s(%s): AER injection failed (%d)", __func__, vdev->= vbasedev.name, ret); + goto vm_stop_out; + } =20 - error_report("%s(%s) Unrecoverable error detected. Please collect any = data possible and then kill the guest", __func__, vdev->vbasedev.name); + return; =20 +vm_stop_out: vm_stop(RUN_STATE_INTERNAL_ERROR); + return; +} + +static void vfio_err_notifier_handler(void *opaque) +{ + VFIOPCIDevice *vdev =3D opaque; + + if (!event_notifier_test_and_clear(&vdev->err_notifier)) { + return; + } + + error_report("%s(%s) Unrecoverable error detected for the device", + __func__, vdev->vbasedev.name); + vfio_err_notify_guest(vdev); } =20 /* @@ -3624,6 +3674,9 @@ static void vfio_exitfn(PCIDevice *pdev) VFIOPCIDevice *vdev =3D VFIO_PCI_DEVICE(pdev); VFIODevice *vbasedev =3D &vdev->vbasedev; =20 + if (pdev->exp.aer_cap) { + pcie_aer_exit(pdev); + } vfio_unregister_req_notifier(vdev); vfio_unregister_err_notifier(vdev); pci_device_set_intx_routing_notifier(pdev, NULL); @@ -3815,6 +3868,7 @@ static const Property vfio_pci_properties[] =3D { DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true= ), DEFINE_PROP_UINT16("x-vpasid-cap-offset", VFIOPCIDevice, vpasid_cap_offset, 0), + DEFINE_PROP_BOOL("x-forward-aer", VFIOPCIDevice, forward_aer, false), }; =20 static void vfio_pci_set_fd(Object *obj, const char *str, Error **errp) @@ -3973,6 +4027,10 @@ static void vfio_pci_class_init(ObjectClass *klass, = const void *data) "a vIOMMU. A value of 0 (default= ) places the capability at the " "end of the extended configurati= on space. The offset must be " "4-byte aligned and within the P= CIe extended configuration space"); + object_class_property_set_description(klass, + "x-forward-aer", + "Forward Advanced Error Reportin= g (AER) events to the guest " + "with generic error status"); } =20 static const TypeInfo vfio_pci_info =3D { diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index c3a1f53d35..b1d19c4c9e 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -187,6 +187,7 @@ struct VFIOPCIDevice { bool defer_kvm_irq_routing; bool clear_parent_atomics_on_exit; bool skip_vsc_check; + bool forward_aer; uint16_t vpasid_cap_offset; VFIODisplay *dpy; Notifier irqchip_change_notifier; --=20 2.43.0