Commit c1acb0ba authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info
				    "discard-secure", "%d",
				    blkif->vbd.discard_secure);
		if (err) {
			dev_warn(dev-dev, "writing discard-secure (%d)", err);
			dev_warn(&dev->dev, "writing discard-secure (%d)", err);
			return;
		}
	}
+1 −1
Original line number Diff line number Diff line
@@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
	vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;

	if (use_ptemod)
		vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP;
		vma->vm_flags |= VM_DONTCOPY;

	vma->vm_private_data = map;

+9 −4
Original line number Diff line number Diff line
@@ -1029,6 +1029,7 @@ int gnttab_init(void)
	int i;
	unsigned int max_nr_glist_frames, nr_glist_frames;
	unsigned int nr_init_grefs;
	int ret;

	nr_grant_frames = 1;
	boot_max_nr_grant_frames = __max_nr_grant_frames();
@@ -1047,12 +1048,16 @@ int gnttab_init(void)
	nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
	for (i = 0; i < nr_glist_frames; i++) {
		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;
		}
	}

	if (gnttab_resume() < 0)
		return -ENODEV;
	if (gnttab_resume() < 0) {
		ret = -ENODEV;
		goto ini_nomem;
	}

	nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;

@@ -1070,7 +1075,7 @@ int gnttab_init(void)
	for (i--; i >= 0; i--)
		free_page((unsigned long)gnttab_list[i]);
	kfree(gnttab_list);
	return -ENOMEM;
	return ret;
}
EXPORT_SYMBOL_GPL(gnttab_init);

+1 −0
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ static void do_suspend(void)
	err = dpm_suspend_end(PMSG_FREEZE);
	if (err) {
		printk(KERN_ERR "dpm_suspend_end failed: %d\n", err);
		si.cancelled = 0;
		goto out_resume;
	}

+53 −16
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev)
	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 device_driver *drv = data;
@@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data)
	if (drv && (dev->driver != drv))
		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);
	return (xendev->state < XenbusStateConnected ||
		(xendev->state == XenbusStateConnected &&
		 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,
				essential_device_connecting);
}
static int exists_non_essential_connecting_device(struct device_driver *drv)
{
	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
				is_device_connecting);
				non_essential_device_connecting);
}

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. */
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
 * 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)
	if (!ready_to_wait_for_devices || !xen_domain())
		return;

	while (exists_connecting_device(drv)) {
		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...", 300 - seconds_waited);
			if (seconds_waited == 300)
	while (exists_non_essential_connecting_device(drv))
		if (wait_loop(start, 30, &seconds_waited))
			break;
		}

		schedule_timeout_interruptible(HZ/10);
	}
	/* Skips PVKB and PVFB check.*/
	while (exists_essential_connecting_device(drv))
		if (wait_loop(start, 270, &seconds_waited))
			break;

	if (seconds_waited)
		printk("\n");