diff options
-rw-r--r-- | arch/x86/xen/enlighten.c | 9 | ||||
-rw-r--r-- | drivers/video/xen-fbfront.c | 19 | ||||
-rw-r--r-- | drivers/xen/events.c | 21 |
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, | |||
562 | static int xenfb_connect_backend(struct xenbus_device *dev, | 562 | static 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 | ||
618 | static void xenfb_disconnect_backend(struct xenfb_info *info) | 619 | static 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 | ||
171 | static unsigned int evtchn_from_irq(unsigned irq) | 171 | static 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); |