summaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/Kconfig22
-rw-r--r--drivers/xen/events.c2
-rw-r--r--drivers/xen/gntdev.c2
-rw-r--r--drivers/xen/grant-table.c13
-rw-r--r--drivers/xen/manage.c1
-rw-r--r--drivers/xen/xen-acpi-processor.c5
-rw-r--r--drivers/xen/xenbus/xenbus_probe_frontend.c69
7 files changed, 81 insertions, 33 deletions
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 73f1c99bc540..8d2501e604dd 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -183,15 +183,17 @@ config XEN_ACPI_PROCESSOR
depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ
default m
help
- This ACPI processor uploads Power Management information to the Xen hypervisor.
-
- To do that the driver parses the Power Management data and uploads said
- information to the Xen hypervisor. Then the Xen hypervisor can select the
- proper Cx and Pxx states. It also registers itslef as the SMM so that
- other drivers (such as ACPI cpufreq scaling driver) will not load.
-
- To compile this driver as a module, choose M here: the
- module will be called xen_acpi_processor If you do not know what to choose,
- select M here. If the CPUFREQ drivers are built in, select Y here.
+ This ACPI processor uploads Power Management information to the Xen
+ hypervisor.
+
+ To do that the driver parses the Power Management data and uploads
+ said information to the Xen hypervisor. Then the Xen hypervisor can
+ select the proper Cx and Pxx states. It also registers itslef as the
+ SMM so that other drivers (such as ACPI cpufreq scaling driver) will
+ not load.
+
+ To compile this driver as a module, choose M here: the module will be
+ called xen_acpi_processor If you do not know what to choose, select
+ M here. If the CPUFREQ drivers are built in, select Y here.
endmenu
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 4b33acd8ed4e..0a8a17cd80be 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -274,7 +274,7 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn)
static bool pirq_check_eoi_map(unsigned irq)
{
- return test_bit(irq, pirq_eoi_map);
+ return test_bit(pirq_from_irq(irq), pirq_eoi_map);
}
static bool pirq_needs_eoi_flag(unsigned irq)
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 99d8151c824a..1ffd03bf8e10 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -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;
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index b4d4eac761db..f100ce20b16b 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -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);
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 9e14ae6cd49c..412b96cc5305 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -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;
}
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index 174b5653cd8a..0b48579a9cd6 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -128,7 +128,10 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr)
pr_debug(" C%d: %s %d uS\n",
cx->type, cx->desc, (u32)cx->latency);
}
- } else
+ } else if (ret != -EINVAL)
+ /* EINVAL means the ACPI ID is incorrect - meaning the ACPI
+ * table is referencing a non-existing CPU - which can happen
+ * with broken ACPI tables. */
pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n",
ret, _pr->acpi_id);
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index f20c5f178b40..a31b54d48839 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -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,
- 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)
@@ -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)
- break;
- }
-
- schedule_timeout_interruptible(HZ/10);
- }
+ while (exists_non_essential_connecting_device(drv))
+ if (wait_loop(start, 30, &seconds_waited))
+ break;
+
+ /* Skips PVKB and PVFB check.*/
+ while (exists_essential_connecting_device(drv))
+ if (wait_loop(start, 270, &seconds_waited))
+ break;
if (seconds_waited)
printk("\n");