aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2015-03-11 10:49:56 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2015-03-16 10:49:15 -0400
commit628c28eefd6f2cef03b212081b466ae43fd093a3 (patch)
treeedcde5040badd2068efe925f8253961e0ca71c48 /drivers/xen
parentb3b06c7eb7820cea5c15f9faa4964044284c5399 (diff)
xen: unify foreign GFN map/unmap for auto-xlated physmap guests
Auto-translated physmap guests (arm, arm64 and x86 PVHVM/PVH) map and unmap foreign GFNs using the same method (updating the physmap). Unify the two arm and x86 implementations into one commont one. Note that on arm and arm64, the correct error code will be returned (instead of always -EFAULT) and map/unmap failure warnings are no longer printed. These changes are required if the foreign domain is paging (-ENOENT failures are expected and must be propagated up to the caller). Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/Kconfig6
-rw-r--r--drivers/xen/Makefile1
-rw-r--r--drivers/xen/xlate_mmu.c133
3 files changed, 140 insertions, 0 deletions
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index b812462083fc..afc39ca5cc4f 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -253,4 +253,10 @@ config XEN_EFI
253 def_bool y 253 def_bool y
254 depends on X86_64 && EFI 254 depends on X86_64 && EFI
255 255
256config XEN_AUTO_XLATE
257 def_bool y
258 depends on ARM || ARM64 || XEN_PVHVM
259 help
260 Support for auto-translated physmap guests.
261
256endmenu 262endmenu
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 2ccd3592d41f..40edd1cbb60d 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU) += xen-acpi-cpuhotplug.o
37obj-$(CONFIG_XEN_ACPI_PROCESSOR) += xen-acpi-processor.o 37obj-$(CONFIG_XEN_ACPI_PROCESSOR) += xen-acpi-processor.o
38obj-$(CONFIG_XEN_EFI) += efi.o 38obj-$(CONFIG_XEN_EFI) += efi.o
39obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsiback.o 39obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsiback.o
40obj-$(CONFIG_XEN_AUTO_XLATE) += xlate_mmu.o
40xen-evtchn-y := evtchn.o 41xen-evtchn-y := evtchn.o
41xen-gntdev-y := gntdev.o 42xen-gntdev-y := gntdev.o
42xen-gntalloc-y := gntalloc.o 43xen-gntalloc-y := gntalloc.o
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
new file mode 100644
index 000000000000..7724d90fc697
--- /dev/null
+++ b/drivers/xen/xlate_mmu.c
@@ -0,0 +1,133 @@
1/*
2 * MMU operations common to all auto-translated physmap guests.
3 *
4 * Copyright (C) 2015 Citrix Systems R&D Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation; or, when distributed
9 * separately from the Linux kernel or incorporated into other
10 * software packages, subject to the following license:
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this source file (the "Software"), to deal in the Software without
14 * restriction, including without limitation the rights to use, copy, modify,
15 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
16 * and to permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30#include <linux/kernel.h>
31#include <linux/mm.h>
32
33#include <asm/xen/hypercall.h>
34#include <asm/xen/hypervisor.h>
35
36#include <xen/xen.h>
37#include <xen/page.h>
38#include <xen/interface/xen.h>
39#include <xen/interface/memory.h>
40
41/* map fgmfn of domid to lpfn in the current domain */
42static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
43 unsigned int domid)
44{
45 int rc;
46 struct xen_add_to_physmap_range xatp = {
47 .domid = DOMID_SELF,
48 .foreign_domid = domid,
49 .size = 1,
50 .space = XENMAPSPACE_gmfn_foreign,
51 };
52 xen_ulong_t idx = fgmfn;
53 xen_pfn_t gpfn = lpfn;
54 int err = 0;
55
56 set_xen_guest_handle(xatp.idxs, &idx);
57 set_xen_guest_handle(xatp.gpfns, &gpfn);
58 set_xen_guest_handle(xatp.errs, &err);
59
60 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
61 return rc < 0 ? rc : err;
62}
63
64struct remap_data {
65 xen_pfn_t fgmfn; /* foreign domain's gmfn */
66 pgprot_t prot;
67 domid_t domid;
68 struct vm_area_struct *vma;
69 int index;
70 struct page **pages;
71 struct xen_remap_mfn_info *info;
72};
73
74static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
75 void *data)
76{
77 struct remap_data *info = data;
78 struct page *page = info->pages[info->index++];
79 unsigned long pfn = page_to_pfn(page);
80 pte_t pte = pte_mkspecial(pfn_pte(pfn, info->prot));
81 int rc;
82
83 rc = map_foreign_page(pfn, info->fgmfn, info->domid);
84 if (rc < 0)
85 return rc;
86 set_pte_at(info->vma->vm_mm, addr, ptep, pte);
87
88 return 0;
89}
90
91int xen_xlate_remap_gfn_range(struct vm_area_struct *vma,
92 unsigned long addr,
93 xen_pfn_t gfn, int nr,
94 pgprot_t prot, unsigned domid,
95 struct page **pages)
96{
97 int err;
98 struct remap_data data;
99
100 /* TBD: Batching, current sole caller only does page at a time */
101 if (nr > 1)
102 return -EINVAL;
103
104 data.fgmfn = gfn;
105 data.prot = prot;
106 data.domid = domid;
107 data.vma = vma;
108 data.index = 0;
109 data.pages = pages;
110 err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT,
111 remap_pte_fn, &data);
112 return err;
113}
114EXPORT_SYMBOL_GPL(xen_xlate_remap_gfn_range);
115
116int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
117 int nr, struct page **pages)
118{
119 int i;
120
121 for (i = 0; i < nr; i++) {
122 struct xen_remove_from_physmap xrp;
123 unsigned long pfn;
124
125 pfn = page_to_pfn(pages[i]);
126
127 xrp.domid = DOMID_SELF;
128 xrp.gpfn = pfn;
129 (void)HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
130 }
131 return 0;
132}
133EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);