From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: imammedo@redhat.com, rth@twiddle.net, ehabkost@redhat.com,
jasowang@redhat.com, marcel@redhat.com, mst@redhat.com,
pbonzini@redhat.com, jan.kiszka@web.de, rkrcmar@redhat.com,
alex.williamson@redhat.com, wexu@redhat.com,
davidkiarie4@gmail.com, peterx@redhat.com
Subject: [Qemu-devel] [PATCH v12 20/27] intel_iommu: add SID validation for IR
Date: Thu, 14 Jul 2016 13:56:29 +0800 [thread overview]
Message-ID: <1468475796-7397-21-git-send-email-peterx@redhat.com> (raw)
In-Reply-To: <1468475796-7397-1-git-send-email-peterx@redhat.com>
This patch enables SID validation. Invalid interrupts will be dropped.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
hw/i386/intel_iommu.c | 69 ++++++++++++++++++++++++++++++++++++-------
include/hw/i386/intel_iommu.h | 17 +++++++++++
2 files changed, 75 insertions(+), 11 deletions(-)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index e96be71..d7d30a7 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2008,9 +2008,13 @@ static Property vtd_properties[] = {
/* Read IRTE entry with specific index */
static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index,
- VTD_IRTE *entry)
+ VTD_IRTE *entry, uint16_t sid)
{
+ static const uint16_t vtd_svt_mask[VTD_SQ_MAX] = \
+ {0xffff, 0xfffb, 0xfff9, 0xfff8};
dma_addr_t addr = 0x00;
+ uint16_t mask, source_id;
+ uint8_t bus, bus_max, bus_min;
addr = iommu->intr_root + index * sizeof(*entry);
if (dma_memory_read(&address_space_memory, addr, entry,
@@ -2037,23 +2041,58 @@ static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index,
return -VTD_FR_IR_IRTE_RSVD;
}
- /*
- * TODO: Check Source-ID corresponds to SVT (Source Validation
- * Type) bits
- */
+ if (sid != X86_IOMMU_SID_INVALID) {
+ /* Validate IRTE SID */
+ source_id = le32_to_cpu(entry->source_id);
+ switch (entry->sid_vtype) {
+ case VTD_SVT_NONE:
+ VTD_DPRINTF(IR, "No SID validation for IRTE index %d", index);
+ break;
+
+ case VTD_SVT_ALL:
+ mask = vtd_svt_mask[entry->sid_q];
+ if ((source_id & mask) != (sid & mask)) {
+ VTD_DPRINTF(GENERAL, "SID validation for IRTE index "
+ "%d failed (reqid 0x%04x sid 0x%04x)", index,
+ sid, source_id);
+ return -VTD_FR_IR_SID_ERR;
+ }
+ break;
+
+ case VTD_SVT_BUS:
+ bus_max = source_id >> 8;
+ bus_min = source_id & 0xff;
+ bus = sid >> 8;
+ if (bus > bus_max || bus < bus_min) {
+ VTD_DPRINTF(GENERAL, "SID validation for IRTE index %d "
+ "failed (bus %d outside %d-%d)", index, bus,
+ bus_min, bus_max);
+ return -VTD_FR_IR_SID_ERR;
+ }
+ break;
+
+ default:
+ VTD_DPRINTF(GENERAL, "Invalid SVT bits (0x%x) in IRTE index "
+ "%d", entry->sid_vtype, index);
+ /* Take this as verification failure. */
+ return -VTD_FR_IR_SID_ERR;
+ break;
+ }
+ }
return 0;
}
/* Fetch IRQ information of specific IR index */
-static int vtd_remap_irq_get(IntelIOMMUState *iommu, uint16_t index, VTDIrq *irq)
+static int vtd_remap_irq_get(IntelIOMMUState *iommu, uint16_t index,
+ VTDIrq *irq, uint16_t sid)
{
VTD_IRTE irte;
int ret = 0;
bzero(&irte, sizeof(irte));
- ret = vtd_irte_get(iommu, index, &irte);
+ ret = vtd_irte_get(iommu, index, &irte, sid);
if (ret) {
return ret;
}
@@ -2105,7 +2144,8 @@ static void vtd_generate_msi_message(VTDIrq *irq, MSIMessage *msg_out)
/* Interrupt remapping for MSI/MSI-X entry */
static int vtd_interrupt_remap_msi(IntelIOMMUState *iommu,
MSIMessage *origin,
- MSIMessage *translated)
+ MSIMessage *translated,
+ uint16_t sid)
{
int ret = 0;
VTD_IR_MSIAddress addr;
@@ -2148,7 +2188,7 @@ static int vtd_interrupt_remap_msi(IntelIOMMUState *iommu,
index += origin->data & VTD_IR_MSI_DATA_SUBHANDLE;
}
- ret = vtd_remap_irq_get(iommu, index, &irq);
+ ret = vtd_remap_irq_get(iommu, index, &irq, sid);
if (ret) {
return ret;
}
@@ -2195,7 +2235,8 @@ do_not_translate:
static int vtd_int_remap(X86IOMMUState *iommu, MSIMessage *src,
MSIMessage *dst, uint16_t sid)
{
- return vtd_interrupt_remap_msi(INTEL_IOMMU_DEVICE(iommu), src, dst);
+ return vtd_interrupt_remap_msi(INTEL_IOMMU_DEVICE(iommu),
+ src, dst, sid);
}
static MemTxResult vtd_mem_ir_read(void *opaque, hwaddr addr,
@@ -2211,11 +2252,17 @@ static MemTxResult vtd_mem_ir_write(void *opaque, hwaddr addr,
{
int ret = 0;
MSIMessage from = {0}, to = {0};
+ uint16_t sid = X86_IOMMU_SID_INVALID;
from.address = (uint64_t) addr + VTD_INTERRUPT_ADDR_FIRST;
from.data = (uint32_t) value;
- ret = vtd_interrupt_remap_msi(opaque, &from, &to);
+ if (!attrs.unspecified) {
+ /* We have explicit Source ID */
+ sid = attrs.requester_id;
+ }
+
+ ret = vtd_interrupt_remap_msi(opaque, &from, &to, sid);
if (ret) {
/* TODO: report error */
VTD_DPRINTF(GENERAL, "int remap fail for addr 0x%"PRIx64
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 745b4e7..2eba7ed 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -102,6 +102,23 @@ struct VTDIOTLBEntry {
bool write_flags;
};
+/* VT-d Source-ID Qualifier types */
+enum {
+ VTD_SQ_FULL = 0x00, /* Full SID verification */
+ VTD_SQ_IGN_3 = 0x01, /* Ignore bit 3 */
+ VTD_SQ_IGN_2_3 = 0x02, /* Ignore bits 2 & 3 */
+ VTD_SQ_IGN_1_3 = 0x03, /* Ignore bits 1-3 */
+ VTD_SQ_MAX,
+};
+
+/* VT-d Source Validation Types */
+enum {
+ VTD_SVT_NONE = 0x00, /* No validation */
+ VTD_SVT_ALL = 0x01, /* Do full validation */
+ VTD_SVT_BUS = 0x02, /* Validate bus range */
+ VTD_SVT_MAX,
+};
+
/* Interrupt Remapping Table Entry Definition */
union VTD_IRTE {
struct {
--
2.4.11
next prev parent reply other threads:[~2016-07-14 5:58 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-14 5:56 [Qemu-devel] [PATCH v12 00/27] IOMMU: Enable interrupt remapping for Intel IOMMU Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 01/27] x86-iommu: introduce parent class Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 02/27] intel_iommu: rename VTD_PCI_DEVFN_MAX to x86-iommu Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 03/27] x86-iommu: provide x86_iommu_get_default Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 04/27] x86-iommu: introduce "intremap" property Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 05/27] acpi: enable INTR for DMAR report structure Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 06/27] intel_iommu: allow queued invalidation for IR Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 07/27] intel_iommu: set IR bit for ECAP register Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 08/27] acpi: add DMAR scope definition for root IOAPIC Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 09/27] intel_iommu: define interrupt remap table addr register Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 10/27] intel_iommu: handle interrupt remap enable Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 11/27] intel_iommu: define several structs for IOMMU IR Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 12/27] intel_iommu: add IR translation faults defines Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 13/27] intel_iommu: Add support for PCI MSI remap Peter Xu
2016-07-21 17:45 ` Michael S. Tsirkin
2016-07-22 3:17 ` Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 14/27] q35: ioapic: add support for emulated IOAPIC IR Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 15/27] ioapic: introduce ioapic_entry_parse() helper Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 16/27] intel_iommu: add support for split irqchip Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 17/27] x86-iommu: introduce IEC notifiers Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 18/27] ioapic: register IOMMU IEC notifier for ioapic Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 19/27] intel_iommu: Add support for Extended Interrupt Mode Peter Xu
2016-07-14 5:56 ` Peter Xu [this message]
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 21/27] kvm-irqchip: simplify kvm_irqchip_add_msi_route Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 22/27] kvm-irqchip: i386: add hook for add/remove virq Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 23/27] kvm-irqchip: x86: add msi route notify fn Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 24/27] kvm-irqchip: do explicit commit when update irq Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 25/27] intel_iommu: support all masks in interrupt entry cache invalidation Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 26/27] kvm-all: add trace events for kvm irqchip ops Peter Xu
2016-07-14 5:56 ` [Qemu-devel] [PATCH v12 27/27] intel_iommu: disallow kernel-irqchip=on with IR Peter Xu
2016-09-22 8:29 ` [Qemu-devel] [PATCH v12 00/27] IOMMU: Enable interrupt remapping for Intel IOMMU Igor Mammedov
2016-09-22 9:08 ` Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1468475796-7397-21-git-send-email-peterx@redhat.com \
--to=peterx@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=davidkiarie4@gmail.com \
--cc=ehabkost@redhat.com \
--cc=imammedo@redhat.com \
--cc=jan.kiszka@web.de \
--cc=jasowang@redhat.com \
--cc=marcel@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rkrcmar@redhat.com \
--cc=rth@twiddle.net \
--cc=wexu@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).