diff mbox series

[v1,14/14] xen/arm: Add linux,pci-domain property for hwdom if not available.

Message ID 0b979ccab6a4c9b2070748709f737f41fa108a42.1629366665.git.rahul.singh@arm.com (mailing list archive)
State Superseded
Headers show
Series PCI devices passthrough on Arm | expand

Commit Message

Rahul Singh Aug. 19, 2021, 12:02 p.m. UTC
If the property is not present in the device tree node for host bridge,
XEN while creating the dtb for hwdom will create this property and
assigns the already allocated segment to the host bridge
so that XEN and linux will have the same segment for the host bridges.

Signed-off-by: Rahul Singh <rahul.singh@arm.com>
---
 xen/arch/arm/domain_build.c        | 18 ++++++++++++++++++
 xen/arch/arm/pci/pci-host-common.c | 21 +++++++++++++++++++++
 xen/include/asm-arm/pci.h          |  3 +++
 3 files changed, 42 insertions(+)

Comments

Stefano Stabellini Sept. 10, 2021, 1 a.m. UTC | #1
On Thu, 19 Aug 2021, Rahul Singh wrote:
> If the property is not present in the device tree node for host bridge,
> XEN while creating the dtb for hwdom will create this property and
> assigns the already allocated segment to the host bridge
> so that XEN and linux will have the same segment for the host bridges.
> 
> Signed-off-by: Rahul Singh <rahul.singh@arm.com>
> ---
>  xen/arch/arm/domain_build.c        | 18 ++++++++++++++++++
>  xen/arch/arm/pci/pci-host-common.c | 21 +++++++++++++++++++++
>  xen/include/asm-arm/pci.h          |  3 +++
>  3 files changed, 42 insertions(+)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 6c86d52781..e0cf2ff19d 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -581,6 +581,24 @@ static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
>              return res;
>      }
>  
> +#ifdef CONFIG_HAS_PCI
> +    if ( dt_device_type_is_equal(node, "pci") )
> +    {
> +        if ( !dt_find_property(node, "linux,pci-domain", NULL) )
> +        {
> +            uint16_t segment;
> +
> +            res = pci_get_host_bridge_segment(node, &segment);
> +            if ( res < 0 )
> +                return res;
> +
> +            res = fdt_property_cell(kinfo->fdt, "linux,pci-domain", segment);
> +            if ( res )
> +                return res;
> +        }
> +    }
> +#endif

If param_pci_enable is false it might be possible that Xen didn't
allocate a segment. In that case, we should just let Linux do whatever
it wants in terms of segment allocation. So I think the code here should
not return error if param_pci_enable is false.
returning an error instead.
Rahul Singh Sept. 16, 2021, 4:36 p.m. UTC | #2
Hi Stefano,

> On 10 Sep 2021, at 2:00 am, Stefano Stabellini <sstabellini@kernel.org> wrote:
> 
> On Thu, 19 Aug 2021, Rahul Singh wrote:
>> If the property is not present in the device tree node for host bridge,
>> XEN while creating the dtb for hwdom will create this property and
>> assigns the already allocated segment to the host bridge
>> so that XEN and linux will have the same segment for the host bridges.
>> 
>> Signed-off-by: Rahul Singh <rahul.singh@arm.com>
>> ---
>> xen/arch/arm/domain_build.c        | 18 ++++++++++++++++++
>> xen/arch/arm/pci/pci-host-common.c | 21 +++++++++++++++++++++
>> xen/include/asm-arm/pci.h          |  3 +++
>> 3 files changed, 42 insertions(+)
>> 
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index 6c86d52781..e0cf2ff19d 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -581,6 +581,24 @@ static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
>>             return res;
>>     }
>> 
>> +#ifdef CONFIG_HAS_PCI
>> +    if ( dt_device_type_is_equal(node, "pci") )
>> +    {
>> +        if ( !dt_find_property(node, "linux,pci-domain", NULL) )
>> +        {
>> +            uint16_t segment;
>> +
>> +            res = pci_get_host_bridge_segment(node, &segment);
>> +            if ( res < 0 )
>> +                return res;
>> +
>> +            res = fdt_property_cell(kinfo->fdt, "linux,pci-domain", segment);
>> +            if ( res )
>> +                return res;
>> +        }
>> +    }
>> +#endif
> 
> If param_pci_enable is false it might be possible that Xen didn't
> allocate a segment. In that case, we should just let Linux do whatever
> it wants in terms of segment allocation. So I think the code here should
> not return error if param_pci_enable is false.
> returning an error instead.

Ack. I will modify the code as per your request in next version.

Regards,
Rahul
diff mbox series

Patch

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 6c86d52781..e0cf2ff19d 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -581,6 +581,24 @@  static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
             return res;
     }
 
+#ifdef CONFIG_HAS_PCI
+    if ( dt_device_type_is_equal(node, "pci") )
+    {
+        if ( !dt_find_property(node, "linux,pci-domain", NULL) )
+        {
+            uint16_t segment;
+
+            res = pci_get_host_bridge_segment(node, &segment);
+            if ( res < 0 )
+                return res;
+
+            res = fdt_property_cell(kinfo->fdt, "linux,pci-domain", segment);
+            if ( res )
+                return res;
+        }
+    }
+#endif
+
     /*
      * Override the property "status" to disable the device when it's
      * marked for passthrough.
diff --git a/xen/arch/arm/pci/pci-host-common.c b/xen/arch/arm/pci/pci-host-common.c
index 62715b4676..5e34252deb 100644
--- a/xen/arch/arm/pci/pci-host-common.c
+++ b/xen/arch/arm/pci/pci-host-common.c
@@ -280,6 +280,27 @@  struct pci_host_bridge *pci_find_host_bridge(uint16_t segment, uint8_t bus)
 
     return NULL;
 }
+
+/*
+ * This function will lookup an hostbridge based on config space address.
+ */
+int pci_get_host_bridge_segment(const struct dt_device_node *node,
+                                uint16_t *segment)
+{
+    struct pci_host_bridge *bridge;
+
+    list_for_each_entry( bridge, &pci_host_bridges, node )
+    {
+        if ( bridge->dt_node != node )
+            continue;
+
+        *segment = bridge->segment;
+        return 0;
+    }
+
+    return -EINVAL;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/pci.h b/xen/include/asm-arm/pci.h
index c58152de80..2d4610a23a 100644
--- a/xen/include/asm-arm/pci.h
+++ b/xen/include/asm-arm/pci.h
@@ -96,6 +96,9 @@  void __iomem *pci_ecam_map_bus(struct pci_host_bridge *bridge,
                                uint32_t sbdf, uint32_t where);
 
 struct pci_host_bridge *pci_find_host_bridge(uint16_t segment, uint8_t bus);
+int pci_get_host_bridge_segment(const struct dt_device_node *node,
+                                uint16_t *segment);
+
 #else   /*!CONFIG_HAS_PCI*/
 
 struct arch_pci_dev { };