[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 54/91] intel-iommu: block output address in interrupt address rang
From: |
Michael S. Tsirkin |
Subject: |
[PULL 54/91] intel-iommu: block output address in interrupt address range |
Date: |
Mon, 16 May 2022 06:38:46 -0400 |
From: Jason Wang <jasowang@redhat.com>
According to vtd spec v3.3 3.14:
"""
Software must not program paging-structure entries to remap any
address to the interrupt address range. Untranslated requests and
translation requests that result in an address in the interrupt range
will be blocked with condition code LGN.4 or SGN.8.
"""
This patch blocks the request that result in interrupt address range.
Signed-off-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20220210092815.45174-2-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>
---
hw/i386/intel_iommu_internal.h | 4 ++++
hw/i386/intel_iommu.c | 27 ++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index b6a2da8e83..930ce61feb 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -289,6 +289,8 @@ typedef enum VTDFaultReason {
* context-entry.
*/
VTD_FR_CONTEXT_ENTRY_TT,
+ /* Output address in the interrupt address range */
+ VTD_FR_INTERRUPT_ADDR = 0xE,
/* Interrupt remapping transition faults */
VTD_FR_IR_REQ_RSVD = 0x20, /* One or more IR request reserved
@@ -304,6 +306,8 @@ typedef enum VTDFaultReason {
VTD_FR_PASID_TABLE_INV = 0x58, /*Invalid PASID table entry */
+ /* Output address in the interrupt address range for scalable mode */
+ VTD_FR_SM_INTERRUPT_ADDR = 0x87,
VTD_FR_MAX, /* Guard */
} VTDFaultReason;
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 8af2e39151..695dd51dc3 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1020,6 +1020,7 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s,
VTDContextEntry *ce,
uint32_t offset;
uint64_t slpte;
uint64_t access_right_check;
+ uint64_t xlat, size;
if (!vtd_iova_range_check(s, iova, ce, aw_bits)) {
error_report_once("%s: detected IOVA overflow (iova=0x%" PRIx64 ")",
@@ -1064,11 +1065,33 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s,
VTDContextEntry *ce,
if (vtd_is_last_slpte(slpte, level)) {
*slptep = slpte;
*slpte_level = level;
- return 0;
+ break;
}
addr = vtd_get_slpte_addr(slpte, aw_bits);
level--;
}
+
+ xlat = vtd_get_slpte_addr(*slptep, aw_bits);
+ size = ~vtd_slpt_level_page_mask(level) + 1;
+
+ /*
+ * From VT-d spec 3.14: Untranslated requests and translation
+ * requests that result in an address in the interrupt range will be
+ * blocked with condition code LGN.4 or SGN.8.
+ */
+ if ((xlat > VTD_INTERRUPT_ADDR_LAST ||
+ xlat + size - 1 < VTD_INTERRUPT_ADDR_FIRST)) {
+ return 0;
+ } else {
+ error_report_once("%s: xlat address is in interrupt range "
+ "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", "
+ "slpte=0x%" PRIx64 ", write=%d, "
+ "xlat=0x%" PRIx64 ", size=0x%" PRIx64 ")",
+ __func__, iova, level, slpte, is_write,
+ xlat, size);
+ return s->scalable_mode ? -VTD_FR_SM_INTERRUPT_ADDR :
+ -VTD_FR_INTERRUPT_ADDR;
+ }
}
typedef int (*vtd_page_walk_hook)(IOMMUTLBEvent *event, void *private);
@@ -1628,10 +1651,12 @@ static const bool vtd_qualified_faults[] = {
[VTD_FR_PAGING_ENTRY_INV] = true,
[VTD_FR_ROOT_TABLE_INV] = false,
[VTD_FR_CONTEXT_TABLE_INV] = false,
+ [VTD_FR_INTERRUPT_ADDR] = true,
[VTD_FR_ROOT_ENTRY_RSVD] = false,
[VTD_FR_PAGING_ENTRY_RSVD] = true,
[VTD_FR_CONTEXT_ENTRY_TT] = true,
[VTD_FR_PASID_TABLE_INV] = false,
+ [VTD_FR_SM_INTERRUPT_ADDR] = true,
[VTD_FR_MAX] = false,
};
--
MST
- [PULL 44/91] vhost: Fix device's used descriptor dequeue, (continued)
- [PULL 44/91] vhost: Fix device's used descriptor dequeue, Michael S. Tsirkin, 2022/05/16
- [PULL 45/91] vdpa: Fix bad index calculus at vhost_vdpa_get_vring_base, Michael S. Tsirkin, 2022/05/16
- [PULL 48/91] vhost: Fix element in vhost_svq_add failure, Michael S. Tsirkin, 2022/05/16
- [PULL 47/91] hw/virtio: Replace g_memdup() by g_memdup2(), Michael S. Tsirkin, 2022/05/16
- [PULL 46/91] vdpa: Fix index calculus at vhost_vdpa_svqs_start, Michael S. Tsirkin, 2022/05/16
- [PULL 49/91] target/i386: Fix sanity check on max APIC ID / X2APIC enablement, Michael S. Tsirkin, 2022/05/16
- [PULL 50/91] intel_iommu: Support IR-only mode without DMA translation, Michael S. Tsirkin, 2022/05/16
- [PULL 51/91] intel_iommu: Only allow interrupt remapping to be enabled if it's supported, Michael S. Tsirkin, 2022/05/16
- [PULL 52/91] intel_iommu: Fix irqchip / X2APIC configuration checks, Michael S. Tsirkin, 2022/05/16
- [PULL 53/91] intel-iommu: remove VTD_FR_RESERVED_ERR, Michael S. Tsirkin, 2022/05/16
- [PULL 54/91] intel-iommu: block output address in interrupt address range,
Michael S. Tsirkin <=
- [PULL 55/91] intel-iommu: update root_scalable before switching as during post_load, Michael S. Tsirkin, 2022/05/16
- [PULL 56/91] intel-iommu: update iq_dw during post load, Michael S. Tsirkin, 2022/05/16
- [PULL 57/91] vhost_net: Print feature masks in hex, Michael S. Tsirkin, 2022/05/16
- [PULL 60/91] hw/virtio: add vhost_user_[read|write] trace points, Michael S. Tsirkin, 2022/05/16
- [PULL 58/91] hw/virtio: move virtio-pci.h into shared include space, Michael S. Tsirkin, 2022/05/16
- [PULL 62/91] docs: vhost-user: rewrite section on ring state machine, Michael S. Tsirkin, 2022/05/16
- [PULL 63/91] docs: vhost-user: replace master/slave with front-end/back-end, Michael S. Tsirkin, 2022/05/16
- [PULL 59/91] virtio-pci: add notification trace points, Michael S. Tsirkin, 2022/05/16
- [PULL 61/91] docs: vhost-user: clean up request/reply description, Michael S. Tsirkin, 2022/05/16
- [PULL 64/91] vhost-user.rst: add clarifying language about protocol negotiation, Michael S. Tsirkin, 2022/05/16