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

Re: [RFC XEN PATCH v12 7/7] tools: Add new function to do PIRQ (un)map on PVH dom0


  • To: Anthony PERARD <anthony.perard@xxxxxxxxxx>
  • From: "Chen, Jiqian" <Jiqian.Chen@xxxxxxx>
  • Date: Tue, 9 Jul 2024 06:18:03 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.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=otgig24wvUbU2KKGmvwjjV4QW7HyNdIZiSY8ud4OmPI=; b=Q/U7iDkNpuznvPZZ70x/BTprNq7arCWTLS6csCMWKbYeM5CGtrpBcwQoyGPdFoOP22LBkAtOPu6/IRCICludVQL0UNVw/sjBhFTuG86jrpnJx9u3dpY62oHPKADIFJ24xefyy4U7DuPiEX0d+/rxMswiVzrmV/79ApsSQpgy7V7fLhvF4bWW4/ooLoES06qAQPvbIgB+5BSJ3pMptwvBFyksy8MhuCALRsouUENYOejlELQCAKtiO4ze4GVTPimV3YZnMCAkpGiQtc24emkSW2vw8U/8t9Le6X/cbyo4yi+W+O0lOnMYPpU/bAyMbUr2ReNshfdVXdY2EDcooC5F8w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=jFtYfVrdTlUst8vTpFP22vo1vMsfPN8S79yorHGJiEPhNT6KWaXrxkQEMh1SbkUgwVp2Cv/QZh9+XS3sFvmo0O71Cf/NYiqeD8MHFntgN33liwC0F3AE1atbXM1NkOz49BcDHMWFjKbQL7TC5J81UA+2ajP2fcEmSf7QqzoFMfnGMRZv00BpC9rtT1Dvh4bZRnGh2VAI0S+UPACyM2G43FkARvkh+P+z+8VIwgaumNpxvt5Y2ciHQu3FQqDYPixPQykNnIxGoFAU2/NJJCpn3RZsKfkuHJDbJoiR2FNy0sxslbAD4wtvIRPAhjT0XwJlQ6/jjzdU+DMlI94qfv7X2w==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, George Dunlap <gwd@xxxxxxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, "Daniel P . Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>, "Hildebrand, Stewart" <Stewart.Hildebrand@xxxxxxx>, "Huang, Ray" <Ray.Huang@xxxxxxx>, "Chen, Jiqian" <Jiqian.Chen@xxxxxxx>
  • Delivery-date: Tue, 09 Jul 2024 06:18:19 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHa0SvgOieTsdeaYkqG6oiA+zr1RbHs69sAgAFQmIA=
  • Thread-topic: [RFC XEN PATCH v12 7/7] tools: Add new function to do PIRQ (un)map on PVH dom0

