aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/xen/page.h15
-rw-r--r--arch/arm/xen/p2m.c32
-rw-r--r--arch/x86/include/asm/xen/page.h11
-rw-r--r--arch/x86/pci/xen.c29
-rw-r--r--arch/x86/xen/Kconfig5
-rw-r--r--arch/x86/xen/p2m.c121
-rw-r--r--drivers/xen/events/events_base.c83
-rw-r--r--drivers/xen/events/events_internal.h1
-rw-r--r--drivers/xen/grant-table.c73
-rw-r--r--drivers/xen/manage.c16
-rw-r--r--drivers/xen/pcpu.c1
-rw-r--r--drivers/xen/platform-pci.c2
-rw-r--r--drivers/xen/xen-acpi-processor.c15
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c3
-rw-r--r--drivers/xen/xen-selfballoon.c1
-rw-r--r--drivers/xen/xenbus/xenbus_client.c27
-rw-r--r--include/xen/events.h6
-rw-r--r--include/xen/interface/physdev.h10
-rw-r--r--include/xen/xen-ops.h4
-rw-r--r--include/xen/xenbus.h1
20 files changed, 265 insertions, 191 deletions
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index e0965abacb7d..cf4f3e867395 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -97,16 +97,13 @@ static inline pte_t *lookup_address(unsigned long address, unsigned int *level)
97 return NULL; 97 return NULL;
98} 98}
99 99
100static inline int m2p_add_override(unsigned long mfn, struct page *page, 100extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
101 struct gnttab_map_grant_ref *kmap_op) 101 struct gnttab_map_grant_ref *kmap_ops,
102{ 102 struct page **pages, unsigned int count);
103 return 0;
104}
105 103
106static inline int m2p_remove_override(struct page *page, bool clear_pte) 104extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
107{ 105 struct gnttab_map_grant_ref *kmap_ops,
108 return 0; 106 struct page **pages, unsigned int count);
109}
110 107
111bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); 108bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
112bool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn, 109bool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn,
diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c
index b31ee1b275b0..97baf4427817 100644
--- a/arch/arm/xen/p2m.c
+++ b/arch/arm/xen/p2m.c
@@ -146,6 +146,38 @@ unsigned long __mfn_to_pfn(unsigned long mfn)
146} 146}
147EXPORT_SYMBOL_GPL(__mfn_to_pfn); 147EXPORT_SYMBOL_GPL(__mfn_to_pfn);
148 148
149int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
150 struct gnttab_map_grant_ref *kmap_ops,
151 struct page **pages, unsigned int count)
152{
153 int i;
154
155 for (i = 0; i < count; i++) {
156 if (map_ops[i].status)
157 continue;
158 set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT,
159 map_ops[i].dev_bus_addr >> PAGE_SHIFT);
160 }
161
162 return 0;
163}
164EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping);
165
166int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
167 struct gnttab_map_grant_ref *kmap_ops,
168 struct page **pages, unsigned int count)
169{
170 int i;
171
172 for (i = 0; i < count; i++) {
173 set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT,
174 INVALID_P2M_ENTRY);
175 }
176
177 return 0;
178}
179EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping);
180
149bool __set_phys_to_machine_multi(unsigned long pfn, 181bool __set_phys_to_machine_multi(unsigned long pfn,
150 unsigned long mfn, unsigned long nr_pages) 182 unsigned long mfn, unsigned long nr_pages)
151{ 183{
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 3e276eb23d1b..c949923a5668 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -49,10 +49,17 @@ extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
49extern unsigned long set_phys_range_identity(unsigned long pfn_s, 49extern unsigned long set_phys_range_identity(unsigned long pfn_s,
50 unsigned long pfn_e); 50 unsigned long pfn_e);
51 51
52extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
53 struct gnttab_map_grant_ref *kmap_ops,
54 struct page **pages, unsigned int count);
52extern int m2p_add_override(unsigned long mfn, struct page *page, 55extern int m2p_add_override(unsigned long mfn, struct page *page,
53 struct gnttab_map_grant_ref *kmap_op); 56 struct gnttab_map_grant_ref *kmap_op);
57extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
58 struct gnttab_map_grant_ref *kmap_ops,
59 struct page **pages, unsigned int count);
54extern int m2p_remove_override(struct page *page, 60extern int m2p_remove_override(struct page *page,
55 struct gnttab_map_grant_ref *kmap_op); 61 struct gnttab_map_grant_ref *kmap_op,
62 unsigned long mfn);
56extern struct page *m2p_find_override(unsigned long mfn); 63extern struct page *m2p_find_override(unsigned long mfn);
57extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); 64extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
58 65
@@ -121,7 +128,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
121 pfn = m2p_find_override_pfn(mfn, ~0); 128 pfn = m2p_find_override_pfn(mfn, ~0);
122 } 129 }
123 130
124 /* 131 /*
125 * pfn is ~0 if there are no entries in the m2p for mfn or if the 132 * pfn is ~0 if there are no entries in the m2p for mfn or if the
126 * entry doesn't map back to the mfn and m2p_override doesn't have a 133 * entry doesn't map back to the mfn and m2p_override doesn't have a
127 * valid entry for it. 134 * valid entry for it.
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 103e702ec5a7..905956f16465 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -178,6 +178,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
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], 180 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
181 (type == PCI_CAP_ID_MSI) ? nvec : 1,
181 (type == PCI_CAP_ID_MSIX) ? 182 (type == PCI_CAP_ID_MSIX) ?
182 "pcifront-msi-x" : 183 "pcifront-msi-x" :
183 "pcifront-msi", 184 "pcifront-msi",
@@ -245,6 +246,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
245 "xen: msi already bound to pirq=%d\n", pirq); 246 "xen: msi already bound to pirq=%d\n", pirq);
246 } 247 }
247 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 248 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
249 (type == PCI_CAP_ID_MSI) ? nvec : 1,
248 (type == PCI_CAP_ID_MSIX) ? 250 (type == PCI_CAP_ID_MSIX) ?
249 "msi-x" : "msi", 251 "msi-x" : "msi",
250 DOMID_SELF); 252 DOMID_SELF);
@@ -269,9 +271,6 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
269 int ret = 0; 271 int ret = 0;
270 struct msi_desc *msidesc; 272 struct msi_desc *msidesc;
271 273
272 if (type == PCI_CAP_ID_MSI && nvec > 1)
273 return 1;
274
275 list_for_each_entry(msidesc, &dev->msi_list, list) { 274 list_for_each_entry(msidesc, &dev->msi_list, list) {
276 struct physdev_map_pirq map_irq; 275 struct physdev_map_pirq map_irq;
277 domid_t domid; 276 domid_t domid;
@@ -291,7 +290,10 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
291 (pci_domain_nr(dev->bus) << 16); 290 (pci_domain_nr(dev->bus) << 16);
292 map_irq.devfn = dev->devfn; 291 map_irq.devfn = dev->devfn;
293 292
294 if (type == PCI_CAP_ID_MSIX) { 293 if (type == PCI_CAP_ID_MSI && nvec > 1) {
294 map_irq.type = MAP_PIRQ_TYPE_MULTI_MSI;
295 map_irq.entry_nr = nvec;
296 } else if (type == PCI_CAP_ID_MSIX) {
295 int pos; 297 int pos;
296 u32 table_offset, bir; 298 u32 table_offset, bir;
297 299
@@ -308,6 +310,16 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
308 if (pci_seg_supported) 310 if (pci_seg_supported)
309 ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, 311 ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq,
310 &map_irq); 312 &map_irq);
313 if (type == PCI_CAP_ID_MSI && nvec > 1 && ret) {
314 /*
315 * If MAP_PIRQ_TYPE_MULTI_MSI is not available
316 * there's nothing else we can do in this case.
317 * Just set ret > 0 so driver can retry with
318 * single MSI.
319 */
320 ret = 1;
321 goto out;
322 }
311 if (ret == -EINVAL && !pci_domain_nr(dev->bus)) { 323 if (ret == -EINVAL && !pci_domain_nr(dev->bus)) {
312 map_irq.type = MAP_PIRQ_TYPE_MSI; 324 map_irq.type = MAP_PIRQ_TYPE_MSI;
313 map_irq.index = -1; 325 map_irq.index = -1;
@@ -324,11 +336,10 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
324 goto out; 336 goto out;
325 } 337 }
326 338
327 ret = xen_bind_pirq_msi_to_irq(dev, msidesc, 339 ret = xen_bind_pirq_msi_to_irq(dev, msidesc, map_irq.pirq,
328 map_irq.pirq, 340 (type == PCI_CAP_ID_MSI) ? nvec : 1,
329 (type == PCI_CAP_ID_MSIX) ? 341 (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi",
330 "msi-x" : "msi", 342 domid);
331 domid);
332 if (ret < 0) 343 if (ret < 0)
333 goto out; 344 goto out;
334 } 345 }
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 9c50cc2e403b..e88fda867a33 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -19,11 +19,6 @@ config XEN_DOM0
19 depends on XEN && PCI_XEN && SWIOTLB_XEN 19 depends on XEN && PCI_XEN && SWIOTLB_XEN
20 depends on X86_LOCAL_APIC && X86_IO_APIC && ACPI && PCI 20 depends on X86_LOCAL_APIC && X86_IO_APIC && ACPI && PCI
21 21
22# Dummy symbol since people have come to rely on the PRIVILEGED_GUEST
23# name in tools.
24config XEN_PRIVILEGED_GUEST
25 def_bool XEN_DOM0
26
27config XEN_PVHVM 22config XEN_PVHVM
28 def_bool y 23 def_bool y
29 depends on XEN && PCI && X86_LOCAL_APIC 24 depends on XEN && PCI && X86_LOCAL_APIC
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 696c694986d0..85e5d78c9874 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -881,6 +881,65 @@ static unsigned long mfn_hash(unsigned long mfn)
881 return hash_long(mfn, M2P_OVERRIDE_HASH_SHIFT); 881 return hash_long(mfn, M2P_OVERRIDE_HASH_SHIFT);
882} 882}
883 883
884int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
885 struct gnttab_map_grant_ref *kmap_ops,
886 struct page **pages, unsigned int count)
887{
888 int i, ret = 0;
889 bool lazy = false;
890 pte_t *pte;
891
892 if (xen_feature(XENFEAT_auto_translated_physmap))
893 return 0;
894
895 if (kmap_ops &&
896 !in_interrupt() &&
897 paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) {
898 arch_enter_lazy_mmu_mode();
899 lazy = true;
900 }
901
902 for (i = 0; i < count; i++) {
903 unsigned long mfn, pfn;
904
905 /* Do not add to override if the map failed. */
906 if (map_ops[i].status)
907 continue;
908
909 if (map_ops[i].flags & GNTMAP_contains_pte) {
910 pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
911 (map_ops[i].host_addr & ~PAGE_MASK));
912 mfn = pte_mfn(*pte);
913 } else {
914 mfn = PFN_DOWN(map_ops[i].dev_bus_addr);
915 }
916 pfn = page_to_pfn(pages[i]);
917
918 WARN_ON(PagePrivate(pages[i]));
919 SetPagePrivate(pages[i]);
920 set_page_private(pages[i], mfn);
921 pages[i]->index = pfn_to_mfn(pfn);
922
923 if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) {
924 ret = -ENOMEM;
925 goto out;
926 }
927
928 if (kmap_ops) {
929 ret = m2p_add_override(mfn, pages[i], &kmap_ops[i]);
930 if (ret)
931 goto out;
932 }
933 }
934
935out:
936 if (lazy)
937 arch_leave_lazy_mmu_mode();
938
939 return ret;
940}
941EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping);
942
884/* Add an MFN override for a particular page */ 943/* Add an MFN override for a particular page */
885int m2p_add_override(unsigned long mfn, struct page *page, 944int m2p_add_override(unsigned long mfn, struct page *page,
886 struct gnttab_map_grant_ref *kmap_op) 945 struct gnttab_map_grant_ref *kmap_op)
@@ -899,13 +958,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
899 "m2p_add_override: pfn %lx not mapped", pfn)) 958 "m2p_add_override: pfn %lx not mapped", pfn))
900 return -EINVAL; 959 return -EINVAL;
901 } 960 }
902 WARN_ON(PagePrivate(page));
903 SetPagePrivate(page);
904 set_page_private(page, mfn);
905 page->index = pfn_to_mfn(pfn);
906
907 if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn))))
908 return -ENOMEM;
909 961
910 if (kmap_op != NULL) { 962 if (kmap_op != NULL) {
911 if (!PageHighMem(page)) { 963 if (!PageHighMem(page)) {
@@ -943,20 +995,62 @@ int m2p_add_override(unsigned long mfn, struct page *page,
943 return 0; 995 return 0;
944} 996}
945EXPORT_SYMBOL_GPL(m2p_add_override); 997EXPORT_SYMBOL_GPL(m2p_add_override);
998
999int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
1000 struct gnttab_map_grant_ref *kmap_ops,
1001 struct page **pages, unsigned int count)
1002{
1003 int i, ret = 0;
1004 bool lazy = false;
1005
1006 if (xen_feature(XENFEAT_auto_translated_physmap))
1007 return 0;
1008
1009 if (kmap_ops &&
1010 !in_interrupt() &&
1011 paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) {
1012 arch_enter_lazy_mmu_mode();
1013 lazy = true;
1014 }
1015
1016 for (i = 0; i < count; i++) {
1017 unsigned long mfn = get_phys_to_machine(page_to_pfn(pages[i]));
1018 unsigned long pfn = page_to_pfn(pages[i]);
1019
1020 if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) {
1021 ret = -EINVAL;
1022 goto out;
1023 }
1024
1025 set_page_private(pages[i], INVALID_P2M_ENTRY);
1026 WARN_ON(!PagePrivate(pages[i]));
1027 ClearPagePrivate(pages[i]);
1028 set_phys_to_machine(pfn, pages[i]->index);
1029
1030 if (kmap_ops)
1031 ret = m2p_remove_override(pages[i], &kmap_ops[i], mfn);
1032 if (ret)
1033 goto out;
1034 }
1035
1036out:
1037 if (lazy)
1038 arch_leave_lazy_mmu_mode();
1039 return ret;
1040}
1041EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping);
1042
946int m2p_remove_override(struct page *page, 1043int m2p_remove_override(struct page *page,
947 struct gnttab_map_grant_ref *kmap_op) 1044 struct gnttab_map_grant_ref *kmap_op,
1045 unsigned long mfn)
948{ 1046{
949 unsigned long flags; 1047 unsigned long flags;
950 unsigned long mfn;
951 unsigned long pfn; 1048 unsigned long pfn;
952 unsigned long uninitialized_var(address); 1049 unsigned long uninitialized_var(address);
953 unsigned level; 1050 unsigned level;
954 pte_t *ptep = NULL; 1051 pte_t *ptep = NULL;
955 1052
956 pfn = page_to_pfn(page); 1053 pfn = page_to_pfn(page);
957 mfn = get_phys_to_machine(pfn);
958 if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT))
959 return -EINVAL;
960 1054
961 if (!PageHighMem(page)) { 1055 if (!PageHighMem(page)) {
962 address = (unsigned long)__va(pfn << PAGE_SHIFT); 1056 address = (unsigned long)__va(pfn << PAGE_SHIFT);
@@ -970,10 +1064,7 @@ int m2p_remove_override(struct page *page,
970 spin_lock_irqsave(&m2p_override_lock, flags); 1064 spin_lock_irqsave(&m2p_override_lock, flags);
971 list_del(&page->lru); 1065 list_del(&page->lru);
972 spin_unlock_irqrestore(&m2p_override_lock, flags); 1066 spin_unlock_irqrestore(&m2p_override_lock, flags);
973 WARN_ON(!PagePrivate(page));
974 ClearPagePrivate(page);
975 1067
976 set_phys_to_machine(pfn, page->index);
977 if (kmap_op != NULL) { 1068 if (kmap_op != NULL) {
978 if (!PageHighMem(page)) { 1069 if (!PageHighMem(page)) {
979 struct multicall_space mcs; 1070 struct multicall_space mcs;
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index c3458f58de90..d5a3de88ac59 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -388,10 +388,10 @@ static void xen_irq_init(unsigned irq)
388 list_add_tail(&info->list, &xen_irq_list_head); 388 list_add_tail(&info->list, &xen_irq_list_head);
389} 389}
390 390
391static int __must_check xen_allocate_irq_dynamic(void) 391static int __must_check xen_allocate_irqs_dynamic(int nvec)
392{ 392{
393 int first = 0; 393 int first = 0;
394 int irq; 394 int i, irq;
395 395
396#ifdef CONFIG_X86_IO_APIC 396#ifdef CONFIG_X86_IO_APIC
397 /* 397 /*
@@ -405,14 +405,22 @@ static int __must_check xen_allocate_irq_dynamic(void)
405 first = get_nr_irqs_gsi(); 405 first = get_nr_irqs_gsi();
406#endif 406#endif
407 407
408 irq = irq_alloc_desc_from(first, -1); 408 irq = irq_alloc_descs_from(first, nvec, -1);
409 409
410 if (irq >= 0) 410 if (irq >= 0) {
411 xen_irq_init(irq); 411 for (i = 0; i < nvec; i++)
412 xen_irq_init(irq + i);
413 }
412 414
413 return irq; 415 return irq;
414} 416}
415 417
418static inline int __must_check xen_allocate_irq_dynamic(void)
419{
420
421 return xen_allocate_irqs_dynamic(1);
422}
423
416static int __must_check xen_allocate_irq_gsi(unsigned gsi) 424static int __must_check xen_allocate_irq_gsi(unsigned gsi)
417{ 425{
418 int irq; 426 int irq;
@@ -466,9 +474,6 @@ static void xen_evtchn_close(unsigned int port)
466 close.port = port; 474 close.port = port;
467 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) 475 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
468 BUG(); 476 BUG();
469
470 /* Closed ports are implicitly re-bound to VCPU0. */
471 bind_evtchn_to_cpu(port, 0);
472} 477}
473 478
474static void pirq_query_unmask(int irq) 479static void pirq_query_unmask(int irq)
@@ -730,22 +735,25 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
730} 735}
731 736
732int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, 737int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
733 int pirq, const char *name, domid_t domid) 738 int pirq, int nvec, const char *name, domid_t domid)
734{ 739{
735 int irq, ret; 740 int i, irq, ret;
736 741
737 mutex_lock(&irq_mapping_update_lock); 742 mutex_lock(&irq_mapping_update_lock);
738 743
739 irq = xen_allocate_irq_dynamic(); 744 irq = xen_allocate_irqs_dynamic(nvec);
740 if (irq < 0) 745 if (irq < 0)
741 goto out; 746 goto out;
742 747
743 irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq, 748 for (i = 0; i < nvec; i++) {
744 name); 749 irq_set_chip_and_handler_name(irq + i, &xen_pirq_chip, handle_edge_irq, name);
750
751 ret = xen_irq_info_pirq_setup(irq + i, 0, pirq + i, 0, domid,
752 i == 0 ? 0 : PIRQ_MSI_GROUP);
753 if (ret < 0)
754 goto error_irq;
755 }
745 756
746 ret = xen_irq_info_pirq_setup(irq, 0, pirq, 0, domid, 0);
747 if (ret < 0)
748 goto error_irq;
749 ret = irq_set_msi_desc(irq, msidesc); 757 ret = irq_set_msi_desc(irq, msidesc);
750 if (ret < 0) 758 if (ret < 0)
751 goto error_irq; 759 goto error_irq;
@@ -753,7 +761,8 @@ out:
753 mutex_unlock(&irq_mapping_update_lock); 761 mutex_unlock(&irq_mapping_update_lock);
754 return irq; 762 return irq;
755error_irq: 763error_irq:
756 __unbind_from_irq(irq); 764 for (; i >= 0; i--)
765 __unbind_from_irq(irq + i);
757 mutex_unlock(&irq_mapping_update_lock); 766 mutex_unlock(&irq_mapping_update_lock);
758 return ret; 767 return ret;
759} 768}
@@ -767,7 +776,12 @@ int xen_destroy_irq(int irq)
767 776
768 mutex_lock(&irq_mapping_update_lock); 777 mutex_lock(&irq_mapping_update_lock);
769 778
770 if (xen_initial_domain()) { 779 /*
780 * If trying to remove a vector in a MSI group different
781 * than the first one skip the PIRQ unmap unless this vector
782 * is the first one in the group.
783 */
784 if (xen_initial_domain() && !(info->u.pirq.flags & PIRQ_MSI_GROUP)) {
771 unmap_irq.pirq = info->u.pirq.pirq; 785 unmap_irq.pirq = info->u.pirq.pirq;
772 unmap_irq.domid = info->u.pirq.domid; 786 unmap_irq.domid = info->u.pirq.domid;
773 rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq); 787 rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
@@ -1329,26 +1343,6 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
1329 return rebind_irq_to_cpu(data->irq, tcpu); 1343 return rebind_irq_to_cpu(data->irq, tcpu);
1330} 1344}
1331 1345
1332static int retrigger_evtchn(int evtchn)
1333{
1334 int masked;
1335
1336 if (!VALID_EVTCHN(evtchn))
1337 return 0;
1338
1339 masked = test_and_set_mask(evtchn);
1340 set_evtchn(evtchn);
1341 if (!masked)
1342 unmask_evtchn(evtchn);
1343
1344 return 1;
1345}
1346
1347int resend_irq_on_evtchn(unsigned int irq)
1348{
1349 return retrigger_evtchn(evtchn_from_irq(irq));
1350}
1351
1352static void enable_dynirq(struct irq_data *data) 1346static void enable_dynirq(struct irq_data *data)
1353{ 1347{
1354 int evtchn = evtchn_from_irq(data->irq); 1348 int evtchn = evtchn_from_irq(data->irq);
@@ -1383,7 +1377,18 @@ static void mask_ack_dynirq(struct irq_data *data)
1383 1377
1384static int retrigger_dynirq(struct irq_data *data) 1378static int retrigger_dynirq(struct irq_data *data)
1385{ 1379{
1386 return retrigger_evtchn(evtchn_from_irq(data->irq)); 1380 unsigned int evtchn = evtchn_from_irq(data->irq);
1381 int masked;
1382
1383 if (!VALID_EVTCHN(evtchn))
1384 return 0;
1385
1386 masked = test_and_set_mask(evtchn);
1387 set_evtchn(evtchn);
1388 if (!masked)
1389 unmask_evtchn(evtchn);
1390
1391 return 1;
1387} 1392}
1388 1393
1389static void restore_pirqs(void) 1394static void restore_pirqs(void)
diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h
index 677f41a0fff9..50c2050a1e32 100644
--- a/drivers/xen/events/events_internal.h
+++ b/drivers/xen/events/events_internal.h
@@ -53,6 +53,7 @@ struct irq_info {
53 53
54#define PIRQ_NEEDS_EOI (1 << 0) 54#define PIRQ_NEEDS_EOI (1 << 0)
55#define PIRQ_SHAREABLE (1 << 1) 55#define PIRQ_SHAREABLE (1 << 1)
56#define PIRQ_MSI_GROUP (1 << 2)
56 57
57struct evtchn_ops { 58struct evtchn_ops {
58 unsigned (*max_channels)(void); 59 unsigned (*max_channels)(void);
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index b84e3ab839aa..6d325bda76da 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -933,9 +933,6 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
933 struct page **pages, unsigned int count) 933 struct page **pages, unsigned int count)
934{ 934{
935 int i, ret; 935 int i, ret;
936 bool lazy = false;
937 pte_t *pte;
938 unsigned long mfn;
939 936
940 ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); 937 ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count);
941 if (ret) 938 if (ret)
@@ -947,45 +944,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
947 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i, 944 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i,
948 &map_ops[i].status, __func__); 945 &map_ops[i].status, __func__);
949 946
950 /* this is basically a nop on x86 */ 947 return set_foreign_p2m_mapping(map_ops, kmap_ops, pages, count);
951 if (xen_feature(XENFEAT_auto_translated_physmap)) {
952 for (i = 0; i < count; i++) {
953 if (map_ops[i].status)
954 continue;
955 set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT,
956 map_ops[i].dev_bus_addr >> PAGE_SHIFT);
957 }
958 return ret;
959 }
960
961 if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) {
962 arch_enter_lazy_mmu_mode();
963 lazy = true;
964 }
965
966 for (i = 0; i < count; i++) {
967 /* Do not add to override if the map failed. */
968 if (map_ops[i].status)
969 continue;
970
971 if (map_ops[i].flags & GNTMAP_contains_pte) {
972 pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
973 (map_ops[i].host_addr & ~PAGE_MASK));
974 mfn = pte_mfn(*pte);
975 } else {
976 mfn = PFN_DOWN(map_ops[i].dev_bus_addr);
977 }
978 ret = m2p_add_override(mfn, pages[i], kmap_ops ?
979 &kmap_ops[i] : NULL);
980 if (ret)
981 goto out;
982 }
983
984 out:
985 if (lazy)
986 arch_leave_lazy_mmu_mode();
987
988 return ret;
989} 948}
990EXPORT_SYMBOL_GPL(gnttab_map_refs); 949EXPORT_SYMBOL_GPL(gnttab_map_refs);
991 950
@@ -993,39 +952,13 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
993 struct gnttab_map_grant_ref *kmap_ops, 952 struct gnttab_map_grant_ref *kmap_ops,
994 struct page **pages, unsigned int count) 953 struct page **pages, unsigned int count)
995{ 954{
996 int i, ret; 955 int ret;
997 bool lazy = false;
998 956
999 ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); 957 ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count);
1000 if (ret) 958 if (ret)
1001 return ret; 959 return ret;
1002 960
1003 /* this is basically a nop on x86 */ 961 return clear_foreign_p2m_mapping(unmap_ops, kmap_ops, pages, count);
1004 if (xen_feature(XENFEAT_auto_translated_physmap)) {
1005 for (i = 0; i < count; i++) {
1006 set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT,
1007 INVALID_P2M_ENTRY);
1008 }
1009 return ret;
1010 }
1011
1012 if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) {
1013 arch_enter_lazy_mmu_mode();
1014 lazy = true;
1015 }
1016
1017 for (i = 0; i < count; i++) {
1018 ret = m2p_remove_override(pages[i], kmap_ops ?
1019 &kmap_ops[i] : NULL);
1020 if (ret)
1021 goto out;
1022 }
1023
1024 out:
1025 if (lazy)
1026 arch_leave_lazy_mmu_mode();
1027
1028 return ret;
1029} 962}
1030EXPORT_SYMBOL_GPL(gnttab_unmap_refs); 963EXPORT_SYMBOL_GPL(gnttab_unmap_refs);
1031 964
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 624e8dc24532..fc6c94c0b436 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -46,6 +46,20 @@ struct suspend_info {
46 void (*post)(int cancelled); 46 void (*post)(int cancelled);
47}; 47};
48 48
49static RAW_NOTIFIER_HEAD(xen_resume_notifier);
50
51void xen_resume_notifier_register(struct notifier_block *nb)
52{
53 raw_notifier_chain_register(&xen_resume_notifier, nb);
54}
55EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
56
57void xen_resume_notifier_unregister(struct notifier_block *nb)
58{
59 raw_notifier_chain_unregister(&xen_resume_notifier, nb);
60}
61EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
62
49#ifdef CONFIG_HIBERNATE_CALLBACKS 63#ifdef CONFIG_HIBERNATE_CALLBACKS
50static void xen_hvm_post_suspend(int cancelled) 64static void xen_hvm_post_suspend(int cancelled)
51{ 65{
@@ -152,6 +166,8 @@ static void do_suspend(void)
152 166
153 err = stop_machine(xen_suspend, &si, cpumask_of(0)); 167 err = stop_machine(xen_suspend, &si, cpumask_of(0));
154 168
169 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
170
155 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE); 171 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
156 172
157 if (err) { 173 if (err) {
diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c
index 79e1dff7ed4f..0aac403d53fd 100644
--- a/drivers/xen/pcpu.c
+++ b/drivers/xen/pcpu.c
@@ -40,6 +40,7 @@
40#include <linux/capability.h> 40#include <linux/capability.h>
41 41
42#include <xen/xen.h> 42#include <xen/xen.h>
43#include <xen/acpi.h>
43#include <xen/xenbus.h> 44#include <xen/xenbus.h>
44#include <xen/events.h> 45#include <xen/events.h>
45#include <xen/interface/platform.h> 46#include <xen/interface/platform.h>
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
index a1361c312c06..3454973dc3bb 100644
--- a/drivers/xen/platform-pci.c
+++ b/drivers/xen/platform-pci.c
@@ -45,7 +45,7 @@ static unsigned long platform_mmio_alloc;
45static unsigned long platform_mmiolen; 45static unsigned long platform_mmiolen;
46static uint64_t callback_via; 46static uint64_t callback_via;
47 47
48unsigned long alloc_xen_mmio(unsigned long len) 48static unsigned long alloc_xen_mmio(unsigned long len)
49{ 49{
50 unsigned long addr; 50 unsigned long addr;
51 51
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index 7231859119f1..82358d14ecf1 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -27,10 +27,10 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/syscore_ops.h>
31#include <linux/acpi.h> 30#include <linux/acpi.h>
32#include <acpi/processor.h> 31#include <acpi/processor.h>
33#include <xen/xen.h> 32#include <xen/xen.h>
33#include <xen/xen-ops.h>
34#include <xen/interface/platform.h> 34#include <xen/interface/platform.h>
35#include <asm/xen/hypercall.h> 35#include <asm/xen/hypercall.h>
36 36
@@ -495,14 +495,15 @@ static int xen_upload_processor_pm_data(void)
495 return rc; 495 return rc;
496} 496}
497 497
498static void xen_acpi_processor_resume(void) 498static int xen_acpi_processor_resume(struct notifier_block *nb,
499 unsigned long action, void *data)
499{ 500{
500 bitmap_zero(acpi_ids_done, nr_acpi_bits); 501 bitmap_zero(acpi_ids_done, nr_acpi_bits);
501 xen_upload_processor_pm_data(); 502 return xen_upload_processor_pm_data();
502} 503}
503 504
504static struct syscore_ops xap_syscore_ops = { 505struct notifier_block xen_acpi_processor_resume_nb = {
505 .resume = xen_acpi_processor_resume, 506 .notifier_call = xen_acpi_processor_resume,
506}; 507};
507 508
508static int __init xen_acpi_processor_init(void) 509static int __init xen_acpi_processor_init(void)
@@ -555,7 +556,7 @@ static int __init xen_acpi_processor_init(void)
555 if (rc) 556 if (rc)
556 goto err_unregister; 557 goto err_unregister;
557 558
558 register_syscore_ops(&xap_syscore_ops); 559 xen_resume_notifier_register(&xen_acpi_processor_resume_nb);
559 560
560 return 0; 561 return 0;
561err_unregister: 562err_unregister:
@@ -574,7 +575,7 @@ static void __exit xen_acpi_processor_exit(void)
574{ 575{
575 int i; 576 int i;
576 577
577 unregister_syscore_ops(&xap_syscore_ops); 578 xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb);
578 kfree(acpi_ids_done); 579 kfree(acpi_ids_done);
579 kfree(acpi_id_present); 580 kfree(acpi_id_present);
580 kfree(acpi_id_cst_present); 581 kfree(acpi_id_cst_present);
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 64eb0cd8b8af..929dd46bb40c 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -213,8 +213,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
213 entries[i].vector = op->msix_entries[i].vector; 213 entries[i].vector = op->msix_entries[i].vector;
214 } 214 }
215 215
216 result = pci_enable_msix(dev, entries, op->value); 216 result = pci_enable_msix_exact(dev, entries, op->value);
217
218 if (result == 0) { 217 if (result == 0) {
219 for (i = 0; i < op->value; i++) { 218 for (i = 0; i < op->value; i++) {
220 op->msix_entries[i].entry = entries[i].entry; 219 op->msix_entries[i].entry = entries[i].entry;
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c
index 745ad79c1d8e..3b2bffde534f 100644
--- a/drivers/xen/xen-selfballoon.c
+++ b/drivers/xen/xen-selfballoon.c
@@ -170,6 +170,7 @@ static void frontswap_selfshrink(void)
170 tgt_frontswap_pages = cur_frontswap_pages - 170 tgt_frontswap_pages = cur_frontswap_pages -
171 (cur_frontswap_pages / frontswap_hysteresis); 171 (cur_frontswap_pages / frontswap_hysteresis);
172 frontswap_shrink(tgt_frontswap_pages); 172 frontswap_shrink(tgt_frontswap_pages);
173 frontswap_inertia_counter = frontswap_inertia;
173} 174}
174 175
175#endif /* CONFIG_FRONTSWAP */ 176#endif /* CONFIG_FRONTSWAP */
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 01d59e66565d..439c9dca9eee 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -401,33 +401,6 @@ EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
401 401
402 402
403/** 403/**
404 * Bind to an existing interdomain event channel in another domain. Returns 0
405 * on success and stores the local port in *port. On error, returns -errno,
406 * switches the device to XenbusStateClosing, and saves the error in XenStore.
407 */
408int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
409{
410 struct evtchn_bind_interdomain bind_interdomain;
411 int err;
412
413 bind_interdomain.remote_dom = dev->otherend_id;
414 bind_interdomain.remote_port = remote_port;
415
416 err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
417 &bind_interdomain);
418 if (err)
419 xenbus_dev_fatal(dev, err,
420 "binding to event channel %d from domain %d",
421 remote_port, dev->otherend_id);
422 else
423 *port = bind_interdomain.local_port;
424
425 return err;
426}
427EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
428
429
430/**
431 * Free an existing event channel. Returns 0 on success or -errno on error. 404 * Free an existing event channel. Returns 0 on success or -errno on error.
432 */ 405 */
433int xenbus_free_evtchn(struct xenbus_device *dev, int port) 406int xenbus_free_evtchn(struct xenbus_device *dev, int port)
diff --git a/include/xen/events.h b/include/xen/events.h
index c9c85cf84895..8bee7a75e850 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -2,6 +2,9 @@
2#define _XEN_EVENTS_H 2#define _XEN_EVENTS_H
3 3
4#include <linux/interrupt.h> 4#include <linux/interrupt.h>
5#ifdef CONFIG_PCI_MSI
6#include <linux/msi.h>
7#endif
5 8
6#include <xen/interface/event_channel.h> 9#include <xen/interface/event_channel.h>
7#include <asm/xen/hypercall.h> 10#include <asm/xen/hypercall.h>
@@ -52,7 +55,6 @@ int evtchn_get(unsigned int evtchn);
52void evtchn_put(unsigned int evtchn); 55void evtchn_put(unsigned int evtchn);
53 56
54void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector); 57void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector);
55int resend_irq_on_evtchn(unsigned int irq);
56void rebind_evtchn_irq(int evtchn, int irq); 58void rebind_evtchn_irq(int evtchn, int irq);
57 59
58static inline void notify_remote_via_evtchn(int port) 60static inline void notify_remote_via_evtchn(int port)
@@ -102,7 +104,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
102int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); 104int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc);
103/* Bind an PSI pirq to an irq. */ 105/* Bind an PSI pirq to an irq. */
104int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, 106int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
105 int pirq, const char *name, domid_t domid); 107 int pirq, int nvec, const char *name, domid_t domid);
106#endif 108#endif
107 109
108/* De-allocates the above mentioned physical interrupt. */ 110/* De-allocates the above mentioned physical interrupt. */
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index 42721d13a106..610dba9b620a 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -131,6 +131,7 @@ struct physdev_irq {
131#define MAP_PIRQ_TYPE_GSI 0x1 131#define MAP_PIRQ_TYPE_GSI 0x1
132#define MAP_PIRQ_TYPE_UNKNOWN 0x2 132#define MAP_PIRQ_TYPE_UNKNOWN 0x2
133#define MAP_PIRQ_TYPE_MSI_SEG 0x3 133#define MAP_PIRQ_TYPE_MSI_SEG 0x3
134#define MAP_PIRQ_TYPE_MULTI_MSI 0x4
134 135
135#define PHYSDEVOP_map_pirq 13 136#define PHYSDEVOP_map_pirq 13
136struct physdev_map_pirq { 137struct physdev_map_pirq {
@@ -141,11 +142,16 @@ struct physdev_map_pirq {
141 int index; 142 int index;
142 /* IN or OUT */ 143 /* IN or OUT */
143 int pirq; 144 int pirq;
144 /* IN - high 16 bits hold segment for MAP_PIRQ_TYPE_MSI_SEG */ 145 /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */
145 int bus; 146 int bus;
146 /* IN */ 147 /* IN */
147 int devfn; 148 int devfn;
148 /* IN */ 149 /* IN
150 * - For MSI-X contains entry number.
151 * - For MSI with ..._MULTI_MSI contains number of vectors.
152 * OUT (..._MULTI_MSI only)
153 * - Number of vectors allocated.
154 */
149 int entry_nr; 155 int entry_nr;
150 /* IN */ 156 /* IN */
151 uint64_t table_base; 157 uint64_t table_base;
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index fb2ea8f26552..2cf47175b12b 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -2,6 +2,7 @@
2#define INCLUDE_XEN_OPS_H 2#define INCLUDE_XEN_OPS_H
3 3
4#include <linux/percpu.h> 4#include <linux/percpu.h>
5#include <linux/notifier.h>
5#include <asm/xen/interface.h> 6#include <asm/xen/interface.h>
6 7
7DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); 8DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
@@ -16,6 +17,9 @@ void xen_mm_unpin_all(void);
16void xen_timer_resume(void); 17void xen_timer_resume(void);
17void xen_arch_resume(void); 18void xen_arch_resume(void);
18 19
20void xen_resume_notifier_register(struct notifier_block *nb);
21void xen_resume_notifier_unregister(struct notifier_block *nb);
22
19int xen_setup_shutdown_event(void); 23int xen_setup_shutdown_event(void);
20 24
21extern unsigned long *xen_contiguous_bitmap; 25extern unsigned long *xen_contiguous_bitmap;
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index 569c07f2e344..0324c6d340c1 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -207,7 +207,6 @@ int xenbus_unmap_ring(struct xenbus_device *dev,
207 grant_handle_t handle, void *vaddr); 207 grant_handle_t handle, void *vaddr);
208 208
209int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port); 209int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
210int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port);
211int xenbus_free_evtchn(struct xenbus_device *dev, int port); 210int xenbus_free_evtchn(struct xenbus_device *dev, int port);
212 211
213enum xenbus_state xenbus_read_driver_state(const char *path); 212enum xenbus_state xenbus_read_driver_state(const char *path);