diff options
author | Peter Xu <peterx@redhat.com> | 2016-07-14 13:56:26 +0800 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2016-07-21 20:43:49 +0300 |
commit | 02a2cbc872df99205eeafd399f01c210e0b797c4 (patch) | |
tree | 5bfb6691fc1c0673f4082d2310f693fb19332a89 /hw/i386/intel_iommu.c | |
parent | 8b5ed7dffa1fa2835a782a8db8d4f3f1f772ada9 (diff) |
x86-iommu: introduce IEC notifiers
This patch introduces x86 IOMMU IEC (Interrupt Entry Cache)
invalidation notifier list. When vIOMMU receives IEC invalidate
request, all the registered units will be notified with specific
invalidation requests.
Intel IOMMU is the first provider that generates such a event.
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386/intel_iommu.c')
-rw-r--r-- | hw/i386/intel_iommu.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index c7ded0fc81..2acec8555d 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -904,6 +904,12 @@ static void vtd_root_table_setup(IntelIOMMUState *s) (s->root_extended ? "(extended)" : "")); } +static void vtd_iec_notify_all(IntelIOMMUState *s, bool global, + uint32_t index, uint32_t mask) +{ + x86_iommu_iec_notify_all(X86_IOMMU_DEVICE(s), global, index, mask); +} + static void vtd_interrupt_remap_table_setup(IntelIOMMUState *s) { uint64_t value = 0; @@ -911,7 +917,8 @@ static void vtd_interrupt_remap_table_setup(IntelIOMMUState *s) s->intr_size = 1UL << ((value & VTD_IRTA_SIZE_MASK) + 1); s->intr_root = value & VTD_IRTA_ADDR_MASK; - /* TODO: invalidate interrupt entry cache */ + /* Notify global invalidation */ + vtd_iec_notify_all(s, true, 0, 0); VTD_DPRINTF(CSR, "int remap table addr 0x%"PRIx64 " size %"PRIu32, s->intr_root, s->intr_size); @@ -1413,6 +1420,21 @@ 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_DPRINTF(INV, "inv ir glob %d index %d mask %d", + inv_desc->iec.granularity, + inv_desc->iec.index, + inv_desc->iec.index_mask); + + vtd_iec_notify_all(s, !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; @@ -1453,12 +1475,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: |