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

Re: [PATCH 10/11] xen/arm: Do not map PCI ECAM space to Domain-0's p2m


  • To: Julien Grall <julien@xxxxxxx>, Oleksandr Andrushchenko <andr2000@xxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Oleksandr Andrushchenko <Oleksandr_Andrushchenko@xxxxxxxx>
  • Date: Fri, 10 Sep 2021 12:37:44 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.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; bh=fOY/k+Cl916ZN8DknowvG6mZDifaIyk5CAKNXWJuwOg=; b=ZMckj97MYUnaPkecitEZ9uvTWEzKY5fgFh2eKvq/CTZA+jjjwrVjAfdxE5qXjqwYG/M8FPkUsRWG8ISbvewV82YGwA8BEHqmw2C/Se0IVmgDMh49BmMxQneSIEM3WMGktt7bRkAPABiE5UyR+U6NqlEupBc+i2NkV2GN9dCm1HqipW44irN4bO57t0v6bdVQiKMUklNGLOfLXXZlBekd5zmQWsBsndOr+ELHBoIyHlilztfHRdn18L4DWHjkRNQNvcPFJYw9rZWAxlCs4c0JGvsH8z5enWd4tlplMn/5hg7c0XtnZyeBOrU3VEb3f1I6x6H7BQh7b/BwjV+9s9n0qg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=VG4qmk8IRMawKYHO4H2DolR11+n7ZYfQU2QKWZidnArZKv8irpE6zE/tpdJMdKZYTwhZbBrBdOC70LgTKCnKa+RoA/KvcOiZXhjCS3rmLkaUmrdDOnlfizPOBIShL1//0kcaY/QKheKgPjUd3tsb4Xi4SWjLMYLyTjLFPbcgcxYx7o4LZRM1fH+Dc8AhecKD66U2YZFVR2alfYvXE2t+UcqVcuyqku8fqd3sHLD2T6WiU1Y3pknWfEqojckN++8QgOPcFsRHjj1gxwrO6V2jg/UfBMWIq63Xedf/prBjs4EnM7n4FGey8WA9/RWtKMkE+GPqJI4dupoStdnqecdpng==
  • Authentication-results: xen.org; dkim=none (message not signed) header.d=none;xen.org; dmarc=none action=none header.from=epam.com;
  • Cc: "sstabellini@xxxxxxxxxx" <sstabellini@xxxxxxxxxx>, Oleksandr Tyshchenko <Oleksandr_Tyshchenko@xxxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Artem Mygaiev <Artem_Mygaiev@xxxxxxxx>, "roger.pau@xxxxxxxxxx" <roger.pau@xxxxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Rahul Singh <rahul.singh@xxxxxxx>
  • Delivery-date: Fri, 10 Sep 2021 12:38:00 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHXoJ50hf+zXQhc2ka7YfmmERKX+aucB06AgAE4wYA=
  • Thread-topic: [PATCH 10/11] xen/arm: Do not map PCI ECAM space to Domain-0's p2m

Hi, Julien!

On 09.09.21 20:58, Julien Grall wrote:
> Hi Oleksandr,
>
> On 03/09/2021 09:33, Oleksandr Andrushchenko wrote:
>> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx>
>>
>> Host bridge controller's ECAM space is mapped into Domain-0's p2m,
>> thus it is not possible to trap the same for vPCI via MMIO handlers.
>> For this to work we need to not map those while constructing the domain.
>>
>> Note, that during Domain-0 creation there is no pci_dev yet allocated for
>> host bridges, thus we cannot match PCI host and its associated
>> bridge by SBDF. Use dt_device_node field for checks instead.
>>
>> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx>
>> ---
>>   xen/arch/arm/domain_build.c        |  3 +++
>>   xen/arch/arm/pci/ecam.c            | 17 +++++++++++++++++
>>   xen/arch/arm/pci/pci-host-common.c | 22 ++++++++++++++++++++++
>>   xen/include/asm-arm/pci.h          | 12 ++++++++++++
>>   4 files changed, 54 insertions(+)
>>
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index da427f399711..76f5b513280c 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -1257,6 +1257,9 @@ static int __init map_range_to_domain(const struct 
>> dt_device_node *dev,
>>           }
>>       }
>>   +    if ( need_mapping && (device_get_class(dev) == DEVICE_PCI) ) > +      
>>   need_mapping = pci_host_bridge_need_p2m_mapping(d, dev, 
> addr, len);
>
> AFAICT, with device_get_class(dev), you know whether the hostbridge is used 
> by Xen. Therefore, I would expect that we don't want to map all the regions 
> of the hostbridges in dom0 (including the BARs).
>
> Can you clarify it?
We only want to trap ECAM, not MMIOs and any other memory regions as the bridge 
is

initialized and used by Domain-0 completely. But at the same time we want to 
trap all

configuration space access, so we can see what is happening to it.

