Re: [XEN][PATCH v11 03/20] xen/arm/device: Remove __init from function type
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
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); +