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

Re: [PATCH v7 2/5] xen/arm: Enable the existing x86 virtual PCI support for ARM


  • To: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Bertrand Marquis <Bertrand.Marquis@xxxxxxx>
  • Date: Fri, 15 Oct 2021 15:50:59 +0000
  • Accept-language: en-GB, 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=0bGH/qu2dgSDtErA7z2J90g4PQX1c+73o5cjfXC4M2E=; b=M+1lqnzofTLv7Emql1yGFObODp2yhsJcX0waBQPC6QaoFo+bAHNVW67KXGDgQOQIYXi64o1B0verQY9tcYKoaFUEHgSvHy+IVlK2sz5rF2rK6w7gPEzHA3Rs1LCp+EZRgTm/C96mWVPrs3zyyEd7APZBs0lq0uzbMayBesJedmWXXJ9oTcmVqp93UJx9yEN/1BpuCWb71j8ZsCk7w47Ou6L1i2rAnUT3KF7QRPKASjJnxg3xjCnCmqtSorDHnze3RTjoFdMyMhG63Q9RSma23hajfZxNP1MVHMGYsmgs3x7SHgi3vssbmYlX2DHThlGXKYyg04a+NhqXvQjYzwOnZA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AjDk4WOcsuVq4saTb6wP/RPdvg2YUACttoRfsoPUbixAv7UomuuWrI07T9lUZ5tWFRwr6ydp6Hkc7ZjIQaUSRqN7JSfKk74FaYYAixl+JWGWwoWxaQyBsgJUcZ0SCiIEdlV9iCcya6B59crsDeDbOY/hmpC4duyCXZKwTAiqCGCda4dSV/GP59zC+wwHZTT6bm0IrL6WMC6VMzjM5w1sMJ79mlzVpi7asKTItx/mWWS/5DT/Dmf7TpmzY+BM9Y0AxsQOBRT1cXJX6ixuot0U8Zk3eGNaOPrl7LDKN1zqd6hZkjxmnJzfMJ1JR+bnytVKqFv9Z6/nBTMPEWc5pTcAgw==
  • Authentication-results-original: lists.xenproject.org; dkim=none (message not signed) header.d=none;lists.xenproject.org; dmarc=none action=none header.from=arm.com;
  • Cc: Ian Jackson <iwj@xxxxxxxxxxxxxx>, Rahul Singh <Rahul.Singh@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Wei Liu <wl@xxxxxxx>, Paul Durrant <paul@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Fri, 15 Oct 2021 15:51:20 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: lists.xenproject.org; dkim=none (message not signed) header.d=none;lists.xenproject.org; dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHXwcz8unryLt1qUEeMdpd7xMjDNavUNUuA
  • Thread-topic: [PATCH v7 2/5] xen/arm: Enable the existing x86 virtual PCI support for ARM

Hi,

