aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/pci/xen.c6
-rw-r--r--arch/x86/xen/enlighten.c57
-rw-r--r--arch/x86/xen/smp.c21
-rw-r--r--arch/x86/xen/spinlock.c25
-rw-r--r--arch/x86/xen/time.c13
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/xen/events.c33
-rw-r--r--drivers/xen/xen-acpi-processor.c82
-rw-r--r--include/xen/events.h3
9 files changed, 188 insertions, 54 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 94e76620460f..4a9be6ddf054 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -177,7 +177,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
177 goto error; 177 goto error;
178 i = 0; 178 i = 0;
179 list_for_each_entry(msidesc, &dev->msi_list, list) { 179 list_for_each_entry(msidesc, &dev->msi_list, list) {
180 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, 180 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
181 (type == PCI_CAP_ID_MSIX) ? 181 (type == PCI_CAP_ID_MSIX) ?
182 "pcifront-msi-x" : 182 "pcifront-msi-x" :
183 "pcifront-msi", 183 "pcifront-msi",
@@ -244,7 +244,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
244 dev_dbg(&dev->dev, 244 dev_dbg(&dev->dev,
245 "xen: msi already bound to pirq=%d\n", pirq); 245 "xen: msi already bound to pirq=%d\n", pirq);
246 } 246 }
247 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0, 247 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
248 (type == PCI_CAP_ID_MSIX) ? 248 (type == PCI_CAP_ID_MSIX) ?
249 "msi-x" : "msi", 249 "msi-x" : "msi",
250 DOMID_SELF); 250 DOMID_SELF);
@@ -326,7 +326,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
326 } 326 }
327 327
328 ret = xen_bind_pirq_msi_to_irq(dev, msidesc, 328 ret = xen_bind_pirq_msi_to_irq(dev, msidesc,
329 map_irq.pirq, map_irq.index, 329 map_irq.pirq,
330 (type == PCI_CAP_ID_MSIX) ? 330 (type == PCI_CAP_ID_MSIX) ?
331 "msi-x" : "msi", 331 "msi-x" : "msi",
332 domid); 332 domid);
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index c8e1c7b95c3b..ddbd54a9b845 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -31,6 +31,7 @@
31#include <linux/pci.h> 31#include <linux/pci.h>
32#include <linux/gfp.h> 32#include <linux/gfp.h>
33#include <linux/memblock.h> 33#include <linux/memblock.h>
34#include <linux/edd.h>
34 35
35#include <xen/xen.h> 36#include <xen/xen.h>
36#include <xen/events.h> 37#include <xen/events.h>
@@ -1306,6 +1307,55 @@ static const struct machine_ops xen_machine_ops __initconst = {
1306 .emergency_restart = xen_emergency_restart, 1307 .emergency_restart = xen_emergency_restart,
1307}; 1308};
1308 1309
1310static void __init xen_boot_params_init_edd(void)
1311{
1312#if IS_ENABLED(CONFIG_EDD)
1313 struct xen_platform_op op;
1314 struct edd_info *edd_info;
1315 u32 *mbr_signature;
1316 unsigned nr;
1317 int ret;
1318
1319 edd_info = boot_params.eddbuf;
1320 mbr_signature = boot_params.edd_mbr_sig_buffer;
1321
1322 op.cmd = XENPF_firmware_info;
1323
1324 op.u.firmware_info.type = XEN_FW_DISK_INFO;
1325 for (nr = 0; nr < EDDMAXNR; nr++) {
1326 struct edd_info *info = edd_info + nr;
1327
1328 op.u.firmware_info.index = nr;
1329 info->params.length = sizeof(info->params);
1330 set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params,
1331 &info->params);
1332 ret = HYPERVISOR_dom0_op(&op);
1333 if (ret)
1334 break;
1335
1336#define C(x) info->x = op.u.firmware_info.u.disk_info.x
1337 C(device);
1338 C(version);
1339 C(interface_support);
1340 C(legacy_max_cylinder);
1341 C(legacy_max_head);
1342 C(legacy_sectors_per_track);
1343#undef C
1344 }
1345 boot_params.eddbuf_entries = nr;
1346
1347 op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE;
1348 for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) {
1349 op.u.firmware_info.index = nr;
1350 ret = HYPERVISOR_dom0_op(&op);
1351 if (ret)
1352 break;
1353 mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature;
1354 }
1355 boot_params.edd_mbr_sig_buf_entries = nr;
1356#endif
1357}
1358
1309/* 1359/*
1310 * Set up the GDT and segment registers for -fstack-protector. Until 1360 * Set up the GDT and segment registers for -fstack-protector. Until
1311 * we do this, we have to be careful not to call any stack-protected 1361 * we do this, we have to be careful not to call any stack-protected
@@ -1508,6 +1558,8 @@ asmlinkage void __init xen_start_kernel(void)
1508 /* Avoid searching for BIOS MP tables */ 1558 /* Avoid searching for BIOS MP tables */
1509 x86_init.mpparse.find_smp_config = x86_init_noop; 1559 x86_init.mpparse.find_smp_config = x86_init_noop;
1510 x86_init.mpparse.get_smp_config = x86_init_uint_noop; 1560 x86_init.mpparse.get_smp_config = x86_init_uint_noop;
1561
1562 xen_boot_params_init_edd();
1511 } 1563 }
1512#ifdef CONFIG_PCI 1564#ifdef CONFIG_PCI
1513 /* PCI BIOS service won't work from a PV guest. */ 1565 /* PCI BIOS service won't work from a PV guest. */
@@ -1589,8 +1641,11 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
1589 switch (action) { 1641 switch (action) {
1590 case CPU_UP_PREPARE: 1642 case CPU_UP_PREPARE:
1591 xen_vcpu_setup(cpu); 1643 xen_vcpu_setup(cpu);
1592 if (xen_have_vector_callback) 1644 if (xen_have_vector_callback) {
1593 xen_init_lock_cpu(cpu); 1645 xen_init_lock_cpu(cpu);
1646 if (xen_feature(XENFEAT_hvm_safe_pvclock))
1647 xen_setup_timer(cpu);
1648 }
1594 break; 1649 break;
1595 default: 1650 default:
1596 break; 1651 break;
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 09ea61d2e02f..0d466d7c7175 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -144,6 +144,13 @@ static int xen_smp_intr_init(unsigned int cpu)
144 goto fail; 144 goto fail;
145 per_cpu(xen_callfuncsingle_irq, cpu) = rc; 145 per_cpu(xen_callfuncsingle_irq, cpu) = rc;
146 146
147 /*
148 * The IRQ worker on PVHVM goes through the native path and uses the
149 * IPI mechanism.
150 */
151 if (xen_hvm_domain())
152 return 0;
153
147 callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); 154 callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu);
148 rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, 155 rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR,
149 cpu, 156 cpu,
@@ -167,6 +174,9 @@ static int xen_smp_intr_init(unsigned int cpu)
167 if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0) 174 if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0)
168 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), 175 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu),
169 NULL); 176 NULL);
177 if (xen_hvm_domain())
178 return rc;
179
170 if (per_cpu(xen_irq_work, cpu) >= 0) 180 if (per_cpu(xen_irq_work, cpu) >= 0)
171 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); 181 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
172 182
@@ -418,7 +428,7 @@ static int xen_cpu_disable(void)
418 428
419static void xen_cpu_die(unsigned int cpu) 429static void xen_cpu_die(unsigned int cpu)
420{ 430{
421 while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { 431 while (xen_pv_domain() && HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) {
422 current->state = TASK_UNINTERRUPTIBLE; 432 current->state = TASK_UNINTERRUPTIBLE;
423 schedule_timeout(HZ/10); 433 schedule_timeout(HZ/10);
424 } 434 }
@@ -426,7 +436,8 @@ static void xen_cpu_die(unsigned int cpu)
426 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); 436 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
427 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); 437 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
428 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); 438 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
429 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); 439 if (!xen_hvm_domain())
440 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
430 xen_uninit_lock_cpu(cpu); 441 xen_uninit_lock_cpu(cpu);
431 xen_teardown_timer(cpu); 442 xen_teardown_timer(cpu);
432} 443}
@@ -657,11 +668,7 @@ static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
657 668
658static void xen_hvm_cpu_die(unsigned int cpu) 669static void xen_hvm_cpu_die(unsigned int cpu)
659{ 670{
660 unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL); 671 xen_cpu_die(cpu);
661 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
662 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
663 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
664 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
665 native_cpu_die(cpu); 672 native_cpu_die(cpu);
666} 673}
667 674
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index f7a080ef0354..8b54603ce816 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -364,6 +364,16 @@ void __cpuinit xen_init_lock_cpu(int cpu)
364 int irq; 364 int irq;
365 const char *name; 365 const char *name;
366 366
367 WARN(per_cpu(lock_kicker_irq, cpu) > 0, "spinlock on CPU%d exists on IRQ%d!\n",
368 cpu, per_cpu(lock_kicker_irq, cpu));
369
370 /*
371 * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
372 * (xen: disable PV spinlocks on HVM)
373 */
374 if (xen_hvm_domain())
375 return;
376
367 name = kasprintf(GFP_KERNEL, "spinlock%d", cpu); 377 name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
368 irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, 378 irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
369 cpu, 379 cpu,
@@ -382,11 +392,26 @@ void __cpuinit xen_init_lock_cpu(int cpu)
382 392
383void xen_uninit_lock_cpu(int cpu) 393void xen_uninit_lock_cpu(int cpu)
384{ 394{
395 /*
396 * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
397 * (xen: disable PV spinlocks on HVM)
398 */
399 if (xen_hvm_domain())
400 return;
401
385 unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); 402 unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL);
403 per_cpu(lock_kicker_irq, cpu) = -1;
386} 404}
387 405
388void __init xen_init_spinlocks(void) 406void __init xen_init_spinlocks(void)
389{ 407{
408 /*
409 * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
410 * (xen: disable PV spinlocks on HVM)
411 */
412 if (xen_hvm_domain())
413 return;
414
390 BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); 415 BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t));
391 416
392 pv_lock_ops.spin_is_locked = xen_spin_is_locked; 417 pv_lock_ops.spin_is_locked = xen_spin_is_locked;
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 0296a9522501..3d88bfdf9e1c 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -377,7 +377,7 @@ static const struct clock_event_device xen_vcpuop_clockevent = {
377 377
378static const struct clock_event_device *xen_clockevent = 378static const struct clock_event_device *xen_clockevent =
379 &xen_timerop_clockevent; 379 &xen_timerop_clockevent;
380static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events); 380static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events) = { .irq = -1 };
381 381
382static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) 382static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
383{ 383{
@@ -401,6 +401,9 @@ void xen_setup_timer(int cpu)
401 struct clock_event_device *evt; 401 struct clock_event_device *evt;
402 int irq; 402 int irq;
403 403
404 evt = &per_cpu(xen_clock_events, cpu);
405 WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
406
404 printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); 407 printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
405 408
406 name = kasprintf(GFP_KERNEL, "timer%d", cpu); 409 name = kasprintf(GFP_KERNEL, "timer%d", cpu);
@@ -413,7 +416,6 @@ void xen_setup_timer(int cpu)
413 IRQF_FORCE_RESUME, 416 IRQF_FORCE_RESUME,
414 name, NULL); 417 name, NULL);
415 418
416 evt = &per_cpu(xen_clock_events, cpu);
417 memcpy(evt, xen_clockevent, sizeof(*evt)); 419 memcpy(evt, xen_clockevent, sizeof(*evt));
418 420
419 evt->cpumask = cpumask_of(cpu); 421 evt->cpumask = cpumask_of(cpu);
@@ -426,6 +428,7 @@ void xen_teardown_timer(int cpu)
426 BUG_ON(cpu == 0); 428 BUG_ON(cpu == 0);
427 evt = &per_cpu(xen_clock_events, cpu); 429 evt = &per_cpu(xen_clock_events, cpu);
428 unbind_from_irqhandler(evt->irq, NULL); 430 unbind_from_irqhandler(evt->irq, NULL);
431 evt->irq = -1;
429} 432}
430 433
431void xen_setup_cpu_clockevents(void) 434void xen_setup_cpu_clockevents(void)
@@ -497,7 +500,11 @@ static void xen_hvm_setup_cpu_clockevents(void)
497{ 500{
498 int cpu = smp_processor_id(); 501 int cpu = smp_processor_id();
499 xen_setup_runstate_info(cpu); 502 xen_setup_runstate_info(cpu);
500 xen_setup_timer(cpu); 503 /*
504 * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence
505 * doing it xen_hvm_cpu_notify (which gets called by smp_init during
506 * early bootup and also during CPU hotplug events).
507 */
501 xen_setup_cpu_clockevents(); 508 xen_setup_cpu_clockevents();
502} 509}
503 510
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4c1546f71d56..09394657926e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2277,7 +2277,7 @@ config XEN_FBDEV_FRONTEND
2277 select FB_SYS_IMAGEBLIT 2277 select FB_SYS_IMAGEBLIT
2278 select FB_SYS_FOPS 2278 select FB_SYS_FOPS
2279 select FB_DEFERRED_IO 2279 select FB_DEFERRED_IO
2280 select INPUT_XEN_KBDDEV_FRONTEND 2280 select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
2281 select XEN_XENBUS_FRONTEND 2281 select XEN_XENBUS_FRONTEND
2282 default y 2282 default y
2283 help 2283 help
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 2647ad8e1f19..d8cc8127f19c 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -85,8 +85,7 @@ enum xen_irq_type {
85 * event channel - irq->event channel mapping 85 * event channel - irq->event channel mapping
86 * cpu - cpu this event channel is bound to 86 * cpu - cpu this event channel is bound to
87 * index - type-specific information: 87 * index - type-specific information:
88 * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM 88 * PIRQ - physical IRQ, GSI, flags, and owner domain
89 * guest, or GSI (real passthrough IRQ) of the device.
90 * VIRQ - virq number 89 * VIRQ - virq number
91 * IPI - IPI vector 90 * IPI - IPI vector
92 * EVTCHN - 91 * EVTCHN -
@@ -105,7 +104,6 @@ struct irq_info {
105 struct { 104 struct {
106 unsigned short pirq; 105 unsigned short pirq;
107 unsigned short gsi; 106 unsigned short gsi;
108 unsigned char vector;
109 unsigned char flags; 107 unsigned char flags;
110 uint16_t domid; 108 uint16_t domid;
111 } pirq; 109 } pirq;
@@ -211,7 +209,6 @@ static void xen_irq_info_pirq_init(unsigned irq,
211 unsigned short evtchn, 209 unsigned short evtchn,
212 unsigned short pirq, 210 unsigned short pirq,
213 unsigned short gsi, 211 unsigned short gsi,
214 unsigned short vector,
215 uint16_t domid, 212 uint16_t domid,
216 unsigned char flags) 213 unsigned char flags)
217{ 214{
@@ -221,7 +218,6 @@ static void xen_irq_info_pirq_init(unsigned irq,
221 218
222 info->u.pirq.pirq = pirq; 219 info->u.pirq.pirq = pirq;
223 info->u.pirq.gsi = gsi; 220 info->u.pirq.gsi = gsi;
224 info->u.pirq.vector = vector;
225 info->u.pirq.domid = domid; 221 info->u.pirq.domid = domid;
226 info->u.pirq.flags = flags; 222 info->u.pirq.flags = flags;
227} 223}
@@ -519,6 +515,9 @@ static void xen_free_irq(unsigned irq)
519{ 515{
520 struct irq_info *info = irq_get_handler_data(irq); 516 struct irq_info *info = irq_get_handler_data(irq);
521 517
518 if (WARN_ON(!info))
519 return;
520
522 list_del(&info->list); 521 list_del(&info->list);
523 522
524 irq_set_handler_data(irq, NULL); 523 irq_set_handler_data(irq, NULL);
@@ -714,7 +713,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
714 goto out; 713 goto out;
715 } 714 }
716 715
717 xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector, DOMID_SELF, 716 xen_irq_info_pirq_init(irq, 0, pirq, gsi, DOMID_SELF,
718 shareable ? PIRQ_SHAREABLE : 0); 717 shareable ? PIRQ_SHAREABLE : 0);
719 718
720 pirq_query_unmask(irq); 719 pirq_query_unmask(irq);
@@ -762,8 +761,7 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
762} 761}
763 762
764int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, 763int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
765 int pirq, int vector, const char *name, 764 int pirq, const char *name, domid_t domid)
766 domid_t domid)
767{ 765{
768 int irq, ret; 766 int irq, ret;
769 767
@@ -776,7 +774,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
776 irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq, 774 irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq,
777 name); 775 name);
778 776
779 xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, domid, 0); 777 xen_irq_info_pirq_init(irq, 0, pirq, 0, domid, 0);
780 ret = irq_set_msi_desc(irq, msidesc); 778 ret = irq_set_msi_desc(irq, msidesc);
781 if (ret < 0) 779 if (ret < 0)
782 goto error_irq; 780 goto error_irq;
@@ -1008,6 +1006,9 @@ static void unbind_from_irq(unsigned int irq)
1008 int evtchn = evtchn_from_irq(irq); 1006 int evtchn = evtchn_from_irq(irq);
1009 struct irq_info *info = irq_get_handler_data(irq); 1007 struct irq_info *info = irq_get_handler_data(irq);
1010 1008
1009 if (WARN_ON(!info))
1010 return;
1011
1011 mutex_lock(&irq_mapping_update_lock); 1012 mutex_lock(&irq_mapping_update_lock);
1012 1013
1013 if (info->refcnt > 0) { 1014 if (info->refcnt > 0) {
@@ -1135,6 +1136,10 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
1135 1136
1136void unbind_from_irqhandler(unsigned int irq, void *dev_id) 1137void unbind_from_irqhandler(unsigned int irq, void *dev_id)
1137{ 1138{
1139 struct irq_info *info = irq_get_handler_data(irq);
1140
1141 if (WARN_ON(!info))
1142 return;
1138 free_irq(irq, dev_id); 1143 free_irq(irq, dev_id);
1139 unbind_from_irq(irq); 1144 unbind_from_irq(irq);
1140} 1145}
@@ -1457,6 +1462,9 @@ void rebind_evtchn_irq(int evtchn, int irq)
1457{ 1462{
1458 struct irq_info *info = info_for_irq(irq); 1463 struct irq_info *info = info_for_irq(irq);
1459 1464
1465 if (WARN_ON(!info))
1466 return;
1467
1460 /* Make sure the irq is masked, since the new event channel 1468 /* Make sure the irq is masked, since the new event channel
1461 will also be masked. */ 1469 will also be masked. */
1462 disable_irq(irq); 1470 disable_irq(irq);
@@ -1730,7 +1738,12 @@ void xen_poll_irq(int irq)
1730int xen_test_irq_shared(int irq) 1738int xen_test_irq_shared(int irq)
1731{ 1739{
1732 struct irq_info *info = info_for_irq(irq); 1740 struct irq_info *info = info_for_irq(irq);
1733 struct physdev_irq_status_query irq_status = { .irq = info->u.pirq.pirq }; 1741 struct physdev_irq_status_query irq_status;
1742
1743 if (WARN_ON(!info))
1744 return -ENOENT;
1745
1746 irq_status.irq = info->u.pirq.pirq;
1734 1747
1735 if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status)) 1748 if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
1736 return 0; 1749 return 0;
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index 90e34ac7e522..8abd7d579037 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -25,6 +25,7 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/syscore_ops.h>
28#include <acpi/acpi_bus.h> 29#include <acpi/acpi_bus.h>
29#include <acpi/acpi_drivers.h> 30#include <acpi/acpi_drivers.h>
30#include <acpi/processor.h> 31#include <acpi/processor.h>
@@ -51,9 +52,9 @@ static DEFINE_MUTEX(acpi_ids_mutex);
51/* Which ACPI ID we have processed from 'struct acpi_processor'. */ 52/* Which ACPI ID we have processed from 'struct acpi_processor'. */
52static unsigned long *acpi_ids_done; 53static unsigned long *acpi_ids_done;
53/* Which ACPI ID exist in the SSDT/DSDT processor definitions. */ 54/* Which ACPI ID exist in the SSDT/DSDT processor definitions. */
54static unsigned long __initdata *acpi_id_present; 55static unsigned long *acpi_id_present;
55/* And if there is an _CST definition (or a PBLK) for the ACPI IDs */ 56/* And if there is an _CST definition (or a PBLK) for the ACPI IDs */
56static unsigned long __initdata *acpi_id_cst_present; 57static unsigned long *acpi_id_cst_present;
57 58
58static int push_cxx_to_hypervisor(struct acpi_processor *_pr) 59static int push_cxx_to_hypervisor(struct acpi_processor *_pr)
59{ 60{
@@ -329,7 +330,7 @@ static unsigned int __init get_max_acpi_id(void)
329 * for_each_[present|online]_cpu macros which are banded to the virtual 330 * for_each_[present|online]_cpu macros which are banded to the virtual
330 * CPU amount. 331 * CPU amount.
331 */ 332 */
332static acpi_status __init 333static acpi_status
333read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) 334read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv)
334{ 335{
335 u32 acpi_id; 336 u32 acpi_id;
@@ -384,12 +385,16 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv)
384 385
385 return AE_OK; 386 return AE_OK;
386} 387}
387static int __init check_acpi_ids(struct acpi_processor *pr_backup) 388static int check_acpi_ids(struct acpi_processor *pr_backup)
388{ 389{
389 390
390 if (!pr_backup) 391 if (!pr_backup)
391 return -ENODEV; 392 return -ENODEV;
392 393
394 if (acpi_id_present && acpi_id_cst_present)
395 /* OK, done this once .. skip to uploading */
396 goto upload;
397
393 /* All online CPUs have been processed at this stage. Now verify 398 /* All online CPUs have been processed at this stage. Now verify
394 * whether in fact "online CPUs" == physical CPUs. 399 * whether in fact "online CPUs" == physical CPUs.
395 */ 400 */
@@ -408,6 +413,7 @@ static int __init check_acpi_ids(struct acpi_processor *pr_backup)
408 read_acpi_id, NULL, NULL, NULL); 413 read_acpi_id, NULL, NULL, NULL);
409 acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL); 414 acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL);
410 415
416upload:
411 if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) { 417 if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) {
412 unsigned int i; 418 unsigned int i;
413 for_each_set_bit(i, acpi_id_present, nr_acpi_bits) { 419 for_each_set_bit(i, acpi_id_present, nr_acpi_bits) {
@@ -417,10 +423,7 @@ static int __init check_acpi_ids(struct acpi_processor *pr_backup)
417 (void)upload_pm_data(pr_backup); 423 (void)upload_pm_data(pr_backup);
418 } 424 }
419 } 425 }
420 kfree(acpi_id_present); 426
421 acpi_id_present = NULL;
422 kfree(acpi_id_cst_present);
423 acpi_id_cst_present = NULL;
424 return 0; 427 return 0;
425} 428}
426static int __init check_prereq(void) 429static int __init check_prereq(void)
@@ -467,10 +470,47 @@ static void free_acpi_perf_data(void)
467 free_percpu(acpi_perf_data); 470 free_percpu(acpi_perf_data);
468} 471}
469 472
470static int __init xen_acpi_processor_init(void) 473static int xen_upload_processor_pm_data(void)
471{ 474{
472 struct acpi_processor *pr_backup = NULL; 475 struct acpi_processor *pr_backup = NULL;
473 unsigned int i; 476 unsigned int i;
477 int rc = 0;
478
479 pr_info(DRV_NAME "Uploading Xen processor PM info\n");
480
481 for_each_possible_cpu(i) {
482 struct acpi_processor *_pr;
483 _pr = per_cpu(processors, i /* APIC ID */);
484 if (!_pr)
485 continue;
486
487 if (!pr_backup) {
488 pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
489 if (pr_backup)
490 memcpy(pr_backup, _pr, sizeof(struct acpi_processor));
491 }
492 (void)upload_pm_data(_pr);
493 }
494
495 rc = check_acpi_ids(pr_backup);
496 kfree(pr_backup);
497
498 return rc;
499}
500
501static void xen_acpi_processor_resume(void)
502{
503 bitmap_zero(acpi_ids_done, nr_acpi_bits);
504 xen_upload_processor_pm_data();
505}
506
507static struct syscore_ops xap_syscore_ops = {
508 .resume = xen_acpi_processor_resume,
509};
510
511static int __init xen_acpi_processor_init(void)
512{
513 unsigned int i;
474 int rc = check_prereq(); 514 int rc = check_prereq();
475 515
476 if (rc) 516 if (rc)
@@ -514,27 +554,12 @@ static int __init xen_acpi_processor_init(void)
514 goto err_out; 554 goto err_out;
515 } 555 }
516 556
517 for_each_possible_cpu(i) { 557 rc = xen_upload_processor_pm_data();
518 struct acpi_processor *_pr;
519 _pr = per_cpu(processors, i /* APIC ID */);
520 if (!_pr)
521 continue;
522
523 if (!pr_backup) {
524 pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
525 if (pr_backup)
526 memcpy(pr_backup, _pr, sizeof(struct acpi_processor));
527 }
528 (void)upload_pm_data(_pr);
529 }
530 rc = check_acpi_ids(pr_backup);
531
532 kfree(pr_backup);
533 pr_backup = NULL;
534
535 if (rc) 558 if (rc)
536 goto err_unregister; 559 goto err_unregister;
537 560
561 register_syscore_ops(&xap_syscore_ops);
562
538 return 0; 563 return 0;
539err_unregister: 564err_unregister:
540 for_each_possible_cpu(i) { 565 for_each_possible_cpu(i) {
@@ -552,7 +577,10 @@ static void __exit xen_acpi_processor_exit(void)
552{ 577{
553 int i; 578 int i;
554 579
580 unregister_syscore_ops(&xap_syscore_ops);
555 kfree(acpi_ids_done); 581 kfree(acpi_ids_done);
582 kfree(acpi_id_present);
583 kfree(acpi_id_cst_present);
556 for_each_possible_cpu(i) { 584 for_each_possible_cpu(i) {
557 struct acpi_processor_performance *perf; 585 struct acpi_processor_performance *perf;
558 perf = per_cpu_ptr(acpi_perf_data, i); 586 perf = per_cpu_ptr(acpi_perf_data, i);
diff --git a/include/xen/events.h b/include/xen/events.h
index c6bfe01acf6b..b2b27c6a0f7b 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -90,8 +90,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
90int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); 90int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc);
91/* Bind an PSI pirq to an irq. */ 91/* Bind an PSI pirq to an irq. */
92int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, 92int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
93 int pirq, int vector, const char *name, 93 int pirq, const char *name, domid_t domid);
94 domid_t domid);
95#endif 94#endif
96 95
97/* De-allocates the above mentioned physical interrupt. */ 96/* De-allocates the above mentioned physical interrupt. */