From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
---
hw/i386/intel_iommu_internal.h | 11 ++++++++
hw/i386/intel_iommu.c | 50 ++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 4f2c3a9350..52bdbf3bc5 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -375,6 +375,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*/
@@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
+/* Mask for PASID 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_HI 0x7feULL
+#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO 0xfff000000000f000ULL
+
/* Rsvd field masks for spte */
#define VTD_SPTE_SNP 0x800ULL
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index d28c862598..4cf56924e1 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3017,6 +3017,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;
+
+ if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
+ (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
+ error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
+ "hi=%"PRIx64 "(reserved nonzero)",
+ __func__, inv_desc->hi);
+ 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)
{
@@ -3111,6 +3154,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)) {
--
2.34.1
On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan <zhenzhong.duan@intel.com> wrote:
>
> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>
> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> ---
> hw/i386/intel_iommu_internal.h | 11 ++++++++
> hw/i386/intel_iommu.c | 50 ++++++++++++++++++++++++++++++++++
> 2 files changed, 61 insertions(+)
>
> diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
> index 4f2c3a9350..52bdbf3bc5 100644
> --- a/hw/i386/intel_iommu_internal.h
> +++ b/hw/i386/intel_iommu_internal.h
> @@ -375,6 +375,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*/
> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
>
> +/* Mask for PASID 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_HI 0x7feULL
> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO 0xfff000000000f000ULL
> +
> /* Rsvd field masks for spte */
> #define VTD_SPTE_SNP 0x800ULL
>
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index d28c862598..4cf56924e1 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -3017,6 +3017,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;
> +
> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
> + "hi=%"PRIx64 "(reserved nonzero)",
> + __func__, inv_desc->hi);
> + 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);
Question:
I wonder if current vhost (which has a device IOTLB abstraction via
virtio-pci) can work with this (PASID based IOTLB invalidation)
THanks
> + }
> +
> + return true;
> +}
> +
> static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
> VTDInvDesc *inv_desc)
> {
> @@ -3111,6 +3154,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)) {
> --
> 2.34.1
>
>-----Original Message-----
>From: Jason Wang <jasowang@redhat.com>
>Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
>device IOTLB invalidation
>
>On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan
><zhenzhong.duan@intel.com> wrote:
>>
>> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>>
>> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> ---
>> hw/i386/intel_iommu_internal.h | 11 ++++++++
>> hw/i386/intel_iommu.c | 50
>++++++++++++++++++++++++++++++++++
>> 2 files changed, 61 insertions(+)
>>
>> diff --git a/hw/i386/intel_iommu_internal.h
>b/hw/i386/intel_iommu_internal.h
>> index 4f2c3a9350..52bdbf3bc5 100644
>> --- a/hw/i386/intel_iommu_internal.h
>> +++ b/hw/i386/intel_iommu_internal.h
>> @@ -375,6 +375,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*/
>> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
>> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
>> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
>>
>> +/* Mask for PASID 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_HI 0x7feULL
>> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO
>0xfff000000000f000ULL
>> +
>> /* Rsvd field masks for spte */
>> #define VTD_SPTE_SNP 0x800ULL
>>
>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> index d28c862598..4cf56924e1 100644
>> --- a/hw/i386/intel_iommu.c
>> +++ b/hw/i386/intel_iommu.c
>> @@ -3017,6 +3017,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;
>> +
>> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
>> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
>> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
>> + "hi=%"PRIx64 "(reserved nonzero)",
>> + __func__, inv_desc->hi);
>> + 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);
>
>Question:
>
>I wonder if current vhost (which has a device IOTLB abstraction via
>virtio-pci) can work with this (PASID based IOTLB invalidation)
Currently, it depends on if caching-mode is on. If it's off, vhost works. E.g.:
-device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-scalable-mode=on
-netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
-device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
It doesn't work currently when caching-mode is on.
Reason is linux kernel has an optimization to send only piotlb invalidation,
no device-piotlb invalidation is sent. But I heard from Yi the optimization
will be dropped, then it will work too when caching-mode is on.
Thanks
Zhenzhong
On Fri, Sep 27, 2024 at 3:18 PM Duan, Zhenzhong
<zhenzhong.duan@intel.com> wrote:
>
>
>
> >-----Original Message-----
> >From: Jason Wang <jasowang@redhat.com>
> >Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
> >device IOTLB invalidation
> >
> >On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan
> ><zhenzhong.duan@intel.com> wrote:
> >>
> >> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
> >>
> >> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
> >> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> >> ---
> >> hw/i386/intel_iommu_internal.h | 11 ++++++++
> >> hw/i386/intel_iommu.c | 50
> >++++++++++++++++++++++++++++++++++
> >> 2 files changed, 61 insertions(+)
> >>
> >> diff --git a/hw/i386/intel_iommu_internal.h
> >b/hw/i386/intel_iommu_internal.h
> >> index 4f2c3a9350..52bdbf3bc5 100644
> >> --- a/hw/i386/intel_iommu_internal.h
> >> +++ b/hw/i386/intel_iommu_internal.h
> >> @@ -375,6 +375,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*/
> >> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
> >>
> >> +/* Mask for PASID 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_HI 0x7feULL
> >> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO
> >0xfff000000000f000ULL
> >> +
> >> /* Rsvd field masks for spte */
> >> #define VTD_SPTE_SNP 0x800ULL
> >>
> >> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> >> index d28c862598..4cf56924e1 100644
> >> --- a/hw/i386/intel_iommu.c
> >> +++ b/hw/i386/intel_iommu.c
> >> @@ -3017,6 +3017,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;
> >> +
> >> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
> >> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
> >> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
> >> + "hi=%"PRIx64 "(reserved nonzero)",
> >> + __func__, inv_desc->hi);
> >> + 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);
> >
> >Question:
> >
> >I wonder if current vhost (which has a device IOTLB abstraction via
> >virtio-pci) can work with this (PASID based IOTLB invalidation)
>
> Currently, it depends on if caching-mode is on. If it's off, vhost works. E.g.:
>
> -device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-scalable-mode=on
> -netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
> -device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
>
> It doesn't work currently when caching-mode is on.
> Reason is linux kernel has an optimization to send only piotlb invalidation,
> no device-piotlb invalidation is sent. But I heard from Yi the optimization
> will be dropped, then it will work too when caching-mode is on.
Great, if possible please copy me when sending those fixes.
Thanks
>
> Thanks
> Zhenzhong
>-----Original Message-----
>From: Jason Wang <jasowang@redhat.com>
>Sent: Sunday, September 29, 2024 9:59 AM
>Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based device
>IOTLB invalidation
>
>On Fri, Sep 27, 2024 at 3:18 PM Duan, Zhenzhong
><zhenzhong.duan@intel.com> wrote:
>>
>>
>>
>> >-----Original Message-----
>> >From: Jason Wang <jasowang@redhat.com>
>> >Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
>> >device IOTLB invalidation
>> >
>> >On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan
>> ><zhenzhong.duan@intel.com> wrote:
>> >>
>> >> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>> >>
>> >> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>> >> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> >> ---
>> >> hw/i386/intel_iommu_internal.h | 11 ++++++++
>> >> hw/i386/intel_iommu.c | 50
>> >++++++++++++++++++++++++++++++++++
>> >> 2 files changed, 61 insertions(+)
>> >>
>> >> diff --git a/hw/i386/intel_iommu_internal.h
>> >b/hw/i386/intel_iommu_internal.h
>> >> index 4f2c3a9350..52bdbf3bc5 100644
>> >> --- a/hw/i386/intel_iommu_internal.h
>> >> +++ b/hw/i386/intel_iommu_internal.h
>> >> @@ -375,6 +375,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*/
>> >> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
>> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
>> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
>> >>
>> >> +/* Mask for PASID 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_HI 0x7feULL
>> >> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO
>> >0xfff000000000f000ULL
>> >> +
>> >> /* Rsvd field masks for spte */
>> >> #define VTD_SPTE_SNP 0x800ULL
>> >>
>> >> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> >> index d28c862598..4cf56924e1 100644
>> >> --- a/hw/i386/intel_iommu.c
>> >> +++ b/hw/i386/intel_iommu.c
>> >> @@ -3017,6 +3017,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;
>> >> +
>> >> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
>> >> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
>> >> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
>> >> + "hi=%"PRIx64 "(reserved nonzero)",
>> >> + __func__, inv_desc->hi);
>> >> + 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);
>> >
>> >Question:
>> >
>> >I wonder if current vhost (which has a device IOTLB abstraction via
>> >virtio-pci) can work with this (PASID based IOTLB invalidation)
>>
>> Currently, it depends on if caching-mode is on. If it's off, vhost works. E.g.:
>>
>> -device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-
>scalable-mode=on
>> -netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
>> -device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
>>
>> It doesn't work currently when caching-mode is on.
>> Reason is linux kernel has an optimization to send only piotlb invalidation,
>> no device-piotlb invalidation is sent. But I heard from Yi the optimization
>> will be dropped, then it will work too when caching-mode is on.
>
>Great, if possible please copy me when sending those fixes.
FYI, I just found the optimization had already been dropped since April 2024 by commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=304b3bde24b58515a75fd198beb52ca57df6275f
After updating guest kernel to a new version containing above commit,
vhost works irrespective the value of caching-mode.
Thanks
Zhenzhong
On Mon, Dec 16, 2024 at 4:22 PM Duan, Zhenzhong
<zhenzhong.duan@intel.com> wrote:
>
>
>
> >-----Original Message-----
> >From: Jason Wang <jasowang@redhat.com>
> >Sent: Sunday, September 29, 2024 9:59 AM
> >Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based device
> >IOTLB invalidation
> >
> >On Fri, Sep 27, 2024 at 3:18 PM Duan, Zhenzhong
> ><zhenzhong.duan@intel.com> wrote:
> >>
> >>
> >>
> >> >-----Original Message-----
> >> >From: Jason Wang <jasowang@redhat.com>
> >> >Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
> >> >device IOTLB invalidation
> >> >
> >> >On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan
> >> ><zhenzhong.duan@intel.com> wrote:
> >> >>
> >> >> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
> >> >>
> >> >> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
> >> >> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> >> >> ---
> >> >> hw/i386/intel_iommu_internal.h | 11 ++++++++
> >> >> hw/i386/intel_iommu.c | 50
> >> >++++++++++++++++++++++++++++++++++
> >> >> 2 files changed, 61 insertions(+)
> >> >>
> >> >> diff --git a/hw/i386/intel_iommu_internal.h
> >> >b/hw/i386/intel_iommu_internal.h
> >> >> index 4f2c3a9350..52bdbf3bc5 100644
> >> >> --- a/hw/i386/intel_iommu_internal.h
> >> >> +++ b/hw/i386/intel_iommu_internal.h
> >> >> @@ -375,6 +375,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*/
> >> >> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
> >> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
> >> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
> >> >>
> >> >> +/* Mask for PASID 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_HI 0x7feULL
> >> >> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO
> >> >0xfff000000000f000ULL
> >> >> +
> >> >> /* Rsvd field masks for spte */
> >> >> #define VTD_SPTE_SNP 0x800ULL
> >> >>
> >> >> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> >> >> index d28c862598..4cf56924e1 100644
> >> >> --- a/hw/i386/intel_iommu.c
> >> >> +++ b/hw/i386/intel_iommu.c
> >> >> @@ -3017,6 +3017,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;
> >> >> +
> >> >> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
> >> >> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
> >> >> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
> >> >> + "hi=%"PRIx64 "(reserved nonzero)",
> >> >> + __func__, inv_desc->hi);
> >> >> + 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);
> >> >
> >> >Question:
> >> >
> >> >I wonder if current vhost (which has a device IOTLB abstraction via
> >> >virtio-pci) can work with this (PASID based IOTLB invalidation)
> >>
> >> Currently, it depends on if caching-mode is on. If it's off, vhost works. E.g.:
> >>
> >> -device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-
> >scalable-mode=on
> >> -netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
> >> -device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
> >>
> >> It doesn't work currently when caching-mode is on.
> >> Reason is linux kernel has an optimization to send only piotlb invalidation,
> >> no device-piotlb invalidation is sent. But I heard from Yi the optimization
> >> will be dropped, then it will work too when caching-mode is on.
> >
> >Great, if possible please copy me when sending those fixes.
>
> FYI, I just found the optimization had already been dropped since April 2024 by commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=304b3bde24b58515a75fd198beb52ca57df6275f
>
> After updating guest kernel to a new version containing above commit,
> vhost works irrespective the value of caching-mode.
>
> Thanks
> Zhenzhong
Great. Thanks for the updating.
On 17/12/2024 03:13, Jason Wang wrote:
> Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe.
>
>
> On Mon, Dec 16, 2024 at 4:22 PM Duan, Zhenzhong
> <zhenzhong.duan@intel.com> wrote:
>>
>>
>>> -----Original Message-----
>>> From: Jason Wang <jasowang@redhat.com>
>>> Sent: Sunday, September 29, 2024 9:59 AM
>>> Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based device
>>> IOTLB invalidation
>>>
>>> On Fri, Sep 27, 2024 at 3:18 PM Duan, Zhenzhong
>>> <zhenzhong.duan@intel.com> wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Jason Wang <jasowang@redhat.com>
>>>>> Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
>>>>> device IOTLB invalidation
>>>>>
>>>>> On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan
>>>>> <zhenzhong.duan@intel.com> wrote:
>>>>>> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>>>>>>
>>>>>> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>>>>>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>>>>>> ---
>>>>>> hw/i386/intel_iommu_internal.h | 11 ++++++++
>>>>>> hw/i386/intel_iommu.c | 50
>>>>> ++++++++++++++++++++++++++++++++++
>>>>>> 2 files changed, 61 insertions(+)
>>>>>>
>>>>>> diff --git a/hw/i386/intel_iommu_internal.h
>>>>> b/hw/i386/intel_iommu_internal.h
>>>>>> index 4f2c3a9350..52bdbf3bc5 100644
>>>>>> --- a/hw/i386/intel_iommu_internal.h
>>>>>> +++ b/hw/i386/intel_iommu_internal.h
>>>>>> @@ -375,6 +375,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*/
>>>>>> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
>>>>>> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
>>>>>> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
>>>>>>
>>>>>> +/* Mask for PASID 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_HI 0x7feULL
>>>>>> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO
>>>>> 0xfff000000000f000ULL
>>>>>> +
>>>>>> /* Rsvd field masks for spte */
>>>>>> #define VTD_SPTE_SNP 0x800ULL
>>>>>>
>>>>>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>>>>>> index d28c862598..4cf56924e1 100644
>>>>>> --- a/hw/i386/intel_iommu.c
>>>>>> +++ b/hw/i386/intel_iommu.c
>>>>>> @@ -3017,6 +3017,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;
>>>>>> +
>>>>>> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
>>>>>> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
>>>>>> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
>>>>>> + "hi=%"PRIx64 "(reserved nonzero)",
>>>>>> + __func__, inv_desc->hi);
>>>>>> + 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);
>>>>> Question:
>>>>>
>>>>> I wonder if current vhost (which has a device IOTLB abstraction via
>>>>> virtio-pci) can work with this (PASID based IOTLB invalidation)
>>>> Currently, it depends on if caching-mode is on. If it's off, vhost works. E.g.:
>>>>
>>>> -device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-
>>> scalable-mode=on
>>>> -netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
>>>> -device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
>>>>
>>>> It doesn't work currently when caching-mode is on.
>>>> Reason is linux kernel has an optimization to send only piotlb invalidation,
>>>> no device-piotlb invalidation is sent. But I heard from Yi the optimization
>>>> will be dropped, then it will work too when caching-mode is on.
>>> Great, if possible please copy me when sending those fixes.
>> FYI, I just found the optimization had already been dropped since April 2024 by commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=304b3bde24b58515a75fd198beb52ca57df6275f
>>
>> After updating guest kernel to a new version containing above commit,
>> vhost works irrespective the value of caching-mode.
>>
>> Thanks
>> Zhenzhong
> Great. Thanks for the updating.
Good news,
Thanks Zhenzhong!
>-----Original Message-----
>From: Jason Wang <jasowang@redhat.com>
>Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
>device IOTLB invalidation
>
>On Fri, Sep 27, 2024 at 3:18 PM Duan, Zhenzhong
><zhenzhong.duan@intel.com> wrote:
>>
>>
>>
>> >-----Original Message-----
>> >From: Jason Wang <jasowang@redhat.com>
>> >Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-
>based
>> >device IOTLB invalidation
>> >
>> >On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan
>> ><zhenzhong.duan@intel.com> wrote:
>> >>
>> >> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>> >>
>> >> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--
>drif@eviden.com>
>> >> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> >> ---
>> >> hw/i386/intel_iommu_internal.h | 11 ++++++++
>> >> hw/i386/intel_iommu.c | 50
>> >++++++++++++++++++++++++++++++++++
>> >> 2 files changed, 61 insertions(+)
>> >>
>> >> diff --git a/hw/i386/intel_iommu_internal.h
>> >b/hw/i386/intel_iommu_internal.h
>> >> index 4f2c3a9350..52bdbf3bc5 100644
>> >> --- a/hw/i386/intel_iommu_internal.h
>> >> +++ b/hw/i386/intel_iommu_internal.h
>> >> @@ -375,6 +375,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*/
>> >> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
>> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
>> >> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
>> >>
>> >> +/* Mask for PASID 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_HI 0x7feULL
>> >> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO
>> >0xfff000000000f000ULL
>> >> +
>> >> /* Rsvd field masks for spte */
>> >> #define VTD_SPTE_SNP 0x800ULL
>> >>
>> >> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> >> index d28c862598..4cf56924e1 100644
>> >> --- a/hw/i386/intel_iommu.c
>> >> +++ b/hw/i386/intel_iommu.c
>> >> @@ -3017,6 +3017,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;
>> >> +
>> >> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI)
>||
>> >> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO))
>{
>> >> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
>> >> + "hi=%"PRIx64 "(reserved nonzero)",
>> >> + __func__, inv_desc->hi);
>> >> + 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);
>> >
>> >Question:
>> >
>> >I wonder if current vhost (which has a device IOTLB abstraction via
>> >virtio-pci) can work with this (PASID based IOTLB invalidation)
>>
>> Currently, it depends on if caching-mode is on. If it's off, vhost works. E.g.:
>>
>> -device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-
>scalable-mode=on
>> -netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
>> -device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
>>
>> It doesn't work currently when caching-mode is on.
>> Reason is linux kernel has an optimization to send only piotlb invalidation,
>> no device-piotlb invalidation is sent. But I heard from Yi the optimization
>> will be dropped, then it will work too when caching-mode is on.
>
>Great, if possible please copy me when sending those fixes.
Sure, +Yi, Baolu for their attention.
Thanks
Zhenzhong
>-----Original Message-----
>From: Duan, Zhenzhong
>Subject: RE: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
>device IOTLB invalidation
>
>
>
>>-----Original Message-----
>>From: Jason Wang <jasowang@redhat.com>
>>Subject: Re: [PATCH v3 12/17] intel_iommu: Add support for PASID-based
>>device IOTLB invalidation
>>
>>On Wed, Sep 11, 2024 at 1:27 PM Zhenzhong Duan
>><zhenzhong.duan@intel.com> wrote:
>>>
>>> From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>>>
>>> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--
>drif@eviden.com>
>>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>>> ---
>>> hw/i386/intel_iommu_internal.h | 11 ++++++++
>>> hw/i386/intel_iommu.c | 50
>>++++++++++++++++++++++++++++++++++
>>> 2 files changed, 61 insertions(+)
>>>
>>> diff --git a/hw/i386/intel_iommu_internal.h
>>b/hw/i386/intel_iommu_internal.h
>>> index 4f2c3a9350..52bdbf3bc5 100644
>>> --- a/hw/i386/intel_iommu_internal.h
>>> +++ b/hw/i386/intel_iommu_internal.h
>>> @@ -375,6 +375,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*/
>>> @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc;
>>> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
>>> #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
>>>
>>> +/* Mask for PASID 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_HI 0x7feULL
>>> +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO
>>0xfff000000000f000ULL
>>> +
>>> /* Rsvd field masks for spte */
>>> #define VTD_SPTE_SNP 0x800ULL
>>>
>>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>>> index d28c862598..4cf56924e1 100644
>>> --- a/hw/i386/intel_iommu.c
>>> +++ b/hw/i386/intel_iommu.c
>>> @@ -3017,6 +3017,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;
>>> +
>>> + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) ||
>>> + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) {
>>> + error_report_once("%s: invalid pasid-based dev iotlb inv desc:"
>>> + "hi=%"PRIx64 "(reserved nonzero)",
>>> + __func__, inv_desc->hi);
>>> + 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);
>>
>>Question:
>>
>>I wonder if current vhost (which has a device IOTLB abstraction via
>>virtio-pci) can work with this (PASID based IOTLB invalidation)
>
>Currently, it depends on if caching-mode is on. If it's off, vhost works. E.g.:
>
>-device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-
>scalable-mode=on
>-netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
>-device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
Sorry, typo error on scalable mode parameter, should be:
-device intel-iommu,caching-mode=off,dma-drain=on,device-iotlb=on,x-scalable-mode=modern
-netdev tap,id=tap0,vhost=on,script=/etc/qemu-ifup
-device virtio-net-pci,netdev=tap0,bus=root0,iommu_platform=on,ats=on
Thanks
Zhenzhong
>
>It doesn't work currently when caching-mode is on.
>Reason is linux kernel has an optimization to send only piotlb invalidation,
>no device-piotlb invalidation is sent. But I heard from Yi the optimization
>will be dropped, then it will work too when caching-mode is on.
>
>Thanks
>Zhenzhong
© 2016 - 2026 Red Hat, Inc.