mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
intel_iommu: Add support for PASID-based device IOTLB invalidation
Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Acked-by: Jason Wang <jasowang@redhat.com> Message-Id: <20241212083757.605022-14-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
1075645d43
commit
dd8200503e
2 changed files with 61 additions and 0 deletions
|
@ -3075,6 +3075,49 @@ static void do_invalidate_device_tlb(VTDAddressSpace *vtd_dev_as,
|
|||
memory_region_notify_iommu(&vtd_dev_as->iommu, 0, event);
|
||||
}
|
||||
|
||||
static bool vtd_process_device_piotlb_desc(IntelIOMMUState *s,
|
||||
VTDInvDesc *inv_desc)
|
||||
{
|
||||
uint16_t sid;
|
||||
VTDAddressSpace *vtd_dev_as;
|
||||
bool size;
|
||||
bool global;
|
||||
hwaddr addr;
|
||||
uint32_t pasid;
|
||||
uint64_t mask[4] = {VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_VAL0,
|
||||
VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_VAL1,
|
||||
VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
|
||||
|
||||
if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, true,
|
||||
__func__, "device piotlb inv")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
global = VTD_INV_DESC_PASID_DEVICE_IOTLB_GLOBAL(inv_desc->hi);
|
||||
size = VTD_INV_DESC_PASID_DEVICE_IOTLB_SIZE(inv_desc->hi);
|
||||
addr = VTD_INV_DESC_PASID_DEVICE_IOTLB_ADDR(inv_desc->hi);
|
||||
sid = VTD_INV_DESC_PASID_DEVICE_IOTLB_SID(inv_desc->lo);
|
||||
if (global) {
|
||||
QLIST_FOREACH(vtd_dev_as, &s->vtd_as_with_notifiers, next) {
|
||||
if ((vtd_dev_as->pasid != PCI_NO_PASID) &&
|
||||
(PCI_BUILD_BDF(pci_bus_num(vtd_dev_as->bus),
|
||||
vtd_dev_as->devfn) == sid)) {
|
||||
do_invalidate_device_tlb(vtd_dev_as, size, addr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pasid = VTD_INV_DESC_PASID_DEVICE_IOTLB_PASID(inv_desc->lo);
|
||||
vtd_dev_as = vtd_get_as_by_sid_and_pasid(s, sid, pasid);
|
||||
if (!vtd_dev_as) {
|
||||
return true;
|
||||
}
|
||||
|
||||
do_invalidate_device_tlb(vtd_dev_as, size, addr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
|
||||
VTDInvDesc *inv_desc)
|
||||
{
|
||||
|
@ -3161,6 +3204,13 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
|
|||
}
|
||||
break;
|
||||
|
||||
case VTD_INV_DESC_DEV_PIOTLB:
|
||||
trace_vtd_inv_desc("device-piotlb", inv_desc.hi, inv_desc.lo);
|
||||
if (!vtd_process_device_piotlb_desc(s, &inv_desc)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case VTD_INV_DESC_DEVICE:
|
||||
trace_vtd_inv_desc("device", inv_desc.hi, inv_desc.lo);
|
||||
if (!vtd_process_device_iotlb_desc(s, &inv_desc)) {
|
||||
|
|
|
@ -385,6 +385,7 @@ typedef union VTDInvDesc VTDInvDesc;
|
|||
#define VTD_INV_DESC_WAIT 0x5 /* Invalidation Wait Descriptor */
|
||||
#define VTD_INV_DESC_PIOTLB 0x6 /* PASID-IOTLB Invalidate Desc */
|
||||
#define VTD_INV_DESC_PC 0x7 /* PASID-cache Invalidate Desc */
|
||||
#define VTD_INV_DESC_DEV_PIOTLB 0x8 /* PASID-based-DIOTLB inv_desc*/
|
||||
#define VTD_INV_DESC_NONE 0 /* Not an Invalidate Descriptor */
|
||||
|
||||
/* Masks for Invalidation Wait Descriptor*/
|
||||
|
@ -426,6 +427,16 @@ typedef union VTDInvDesc VTDInvDesc;
|
|||
/* Masks for Interrupt Entry Invalidate Descriptor */
|
||||
#define VTD_INV_DESC_IEC_RSVD 0xffff000007fff1e0ULL
|
||||
|
||||
/* Masks for PASID based Device IOTLB Invalidate Descriptor */
|
||||
#define VTD_INV_DESC_PASID_DEVICE_IOTLB_ADDR(val) ((val) & \
|
||||
0xfffffffffffff000ULL)
|
||||
#define VTD_INV_DESC_PASID_DEVICE_IOTLB_SIZE(val) ((val >> 11) & 0x1)
|
||||
#define VTD_INV_DESC_PASID_DEVICE_IOTLB_GLOBAL(val) ((val) & 0x1)
|
||||
#define VTD_INV_DESC_PASID_DEVICE_IOTLB_SID(val) (((val) >> 16) & 0xffffULL)
|
||||
#define VTD_INV_DESC_PASID_DEVICE_IOTLB_PASID(val) ((val >> 32) & 0xfffffULL)
|
||||
#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_VAL0 0xfff000000000f000ULL
|
||||
#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_VAL1 0x7feULL
|
||||
|
||||
/* Rsvd field masks for spte */
|
||||
#define VTD_SPTE_SNP 0x800ULL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue