[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v6 10/20] intel_iommu: Flush stage-1 cache in iotlb invalidation
From: |
Zhenzhong Duan |
Subject: |
[PATCH v6 10/20] intel_iommu: Flush stage-1 cache in iotlb invalidation |
Date: |
Thu, 12 Dec 2024 16:37:47 +0800 |
According to spec, Page-Selective-within-Domain Invalidation (11b):
1. IOTLB entries caching second-stage mappings (PGTT=010b) or pass-through
(PGTT=100b) mappings associated with the specified domain-id and the
input-address range are invalidated.
2. IOTLB entries caching first-stage (PGTT=001b) or nested (PGTT=011b)
mapping associated with specified domain-id are invalidated.
So per spec definition the Page-Selective-within-Domain Invalidation
needs to flush first stage and nested cached IOTLB entries as well.
We don't support nested yet and pass-through mapping is never cached,
so what in iotlb cache are only first-stage and second-stage mappings.
Add a tag pgtt in VTDIOTLBEntry to mark PGTT type of the mapping and
invalidate entries based on PGTT type.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Clément Mathieu--Drif<clement.mathieu--drif@eviden.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
---
include/hw/i386/intel_iommu.h | 1 +
hw/i386/intel_iommu.c | 27 +++++++++++++++++++++------
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index f44f3eb63a..a434c2489c 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -155,6 +155,7 @@ struct VTDIOTLBEntry {
uint64_t pte;
uint64_t mask;
uint8_t access_flags;
+ uint8_t pgtt;
};
/* VT-d Source-ID Qualifier types */
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index ba2eba69c7..0ba94d1d03 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -305,9 +305,21 @@ static gboolean vtd_hash_remove_by_page(gpointer key,
gpointer value,
VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data;
uint64_t gfn = (info->addr >> VTD_PAGE_SHIFT_4K) & info->mask;
uint64_t gfn_tlb = (info->addr & entry->mask) >> VTD_PAGE_SHIFT_4K;
- return (entry->domain_id == info->domain_id) &&
- (((entry->gfn & info->mask) == gfn) ||
- (entry->gfn == gfn_tlb));
+
+ if (entry->domain_id != info->domain_id) {
+ return false;
+ }
+
+ /*
+ * According to spec, IOTLB entries caching first-stage (PGTT=001b) or
+ * nested (PGTT=011b) mapping associated with specified domain-id are
+ * invalidated. Nested isn't supported yet, so only need to check 001b.
+ */
+ if (entry->pgtt == VTD_SM_PASID_ENTRY_FLT) {
+ return true;
+ }
+
+ return (entry->gfn & info->mask) == gfn || entry->gfn == gfn_tlb;
}
/* Reset all the gen of VTDAddressSpace to zero and set the gen of
@@ -382,7 +394,7 @@ out:
static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
uint16_t domain_id, hwaddr addr, uint64_t pte,
uint8_t access_flags, uint32_t level,
- uint32_t pasid)
+ uint32_t pasid, uint8_t pgtt)
{
VTDIOTLBEntry *entry = g_malloc(sizeof(*entry));
struct vtd_iotlb_key *key = g_malloc(sizeof(*key));
@@ -400,6 +412,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t
source_id,
entry->access_flags = access_flags;
entry->mask = vtd_pt_level_page_mask(level);
entry->pasid = pasid;
+ entry->pgtt = pgtt;
key->gfn = gfn;
key->sid = source_id;
@@ -2062,7 +2075,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace
*vtd_as, PCIBus *bus,
bool is_fpd_set = false;
bool reads = true;
bool writes = true;
- uint8_t access_flags;
+ uint8_t access_flags, pgtt;
bool rid2pasid = (pasid == PCI_NO_PASID) && s->root_scalable;
VTDIOTLBEntry *iotlb_entry;
uint64_t xlat, size;
@@ -2171,9 +2184,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace
*vtd_as, PCIBus *bus,
if (s->flts && s->root_scalable) {
ret_fr = vtd_iova_to_flpte(s, &ce, addr, is_write, &pte, &level,
&reads, &writes, s->aw_bits, pasid);
+ pgtt = VTD_SM_PASID_ENTRY_FLT;
} else {
ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level,
&reads, &writes, s->aw_bits, pasid);
+ pgtt = VTD_SM_PASID_ENTRY_SLT;
}
if (!ret_fr) {
xlat = vtd_get_pte_addr(pte, s->aw_bits);
@@ -2207,7 +2222,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace
*vtd_as, PCIBus *bus,
page_mask = vtd_pt_level_page_mask(level);
access_flags = IOMMU_ACCESS_FLAG(reads, writes);
vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce, pasid),
- addr, pte, access_flags, level, pasid);
+ addr, pte, access_flags, level, pasid, pgtt);
out:
vtd_iommu_unlock(s);
entry->iova = addr & page_mask;
--
2.34.1
- [PATCH v6 00/20] intel_iommu: Enable stage-1 translation for emulated device, Zhenzhong Duan, 2024/12/12
- [PATCH v6 01/20] intel_iommu: Use the latest fault reasons defined by spec, Zhenzhong Duan, 2024/12/12
- [PATCH v6 02/20] intel_iommu: Make pasid entry type check accurate, Zhenzhong Duan, 2024/12/12
- [PATCH v6 03/20] intel_iommu: Add a placeholder variable for scalable mode stage-1 translation, Zhenzhong Duan, 2024/12/12
- [PATCH v6 04/20] intel_iommu: Flush stage-2 cache in PASID-selective PASID-based iotlb invalidation, Zhenzhong Duan, 2024/12/12
- [PATCH v6 05/20] intel_iommu: Rename slpte to pte, Zhenzhong Duan, 2024/12/12
- [PATCH v6 06/20] intel_iommu: Implement stage-1 translation, Zhenzhong Duan, 2024/12/12
- [PATCH v6 07/20] intel_iommu: Check if the input address is canonical, Zhenzhong Duan, 2024/12/12
- [PATCH v6 09/20] intel_iommu: Set accessed and dirty bits during stage-1 translation, Zhenzhong Duan, 2024/12/12
- [PATCH v6 08/20] intel_iommu: Check stage-1 translation result with interrupt range, Zhenzhong Duan, 2024/12/12
- [PATCH v6 10/20] intel_iommu: Flush stage-1 cache in iotlb invalidation,
Zhenzhong Duan <=
- [PATCH v6 12/20] intel_iommu: Add an internal API to find an address space with PASID, Zhenzhong Duan, 2024/12/12
- [PATCH v6 14/20] intel_iommu: piotlb invalidation should notify unmap, Zhenzhong Duan, 2024/12/12
- [PATCH v6 11/20] intel_iommu: Process PASID-based iotlb invalidation, Zhenzhong Duan, 2024/12/12
- [PATCH v6 13/20] intel_iommu: Add support for PASID-based device IOTLB invalidation, Zhenzhong Duan, 2024/12/12
- [PATCH v6 16/20] intel_iommu: Set default aw_bits to 48 starting from QEMU 9.2, Zhenzhong Duan, 2024/12/12
- [PATCH v6 15/20] tests/acpi: q35: allow DMAR acpi table changes, Zhenzhong Duan, 2024/12/12
- [PATCH v6 17/20] tests/acpi: q35: Update host address width in DMAR, Zhenzhong Duan, 2024/12/12
- [PATCH v6 18/20] intel_iommu: Introduce a property x-flts for stage-1 translation, Zhenzhong Duan, 2024/12/12