diff options
-rw-r--r-- | arch/arm/include/asm/xen/page.h | 15 | ||||
-rw-r--r-- | arch/arm/xen/p2m.c | 32 | ||||
-rw-r--r-- | arch/x86/include/asm/xen/page.h | 11 | ||||
-rw-r--r-- | arch/x86/pci/xen.c | 29 | ||||
-rw-r--r-- | arch/x86/xen/Kconfig | 5 | ||||
-rw-r--r-- | arch/x86/xen/p2m.c | 121 | ||||
-rw-r--r-- | drivers/xen/events/events_base.c | 83 | ||||
-rw-r--r-- | drivers/xen/events/events_internal.h | 1 | ||||
-rw-r--r-- | drivers/xen/grant-table.c | 73 | ||||
-rw-r--r-- | drivers/xen/manage.c | 16 | ||||
-rw-r--r-- | drivers/xen/pcpu.c | 1 | ||||
-rw-r--r-- | drivers/xen/platform-pci.c | 2 | ||||
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 15 | ||||
-rw-r--r-- | drivers/xen/xen-pciback/pciback_ops.c | 3 | ||||
-rw-r--r-- | drivers/xen/xen-selfballoon.c | 1 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_client.c | 27 | ||||
-rw-r--r-- | include/xen/events.h | 6 | ||||
-rw-r--r-- | include/xen/interface/physdev.h | 10 | ||||
-rw-r--r-- | include/xen/xen-ops.h | 4 | ||||
-rw-r--r-- | include/xen/xenbus.h | 1 |
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 | ||
100 | static inline int m2p_add_override(unsigned long mfn, struct page *page, | 100 | extern 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 | ||
106 | static inline int m2p_remove_override(struct page *page, bool clear_pte) | 104 | extern 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 | ||
111 | bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); | 108 | bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); |
112 | bool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn, | 109 | bool __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 | } |
147 | EXPORT_SYMBOL_GPL(__mfn_to_pfn); | 147 | EXPORT_SYMBOL_GPL(__mfn_to_pfn); |
148 | 148 | ||
149 | int 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 | } | ||
164 | EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping); | ||
165 | |||
166 | int 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 | } | ||
179 | EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping); | ||
180 | |||
149 | bool __set_phys_to_machine_multi(unsigned long pfn, | 181 | bool __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); | |||
49 | extern unsigned long set_phys_range_identity(unsigned long pfn_s, | 49 | extern unsigned long set_phys_range_identity(unsigned long pfn_s, |
50 | unsigned long pfn_e); | 50 | unsigned long pfn_e); |
51 | 51 | ||
52 | extern 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); | ||
52 | extern int m2p_add_override(unsigned long mfn, struct page *page, | 55 | extern 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); |
57 | extern 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); | ||
54 | extern int m2p_remove_override(struct page *page, | 60 | extern 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); | ||
56 | extern struct page *m2p_find_override(unsigned long mfn); | 63 | extern struct page *m2p_find_override(unsigned long mfn); |
57 | extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); | 64 | extern 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. | ||
24 | config XEN_PRIVILEGED_GUEST | ||
25 | def_bool XEN_DOM0 | ||
26 | |||
27 | config XEN_PVHVM | 22 | config 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 | ||
884 | int 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 | |||
935 | out: | ||
936 | if (lazy) | ||
937 | arch_leave_lazy_mmu_mode(); | ||
938 | |||
939 | return ret; | ||
940 | } | ||
941 | EXPORT_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 */ |
885 | int m2p_add_override(unsigned long mfn, struct page *page, | 944 | int 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 | } |
945 | EXPORT_SYMBOL_GPL(m2p_add_override); | 997 | EXPORT_SYMBOL_GPL(m2p_add_override); |
998 | |||
999 | int 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 | |||
1036 | out: | ||
1037 | if (lazy) | ||
1038 | arch_leave_lazy_mmu_mode(); | ||
1039 | return ret; | ||
1040 | } | ||
1041 | EXPORT_SYMBOL_GPL(clear_foreign_p2m_mapping); | ||
1042 | |||
946 | int m2p_remove_override(struct page *page, | 1043 | int 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 | ||
391 | static int __must_check xen_allocate_irq_dynamic(void) | 391 | static 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 | ||
418 | static inline int __must_check xen_allocate_irq_dynamic(void) | ||
419 | { | ||
420 | |||
421 | return xen_allocate_irqs_dynamic(1); | ||
422 | } | ||
423 | |||
416 | static int __must_check xen_allocate_irq_gsi(unsigned gsi) | 424 | static 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 | ||
474 | static void pirq_query_unmask(int irq) | 479 | static 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 | ||
732 | int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, | 737 | int 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; |
755 | error_irq: | 763 | error_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 | ||
1332 | static 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 | |||
1347 | int resend_irq_on_evtchn(unsigned int irq) | ||
1348 | { | ||
1349 | return retrigger_evtchn(evtchn_from_irq(irq)); | ||
1350 | } | ||
1351 | |||
1352 | static void enable_dynirq(struct irq_data *data) | 1346 | static 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 | ||
1384 | static int retrigger_dynirq(struct irq_data *data) | 1378 | static 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 | ||
1389 | static void restore_pirqs(void) | 1394 | static 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 | ||
57 | struct evtchn_ops { | 58 | struct 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 | } |
990 | EXPORT_SYMBOL_GPL(gnttab_map_refs); | 949 | EXPORT_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 | } |
1030 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); | 963 | EXPORT_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 | ||
49 | static RAW_NOTIFIER_HEAD(xen_resume_notifier); | ||
50 | |||
51 | void xen_resume_notifier_register(struct notifier_block *nb) | ||
52 | { | ||
53 | raw_notifier_chain_register(&xen_resume_notifier, nb); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(xen_resume_notifier_register); | ||
56 | |||
57 | void xen_resume_notifier_unregister(struct notifier_block *nb) | ||
58 | { | ||
59 | raw_notifier_chain_unregister(&xen_resume_notifier, nb); | ||
60 | } | ||
61 | EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister); | ||
62 | |||
49 | #ifdef CONFIG_HIBERNATE_CALLBACKS | 63 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
50 | static void xen_hvm_post_suspend(int cancelled) | 64 | static 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; | |||
45 | static unsigned long platform_mmiolen; | 45 | static unsigned long platform_mmiolen; |
46 | static uint64_t callback_via; | 46 | static uint64_t callback_via; |
47 | 47 | ||
48 | unsigned long alloc_xen_mmio(unsigned long len) | 48 | static 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 | ||
498 | static void xen_acpi_processor_resume(void) | 498 | static 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 | ||
504 | static struct syscore_ops xap_syscore_ops = { | 505 | struct notifier_block xen_acpi_processor_resume_nb = { |
505 | .resume = xen_acpi_processor_resume, | 506 | .notifier_call = xen_acpi_processor_resume, |
506 | }; | 507 | }; |
507 | 508 | ||
508 | static int __init xen_acpi_processor_init(void) | 509 | static 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; |
561 | err_unregister: | 562 | err_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 | */ | ||
408 | int 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 | } | ||
427 | EXPORT_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 | */ |
433 | int xenbus_free_evtchn(struct xenbus_device *dev, int port) | 406 | int 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); | |||
52 | void evtchn_put(unsigned int evtchn); | 55 | void evtchn_put(unsigned int evtchn); |
53 | 56 | ||
54 | void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector); | 57 | void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector); |
55 | int resend_irq_on_evtchn(unsigned int irq); | ||
56 | void rebind_evtchn_irq(int evtchn, int irq); | 58 | void rebind_evtchn_irq(int evtchn, int irq); |
57 | 59 | ||
58 | static inline void notify_remote_via_evtchn(int port) | 60 | static inline void notify_remote_via_evtchn(int port) |
@@ -102,7 +104,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi, | |||
102 | int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); | 104 | int 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. */ |
104 | int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, | 106 | int 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 |
136 | struct physdev_map_pirq { | 137 | struct 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 | ||
7 | DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); | 8 | DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); |
@@ -16,6 +17,9 @@ void xen_mm_unpin_all(void); | |||
16 | void xen_timer_resume(void); | 17 | void xen_timer_resume(void); |
17 | void xen_arch_resume(void); | 18 | void xen_arch_resume(void); |
18 | 19 | ||
20 | void xen_resume_notifier_register(struct notifier_block *nb); | ||
21 | void xen_resume_notifier_unregister(struct notifier_block *nb); | ||
22 | |||
19 | int xen_setup_shutdown_event(void); | 23 | int xen_setup_shutdown_event(void); |
20 | 24 | ||
21 | extern unsigned long *xen_contiguous_bitmap; | 25 | extern 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 | ||
209 | int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port); | 209 | int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port); |
210 | int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port); | ||
211 | int xenbus_free_evtchn(struct xenbus_device *dev, int port); | 210 | int xenbus_free_evtchn(struct xenbus_device *dev, int port); |
212 | 211 | ||
213 | enum xenbus_state xenbus_read_driver_state(const char *path); | 212 | enum xenbus_state xenbus_read_driver_state(const char *path); |