aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2014-01-03 10:20:18 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2014-01-06 10:44:21 -0500
commit6926f6d6109714aab7b26df7099b12555e36676f (patch)
tree48d0a61f2db6b3d75ff90f83d3726d975a0cce5b
parentefaf30a3357872cf0fc7d555b1f9968ec71535d3 (diff)
xen/pvh: Piggyback on PVHVM for grant driver (v4)
In PVH the shared grant frame is the PFN and not MFN, hence its mapped via the same code path as HVM. The allocation of the grant frame is done differently - we do not use the early platform-pci driver and have an ioremap area - instead we use balloon memory and stitch all of the non-contingous pages in a virtualized area. That means when we call the hypervisor to replace the GMFN with a XENMAPSPACE_grant_table type, we need to lookup the old PFN for every iteration instead of assuming a flat contingous PFN allocation. Lastly, we only use v1 for grants. This is because PVHVM is not able to use v2 due to no XENMEM_add_to_physmap calls on the error status page (see commit 69e8f430e243d657c2053f097efebc2e2cd559f0 xen/granttable: Disable grant v2 for HVM domains.) Until that is implemented this workaround has to be in place. Also per suggestions by Stefano utilize the PVHVM paths as they share common functionality. v2 of this patch moves most of the PVH code out in the arch/x86/xen/grant-table driver and touches only minimally the generic driver. v3, v4: fixes us some of the code due to earlier patches. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
-rw-r--r--arch/x86/xen/grant-table.c62
-rw-r--r--drivers/xen/gntdev.c2
-rw-r--r--drivers/xen/grant-table.c9
3 files changed, 68 insertions, 5 deletions
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 3a5f55d51907..2d719799fd6a 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -125,3 +125,65 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
125 apply_to_page_range(&init_mm, (unsigned long)shared, 125 apply_to_page_range(&init_mm, (unsigned long)shared,
126 PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL); 126 PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL);
127} 127}
128#ifdef CONFIG_XEN_PVH
129#include <xen/balloon.h>
130#include <xen/events.h>
131#include <linux/slab.h>
132static int __init xlated_setup_gnttab_pages(void)
133{
134 struct page **pages;
135 xen_pfn_t *pfns;
136 int rc;
137 unsigned int i;
138 unsigned long nr_grant_frames = gnttab_max_grant_frames();
139
140 BUG_ON(nr_grant_frames == 0);
141 pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
142 if (!pages)
143 return -ENOMEM;
144
145 pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
146 if (!pfns) {
147 kfree(pages);
148 return -ENOMEM;
149 }
150 rc = alloc_xenballooned_pages(nr_grant_frames, pages, 0 /* lowmem */);
151 if (rc) {
152 pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
153 nr_grant_frames, rc);
154 kfree(pages);
155 kfree(pfns);
156 return rc;
157 }
158 for (i = 0; i < nr_grant_frames; i++)
159 pfns[i] = page_to_pfn(pages[i]);
160
161 rc = arch_gnttab_map_shared(pfns, nr_grant_frames, nr_grant_frames,
162 &xen_auto_xlat_grant_frames.vaddr);
163
164 kfree(pages);
165 if (rc) {
166 pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
167 nr_grant_frames, rc);
168 free_xenballooned_pages(nr_grant_frames, pages);
169 kfree(pfns);
170 return rc;
171 }
172
173 xen_auto_xlat_grant_frames.pfn = pfns;
174 xen_auto_xlat_grant_frames.count = nr_grant_frames;
175
176 return 0;
177}
178
179static int __init xen_pvh_gnttab_setup(void)
180{
181 if (!xen_pvh_domain())
182 return -ENODEV;
183
184 return xlated_setup_gnttab_pages();
185}
186/* Call it _before_ __gnttab_init as we need to initialize the
187 * xen_auto_xlat_grant_frames first. */
188core_initcall(xen_pvh_gnttab_setup);
189#endif
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index e41c79c986ea..073b4a19a8b0 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -846,7 +846,7 @@ static int __init gntdev_init(void)
846 if (!xen_domain()) 846 if (!xen_domain())
847 return -ENODEV; 847 return -ENODEV;
848 848
849 use_ptemod = xen_pv_domain(); 849 use_ptemod = !xen_feature(XENFEAT_auto_translated_physmap);
850 850
851 err = misc_register(&gntdev_miscdev); 851 err = misc_register(&gntdev_miscdev);
852 if (err != 0) { 852 if (err != 0) {
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 44b75ccfbbff..1d5fbce4acb7 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -1108,7 +1108,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
1108 unsigned int nr_gframes = end_idx + 1; 1108 unsigned int nr_gframes = end_idx + 1;
1109 int rc; 1109 int rc;
1110 1110
1111 if (xen_hvm_domain()) { 1111 if (xen_feature(XENFEAT_auto_translated_physmap)) {
1112 struct xen_add_to_physmap xatp; 1112 struct xen_add_to_physmap xatp;
1113 unsigned int i = end_idx; 1113 unsigned int i = end_idx;
1114 rc = 0; 1114 rc = 0;
@@ -1184,7 +1184,7 @@ static void gnttab_request_version(void)
1184 int rc; 1184 int rc;
1185 struct gnttab_set_version gsv; 1185 struct gnttab_set_version gsv;
1186 1186
1187 if (xen_hvm_domain()) 1187 if (xen_feature(XENFEAT_auto_translated_physmap))
1188 gsv.version = 1; 1188 gsv.version = 1;
1189 else 1189 else
1190 gsv.version = 2; 1190 gsv.version = 2;
@@ -1327,5 +1327,6 @@ static int __gnttab_init(void)
1327 1327
1328 return gnttab_init(); 1328 return gnttab_init();
1329} 1329}
1330 1330/* Starts after core_initcall so that xen_pvh_gnttab_setup can be called
1331core_initcall(__gnttab_init); 1331 * beforehand to initialize xen_auto_xlat_grant_frames. */
1332core_initcall_sync(__gnttab_init);