aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2021-11-29 11:36:18 +0800
committerMichael S. Tsirkin <mst@redhat.com>2021-11-29 08:49:36 -0500
commit0192d6677c383d812fb23f572fda4e449e89d3f1 (patch)
tree4fe4da241733b4b6b5e4f4eaa98650cbd8327c96 /hw
parentd3f1f940ebe43403feb1d12e4b5b9236aba50cb9 (diff)
downloadqemu-0192d6677c383d812fb23f572fda4e449e89d3f1.zip
qemu-0192d6677c383d812fb23f572fda4e449e89d3f1.tar.gz
qemu-0192d6677c383d812fb23f572fda4e449e89d3f1.tar.bz2
intel-iommu: ignore leaf SNP bit in scalable mode
When booting with scalable mode, I hit this error: qemu-system-x86_64: vtd_iova_to_slpte: detected splte reserve non-zero iova=0xfffff002, level=0x1slpte=0x102681803) qemu-system-x86_64: vtd_iommu_translate: detected translation failure (dev=01:00:00, iova=0xfffff002) qemu-system-x86_64: New fault is not recorded due to compression of faults This is because the SNP bit is set for second level page table since Linux kernel commit 6c00612d0cba1 ("iommu/vt-d: Report right snoop capability when using FL for IOVA") even if SC is not supported by the hardware. To unbreak the guest, ignore the leaf SNP bit for scalable mode first. In the future we may consider to add SC support. Signed-off-by: Jason Wang <jasowang@redhat.com> Message-Id: <20211129033618.3857-1-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/i386/intel_iommu.c6
-rw-r--r--hw/i386/intel_iommu_internal.h2
2 files changed, 8 insertions, 0 deletions
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 294499e..f584449 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3629,6 +3629,12 @@ static void vtd_init(IntelIOMMUState *s)
vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits,
x86_iommu->dt_supported);
+ if (s->scalable_mode) {
+ vtd_spte_rsvd[1] &= ~VTD_SPTE_SNP;
+ vtd_spte_rsvd_large[2] &= ~VTD_SPTE_SNP;
+ vtd_spte_rsvd_large[3] &= ~VTD_SPTE_SNP;
+ }
+
if (x86_iommu_ir_supported(x86_iommu)) {
s->ecap |= VTD_ECAP_IR | VTD_ECAP_MHMV;
if (s->intr_eim == ON_OFF_AUTO_ON) {
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 3d5487f..a6c7880 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -388,6 +388,8 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
/* Rsvd field masks for spte */
+#define VTD_SPTE_SNP 0x800ULL
+
#define VTD_SPTE_PAGE_L1_RSVD_MASK(aw, dt_supported) \
dt_supported ? \
(0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \