[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 15/16] intel_iommu: introduce IEC notifiers
From: |
Peter Xu |
Subject: |
[Qemu-devel] [PATCH v4 15/16] intel_iommu: introduce IEC notifiers |
Date: |
Tue, 19 Apr 2016 16:38:41 +0800 |
This patch introduces Intel VT-d IEC (Interrupt Entry Cache)
invalidation notifier list. When vIOMMU receives IEC invalidate request,
all the registered units will be notified with specific invalidation
requests.
Signed-off-by: Peter Xu <address@hidden>
---
hw/i386/intel_iommu.c | 52 ++++++++++++++++++++++++++++++++++++------
hw/i386/intel_iommu_internal.h | 24 +++++++++++++++----
include/hw/i386/intel_iommu.h | 22 ++++++++++++++++++
3 files changed, 87 insertions(+), 11 deletions(-)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index ca7e069..1082ab5 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -902,12 +902,18 @@ static void vtd_root_table_setup(IntelIOMMUState *s)
static void vtd_interrupt_remap_table_setup(IntelIOMMUState *s)
{
+ VTD_IEC_Notifier *notifier;
uint64_t value = 0;
value = vtd_get_quad_raw(s, DMAR_IRTA_REG);
s->intr_size = 1UL << ((value & VTD_IRTA_SIZE_MASK) + 1);
s->intr_root = value & VTD_IRTA_ADDR_MASK;
- /* TODO: invalidate interrupt entry cache */
+ QLIST_FOREACH(notifier, &s->iec_notifiers, list) {
+ if (notifier->iec_notify) {
+ /* Notify global invalidation */
+ notifier->iec_notify(notifier->private, true, 0, 0);
+ }
+ }
VTD_DPRINTF(CSR, "int remap table addr 0x%"PRIx64 " size %"PRIu32,
s->intr_root, s->intr_size);
@@ -1409,6 +1415,28 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState *s,
VTDInvDesc *inv_desc)
return true;
}
+static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
+ VTDInvDesc *inv_desc)
+{
+ VTD_IEC_Notifier *notifier;
+
+ VTD_DPRINTF(INV, "inv ir glob %d index %d mask %d",
+ inv_desc->iec.granularity,
+ inv_desc->iec.index,
+ inv_desc->iec.index_mask);
+
+ QLIST_FOREACH(notifier, &s->iec_notifiers, list) {
+ if (notifier->iec_notify) {
+ notifier->iec_notify(notifier->private,
+ inv_desc->iec.granularity,
+ inv_desc->iec.index,
+ inv_desc->iec.index_mask);
+ }
+ }
+
+ return true;
+}
+
static bool vtd_process_inv_desc(IntelIOMMUState *s)
{
VTDInvDesc inv_desc;
@@ -1449,12 +1477,12 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
break;
case VTD_INV_DESC_IEC:
- VTD_DPRINTF(INV, "Interrupt Entry Cache Invalidation "
- "not implemented yet");
- /*
- * Since currently we do not cache interrupt entries, we can
- * just mark this descriptor as "good" and move on.
- */
+ VTD_DPRINTF(INV, "Invalidation Interrupt Entry Cache "
+ "Descriptor hi 0x%"PRIx64 " lo 0x%"PRIx64,
+ inv_desc.hi, inv_desc.lo);
+ if (!vtd_process_inv_iec_desc(s, &inv_desc)) {
+ return false;
+ }
break;
default:
@@ -2202,6 +2230,15 @@ static const MemoryRegionOps vtd_mem_ir_ops = {
},
};
+void vtd_iec_register_notifier(IntelIOMMUState *s, vtd_iec_notify_fn fn,
+ void *data)
+{
+ VTD_IEC_Notifier *notifier = g_new0(VTD_IEC_Notifier, 1);
+ notifier->iec_notify = fn;
+ notifier->private = data;
+ QLIST_INSERT_HEAD(&s->iec_notifiers, notifier, list);
+}
+
VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
{
uintptr_t key = (uintptr_t)bus;
@@ -2364,6 +2401,7 @@ static void vtd_realize(DeviceState *dev, Error **errp)
g_free, g_free);
s->vtd_as_by_busptr = g_hash_table_new_full(vtd_uint64_hash,
vtd_uint64_equal,
g_free, g_free);
+ QLIST_INIT(&s->iec_notifiers);
vtd_init(s);
}
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index e1a08cb..10c20fe 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -296,12 +296,28 @@ typedef enum VTDFaultReason {
#define VTD_CONTEXT_CACHE_GEN_MAX 0xffffffffUL
+/* Interrupt Entry Cache Invalidation Descriptor: VT-d 6.5.2.7. */
+struct VTDInvDescIEC {
+ uint32_t type:4; /* Should always be 0x4 */
+ uint32_t granularity:1; /* If set, it's global IR invalidation */
+ uint32_t resved_1:22;
+ uint32_t index_mask:5; /* 2^N for continuous int invalidation */
+ uint32_t index:16; /* Start index to invalidate */
+ uint32_t reserved_2:16;
+};
+typedef struct VTDInvDescIEC VTDInvDescIEC;
+
/* Queued Invalidation Descriptor */
-struct VTDInvDesc {
- uint64_t lo;
- uint64_t hi;
+union VTDInvDesc {
+ struct {
+ uint64_t lo;
+ uint64_t hi;
+ };
+ union {
+ VTDInvDescIEC iec;
+ };
};
-typedef struct VTDInvDesc VTDInvDesc;
+typedef union VTDInvDesc VTDInvDesc;
/* Masks for struct VTDInvDesc */
#define VTD_INV_DESC_TYPE 0xf
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 5910e6f..d7613af 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -203,6 +203,24 @@ struct VTD_MSIMessage {
/* When IR is enabled, all MSI/MSI-X data bits should be zero */
#define VTD_IR_MSI_DATA (0)
+/**
+ * iec_notifier - IEC (Interrupt Entry Cache) notifier, triggered
+ * when IR hhinvalidation happens.
+ * @private: private data
+ * @global: whether this is a global IEC invalidation
+ * @index: IRTE index to invalidate (start from)
+ * @mask: invalidation mask
+ */
+typedef void (*vtd_iec_notify_fn)(void *private, bool global,
+ uint32_t index, uint32_t mask);
+
+struct VTD_IEC_Notifier {
+ vtd_iec_notify_fn iec_notify;
+ void *private;
+ QLIST_ENTRY(VTD_IEC_Notifier) list;
+};
+typedef struct VTD_IEC_Notifier VTD_IEC_Notifier;
+
/* The iommu (DMAR) device state struct */
struct IntelIOMMUState {
SysBusDevice busdev;
@@ -243,6 +261,7 @@ struct IntelIOMMUState {
bool intr_enabled; /* Whether guest enabled IR */
dma_addr_t intr_root; /* Interrupt remapping table pointer */
uint32_t intr_size; /* Number of IR table entries */
+ QLIST_HEAD(, VTD_IEC_Notifier) iec_notifiers; /* IEC notify list */
};
/* Find the VTD Address space associated with the given bus pointer,
@@ -252,5 +271,8 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus
*bus, int devfn);
/* Get default IOMMU object */
IntelIOMMUState *vtd_iommu_get(void);
int vtd_int_remap(void *iommu, MSIMessage *src, MSIMessage *dst);
+/* Register IEC invalidate notifier */
+void vtd_iec_register_notifier(IntelIOMMUState *s, vtd_iec_notify_fn fn,
+ void *data);
#endif
--
2.4.3
- [Qemu-devel] [PATCH v4 06/16] intel_iommu: handle interrupt remap enable, (continued)
- [Qemu-devel] [PATCH v4 06/16] intel_iommu: handle interrupt remap enable, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 08/16] intel_iommu: provide helper function vtd_get_iommu, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 07/16] intel_iommu: define several structs for IOMMU IR, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 09/16] intel_iommu: add IR translation faults defines, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 10/16] intel_iommu: Add support for PCI MSI remap, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 12/16] ioapic: introduce ioapic_entry_parse() helper, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 11/16] q35: ioapic: add support for emulated IOAPIC IR, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 13/16] intel_iommu: add support for split irqchip, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 14/16] q35: add "int-remap" flag to enable intr, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 16/16] ioapic: register VT-d IEC invalidate notifier, Peter Xu, 2016/04/19
- [Qemu-devel] [PATCH v4 15/16] intel_iommu: introduce IEC notifiers,
Peter Xu <=
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Jan Kiszka, 2016/04/25
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Peter Xu, 2016/04/25
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Jan Kiszka, 2016/04/25
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Radim Krčmář, 2016/04/25
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Peter Xu, 2016/04/26
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Jan Kiszka, 2016/04/26
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Jan Kiszka, 2016/04/26
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Peter Xu, 2016/04/26
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Jan Kiszka, 2016/04/26
- Re: [Qemu-devel] [PATCH v4 00/16] IOMMU: Enable interrupt remapping for Intel IOMMU, Peter Xu, 2016/04/26