All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot
@ 2019-06-26 13:37 Juergen Gross
  2019-06-27  8:28 ` Roger Pau Monné
  0 siblings, 1 reply; 4+ messages in thread
From: Juergen Gross @ 2019-06-26 13:37 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Ian Jackson, Wei Liu

After a reboot of a guest only the first pci device configuration will
be retrieved from Xenstore resulting in loss of any further assigned
passed through pci devices.

The main reason is that all passed through pci devices reside under a
common root device "0" in Xenstore. So when the device list is rebuilt
from Xenstore after a reboot the sub-devices below that root device
need to be selected instead of using the root device number as a
selector.

Fix that by adding a new member to struct libxl_device_type which when
set is used to get the number of devices. Add such a member for pci to
get the correct number of pci devices instead of implying it from the
number of pci root devices (which will always be 1).

While at it fix the type of libxl__device_pci_from_xs_be() to match
the one of the .from_xenstore member of struct libxl_device_type. This
fixes a latent bug checking the return value of a function returning
void.

Signed-off-by: Juergen Gross <jgross@suse.com>
Tested-by: Chao Gao <chao.gao@intel.com>
---
 tools/libxl/libxl_device.c   | 24 +++++++++++++++++++-----
 tools/libxl/libxl_internal.h |  2 ++
 tools/libxl/libxl_pci.c      | 35 ++++++++++++++++++++++++++---------
 3 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index db6c0203b7..a2569102ee 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -2026,6 +2026,7 @@ void *libxl__device_list(libxl__gc *gc, const struct libxl_device_type *dt,
     char *libxl_path;
     char **dir = NULL;
     unsigned int ndirs = 0;
+    unsigned int ndevs = 0;
     int rc;
 
     *num = 0;
@@ -2037,21 +2038,34 @@ void *libxl__device_list(libxl__gc *gc, const struct libxl_device_type *dt,
     dir = libxl__xs_directory(gc, XBT_NULL, libxl_path, &ndirs);
 
     if (dir && ndirs) {
-        list = libxl__malloc(NOGC, dt->dev_elem_size * ndirs);
+        if (dt->get_num) {
+            if (ndirs != 1) {
+                LOGD(ERROR, domid, "multiple entries in %s\n", libxl_path);
+                rc = ERROR_FAIL;
+                goto out;
+            }
+            rc = dt->get_num(gc, GCSPRINTF("%s/%s", libxl_path, *dir), &ndevs);
+            if (rc) goto out;
+        } else {
+            ndevs = ndirs;
+        }
+        list = libxl__malloc(NOGC, dt->dev_elem_size * ndevs);
         item = list;
 
-        while (*num < ndirs) {
+        while (*num < ndevs) {
             dt->init(item);
-            ++(*num);
 
             if (dt->from_xenstore) {
+                int nr = dt->get_num ? *num : atoi(*dir);
                 char *device_libxl_path = GCSPRINTF("%s/%s", libxl_path, *dir);
-                rc = dt->from_xenstore(gc, device_libxl_path, atoi(*dir), item);
+                rc = dt->from_xenstore(gc, device_libxl_path, nr, item);
                 if (rc) goto out;
             }
 
             item = (uint8_t *)item + dt->dev_elem_size;
-            ++dir;
+            ++(*num);
+            if (!dt->get_num)
+                ++dir;
         }
     }
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 3be5c644c1..a3102871f3 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3707,6 +3707,7 @@ typedef void (*device_merge_fn_t)(libxl_ctx *, void *, void *);
 typedef int (*device_dm_needed_fn_t)(void *, unsigned);
 typedef void (*device_update_config_fn_t)(libxl__gc *, void *, void *);
 typedef int (*device_update_devid_fn_t)(libxl__gc *, uint32_t, void *);
+typedef int (*device_get_num_fn_t)(libxl__gc *, const char *, unsigned int *);
 typedef int (*device_from_xenstore_fn_t)(libxl__gc *, const char *,
                                          libxl_devid, void *);
 typedef int (*device_set_xenstore_config_fn_t)(libxl__gc *, uint32_t, void *,
@@ -3730,6 +3731,7 @@ struct libxl_device_type {
     device_dm_needed_fn_t           dm_needed;
     device_update_config_fn_t       update_config;
     device_update_devid_fn_t        update_devid;
+    device_get_num_fn_t             get_num;
     device_from_xenstore_fn_t       from_xenstore;
     device_set_xenstore_config_fn_t set_xenstore_config;
 };
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 4ec6872798..03beb865d9 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -1547,12 +1547,13 @@ int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static void libxl__device_pci_from_xs_be(libxl__gc *gc,
-                                         const char *be_path,
-                                         int nr, libxl_device_pci *pci)
+static int libxl__device_pci_from_xs_be(libxl__gc *gc,
+                                        const char *be_path,
+                                        libxl_devid nr, void *data)
 {
     char *s;
     unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
+    libxl_device_pci *pci = data;
 
     s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, nr));
     sscanf(s, PCI_BDF, &domain, &bus, &dev, &func);
@@ -1582,24 +1583,39 @@ static void libxl__device_pci_from_xs_be(libxl__gc *gc,
             }
         } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
     }
+
+    return 0;
+}
+
+static int libxl__device_pci_get_num(libxl__gc *gc, const char *be_path,
+                                     unsigned int *num)
+{
+    char *num_devs;
+    int rc = 0;
+
+    num_devs = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num_devs", be_path));
+    if (!num_devs)
+        rc = ERROR_FAIL;
+    else
+        *num = atoi(num_devs);
+
+    return rc;
 }
 
 libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num)
 {
     GC_INIT(ctx);
-    char *be_path, *num_devs;
-    int n, i;
+    char *be_path;
+    unsigned int n, i;
     libxl_device_pci *pcidevs = NULL;
 
     *num = 0;
 
     be_path = libxl__domain_device_backend_path(gc, 0, domid, 0,
                                                 LIBXL__DEVICE_KIND_PCI);
-    num_devs = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num_devs", be_path));
-    if (!num_devs)
+    if (libxl__device_pci_get_num(gc, be_path, &n))
         goto out;
 
-    n = atoi(num_devs);
     pcidevs = calloc(n, sizeof(libxl_device_pci));
 
     for (i = 0; i < n; i++)
@@ -1688,7 +1704,8 @@ static int libxl_device_pci_compare(const libxl_device_pci *d1,
 #define libxl__device_pci_update_devid NULL
 
 DEFINE_DEVICE_TYPE_STRUCT_X(pcidev, pci, PCI,
-    .from_xenstore = (device_from_xenstore_fn_t)libxl__device_pci_from_xs_be,
+    .get_num = libxl__device_pci_get_num,
+    .from_xenstore = libxl__device_pci_from_xs_be,
 );
 
 /*
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot
  2019-06-26 13:37 [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot Juergen Gross
@ 2019-06-27  8:28 ` Roger Pau Monné
  2019-07-10 18:44   ` Ian Jackson
  0 siblings, 1 reply; 4+ messages in thread
From: Roger Pau Monné @ 2019-06-27  8:28 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Ian Jackson, Wei Liu

On Wed, Jun 26, 2019 at 03:37:26PM +0200, Juergen Gross wrote:
> After a reboot of a guest only the first pci device configuration will
> be retrieved from Xenstore resulting in loss of any further assigned
> passed through pci devices.
> 
> The main reason is that all passed through pci devices reside under a
> common root device "0" in Xenstore. So when the device list is rebuilt
> from Xenstore after a reboot the sub-devices below that root device
> need to be selected instead of using the root device number as a
> selector.
> 
> Fix that by adding a new member to struct libxl_device_type which when
> set is used to get the number of devices. Add such a member for pci to
> get the correct number of pci devices instead of implying it from the
> number of pci root devices (which will always be 1).
> 
> While at it fix the type of libxl__device_pci_from_xs_be() to match
> the one of the .from_xenstore member of struct libxl_device_type. This
> fixes a latent bug checking the return value of a function returning
> void.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Tested-by: Chao Gao <chao.gao@intel.com>

Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

Thanks!

> ---
>  tools/libxl/libxl_device.c   | 24 +++++++++++++++++++-----
>  tools/libxl/libxl_internal.h |  2 ++
>  tools/libxl/libxl_pci.c      | 35 ++++++++++++++++++++++++++---------
>  3 files changed, 47 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
> index db6c0203b7..a2569102ee 100644
> --- a/tools/libxl/libxl_device.c
> +++ b/tools/libxl/libxl_device.c
> @@ -2026,6 +2026,7 @@ void *libxl__device_list(libxl__gc *gc, const struct libxl_device_type *dt,
>      char *libxl_path;
>      char **dir = NULL;
>      unsigned int ndirs = 0;
> +    unsigned int ndevs = 0;

I think you could reduce the scope of ndevs...

>      int rc;
>  
>      *num = 0;
> @@ -2037,21 +2038,34 @@ void *libxl__device_list(libxl__gc *gc, const struct libxl_device_type *dt,
>      dir = libxl__xs_directory(gc, XBT_NULL, libxl_path, &ndirs);
>  
>      if (dir && ndirs) {

... by declaring it here.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot
  2019-06-27  8:28 ` Roger Pau Monné
