Commit c1acb0ba authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'stable/for-linus-3.4-rc3-tag' of...

Merge tag 'stable/for-linus-3.4-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen

Pull xen fixes from Konrad Rzeszutek Wilk:
 - mechanism to work with misconfigured backends (where they are
   advertised but in reality don't exist).
 - two tiny compile warning fixes.
 - proper error handling in gnttab_resume
 - Not using VM_PFNMAP anymore to allow backends in the same domain.

* tag 'stable/for-linus-3.4-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  Revert "xen/p2m: m2p_find_override: use list_for_each_entry_safe"
  xen/resume: Fix compile warnings.
  xen/xenbus: Add quirk to deal with misconfigured backends.
  xen/blkback: Fix warning error.
  xen/p2m: m2p_find_override: use list_for_each_entry_safe
  xen/gntdev: do not set VM_PFNMAP
  xen/grant-table: add error-handling code on failure of gnttab_resume
parents 19244ad0 3d81acb1
...@@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info ...@@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info
"discard-secure", "%d", "discard-secure", "%d",
blkif->vbd.discard_secure); blkif->vbd.discard_secure);
if (err) { if (err) {
dev_warn(dev-dev, "writing discard-secure (%d)", err); dev_warn(&dev->dev, "writing discard-secure (%d)", err);
return; return;
} }
} }
......
...@@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) ...@@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND; vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
if (use_ptemod) if (use_ptemod)
vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; vma->vm_flags |= VM_DONTCOPY;
vma->vm_private_data = map; vma->vm_private_data = map;
......
...@@ -1029,6 +1029,7 @@ int gnttab_init(void) ...@@ -1029,6 +1029,7 @@ int gnttab_init(void)
int i; int i;
unsigned int max_nr_glist_frames, nr_glist_frames; unsigned int max_nr_glist_frames, nr_glist_frames;
unsigned int nr_init_grefs; unsigned int nr_init_grefs;
int ret;
nr_grant_frames = 1; nr_grant_frames = 1;
boot_max_nr_grant_frames = __max_nr_grant_frames(); boot_max_nr_grant_frames = __max_nr_grant_frames();
...@@ -1047,12 +1048,16 @@ int gnttab_init(void) ...@@ -1047,12 +1048,16 @@ int gnttab_init(void)
nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
for (i = 0; i < nr_glist_frames; i++) { for (i = 0; i < nr_glist_frames; i++) {
gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
if (gnttab_list[i] == NULL) if (gnttab_list[i] == NULL) {
ret = -ENOMEM;
goto ini_nomem; goto ini_nomem;
}
} }
if (gnttab_resume() < 0) if (gnttab_resume() < 0) {
return -ENODEV; ret = -ENODEV;
goto ini_nomem;
}
nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
...@@ -1070,7 +1075,7 @@ int gnttab_init(void) ...@@ -1070,7 +1075,7 @@ int gnttab_init(void)
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
free_page((unsigned long)gnttab_list[i]); free_page((unsigned long)gnttab_list[i]);
kfree(gnttab_list); kfree(gnttab_list);
return -ENOMEM; return ret;
} }
EXPORT_SYMBOL_GPL(gnttab_init); EXPORT_SYMBOL_GPL(gnttab_init);
......
...@@ -132,6 +132,7 @@ static void do_suspend(void) ...@@ -132,6 +132,7 @@ static void do_suspend(void)
err = dpm_suspend_end(PMSG_FREEZE); err = dpm_suspend_end(PMSG_FREEZE);
if (err) { if (err) {
printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); printk(KERN_ERR "dpm_suspend_end failed: %d\n", err);
si.cancelled = 0;
goto out_resume; goto out_resume;
} }
......
...@@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev) ...@@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev)
return xenbus_read_otherend_details(xendev, "backend-id", "backend"); return xenbus_read_otherend_details(xendev, "backend-id", "backend");
} }
static int is_device_connecting(struct device *dev, void *data) static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)
{ {
struct xenbus_device *xendev = to_xenbus_device(dev); struct xenbus_device *xendev = to_xenbus_device(dev);
struct device_driver *drv = data; struct device_driver *drv = data;
...@@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data) ...@@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data)
if (drv && (dev->driver != drv)) if (drv && (dev->driver != drv))
return 0; return 0;
if (ignore_nonessential) {
/* With older QEMU, for PVonHVM guests the guest config files
* could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0']
* which is nonsensical as there is no PV FB (there can be
* a PVKB) running as HVM guest. */
if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0))
return 0;
if ((strncmp(xendev->nodename, "device/vfb", 10) == 0))
return 0;
}
xendrv = to_xenbus_driver(dev->driver); xendrv = to_xenbus_driver(dev->driver);
return (xendev->state < XenbusStateConnected || return (xendev->state < XenbusStateConnected ||
(xendev->state == XenbusStateConnected && (xendev->state == XenbusStateConnected &&
xendrv->is_ready && !xendrv->is_ready(xendev))); xendrv->is_ready && !xendrv->is_ready(xendev)));
} }
static int essential_device_connecting(struct device *dev, void *data)
{
return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */);
}
static int non_essential_device_connecting(struct device *dev, void *data)
{
return is_device_connecting(dev, data, false);
}
static int exists_connecting_device(struct device_driver *drv) static int exists_essential_connecting_device(struct device_driver *drv)
{ {
return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
is_device_connecting); essential_device_connecting);
}
static int exists_non_essential_connecting_device(struct device_driver *drv)
{
return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
non_essential_device_connecting);
} }
static int print_device_status(struct device *dev, void *data) static int print_device_status(struct device *dev, void *data)
...@@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data) ...@@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data)
/* We only wait for device setup after most initcalls have run. */ /* We only wait for device setup after most initcalls have run. */
static int ready_to_wait_for_devices; static int ready_to_wait_for_devices;
static bool wait_loop(unsigned long start, unsigned int max_delay,
unsigned int *seconds_waited)
{
if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) {
if (!*seconds_waited)
printk(KERN_WARNING "XENBUS: Waiting for "
"devices to initialise: ");
*seconds_waited += 5;
printk("%us...", max_delay - *seconds_waited);
if (*seconds_waited == max_delay)
return true;
}
schedule_timeout_interruptible(HZ/10);
return false;
}
/* /*
* On a 5-minute timeout, wait for all devices currently configured. We need * On a 5-minute timeout, wait for all devices currently configured. We need
* to do this to guarantee that the filesystems and / or network devices * to do this to guarantee that the filesystems and / or network devices
...@@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv) ...@@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv)
if (!ready_to_wait_for_devices || !xen_domain()) if (!ready_to_wait_for_devices || !xen_domain())
return; return;
while (exists_connecting_device(drv)) { while (exists_non_essential_connecting_device(drv))
if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { if (wait_loop(start, 30, &seconds_waited))
if (!seconds_waited) break;
printk(KERN_WARNING "XENBUS: Waiting for "
"devices to initialise: "); /* Skips PVKB and PVFB check.*/
seconds_waited += 5; while (exists_essential_connecting_device(drv))
printk("%us...", 300 - seconds_waited); if (wait_loop(start, 270, &seconds_waited))
if (seconds_waited == 300) break;
break;
}
schedule_timeout_interruptible(HZ/10);
}
if (seconds_waited) if (seconds_waited)
printk("\n"); printk("\n");
......
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