> On 15 Oct 2021, at 14:59, Bertrand Marquis <bertrand.marquis@xxxxxxx> wrote:
> 
> From: Rahul Singh <rahul.singh@xxxxxxx>
> 
> The existing VPCI support available for X86 is adapted for Arm.
> When the device is added to XEN via the hyper call
> “PHYSDEVOP_pci_device_add”, VPCI handler for the config space
> access is added to the Xen to emulate the PCI devices config space.
> 
> A MMIO trap handler for the PCI ECAM space is registered in XEN
> so that when guest is trying to access the PCI config space,XEN
> will trap the access and emulate read/write using the VPCI and
> not the real PCI hardware.
> 
> For Dom0less systems scan_pci_devices() would be used to discover the
> PCI device in XEN and VPCI handler will be added during XEN boots.
> 
> This patch is also doing some small fixes to fix compilation errors on
> arm32 of vpci and prevent 64bit accesses on 32bit:
> - use %zu instead of lu in header.c for print
> - prevent 64bit accesses in vpci_access_allowed
> - ifdef out using CONFIG_64BIT handling of len 8 in
> vpci_ecam_{read/write}
> 
> Signed-off-by: Rahul Singh <rahul.singh@xxxxxxx>
> Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
> ---
> Changes in v7:
> - adapt to changes in vpci generic functions (name and type)
> - remove call to pci_cleanup_msi on error exit
> - move pci_add_handlers to be only done when pdev->domain is not NULL
> - Remove cast to unsigned long in header.c and use %zu for print
> - Fix non ascii chars in arch-arm.h
> - Use CONFIG_64BIT inside vpci_access_allowed to prevent 64bit access on
> 32bit platforms
> - Use CONFIG_64BIT to compile out 64bit cases in vpci_ecam_{read/write}
> Changes in v6:
> - Use new vpci_ecam_ helpers for PCI access
> - Do not set XEN_DOMCTL_CDF_vpci for dom0 for now (will be done in a
> future patch once everything is ready)
> - rename REGISTER_OFFSET to ECAM_REG_OFFSET and move it to pci.h
> - remove not needed local variables in vpci_mmio_write, the one in read
> has been kept to ensure proper compilation on arm32
> - move call to vpci_add_handlers before iommu init to simplify exit path
> - move call to pci_cleanup_msi in the out section of pci_add_device if
> pdev is not NULL and on error
> - initialize pdev to NULL to handle properly exit path call of
> pci_cleanup_msi
> - keep has_vpci to return false for now as CFG_vpci has been removed.
> Added a comment on top of the definition.
> - fix compilation errors on arm32 (print in header.c, cast missing in
> mmio_write.
> - local variable was kept in vpci_mmio_read on arm to prevent a cast
> error in arm32.
> Change in v5:
> - Add pci_cleanup_msi(pdev) incleanup part.
> - Added Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> Change in v4:
> - Move addition of XEN_DOMCTL_CDF_vpci flag to separate patch
> Change in v3:
> - Use is_pci_passthrough_enabled() in place of pci_passthrough_enabled 
> variable
> - Reject XEN_DOMCTL_CDF_vpci for x86 in arch_sanitise_domain_config()
> - Remove IS_ENABLED(CONFIG_HAS_VPCI) from has_vpci()
> Change in v2:
> - Add new XEN_DOMCTL_CDF_vpci flag
> - modify has_vpci() to include XEN_DOMCTL_CDF_vpci
> - enable vpci support when pci-passthough option is enabled.
> ---
> ---
> xen/arch/arm/Makefile         |  1 +
> xen/arch/arm/domain.c         |  4 ++
> xen/arch/arm/vpci.c           | 77 +++++++++++++++++++++++++++++++++++
> xen/arch/arm/vpci.h           | 36 ++++++++++++++++
> xen/drivers/passthrough/pci.c | 14 +++++++
> xen/drivers/vpci/header.c     |  2 +-
> xen/drivers/vpci/vpci.c       | 10 +++++
> xen/include/asm-arm/domain.h  |  1 +
> xen/include/public/arch-arm.h |  7 ++++
> xen/include/xen/pci.h         |  2 +
> 10 files changed, 153 insertions(+), 1 deletion(-)
> create mode 100644 xen/arch/arm/vpci.c
> create mode 100644 xen/arch/arm/vpci.h
> 
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index 64518848b2..07f634508e 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -7,6 +7,7 @@ ifneq ($(CONFIG_NO_PLAT),y)
> obj-y += platforms/
> endif
> obj-$(CONFIG_TEE) += tee/
> +obj-$(CONFIG_HAS_VPCI) += vpci.o
> 
> obj-$(CONFIG_HAS_ALTERNATIVE) += alternative.o
> obj-y += bootfdt.init.o
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index eef0661beb..96e1b23550 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -39,6 +39,7 @@
> #include <asm/vgic.h>
> #include <asm/vtimer.h>
> 
> +#include "vpci.h"
> #include "vuart.h"
> 
> DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
> @@ -773,6 +774,9 @@ int arch_domain_create(struct domain *d,
>     if ( is_hardware_domain(d) && (rc = domain_vuart_init(d)) )
>         goto fail;
> 
> +    if ( (rc = domain_vpci_init(d)) != 0 )
> +        goto fail;
> +
>     return 0;
> 
> fail:
> diff --git a/xen/arch/arm/vpci.c b/xen/arch/arm/vpci.c
> new file mode 100644
> index 0000000000..a312d02f3d
> --- /dev/null
> +++ b/xen/arch/arm/vpci.c
> @@ -0,0 +1,77 @@
> +/*
> + * xen/arch/arm/vpci.c
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#include <xen/sched.h>
> +#include <xen/vpci.h>
> +
> +#include <asm/mmio.h>
> +
> +static int vpci_mmio_read(struct vcpu *v, mmio_info_t *info,
> +                          register_t *r, void *p)
> +{
> +    pci_sbdf_t sbdf;
> +    /* data is needed to prevent a pointer cast on 32bit */
> +    unsigned long data;
> +
> +    /* We ignore segment part and always handle segment 0 */
> +    sbdf.sbdf = VCPI_ECAM_BDF(info->gpa);

Typo: s/VCPI/VPCI !!

Sorry for that.

Will fix in v8.

Cheers
Bertrand

> +
> +    if ( vpci_ecam_read(sbdf, ECAM_REG_OFFSET(info->gpa),
> +                        1U << info->dabt.size, &data) )
> +    {
> +        *r = data;
> +        return 1;
> +    }
> +
> +    *r = ~0ul;
> +
> +    return 0;
> +}
> +
> +static int vpci_mmio_write(struct vcpu *v, mmio_info_t *info,
> +                           register_t r, void *p)
> +{
> +    pci_sbdf_t sbdf;
> +
> +    /* We ignore segment part and always handle segment 0 */
> +    sbdf.sbdf = VCPI_ECAM_BDF(info->gpa);

Typo: s/VCPI/VPCI !

> +
> +    return vpci_ecam_write(sbdf, ECAM_REG_OFFSET(info->gpa),
> +                           1U << info->dabt.size, r);
> +}
> +
> +static const struct mmio_handler_ops vpci_mmio_handler = {
> +    .read  = vpci_mmio_read,
> +    .write = vpci_mmio_write,
> +};
> +
> +int domain_vpci_init(struct domain *d)
> +{
> +    if ( !has_vpci(d) )
> +        return 0;
> +
> +    register_mmio_handler(d, &vpci_mmio_handler,
> +                          GUEST_VPCI_ECAM_BASE, GUEST_VPCI_ECAM_SIZE, NULL);
> +
> +    return 0;
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> +
> diff --git a/xen/arch/arm/vpci.h b/xen/arch/arm/vpci.h
> new file mode 100644
> index 0000000000..d8a7b0e3e8
> --- /dev/null
> +++ b/xen/arch/arm/vpci.h
> @@ -0,0 +1,36 @@
> +/*
> + * xen/arch/arm/vpci.h
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef __ARCH_ARM_VPCI_H__
> +#define __ARCH_ARM_VPCI_H__
> +
> +#ifdef CONFIG_HAS_VPCI
> +int domain_vpci_init(struct domain *d);
> +#else
> +static inline int domain_vpci_init(struct domain *d)
> +{
> +    return 0;
> +}
> +#endif
> +
> +#endif /* __ARCH_ARM_VPCI_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
> index 3aa8c3175f..082892c8a2 100644
> --- a/xen/drivers/passthrough/pci.c
> +++ b/xen/drivers/passthrough/pci.c
> @@ -766,7 +766,21 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
>         list_add(&pdev->domain_list, &hardware_domain->pdev_list);
>     }
>     else
> +    {
> +#ifdef CONFIG_ARM
> +        /*
> +         * On ARM PCI devices discovery will be done by Dom0. Add vpci 
> handler
> +         * when Dom0 inform XEN to add the PCI devices in XEN.
> +         */
> +        ret = vpci_add_handlers(pdev);
> +        if ( ret )
> +        {
> +            printk(XENLOG_ERR "Setup of vPCI failed: %d\n", ret);
> +            goto out;
> +        }
> +#endif
>         iommu_enable_device(pdev);
> +    }
> 
>     pci_enable_acs(pdev);
> 
> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
> index f8cd55e7c0..40ff79c33f 100644
> --- a/xen/drivers/vpci/header.c
> +++ b/xen/drivers/vpci/header.c
> @@ -373,7 +373,7 @@ static void bar_write(const struct pci_dev *pdev, 
> unsigned int reg,
>         /* If the value written is the current one avoid printing a warning. 
> */
>         if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
>             gprintk(XENLOG_WARNING,
> -                    "%pp: ignored BAR %lu write with memory decoding 
> enabled\n",
> +                    "%pp: ignored BAR %zu write with memory decoding 
> enabled\n",
>                     &pdev->sbdf, bar - pdev->vpci->header.bars + hi);
>         return;
>     }
> diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
> index ef690f15a9..decf7d87a1 100644
> --- a/xen/drivers/vpci/vpci.c
> +++ b/xen/drivers/vpci/vpci.c
> @@ -485,6 +485,12 @@ bool vpci_access_allowed(unsigned int reg, unsigned int 
> len)
>     if ( len != 1 && len != 2 && len != 4 && len != 8 )
>         return false;
> 
> +#ifndef CONFIG_64BIT
> +    /* Prevent 64bit accesses on 32bit */
> +    if ( len == 8 )
> +        return false;
> +#endif
> +
>     /* Check that access is size aligned. */
>     if ( (reg & (len - 1)) )
>         return false;
> @@ -500,8 +506,10 @@ bool vpci_ecam_write(pci_sbdf_t sbdf, unsigned int reg, 
> unsigned int len,
>         return false;
> 
>     vpci_write(sbdf, reg, min(4u, len), data);
> +#ifdef CONFIG_64BIT
>     if ( len == 8 )
>         vpci_write(sbdf, reg + 4, 4, data >> 32);
> +#endif
> 
>     return true;
> }
> @@ -526,8 +534,10 @@ bool vpci_ecam_read(pci_sbdf_t sbdf, unsigned int reg, 
> unsigned int len,
>      *  4byte accesses.
>      */
>     *data = vpci_read(sbdf, reg, min(4u, len));
> +#ifdef CONFIG_64BIT
>     if ( len == 8 )
>         *data |= (uint64_t)vpci_read(sbdf, reg + 4, 4) << 32;
> +#endif
> 
>     return true;
> }
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 14e575288f..9b3647587a 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -263,6 +263,7 @@ static inline void arch_vcpu_block(struct vcpu *v) {}
> 
> #define arch_vm_assist_valid_mask(d) (1UL << VMASST_TYPE_runstate_update_flag)
> 
> +/* vPCI is not available on Arm */
> #define has_vpci(d)    ({ (void)(d); false; })
> 
> #endif /* __ASM_DOMAIN_H__ */
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index 96ead3de07..b4c615bcdf 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -418,6 +418,13 @@ typedef uint64_t xen_callback_t;
> #define GUEST_GICV3_GICR0_BASE     xen_mk_ullong(0x03020000) /* vCPU0..127 */
> #define GUEST_GICV3_GICR0_SIZE     xen_mk_ullong(0x01000000)
> 
> +/*
> + * 256 MB is reserved for VPCI configuration space based on calculation
> + * 256 buses x 32 devices x 8 functions x 4 KB = 256 MB
> + */
> +#define GUEST_VPCI_ECAM_BASE    xen_mk_ullong(0x10000000)
> +#define GUEST_VPCI_ECAM_SIZE    xen_mk_ullong(0x10000000)
> +
> /* ACPI tables physical address */
> #define GUEST_ACPI_BASE xen_mk_ullong(0x20000000)
> #define GUEST_ACPI_SIZE xen_mk_ullong(0x02000000)
> diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
> index 70ac25345c..b6d7e454f8 100644
> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -40,6 +40,8 @@
> #define PCI_SBDF3(s,b,df) \
>     ((pci_sbdf_t){ .sbdf = (((s) & 0xffff) << 16) | PCI_BDF2(b, df) })
> 
> +#define ECAM_REG_OFFSET(addr)  ((addr) & 0x00000fff)
> +
> typedef union {
>     uint32_t sbdf;
>     struct {
> -- 
> 2.25.1
> 
> 


 


Rackspace

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