[PATCH v2 05/19] hw/pci: Export pci_device_get_iommu_bus_devfn() and return bool

Zhenzhong Duan posted 19 patches 4 months, 4 weeks ago
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowang@redhat.com>, Yi Liu <yi.l.liu@intel.com>, "Clément Mathieu--Drif" <clement.mathieu--drif@eviden.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, Eduardo Habkost <eduardo@habkost.net>, Alex Williamson <alex.williamson@redhat.com>, "Cédric Le Goater" <clg@redhat.com>, Eric Auger <eric.auger@redhat.com>, Zhenzhong Duan <zhenzhong.duan@intel.com>
There is a newer version of this series
[PATCH v2 05/19] hw/pci: Export pci_device_get_iommu_bus_devfn() and return bool
Posted by Zhenzhong Duan 4 months, 4 weeks ago
Returns true if PCI device is aliased or false otherwise. This will be
used in following patch to determine if a PCI device is under a PCI
bridge.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
---
 include/hw/pci/pci.h |  2 ++
 hw/pci/pci.c         | 12 ++++++++----
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 829757b2c2..3029cdf26f 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -640,6 +640,8 @@ typedef struct PCIIOMMUOps {
                             bool is_write);
 } PCIIOMMUOps;
 
+bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
+                                    PCIBus **aliased_bus, int *aliased_devfn);
 AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
 bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
                                  Error **errp);
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index df1fb615a8..87f7c942b3 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2857,20 +2857,21 @@ static void pci_device_class_base_init(ObjectClass *klass, const void *data)
  * For call sites which don't need aliased BDF, passing NULL to
  * aliased_[bus|devfn] is allowed.
  *
+ * Returns true if PCI device is aliased or false otherwise.
+ *
  * @piommu_bus: return root #PCIBus backed by an IOMMU for the PCI device.
  *
  * @aliased_bus: return aliased #PCIBus of the PCI device, optional.
  *
  * @aliased_devfn: return aliased devfn of the PCI device, optional.
  */
-static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
-                                           PCIBus **piommu_bus,
-                                           PCIBus **aliased_bus,
-                                           int *aliased_devfn)
+bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
+                                    PCIBus **aliased_bus, int *aliased_devfn)
 {
     PCIBus *bus = pci_get_bus(dev);
     PCIBus *iommu_bus = bus;
     int devfn = dev->devfn;
+    bool aliased = false;
 
     while (iommu_bus && !iommu_bus->iommu_ops && iommu_bus->parent_dev) {
         PCIBus *parent_bus = pci_get_bus(iommu_bus->parent_dev);
@@ -2907,6 +2908,7 @@ static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
                 devfn = parent->devfn;
                 bus = parent_bus;
             }
+            aliased = true;
         }
 
         iommu_bus = parent_bus;
@@ -2928,6 +2930,8 @@ static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
     if (aliased_devfn) {
         *aliased_devfn = devfn;
     }
+
+    return aliased;
 }
 
 AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
-- 
2.34.1
Re: [PATCH v2 05/19] hw/pci: Export pci_device_get_iommu_bus_devfn() and return bool
Posted by Eric Auger 4 months, 4 weeks ago
Hi Zhenzhong,

On 6/20/25 9:17 AM, Zhenzhong Duan wrote:
> Returns true if PCI device is aliased or false otherwise. This will be
> used in following patch to determine if a PCI device is under a PCI
> bridge.
>
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> ---
>  include/hw/pci/pci.h |  2 ++
>  hw/pci/pci.c         | 12 ++++++++----
>  2 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index 829757b2c2..3029cdf26f 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -640,6 +640,8 @@ typedef struct PCIIOMMUOps {
>                              bool is_write);
>  } PCIIOMMUOps;
>  
> +bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
> +                                    PCIBus **aliased_bus, int *aliased_devfn);
if I am correct you have a single caller of the helper using the
returned value, in intel_iommu.c, whereas all the existing callers are
not using the returned value. You may simply pass a non NULL aliased_bus
and aliased_devfn and check whether they differ from the original
bus/devfn. Besides the patch looks ok to me.

Thanks

