Commit 23d72926 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-5.13b-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fixes from Juergen Gross:

 - a fix for a boot regression when running as PV guest on hardware
   without NX support

 - a small series fixing a bug in the Xen pciback driver when
   configuring a PCI card with multiple virtual functions

* tag 'for-linus-5.13b-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen-pciback: reconfigure also from backend watch handler
  xen-pciback: redo VF placement in the virtual topology
  x86/Xen: swap NX determination and GDT setup on BSP
parents a3969ef4 c81d3d24
...@@ -1273,16 +1273,16 @@ asmlinkage __visible void __init xen_start_kernel(void) ...@@ -1273,16 +1273,16 @@ asmlinkage __visible void __init xen_start_kernel(void)
/* Get mfn list */ /* Get mfn list */
xen_build_dynamic_phys_to_machine(); xen_build_dynamic_phys_to_machine();
/* Work out if we support NX */
get_cpu_cap(&boot_cpu_data);
x86_configure_nx();
/* /*
* Set up kernel GDT and segment registers, mainly so that * Set up kernel GDT and segment registers, mainly so that
* -fstack-protector code can be executed. * -fstack-protector code can be executed.
*/ */
xen_setup_gdt(0); xen_setup_gdt(0);
/* Work out if we support NX */
get_cpu_cap(&boot_cpu_data);
x86_configure_nx();
/* Determine virtual and physical address sizes */ /* Determine virtual and physical address sizes */
get_cpu_address_sizes(&boot_cpu_data); get_cpu_address_sizes(&boot_cpu_data);
......
...@@ -70,7 +70,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, ...@@ -70,7 +70,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
struct pci_dev *dev, int devid, struct pci_dev *dev, int devid,
publish_pci_dev_cb publish_cb) publish_pci_dev_cb publish_cb)
{ {
int err = 0, slot, func = -1; int err = 0, slot, func = PCI_FUNC(dev->devfn);
struct pci_dev_entry *t, *dev_entry; struct pci_dev_entry *t, *dev_entry;
struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
...@@ -95,22 +95,25 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, ...@@ -95,22 +95,25 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
/* /*
* Keep multi-function devices together on the virtual PCI bus, except * Keep multi-function devices together on the virtual PCI bus, except
* virtual functions. * that we want to keep virtual functions at func 0 on their own. They
* aren't multi-function devices and hence their presence at func 0
* may cause guests to not scan the other functions.
*/ */
if (!dev->is_virtfn) { if (!dev->is_virtfn || func) {
for (slot = 0; slot < PCI_SLOT_MAX; slot++) { for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
if (list_empty(&vpci_dev->dev_list[slot])) if (list_empty(&vpci_dev->dev_list[slot]))
continue; continue;
t = list_entry(list_first(&vpci_dev->dev_list[slot]), t = list_entry(list_first(&vpci_dev->dev_list[slot]),
struct pci_dev_entry, list); struct pci_dev_entry, list);
if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn))
continue;
if (match_slot(dev, t->dev)) { if (match_slot(dev, t->dev)) {
dev_info(&dev->dev, "vpci: assign to virtual slot %d func %d\n", dev_info(&dev->dev, "vpci: assign to virtual slot %d func %d\n",
slot, PCI_FUNC(dev->devfn)); slot, func);
list_add_tail(&dev_entry->list, list_add_tail(&dev_entry->list,
&vpci_dev->dev_list[slot]); &vpci_dev->dev_list[slot]);
func = PCI_FUNC(dev->devfn);
goto unlock; goto unlock;
} }
} }
...@@ -123,7 +126,6 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, ...@@ -123,7 +126,6 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
slot); slot);
list_add_tail(&dev_entry->list, list_add_tail(&dev_entry->list,
&vpci_dev->dev_list[slot]); &vpci_dev->dev_list[slot]);
func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn);
goto unlock; goto unlock;
} }
} }
......
...@@ -359,7 +359,8 @@ static int xen_pcibk_publish_pci_root(struct xen_pcibk_device *pdev, ...@@ -359,7 +359,8 @@ static int xen_pcibk_publish_pci_root(struct xen_pcibk_device *pdev,
return err; 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 err = 0;
int num_devs; int num_devs;
...@@ -373,9 +374,7 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) ...@@ -373,9 +374,7 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev)
dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n"); dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n");
mutex_lock(&pdev->dev_lock); mutex_lock(&pdev->dev_lock);
/* Make sure we only reconfigure once */ if (xenbus_read_driver_state(pdev->xdev->nodename) != state)
if (xenbus_read_driver_state(pdev->xdev->nodename) !=
XenbusStateReconfiguring)
goto out; goto out;
err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d", err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
...@@ -500,6 +499,10 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) ...@@ -500,6 +499,10 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev)
} }
} }
if (state != XenbusStateReconfiguring)
/* Make sure we only reconfigure once. */
goto out;
err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured); err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured);
if (err) { if (err) {
xenbus_dev_fatal(pdev->xdev, err, xenbus_dev_fatal(pdev->xdev, err,
...@@ -525,7 +528,7 @@ static void xen_pcibk_frontend_changed(struct xenbus_device *xdev, ...@@ -525,7 +528,7 @@ static void xen_pcibk_frontend_changed(struct xenbus_device *xdev,
break; break;
case XenbusStateReconfiguring: case XenbusStateReconfiguring:
xen_pcibk_reconfigure(pdev); xen_pcibk_reconfigure(pdev, XenbusStateReconfiguring);
break; break;
case XenbusStateConnected: case XenbusStateConnected:
...@@ -664,6 +667,15 @@ static void xen_pcibk_be_watch(struct xenbus_watch *watch, ...@@ -664,6 +667,15 @@ static void xen_pcibk_be_watch(struct xenbus_watch *watch,
xen_pcibk_setup_backend(pdev); xen_pcibk_setup_backend(pdev);
break; 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: default:
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment