From: Vikram Garhwal <vikram.garhwal@amd.com>
To: Luca Fancellu <Luca.Fancellu@arm.com>
Cc: Vikram Garhwal <fnu.vikram@xilinx.com>,
Xen-devel <xen-devel@lists.xenproject.org>,
"sstabellini@kernel.org" <sstabellini@kernel.org>,
"julien@xen.org" <julien@xen.org>,
Bertrand Marquis <Bertrand.Marquis@arm.com>,
"volodymyr_babchuk@epam.com" <volodymyr_babchuk@epam.com>
Subject: Re: [XEN][RFC PATCH v3 01/14] xen/arm/device: Remove __init from function type
Date: Tue, 15 Mar 2022 15:42:55 -0700 [thread overview]
Message-ID: <20220315224252.GB23054@xilinx.com> (raw)
In-Reply-To: <337CEFA8-895C-4B5D-810A-3D4E2927CE01@arm.com>
On Mon, Mar 14, 2022 at 12:31:06PM +0000, Luca Fancellu wrote:
>
>
> > On 8 Mar 2022, at 19:46, Vikram Garhwal <fnu.vikram@xilinx.com> wrote:
> >
> > Change function type of following function to access during runtime:
> > 1. map_irq_to_domain()
> > 2. handle_device_interrupt()
> > 3. map_range_to_domain()
> > 4. unflatten_dt_node()
> > 5. unflatten_device_tree()
> >
> > Move map_irq_to_domain(), handle_device_interrupt() and map_range_to_domain() to
> > device.c.
> >
> > 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 <fnu.vikram@xilinx.com>
> > ---
> > xen/arch/arm/device.c | 136 +++++++++++++++++++++++++++++
> > xen/arch/arm/domain_build.c | 142 -------------------------------
> > xen/arch/arm/include/asm/setup.h | 3 +
> > xen/common/device_tree.c | 20 ++---
> > xen/include/xen/device_tree.h | 5 ++
> > 5 files changed, 154 insertions(+), 152 deletions(-)
> >
> > diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
> > index 70cd6c1a19..0dfd33b33e 100644
> > --- a/xen/arch/arm/device.c
> > +++ b/xen/arch/arm/device.c
> > @@ -21,6 +21,9 @@
> > #include <xen/errno.h>
> > #include <xen/init.h>
> > #include <xen/lib.h>
> > +#include <xen/iocap.h>
> > +#include <asm/domain_build.h>
> > +#include <asm/setup.h>
> >
> > extern const struct device_desc _sdevice[], _edevice[];
> > extern const struct acpi_device_desc _asdevice[], _aedevice[];
> > @@ -84,6 +87,139 @@ 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 dom%u access to IRQ %u\n",
> > + d->domain_id, 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%"PRId32" to dom%d\n",
> > + irq, d->domain_id);
> > + return res;
> > + }
> > + }
> > +
> > + dt_dprintk(" - IRQ: %u\n", irq);
> > + return 0;
> > +}
> > +
> > +int map_range_to_domain(const struct dt_device_node *dev,
> > + u64 addr, u64 len, void *data)
> > +{
> > + struct map_range_data *mr_data = data;
> > + struct domain *d = mr_data->d;
> > + int res;
> > +
> > + res = iomem_permit_access(d, paddr_to_pfn(addr),
> > + paddr_to_pfn(PAGE_ALIGN(addr + len - 1)));
>
> Hi Vikram,
>
> Why the if ( strncasecmp(dt_node_full_name(dev), "/reserved-memory/",
> strlen("/reserved-memory/")) != 0 ) was dropped?
>
>
Hi Luca,
Thanks for spotting this. Yeah, I messed this while porting the patches from
internal to upstream Xen.
Will address this in v4!
@everyone, apologies for resending the same email. Previous one didn't make to
xen-devel due to change in my email ID.
Regards,
Vikram
> > + 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);
> > + return res;
> > + }
> > + }
> > +
> > + dt_dprintk(" - MMIO: %010"PRIx64" - %010"PRIx64" P2MType=%x\n",
> > + addr, addr + len, mr_data->p2mt);
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * handle_device_interrupts retrieves the interrupts configuration from
> > + * a device tree node and maps those interrupts to the target domain.
> > + *
> > + * Returns:
> > + * < 0 error
> > + * 0 success
> > + */
> > +int handle_device_interrupts(struct domain *d,
> > + struct dt_device_node *dev,
> > + bool need_mapping)
> > +{
> > + unsigned int i, nirq;
> > + int res;
> > + struct dt_raw_irq rirq;
> > +
> > + nirq = dt_number_of_irq(dev);
> > +
> > + /* Give permission and map IRQs */
> > + for ( i = 0; i < nirq; i++ )
> > + {
> > + res = dt_device_get_raw_irq(dev, i, &rirq);
> > + if ( res )
> > + {
> > + printk(XENLOG_ERR "Unable to retrieve irq %u for %s\n",
> > + i, dt_node_full_name(dev));
> > + return res;
> > + }
> > +
> > + /*
> > + * Don't map IRQ that have no physical meaning
> > + * ie: IRQ whose controller is not the GIC
> > + */
> > + if ( rirq.controller != dt_interrupt_controller )
> > + {
> > + dt_dprintk("irq %u not connected to primary controller. Connected to %s\n",
> > + i, dt_node_full_name(rirq.controller));
> > + continue;
> > + }
> > +
> > + res = platform_get_irq(dev, i);
> > + if ( res < 0 )
> > + {
> > + printk(XENLOG_ERR "Unable to get irq %u for %s\n",
> > + i, dt_node_full_name(dev));
> > + return res;
> > + }
> > +
> > + res = map_irq_to_domain(d, res, need_mapping, dt_node_name(dev));
> > + if ( res )
> > + return res;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > /*
> > * Local variables:
> > * mode: C
> > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> > index 8be01678de..b06770a2af 100644
> > --- a/xen/arch/arm/domain_build.c
> > +++ b/xen/arch/arm/domain_build.c
> > @@ -1794,41 +1794,6 @@ int __init make_chosen_node(const struct kernel_info *kinfo)
> > return res;
> > }
> >
> > -int __init 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 dom%u access to IRQ %u\n",
> > - d->domain_id, 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%"PRId32" to dom%d\n",
> > - irq, d->domain_id);
> > - return res;
> > - }
> > - }
> > -
> > - dt_dprintk(" - IRQ: %u\n", irq);
> > - return 0;
> > -}
> > -
> > static int __init map_dt_irq_to_domain(const struct dt_device_node *dev,
> > const struct dt_irq *dt_irq,
> > void *data)
> > @@ -1860,57 +1825,6 @@ static int __init map_dt_irq_to_domain(const struct dt_device_node *dev,
> > return 0;
> > }
> >
> > -int __init map_range_to_domain(const struct dt_device_node *dev,
> > - u64 addr, u64 len, void *data)
> > -{
> > - struct map_range_data *mr_data = data;
> > - struct domain *d = mr_data->d;
> > - int res;
> > -
> > - /*
> > - * 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);
> > - return res;
> > - }
> > - }
> > -
> > - dt_dprintk(" - MMIO: %010"PRIx64" - %010"PRIx64" P2MType=%x\n",
> > - addr, addr + len, mr_data->p2mt);
> > -
> > - return 0;
> > -}
> > -
> > /*
> > * For a node which describes a discoverable bus (such as a PCI bus)
> > * then we may need to perform additional mappings in order to make
> > @@ -1938,62 +1852,6 @@ static int __init map_device_children(const struct dt_device_node *dev,
> > return 0;
> > }
> >
> > -/*
> > - * handle_device_interrupts retrieves the interrupts configuration from
> > - * a device tree node and maps those interrupts to the target domain.
> > - *
> > - * Returns:
> > - * < 0 error
> > - * 0 success
> > - */
> > -static int __init handle_device_interrupts(struct domain *d,
> > - struct dt_device_node *dev,
> > - bool need_mapping)
> > -{
> > - unsigned int i, nirq;
> > - int res;
> > - struct dt_raw_irq rirq;
> > -
> > - nirq = dt_number_of_irq(dev);
> > -
> > - /* Give permission and map IRQs */
> > - for ( i = 0; i < nirq; i++ )
> > - {
> > - res = dt_device_get_raw_irq(dev, i, &rirq);
> > - if ( res )
> > - {
> > - printk(XENLOG_ERR "Unable to retrieve irq %u for %s\n",
> > - i, dt_node_full_name(dev));
> > - return res;
> > - }
> > -
> > - /*
> > - * Don't map IRQ that have no physical meaning
> > - * ie: IRQ whose controller is not the GIC
> > - */
> > - if ( rirq.controller != dt_interrupt_controller )
> > - {
> > - dt_dprintk("irq %u not connected to primary controller. Connected to %s\n",
> > - i, dt_node_full_name(rirq.controller));
> > - continue;
> > - }
> > -
> > - res = platform_get_irq(dev, i);
> > - if ( res < 0 )
> > - {
> > - printk(XENLOG_ERR "Unable to get irq %u for %s\n",
> > - i, dt_node_full_name(dev));
> > - return res;
> > - }
> > -
> > - res = map_irq_to_domain(d, res, need_mapping, dt_node_name(dev));
> > - if ( res )
> > - return res;
> > - }
> > -
> > - return 0;
> > -}
> > -
> > /*
> > * For a given device node:
> > * - Give permission to the guest to manage IRQ and MMIO range
> > diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
> > index 7a1e1d6798..8a26f1845c 100644
> > --- a/xen/arch/arm/include/asm/setup.h
> > +++ b/xen/arch/arm/include/asm/setup.h
> > @@ -134,6 +134,9 @@ void device_tree_get_reg(const __be32 **cell, u32 address_cells,
> > u32 device_tree_get_u32(const void *fdt, int node,
> > const char *prop_name, u32 dflt);
> >
> > +int handle_device_interrupts(struct domain *d, struct dt_device_node *dev,
> > + bool need_mapping);
> > +
> > int map_range_to_domain(const struct dt_device_node *dev,
> > u64 addr, u64 len, void *data);
> >
> > diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> > index 4aae281e89..f43d66a501 100644
> > --- a/xen/common/device_tree.c
> > +++ b/xen/common/device_tree.c
> > @@ -1811,12 +1811,12 @@ int dt_count_phandle_with_args(const struct dt_device_node *np,
> > * @allnextpp: pointer to ->allnext from last allocated device_node
> > * @fpsize: Size of the node path up at the current depth.
> > */
> > -static unsigned long __init unflatten_dt_node(const void *fdt,
> > - unsigned long mem,
> > - unsigned long *p,
> > - struct dt_device_node *dad,
> > - struct dt_device_node ***allnextpp,
> > - unsigned long fpsize)
> > +static unsigned long unflatten_dt_node(const void *fdt,
> > + unsigned long mem,
> > + unsigned long *p,
> > + struct dt_device_node *dad,
> > + struct dt_device_node ***allnextpp,
> > + unsigned long fpsize)
> > {
> > struct dt_device_node *np;
> > struct dt_property *pp, **prev_pp = NULL;
> > @@ -2047,7 +2047,7 @@ static unsigned long __init unflatten_dt_node(const void *fdt,
> > }
> >
> > /**
> > - * __unflatten_device_tree - create tree of device_nodes from flat blob
> > + * unflatten_device_tree - create tree of device_nodes from flat blob
> > *
> > * unflattens a device-tree, creating the
> > * tree of struct device_node. It also fills the "name" and "type"
> > @@ -2056,8 +2056,8 @@ static unsigned long __init unflatten_dt_node(const void *fdt,
> > * @fdt: The fdt to expand
> > * @mynodes: The device_node tree created by the call
> > */
> > -static void __init __unflatten_device_tree(const void *fdt,
> > - struct dt_device_node **mynodes)
> > +void unflatten_device_tree(const void *fdt,
> > + struct dt_device_node **mynodes)
> > {
> > unsigned long start, mem, size;
> > struct dt_device_node **allnextp = mynodes;
> > @@ -2179,7 +2179,7 @@ dt_find_interrupt_controller(const struct dt_device_match *matches)
> >
> > void __init dt_unflatten_host_device_tree(void)
> > {
> > - __unflatten_device_tree(device_tree_flattened, &dt_host);
> > + unflatten_device_tree(device_tree_flattened, &dt_host);
> > dt_alias_scan();
> > }
> >
> > diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
> > index fd6cd00b43..06d7866c10 100644
> > --- a/xen/include/xen/device_tree.h
> > +++ b/xen/include/xen/device_tree.h
> > @@ -177,6 +177,11 @@ int device_tree_for_each_node(const void *fdt, int node,
> > */
> > void dt_unflatten_host_device_tree(void);
> >
> > +/*
> > + * unflatten any device tree.
> > + */
> > +void unflatten_device_tree(const void *fdt, struct dt_device_node **mynodes);
> > +
> > /**
> > * IRQ translation callback
> > * TODO: For the moment we assume that we only have ONE
>
> NIT: there are some minor code style issues, like indentation that could be fixed
>
> Cheers,
> Luca
>
next prev parent reply other threads:[~2022-03-15 22:43 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-08 19:46 [XEN][RFC PATCH v3 00/14] dynamic node programming using overlay dtbo Vikram Garhwal
2022-03-08 19:46 ` [XEN][RFC PATCH v3 01/14] xen/arm/device: Remove __init from function type Vikram Garhwal
2022-03-14 12:31 ` Luca Fancellu
2022-03-15 22:29 ` Vikram Garhwal
2022-03-15 22:42 ` Vikram Garhwal [this message]
2022-03-08 19:46 ` [XEN][RFC PATCH v3 02/14] xen/arm: Add CONFIG_OVERLAY_DTB Vikram Garhwal
2022-03-14 12:42 ` Luca Fancellu
2022-03-08 19:46 ` [XEN][RFC PATCH v3 03/14] libfdt: Keep fdt functions after init for CONFIG_OVERLAY_DTB Vikram Garhwal
2022-05-17 17:36 ` Julien Grall
2022-03-08 19:46 ` [XEN][RFC PATCH v3 04/14] libfdt: overlay: change overlay_get_target() Vikram Garhwal
2022-03-14 14:55 ` Luca Fancellu
2022-05-17 17:51 ` Julien Grall
2022-03-08 19:46 ` [XEN][RFC PATCH v3 05/14] xen/device-tree: Add _dt_find_node_by_path() to find nodes in device tree Vikram Garhwal
2022-03-14 15:35 ` Luca Fancellu
2022-03-08 19:46 ` [XEN][RFC PATCH v3 06/14] xen/smmu: Add remove_device callback for smmu_iommu ops Vikram Garhwal
2022-03-14 15:45 ` Luca Fancellu
2022-03-08 19:46 ` [XEN][RFC PATCH v3 07/14] xen/iommu: Move spin_lock from iommu_dt_device_is_assigned to caller Vikram Garhwal
2022-03-14 15:58 ` Luca Fancellu
2022-05-17 18:19 ` Julien Grall
2022-03-08 19:46 ` [XEN][RFC PATCH v3 08/14] xen/iommu: protect iommu_add_dt_device() with dtdevs_lock Vikram Garhwal
2022-03-14 17:34 ` Luca Fancellu
2022-03-08 19:46 ` [XEN][RFC PATCH v3 09/14] xen/iommu: Introduce iommu_remove_dt_device() Vikram Garhwal
2022-03-14 17:50 ` Luca Fancellu
2022-12-07 5:21 ` Vikram Garhwal
2022-03-08 19:47 ` [XEN][RFC PATCH v3 10/14] xen/arm: Implement device tree node removal functionalities Vikram Garhwal
2022-03-15 10:10 ` Luca Fancellu
2022-05-18 18:31 ` Julien Grall
2022-12-07 1:37 ` Vikram Garhwal
2022-12-07 16:50 ` Julien Grall
2022-05-19 8:13 ` Julien Grall
2022-03-08 19:47 ` [XEN][RFC PATCH v3 11/14] xen/arm: Implement device tree node addition functionalities Vikram Garhwal
2022-03-15 10:40 ` Luca Fancellu
2022-05-18 19:03 ` Julien Grall
2022-03-08 19:47 ` [XEN][RFC PATCH v3 12/14] tools/libs/ctrl: Implement new xc interfaces for dt overlay Vikram Garhwal
2022-03-15 10:49 ` Luca Fancellu
2022-03-17 15:47 ` Anthony PERARD
2022-03-08 19:47 ` [XEN][RFC PATCH v3 13/14] tools/libs/light: Implement new libxl functions for device tree overlay ops Vikram Garhwal
2022-03-15 10:58 ` Luca Fancellu
2022-03-17 17:45 ` Anthony PERARD
2022-03-08 19:47 ` [XEN][RFC PATCH v3 14/14] tools/xl: Add new xl command overlay for device tree overlay support Vikram Garhwal
2022-03-15 12:11 ` Luca Fancellu
2022-03-17 18:18 ` Anthony PERARD
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220315224252.GB23054@xilinx.com \
--to=vikram.garhwal@amd.com \
--cc=Bertrand.Marquis@arm.com \
--cc=Luca.Fancellu@arm.com \
--cc=fnu.vikram@xilinx.com \
--cc=julien@xen.org \
--cc=sstabellini@kernel.org \
--cc=volodymyr_babchuk@epam.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.