diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-30 17:01:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-30 17:01:18 -0400 |
commit | 3655b22de04e3635fe3a2d7b9529cb12609a9bd0 (patch) | |
tree | e9c55e77e44a6de74c62ee7d907a293d97033fd3 | |
parent | 5489e948dc0f41a249c109d74612bf5aceab8f38 (diff) | |
parent | 8d0b8801c9e4c2c6b20cdac74dbab16facce7653 (diff) |
Merge tag 'stable/for-linus-3.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
Pull Xen fixes from Konrad Rzeszutek Wilk:
- Use proper error paths
- Clean up APIC IPI usage (incorrect arguments)
- Delay XenBus frontend resume is backend (xenstored) is not running
- Fix build error with various combinations of CONFIG_
* tag 'stable/for-linus-3.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
xenbus_client.c: correct exit path for xenbus_map_ring_valloc_hvm
xen-pciback: more uses of cached MSI-X capability offset
xen: Clean up apic ipi interface
xenbus: save xenstore local status for later use
xenbus: delay xenbus frontend resume if xenstored is not running
xmem/tmem: fix 'undefined variable' build error.
-rw-r--r-- | arch/x86/xen/smp.c | 10 | ||||
-rw-r--r-- | arch/x86/xen/smp.h | 1 | ||||
-rw-r--r-- | drivers/xen/tmem.c | 2 | ||||
-rw-r--r-- | drivers/xen/xen-pciback/pci_stub.c | 4 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_client.c | 5 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_comms.h | 1 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_probe.c | 27 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_probe.h | 7 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_probe_frontend.c | 37 | ||||
-rw-r--r-- | include/xen/xenbus.h | 1 |
10 files changed, 68 insertions, 27 deletions
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 8ff37995d54e..fb44426fe931 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -576,24 +576,22 @@ void xen_send_IPI_mask_allbutself(const struct cpumask *mask, | |||
576 | { | 576 | { |
577 | unsigned cpu; | 577 | unsigned cpu; |
578 | unsigned int this_cpu = smp_processor_id(); | 578 | unsigned int this_cpu = smp_processor_id(); |
579 | int xen_vector = xen_map_vector(vector); | ||
579 | 580 | ||
580 | if (!(num_online_cpus() > 1)) | 581 | if (!(num_online_cpus() > 1) || (xen_vector < 0)) |
581 | return; | 582 | return; |
582 | 583 | ||
583 | for_each_cpu_and(cpu, mask, cpu_online_mask) { | 584 | for_each_cpu_and(cpu, mask, cpu_online_mask) { |
584 | if (this_cpu == cpu) | 585 | if (this_cpu == cpu) |
585 | continue; | 586 | continue; |
586 | 587 | ||
587 | xen_smp_send_call_function_single_ipi(cpu); | 588 | xen_send_IPI_one(cpu, xen_vector); |
588 | } | 589 | } |
589 | } | 590 | } |
590 | 591 | ||
591 | void xen_send_IPI_allbutself(int vector) | 592 | void xen_send_IPI_allbutself(int vector) |
592 | { | 593 | { |
593 | int xen_vector = xen_map_vector(vector); | 594 | xen_send_IPI_mask_allbutself(cpu_online_mask, vector); |
594 | |||
595 | if (xen_vector >= 0) | ||
596 | xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector); | ||
597 | } | 595 | } |
598 | 596 | ||
599 | static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) | 597 | static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) |
diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h index 8981a76d081a..c7c2d89efd76 100644 --- a/arch/x86/xen/smp.h +++ b/arch/x86/xen/smp.h | |||
@@ -5,7 +5,6 @@ extern void xen_send_IPI_mask(const struct cpumask *mask, | |||
5 | extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask, | 5 | extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask, |
6 | int vector); | 6 | int vector); |
7 | extern void xen_send_IPI_allbutself(int vector); | 7 | extern void xen_send_IPI_allbutself(int vector); |
8 | extern void physflat_send_IPI_allbutself(int vector); | ||
9 | extern void xen_send_IPI_all(int vector); | 8 | extern void xen_send_IPI_all(int vector); |
10 | extern void xen_send_IPI_self(int vector); | 9 | extern void xen_send_IPI_self(int vector); |
11 | 10 | ||
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 18e8bd8fa947..cc072c66c766 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c | |||
@@ -41,6 +41,8 @@ module_param(selfballooning, bool, S_IRUGO); | |||
41 | #ifdef CONFIG_FRONTSWAP | 41 | #ifdef CONFIG_FRONTSWAP |
42 | static bool frontswap __read_mostly = true; | 42 | static bool frontswap __read_mostly = true; |
43 | module_param(frontswap, bool, S_IRUGO); | 43 | module_param(frontswap, bool, S_IRUGO); |
44 | #else /* CONFIG_FRONTSWAP */ | ||
45 | #define frontswap (0) | ||
44 | #endif /* CONFIG_FRONTSWAP */ | 46 | #endif /* CONFIG_FRONTSWAP */ |
45 | 47 | ||
46 | #ifdef CONFIG_XEN_SELFBALLOONING | 48 | #ifdef CONFIG_XEN_SELFBALLOONING |
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index a2278ba7fb27..4e8ba38aa0c9 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
@@ -106,7 +106,7 @@ static void pcistub_device_release(struct kref *kref) | |||
106 | else | 106 | else |
107 | pci_restore_state(dev); | 107 | pci_restore_state(dev); |
108 | 108 | ||
109 | if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { | 109 | if (dev->msix_cap) { |
110 | struct physdev_pci_device ppdev = { | 110 | struct physdev_pci_device ppdev = { |
111 | .seg = pci_domain_nr(dev->bus), | 111 | .seg = pci_domain_nr(dev->bus), |
112 | .bus = dev->bus->number, | 112 | .bus = dev->bus->number, |
@@ -371,7 +371,7 @@ static int pcistub_init_device(struct pci_dev *dev) | |||
371 | if (err) | 371 | if (err) |
372 | goto config_release; | 372 | goto config_release; |
373 | 373 | ||
374 | if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { | 374 | if (dev->msix_cap) { |
375 | struct physdev_pci_device ppdev = { | 375 | struct physdev_pci_device ppdev = { |
376 | .seg = pci_domain_nr(dev->bus), | 376 | .seg = pci_domain_nr(dev->bus), |
377 | .bus = dev->bus->number, | 377 | .bus = dev->bus->number, |
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 61786be9138b..ec097d6f964d 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c | |||
@@ -534,7 +534,7 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, | |||
534 | 534 | ||
535 | err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr); | 535 | err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr); |
536 | if (err) | 536 | if (err) |
537 | goto out_err; | 537 | goto out_err_free_ballooned_pages; |
538 | 538 | ||
539 | spin_lock(&xenbus_valloc_lock); | 539 | spin_lock(&xenbus_valloc_lock); |
540 | list_add(&node->next, &xenbus_valloc_pages); | 540 | list_add(&node->next, &xenbus_valloc_pages); |
@@ -543,8 +543,9 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, | |||
543 | *vaddr = addr; | 543 | *vaddr = addr; |
544 | return 0; | 544 | return 0; |
545 | 545 | ||
546 | out_err: | 546 | out_err_free_ballooned_pages: |
547 | free_xenballooned_pages(1, &node->page); | 547 | free_xenballooned_pages(1, &node->page); |
548 | out_err: | ||
548 | kfree(node); | 549 | kfree(node); |
549 | return err; | 550 | return err; |
550 | } | 551 | } |
diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h index c8abd3b8a6c4..e74f9c1fbd80 100644 --- a/drivers/xen/xenbus/xenbus_comms.h +++ b/drivers/xen/xenbus/xenbus_comms.h | |||
@@ -45,6 +45,7 @@ int xb_wait_for_data_to_read(void); | |||
45 | int xs_input_avail(void); | 45 | int xs_input_avail(void); |
46 | extern struct xenstore_domain_interface *xen_store_interface; | 46 | extern struct xenstore_domain_interface *xen_store_interface; |
47 | extern int xen_store_evtchn; | 47 | extern int xen_store_evtchn; |
48 | extern enum xenstore_init xen_store_domain_type; | ||
48 | 49 | ||
49 | extern const struct file_operations xen_xenbus_fops; | 50 | extern const struct file_operations xen_xenbus_fops; |
50 | 51 | ||
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 3325884c693f..56cfaaa9d006 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -69,6 +69,9 @@ EXPORT_SYMBOL_GPL(xen_store_evtchn); | |||
69 | struct xenstore_domain_interface *xen_store_interface; | 69 | struct xenstore_domain_interface *xen_store_interface; |
70 | EXPORT_SYMBOL_GPL(xen_store_interface); | 70 | EXPORT_SYMBOL_GPL(xen_store_interface); |
71 | 71 | ||
72 | enum xenstore_init xen_store_domain_type; | ||
73 | EXPORT_SYMBOL_GPL(xen_store_domain_type); | ||
74 | |||
72 | static unsigned long xen_store_mfn; | 75 | static unsigned long xen_store_mfn; |
73 | 76 | ||
74 | static BLOCKING_NOTIFIER_HEAD(xenstore_chain); | 77 | static BLOCKING_NOTIFIER_HEAD(xenstore_chain); |
@@ -719,17 +722,11 @@ static int __init xenstored_local_init(void) | |||
719 | return err; | 722 | return err; |
720 | } | 723 | } |
721 | 724 | ||
722 | enum xenstore_init { | ||
723 | UNKNOWN, | ||
724 | PV, | ||
725 | HVM, | ||
726 | LOCAL, | ||
727 | }; | ||
728 | static int __init xenbus_init(void) | 725 | static int __init xenbus_init(void) |
729 | { | 726 | { |
730 | int err = 0; | 727 | int err = 0; |
731 | enum xenstore_init usage = UNKNOWN; | ||
732 | uint64_t v = 0; | 728 | uint64_t v = 0; |
729 | xen_store_domain_type = XS_UNKNOWN; | ||
733 | 730 | ||
734 | if (!xen_domain()) | 731 | if (!xen_domain()) |
735 | return -ENODEV; | 732 | return -ENODEV; |
@@ -737,29 +734,29 @@ static int __init xenbus_init(void) | |||
737 | xenbus_ring_ops_init(); | 734 | xenbus_ring_ops_init(); |
738 | 735 | ||
739 | if (xen_pv_domain()) | 736 | if (xen_pv_domain()) |
740 | usage = PV; | 737 | xen_store_domain_type = XS_PV; |
741 | if (xen_hvm_domain()) | 738 | if (xen_hvm_domain()) |
742 | usage = HVM; | 739 | xen_store_domain_type = XS_HVM; |
743 | if (xen_hvm_domain() && xen_initial_domain()) | 740 | if (xen_hvm_domain() && xen_initial_domain()) |
744 | usage = LOCAL; | 741 | xen_store_domain_type = XS_LOCAL; |
745 | if (xen_pv_domain() && !xen_start_info->store_evtchn) | 742 | if (xen_pv_domain() && !xen_start_info->store_evtchn) |
746 | usage = LOCAL; | 743 | xen_store_domain_type = XS_LOCAL; |
747 | if (xen_pv_domain() && xen_start_info->store_evtchn) | 744 | if (xen_pv_domain() && xen_start_info->store_evtchn) |
748 | xenstored_ready = 1; | 745 | xenstored_ready = 1; |
749 | 746 | ||
750 | switch (usage) { | 747 | switch (xen_store_domain_type) { |
751 | case LOCAL: | 748 | case XS_LOCAL: |
752 | err = xenstored_local_init(); | 749 | err = xenstored_local_init(); |
753 | if (err) | 750 | if (err) |
754 | goto out_error; | 751 | goto out_error; |
755 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 752 | xen_store_interface = mfn_to_virt(xen_store_mfn); |
756 | break; | 753 | break; |
757 | case PV: | 754 | case XS_PV: |
758 | xen_store_evtchn = xen_start_info->store_evtchn; | 755 | xen_store_evtchn = xen_start_info->store_evtchn; |
759 | xen_store_mfn = xen_start_info->store_mfn; | 756 | xen_store_mfn = xen_start_info->store_mfn; |
760 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 757 | xen_store_interface = mfn_to_virt(xen_store_mfn); |
761 | break; | 758 | break; |
762 | case HVM: | 759 | case XS_HVM: |
763 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); | 760 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); |
764 | if (err) | 761 | if (err) |
765 | goto out_error; | 762 | goto out_error; |
diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h index bb4f92ed8730..146f857a36f8 100644 --- a/drivers/xen/xenbus/xenbus_probe.h +++ b/drivers/xen/xenbus/xenbus_probe.h | |||
@@ -47,6 +47,13 @@ struct xen_bus_type { | |||
47 | struct bus_type bus; | 47 | struct bus_type bus; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | enum xenstore_init { | ||
51 | XS_UNKNOWN, | ||
52 | XS_PV, | ||
53 | XS_HVM, | ||
54 | XS_LOCAL, | ||
55 | }; | ||
56 | |||
50 | extern struct device_attribute xenbus_dev_attrs[]; | 57 | extern struct device_attribute xenbus_dev_attrs[]; |
51 | 58 | ||
52 | extern int xenbus_match(struct device *_dev, struct device_driver *_drv); | 59 | extern int xenbus_match(struct device *_dev, struct device_driver *_drv); |
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index 3159a37d966d..a7e25073de19 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include "xenbus_probe.h" | 29 | #include "xenbus_probe.h" |
30 | 30 | ||
31 | 31 | ||
32 | static struct workqueue_struct *xenbus_frontend_wq; | ||
33 | |||
32 | /* device/<type>/<id> => <type>-<id> */ | 34 | /* device/<type>/<id> => <type>-<id> */ |
33 | static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) | 35 | static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) |
34 | { | 36 | { |
@@ -89,9 +91,40 @@ static void backend_changed(struct xenbus_watch *watch, | |||
89 | xenbus_otherend_changed(watch, vec, len, 1); | 91 | xenbus_otherend_changed(watch, vec, len, 1); |
90 | } | 92 | } |
91 | 93 | ||
94 | static void xenbus_frontend_delayed_resume(struct work_struct *w) | ||
95 | { | ||
96 | struct xenbus_device *xdev = container_of(w, struct xenbus_device, work); | ||
97 | |||
98 | xenbus_dev_resume(&xdev->dev); | ||
99 | } | ||
100 | |||
101 | static int xenbus_frontend_dev_resume(struct device *dev) | ||
102 | { | ||
103 | /* | ||
104 | * If xenstored is running in this domain, we cannot access the backend | ||
105 | * state at the moment, so we need to defer xenbus_dev_resume | ||
106 | */ | ||
107 | if (xen_store_domain_type == XS_LOCAL) { | ||
108 | struct xenbus_device *xdev = to_xenbus_device(dev); | ||
109 | |||
110 | if (!xenbus_frontend_wq) { | ||
111 | pr_err("%s: no workqueue to process delayed resume\n", | ||
112 | xdev->nodename); | ||
113 | return -EFAULT; | ||
114 | } | ||
115 | |||
116 | INIT_WORK(&xdev->work, xenbus_frontend_delayed_resume); | ||
117 | queue_work(xenbus_frontend_wq, &xdev->work); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | return xenbus_dev_resume(dev); | ||
123 | } | ||
124 | |||
92 | static const struct dev_pm_ops xenbus_pm_ops = { | 125 | static const struct dev_pm_ops xenbus_pm_ops = { |
93 | .suspend = xenbus_dev_suspend, | 126 | .suspend = xenbus_dev_suspend, |
94 | .resume = xenbus_dev_resume, | 127 | .resume = xenbus_frontend_dev_resume, |
95 | .freeze = xenbus_dev_suspend, | 128 | .freeze = xenbus_dev_suspend, |
96 | .thaw = xenbus_dev_cancel, | 129 | .thaw = xenbus_dev_cancel, |
97 | .restore = xenbus_dev_resume, | 130 | .restore = xenbus_dev_resume, |
@@ -440,6 +473,8 @@ static int __init xenbus_probe_frontend_init(void) | |||
440 | 473 | ||
441 | register_xenstore_notifier(&xenstore_notifier); | 474 | register_xenstore_notifier(&xenstore_notifier); |
442 | 475 | ||
476 | xenbus_frontend_wq = create_workqueue("xenbus_frontend"); | ||
477 | |||
443 | return 0; | 478 | return 0; |
444 | } | 479 | } |
445 | subsys_initcall(xenbus_probe_frontend_init); | 480 | subsys_initcall(xenbus_probe_frontend_init); |
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h index 0a7515c1e3a4..569c07f2e344 100644 --- a/include/xen/xenbus.h +++ b/include/xen/xenbus.h | |||
@@ -70,6 +70,7 @@ struct xenbus_device { | |||
70 | struct device dev; | 70 | struct device dev; |
71 | enum xenbus_state state; | 71 | enum xenbus_state state; |
72 | struct completion down; | 72 | struct completion down; |
73 | struct work_struct work; | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | static inline struct xenbus_device *to_xenbus_device(struct device *dev) | 76 | static inline struct xenbus_device *to_xenbus_device(struct device *dev) |