Re: [PATCH v1 05/15] intel_iommu: Introduce two helpers vtd_as_from/to_iommu_pasid_locked
On 2025/6/11 18:46, Duan, Zhenzhong wrote: -Original Message- From: Liu, Yi L Subject: Re: [PATCH v1 05/15] intel_iommu: Introduce two helpers vtd_as_from/to_iommu_pasid_locked On 2025/6/6 18:04, Zhenzhong Duan wrote: We already have vtd_find_add_as() to find an AS from BDF+pasid, but this pasid is passed from PCI subsystem. PCI device supports two request types, Requests-without-PASID and Requests-with-PASID. Requests-without-PASID doesn't include a PASID TLP prefix, IOMMU fetches rid_pasid from context entry and use it as IOMMU's pasid to index pasid table. When reading the first line, it makes me thinking why need the helpers since there is already a helper to find. The key is the later part. We need to translate the PCI_NO_PASID to ridpasid. OK, presume you want me to delete first line. Let me know if you mean not. yes. :) Regards, Yi Liu
RE: [PATCH v1 05/15] intel_iommu: Introduce two helpers vtd_as_from/to_iommu_pasid_locked
>-Original Message-
>From: Liu, Yi L
>Subject: Re: [PATCH v1 05/15] intel_iommu: Introduce two helpers
>vtd_as_from/to_iommu_pasid_locked
>
>On 2025/6/6 18:04, Zhenzhong Duan wrote:
>> We already have vtd_find_add_as() to find an AS from BDF+pasid, but this
>> pasid is passed from PCI subsystem. PCI device supports two request types,
>> Requests-without-PASID and Requests-with-PASID. Requests-without-PASID
>> doesn't include a PASID TLP prefix, IOMMU fetches rid_pasid from context
>> entry and use it as IOMMU's pasid to index pasid table.
>
>When reading the first line, it makes me thinking why need the helpers
>since there is already a helper to find. The key is the later part. We need
>to translate the PCI_NO_PASID to ridpasid.
OK, presume you want me to delete first line.
Let me know if you mean not.
Thanks
Zhenzhong
>
>> So we need to translate between PCI's pasid and IOMMU's pasid specially
>> for Requests-without-PASID, e.g., PCI_NO_PASID(-1) <-> rid_pasid.
>> For Requests-with-PASID, PCI's pasid and IOMMU's pasid are same value.
>>
>> vtd_as_from_iommu_pasid_locked() translates from BDF+iommu_pasid to
>vtd_as
>> which contains PCI's pasid vtd_as->pasid.
>>
>> vtd_as_to_iommu_pasid_locked() translates from BDF+vtd_as->pasid to
>iommu_pasid.
>>
>> Signed-off-by: Zhenzhong Duan
>> ---
>> hw/i386/intel_iommu.c | 50
>+++
>> 1 file changed, 50 insertions(+)
>>
>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> index 796b71605c..112e09e305 100644
>> --- a/hw/i386/intel_iommu.c
>> +++ b/hw/i386/intel_iommu.c
>> @@ -1617,6 +1617,56 @@ static int
>vtd_as_to_context_entry(VTDAddressSpace *vtd_as, VTDContextEntry *ce)
>> }
>> }
>>
>> +static inline int vtd_as_to_iommu_pasid_locked(VTDAddressSpace *vtd_as,
>> + uint32_t *pasid)
>> +{
>> +VTDContextEntry ce;
>> +int ret;
>> +
>> +ret = vtd_as_to_context_entry(vtd_as, &ce);
>> +if (ret) {
>> +return ret;
>> +}
>> +
>> +/* Translate to iommu pasid if PCI_NO_PASID */
>> +if (vtd_as->pasid == PCI_NO_PASID) {
>> +*pasid = VTD_CE_GET_RID2PASID(&ce);
>> +} else {
>> +*pasid = vtd_as->pasid;
>> +}
>> +
>> +return 0;
>> +}
>> +
>> +static gboolean vtd_find_as_by_sid_and_iommu_pasid(gpointer key, gpointer
>value,
>> + gpointer user_data)
>> +{
>> +VTDAddressSpace *vtd_as = (VTDAddressSpace *)value;
>> +struct vtd_as_raw_key *target = (struct vtd_as_raw_key *)user_data;
>> +uint16_t sid = PCI_BUILD_BDF(pci_bus_num(vtd_as->bus), vtd_as->devfn);
>> +uint32_t pasid;
>> +
>> +if (vtd_as_to_iommu_pasid_locked(vtd_as, &pasid)) {
>> +return false;
>> +}
>> +
>> +return (pasid == target->pasid) && (sid == target->sid);
>> +}
>> +
>> +/* Translate iommu pasid to vtd_as */
>> +static inline
>> +VTDAddressSpace *vtd_as_from_iommu_pasid_locked(IntelIOMMUState *s,
>> +uint16_t sid, uint32_t
>> pasid)
>> +{
>> +struct vtd_as_raw_key key = {
>> +.sid = sid,
>> +.pasid = pasid
>> +};
>> +
>> +return g_hash_table_find(s->vtd_address_spaces,
>> + vtd_find_as_by_sid_and_iommu_pasid, &key);
>> +}
>> +
>> static int vtd_sync_shadow_page_hook(const IOMMUTLBEvent *event,
>>void *private)
>> {
>
>--
>Regards,
>Yi Liu
Re: [PATCH v1 05/15] intel_iommu: Introduce two helpers vtd_as_from/to_iommu_pasid_locked
On 2025/6/6 18:04, Zhenzhong Duan wrote:
We already have vtd_find_add_as() to find an AS from BDF+pasid, but this
pasid is passed from PCI subsystem. PCI device supports two request types,
Requests-without-PASID and Requests-with-PASID. Requests-without-PASID
doesn't include a PASID TLP prefix, IOMMU fetches rid_pasid from context
entry and use it as IOMMU's pasid to index pasid table.
When reading the first line, it makes me thinking why need the helpers
since there is already a helper to find. The key is the later part. We need
to translate the PCI_NO_PASID to ridpasid.
So we need to translate between PCI's pasid and IOMMU's pasid specially
for Requests-without-PASID, e.g., PCI_NO_PASID(-1) <-> rid_pasid.
For Requests-with-PASID, PCI's pasid and IOMMU's pasid are same value.
vtd_as_from_iommu_pasid_locked() translates from BDF+iommu_pasid to vtd_as
which contains PCI's pasid vtd_as->pasid.
vtd_as_to_iommu_pasid_locked() translates from BDF+vtd_as->pasid to iommu_pasid.
Signed-off-by: Zhenzhong Duan
---
hw/i386/intel_iommu.c | 50 +++
1 file changed, 50 insertions(+)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 796b71605c..112e09e305 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1617,6 +1617,56 @@ static int vtd_as_to_context_entry(VTDAddressSpace
*vtd_as, VTDContextEntry *ce)
}
}
+static inline int vtd_as_to_iommu_pasid_locked(VTDAddressSpace *vtd_as,
+ uint32_t *pasid)
+{
+VTDContextEntry ce;
+int ret;
+
+ret = vtd_as_to_context_entry(vtd_as, &ce);
+if (ret) {
+return ret;
+}
+
+/* Translate to iommu pasid if PCI_NO_PASID */
+if (vtd_as->pasid == PCI_NO_PASID) {
+*pasid = VTD_CE_GET_RID2PASID(&ce);
+} else {
+*pasid = vtd_as->pasid;
+}
+
+return 0;
+}
+
+static gboolean vtd_find_as_by_sid_and_iommu_pasid(gpointer key, gpointer
value,
+ gpointer user_data)
+{
+VTDAddressSpace *vtd_as = (VTDAddressSpace *)value;
+struct vtd_as_raw_key *target = (struct vtd_as_raw_key *)user_data;
+uint16_t sid = PCI_BUILD_BDF(pci_bus_num(vtd_as->bus), vtd_as->devfn);
+uint32_t pasid;
+
+if (vtd_as_to_iommu_pasid_locked(vtd_as, &pasid)) {
+return false;
+}
+
+return (pasid == target->pasid) && (sid == target->sid);
+}
+
+/* Translate iommu pasid to vtd_as */
+static inline
+VTDAddressSpace *vtd_as_from_iommu_pasid_locked(IntelIOMMUState *s,
+uint16_t sid, uint32_t pasid)
+{
+struct vtd_as_raw_key key = {
+.sid = sid,
+.pasid = pasid
+};
+
+return g_hash_table_find(s->vtd_address_spaces,
+ vtd_find_as_by_sid_and_iommu_pasid, &key);
+}
+
static int vtd_sync_shadow_page_hook(const IOMMUTLBEvent *event,
void *private)
{
--
Regards,
Yi Liu
