aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/xen/page.h1
-rw-r--r--arch/arm/xen/enlighten.c9
-rw-r--r--arch/x86/include/asm/xen/page.h1
-rw-r--r--drivers/xen/grant-table.c58
-rw-r--r--drivers/xen/platform-pci.c10
-rw-r--r--include/xen/grant_table.h9
6 files changed, 75 insertions, 13 deletions
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index ac6789aad059..709c4b4d2f1d 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -118,5 +118,6 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
118} 118}
119 119
120#define xen_remap(cookie, size) ioremap_cached((cookie), (size)) 120#define xen_remap(cookie, size) ioremap_cached((cookie), (size))
121#define xen_unmap(cookie) iounmap((cookie))
121 122
122#endif /* _ASM_ARM_XEN_PAGE_H */ 123#endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 85501238b425..2162172c0ddc 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -208,6 +208,7 @@ static int __init xen_guest_init(void)
208 const char *version = NULL; 208 const char *version = NULL;
209 const char *xen_prefix = "xen,xen-"; 209 const char *xen_prefix = "xen,xen-";
210 struct resource res; 210 struct resource res;
211 unsigned long grant_frames;
211 212
212 node = of_find_compatible_node(NULL, NULL, "xen,xen"); 213 node = of_find_compatible_node(NULL, NULL, "xen,xen");
213 if (!node) { 214 if (!node) {
@@ -224,10 +225,10 @@ static int __init xen_guest_init(void)
224 } 225 }
225 if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res)) 226 if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res))
226 return 0; 227 return 0;
227 xen_hvm_resume_frames = res.start; 228 grant_frames = res.start;
228 xen_events_irq = irq_of_parse_and_map(node, 0); 229 xen_events_irq = irq_of_parse_and_map(node, 0);
229 pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n", 230 pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n",
230 version, xen_events_irq, (xen_hvm_resume_frames >> PAGE_SHIFT)); 231 version, xen_events_irq, (grant_frames >> PAGE_SHIFT));
231 xen_domain_type = XEN_HVM_DOMAIN; 232 xen_domain_type = XEN_HVM_DOMAIN;
232 233
233 xen_setup_features(); 234 xen_setup_features();
@@ -265,6 +266,10 @@ static int __init xen_guest_init(void)
265 if (xen_vcpu_info == NULL) 266 if (xen_vcpu_info == NULL)
266 return -ENOMEM; 267 return -ENOMEM;
267 268
269 if (gnttab_setup_auto_xlat_frames(grant_frames)) {
270 free_percpu(xen_vcpu_info);
271 return -ENOMEM;
272 }
268 gnttab_init(); 273 gnttab_init();
269 if (!xen_initial_domain()) 274 if (!xen_initial_domain())
270 xenbus_probe(NULL); 275 xenbus_probe(NULL);
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 4a092ccdd147..3e276eb23d1b 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -227,5 +227,6 @@ void make_lowmem_page_readonly(void *vaddr);
227void make_lowmem_page_readwrite(void *vaddr); 227void make_lowmem_page_readwrite(void *vaddr);
228 228
229#define xen_remap(cookie, size) ioremap((cookie), (size)); 229#define xen_remap(cookie, size) ioremap((cookie), (size));
230#define xen_unmap(cookie) iounmap((cookie))
230 231
231#endif /* _ASM_X86_XEN_PAGE_H */ 232#endif /* _ASM_X86_XEN_PAGE_H */
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index e69c7780c208..44b75ccfbbff 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -65,8 +65,7 @@ static unsigned int nr_grant_frames;
65static int gnttab_free_count; 65static int gnttab_free_count;
66static grant_ref_t gnttab_free_head; 66static grant_ref_t gnttab_free_head;
67static DEFINE_SPINLOCK(gnttab_list_lock); 67static DEFINE_SPINLOCK(gnttab_list_lock);
68unsigned long xen_hvm_resume_frames; 68struct grant_frames xen_auto_xlat_grant_frames;
69EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
70 69
71static union { 70static union {
72 struct grant_entry_v1 *v1; 71 struct grant_entry_v1 *v1;
@@ -838,6 +837,51 @@ unsigned int gnttab_max_grant_frames(void)
838} 837}
839EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); 838EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
840 839
840int gnttab_setup_auto_xlat_frames(unsigned long addr)
841{
842 xen_pfn_t *pfn;
843 unsigned int max_nr_gframes = __max_nr_grant_frames();
844 unsigned int i;
845 void *vaddr;
846
847 if (xen_auto_xlat_grant_frames.count)
848 return -EINVAL;
849
850 vaddr = xen_remap(addr, PAGE_SIZE * max_nr_gframes);
851 if (vaddr == NULL) {
852 pr_warn("Failed to ioremap gnttab share frames (addr=0x%08lx)!\n",
853 addr);
854 return -ENOMEM;
855 }
856 pfn = kcalloc(max_nr_gframes, sizeof(pfn[0]), GFP_KERNEL);
857 if (!pfn) {
858 xen_unmap(vaddr);
859 return -ENOMEM;
860 }
861 for (i = 0; i < max_nr_gframes; i++)
862 pfn[i] = PFN_DOWN(addr) + i;
863
864 xen_auto_xlat_grant_frames.vaddr = vaddr;
865 xen_auto_xlat_grant_frames.pfn = pfn;
866 xen_auto_xlat_grant_frames.count = max_nr_gframes;
867
868 return 0;
869}
870EXPORT_SYMBOL_GPL(gnttab_setup_auto_xlat_frames);
871
872void gnttab_free_auto_xlat_frames(void)
873{
874 if (!xen_auto_xlat_grant_frames.count)
875 return;
876 kfree(xen_auto_xlat_grant_frames.pfn);
877 xen_unmap(xen_auto_xlat_grant_frames.vaddr);
878
879 xen_auto_xlat_grant_frames.pfn = NULL;
880 xen_auto_xlat_grant_frames.count = 0;
881 xen_auto_xlat_grant_frames.vaddr = NULL;
882}
883EXPORT_SYMBOL_GPL(gnttab_free_auto_xlat_frames);
884
841/* Handling of paged out grant targets (GNTST_eagain) */ 885/* Handling of paged out grant targets (GNTST_eagain) */
842#define MAX_DELAY 256 886#define MAX_DELAY 256
843static inline void 887static inline void
@@ -1068,6 +1112,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
1068 struct xen_add_to_physmap xatp; 1112 struct xen_add_to_physmap xatp;
1069 unsigned int i = end_idx; 1113 unsigned int i = end_idx;
1070 rc = 0; 1114 rc = 0;
1115 BUG_ON(xen_auto_xlat_grant_frames.count < nr_gframes);
1071 /* 1116 /*
1072 * Loop backwards, so that the first hypercall has the largest 1117 * Loop backwards, so that the first hypercall has the largest
1073 * index, ensuring that the table will grow only once. 1118 * index, ensuring that the table will grow only once.
@@ -1076,7 +1121,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
1076 xatp.domid = DOMID_SELF; 1121 xatp.domid = DOMID_SELF;
1077 xatp.idx = i; 1122 xatp.idx = i;
1078 xatp.space = XENMAPSPACE_grant_table; 1123 xatp.space = XENMAPSPACE_grant_table;
1079 xatp.gpfn = (xen_hvm_resume_frames >> PAGE_SHIFT) + i; 1124 xatp.gpfn = xen_auto_xlat_grant_frames.pfn[i];
1080 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); 1125 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
1081 if (rc != 0) { 1126 if (rc != 0) {
1082 pr_warn("grant table add_to_physmap failed, err=%d\n", 1127 pr_warn("grant table add_to_physmap failed, err=%d\n",
@@ -1174,11 +1219,10 @@ static int gnttab_setup(void)
1174 return -ENOSYS; 1219 return -ENOSYS;
1175 1220
1176 if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) { 1221 if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) {
1177 gnttab_shared.addr = xen_remap(xen_hvm_resume_frames, 1222 gnttab_shared.addr = xen_auto_xlat_grant_frames.vaddr;
1178 PAGE_SIZE * max_nr_gframes);
1179 if (gnttab_shared.addr == NULL) { 1223 if (gnttab_shared.addr == NULL) {
1180 pr_warn("Failed to ioremap gnttab share frames (addr=0x%08lx)!\n", 1224 pr_warn("gnttab share frames (addr=0x%08lx) is not mapped!\n",
1181 xen_hvm_resume_frames); 1225 (unsigned long)xen_auto_xlat_grant_frames.vaddr);
1182 return -ENOMEM; 1226 return -ENOMEM;
1183 } 1227 }
1184 } 1228 }
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
index 2f3528e93cb9..f1947ac218d9 100644
--- a/drivers/xen/platform-pci.c
+++ b/drivers/xen/platform-pci.c
@@ -108,6 +108,7 @@ static int platform_pci_init(struct pci_dev *pdev,
108 long ioaddr; 108 long ioaddr;
109 long mmio_addr, mmio_len; 109 long mmio_addr, mmio_len;
110 unsigned int max_nr_gframes; 110 unsigned int max_nr_gframes;
111 unsigned long grant_frames;
111 112
112 if (!xen_domain()) 113 if (!xen_domain())
113 return -ENODEV; 114 return -ENODEV;
@@ -154,13 +155,16 @@ static int platform_pci_init(struct pci_dev *pdev,
154 } 155 }
155 156
156 max_nr_gframes = gnttab_max_grant_frames(); 157 max_nr_gframes = gnttab_max_grant_frames();
157 xen_hvm_resume_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes); 158 grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
159 if (gnttab_setup_auto_xlat_frames(grant_frames))
160 goto out;
158 ret = gnttab_init(); 161 ret = gnttab_init();
159 if (ret) 162 if (ret)
160 goto out; 163 goto grant_out;
161 xenbus_probe(NULL); 164 xenbus_probe(NULL);
162 return 0; 165 return 0;
163 166grant_out:
167 gnttab_free_auto_xlat_frames();
164out: 168out:
165 pci_release_region(pdev, 0); 169 pci_release_region(pdev, 0);
166mem_out: 170mem_out:
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index 694dcaf266e6..5acb1e4ac0d3 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -178,8 +178,15 @@ int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
178 grant_status_t **__shared); 178 grant_status_t **__shared);
179void arch_gnttab_unmap(void *shared, unsigned long nr_gframes); 179void arch_gnttab_unmap(void *shared, unsigned long nr_gframes);
180 180
181extern unsigned long xen_hvm_resume_frames; 181struct grant_frames {
182 xen_pfn_t *pfn;
183 unsigned int count;
184 void *vaddr;
185};
186extern struct grant_frames xen_auto_xlat_grant_frames;
182unsigned int gnttab_max_grant_frames(void); 187unsigned int gnttab_max_grant_frames(void);
188int gnttab_setup_auto_xlat_frames(unsigned long addr);
189void gnttab_free_auto_xlat_frames(void);
183 190
184#define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) 191#define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
185 192