mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 15:23:53 -06:00
intel_iommu: Process PASID-based iotlb invalidation
PASID-based iotlb (piotlb) is used during walking Intel VT-d stage-1 page table. This emulates the stage-1 page table iotlb invalidation requested by a PASID-based IOTLB Invalidate Descriptor (P_IOTLB). Signed-off-by: Yi Liu <yi.l.liu@intel.com> 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> Message-Id: <20241212083757.605022-12-zhenzhong.duan@intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
16d4e418e9
commit
6ebe6cf2a0
2 changed files with 46 additions and 0 deletions
|
@ -322,6 +322,28 @@ static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value,
|
|||
return (entry->gfn & info->mask) == gfn || entry->gfn == gfn_tlb;
|
||||
}
|
||||
|
||||
static gboolean vtd_hash_remove_by_page_piotlb(gpointer key, gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
VTDIOTLBEntry *entry = (VTDIOTLBEntry *)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;
|
||||
|
||||
/*
|
||||
* According to spec, PASID-based-IOTLB Invalidation in page granularity
|
||||
* doesn't invalidate IOTLB entries caching second-stage (PGTT=010b)
|
||||
* or pass-through (PGTT=100b) mappings. Nested isn't supported yet,
|
||||
* so only need to check first-stage (PGTT=001b) mappings.
|
||||
*/
|
||||
if (entry->pgtt != VTD_SM_PASID_ENTRY_FLT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return entry->domain_id == info->domain_id && entry->pasid == info->pasid &&
|
||||
((entry->gfn & info->mask) == gfn || entry->gfn == gfn_tlb);
|
||||
}
|
||||
|
||||
/* Reset all the gen of VTDAddressSpace to zero and set the gen of
|
||||
* IntelIOMMUState to 1. Must be called with IOMMU lock held.
|
||||
*/
|
||||
|
@ -2937,11 +2959,29 @@ static void vtd_piotlb_pasid_invalidate(IntelIOMMUState *s,
|
|||
}
|
||||
}
|
||||
|
||||
static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
|
||||
uint32_t pasid, hwaddr addr, uint8_t am)
|
||||
{
|
||||
VTDIOTLBPageInvInfo info;
|
||||
|
||||
info.domain_id = domain_id;
|
||||
info.pasid = pasid;
|
||||
info.addr = addr;
|
||||
info.mask = ~((1 << am) - 1);
|
||||
|
||||
vtd_iommu_lock(s);
|
||||
g_hash_table_foreach_remove(s->iotlb,
|
||||
vtd_hash_remove_by_page_piotlb, &info);
|
||||
vtd_iommu_unlock(s);
|
||||
}
|
||||
|
||||
static bool vtd_process_piotlb_desc(IntelIOMMUState *s,
|
||||
VTDInvDesc *inv_desc)
|
||||
{
|
||||
uint16_t domain_id;
|
||||
uint32_t pasid;
|
||||
hwaddr addr;
|
||||
uint8_t am;
|
||||
uint64_t mask[4] = {VTD_INV_DESC_PIOTLB_RSVD_VAL0,
|
||||
VTD_INV_DESC_PIOTLB_RSVD_VAL1,
|
||||
VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
|
||||
|
@ -2959,6 +2999,9 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState *s,
|
|||
break;
|
||||
|
||||
case VTD_INV_DESC_PIOTLB_PSI_IN_PASID:
|
||||
am = VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]);
|
||||
addr = (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]);
|
||||
vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -471,6 +471,9 @@ typedef union VTDInvDesc VTDInvDesc;
|
|||
#define VTD_INV_DESC_PIOTLB_PSI_IN_PASID (3ULL << 4)
|
||||
#define VTD_INV_DESC_PIOTLB_DID(val) (((val) >> 16) & VTD_DOMAIN_ID_MASK)
|
||||
#define VTD_INV_DESC_PIOTLB_PASID(val) (((val) >> 32) & 0xfffffULL)
|
||||
#define VTD_INV_DESC_PIOTLB_AM(val) ((val) & 0x3fULL)
|
||||
#define VTD_INV_DESC_PIOTLB_IH(val) (((val) >> 6) & 0x1)
|
||||
#define VTD_INV_DESC_PIOTLB_ADDR(val) ((val) & ~0xfffULL)
|
||||
#define VTD_INV_DESC_PIOTLB_RSVD_VAL0 0xfff000000000f1c0ULL
|
||||
#define VTD_INV_DESC_PIOTLB_RSVD_VAL1 0xf80ULL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue