diff options
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/Kconfig | 24 | ||||
-rw-r--r-- | drivers/xen/events.c | 2 | ||||
-rw-r--r-- | drivers/xen/gntdev.c | 2 | ||||
-rw-r--r-- | drivers/xen/grant-table.c | 13 | ||||
-rw-r--r-- | drivers/xen/manage.c | 1 | ||||
-rw-r--r-- | drivers/xen/tmem.c | 8 | ||||
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 6 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_probe_frontend.c | 69 |
8 files changed, 87 insertions, 38 deletions
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 94243136f6bf..8d2501e604dd 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig | |||
@@ -71,7 +71,7 @@ config XEN_DEV_EVTCHN | |||
71 | tristate "Xen /dev/xen/evtchn device" | 71 | tristate "Xen /dev/xen/evtchn device" |
72 | default y | 72 | default y |
73 | help | 73 | help |
74 | The evtchn driver allows a userspace process to triger event | 74 | The evtchn driver allows a userspace process to trigger event |
75 | channels and to receive notification of an event channel | 75 | channels and to receive notification of an event channel |
76 | firing. | 76 | firing. |
77 | If in doubt, say yes. | 77 | If in doubt, say yes. |
@@ -183,15 +183,17 @@ config XEN_ACPI_PROCESSOR | |||
183 | depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ | 183 | depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ |
184 | default m | 184 | default m |
185 | help | 185 | help |
186 | This ACPI processor uploads Power Management information to the Xen hypervisor. | 186 | This ACPI processor uploads Power Management information to the Xen |
187 | 187 | hypervisor. | |
188 | To do that the driver parses the Power Management data and uploads said | 188 | |
189 | information to the Xen hypervisor. Then the Xen hypervisor can select the | 189 | To do that the driver parses the Power Management data and uploads |
190 | proper Cx and Pxx states. It also registers itslef as the SMM so that | 190 | said information to the Xen hypervisor. Then the Xen hypervisor can |
191 | other drivers (such as ACPI cpufreq scaling driver) will not load. | 191 | select the proper Cx and Pxx states. It also registers itslef as the |
192 | 192 | SMM so that other drivers (such as ACPI cpufreq scaling driver) will | |
193 | To compile this driver as a module, choose M here: the | 193 | not load. |
194 | module will be called xen_acpi_processor If you do not know what to choose, | 194 | |
195 | select M here. If the CPUFREQ drivers are built in, select Y here. | 195 | To compile this driver as a module, choose M here: the module will be |
196 | called xen_acpi_processor If you do not know what to choose, select | ||
197 | M here. If the CPUFREQ drivers are built in, select Y here. | ||
196 | 198 | ||
197 | endmenu | 199 | endmenu |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index af8b8fbd9d88..7595581d032c 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -274,7 +274,7 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn) | |||
274 | 274 | ||
275 | static bool pirq_check_eoi_map(unsigned irq) | 275 | static bool pirq_check_eoi_map(unsigned irq) |
276 | { | 276 | { |
277 | return test_bit(irq, pirq_eoi_map); | 277 | return test_bit(pirq_from_irq(irq), pirq_eoi_map); |
278 | } | 278 | } |
279 | 279 | ||
280 | static bool pirq_needs_eoi_flag(unsigned irq) | 280 | 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) | |||
722 | vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND; | 722 | vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND; |
723 | 723 | ||
724 | if (use_ptemod) | 724 | if (use_ptemod) |
725 | vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; | 725 | vma->vm_flags |= VM_DONTCOPY; |
726 | 726 | ||
727 | vma->vm_private_data = map; | 727 | vma->vm_private_data = map; |
728 | 728 | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 487e468f9ded..0bfc1ef11259 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -1134,6 +1134,7 @@ int gnttab_init(void) | |||
1134 | int i; | 1134 | int i; |
1135 | unsigned int max_nr_glist_frames, nr_glist_frames; | 1135 | unsigned int max_nr_glist_frames, nr_glist_frames; |
1136 | unsigned int nr_init_grefs; | 1136 | unsigned int nr_init_grefs; |
1137 | int ret; | ||
1137 | 1138 | ||
1138 | nr_grant_frames = 1; | 1139 | nr_grant_frames = 1; |
1139 | boot_max_nr_grant_frames = __max_nr_grant_frames(); | 1140 | boot_max_nr_grant_frames = __max_nr_grant_frames(); |
@@ -1152,12 +1153,16 @@ int gnttab_init(void) | |||
1152 | nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; | 1153 | nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; |
1153 | for (i = 0; i < nr_glist_frames; i++) { | 1154 | for (i = 0; i < nr_glist_frames; i++) { |
1154 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); | 1155 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); |
1155 | if (gnttab_list[i] == NULL) | 1156 | if (gnttab_list[i] == NULL) { |
1157 | ret = -ENOMEM; | ||
1156 | goto ini_nomem; | 1158 | goto ini_nomem; |
1159 | } | ||
1157 | } | 1160 | } |
1158 | 1161 | ||
1159 | if (gnttab_resume() < 0) | 1162 | if (gnttab_resume() < 0) { |
1160 | return -ENODEV; | 1163 | ret = -ENODEV; |
1164 | goto ini_nomem; | ||
1165 | } | ||
1161 | 1166 | ||
1162 | nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; | 1167 | nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; |
1163 | 1168 | ||
@@ -1175,7 +1180,7 @@ int gnttab_init(void) | |||
1175 | for (i--; i >= 0; i--) | 1180 | for (i--; i >= 0; i--) |
1176 | free_page((unsigned long)gnttab_list[i]); | 1181 | free_page((unsigned long)gnttab_list[i]); |
1177 | kfree(gnttab_list); | 1182 | kfree(gnttab_list); |
1178 | return -ENOMEM; | 1183 | return ret; |
1179 | } | 1184 | } |
1180 | EXPORT_SYMBOL_GPL(gnttab_init); | 1185 | EXPORT_SYMBOL_GPL(gnttab_init); |
1181 | 1186 | ||
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) | |||
132 | err = dpm_suspend_end(PMSG_FREEZE); | 132 | err = dpm_suspend_end(PMSG_FREEZE); |
133 | if (err) { | 133 | if (err) { |
134 | printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); | 134 | printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); |
135 | si.cancelled = 0; | ||
135 | goto out_resume; | 136 | goto out_resume; |
136 | } | 137 | } |
137 | 138 | ||
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index dcb79521e6c8..89f264c67420 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c | |||
@@ -269,7 +269,7 @@ static inline struct tmem_oid oswiz(unsigned type, u32 ind) | |||
269 | } | 269 | } |
270 | 270 | ||
271 | /* returns 0 if the page was successfully put into frontswap, -1 if not */ | 271 | /* returns 0 if the page was successfully put into frontswap, -1 if not */ |
272 | static int tmem_frontswap_put_page(unsigned type, pgoff_t offset, | 272 | static int tmem_frontswap_store(unsigned type, pgoff_t offset, |
273 | struct page *page) | 273 | struct page *page) |
274 | { | 274 | { |
275 | u64 ind64 = (u64)offset; | 275 | u64 ind64 = (u64)offset; |
@@ -295,7 +295,7 @@ static int tmem_frontswap_put_page(unsigned type, pgoff_t offset, | |||
295 | * returns 0 if the page was successfully gotten from frontswap, -1 if | 295 | * returns 0 if the page was successfully gotten from frontswap, -1 if |
296 | * was not present (should never happen!) | 296 | * was not present (should never happen!) |
297 | */ | 297 | */ |
298 | static int tmem_frontswap_get_page(unsigned type, pgoff_t offset, | 298 | static int tmem_frontswap_load(unsigned type, pgoff_t offset, |
299 | struct page *page) | 299 | struct page *page) |
300 | { | 300 | { |
301 | u64 ind64 = (u64)offset; | 301 | u64 ind64 = (u64)offset; |
@@ -362,8 +362,8 @@ static int __init no_frontswap(char *s) | |||
362 | __setup("nofrontswap", no_frontswap); | 362 | __setup("nofrontswap", no_frontswap); |
363 | 363 | ||
364 | static struct frontswap_ops __initdata tmem_frontswap_ops = { | 364 | static struct frontswap_ops __initdata tmem_frontswap_ops = { |
365 | .put_page = tmem_frontswap_put_page, | 365 | .store = tmem_frontswap_store, |
366 | .get_page = tmem_frontswap_get_page, | 366 | .load = tmem_frontswap_load, |
367 | .invalidate_page = tmem_frontswap_flush_page, | 367 | .invalidate_page = tmem_frontswap_flush_page, |
368 | .invalidate_area = tmem_frontswap_flush_area, | 368 | .invalidate_area = tmem_frontswap_flush_area, |
369 | .init = tmem_frontswap_init | 369 | .init = tmem_frontswap_init |
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 174b5653cd8a..7ff2569e17ae 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <acpi/acpi_drivers.h> | 29 | #include <acpi/acpi_drivers.h> |
30 | #include <acpi/processor.h> | 30 | #include <acpi/processor.h> |
31 | 31 | ||
32 | #include <xen/xen.h> | ||
32 | #include <xen/interface/platform.h> | 33 | #include <xen/interface/platform.h> |
33 | #include <asm/xen/hypercall.h> | 34 | #include <asm/xen/hypercall.h> |
34 | 35 | ||
@@ -128,7 +129,10 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr) | |||
128 | pr_debug(" C%d: %s %d uS\n", | 129 | pr_debug(" C%d: %s %d uS\n", |
129 | cx->type, cx->desc, (u32)cx->latency); | 130 | cx->type, cx->desc, (u32)cx->latency); |
130 | } | 131 | } |
131 | } else | 132 | } else if (ret != -EINVAL) |
133 | /* EINVAL means the ACPI ID is incorrect - meaning the ACPI | ||
134 | * table is referencing a non-existing CPU - which can happen | ||
135 | * with broken ACPI tables. */ | ||
132 | pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n", | 136 | pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n", |
133 | ret, _pr->acpi_id); | 137 | ret, _pr->acpi_id); |
134 | 138 | ||
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) | |||
135 | return xenbus_read_otherend_details(xendev, "backend-id", "backend"); | 135 | return xenbus_read_otherend_details(xendev, "backend-id", "backend"); |
136 | } | 136 | } |
137 | 137 | ||
138 | static int is_device_connecting(struct device *dev, void *data) | 138 | static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential) |
139 | { | 139 | { |
140 | struct xenbus_device *xendev = to_xenbus_device(dev); | 140 | struct xenbus_device *xendev = to_xenbus_device(dev); |
141 | struct device_driver *drv = data; | 141 | struct device_driver *drv = data; |
@@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data) | |||
152 | if (drv && (dev->driver != drv)) | 152 | if (drv && (dev->driver != drv)) |
153 | return 0; | 153 | return 0; |
154 | 154 | ||
155 | if (ignore_nonessential) { | ||
156 | /* With older QEMU, for PVonHVM guests the guest config files | ||
157 | * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0'] | ||
158 | * which is nonsensical as there is no PV FB (there can be | ||
159 | * a PVKB) running as HVM guest. */ | ||
160 | |||
161 | if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0)) | ||
162 | return 0; | ||
163 | |||
164 | if ((strncmp(xendev->nodename, "device/vfb", 10) == 0)) | ||
165 | return 0; | ||
166 | } | ||
155 | xendrv = to_xenbus_driver(dev->driver); | 167 | xendrv = to_xenbus_driver(dev->driver); |
156 | return (xendev->state < XenbusStateConnected || | 168 | return (xendev->state < XenbusStateConnected || |
157 | (xendev->state == XenbusStateConnected && | 169 | (xendev->state == XenbusStateConnected && |
158 | xendrv->is_ready && !xendrv->is_ready(xendev))); | 170 | xendrv->is_ready && !xendrv->is_ready(xendev))); |
159 | } | 171 | } |
172 | static int essential_device_connecting(struct device *dev, void *data) | ||
173 | { | ||
174 | return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */); | ||
175 | } | ||
176 | static int non_essential_device_connecting(struct device *dev, void *data) | ||
177 | { | ||
178 | return is_device_connecting(dev, data, false); | ||
179 | } | ||
160 | 180 | ||
161 | static int exists_connecting_device(struct device_driver *drv) | 181 | static int exists_essential_connecting_device(struct device_driver *drv) |
162 | { | 182 | { |
163 | return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | 183 | return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, |
164 | is_device_connecting); | 184 | essential_device_connecting); |
185 | } | ||
186 | static int exists_non_essential_connecting_device(struct device_driver *drv) | ||
187 | { | ||
188 | return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | ||
189 | non_essential_device_connecting); | ||
165 | } | 190 | } |
166 | 191 | ||
167 | static int print_device_status(struct device *dev, void *data) | 192 | 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 | /* We only wait for device setup after most initcalls have run. */ | 217 | /* We only wait for device setup after most initcalls have run. */ |
193 | static int ready_to_wait_for_devices; | 218 | static int ready_to_wait_for_devices; |
194 | 219 | ||
220 | static bool wait_loop(unsigned long start, unsigned int max_delay, | ||
221 | unsigned int *seconds_waited) | ||
222 | { | ||
223 | if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) { | ||
224 | if (!*seconds_waited) | ||
225 | printk(KERN_WARNING "XENBUS: Waiting for " | ||
226 | "devices to initialise: "); | ||
227 | *seconds_waited += 5; | ||
228 | printk("%us...", max_delay - *seconds_waited); | ||
229 | if (*seconds_waited == max_delay) | ||
230 | return true; | ||
231 | } | ||
232 | |||
233 | schedule_timeout_interruptible(HZ/10); | ||
234 | |||
235 | return false; | ||
236 | } | ||
195 | /* | 237 | /* |
196 | * On a 5-minute timeout, wait for all devices currently configured. We need | 238 | * On a 5-minute timeout, wait for all devices currently configured. We need |
197 | * to do this to guarantee that the filesystems and / or network devices | 239 | * 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 | if (!ready_to_wait_for_devices || !xen_domain()) | 257 | if (!ready_to_wait_for_devices || !xen_domain()) |
216 | return; | 258 | return; |
217 | 259 | ||
218 | while (exists_connecting_device(drv)) { | 260 | while (exists_non_essential_connecting_device(drv)) |
219 | if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { | 261 | if (wait_loop(start, 30, &seconds_waited)) |
220 | if (!seconds_waited) | 262 | break; |
221 | printk(KERN_WARNING "XENBUS: Waiting for " | 263 | |
222 | "devices to initialise: "); | 264 | /* Skips PVKB and PVFB check.*/ |
223 | seconds_waited += 5; | 265 | while (exists_essential_connecting_device(drv)) |
224 | printk("%us...", 300 - seconds_waited); | 266 | if (wait_loop(start, 270, &seconds_waited)) |
225 | if (seconds_waited == 300) | 267 | break; |
226 | break; | ||
227 | } | ||
228 | |||
229 | schedule_timeout_interruptible(HZ/10); | ||
230 | } | ||
231 | 268 | ||
232 | if (seconds_waited) | 269 | if (seconds_waited) |
233 | printk("\n"); | 270 | printk("\n"); |