|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] xen/arm: vpci: Remove PCI I/O ranges property value
Hi Stefano,
> On 16 Dec 2021, at 2:33 am, Stefano Stabellini <sstabellini@xxxxxxxxxx> wrote:
>
> On Tue, 14 Dec 2021, Rahul Singh wrote:
>> IO ports on ARM don't exist so all IO ports related hypercalls are going
>> to fail on ARM when we passthrough a PCI device.
>> Failure of xc_domain_ioport_permission(..) would turn into a critical
>> failure at domain creation. We need to avoid this outcome, instead we
>> want to continue with domain creation as normal even if
>> xc_domain_ioport_permission(..) fails. XEN_DOMCTL_ioport_permission
>> is not implemented on ARM so it would return -ENOSYS.
>>
>> To solve above issue remove PCI I/O ranges property value from dom0
>> device tree node so that dom0 linux will not allocate I/O space for PCI
>> devices if pci-passthrough is enabled.
>>
>> Another valid reason to remove I/O ranges is that PCI I/O space are not
>> mapped to dom0 when PCI passthrough is enabled, also there is no vpci
>> trap handler register for IO bar.
>>
>> Signed-off-by: Rahul Singh <rahul.singh@xxxxxxx>
>> ---
>> xen/arch/arm/domain_build.c | 14 +++++++
>> xen/common/device_tree.c | 72 +++++++++++++++++++++++++++++++++++
>> xen/include/xen/device_tree.h | 10 +++++
>> 3 files changed, 96 insertions(+)
>>
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index d02bacbcd1..60f6b2c73b 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -749,6 +749,11 @@ static int __init write_properties(struct domain *d,
>> struct kernel_info *kinfo,
>> continue;
>> }
>>
>> + if ( is_pci_passthrough_enabled() &&
>> + dt_device_type_is_equal(node, "pci") )
>> + if ( dt_property_name_is_equal(prop, "ranges") )
>> + continue;
>
> It looks like we are skipping the "ranges" property entirely for the PCI
> node, is that right? Wouldn't that also remove the other (not ioports)
> address ranges?
We are skipping the “ranges” property here to avoid setting the “ranges”
property when
pci_passthrough is enabled. We will remove only remove IO port and set the
other ‘ranges” property
value in dt_pci_remove_io_ranges() in next if() condition.
>> res = fdt_property(kinfo->fdt, prop->name, prop_data, prop_len);
>>
>> if ( res )
>> @@ -769,6 +774,15 @@ static int __init write_properties(struct domain *d,
>> struct kernel_info *kinfo,
>> if ( res )
>> return res;
>> }
>> +
>> + /*
>> + * PCI IO bar are not mapped to dom0 when PCI passthrough is
>> enabled,
>> + * also there is no trap handler registered for IO bar therefor
>> remove
>> + * the IO range property from the device tree node for dom0.
>> + */
>> + res = dt_pci_remove_io_ranges(kinfo->fdt, node);
>> + if ( res )
>> + return res;
>
> I tried to apply this patch to staging to make it easier to review but I
> think this chuck got applied wrongly: I can see
> dt_pci_remove_io_ranges() added to the function "handle_prop_pfdt" which
> is for guest partial DTBs and not for dom0.
Oleksandr’s patch series was merged yesterday because of that there is conflict
in applying
this patch. I will rebase the patch and will send it again for review.
>
> Is dt_pci_remove_io_ranges() meant to be called from write_properties
> instead? It looks like it would be best to call it from
> write_properties, maybe it could be combined with the other new check
> just above in this patch?
Yes dt_pci_remove_io_ranges() is to be called from write_properties().
Regards,
Rahul
>
>
>> /*
>> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
>> index 4aae281e89..9fa25f6723 100644
>> --- a/xen/common/device_tree.c
>> +++ b/xen/common/device_tree.c
>> @@ -2195,6 +2195,78 @@ int dt_get_pci_domain_nr(struct dt_device_node *node)
>> return (u16)domain;
>> }
>>
>> +int dt_pci_remove_io_ranges(void *fdt, const struct dt_device_node *dev)
>> +{
>> + const struct dt_device_node *parent = NULL;
>> + const struct dt_bus *bus, *pbus;
>> + unsigned int rlen;
>> + int na, ns, pna, pns, rone, ret;
>> + const __be32 *ranges;
>> + __be32 regs[((GUEST_ROOT_ADDRESS_CELLS * 2) + GUEST_ROOT_SIZE_CELLS + 1)
>> + * 2];
>> + __be32 *addr = ®s[0];
>> +
>> + bus = dt_match_bus(dev);
>> + if ( !bus )
>> + return 0; /* device is not a bus */
>> +
>> + parent = dt_get_parent(dev);
>> + if ( parent == NULL )
>> + return -EINVAL;
>> +
>> + ranges = dt_get_property(dev, "ranges", &rlen);
>> + if ( ranges == NULL )
>> + {
>> + printk(XENLOG_ERR "DT: no ranges; cannot enumerate %s\n",
>> + dev->full_name);
>> + return -EINVAL;
>> + }
>> + if ( rlen == 0 ) /* Nothing to do */
>> + return 0;
>> +
>> + bus->count_cells(dev, &na, &ns);
>> + if ( !DT_CHECK_COUNTS(na, ns) )
>> + {
>> + printk(XENLOG_ERR "dt_parse: Bad cell count for device %s\n",
>> + dev->full_name);
>> + return -EINVAL;
>> + }
>> + pbus = dt_match_bus(parent);
>> + if ( pbus == NULL )
>> + {
>> + printk("DT: %s is not a valid bus\n", parent->full_name);
>> + return -EINVAL;
>> + }
>> +
>> + pbus->count_cells(dev, &pna, &pns);
>> + if ( !DT_CHECK_COUNTS(pna, pns) )
>> + {
>> + printk(XENLOG_ERR "dt_parse: Bad cell count for parent %s\n",
>> + dev->full_name);
>> + return -EINVAL;
>> + }
>> + /* Now walk through the ranges */
>> + rlen /= 4;
>> + rone = na + pna + ns;
>> +
>> + for ( ; rlen >= rone; rlen -= rone, ranges += rone )
>> + {
>> + unsigned int flags = bus->get_flags(ranges);
>> + if ( flags & IORESOURCE_IO )
>> + continue;
>> +
>> + memcpy(addr, ranges, 4 * rone);
>> +
>> + addr += rone;
>> + }
>> +
>> + ret = fdt_property(fdt, "ranges", regs, sizeof(regs));
>> + if ( ret )
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> /*
>> * Local variables:
>> * mode: C
>> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
>> index fd6cd00b43..ad2e905595 100644
>> --- a/xen/include/xen/device_tree.h
>> +++ b/xen/include/xen/device_tree.h
>> @@ -849,6 +849,16 @@ int dt_count_phandle_with_args(const struct
>> dt_device_node *np,
>> */
>> int dt_get_pci_domain_nr(struct dt_device_node *node);
>>
>> +/**
>> + * dt_get_remove_io_range - Remove the PCI I/O range property value.
>> + * @fdt: Pointer to the file descriptor tree.
>> + * @node: Device tree node.
>> + *
>> + * This function will remove the PCI IO range property from the PCI device
>> tree
>> + * node.
>> + */
>> +int dt_pci_remove_io_ranges(void *fdt, const struct dt_device_node *node);
>> +
>> struct dt_device_node *dt_find_node_by_phandle(dt_phandle handle);
>>
>> #ifdef CONFIG_DEVICE_TREE_DEBUG
>> --
>> 2.25.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |