Re: [XEN][PATCH v11 03/20] xen/arm/device: Remove __init from function type

2023-09-05 Thread Stefano Stabellini
On Thu, 31 Aug 2023, Vikram Garhwal wrote:
> Remove __init from following function to access during runtime:
> 1. map_irq_to_domain()
> 2. handle_device_interrupts()
> 3. map_range_to_domain()
> 4. unflatten_dt_node()
> 5. handle_device()
> 6. map_device_children()
> 7. map_dt_irq_to_domain()
> Move map_irq_to_domain() prototype from domain_build.h to setup.h.
> 
> Above changes will create an error on build as non-init function are still
> in domain_build.c file. So, to avoid build fails, following changes are done:
> 1. Move map_irq_to_domain(), handle_device_interrupts(), 
> map_range_to_domain(),
> handle_device(), map_device_children() and map_dt_irq_to_domain()
> to device.c. After removing __init type,  these functions are not specific
> to domain building, so moving them out of domain_build.c to device.c.
> 2. Remove static type from handle_device_interrupts().
> 
> Also, renamed handle_device_interrupts() to map_device_irqs_to_domain().
> 
> Overall, these changes are done to support the dynamic programming of a nodes
> where an overlay node will be added to fdt and unflattened node will be added 
> to
> dt_host. Furthermore, IRQ and mmio mapping will be done for the added node.
> 
> Signed-off-by: Vikram Garhwal 
> Reviewed-by: Michal Orzel 

Acked-by: Stefano Stabellini 


> ---
> Changes from v10:
> Remove unnecessary rangeset variables  from handle_device() declaration.
> Rename handle_device_interrupts() to map_device_irqs_to_domain().
> Fix code styles.
> 
> Changes from v9:
> Move handle_device(), map_device_children() and map_dt_irq_to_domain() out
> of domain_build.c
> ---
> ---
>  xen/arch/arm/device.c   | 294 +++
>  xen/arch/arm/domain_build.c | 295 +---
>  xen/arch/arm/include/asm/domain_build.h |   2 -
>  xen/arch/arm/include/asm/setup.h|   9 +
>  xen/common/device_tree.c|  12 +-
>  5 files changed, 310 insertions(+), 302 deletions(-)
> 
> diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
> index ca8539dee5..327e4d24fb 100644
> --- a/xen/arch/arm/device.c
> +++ b/xen/arch/arm/device.c
> @@ -9,8 +9,10 @@
>   */
>  
>  #include 
> +#include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  extern const struct device_desc _sdevice[], _edevice[];
> @@ -75,6 +77,298 @@ enum device_class device_get_class(const struct 
> dt_device_node *dev)
>  return DEVICE_UNKNOWN;
>  }
>  
> +int map_irq_to_domain(struct domain *d, unsigned int irq,
> +  bool need_mapping, const char *devname)
> +{
> +int res;
> +
> +res = irq_permit_access(d, irq);
> +if ( res )
> +{
> +printk(XENLOG_ERR "Unable to permit to %pd access to IRQ %u\n", d, 
> irq);
> +return res;
> +}
> +
> +if ( need_mapping )
> +{
> +/*
> + * Checking the return of vgic_reserve_virq is not
> + * necessary. It should not fail except when we try to map
> + * the IRQ twice. This can legitimately happen if the IRQ is shared
> + */
> +vgic_reserve_virq(d, irq);
> +
> +res = route_irq_to_guest(d, irq, irq, devname);
> +if ( res < 0 )
> +{
> +printk(XENLOG_ERR "Unable to map IRQ%u to %pd\n", irq, d);
> +return res;
> +}
> +}
> +
> +dt_dprintk("  - IRQ: %u\n", irq);
> +return 0;
> +}
> +
> +int map_range_to_domain(const struct dt_device_node *dev,
> +uint64_t addr, uint64_t len, void *data)
> +{
> +struct map_range_data *mr_data = data;
> +struct domain *d = mr_data->d;
> +int res;
> +
> +if ( (addr != (paddr_t)addr) || (((paddr_t)~0 - addr) < len) )
> +{
> +printk(XENLOG_ERR "%s: [0x%"PRIx64", 0x%"PRIx64"] exceeds the 
> maximum allowed PA width (%u bits)",
> +   dt_node_full_name(dev), addr, (addr + len), PADDR_BITS);
> +return -ERANGE;
> +}
> +
> +/*
> + * reserved-memory regions are RAM carved out for a special purpose.
> + * They are not MMIO and therefore a domain should not be able to
> + * manage them via the IOMEM interface.
> + */
> +if ( strncasecmp(dt_node_full_name(dev), "/reserved-memory/",
> + strlen("/reserved-memory/")) != 0 )
> +{
> +res = iomem_permit_access(d, paddr_to_pfn(addr),
> +paddr_to_pfn(PAGE_ALIGN(addr + len - 1)));
> +if ( res )
> +{
> +printk(XENLOG_ERR "Unable to permit to dom%d access to"
> +" 0x%"PRIx64" - 0x%"PRIx64"\n",
> +d->domain_id,
> +addr & PAGE_MASK, PAGE_ALIGN(addr + len) - 1);
> +return res;
> +}
> +}
> +
> +if ( !mr_data->skip_mapping )
> +{
> +res = map_regions_p2mt(d,
> +   gaddr_to_gfn(addr),
> +   PFN_UP(len),
> +   

[XEN][PATCH v11 03/20] xen/arm/device: Remove __init from function type

2023-08-31 Thread Vikram Garhwal
Remove __init from following function to access during runtime:
1. map_irq_to_domain()
2. handle_device_interrupts()
3. map_range_to_domain()
4. unflatten_dt_node()
5. handle_device()
6. map_device_children()
7. map_dt_irq_to_domain()
Move map_irq_to_domain() prototype from domain_build.h to setup.h.

Above changes will create an error on build as non-init function are still
in domain_build.c file. So, to avoid build fails, following changes are done:
1. Move map_irq_to_domain(), handle_device_interrupts(), map_range_to_domain(),
handle_device(), map_device_children() and map_dt_irq_to_domain()
to device.c. After removing __init type,  these functions are not specific
to domain building, so moving them out of domain_build.c to device.c.
2. Remove static type from handle_device_interrupts().

Also, renamed handle_device_interrupts() to map_device_irqs_to_domain().

Overall, these changes are done to support the dynamic programming of a nodes
where an overlay node will be added to fdt and unflattened node will be added to
dt_host. Furthermore, IRQ and mmio mapping will be done for the added node.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Michal Orzel 

---
Changes from v10:
Remove unnecessary rangeset variables  from handle_device() declaration.
Rename handle_device_interrupts() to map_device_irqs_to_domain().
Fix code styles.

Changes from v9:
Move handle_device(), map_device_children() and map_dt_irq_to_domain() out
of domain_build.c
---
---
 xen/arch/arm/device.c   | 294 +++
 xen/arch/arm/domain_build.c | 295 +---
 xen/arch/arm/include/asm/domain_build.h |   2 -
 xen/arch/arm/include/asm/setup.h|   9 +
 xen/common/device_tree.c|  12 +-
 5 files changed, 310 insertions(+), 302 deletions(-)

diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
index ca8539dee5..327e4d24fb 100644
--- a/xen/arch/arm/device.c
+++ b/xen/arch/arm/device.c
@@ -9,8 +9,10 @@
  */
 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 
 extern const struct device_desc _sdevice[], _edevice[];
@@ -75,6 +77,298 @@ enum device_class device_get_class(const struct 
dt_device_node *dev)
 return DEVICE_UNKNOWN;
 }
 
+int map_irq_to_domain(struct domain *d, unsigned int irq,
+  bool need_mapping, const char *devname)
+{
+int res;
+
+res = irq_permit_access(d, irq);
+if ( res )
+{
+printk(XENLOG_ERR "Unable to permit to %pd access to IRQ %u\n", d, 
irq);
+return res;
+}
+
+if ( need_mapping )
+{
+/*
+ * Checking the return of vgic_reserve_virq is not
+ * necessary. It should not fail except when we try to map
+ * the IRQ twice. This can legitimately happen if the IRQ is shared
+ */
+vgic_reserve_virq(d, irq);
+
+res = route_irq_to_guest(d, irq, irq, devname);
+if ( res < 0 )
+{
+printk(XENLOG_ERR "Unable to map IRQ%u to %pd\n", irq, d);
+return res;
+}
+}
+
+dt_dprintk("  - IRQ: %u\n", irq);
+return 0;
+}
+
+int map_range_to_domain(const struct dt_device_node *dev,
+uint64_t addr, uint64_t len, void *data)
+{
+struct map_range_data *mr_data = data;
+struct domain *d = mr_data->d;
+int res;
+
+if ( (addr != (paddr_t)addr) || (((paddr_t)~0 - addr) < len) )
+{
+printk(XENLOG_ERR "%s: [0x%"PRIx64", 0x%"PRIx64"] exceeds the maximum 
allowed PA width (%u bits)",
+   dt_node_full_name(dev), addr, (addr + len), PADDR_BITS);
+return -ERANGE;
+}
+
+/*
+ * reserved-memory regions are RAM carved out for a special purpose.
+ * They are not MMIO and therefore a domain should not be able to
+ * manage them via the IOMEM interface.
+ */
+if ( strncasecmp(dt_node_full_name(dev), "/reserved-memory/",
+ strlen("/reserved-memory/")) != 0 )
+{
+res = iomem_permit_access(d, paddr_to_pfn(addr),
+paddr_to_pfn(PAGE_ALIGN(addr + len - 1)));
+if ( res )
+{
+printk(XENLOG_ERR "Unable to permit to dom%d access to"
+" 0x%"PRIx64" - 0x%"PRIx64"\n",
+d->domain_id,
+addr & PAGE_MASK, PAGE_ALIGN(addr + len) - 1);
+return res;
+}
+}
+
+if ( !mr_data->skip_mapping )
+{
+res = map_regions_p2mt(d,
+   gaddr_to_gfn(addr),
+   PFN_UP(len),
+   maddr_to_mfn(addr),
+   mr_data->p2mt);
+
+if ( res < 0 )
+{
+printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+   " - 0x%"PRIx64" in domain %d\n",
+   addr & PAGE_MASK, PAGE_ALIGN(addr + len) - 1,
+   d->domain_id);
+