On a successful translation, cache the PASID Table entry flags set at the context at the time i.e. the first 12bits. These bits contain read, write, dirty and access for example. This is a preparatory for SSADS which requires updating A/D bits on a translation based on the fact that SSADS was enabled on the given scalable mode PASID Table entry. Signed-off-by: Joao Martins <joao.m.martins@xxxxxxxxxx> --- hw/i386/intel_iommu.c | 18 ++++++++++++++++-- include/hw/i386/intel_iommu.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index c64aa81a83fc..752940fa4c0e 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -314,7 +314,7 @@ out: /* Must be with IOMMU lock held */ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, uint16_t domain_id, hwaddr addr, uint64_t slpte, - uint8_t access_flags, uint32_t level) + uint8_t access_flags, uint32_t level, uint16_t pe) { VTDIOTLBEntry *entry = g_malloc(sizeof(*entry)); uint64_t *key = g_malloc(sizeof(*key)); @@ -331,6 +331,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, entry->slpte = slpte; entry->access_flags = access_flags; entry->mask = vtd_slpt_level_page_mask(level); + entry->sm_pe_flags = pe; *key = vtd_get_iotlb_key(gfn, source_id, level); g_hash_table_replace(s->iotlb, key, entry); } @@ -965,6 +966,19 @@ static dma_addr_t vtd_get_iova_pgtbl_base(IntelIOMMUState *s, return vtd_ce_get_slpt_base(ce); } +static uint64_t vtd_sm_pasid_entry_flags(IntelIOMMUState *s, + VTDContextEntry *ce) +{ + VTDPASIDEntry pe; + + if (!s->root_scalable) { + return 0; + } + + vtd_ce_get_rid2pasid_entry(s, ce, &pe); + return pe.val[0] & (~VTD_SM_PASID_ENTRY_SLPTPTR); +} + /* * Rsvd field masks for spte: * vtd_spte_rsvd 4k pages @@ -1789,7 +1803,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, page_mask = vtd_slpt_level_page_mask(level); access_flags = IOMMU_ACCESS_FLAG(reads, writes); vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce), addr, slpte, - access_flags, level); + access_flags, level, vtd_sm_pasid_entry_flags(s, &ce)); out: vtd_iommu_unlock(s); entry->iova = addr & page_mask; diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 3b5ac869db6e..11446012a94c 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -123,6 +123,7 @@ struct VTDIOTLBEntry { uint64_t slpte; uint64_t mask; uint8_t access_flags; + uint16_t sm_pe_flags; }; /* VT-d Source-ID Qualifier types */ -- 2.17.2