Skip to content

Commit b1cc188

Browse files
Sainath Grandhiacrnsi
authored andcommitted
hv: Use domain/device specific invalidation for DMAR translation caches
ACRN uses global invalidation for all DMAR translation caches. Whenever a UOS is shutdown or rebooted, it ends up clearing entries in translation caches belonging to other VMs/domains. This patch adds support for domain/device level invalidation for DMA translation caches and index based invalidation for Interrupt Remapping Cache. Tracked-On: #2738 Signed-off-by: Sainath Grandhi sainath.grandhi@intel.com Acked-by: Eddie Dong eddie.dong@intel.com
1 parent 5c04687 commit b1cc188

File tree

2 files changed

+14
-13
lines changed

2 files changed

+14
-13
lines changed

hypervisor/arch/x86/vtd.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ static inline uint64_t dmar_set_bitslice(uint64_t var, uint64_t mask, uint32_t p
9898
#define DMAR_IR_ENABLE_EIM_SHIFT 11UL
9999
#define DMAR_IR_ENABLE_EIM (1UL << DMAR_IR_ENABLE_EIM_SHIFT)
100100

101-
#define DMAR_IECI_INDEXED 1U
102-
#define DMAR_IEC_GLOBAL_INVL 0U
103-
104101
enum dmar_cirg_type {
105102
DMAR_CIRG_RESERVED = 0,
106103
DMAR_CIRG_GLOBAL,
@@ -634,7 +631,7 @@ static void dmar_invalid_context_cache(struct dmar_drhd_rt *dmar_unit,
634631
invalidate_desc.lo_64 |= DMA_CONTEXT_DOMAIN_INVL | dma_ccmd_did(did);
635632
break;
636633
case DMAR_CIRG_DEVICE:
637-
invalidate_desc.lo_64 |= DMA_CCMD_DEVICE_INVL | dma_ccmd_did(did) | dma_ccmd_sid(sid) | dma_ccmd_fm(fm);
634+
invalidate_desc.lo_64 |= DMA_CONTEXT_DEVICE_INVL | dma_ccmd_did(did) | dma_ccmd_sid(sid) | dma_ccmd_fm(fm);
638635
break;
639636
default:
640637
invalidate_desc.lo_64 = 0UL;
@@ -992,6 +989,7 @@ static void dmar_enable(struct dmar_drhd_rt *dmar_unit)
992989
dev_dbg(ACRN_DBG_IOMMU, "enable dmar uint [0x%x]", dmar_unit->drhd->reg_base_addr);
993990
dmar_invalid_context_cache_global(dmar_unit);
994991
dmar_invalid_iotlb_global(dmar_unit);
992+
dmar_invalid_iec_global(dmar_unit);
995993
dmar_enable_translation(dmar_unit);
996994
}
997995

@@ -1009,6 +1007,7 @@ static void dmar_suspend(struct dmar_drhd_rt *dmar_unit)
10091007

10101008
dmar_invalid_context_cache_global(dmar_unit);
10111009
dmar_invalid_iotlb_global(dmar_unit);
1010+
dmar_invalid_iec_global(dmar_unit);
10121011

10131012
dmar_disable(dmar_unit);
10141013

@@ -1149,6 +1148,7 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
11491148
struct dmar_entry *context;
11501149
struct dmar_entry *root_entry;
11511150
struct dmar_entry *context_entry;
1151+
union pci_bdf sid;
11521152
int32_t ret = 0;
11531153

11541154
dmar_unit = device_to_dmaru(segment, bus, devfun);
@@ -1184,8 +1184,11 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
11841184
context_entry->hi_64 = 0UL;
11851185
iommu_flush_cache(dmar_unit, context_entry, sizeof(struct dmar_entry));
11861186

1187-
dmar_invalid_context_cache_global(dmar_unit);
1188-
dmar_invalid_iotlb_global(dmar_unit);
1187+
sid.bits.b = bus;
1188+
sid.bits.d = pci_slot(devfun);
1189+
sid.bits.f = pci_func(devfun);
1190+
dmar_invalid_context_cache(dmar_unit, vmid_to_domainid(domain->vm_id), sid.value, 0U, DMAR_CIRG_DEVICE);
1191+
dmar_invalid_iotlb(dmar_unit, vmid_to_domainid(domain->vm_id), 0UL, 0U, false, DMAR_IIRG_DOMAIN);
11891192
}
11901193
}
11911194
}
@@ -1407,7 +1410,7 @@ int32_t dmar_assign_irte(struct intr_source intr_src, union dmar_ir_entry irte,
14071410
ir_entry->entry.lo_64 = irte.entry.lo_64;
14081411

14091412
iommu_flush_cache(dmar_unit, ir_entry, sizeof(union dmar_ir_entry));
1410-
dmar_invalid_iec_global(dmar_unit);
1413+
dmar_invalid_iec(dmar_unit, index, 0U, false);
14111414
}
14121415
return ret;
14131416
}
@@ -1438,6 +1441,6 @@ void dmar_free_irte(struct intr_source intr_src, uint16_t index)
14381441
ir_entry->bits.present = 0x0UL;
14391442

14401443
iommu_flush_cache(dmar_unit, ir_entry, sizeof(union dmar_ir_entry));
1441-
dmar_invalid_iec_global(dmar_unit);
1444+
dmar_invalid_iec(dmar_unit, index, 0U, false);
14421445
}
14431446
}

hypervisor/include/arch/x86/vtd.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,6 @@ static inline uint8_t iommu_ecap_pds(uint64_t ecap)
300300
#define DMA_GSTS_CFIS (1U << 23U)
301301

302302
/* CCMD_REG */
303-
#define DMA_CCMD_ICC (1UL << 63U)
304-
#define DMA_CCMD_ICC_32 (1U << 31U)
305-
#define DMA_CCMD_GLOBAL_INVL (1UL << 61U)
306-
#define DMA_CCMD_DOMAIN_INVL (2UL << 61U)
307-
#define DMA_CCMD_DEVICE_INVL (3UL << 61U)
308303
#define DMA_CONTEXT_GLOBAL_INVL (1UL << 4U)
309304
#define DMA_CONTEXT_DOMAIN_INVL (2UL << 4U)
310305
#define DMA_CONTEXT_DEVICE_INVL (3UL << 4U)
@@ -357,6 +352,9 @@ static inline uint8_t dma_iotlb_invl_addr_am(uint8_t am)
357352
return (am & 0x3fU);
358353
}
359354

355+
/* IEC_REG */
356+
#define DMAR_IECI_INDEXED (((uint64_t)1UL) << 4U)
357+
#define DMAR_IEC_GLOBAL_INVL (((uint64_t)0UL) << 4U)
360358
static inline uint64_t dma_iec_index(uint16_t index, uint8_t index_mask)
361359
{
362360
return ((((uint64_t)index & 0xFFFFU) << 32U) | (((uint64_t)index_mask & 0x1FU) << 27U));

0 commit comments

Comments
 (0)