aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/Kconfig10
-rw-r--r--drivers/xen/Makefile4
-rw-r--r--drivers/xen/events.c37
-rw-r--r--drivers/xen/pci.c105
-rw-r--r--drivers/xen/swiotlb-xen.c70
-rw-r--r--drivers/xen/xen-pciback/conf_space.c1
-rw-r--r--drivers/xen/xen-pciback/conf_space_header.c5
-rw-r--r--drivers/xen/xen-pciback/conf_space_quirks.c3
-rw-r--r--drivers/xen/xen-pciback/passthrough.c34
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c35
-rw-r--r--drivers/xen/xen-pciback/pciback.h32
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c1
-rw-r--r--drivers/xen/xen-pciback/vpci.c35
-rw-r--r--drivers/xen/xen-pciback/xenbus.c27
-rw-r--r--drivers/xen/xenbus/xenbus_comms.c4
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c101
-rw-r--r--drivers/xen/xenbus/xenbus_probe_frontend.c121
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c17
18 files changed, 447 insertions, 195 deletions
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 5f7ff8e2fc14..8795480c2350 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -137,16 +137,6 @@ config XEN_GRANT_DEV_ALLOC
137 to other domains. This can be used to implement frontend drivers 137 to other domains. This can be used to implement frontend drivers
138 or as part of an inter-domain shared memory channel. 138 or as part of an inter-domain shared memory channel.
139 139
140config XEN_PLATFORM_PCI
141 tristate "xen platform pci device driver"
142 depends on XEN_PVHVM && PCI
143 default m
144 help
145 Driver for the Xen PCI Platform device: it is responsible for
146 initializing xenbus and grant_table when running in a Xen HVM
147 domain. As a consequence this driver is required to run any Xen PV
148 frontend on Xen HVM.
149
150config SWIOTLB_XEN 140config SWIOTLB_XEN
151 def_bool y 141 def_bool y
152 depends on PCI 142 depends on PCI
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 72bbb27d7a68..974fffdf22b2 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_XEN_GNTDEV) += xen-gntdev.o
14obj-$(CONFIG_XEN_GRANT_DEV_ALLOC) += xen-gntalloc.o 14obj-$(CONFIG_XEN_GRANT_DEV_ALLOC) += xen-gntalloc.o
15obj-$(CONFIG_XENFS) += xenfs/ 15obj-$(CONFIG_XENFS) += xenfs/
16obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o 16obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
17obj-$(CONFIG_XEN_PLATFORM_PCI) += xen-platform-pci.o 17obj-$(CONFIG_XEN_PVHVM) += platform-pci.o
18obj-$(CONFIG_XEN_TMEM) += tmem.o 18obj-$(CONFIG_XEN_TMEM) += tmem.o
19obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o 19obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o
20obj-$(CONFIG_XEN_DOM0) += pci.o 20obj-$(CONFIG_XEN_DOM0) += pci.o
@@ -23,5 +23,3 @@ obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/
23xen-evtchn-y := evtchn.o 23xen-evtchn-y := evtchn.o
24xen-gntdev-y := gntdev.o 24xen-gntdev-y := gntdev.o
25xen-gntalloc-y := gntalloc.o 25xen-gntalloc-y := gntalloc.o
26
27xen-platform-pci-y := platform-pci.o
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 212a5c871bf4..7a55b292bf39 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -873,11 +873,32 @@ static int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
873 return err ? : bind_evtchn_to_irq(bind_interdomain.local_port); 873 return err ? : bind_evtchn_to_irq(bind_interdomain.local_port);
874} 874}
875 875
876static int find_virq(unsigned int virq, unsigned int cpu)
877{
878 struct evtchn_status status;
879 int port, rc = -ENOENT;
880
881 memset(&status, 0, sizeof(status));
882 for (port = 0; port <= NR_EVENT_CHANNELS; port++) {
883 status.dom = DOMID_SELF;
884 status.port = port;
885 rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status);
886 if (rc < 0)
887 continue;
888 if (status.status != EVTCHNSTAT_virq)
889 continue;
890 if (status.u.virq == virq && status.vcpu == cpu) {
891 rc = port;
892 break;
893 }
894 }
895 return rc;
896}
876 897
877int bind_virq_to_irq(unsigned int virq, unsigned int cpu) 898int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
878{ 899{
879 struct evtchn_bind_virq bind_virq; 900 struct evtchn_bind_virq bind_virq;
880 int evtchn, irq; 901 int evtchn, irq, ret;
881 902
882 mutex_lock(&irq_mapping_update_lock); 903 mutex_lock(&irq_mapping_update_lock);
883 904
@@ -893,10 +914,16 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
893 914
894 bind_virq.virq = virq; 915 bind_virq.virq = virq;
895 bind_virq.vcpu = cpu; 916 bind_virq.vcpu = cpu;
896 if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, 917 ret = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
897 &bind_virq) != 0) 918 &bind_virq);
898 BUG(); 919 if (ret == 0)
899 evtchn = bind_virq.port; 920 evtchn = bind_virq.port;
921 else {
922 if (ret == -EEXIST)
923 ret = find_virq(virq, cpu);
924 BUG_ON(ret < 0);
925 evtchn = ret;
926 }
900 927
901 xen_irq_info_virq_init(cpu, irq, evtchn, virq); 928 xen_irq_info_virq_init(cpu, irq, evtchn, virq);
902 929
diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
index cef4bafc07dc..66057075d6e2 100644
--- a/drivers/xen/pci.c
+++ b/drivers/xen/pci.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/pci.h> 20#include <linux/pci.h>
21#include <linux/acpi.h>
21#include <xen/xen.h> 22#include <xen/xen.h>
22#include <xen/interface/physdev.h> 23#include <xen/interface/physdev.h>
23#include <xen/interface/xen.h> 24#include <xen/interface/xen.h>
@@ -26,26 +27,85 @@
26#include <asm/xen/hypercall.h> 27#include <asm/xen/hypercall.h>
27#include "../pci/pci.h" 28#include "../pci/pci.h"
28 29
30static bool __read_mostly pci_seg_supported = true;
31
29static int xen_add_device(struct device *dev) 32static int xen_add_device(struct device *dev)
30{ 33{
31 int r; 34 int r;
32 struct pci_dev *pci_dev = to_pci_dev(dev); 35 struct pci_dev *pci_dev = to_pci_dev(dev);
36#ifdef CONFIG_PCI_IOV
37 struct pci_dev *physfn = pci_dev->physfn;
38#endif
39
40 if (pci_seg_supported) {
41 struct physdev_pci_device_add add = {
42 .seg = pci_domain_nr(pci_dev->bus),
43 .bus = pci_dev->bus->number,
44 .devfn = pci_dev->devfn
45 };
46#ifdef CONFIG_ACPI
47 acpi_handle handle;
48#endif
49
50#ifdef CONFIG_PCI_IOV
51 if (pci_dev->is_virtfn) {
52 add.flags = XEN_PCI_DEV_VIRTFN;
53 add.physfn.bus = physfn->bus->number;
54 add.physfn.devfn = physfn->devfn;
55 } else
56#endif
57 if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn))
58 add.flags = XEN_PCI_DEV_EXTFN;
59
60#ifdef CONFIG_ACPI
61 handle = DEVICE_ACPI_HANDLE(&pci_dev->dev);
62 if (!handle)
63 handle = DEVICE_ACPI_HANDLE(pci_dev->bus->bridge);
64#ifdef CONFIG_PCI_IOV
65 if (!handle && pci_dev->is_virtfn)
66 handle = DEVICE_ACPI_HANDLE(physfn->bus->bridge);
67#endif
68 if (handle) {
69 acpi_status status;
70
71 do {
72 unsigned long long pxm;
73
74 status = acpi_evaluate_integer(handle, "_PXM",
75 NULL, &pxm);
76 if (ACPI_SUCCESS(status)) {
77 add.optarr[0] = pxm;
78 add.flags |= XEN_PCI_DEV_PXM;
79 break;
80 }
81 status = acpi_get_parent(handle, &handle);
82 } while (ACPI_SUCCESS(status));
83 }
84#endif /* CONFIG_ACPI */
85
86 r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_add, &add);
87 if (r != -ENOSYS)
88 return r;
89 pci_seg_supported = false;
90 }
33 91
92 if (pci_domain_nr(pci_dev->bus))
93 r = -ENOSYS;
34#ifdef CONFIG_PCI_IOV 94#ifdef CONFIG_PCI_IOV
35 if (pci_dev->is_virtfn) { 95 else if (pci_dev->is_virtfn) {
36 struct physdev_manage_pci_ext manage_pci_ext = { 96 struct physdev_manage_pci_ext manage_pci_ext = {
37 .bus = pci_dev->bus->number, 97 .bus = pci_dev->bus->number,
38 .devfn = pci_dev->devfn, 98 .devfn = pci_dev->devfn,
39 .is_virtfn = 1, 99 .is_virtfn = 1,
40 .physfn.bus = pci_dev->physfn->bus->number, 100 .physfn.bus = physfn->bus->number,
41 .physfn.devfn = pci_dev->physfn->devfn, 101 .physfn.devfn = physfn->devfn,
42 }; 102 };
43 103
44 r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext, 104 r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext,
45 &manage_pci_ext); 105 &manage_pci_ext);
46 } else 106 }
47#endif 107#endif
48 if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn)) { 108 else if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn)) {
49 struct physdev_manage_pci_ext manage_pci_ext = { 109 struct physdev_manage_pci_ext manage_pci_ext = {
50 .bus = pci_dev->bus->number, 110 .bus = pci_dev->bus->number,
51 .devfn = pci_dev->devfn, 111 .devfn = pci_dev->devfn,
@@ -71,13 +131,27 @@ static int xen_remove_device(struct device *dev)
71{ 131{
72 int r; 132 int r;
73 struct pci_dev *pci_dev = to_pci_dev(dev); 133 struct pci_dev *pci_dev = to_pci_dev(dev);
74 struct physdev_manage_pci manage_pci;
75 134
76 manage_pci.bus = pci_dev->bus->number; 135 if (pci_seg_supported) {
77 manage_pci.devfn = pci_dev->devfn; 136 struct physdev_pci_device device = {
137 .seg = pci_domain_nr(pci_dev->bus),
138 .bus = pci_dev->bus->number,
139 .devfn = pci_dev->devfn
140 };
78 141
79 r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove, 142 r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_remove,
80 &manage_pci); 143 &device);
144 } else if (pci_domain_nr(pci_dev->bus))
145 r = -ENOSYS;
146 else {
147 struct physdev_manage_pci manage_pci = {
148 .bus = pci_dev->bus->number,
149 .devfn = pci_dev->devfn
150 };
151
152 r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove,
153 &manage_pci);
154 }
81 155
82 return r; 156 return r;
83} 157}
@@ -96,13 +170,16 @@ static int xen_pci_notifier(struct notifier_block *nb,
96 r = xen_remove_device(dev); 170 r = xen_remove_device(dev);
97 break; 171 break;
98 default: 172 default:
99 break; 173 return NOTIFY_DONE;
100 } 174 }
101 175 if (r)
102 return r; 176 dev_err(dev, "Failed to %s - passthrough or MSI/MSI-X might fail!\n",
177 action == BUS_NOTIFY_ADD_DEVICE ? "add" :
178 (action == BUS_NOTIFY_DEL_DEVICE ? "delete" : "?"));
179 return NOTIFY_OK;
103} 180}
104 181
105struct notifier_block device_nb = { 182static struct notifier_block device_nb = {
106 .notifier_call = xen_pci_notifier, 183 .notifier_call = xen_pci_notifier,
107}; 184};
108 185
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 6e8c15a23201..c984768d98ca 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -38,6 +38,7 @@
38#include <xen/swiotlb-xen.h> 38#include <xen/swiotlb-xen.h>
39#include <xen/page.h> 39#include <xen/page.h>
40#include <xen/xen-ops.h> 40#include <xen/xen-ops.h>
41#include <xen/hvc-console.h>
41/* 42/*
42 * Used to do a quick range check in swiotlb_tbl_unmap_single and 43 * Used to do a quick range check in swiotlb_tbl_unmap_single and
43 * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this 44 * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this
@@ -146,8 +147,10 @@ xen_swiotlb_fixup(void *buf, size_t size, unsigned long nslabs)
146void __init xen_swiotlb_init(int verbose) 147void __init xen_swiotlb_init(int verbose)
147{ 148{
148 unsigned long bytes; 149 unsigned long bytes;
149 int rc; 150 int rc = -ENOMEM;
150 unsigned long nr_tbl; 151 unsigned long nr_tbl;
152 char *m = NULL;
153 unsigned int repeat = 3;
151 154
152 nr_tbl = swioltb_nr_tbl(); 155 nr_tbl = swioltb_nr_tbl();
153 if (nr_tbl) 156 if (nr_tbl)
@@ -156,16 +159,17 @@ void __init xen_swiotlb_init(int verbose)
156 xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT); 159 xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT);
157 xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE); 160 xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE);
158 } 161 }
159 162retry:
160 bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT; 163 bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT;
161 164
162 /* 165 /*
163 * Get IO TLB memory from any location. 166 * Get IO TLB memory from any location.
164 */ 167 */
165 xen_io_tlb_start = alloc_bootmem(bytes); 168 xen_io_tlb_start = alloc_bootmem(bytes);
166 if (!xen_io_tlb_start) 169 if (!xen_io_tlb_start) {
167 panic("Cannot allocate SWIOTLB buffer"); 170 m = "Cannot allocate Xen-SWIOTLB buffer!\n";
168 171 goto error;
172 }
169 xen_io_tlb_end = xen_io_tlb_start + bytes; 173 xen_io_tlb_end = xen_io_tlb_start + bytes;
170 /* 174 /*
171 * And replace that memory with pages under 4GB. 175 * And replace that memory with pages under 4GB.
@@ -173,17 +177,28 @@ void __init xen_swiotlb_init(int verbose)
173 rc = xen_swiotlb_fixup(xen_io_tlb_start, 177 rc = xen_swiotlb_fixup(xen_io_tlb_start,
174 bytes, 178 bytes,
175 xen_io_tlb_nslabs); 179 xen_io_tlb_nslabs);
176 if (rc) 180 if (rc) {
181 free_bootmem(__pa(xen_io_tlb_start), bytes);
182 m = "Failed to get contiguous memory for DMA from Xen!\n"\
183 "You either: don't have the permissions, do not have"\
184 " enough free memory under 4GB, or the hypervisor memory"\
185 "is too fragmented!";
177 goto error; 186 goto error;
178 187 }
179 start_dma_addr = xen_virt_to_bus(xen_io_tlb_start); 188 start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
180 swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose); 189 swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose);
181 190
182 return; 191 return;
183error: 192error:
184 panic("DMA(%d): Failed to exchange pages allocated for DMA with Xen! "\ 193 if (repeat--) {
185 "We either don't have the permission or you do not have enough"\ 194 xen_io_tlb_nslabs = max(1024UL, /* Min is 2MB */
186 "free memory under 4GB!\n", rc); 195 (xen_io_tlb_nslabs >> 1));
196 printk(KERN_INFO "Xen-SWIOTLB: Lowering to %luMB\n",
197 (xen_io_tlb_nslabs << IO_TLB_SHIFT) >> 20);
198 goto retry;
199 }
200 xen_raw_printk("%s (rc:%d)", m, rc);
201 panic("%s (rc:%d)", m, rc);
187} 202}
188 203
189void * 204void *
@@ -194,6 +209,8 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
194 int order = get_order(size); 209 int order = get_order(size);
195 u64 dma_mask = DMA_BIT_MASK(32); 210 u64 dma_mask = DMA_BIT_MASK(32);
196 unsigned long vstart; 211 unsigned long vstart;
212 phys_addr_t phys;
213 dma_addr_t dev_addr;
197 214
198 /* 215 /*
199 * Ignore region specifiers - the kernel's ideas of 216 * Ignore region specifiers - the kernel's ideas of
@@ -209,18 +226,26 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
209 vstart = __get_free_pages(flags, order); 226 vstart = __get_free_pages(flags, order);
210 ret = (void *)vstart; 227 ret = (void *)vstart;
211 228
229 if (!ret)
230 return ret;
231
212 if (hwdev && hwdev->coherent_dma_mask) 232 if (hwdev && hwdev->coherent_dma_mask)
213 dma_mask = dma_alloc_coherent_mask(hwdev, flags); 233 dma_mask = hwdev->coherent_dma_mask;
214 234
215 if (ret) { 235 phys = virt_to_phys(ret);
236 dev_addr = xen_phys_to_bus(phys);
237 if (((dev_addr + size - 1 <= dma_mask)) &&
238 !range_straddles_page_boundary(phys, size))
239 *dma_handle = dev_addr;
240 else {
216 if (xen_create_contiguous_region(vstart, order, 241 if (xen_create_contiguous_region(vstart, order,
217 fls64(dma_mask)) != 0) { 242 fls64(dma_mask)) != 0) {
218 free_pages(vstart, order); 243 free_pages(vstart, order);
219 return NULL; 244 return NULL;
220 } 245 }
221 memset(ret, 0, size);
222 *dma_handle = virt_to_machine(ret).maddr; 246 *dma_handle = virt_to_machine(ret).maddr;
223 } 247 }
248 memset(ret, 0, size);
224 return ret; 249 return ret;
225} 250}
226EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent); 251EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
@@ -230,11 +255,21 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
230 dma_addr_t dev_addr) 255 dma_addr_t dev_addr)
231{ 256{
232 int order = get_order(size); 257 int order = get_order(size);
258 phys_addr_t phys;
259 u64 dma_mask = DMA_BIT_MASK(32);
233 260
234 if (dma_release_from_coherent(hwdev, order, vaddr)) 261 if (dma_release_from_coherent(hwdev, order, vaddr))
235 return; 262 return;
236 263
237 xen_destroy_contiguous_region((unsigned long)vaddr, order); 264 if (hwdev && hwdev->coherent_dma_mask)
265 dma_mask = hwdev->coherent_dma_mask;
266
267 phys = virt_to_phys(vaddr);
268
269 if (((dev_addr + size - 1 > dma_mask)) ||
270 range_straddles_page_boundary(phys, size))
271 xen_destroy_contiguous_region((unsigned long)vaddr, order);
272
238 free_pages((unsigned long)vaddr, order); 273 free_pages((unsigned long)vaddr, order);
239} 274}
240EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent); 275EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
@@ -278,9 +313,10 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
278 /* 313 /*
279 * Ensure that the address returned is DMA'ble 314 * Ensure that the address returned is DMA'ble
280 */ 315 */
281 if (!dma_capable(dev, dev_addr, size)) 316 if (!dma_capable(dev, dev_addr, size)) {
282 panic("map_single: bounce buffer is not DMA'ble"); 317 swiotlb_tbl_unmap_single(dev, map, size, dir);
283 318 dev_addr = 0;
319 }
284 return dev_addr; 320 return dev_addr;
285} 321}
286EXPORT_SYMBOL_GPL(xen_swiotlb_map_page); 322EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
index a8031445d94e..444345afbd5c 100644
--- a/drivers/xen/xen-pciback/conf_space.c
+++ b/drivers/xen/xen-pciback/conf_space.c
@@ -15,7 +15,6 @@
15#include "conf_space.h" 15#include "conf_space.h"
16#include "conf_space_quirks.h" 16#include "conf_space_quirks.h"
17 17
18#define DRV_NAME "xen-pciback"
19static int permissive; 18static int permissive;
20module_param(permissive, bool, 0644); 19module_param(permissive, bool, 0644);
21 20
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c
index da3cbdfcb5dc..3daf862d739d 100644
--- a/drivers/xen/xen-pciback/conf_space_header.c
+++ b/drivers/xen/xen-pciback/conf_space_header.c
@@ -15,7 +15,6 @@ struct pci_bar_info {
15 int which; 15 int which;
16}; 16};
17 17
18#define DRV_NAME "xen-pciback"
19#define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO)) 18#define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
20#define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER) 19#define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
21 20
@@ -25,7 +24,7 @@ static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
25 int ret; 24 int ret;
26 25
27 ret = xen_pcibk_read_config_word(dev, offset, value, data); 26 ret = xen_pcibk_read_config_word(dev, offset, value, data);
28 if (!atomic_read(&dev->enable_cnt)) 27 if (!pci_is_enabled(dev))
29 return ret; 28 return ret;
30 29
31 for (i = 0; i < PCI_ROM_RESOURCE; i++) { 30 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
@@ -187,7 +186,7 @@ static inline void read_dev_bar(struct pci_dev *dev,
187 186
188 bar_info->val = res[pos].start | 187 bar_info->val = res[pos].start |
189 (res[pos].flags & PCI_REGION_FLAG_MASK); 188 (res[pos].flags & PCI_REGION_FLAG_MASK);
190 bar_info->len_val = res[pos].end - res[pos].start + 1; 189 bar_info->len_val = resource_size(&res[pos]);
191} 190}
192 191
193static void *bar_init(struct pci_dev *dev, int offset) 192static void *bar_init(struct pci_dev *dev, int offset)
diff --git a/drivers/xen/xen-pciback/conf_space_quirks.c b/drivers/xen/xen-pciback/conf_space_quirks.c
index 921a889e65eb..7476791cab40 100644
--- a/drivers/xen/xen-pciback/conf_space_quirks.c
+++ b/drivers/xen/xen-pciback/conf_space_quirks.c
@@ -12,7 +12,6 @@
12#include "conf_space_quirks.h" 12#include "conf_space_quirks.h"
13 13
14LIST_HEAD(xen_pcibk_quirks); 14LIST_HEAD(xen_pcibk_quirks);
15#define DRV_NAME "xen-pciback"
16static inline const struct pci_device_id * 15static inline const struct pci_device_id *
17match_one_device(const struct pci_device_id *id, const struct pci_dev *dev) 16match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
18{ 17{
@@ -36,7 +35,7 @@ static struct xen_pcibk_config_quirk *xen_pcibk_find_quirk(struct pci_dev *dev)
36 goto out; 35 goto out;
37 tmp_quirk = NULL; 36 tmp_quirk = NULL;
38 printk(KERN_DEBUG DRV_NAME 37 printk(KERN_DEBUG DRV_NAME
39 ":quirk didn't match any device xen_pciback knows about\n"); 38 ": quirk didn't match any device known\n");
40out: 39out:
41 return tmp_quirk; 40 return tmp_quirk;
42} 41}
diff --git a/drivers/xen/xen-pciback/passthrough.c b/drivers/xen/xen-pciback/passthrough.c
index 1d32a9a42c01..828dddc360df 100644
--- a/drivers/xen/xen-pciback/passthrough.c
+++ b/drivers/xen/xen-pciback/passthrough.c
@@ -7,13 +7,13 @@
7 7
8#include <linux/list.h> 8#include <linux/list.h>
9#include <linux/pci.h> 9#include <linux/pci.h>
10#include <linux/spinlock.h> 10#include <linux/mutex.h>
11#include "pciback.h" 11#include "pciback.h"
12 12
13struct passthrough_dev_data { 13struct passthrough_dev_data {
14 /* Access to dev_list must be protected by lock */ 14 /* Access to dev_list must be protected by lock */
15 struct list_head dev_list; 15 struct list_head dev_list;
16 spinlock_t lock; 16 struct mutex lock;
17}; 17};
18 18
19static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, 19static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
@@ -24,9 +24,8 @@ static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
24 struct passthrough_dev_data *dev_data = pdev->pci_dev_data; 24 struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
25 struct pci_dev_entry *dev_entry; 25 struct pci_dev_entry *dev_entry;
26 struct pci_dev *dev = NULL; 26 struct pci_dev *dev = NULL;
27 unsigned long flags;
28 27
29 spin_lock_irqsave(&dev_data->lock, flags); 28 mutex_lock(&dev_data->lock);
30 29
31 list_for_each_entry(dev_entry, &dev_data->dev_list, list) { 30 list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
32 if (domain == (unsigned int)pci_domain_nr(dev_entry->dev->bus) 31 if (domain == (unsigned int)pci_domain_nr(dev_entry->dev->bus)
@@ -37,7 +36,7 @@ static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
37 } 36 }
38 } 37 }
39 38
40 spin_unlock_irqrestore(&dev_data->lock, flags); 39 mutex_unlock(&dev_data->lock);
41 40
42 return dev; 41 return dev;
43} 42}
@@ -48,7 +47,6 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
48{ 47{
49 struct passthrough_dev_data *dev_data = pdev->pci_dev_data; 48 struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
50 struct pci_dev_entry *dev_entry; 49 struct pci_dev_entry *dev_entry;
51 unsigned long flags;
52 unsigned int domain, bus, devfn; 50 unsigned int domain, bus, devfn;
53 int err; 51 int err;
54 52
@@ -57,9 +55,9 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
57 return -ENOMEM; 55 return -ENOMEM;
58 dev_entry->dev = dev; 56 dev_entry->dev = dev;
59 57
60 spin_lock_irqsave(&dev_data->lock, flags); 58 mutex_lock(&dev_data->lock);
61 list_add_tail(&dev_entry->list, &dev_data->dev_list); 59 list_add_tail(&dev_entry->list, &dev_data->dev_list);
62 spin_unlock_irqrestore(&dev_data->lock, flags); 60 mutex_unlock(&dev_data->lock);
63 61
64 /* Publish this device. */ 62 /* Publish this device. */
65 domain = (unsigned int)pci_domain_nr(dev->bus); 63 domain = (unsigned int)pci_domain_nr(dev->bus);
@@ -76,9 +74,8 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
76 struct passthrough_dev_data *dev_data = pdev->pci_dev_data; 74 struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
77 struct pci_dev_entry *dev_entry, *t; 75 struct pci_dev_entry *dev_entry, *t;
78 struct pci_dev *found_dev = NULL; 76 struct pci_dev *found_dev = NULL;
79 unsigned long flags;
80 77
81 spin_lock_irqsave(&dev_data->lock, flags); 78 mutex_lock(&dev_data->lock);
82 79
83 list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) { 80 list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
84 if (dev_entry->dev == dev) { 81 if (dev_entry->dev == dev) {
@@ -88,7 +85,7 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
88 } 85 }
89 } 86 }
90 87
91 spin_unlock_irqrestore(&dev_data->lock, flags); 88 mutex_unlock(&dev_data->lock);
92 89
93 if (found_dev) 90 if (found_dev)
94 pcistub_put_pci_dev(found_dev); 91 pcistub_put_pci_dev(found_dev);
@@ -102,7 +99,7 @@ static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
102 if (!dev_data) 99 if (!dev_data)
103 return -ENOMEM; 100 return -ENOMEM;
104 101
105 spin_lock_init(&dev_data->lock); 102 mutex_init(&dev_data->lock);
106 103
107 INIT_LIST_HEAD(&dev_data->dev_list); 104 INIT_LIST_HEAD(&dev_data->dev_list);
108 105
@@ -116,14 +113,14 @@ static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
116{ 113{
117 int err = 0; 114 int err = 0;
118 struct passthrough_dev_data *dev_data = pdev->pci_dev_data; 115 struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
119 struct pci_dev_entry *dev_entry, *e, *tmp; 116 struct pci_dev_entry *dev_entry, *e;
120 struct pci_dev *dev; 117 struct pci_dev *dev;
121 int found; 118 int found;
122 unsigned int domain, bus; 119 unsigned int domain, bus;
123 120
124 spin_lock(&dev_data->lock); 121 mutex_lock(&dev_data->lock);
125 122
126 list_for_each_entry_safe(dev_entry, tmp, &dev_data->dev_list, list) { 123 list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
127 /* Only publish this device as a root if none of its 124 /* Only publish this device as a root if none of its
128 * parent bridges are exported 125 * parent bridges are exported
129 */ 126 */
@@ -142,16 +139,13 @@ static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
142 bus = (unsigned int)dev_entry->dev->bus->number; 139 bus = (unsigned int)dev_entry->dev->bus->number;
143 140
144 if (!found) { 141 if (!found) {
145 spin_unlock(&dev_data->lock);
146 err = publish_root_cb(pdev, domain, bus); 142 err = publish_root_cb(pdev, domain, bus);
147 if (err) 143 if (err)
148 break; 144 break;
149 spin_lock(&dev_data->lock);
150 } 145 }
151 } 146 }
152 147
153 if (!err) 148 mutex_unlock(&dev_data->lock);
154 spin_unlock(&dev_data->lock);
155 149
156 return err; 150 return err;
157} 151}
@@ -182,7 +176,7 @@ static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
182 return 1; 176 return 1;
183} 177}
184 178
185struct xen_pcibk_backend xen_pcibk_passthrough_backend = { 179const struct xen_pcibk_backend xen_pcibk_passthrough_backend = {
186 .name = "passthrough", 180 .name = "passthrough",
187 .init = __xen_pcibk_init_devices, 181 .init = __xen_pcibk_init_devices,
188 .free = __xen_pcibk_release_devices, 182 .free = __xen_pcibk_release_devices,
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index aec214ac0a14..8f06e1ed028c 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -21,8 +21,6 @@
21#include "conf_space.h" 21#include "conf_space.h"
22#include "conf_space_quirks.h" 22#include "conf_space_quirks.h"
23 23
24#define DRV_NAME "xen-pciback"
25
26static char *pci_devs_to_hide; 24static char *pci_devs_to_hide;
27wait_queue_head_t xen_pcibk_aer_wait_queue; 25wait_queue_head_t xen_pcibk_aer_wait_queue;
28/*Add sem for sync AER handling and xen_pcibk remove/reconfigue ops, 26/*Add sem for sync AER handling and xen_pcibk remove/reconfigue ops,
@@ -222,6 +220,8 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
222 } 220 }
223 221
224 spin_unlock_irqrestore(&pcistub_devices_lock, flags); 222 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
223 if (WARN_ON(!found_psdev))
224 return;
225 225
226 /*hold this lock for avoiding breaking link between 226 /*hold this lock for avoiding breaking link between
227 * pcistub and xen_pcibk when AER is in processing 227 * pcistub and xen_pcibk when AER is in processing
@@ -514,12 +514,9 @@ static void kill_domain_by_device(struct pcistub_device *psdev)
514 int err; 514 int err;
515 char nodename[PCI_NODENAME_MAX]; 515 char nodename[PCI_NODENAME_MAX];
516 516
517 if (!psdev) 517 BUG_ON(!psdev);
518 dev_err(&psdev->dev->dev,
519 "device is NULL when do AER recovery/kill_domain\n");
520 snprintf(nodename, PCI_NODENAME_MAX, "/local/domain/0/backend/pci/%d/0", 518 snprintf(nodename, PCI_NODENAME_MAX, "/local/domain/0/backend/pci/%d/0",
521 psdev->pdev->xdev->otherend_id); 519 psdev->pdev->xdev->otherend_id);
522 nodename[strlen(nodename)] = '\0';
523 520
524again: 521again:
525 err = xenbus_transaction_start(&xbt); 522 err = xenbus_transaction_start(&xbt);
@@ -605,7 +602,7 @@ static pci_ers_result_t common_process(struct pcistub_device *psdev,
605 if (test_bit(_XEN_PCIF_active, 602 if (test_bit(_XEN_PCIF_active,
606 (unsigned long *)&psdev->pdev->sh_info->flags)) { 603 (unsigned long *)&psdev->pdev->sh_info->flags)) {
607 dev_dbg(&psdev->dev->dev, 604 dev_dbg(&psdev->dev->dev,
608 "schedule pci_conf service in xen_pcibk\n"); 605 "schedule pci_conf service in " DRV_NAME "\n");
609 xen_pcibk_test_and_schedule_op(psdev->pdev); 606 xen_pcibk_test_and_schedule_op(psdev->pdev);
610 } 607 }
611 608
@@ -995,8 +992,7 @@ out:
995 err = count; 992 err = count;
996 return err; 993 return err;
997} 994}
998 995static DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
999DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
1000 996
1001static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf, 997static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
1002 size_t count) 998 size_t count)
@@ -1015,8 +1011,7 @@ out:
1015 err = count; 1011 err = count;
1016 return err; 1012 return err;
1017} 1013}
1018 1014static DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
1019DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
1020 1015
1021static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf) 1016static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
1022{ 1017{
@@ -1039,8 +1034,7 @@ static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
1039 1034
1040 return count; 1035 return count;
1041} 1036}
1042 1037static DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
1043DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
1044 1038
1045static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf) 1039static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf)
1046{ 1040{
@@ -1069,8 +1063,7 @@ static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf)
1069 spin_unlock_irqrestore(&pcistub_devices_lock, flags); 1063 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
1070 return count; 1064 return count;
1071} 1065}
1072 1066static DRIVER_ATTR(irq_handlers, S_IRUSR, pcistub_irq_handler_show, NULL);
1073DRIVER_ATTR(irq_handlers, S_IRUSR, pcistub_irq_handler_show, NULL);
1074 1067
1075static ssize_t pcistub_irq_handler_switch(struct device_driver *drv, 1068static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
1076 const char *buf, 1069 const char *buf,
@@ -1106,7 +1099,8 @@ out:
1106 err = count; 1099 err = count;
1107 return err; 1100 return err;
1108} 1101}
1109DRIVER_ATTR(irq_handler_state, S_IWUSR, NULL, pcistub_irq_handler_switch); 1102static DRIVER_ATTR(irq_handler_state, S_IWUSR, NULL,
1103 pcistub_irq_handler_switch);
1110 1104
1111static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf, 1105static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf,
1112 size_t count) 1106 size_t count)
@@ -1170,8 +1164,8 @@ out:
1170 1164
1171 return count; 1165 return count;
1172} 1166}
1173 1167static DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show,
1174DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show, pcistub_quirk_add); 1168 pcistub_quirk_add);
1175 1169
1176static ssize_t permissive_add(struct device_driver *drv, const char *buf, 1170static ssize_t permissive_add(struct device_driver *drv, const char *buf,
1177 size_t count) 1171 size_t count)
@@ -1236,8 +1230,8 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf)
1236 spin_unlock_irqrestore(&pcistub_devices_lock, flags); 1230 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
1237 return count; 1231 return count;
1238} 1232}
1239 1233static DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show,
1240DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add); 1234 permissive_add);
1241 1235
1242static void pcistub_exit(void) 1236static void pcistub_exit(void)
1243{ 1237{
@@ -1374,3 +1368,4 @@ module_init(xen_pcibk_init);
1374module_exit(xen_pcibk_cleanup); 1368module_exit(xen_pcibk_cleanup);
1375 1369
1376MODULE_LICENSE("Dual BSD/GPL"); 1370MODULE_LICENSE("Dual BSD/GPL");
1371MODULE_ALIAS("xen-backend:pci");
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index a0e131a81503..e9b4011c5f9a 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -15,6 +15,8 @@
15#include <linux/atomic.h> 15#include <linux/atomic.h>
16#include <xen/interface/io/pciif.h> 16#include <xen/interface/io/pciif.h>
17 17
18#define DRV_NAME "xen-pciback"
19
18struct pci_dev_entry { 20struct pci_dev_entry {
19 struct list_head list; 21 struct list_head list;
20 struct pci_dev *dev; 22 struct pci_dev *dev;
@@ -27,7 +29,7 @@ struct pci_dev_entry {
27 29
28struct xen_pcibk_device { 30struct xen_pcibk_device {
29 void *pci_dev_data; 31 void *pci_dev_data;
30 spinlock_t dev_lock; 32 struct mutex dev_lock;
31 struct xenbus_device *xdev; 33 struct xenbus_device *xdev;
32 struct xenbus_watch be_watch; 34 struct xenbus_watch be_watch;
33 u8 be_watching; 35 u8 be_watching;
@@ -89,7 +91,7 @@ typedef int (*publish_pci_root_cb) (struct xen_pcibk_device *pdev,
89 * passthrough - BDFs are exactly like in the host. 91 * passthrough - BDFs are exactly like in the host.
90 */ 92 */
91struct xen_pcibk_backend { 93struct xen_pcibk_backend {
92 char *name; 94 const char *name;
93 int (*init)(struct xen_pcibk_device *pdev); 95 int (*init)(struct xen_pcibk_device *pdev);
94 void (*free)(struct xen_pcibk_device *pdev); 96 void (*free)(struct xen_pcibk_device *pdev);
95 int (*find)(struct pci_dev *pcidev, struct xen_pcibk_device *pdev, 97 int (*find)(struct pci_dev *pcidev, struct xen_pcibk_device *pdev,
@@ -104,9 +106,9 @@ struct xen_pcibk_backend {
104 unsigned int devfn); 106 unsigned int devfn);
105}; 107};
106 108
107extern struct xen_pcibk_backend xen_pcibk_vpci_backend; 109extern const struct xen_pcibk_backend xen_pcibk_vpci_backend;
108extern struct xen_pcibk_backend xen_pcibk_passthrough_backend; 110extern const struct xen_pcibk_backend xen_pcibk_passthrough_backend;
109extern struct xen_pcibk_backend *xen_pcibk_backend; 111extern const struct xen_pcibk_backend *xen_pcibk_backend;
110 112
111static inline int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, 113static inline int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
112 struct pci_dev *dev, 114 struct pci_dev *dev,
@@ -116,13 +118,14 @@ static inline int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
116 if (xen_pcibk_backend && xen_pcibk_backend->add) 118 if (xen_pcibk_backend && xen_pcibk_backend->add)
117 return xen_pcibk_backend->add(pdev, dev, devid, publish_cb); 119 return xen_pcibk_backend->add(pdev, dev, devid, publish_cb);
118 return -1; 120 return -1;
119}; 121}
122
120static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, 123static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
121 struct pci_dev *dev) 124 struct pci_dev *dev)
122{ 125{
123 if (xen_pcibk_backend && xen_pcibk_backend->free) 126 if (xen_pcibk_backend && xen_pcibk_backend->free)
124 return xen_pcibk_backend->release(pdev, dev); 127 return xen_pcibk_backend->release(pdev, dev);
125}; 128}
126 129
127static inline struct pci_dev * 130static inline struct pci_dev *
128xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, unsigned int domain, 131xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, unsigned int domain,
@@ -131,7 +134,8 @@ xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, unsigned int domain,
131 if (xen_pcibk_backend && xen_pcibk_backend->get) 134 if (xen_pcibk_backend && xen_pcibk_backend->get)
132 return xen_pcibk_backend->get(pdev, domain, bus, devfn); 135 return xen_pcibk_backend->get(pdev, domain, bus, devfn);
133 return NULL; 136 return NULL;
134}; 137}
138
135/** 139/**
136* Add for domain0 PCIE-AER handling. Get guest domain/bus/devfn in xen_pcibk 140* Add for domain0 PCIE-AER handling. Get guest domain/bus/devfn in xen_pcibk
137* before sending aer request to pcifront, so that guest could identify 141* before sending aer request to pcifront, so that guest could identify
@@ -148,25 +152,29 @@ static inline int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
148 return xen_pcibk_backend->find(pcidev, pdev, domain, bus, 152 return xen_pcibk_backend->find(pcidev, pdev, domain, bus,
149 devfn); 153 devfn);
150 return -1; 154 return -1;
151}; 155}
156
152static inline int xen_pcibk_init_devices(struct xen_pcibk_device *pdev) 157static inline int xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
153{ 158{
154 if (xen_pcibk_backend && xen_pcibk_backend->init) 159 if (xen_pcibk_backend && xen_pcibk_backend->init)
155 return xen_pcibk_backend->init(pdev); 160 return xen_pcibk_backend->init(pdev);
156 return -1; 161 return -1;
157}; 162}
163
158static inline int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev, 164static inline int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
159 publish_pci_root_cb cb) 165 publish_pci_root_cb cb)
160{ 166{
161 if (xen_pcibk_backend && xen_pcibk_backend->publish) 167 if (xen_pcibk_backend && xen_pcibk_backend->publish)
162 return xen_pcibk_backend->publish(pdev, cb); 168 return xen_pcibk_backend->publish(pdev, cb);
163 return -1; 169 return -1;
164}; 170}
171
165static inline void xen_pcibk_release_devices(struct xen_pcibk_device *pdev) 172static inline void xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
166{ 173{
167 if (xen_pcibk_backend && xen_pcibk_backend->free) 174 if (xen_pcibk_backend && xen_pcibk_backend->free)
168 return xen_pcibk_backend->free(pdev); 175 return xen_pcibk_backend->free(pdev);
169}; 176}
177
170/* Handles events from front-end */ 178/* Handles events from front-end */
171irqreturn_t xen_pcibk_handle_event(int irq, void *dev_id); 179irqreturn_t xen_pcibk_handle_event(int irq, void *dev_id);
172void xen_pcibk_do_op(struct work_struct *data); 180void xen_pcibk_do_op(struct work_struct *data);
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 8c95c3415b75..63616d7453e6 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -10,7 +10,6 @@
10#include <linux/sched.h> 10#include <linux/sched.h>
11#include "pciback.h" 11#include "pciback.h"
12 12
13#define DRV_NAME "xen-pciback"
14int verbose_request; 13int verbose_request;
15module_param(verbose_request, int, 0644); 14module_param(verbose_request, int, 0644);
16 15
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index 4a42cfb0959d..46d140baebd8 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -8,16 +8,15 @@
8#include <linux/list.h> 8#include <linux/list.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/pci.h> 10#include <linux/pci.h>
11#include <linux/spinlock.h> 11#include <linux/mutex.h>
12#include "pciback.h" 12#include "pciback.h"
13 13
14#define PCI_SLOT_MAX 32 14#define PCI_SLOT_MAX 32
15#define DRV_NAME "xen-pciback"
16 15
17struct vpci_dev_data { 16struct vpci_dev_data {
18 /* Access to dev_list must be protected by lock */ 17 /* Access to dev_list must be protected by lock */
19 struct list_head dev_list[PCI_SLOT_MAX]; 18 struct list_head dev_list[PCI_SLOT_MAX];
20 spinlock_t lock; 19 struct mutex lock;
21}; 20};
22 21
23static inline struct list_head *list_first(struct list_head *head) 22static inline struct list_head *list_first(struct list_head *head)
@@ -33,13 +32,12 @@ static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
33 struct pci_dev_entry *entry; 32 struct pci_dev_entry *entry;
34 struct pci_dev *dev = NULL; 33 struct pci_dev *dev = NULL;
35 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 34 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
36 unsigned long flags;
37 35
38 if (domain != 0 || bus != 0) 36 if (domain != 0 || bus != 0)
39 return NULL; 37 return NULL;
40 38
41 if (PCI_SLOT(devfn) < PCI_SLOT_MAX) { 39 if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
42 spin_lock_irqsave(&vpci_dev->lock, flags); 40 mutex_lock(&vpci_dev->lock);
43 41
44 list_for_each_entry(entry, 42 list_for_each_entry(entry,
45 &vpci_dev->dev_list[PCI_SLOT(devfn)], 43 &vpci_dev->dev_list[PCI_SLOT(devfn)],
@@ -50,7 +48,7 @@ static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
50 } 48 }
51 } 49 }
52 50
53 spin_unlock_irqrestore(&vpci_dev->lock, flags); 51 mutex_unlock(&vpci_dev->lock);
54 } 52 }
55 return dev; 53 return dev;
56} 54}
@@ -71,7 +69,6 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
71 int err = 0, slot, func = -1; 69 int err = 0, slot, func = -1;
72 struct pci_dev_entry *t, *dev_entry; 70 struct pci_dev_entry *t, *dev_entry;
73 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 71 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
74 unsigned long flags;
75 72
76 if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) { 73 if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
77 err = -EFAULT; 74 err = -EFAULT;
@@ -90,7 +87,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
90 87
91 dev_entry->dev = dev; 88 dev_entry->dev = dev;
92 89
93 spin_lock_irqsave(&vpci_dev->lock, flags); 90 mutex_lock(&vpci_dev->lock);
94 91
95 /* Keep multi-function devices together on the virtual PCI bus */ 92 /* Keep multi-function devices together on the virtual PCI bus */
96 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 93 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
@@ -129,7 +126,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
129 "No more space on root virtual PCI bus"); 126 "No more space on root virtual PCI bus");
130 127
131unlock: 128unlock:
132 spin_unlock_irqrestore(&vpci_dev->lock, flags); 129 mutex_unlock(&vpci_dev->lock);
133 130
134 /* Publish this device. */ 131 /* Publish this device. */
135 if (!err) 132 if (!err)
@@ -145,14 +142,13 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
145 int slot; 142 int slot;
146 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 143 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
147 struct pci_dev *found_dev = NULL; 144 struct pci_dev *found_dev = NULL;
148 unsigned long flags;
149 145
150 spin_lock_irqsave(&vpci_dev->lock, flags); 146 mutex_lock(&vpci_dev->lock);
151 147
152 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 148 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
153 struct pci_dev_entry *e, *tmp; 149 struct pci_dev_entry *e;
154 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot], 150
155 list) { 151 list_for_each_entry(e, &vpci_dev->dev_list[slot], list) {
156 if (e->dev == dev) { 152 if (e->dev == dev) {
157 list_del(&e->list); 153 list_del(&e->list);
158 found_dev = e->dev; 154 found_dev = e->dev;
@@ -163,7 +159,7 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
163 } 159 }
164 160
165out: 161out:
166 spin_unlock_irqrestore(&vpci_dev->lock, flags); 162 mutex_unlock(&vpci_dev->lock);
167 163
168 if (found_dev) 164 if (found_dev)
169 pcistub_put_pci_dev(found_dev); 165 pcistub_put_pci_dev(found_dev);
@@ -178,7 +174,7 @@ static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
178 if (!vpci_dev) 174 if (!vpci_dev)
179 return -ENOMEM; 175 return -ENOMEM;
180 176
181 spin_lock_init(&vpci_dev->lock); 177 mutex_init(&vpci_dev->lock);
182 178
183 for (slot = 0; slot < PCI_SLOT_MAX; slot++) 179 for (slot = 0; slot < PCI_SLOT_MAX; slot++)
184 INIT_LIST_HEAD(&vpci_dev->dev_list[slot]); 180 INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
@@ -222,10 +218,9 @@ static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
222 struct pci_dev_entry *entry; 218 struct pci_dev_entry *entry;
223 struct pci_dev *dev = NULL; 219 struct pci_dev *dev = NULL;
224 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 220 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
225 unsigned long flags;
226 int found = 0, slot; 221 int found = 0, slot;
227 222
228 spin_lock_irqsave(&vpci_dev->lock, flags); 223 mutex_lock(&vpci_dev->lock);
229 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 224 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
230 list_for_each_entry(entry, 225 list_for_each_entry(entry,
231 &vpci_dev->dev_list[slot], 226 &vpci_dev->dev_list[slot],
@@ -243,11 +238,11 @@ static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
243 } 238 }
244 } 239 }
245 } 240 }
246 spin_unlock_irqrestore(&vpci_dev->lock, flags); 241 mutex_unlock(&vpci_dev->lock);
247 return found; 242 return found;
248} 243}
249 244
250struct xen_pcibk_backend xen_pcibk_vpci_backend = { 245const struct xen_pcibk_backend xen_pcibk_vpci_backend = {
251 .name = "vpci", 246 .name = "vpci",
252 .init = __xen_pcibk_init_devices, 247 .init = __xen_pcibk_init_devices,
253 .free = __xen_pcibk_release_devices, 248 .free = __xen_pcibk_release_devices,
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
index 978d2c6f5dca..474d52ec3374 100644
--- a/drivers/xen/xen-pciback/xenbus.c
+++ b/drivers/xen/xen-pciback/xenbus.c
@@ -13,7 +13,6 @@
13#include <asm/xen/pci.h> 13#include <asm/xen/pci.h>
14#include "pciback.h" 14#include "pciback.h"
15 15
16#define DRV_NAME "xen-pciback"
17#define INVALID_EVTCHN_IRQ (-1) 16#define INVALID_EVTCHN_IRQ (-1)
18struct workqueue_struct *xen_pcibk_wq; 17struct workqueue_struct *xen_pcibk_wq;
19 18
@@ -44,7 +43,7 @@ static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)
44 pdev->xdev = xdev; 43 pdev->xdev = xdev;
45 dev_set_drvdata(&xdev->dev, pdev); 44 dev_set_drvdata(&xdev->dev, pdev);
46 45
47 spin_lock_init(&pdev->dev_lock); 46 mutex_init(&pdev->dev_lock);
48 47
49 pdev->sh_info = NULL; 48 pdev->sh_info = NULL;
50 pdev->evtchn_irq = INVALID_EVTCHN_IRQ; 49 pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
@@ -62,14 +61,12 @@ out:
62 61
63static void xen_pcibk_disconnect(struct xen_pcibk_device *pdev) 62static void xen_pcibk_disconnect(struct xen_pcibk_device *pdev)
64{ 63{
65 spin_lock(&pdev->dev_lock); 64 mutex_lock(&pdev->dev_lock);
66
67 /* Ensure the guest can't trigger our handler before removing devices */ 65 /* Ensure the guest can't trigger our handler before removing devices */
68 if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) { 66 if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) {
69 unbind_from_irqhandler(pdev->evtchn_irq, pdev); 67 unbind_from_irqhandler(pdev->evtchn_irq, pdev);
70 pdev->evtchn_irq = INVALID_EVTCHN_IRQ; 68 pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
71 } 69 }
72 spin_unlock(&pdev->dev_lock);
73 70
74 /* If the driver domain started an op, make sure we complete it 71 /* If the driver domain started an op, make sure we complete it
75 * before releasing the shared memory */ 72 * before releasing the shared memory */
@@ -77,13 +74,11 @@ static void xen_pcibk_disconnect(struct xen_pcibk_device *pdev)
77 /* Note, the workqueue does not use spinlocks at all.*/ 74 /* Note, the workqueue does not use spinlocks at all.*/
78 flush_workqueue(xen_pcibk_wq); 75 flush_workqueue(xen_pcibk_wq);
79 76
80 spin_lock(&pdev->dev_lock);
81 if (pdev->sh_info != NULL) { 77 if (pdev->sh_info != NULL) {
82 xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info); 78 xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info);
83 pdev->sh_info = NULL; 79 pdev->sh_info = NULL;
84 } 80 }
85 spin_unlock(&pdev->dev_lock); 81 mutex_unlock(&pdev->dev_lock);
86
87} 82}
88 83
89static void free_pdev(struct xen_pcibk_device *pdev) 84static void free_pdev(struct xen_pcibk_device *pdev)
@@ -120,9 +115,7 @@ static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref,
120 goto out; 115 goto out;
121 } 116 }
122 117
123 spin_lock(&pdev->dev_lock);
124 pdev->sh_info = vaddr; 118 pdev->sh_info = vaddr;
125 spin_unlock(&pdev->dev_lock);
126 119
127 err = bind_interdomain_evtchn_to_irqhandler( 120 err = bind_interdomain_evtchn_to_irqhandler(
128 pdev->xdev->otherend_id, remote_evtchn, xen_pcibk_handle_event, 121 pdev->xdev->otherend_id, remote_evtchn, xen_pcibk_handle_event,
@@ -132,10 +125,7 @@ static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref,
132 "Error binding event channel to IRQ"); 125 "Error binding event channel to IRQ");
133 goto out; 126 goto out;
134 } 127 }
135
136 spin_lock(&pdev->dev_lock);
137 pdev->evtchn_irq = err; 128 pdev->evtchn_irq = err;
138 spin_unlock(&pdev->dev_lock);
139 err = 0; 129 err = 0;
140 130
141 dev_dbg(&pdev->xdev->dev, "Attached!\n"); 131 dev_dbg(&pdev->xdev->dev, "Attached!\n");
@@ -150,6 +140,7 @@ static int xen_pcibk_attach(struct xen_pcibk_device *pdev)
150 char *magic = NULL; 140 char *magic = NULL;
151 141
152 142
143 mutex_lock(&pdev->dev_lock);
153 /* Make sure we only do this setup once */ 144 /* Make sure we only do this setup once */
154 if (xenbus_read_driver_state(pdev->xdev->nodename) != 145 if (xenbus_read_driver_state(pdev->xdev->nodename) !=
155 XenbusStateInitialised) 146 XenbusStateInitialised)
@@ -176,7 +167,7 @@ static int xen_pcibk_attach(struct xen_pcibk_device *pdev)
176 if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) { 167 if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) {
177 xenbus_dev_fatal(pdev->xdev, -EFAULT, 168 xenbus_dev_fatal(pdev->xdev, -EFAULT,
178 "version mismatch (%s/%s) with pcifront - " 169 "version mismatch (%s/%s) with pcifront - "
179 "halting xen_pcibk", 170 "halting " DRV_NAME,
180 magic, XEN_PCI_MAGIC); 171 magic, XEN_PCI_MAGIC);
181 goto out; 172 goto out;
182 } 173 }
@@ -194,6 +185,7 @@ static int xen_pcibk_attach(struct xen_pcibk_device *pdev)
194 185
195 dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err); 186 dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err);
196out: 187out:
188 mutex_unlock(&pdev->dev_lock);
197 189
198 kfree(magic); 190 kfree(magic);
199 191
@@ -369,6 +361,7 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev)
369 361
370 dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n"); 362 dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n");
371 363
364 mutex_lock(&pdev->dev_lock);
372 /* Make sure we only reconfigure once */ 365 /* Make sure we only reconfigure once */
373 if (xenbus_read_driver_state(pdev->xdev->nodename) != 366 if (xenbus_read_driver_state(pdev->xdev->nodename) !=
374 XenbusStateReconfiguring) 367 XenbusStateReconfiguring)
@@ -506,6 +499,7 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev)
506 } 499 }
507 500
508out: 501out:
502 mutex_unlock(&pdev->dev_lock);
509 return 0; 503 return 0;
510} 504}
511 505
@@ -562,6 +556,7 @@ static int xen_pcibk_setup_backend(struct xen_pcibk_device *pdev)
562 char dev_str[64]; 556 char dev_str[64];
563 char state_str[64]; 557 char state_str[64];
564 558
559 mutex_lock(&pdev->dev_lock);
565 /* It's possible we could get the call to setup twice, so make sure 560 /* It's possible we could get the call to setup twice, so make sure
566 * we're not already connected. 561 * we're not already connected.
567 */ 562 */
@@ -642,10 +637,10 @@ static int xen_pcibk_setup_backend(struct xen_pcibk_device *pdev)
642 "Error switching to initialised state!"); 637 "Error switching to initialised state!");
643 638
644out: 639out:
640 mutex_unlock(&pdev->dev_lock);
645 if (!err) 641 if (!err)
646 /* see if pcifront is already configured (if not, we'll wait) */ 642 /* see if pcifront is already configured (if not, we'll wait) */
647 xen_pcibk_attach(pdev); 643 xen_pcibk_attach(pdev);
648
649 return err; 644 return err;
650} 645}
651 646
@@ -724,7 +719,7 @@ static struct xenbus_driver xenbus_xen_pcibk_driver = {
724 .otherend_changed = xen_pcibk_frontend_changed, 719 .otherend_changed = xen_pcibk_frontend_changed,
725}; 720};
726 721
727struct xen_pcibk_backend *xen_pcibk_backend; 722const struct xen_pcibk_backend *__read_mostly xen_pcibk_backend;
728 723
729int __init xen_pcibk_xenbus_register(void) 724int __init xen_pcibk_xenbus_register(void)
730{ 725{
diff --git a/drivers/xen/xenbus/xenbus_comms.c b/drivers/xen/xenbus/xenbus_comms.c
index 090c61ee8fd0..2eff7a6aaa20 100644
--- a/drivers/xen/xenbus/xenbus_comms.c
+++ b/drivers/xen/xenbus/xenbus_comms.c
@@ -212,7 +212,9 @@ int xb_init_comms(void)
212 printk(KERN_WARNING "XENBUS response ring is not quiescent " 212 printk(KERN_WARNING "XENBUS response ring is not quiescent "
213 "(%08x:%08x): fixing up\n", 213 "(%08x:%08x): fixing up\n",
214 intf->rsp_cons, intf->rsp_prod); 214 intf->rsp_cons, intf->rsp_prod);
215 intf->rsp_cons = intf->rsp_prod; 215 /* breaks kdump */
216 if (!reset_devices)
217 intf->rsp_cons = intf->rsp_prod;
216 } 218 }
217 219
218 if (xenbus_irq) { 220 if (xenbus_irq) {
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index bd2f90c9ac8b..cef9b0bf63d5 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -684,64 +684,74 @@ static int __init xenbus_probe_initcall(void)
684 684
685device_initcall(xenbus_probe_initcall); 685device_initcall(xenbus_probe_initcall);
686 686
687static int __init xenbus_init(void) 687/* Set up event channel for xenstored which is run as a local process
688 * (this is normally used only in dom0)
689 */
690static int __init xenstored_local_init(void)
688{ 691{
689 int err = 0; 692 int err = 0;
690 unsigned long page = 0; 693 unsigned long page = 0;
694 struct evtchn_alloc_unbound alloc_unbound;
691 695
692 DPRINTK(""); 696 /* Allocate Xenstore page */
697 page = get_zeroed_page(GFP_KERNEL);
698 if (!page)
699 goto out_err;
693 700
694 err = -ENODEV; 701 xen_store_mfn = xen_start_info->store_mfn =
695 if (!xen_domain()) 702 pfn_to_mfn(virt_to_phys((void *)page) >>
696 return err; 703 PAGE_SHIFT);
697 704
698 /* 705 /* Next allocate a local port which xenstored can bind to */
699 * Domain0 doesn't have a store_evtchn or store_mfn yet. 706 alloc_unbound.dom = DOMID_SELF;
700 */ 707 alloc_unbound.remote_dom = DOMID_SELF;
701 if (xen_initial_domain()) {
702 struct evtchn_alloc_unbound alloc_unbound;
703 708
704 /* Allocate Xenstore page */ 709 err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
705 page = get_zeroed_page(GFP_KERNEL); 710 &alloc_unbound);
706 if (!page) 711 if (err == -ENOSYS)
707 goto out_error; 712 goto out_err;
708 713
709 xen_store_mfn = xen_start_info->store_mfn = 714 BUG_ON(err);
710 pfn_to_mfn(virt_to_phys((void *)page) >> 715 xen_store_evtchn = xen_start_info->store_evtchn =
711 PAGE_SHIFT); 716 alloc_unbound.port;
712 717
713 /* Next allocate a local port which xenstored can bind to */ 718 return 0;
714 alloc_unbound.dom = DOMID_SELF;
715 alloc_unbound.remote_dom = 0;
716 719
717 err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, 720 out_err:
718 &alloc_unbound); 721 if (page != 0)
719 if (err == -ENOSYS) 722 free_page(page);
720 goto out_error; 723 return err;
724}
721 725
722 BUG_ON(err); 726static int __init xenbus_init(void)
723 xen_store_evtchn = xen_start_info->store_evtchn = 727{
724 alloc_unbound.port; 728 int err = 0;
725 729
726 xen_store_interface = mfn_to_virt(xen_store_mfn); 730 if (!xen_domain())
731 return -ENODEV;
732
733 if (xen_hvm_domain()) {
734 uint64_t v = 0;
735 err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
736 if (err)
737 goto out_error;
738 xen_store_evtchn = (int)v;
739 err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
740 if (err)
741 goto out_error;
742 xen_store_mfn = (unsigned long)v;
743 xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
727 } else { 744 } else {
728 if (xen_hvm_domain()) { 745 xen_store_evtchn = xen_start_info->store_evtchn;
729 uint64_t v = 0; 746 xen_store_mfn = xen_start_info->store_mfn;
730 err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); 747 if (xen_store_evtchn)
731 if (err) 748 xenstored_ready = 1;
732 goto out_error; 749 else {
733 xen_store_evtchn = (int)v; 750 err = xenstored_local_init();
734 err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
735 if (err) 751 if (err)
736 goto out_error; 752 goto out_error;
737 xen_store_mfn = (unsigned long)v;
738 xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
739 } else {
740 xen_store_evtchn = xen_start_info->store_evtchn;
741 xen_store_mfn = xen_start_info->store_mfn;
742 xen_store_interface = mfn_to_virt(xen_store_mfn);
743 xenstored_ready = 1;
744 } 753 }
754 xen_store_interface = mfn_to_virt(xen_store_mfn);
745 } 755 }
746 756
747 /* Initialize the interface to xenstore. */ 757 /* Initialize the interface to xenstore. */
@@ -760,12 +770,7 @@ static int __init xenbus_init(void)
760 proc_mkdir("xen", NULL); 770 proc_mkdir("xen", NULL);
761#endif 771#endif
762 772
763 return 0; 773 out_error:
764
765 out_error:
766 if (page != 0)
767 free_page(page);
768
769 return err; 774 return err;
770} 775}
771 776
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index ed2ba474a560..540587e18a94 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -248,10 +248,131 @@ int __xenbus_register_frontend(struct xenbus_driver *drv,
248} 248}
249EXPORT_SYMBOL_GPL(__xenbus_register_frontend); 249EXPORT_SYMBOL_GPL(__xenbus_register_frontend);
250 250
251static DECLARE_WAIT_QUEUE_HEAD(backend_state_wq);
252static int backend_state;
253
254static void xenbus_reset_backend_state_changed(struct xenbus_watch *w,
255 const char **v, unsigned int l)
256{
257 xenbus_scanf(XBT_NIL, v[XS_WATCH_PATH], "", "%i", &backend_state);
258 printk(KERN_DEBUG "XENBUS: backend %s %s\n",
259 v[XS_WATCH_PATH], xenbus_strstate(backend_state));
260 wake_up(&backend_state_wq);
261}
262
263static void xenbus_reset_wait_for_backend(char *be, int expected)
264{
265 long timeout;
266 timeout = wait_event_interruptible_timeout(backend_state_wq,
267 backend_state == expected, 5 * HZ);
268 if (timeout <= 0)
269 printk(KERN_INFO "XENBUS: backend %s timed out.\n", be);
270}
271
272/*
273 * Reset frontend if it is in Connected or Closed state.
274 * Wait for backend to catch up.
275 * State Connected happens during kdump, Closed after kexec.
276 */
277static void xenbus_reset_frontend(char *fe, char *be, int be_state)
278{
279 struct xenbus_watch be_watch;
280
281 printk(KERN_DEBUG "XENBUS: backend %s %s\n",
282 be, xenbus_strstate(be_state));
283
284 memset(&be_watch, 0, sizeof(be_watch));
285 be_watch.node = kasprintf(GFP_NOIO | __GFP_HIGH, "%s/state", be);
286 if (!be_watch.node)
287 return;
288
289 be_watch.callback = xenbus_reset_backend_state_changed;
290 backend_state = XenbusStateUnknown;
291
292 printk(KERN_INFO "XENBUS: triggering reconnect on %s\n", be);
293 register_xenbus_watch(&be_watch);
294
295 /* fall through to forward backend to state XenbusStateInitialising */
296 switch (be_state) {
297 case XenbusStateConnected:
298 xenbus_printf(XBT_NIL, fe, "state", "%d", XenbusStateClosing);
299 xenbus_reset_wait_for_backend(be, XenbusStateClosing);
300
301 case XenbusStateClosing:
302 xenbus_printf(XBT_NIL, fe, "state", "%d", XenbusStateClosed);
303 xenbus_reset_wait_for_backend(be, XenbusStateClosed);
304
305 case XenbusStateClosed:
306 xenbus_printf(XBT_NIL, fe, "state", "%d", XenbusStateInitialising);
307 xenbus_reset_wait_for_backend(be, XenbusStateInitWait);
308 }
309
310 unregister_xenbus_watch(&be_watch);
311 printk(KERN_INFO "XENBUS: reconnect done on %s\n", be);
312 kfree(be_watch.node);
313}
314
315static void xenbus_check_frontend(char *class, char *dev)
316{
317 int be_state, fe_state, err;
318 char *backend, *frontend;
319
320 frontend = kasprintf(GFP_NOIO | __GFP_HIGH, "device/%s/%s", class, dev);
321 if (!frontend)
322 return;
323
324 err = xenbus_scanf(XBT_NIL, frontend, "state", "%i", &fe_state);
325 if (err != 1)
326 goto out;
327
328 switch (fe_state) {
329 case XenbusStateConnected:
330 case XenbusStateClosed:
331 printk(KERN_DEBUG "XENBUS: frontend %s %s\n",
332 frontend, xenbus_strstate(fe_state));
333 backend = xenbus_read(XBT_NIL, frontend, "backend", NULL);
334 if (!backend || IS_ERR(backend))
335 goto out;
336 err = xenbus_scanf(XBT_NIL, backend, "state", "%i", &be_state);
337 if (err == 1)
338 xenbus_reset_frontend(frontend, backend, be_state);
339 kfree(backend);
340 break;
341 default:
342 break;
343 }
344out:
345 kfree(frontend);
346}
347
348static void xenbus_reset_state(void)
349{
350 char **devclass, **dev;
351 int devclass_n, dev_n;
352 int i, j;
353
354 devclass = xenbus_directory(XBT_NIL, "device", "", &devclass_n);
355 if (IS_ERR(devclass))
356 return;
357
358 for (i = 0; i < devclass_n; i++) {
359 dev = xenbus_directory(XBT_NIL, "device", devclass[i], &dev_n);
360 if (IS_ERR(dev))
361 continue;
362 for (j = 0; j < dev_n; j++)
363 xenbus_check_frontend(devclass[i], dev[j]);
364 kfree(dev);
365 }
366 kfree(devclass);
367}
368
251static int frontend_probe_and_watch(struct notifier_block *notifier, 369static int frontend_probe_and_watch(struct notifier_block *notifier,
252 unsigned long event, 370 unsigned long event,
253 void *data) 371 void *data)
254{ 372{
373 /* reset devices in Connected or Closed state */
374 if (xen_hvm_domain())
375 xenbus_reset_state();
255 /* Enumerate devices in xenstore and watch for changes. */ 376 /* Enumerate devices in xenstore and watch for changes. */
256 xenbus_probe_devices(&xenbus_frontend); 377 xenbus_probe_devices(&xenbus_frontend);
257 register_xenbus_watch(&fe_watch); 378 register_xenbus_watch(&fe_watch);
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index 5534690075af..b3b8f2f3ad10 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -45,6 +45,7 @@
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/mutex.h> 46#include <linux/mutex.h>
47#include <xen/xenbus.h> 47#include <xen/xenbus.h>
48#include <xen/xen.h>
48#include "xenbus_comms.h" 49#include "xenbus_comms.h"
49 50
50struct xs_stored_msg { 51struct xs_stored_msg {
@@ -620,6 +621,15 @@ static struct xenbus_watch *find_watch(const char *token)
620 return NULL; 621 return NULL;
621} 622}
622 623
624static void xs_reset_watches(void)
625{
626 int err;
627
628 err = xs_error(xs_single(XBT_NIL, XS_RESET_WATCHES, "", NULL));
629 if (err && err != -EEXIST)
630 printk(KERN_WARNING "xs_reset_watches failed: %d\n", err);
631}
632
623/* Register callback to watch this node. */ 633/* Register callback to watch this node. */
624int register_xenbus_watch(struct xenbus_watch *watch) 634int register_xenbus_watch(struct xenbus_watch *watch)
625{ 635{
@@ -638,8 +648,7 @@ int register_xenbus_watch(struct xenbus_watch *watch)
638 648
639 err = xs_watch(watch->node, token); 649 err = xs_watch(watch->node, token);
640 650
641 /* Ignore errors due to multiple registration. */ 651 if (err) {
642 if ((err != 0) && (err != -EEXIST)) {
643 spin_lock(&watches_lock); 652 spin_lock(&watches_lock);
644 list_del(&watch->list); 653 list_del(&watch->list);
645 spin_unlock(&watches_lock); 654 spin_unlock(&watches_lock);
@@ -897,5 +906,9 @@ int xs_init(void)
897 if (IS_ERR(task)) 906 if (IS_ERR(task))
898 return PTR_ERR(task); 907 return PTR_ERR(task);
899 908
909 /* shutdown watches for kexec boot */
910 if (xen_hvm_domain())
911 xs_reset_watches();
912
900 return 0; 913 return 0;
901} 914}