>
>> + >       if ( need_mapping )
>>       {
>>           res = map_regions_p2mt(d,
>> diff --git a/xen/arch/arm/pci/ecam.c b/xen/arch/arm/pci/ecam.c
>> index 92ecb2e0762b..d32efb7fcbd0 100644
>> --- a/xen/arch/arm/pci/ecam.c
>> +++ b/xen/arch/arm/pci/ecam.c
>> @@ -52,6 +52,22 @@ static int pci_ecam_register_mmio_handler(struct domain 
>> *d,
>>       return 0;
>>   }
>>   +static int pci_ecam_need_p2m_mapping(struct domain *d,
>> +                                     struct pci_host_bridge *bridge,
>> +                                     uint64_t addr, uint64_t len)
>> +{
>> +    struct pci_config_window *cfg = bridge->sysdata;
>> +
>> +    if ( !is_hardware_domain(d) )
>> +        return true;
>
> I am a bit puzzled with this check. If the ECAM has been initialized by Xen, 
> then I believe we cannot expose it to any domain at all.
You are right, this check needs to be removed as this function is only called 
for Domain-0

>
>> +
>> +    /*
>> +     * We do not want ECAM address space to be mapped in domain's p2m,
>> +     * so we can trap access to it.
>> +     */
>> +    return cfg->phys_addr != addr;
>> +}
>> +
>>   /* ECAM ops */
>>   const struct pci_ecam_ops pci_generic_ecam_ops = {
>>       .bus_shift  = 20,
>> @@ -60,6 +76,7 @@ const struct pci_ecam_ops pci_generic_ecam_ops = {
>>           .read                   = pci_generic_config_read,
>>           .write                  = pci_generic_config_write,
>>           .register_mmio_handler  = pci_ecam_register_mmio_handler,
>> +        .need_p2m_mapping       = pci_ecam_need_p2m_mapping,
>>       }
>>   };
>>   diff --git a/xen/arch/arm/pci/pci-host-common.c 
>> b/xen/arch/arm/pci/pci-host-common.c
>> index a89112bfbb7c..c04be636452d 100644
>> --- a/xen/arch/arm/pci/pci-host-common.c
>> +++ b/xen/arch/arm/pci/pci-host-common.c
>> @@ -334,6 +334,28 @@ int pci_host_iterate_bridges(struct domain *d,
>>       }
>>       return 0;
>>   }
>> +
>> +bool pci_host_bridge_need_p2m_mapping(struct domain *d,
>> +                                      const struct dt_device_node *node,
>> +                                      uint64_t addr, uint64_t len)
>> +{
>> +    struct pci_host_bridge *bridge;
>> +
>> +    list_for_each_entry( bridge, &pci_host_bridges, node )
>> +    {
>> +        if ( bridge->dt_node != node )
>> +            continue;
>> +
>> +        if ( !bridge->ops->need_p2m_mapping )
>> +            return true;
>> +
>> +        return bridge->ops->need_p2m_mapping(d, bridge, addr, len);
>> +    }
>> +    printk(XENLOG_ERR "Unable to find PCI bridge for %s segment %d, addr 
>> %lx\n",
>> +           node->full_name, bridge->segment, addr);
>> +    return true;
>> +}
>
> If you really need to map the hostbridges, then I would suggest to defer the 
> P2M mappings for all of them and then walk all the bridge in one go to do the 
> mappings.
>
> This would avoid going through the bridges every time during setup.

Well, this can be done, but: my implementation prevents mappings and what

you suggest will require unmapping. So, the cost in my solution is we need

to go over all the bridges (until we find the one we need) and in what you

suggest we'll need to unmap what we have just mapped.

I think preventing unneeded mappings is cheaper than unmapping afterwards.

>
>> +
>>   /*
>>    * Local variables:
>>    * mode: C
>> diff --git a/xen/include/asm-arm/pci.h b/xen/include/asm-arm/pci.h
>> index 2c7c7649e00f..9c28a4bdc4b7 100644
>> --- a/xen/include/asm-arm/pci.h
>> +++ b/xen/include/asm-arm/pci.h
>> @@ -82,6 +82,8 @@ struct pci_ops {
>>       int (*register_mmio_handler)(struct domain *d,
>>                                    struct pci_host_bridge *bridge,
>>                                    const struct mmio_handler_ops *ops);
>> +    int (*need_p2m_mapping)(struct domain *d, struct pci_host_bridge 
>> *bridge,
>> +                            uint64_t addr, uint64_t len);
>>   };
>>     /*
>> @@ -115,9 +117,19 @@ struct dt_device_node *pci_find_host_bridge_node(struct 
>> device *dev);
>>   int pci_host_iterate_bridges(struct domain *d,
>>                                int (*clb)(struct domain *d,
>>                                           struct pci_host_bridge *bridge));
>> +bool pci_host_bridge_need_p2m_mapping(struct domain *d,
>> +                                      const struct dt_device_node *node,
>> +                                      uint64_t addr, uint64_t len);
>>   #else   /*!CONFIG_HAS_PCI*/
>>     struct arch_pci_dev { };
>>   +static inline bool
>> +pci_host_bridge_need_p2m_mapping(struct domain *d,
>> +                                 const struct dt_device_node *node,
>> +                                 uint64_t addr, uint64_t len)
>> +{
>> +    return true;
>> +}
>>   #endif  /*!CONFIG_HAS_PCI*/
>>   #endif /* __ARM_PCI_H__ */
>>
>
> Cheers,
>
Thank you,

Oleksandr

 


Rackspace

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