|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XEN][PATCH v11 15/20] arm/asm/setup.h: Update struct map_range_data to add rangeset.
Add rangesets for IRQs and IOMEMs. This was done to accommodate dynamic overlay
node addition/removal operations. With overlay operations, new IRQs and IOMEMs
are added in dt_host and routed. While removing overlay nodes, nodes are removed
from dt_host and their IRQs and IOMEMs routing is also removed. Storing IRQs and
IOMEMs in the rangeset will avoid re-parsing the device tree nodes to get the
IOMEM and IRQ ranges for overlay remove ops.
Dynamic overlay node add/remove will be introduced in follow-up patches.
Signed-off-by: Vikram Garhwal <vikram.garhwal@xxxxxxx>
---
Changes from v10:
Replace paddr_to_pfn(PAGE_ALIGN()) with paddr_to_pfn_aligned().
Change data type of irq.
fix function change for handle_device().
Remove unnecessary change .d = d in mr_data.
---
---
xen/arch/arm/device.c | 43 +++++++++++++++++++++++++-------
xen/arch/arm/domain_build.c | 4 +--
xen/arch/arm/include/asm/setup.h | 9 ++++---
3 files changed, 42 insertions(+), 14 deletions(-)
diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
index 327e4d24fb..1f631d3274 100644
--- a/xen/arch/arm/device.c
+++ b/xen/arch/arm/device.c
@@ -165,6 +165,15 @@ int map_range_to_domain(const struct dt_device_node *dev,
dt_dprintk(" - MMIO: %010"PRIx64" - %010"PRIx64" P2MType=%x\n",
addr, addr + len, mr_data->p2mt);
+ if ( mr_data->iomem_ranges )
+ {
+ res = rangeset_add_range(mr_data->iomem_ranges,
+ paddr_to_pfn(addr),
+ paddr_to_pfn_aligned(addr + len - 1));
+ if ( res )
+ return res;
+ }
+
return 0;
}
@@ -178,10 +187,11 @@ int map_range_to_domain(const struct dt_device_node *dev,
*/
int map_device_irqs_to_domain(struct domain *d,
struct dt_device_node *dev,
- bool need_mapping)
+ bool need_mapping,
+ struct rangeset *irq_ranges)
{
unsigned int i, nirq;
- int res;
+ int res, irq;
struct dt_raw_irq rirq;
nirq = dt_number_of_irq(dev);
@@ -208,17 +218,24 @@ int map_device_irqs_to_domain(struct domain *d,
continue;
}
- res = platform_get_irq(dev, i);
- if ( res < 0 )
+ irq = platform_get_irq(dev, i);
+ if ( irq < 0 )
{
printk(XENLOG_ERR "Unable to get irq %u for %s\n",
i, dt_node_full_name(dev));
- return res;
+ return irq;
}
- res = map_irq_to_domain(d, res, need_mapping, dt_node_name(dev));
+ res = map_irq_to_domain(d, irq, need_mapping, dt_node_name(dev));
if ( res )
return res;
+
+ if ( irq_ranges )
+ {
+ res = rangeset_add_singleton(irq_ranges, irq);
+ if ( res )
+ return res;
+ }
}
return 0;
@@ -249,6 +266,11 @@ static int map_dt_irq_to_domain(const struct
dt_device_node *dev,
}
res = map_irq_to_domain(d, irq, !mr_data->skip_mapping, dt_node_name(dev));
+ if ( res )
+ return res;
+
+ if ( mr_data->irq_ranges )
+ res = rangeset_add_singleton(mr_data->irq_ranges, irq);
return res;
}
@@ -289,7 +311,8 @@ static int map_device_children(const struct dt_device_node
*dev,
* - Assign the device to the guest if it's protected by an IOMMU
* - Map the IRQs and iomem regions to DOM0
*/
-int handle_device(struct domain *d, struct dt_device_node *dev, p2m_type_t
p2mt)
+int handle_device(struct domain *d, struct dt_device_node *dev, p2m_type_t
p2mt,
+ struct rangeset *iomem_ranges, struct rangeset *irq_ranges)
{
unsigned int naddr;
unsigned int i;
@@ -308,7 +331,9 @@ int handle_device(struct domain *d, struct dt_device_node
*dev, p2m_type_t p2mt)
.p2mt = p2mt,
.skip_mapping = !own_device ||
(is_pci_passthrough_enabled() &&
- (device_get_class(dev) == DEVICE_PCI_HOSTBRIDGE))
+ (device_get_class(dev) == DEVICE_PCI_HOSTBRIDGE)),
+ .iomem_ranges = iomem_ranges,
+ .irq_ranges = irq_ranges
};
naddr = dt_number_of_address(dev);
@@ -342,7 +367,7 @@ int handle_device(struct domain *d, struct dt_device_node
*dev, p2m_type_t p2mt)
}
}
- res = map_device_irqs_to_domain(d, dev, own_device);
+ res = map_device_irqs_to_domain(d, dev, own_device, irq_ranges);
if ( res < 0 )
return res;
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index ff4fc30769..29dcbb8a2e 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -2402,7 +2402,7 @@ static int __init handle_node(struct domain *d, struct
kernel_info *kinfo,
"WARNING: Path %s is reserved, skip the node as we may re-use
the path.\n",
path);
- res = handle_device(d, node, p2mt);
+ res = handle_device(d, node, p2mt, NULL, NULL);
if ( res)
return res;
@@ -2745,7 +2745,7 @@ static int __init handle_passthrough_prop(struct
kernel_info *kinfo,
return -EINVAL;
}
- res = map_device_irqs_to_domain(kinfo->d, node, true);
+ res = map_device_irqs_to_domain(kinfo->d, node, true, NULL);
if ( res < 0 )
return res;
diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index 6cda3e4039..b8866c20f4 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -113,6 +113,9 @@ struct map_range_data
p2m_type_t p2mt;
/* Set if mapping of the memory ranges must be skipped. */
bool skip_mapping;
+ /* Rangeset to store IRQs and IOMEM for overlay nodes. */
+ struct rangeset *iomem_ranges;
+ struct rangeset *irq_ranges;
};
extern struct bootinfo bootinfo;
@@ -165,11 +168,11 @@ void device_tree_get_reg(const __be32 **cell, uint32_t
address_cells,
u32 device_tree_get_u32(const void *fdt, int node,
const char *prop_name, u32 dflt);
-int handle_device(struct domain *d, struct dt_device_node *dev,
- p2m_type_t p2mt);
+int handle_device(struct domain *d, struct dt_device_node *dev, p2m_type_t
p2mt,
+ struct rangeset *iomem_ranges, struct rangeset *irq_ranges);
int map_device_irqs_to_domain(struct domain *d, struct dt_device_node *dev,
- bool need_mapping);
+ bool need_mapping, struct rangeset *irq_ranges);
int map_irq_to_domain(struct domain *d, unsigned int irq,
bool need_mapping, const char *devname);
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |