[PATCH] intel_iommu: Do not report recoverable faults to host

Clement Mathieu--Drif posted 1 patch 1 day ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260208082252.288-1-clement.mathieu--drif@eviden.com
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowang@redhat.com>, Yi Liu <yi.l.liu@intel.com>, "Clément Mathieu--Drif" <clement.mathieu--drif@eviden.com>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
hw/i386/intel_iommu.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
[PATCH] intel_iommu: Do not report recoverable faults to host
Posted by Clement Mathieu--Drif 1 day ago
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index dd00079a40..0735b24ac0 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1857,6 +1857,21 @@ static const bool vtd_qualified_faults[] = {
     [VTD_FR_MAX] = false,
 };
 
+static const bool vtd_recoverable_faults[] = {
+    [VTD_FR_WRITE] = true,
+    [VTD_FR_READ] = true,
+    [VTD_FR_PASID_DIR_ENTRY_P] = true,
+    [VTD_FR_PASID_ENTRY_P] = true,
+    [VTD_FR_FS_PAGING_ENTRY_INV] = true,
+    [VTD_FR_FS_PAGING_ENTRY_P] = true,
+    [VTD_FR_FS_PAGING_ENTRY_RSVD] = true,
+    [VTD_FR_PASID_ENTRY_FSPTPTR_INV] = true,
+    [VTD_FR_FS_NON_CANONICAL] = true,
+    [VTD_FR_FS_PAGING_ENTRY_US] = true,
+    [VTD_FR_SM_WRITE] = true,
+    [VTD_FR_MAX] = false,
+};
+
 /* To see if a fault condition is "qualified", which is reported to software
  * only if the FPD field in the context-entry used to process the faulting
  * request is 0.
@@ -1866,6 +1881,11 @@ static inline bool vtd_is_qualified_fault(VTDFaultReason fault)
     return vtd_qualified_faults[fault];
 }
 
+static inline bool vtd_is_recoverable_fault(VTDFaultReason fault, int iommu_idx)
+{
+    return iommu_idx == VTD_IDX_ATS && vtd_recoverable_faults[fault];
+}
+
 static inline bool vtd_is_interrupt_addr(hwaddr addr)
 {
     return VTD_INTERRUPT_ADDR_FIRST <= addr && addr <= VTD_INTERRUPT_ADDR_LAST;
@@ -2237,8 +2257,10 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
     }
 
     if (ret_fr) {
-        vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
-                         addr, is_write, pasid != PCI_NO_PASID, pasid);
+        if (!vtd_is_recoverable_fault(-ret_fr, iommu_idx)) {
+            vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
+                            addr, is_write, pasid != PCI_NO_PASID, pasid);
+        }
         goto error;
     }
 
-- 
2.53.0
RE: [PATCH] intel_iommu: Do not report recoverable faults to host
Posted by Duan, Zhenzhong an hour ago
Hi Clement,

>-----Original Message-----
>From: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>Subject: [PATCH] intel_iommu: Do not report recoverable faults to host
>
>Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>---
> hw/i386/intel_iommu.c | 26 ++++++++++++++++++++++++--
> 1 file changed, 24 insertions(+), 2 deletions(-)
>
>diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>index dd00079a40..0735b24ac0 100644
>--- a/hw/i386/intel_iommu.c
>+++ b/hw/i386/intel_iommu.c
>@@ -1857,6 +1857,21 @@ static const bool vtd_qualified_faults[] = {
>     [VTD_FR_MAX] = false,
> };
>
>+static const bool vtd_recoverable_faults[] = {
>+    [VTD_FR_WRITE] = true,
>+    [VTD_FR_READ] = true,
>+    [VTD_FR_PASID_DIR_ENTRY_P] = true,
>+    [VTD_FR_PASID_ENTRY_P] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_INV] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_P] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_RSVD] = true,
>+    [VTD_FR_PASID_ENTRY_FSPTPTR_INV] = true,
>+    [VTD_FR_FS_NON_CANONICAL] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_US] = true,
>+    [VTD_FR_SM_WRITE] = true,

Which fault reason is classified as recoverable fault?
Is this documented somewhere?

Thanks
Zhenzhong

>+    [VTD_FR_MAX] = false,
>+};
>+
> /* To see if a fault condition is "qualified", which is reported to software
>  * only if the FPD field in the context-entry used to process the faulting
>  * request is 0.
>@@ -1866,6 +1881,11 @@ static inline bool
>vtd_is_qualified_fault(VTDFaultReason fault)
>     return vtd_qualified_faults[fault];
> }
>
>+static inline bool vtd_is_recoverable_fault(VTDFaultReason fault, int iommu_idx)
>+{
>+    return iommu_idx == VTD_IDX_ATS && vtd_recoverable_faults[fault];
>+}
>+
> static inline bool vtd_is_interrupt_addr(hwaddr addr)
> {
>     return VTD_INTERRUPT_ADDR_FIRST <= addr && addr <=
>VTD_INTERRUPT_ADDR_LAST;
>@@ -2237,8 +2257,10 @@ static bool
>vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
>     }
>
>     if (ret_fr) {
>-        vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
>-                         addr, is_write, pasid != PCI_NO_PASID, pasid);
>+        if (!vtd_is_recoverable_fault(-ret_fr, iommu_idx)) {
>+            vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
>+                            addr, is_write, pasid != PCI_NO_PASID, pasid);
>+        }
>         goto error;
>     }
>
>--
>2.53.0
Re: [PATCH] intel_iommu: Do not report recoverable faults to host
Posted by CLEMENT MATHIEU--DRIF 11 minutes ago
Hi Zhenzhon,

Yes, you can have a look at table 26 of VT-d 4.1 or table 30 of VT-d 5.1.

These faults are descibed as follows:

"When remapping hardware detects a recoverable fault on a translation-request from Device-TLB, it is
not reported to software as a fault. Instead, remapping hardware sends a successful translation
completion with limited or no permission/privileges"

In the aforementioned tables, such erros contain mentions like "Success with R=W=U=S=0" or "Success with effective permission".

cmd

________________________________
From: Duan, Zhenzhong <zhenzhong.duan@intel.com>
Sent: 09 February 2026 08:34
To: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>; qemu-devel@nongnu.org <qemu-devel@nongnu.org>
Cc: pbonzini@redhat.com <pbonzini@redhat.com>; peterx@redhat.com <peterx@redhat.com>; david@redhat.com <david@redhat.com>; mst@redhat.com <mst@redhat.com>; jasowang@redhat.com <jasowang@redhat.com>; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; joao.m.martins@oracle.com <joao.m.martins@oracle.com>
Subject: RE: [PATCH] intel_iommu: Do not report recoverable faults to host

Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe.


Hi Clement,

>-----Original Message-----
>From: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>Subject: [PATCH] intel_iommu: Do not report recoverable faults to host
>
>Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>---
> hw/i386/intel_iommu.c | 26 ++++++++++++++++++++++++--
> 1 file changed, 24 insertions(+), 2 deletions(-)
>
>diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>index dd00079a40..0735b24ac0 100644
>--- a/hw/i386/intel_iommu.c
>+++ b/hw/i386/intel_iommu.c
>@@ -1857,6 +1857,21 @@ static const bool vtd_qualified_faults[] = {
>     [VTD_FR_MAX] = false,
> };
>
>+static const bool vtd_recoverable_faults[] = {
>+    [VTD_FR_WRITE] = true,
>+    [VTD_FR_READ] = true,
>+    [VTD_FR_PASID_DIR_ENTRY_P] = true,
>+    [VTD_FR_PASID_ENTRY_P] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_INV] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_P] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_RSVD] = true,
>+    [VTD_FR_PASID_ENTRY_FSPTPTR_INV] = true,
>+    [VTD_FR_FS_NON_CANONICAL] = true,
>+    [VTD_FR_FS_PAGING_ENTRY_US] = true,
>+    [VTD_FR_SM_WRITE] = true,

Which fault reason is classified as recoverable fault?
Is this documented somewhere?

Thanks
Zhenzhong

>+    [VTD_FR_MAX] = false,
>+};
>+
> /* To see if a fault condition is "qualified", which is reported to software
>  * only if the FPD field in the context-entry used to process the faulting
>  * request is 0.
>@@ -1866,6 +1881,11 @@ static inline bool
>vtd_is_qualified_fault(VTDFaultReason fault)
>     return vtd_qualified_faults[fault];
> }
>
>+static inline bool vtd_is_recoverable_fault(VTDFaultReason fault, int iommu_idx)
>+{
>+    return iommu_idx == VTD_IDX_ATS && vtd_recoverable_faults[fault];
>+}
>+
> static inline bool vtd_is_interrupt_addr(hwaddr addr)
> {
>     return VTD_INTERRUPT_ADDR_FIRST <= addr && addr <=
>VTD_INTERRUPT_ADDR_LAST;
>@@ -2237,8 +2257,10 @@ static bool
>vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
>     }
>
>     if (ret_fr) {
>-        vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
>-                         addr, is_write, pasid != PCI_NO_PASID, pasid);
>+        if (!vtd_is_recoverable_fault(-ret_fr, iommu_idx)) {
>+            vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
>+                            addr, is_write, pasid != PCI_NO_PASID, pasid);
>+        }
>         goto error;
>     }
>
>--
>2.53.0