[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] xen/arm: vpci: Remove PCI I/O ranges property value


  • To: Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • From: Rahul Singh <Rahul.Singh@xxxxxxx>
  • Date: Thu, 16 Dec 2021 09:57:13 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=JTr32IhtOpI0DMpewFFRmpDZYkBAEYJFzNkVsLqr4Vo=; b=ZthYkBKGwRtTCOVKOI8banh++mjs5dqjuqL/J/ck9Aow5RCA08n1j/SYNKWmF/DuCDwjgL/Sn7tRZQ30emqHTaiCOBdntfMjKXYsH/gpg88JwGgMjR6QJUrFiBf9q9jNZItqiKC9VehkSQxLjDkoIS/1lWE6BBW/caZupuzY/oZw9ee5VN+PaOE4l2tO6/njdxjUGMozoKvph+GUcEu/ixJn+zOWC5VoqjhBC+QUeQi9Wteu088ziVwxK3Rcy6Kld+8gPREos8sge2wxbB5ZNOC3PBsJPYqqCKZ7w8MRXSbwOHadLVFewCswxs03abJBMG8WK7WST4hs+f+RqAUwWg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IHgyW0b2kYbl9iU1N/378vCB2F5KIKh6LMd4fbVpau8HZNY4+7/W7RZoqZ7I1Qr2R4Q8WipzhFKxJ0sUvjT+kRQfbsJ2/ofmM7QLWsaeQWPKuNLq34eA4C3wbqBmIGOwVYfiryJ+m0pmznXgBUgtzVHqNqFX0qmOdWKojwRaU+5Ub1liyJv2Ez1Ex+Rd79saxOVCTKiJti3AF+WStrW57cgRtjLxUGLTVs+iRqhRDx0mfhn94pl6TJ5KaeoiCNknV6s1e6Bw/8w+4QW0+k98Ayij2f7kj/0ggRQss1wOrIYFBnbGrmAzp0mpmouqAWnvrDzxkZuOIjuv3zdGNpCaBw==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Julien Grall <julien@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Thu, 16 Dec 2021 09:57:41 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHX8NfE0k+LAAwoDUiQfCEULp9EE6w0aQgAgAB74AA=
  • Thread-topic: [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 = &regs[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.