@ 2019-07-10 18:44   ` Ian Jackson
  2019-07-23 20:57     ` Pasi Kärkkäinen
  0 siblings, 1 reply; 4+ messages in thread
From: Ian Jackson @ 2019-07-10 18:44 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Juergen Gross, xen-devel, Wei Liu

Roger Pau Monne writes ("Re: [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot"):
> On Wed, Jun 26, 2019 at 03:37:26PM +0200, Juergen Gross wrote:
> > Signed-off-by: Juergen Gross <jgross@suse.com>
> > Tested-by: Chao Gao <chao.gao@intel.com>
> 
> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

Committed, thanks.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot
  2019-07-10 18:44   ` Ian Jackson
@ 2019-07-23 20:57     ` Pasi Kärkkäinen
  0 siblings, 0 replies; 4+ messages in thread
From: Pasi Kärkkäinen @ 2019-07-23 20:57 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Juergen Gross, xen-devel, Wei Liu, Roger Pau Monne

Hello,

On Wed, Jul 10, 2019 at 07:44:08PM +0100, Ian Jackson wrote:
> Roger Pau Monne writes ("Re: [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot"):
> > On Wed, Jun 26, 2019 at 03:37:26PM +0200, Juergen Gross wrote:
> > > Signed-off-by: Juergen Gross <jgross@suse.com>
> > > Tested-by: Chao Gao <chao.gao@intel.com>
> > 
> > Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
> 
> Committed, thanks.
> 

I'd like to request backport of this commit to 4.12 branch.

Thanks,

-- Pasi

> Ian.
> 


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-07-23 20:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-26 13:37 [Xen-devel] [PATCH] libxl: fix pci device re-assigning after domain reboot Juergen Gross
2019-06-27  8:28 ` Roger Pau Monné
2019-07-10 18:44   ` Ian Jackson
2019-07-23 20:57     ` Pasi Kärkkäinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.