| From c81d3d24602540f65256f98831d0a25599ea6b87 Mon Sep 17 00:00:00 2001 |
| From: Jan Beulich <jbeulich@suse.com> |
| Date: Tue, 18 May 2021 18:14:07 +0200 |
| Subject: xen-pciback: reconfigure also from backend watch handler |
| |
| From: Jan Beulich <jbeulich@suse.com> |
| |
| commit c81d3d24602540f65256f98831d0a25599ea6b87 upstream. |
| |
| When multiple PCI devices get assigned to a guest right at boot, libxl |
| incrementally populates the backend tree. The writes for the first of |
| the devices trigger the backend watch. In turn xen_pcibk_setup_backend() |
| will set the XenBus state to Initialised, at which point no further |
| reconfigures would happen unless a device got hotplugged. Arrange for |
| reconfigure to also get triggered from the backend watch handler. |
| |
| Signed-off-by: Jan Beulich <jbeulich@suse.com> |
| Cc: stable@vger.kernel.org |
| Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> |
| Link: https://lore.kernel.org/r/2337cbd6-94b9-4187-9862-c03ea12e0c61@suse.com |
| Signed-off-by: Juergen Gross <jgross@suse.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/xen/xen-pciback/xenbus.c | 22 +++++++++++++++++----- |
| 1 file changed, 17 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/xen/xen-pciback/xenbus.c |
| +++ b/drivers/xen/xen-pciback/xenbus.c |
| @@ -357,7 +357,8 @@ out: |
| return err; |
| } |
| |
| -static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) |
| +static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev, |
| + enum xenbus_state state) |
| { |
| int err = 0; |
| int num_devs; |
| @@ -371,9 +372,7 @@ static int xen_pcibk_reconfigure(struct |
| dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n"); |
| |
| mutex_lock(&pdev->dev_lock); |
| - /* Make sure we only reconfigure once */ |
| - if (xenbus_read_driver_state(pdev->xdev->nodename) != |
| - XenbusStateReconfiguring) |
| + if (xenbus_read_driver_state(pdev->xdev->nodename) != state) |
| goto out; |
| |
| err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d", |
| @@ -500,6 +499,10 @@ static int xen_pcibk_reconfigure(struct |
| } |
| } |
| |
| + if (state != XenbusStateReconfiguring) |
| + /* Make sure we only reconfigure once. */ |
| + goto out; |
| + |
| err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured); |
| if (err) { |
| xenbus_dev_fatal(pdev->xdev, err, |
| @@ -525,7 +528,7 @@ static void xen_pcibk_frontend_changed(s |
| break; |
| |
| case XenbusStateReconfiguring: |
| - xen_pcibk_reconfigure(pdev); |
| + xen_pcibk_reconfigure(pdev, XenbusStateReconfiguring); |
| break; |
| |
| case XenbusStateConnected: |
| @@ -664,6 +667,15 @@ static void xen_pcibk_be_watch(struct xe |
| xen_pcibk_setup_backend(pdev); |
| break; |
| |
| + case XenbusStateInitialised: |
| + /* |
| + * We typically move to Initialised when the first device was |
| + * added. Hence subsequent devices getting added may need |
| + * reconfiguring. |
| + */ |
| + xen_pcibk_reconfigure(pdev, XenbusStateInitialised); |
| + break; |
| + |
| default: |
| break; |
| } |