aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/xen/enlighten.c9
-rw-r--r--drivers/video/xen-fbfront.c19
-rw-r--r--drivers/xen/events.c21
3 files changed, 35 insertions, 14 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 6aba2a23e2c3..7e8d3bc80af6 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1174,6 +1174,15 @@ asmlinkage void __init xen_start_kernel(void)
1174 1174
1175 xen_smp_init(); 1175 xen_smp_init();
1176 1176
1177#ifdef CONFIG_ACPI_NUMA
1178 /*
1179 * The pages we from Xen are not related to machine pages, so
1180 * any NUMA information the kernel tries to get from ACPI will
1181 * be meaningless. Prevent it from trying.
1182 */
1183 acpi_numa = -1;
1184#endif
1185
1177 pgd = (pgd_t *)xen_start_info->pt_base; 1186 pgd = (pgd_t *)xen_start_info->pt_base;
1178 1187
1179 if (!xen_initial_domain()) 1188 if (!xen_initial_domain())
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 4abb0b9ed653..3e6934d4bea8 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -562,26 +562,24 @@ static void xenfb_init_shared_page(struct xenfb_info *info,
562static int xenfb_connect_backend(struct xenbus_device *dev, 562static int xenfb_connect_backend(struct xenbus_device *dev,
563 struct xenfb_info *info) 563 struct xenfb_info *info)
564{ 564{
565 int ret, evtchn; 565 int ret, evtchn, irq;
566 struct xenbus_transaction xbt; 566 struct xenbus_transaction xbt;
567 567
568 ret = xenbus_alloc_evtchn(dev, &evtchn); 568 ret = xenbus_alloc_evtchn(dev, &evtchn);
569 if (ret) 569 if (ret)
570 return ret; 570 return ret;
571 ret = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, 571 irq = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler,
572 0, dev->devicetype, info); 572 0, dev->devicetype, info);
573 if (ret < 0) { 573 if (irq < 0) {
574 xenbus_free_evtchn(dev, evtchn); 574 xenbus_free_evtchn(dev, evtchn);
575 xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); 575 xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
576 return ret; 576 return irq;
577 } 577 }
578 info->irq = ret;
579
580 again: 578 again:
581 ret = xenbus_transaction_start(&xbt); 579 ret = xenbus_transaction_start(&xbt);
582 if (ret) { 580 if (ret) {
583 xenbus_dev_fatal(dev, ret, "starting transaction"); 581 xenbus_dev_fatal(dev, ret, "starting transaction");
584 return ret; 582 goto unbind_irq;
585 } 583 }
586 ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", 584 ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
587 virt_to_mfn(info->page)); 585 virt_to_mfn(info->page));
@@ -603,20 +601,25 @@ static int xenfb_connect_backend(struct xenbus_device *dev,
603 if (ret == -EAGAIN) 601 if (ret == -EAGAIN)
604 goto again; 602 goto again;
605 xenbus_dev_fatal(dev, ret, "completing transaction"); 603 xenbus_dev_fatal(dev, ret, "completing transaction");
606 return ret; 604 goto unbind_irq;
607 } 605 }
608 606
609 xenbus_switch_state(dev, XenbusStateInitialised); 607 xenbus_switch_state(dev, XenbusStateInitialised);
608 info->irq = irq;
610 return 0; 609 return 0;
611 610
612 error_xenbus: 611 error_xenbus:
613 xenbus_transaction_end(xbt, 1); 612 xenbus_transaction_end(xbt, 1);
614 xenbus_dev_fatal(dev, ret, "writing xenstore"); 613 xenbus_dev_fatal(dev, ret, "writing xenstore");
614 unbind_irq:
615 unbind_from_irqhandler(irq, info);
615 return ret; 616 return ret;
616} 617}
617 618
618static void xenfb_disconnect_backend(struct xenfb_info *info) 619static void xenfb_disconnect_backend(struct xenfb_info *info)
619{ 620{
621 /* Prevent xenfb refresh */
622 info->update_wanted = 0;
620 if (info->irq >= 0) 623 if (info->irq >= 0)
621 unbind_from_irqhandler(info->irq, info); 624 unbind_from_irqhandler(info->irq, info);
622 info->irq = -1; 625 info->irq = -1;
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 65f8637d13cf..74681478100a 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -170,6 +170,9 @@ static struct irq_info *info_for_irq(unsigned irq)
170 170
171static unsigned int evtchn_from_irq(unsigned irq) 171static unsigned int evtchn_from_irq(unsigned irq)
172{ 172{
173 if (unlikely(WARN(irq < 0 || irq >= nr_irqs, "Invalid irq %d!\n", irq)))
174 return 0;
175
173 return info_for_irq(irq)->evtchn; 176 return info_for_irq(irq)->evtchn;
174} 177}
175 178
@@ -405,15 +408,21 @@ static int find_unbound_irq(void)
405{ 408{
406 struct irq_data *data; 409 struct irq_data *data;
407 int irq, res; 410 int irq, res;
408 int start = get_nr_hw_irqs(); 411 int bottom = get_nr_hw_irqs();
412 int top = nr_irqs-1;
409 413
410 if (start == nr_irqs) 414 if (bottom == nr_irqs)
411 goto no_irqs; 415 goto no_irqs;
412 416
413 /* nr_irqs is a magic value. Must not use it.*/ 417 /* This loop starts from the top of IRQ space and goes down.
414 for (irq = nr_irqs-1; irq > start; irq--) { 418 * We need this b/c if we have a PCI device in a Xen PV guest
419 * we do not have an IO-APIC (though the backend might have them)
420 * mapped in. To not have a collision of physical IRQs with the Xen
421 * event channels start at the top of the IRQ space for virtual IRQs.
422 */
423 for (irq = top; irq > bottom; irq--) {
415 data = irq_get_irq_data(irq); 424 data = irq_get_irq_data(irq);
416 /* only 0->15 have init'd desc; handle irq > 16 */ 425 /* only 15->0 have init'd desc; handle irq > 16 */
417 if (!data) 426 if (!data)
418 break; 427 break;
419 if (data->chip == &no_irq_chip) 428 if (data->chip == &no_irq_chip)
@@ -424,7 +433,7 @@ static int find_unbound_irq(void)
424 return irq; 433 return irq;
425 } 434 }
426 435
427 if (irq == start) 436 if (irq == bottom)
428 goto no_irqs; 437 goto no_irqs;
429 438
430 res = irq_alloc_desc_at(irq, -1); 439 res = irq_alloc_desc_at(irq, -1);