On 2024/7/8 22:57, Anthony PERARD wrote:
> On Mon, Jul 08, 2024 at 07:41:24PM +0800, Jiqian Chen wrote:
>> diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c
>> index a4029e3ac810..d869bbec769e 100644
>> --- a/tools/libs/light/libxl_arm.c
>> +++ b/tools/libs/light/libxl_arm.c
>> @@ -1774,6 +1774,16 @@ void libxl__arch_update_domain_config(libxl__gc *gc,
>>  {
>>  }
>>  
>> +int libxl__arch_hvm_map_gsi(libxl__gc *gc, uint32_t sbdf, uint32_t domid)
>> +{
>> +    return -1;
> 
> It's best to return an ERROR_* for libxl error code instead of -1.
> ERROR_NI seems to be the one, it probably means not-implemented. Or
> maybe ERROR_INVAL would do to.
Seems ERROR_INVAL is more suitable. Will change in next version.

> 
>> +}
>> +
>> +int libxl__arch_hvm_unmap_gsi(libxl__gc *gc, uint32_t sbdf, uint32_t domid)
>> +{
>> +    return -1;
>> +}
>> +
>>  /*
>>   * Local variables:
>>   * mode: C
>> diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
>> index 96cb4da0794e..3d25997921cc 100644
>> --- a/tools/libs/light/libxl_pci.c
>> +++ b/tools/libs/light/libxl_pci.c
>> @@ -17,6 +17,7 @@
>>  #include "libxl_osdeps.h" /* must come before any other headers */
>>  
>>  #include "libxl_internal.h"
>> +#include "libxl_arch.h"
>>  
>>  #define PCI_BDF                "%04x:%02x:%02x.%01x"
>>  #define PCI_BDF_SHORT          "%02x:%02x.%01x"
>> @@ -1478,6 +1479,16 @@ static void pci_add_dm_done(libxl__egc *egc,
>>      fclose(f);
>>      if (!pci_supp_legacy_irq())
>>          goto out_no_irq;
>> +
>> +    /*
>> +     * When dom0 is PVH and mapping a x86 gsi to pirq for domU,
>> +     * should use gsi to grant irq permission.
>> +     */
>> +    if (!libxl__arch_hvm_map_gsi(gc, pci_encode_bdf(pci), domid))
> 
> Could you store the result of libxl__arch_hvm_map_gsi() in `rc', then
> test that in the condition?
Will change in next version.
> 
>> +        goto pci_permissive;
> 
> Why do you skip part of the function on success?
Because libxl__arch_hvm_map_gsi do the same thing for PVH dom0, and the 
following part is for PV dom0.
If libxl__arch_hvm_map_gsi success, it should skip the following part.

> But also, please avoid the "goto" coding style, in libxl, it's tolerated
> for error handling when used to skip to the end of function to have a
> single path (or error path) out of a function.
Maybe I should split the part " xc_domain_getinfo_single(ctx->xch, 
LIBXL_TOOLSTACK_DOMID, &info); " in libxl__arch_hvm_map_gsi to a single 
function.
Then I can distinguish PVH and PV, and do different things for them.

> 
>> +    else
>> +        LOGED(WARN, domid, "libxl__arch_hvm_map_gsi failed (err=%d)", 
>> errno);
> 
> No one reads logs unless there's a failure or something doesn't work. So
> here we just ignore failure returned by libxl__arch_hvm_map_gsi(), is it
> the right things to do? Usually, just ignoring error is wrong.
Will change in next version.
> 
> FYI: LOGE* already logs errno.
> 
>> +
>>      sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
>>                                  pci->bus, pci->dev, pci->func);
>>      f = fopen(sysfs_path, "r");
>> @@ -1505,6 +1516,7 @@ static void pci_add_dm_done(libxl__egc *egc,
>>      }
>>      fclose(f);
>>  
>> +pci_permissive:
>>      /* Don't restrict writes to the PCI config space from this VM */
>>      if (pci->permissive) {
>>          if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
>> @@ -2229,6 +2241,11 @@ skip_bar:
>>      if (!pci_supp_legacy_irq())
>>          goto skip_legacy_irq;
>>  
>> +    if (!libxl__arch_hvm_unmap_gsi(gc, pci_encode_bdf(pci), domid))
>> +        goto skip_legacy_irq;
>> +    else
>> +        LOGED(WARN, domid, "libxl__arch_hvm_unmap_gsi failed (err=%d)", 
>> errno);
>> +
>>      sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
>>                             pci->bus, pci->dev, pci->func);
>>  
>> diff --git a/tools/libs/light/libxl_x86.c b/tools/libs/light/libxl_x86.c
>> index 60643d6f5376..e7756d323cb6 100644
>> --- a/tools/libs/light/libxl_x86.c
>> +++ b/tools/libs/light/libxl_x86.c
>> @@ -879,6 +879,117 @@ void libxl__arch_update_domain_config(libxl__gc *gc,
>>                                   libxl_defbool_val(src->b_info.u.hvm.pirq));
>>  }
>>  
>> +struct pcidev_map_pirq {
>> +    uint32_t sbdf;
>> +    uint32_t pirq;
>> +    XEN_LIST_ENTRY(struct pcidev_map_pirq) entry;
>> +};
>> +
>> +static pthread_mutex_t pcidev_pirq_mutex = PTHREAD_MUTEX_INITIALIZER;
>> +static XEN_LIST_HEAD(, struct pcidev_map_pirq) pcidev_pirq_list =
>> +    XEN_LIST_HEAD_INITIALIZER(pcidev_pirq_list);
>> +
>> +int libxl__arch_hvm_map_gsi(libxl__gc *gc, uint32_t sbdf, uint32_t domid)
>> +{
>> +    int pirq = -1, gsi, r;
>> +    xc_domaininfo_t info;
>> +    struct pcidev_map_pirq *pcidev_pirq;
>> +    libxl_ctx *ctx = libxl__gc_owner(gc);
> 
> Instead of declaring "ctx", you can use the macro "CTX" when you need
> "ctx".
Will change in next version.

> 
>> +
>> +    r = xc_domain_getinfo_single(ctx->xch, LIBXL_TOOLSTACK_DOMID, &info);
>> +    if (r < 0) {
>> +        LOGED(ERROR, domid, "getdomaininfo failed (error=%d)", errno);
>> +        return r;
> 
> libxl_*() functions should return only libxl error code, that is return
> code from other libxl_* functions, useally store in 'rc', or one of ERROR_*.
OK, will change in next version.

> 
>> +    }
>> +    if ((info.flags & XEN_DOMINF_hvm_guest) &&
>> +        !(info.arch_config.emulation_flags & XEN_X86_EMU_USE_PIRQ)) {
>> +        gsi = xc_physdev_gsi_from_pcidev(ctx->xch, sbdf);
>> +        if (gsi < 0) {
>> +            return ERROR_FAIL;
>> +        }
>> +        r = xc_physdev_map_pirq(ctx->xch, domid, gsi, &pirq);
>> +        if (r < 0) {
>> +            LOGED(ERROR, domid, "xc_physdev_map_pirq gsi=%d (error=%d)",
>> +                  gsi, errno);
>> +            return r;
>> +        }
>> +        r = xc_domain_gsi_permission(ctx->xch, domid, gsi, 1);
>> +        if (r < 0) {
>> +            LOGED(ERROR, domid, "xc_domain_gsi_permission gsi=%d 
>> (error=%d)",
>> +                  gsi, errno);
>> +            return r;
>> +        }
>> +    } else {
>> +        return ERROR_FAIL;
> 
> Is it really an error?
> 
> I few values can be returned here,
>   * ERROR_INVAL meaing that the function was called on a dom0 that don't
>     do "GSI",
I think this is more suitable. And then the following code of PV can be done in 
pci_add_dm_done.

>   * 0, that is success, because the function check if it need to do
>     anything, and since there's nothing to do, we can return success.
> 
>> +    }
>> +
>> +    /* Save the pirq for the usage of unmapping */
>> +    pcidev_pirq = malloc(sizeof(struct pcidev_map_pirq));
>> +    if (!pcidev_pirq) {
>> +        LOGED(ERROR, domid, "no memory for saving pirq of pcidev info");
>> +        return ERROR_NOMEM;
>> +    }
>> +    pcidev_pirq->sbdf = sbdf;
>> +    pcidev_pirq->pirq = pirq;
>> +
>> +    assert(!pthread_mutex_lock(&pcidev_pirq_mutex));
>> +    XEN_LIST_INSERT_HEAD(&pcidev_pirq_list, pcidev_pirq, entry);
> 
> I don't think that's going to work as you expect. libxl isn't a daemon
> (or sometime it is but used for several domains), so anything store in
> memory will be lost, or would be shared with other guest.
> 
> Do you need this mappins sbdf<-> pirq ? 
I need to store the pirq that assigned to the gsi. Because 
libxl__arch_hvm_unmap_gsi need pirq to do xc_physdev_unmap_pirq

> Is there a way to query this information later from the environement? 
What I can think of is before xc_physdev_unmap_pirq, use xc_physdev_map_pirq to 
get the already mapped pirq, but I am not sure if it is suitable.

> If not, you will need to store the data somewhere else, probably in 
> "libxl_domain_config *d_config" as
> libxl can retrive the data with libxl__get_domain_configuration().
However, pirq is dynamically mapped during starting domU, it may not be 
suitable for saving in d_config.

> There's also the posibility to store that info in xenstore, but we
> should probably avoid that.
> 
> Thanks,
> 

-- 
Best regards,
Jiqian Chen.

 


Rackspace

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