Eric
>  AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
>  bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
>                                   Error **errp);
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index df1fb615a8..87f7c942b3 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -2857,20 +2857,21 @@ static void pci_device_class_base_init(ObjectClass *klass, const void *data)
>   * For call sites which don't need aliased BDF, passing NULL to
>   * aliased_[bus|devfn] is allowed.
>   *
> + * Returns true if PCI device is aliased or false otherwise.
> + *
>   * @piommu_bus: return root #PCIBus backed by an IOMMU for the PCI device.
>   *
>   * @aliased_bus: return aliased #PCIBus of the PCI device, optional.
>   *
>   * @aliased_devfn: return aliased devfn of the PCI device, optional.
>   */
> -static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
> -                                           PCIBus **piommu_bus,
> -                                           PCIBus **aliased_bus,
> -                                           int *aliased_devfn)
> +bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
> +                                    PCIBus **aliased_bus, int *aliased_devfn)
>  {
>      PCIBus *bus = pci_get_bus(dev);
>      PCIBus *iommu_bus = bus;
>      int devfn = dev->devfn;
> +    bool aliased = false;
>  
>      while (iommu_bus && !iommu_bus->iommu_ops && iommu_bus->parent_dev) {
>          PCIBus *parent_bus = pci_get_bus(iommu_bus->parent_dev);
> @@ -2907,6 +2908,7 @@ static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
>                  devfn = parent->devfn;
>                  bus = parent_bus;
>              }
> +            aliased = true;
>          }
>  
>          iommu_bus = parent_bus;
> @@ -2928,6 +2930,8 @@ static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
>      if (aliased_devfn) {
>          *aliased_devfn = devfn;
>      }
> +
> +    return aliased;
>  }
>  
>  AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
RE: [PATCH v2 05/19] hw/pci: Export pci_device_get_iommu_bus_devfn() and return bool
Posted by Duan, Zhenzhong 4 months, 3 weeks ago

>-----Original Message-----
>From: Eric Auger <eric.auger@redhat.com>
>Subject: Re: [PATCH v2 05/19] hw/pci: Export pci_device_get_iommu_bus_devfn()
>and return bool
>
>Hi Zhenzhong,
>
>On 6/20/25 9:17 AM, Zhenzhong Duan wrote:
>> Returns true if PCI device is aliased or false otherwise. This will be
>> used in following patch to determine if a PCI device is under a PCI
>> bridge.
>>
>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> ---
>>  include/hw/pci/pci.h |  2 ++
>>  hw/pci/pci.c         | 12 ++++++++----
>>  2 files changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>> index 829757b2c2..3029cdf26f 100644
>> --- a/include/hw/pci/pci.h
>> +++ b/include/hw/pci/pci.h
>> @@ -640,6 +640,8 @@ typedef struct PCIIOMMUOps {
>>                              bool is_write);
>>  } PCIIOMMUOps;
>>
>> +bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus
>**piommu_bus,
>> +                                    PCIBus **aliased_bus, int *aliased_devfn);
>if I am correct you have a single caller of the helper using the
>returned value, in intel_iommu.c, whereas all the existing callers are
>not using the returned value. You may simply pass a non NULL aliased_bus
>and aliased_devfn and check whether they differ from the original
>bus/devfn. Besides the patch looks ok to me.

I do this way initially, but it doesn't work if PCI device is the first device under
PCIE-to-PCI bridge, e.g., 01:00.0, in this case aliased BDF==real BDF.

Thanks
Zhenzhong
Re: [PATCH v2 05/19] hw/pci: Export pci_device_get_iommu_bus_devfn() and return bool
Posted by Eric Auger 4 months, 3 weeks ago

On 6/23/25 4:47 AM, Duan, Zhenzhong wrote:
>
>> -----Original Message-----
>> From: Eric Auger <eric.auger@redhat.com>
>> Subject: Re: [PATCH v2 05/19] hw/pci: Export pci_device_get_iommu_bus_devfn()
>> and return bool
>>
>> Hi Zhenzhong,
>>
>> On 6/20/25 9:17 AM, Zhenzhong Duan wrote:
>>> Returns true if PCI device is aliased or false otherwise. This will be
>>> used in following patch to determine if a PCI device is under a PCI
>>> bridge.
>>>
>>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>>> ---
>>>  include/hw/pci/pci.h |  2 ++
>>>  hw/pci/pci.c         | 12 ++++++++----
>>>  2 files changed, 10 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>>> index 829757b2c2..3029cdf26f 100644
>>> --- a/include/hw/pci/pci.h
>>> +++ b/include/hw/pci/pci.h
>>> @@ -640,6 +640,8 @@ typedef struct PCIIOMMUOps {
>>>                              bool is_write);
>>>  } PCIIOMMUOps;
>>>
>>> +bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus
>> **piommu_bus,
>>> +                                    PCIBus **aliased_bus, int *aliased_devfn);
>> if I am correct you have a single caller of the helper using the
>> returned value, in intel_iommu.c, whereas all the existing callers are
>> not using the returned value. You may simply pass a non NULL aliased_bus
>> and aliased_devfn and check whether they differ from the original
>> bus/devfn. Besides the patch looks ok to me.
> I do this way initially, but it doesn't work if PCI device is the first device under
> PCIE-to-PCI bridge, e.g., 01:00.0, in this case aliased BDF==real BDF.
I see.

Thank you for the explanation

Eric
>
> Thanks
> Zhenzhong