diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-11-30 17:07:59 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-11-30 17:07:59 -0500 |
commit | 6a7ed405114b2a53ccd99631b0636aaeabf71b3e (patch) | |
tree | f8bb0dcddc66c59843433e2283f6bea57cc8ce24 /arch | |
parent | a7be94ac8d69c037d08f0fd94b45a593f1d45176 (diff) | |
parent | f832da068b0aadb15f747f6427b6bf945f525ba4 (diff) |
Merge branch 'arm-privcmd-for-3.8' of git://xenbits.xen.org/people/ianc/linux into stable/for-linus-3.8
* 'arm-privcmd-for-3.8' of git://xenbits.xen.org/people/ianc/linux:
xen: arm: implement remap interfaces needed for privcmd mappings.
xen: correctly use xen_pfn_t in remap_domain_mfn_range.
xen: arm: enable balloon driver
xen: balloon: allow PVMMU interfaces to be compiled out
xen: privcmd: support autotranslated physmap guests.
xen: add pages parameter to xen_remap_domain_mfn_range
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/xen/interface.h | 1 | ||||
-rw-r--r-- | arch/arm/xen/enlighten.c | 123 | ||||
-rw-r--r-- | arch/x86/include/asm/xen/interface.h | 1 | ||||
-rw-r--r-- | arch/x86/xen/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 17 |
5 files changed, 120 insertions, 23 deletions
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h index 5000397134b4..1151188bcd83 100644 --- a/arch/arm/include/asm/xen/interface.h +++ b/arch/arm/include/asm/xen/interface.h | |||
@@ -49,6 +49,7 @@ DEFINE_GUEST_HANDLE(void); | |||
49 | DEFINE_GUEST_HANDLE(uint64_t); | 49 | DEFINE_GUEST_HANDLE(uint64_t); |
50 | DEFINE_GUEST_HANDLE(uint32_t); | 50 | DEFINE_GUEST_HANDLE(uint32_t); |
51 | DEFINE_GUEST_HANDLE(xen_pfn_t); | 51 | DEFINE_GUEST_HANDLE(xen_pfn_t); |
52 | DEFINE_GUEST_HANDLE(xen_ulong_t); | ||
52 | 53 | ||
53 | /* Maximum number of virtual CPUs in multi-processor guests. */ | 54 | /* Maximum number of virtual CPUs in multi-processor guests. */ |
54 | #define MAX_VIRT_CPUS 1 | 55 | #define MAX_VIRT_CPUS 1 |
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 59bcb96ac369..f28fc1ac8760 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <xen/features.h> | 8 | #include <xen/features.h> |
9 | #include <xen/platform_pci.h> | 9 | #include <xen/platform_pci.h> |
10 | #include <xen/xenbus.h> | 10 | #include <xen/xenbus.h> |
11 | #include <xen/page.h> | ||
12 | #include <xen/xen-ops.h> | ||
11 | #include <asm/xen/hypervisor.h> | 13 | #include <asm/xen/hypervisor.h> |
12 | #include <asm/xen/hypercall.h> | 14 | #include <asm/xen/hypercall.h> |
13 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
@@ -17,6 +19,8 @@ | |||
17 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
18 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
19 | 21 | ||
22 | #include <linux/mm.h> | ||
23 | |||
20 | struct start_info _xen_start_info; | 24 | struct start_info _xen_start_info; |
21 | struct start_info *xen_start_info = &_xen_start_info; | 25 | struct start_info *xen_start_info = &_xen_start_info; |
22 | EXPORT_SYMBOL_GPL(xen_start_info); | 26 | EXPORT_SYMBOL_GPL(xen_start_info); |
@@ -29,6 +33,10 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info; | |||
29 | 33 | ||
30 | DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); | 34 | DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); |
31 | 35 | ||
36 | /* These are unused until we support booting "pre-ballooned" */ | ||
37 | unsigned long xen_released_pages; | ||
38 | struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata; | ||
39 | |||
32 | /* TODO: to be removed */ | 40 | /* TODO: to be removed */ |
33 | __read_mostly int xen_have_vector_callback; | 41 | __read_mostly int xen_have_vector_callback; |
34 | EXPORT_SYMBOL_GPL(xen_have_vector_callback); | 42 | EXPORT_SYMBOL_GPL(xen_have_vector_callback); |
@@ -38,15 +46,106 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug); | |||
38 | 46 | ||
39 | static __read_mostly int xen_events_irq = -1; | 47 | static __read_mostly int xen_events_irq = -1; |
40 | 48 | ||
49 | /* map fgmfn of domid to lpfn in the current domain */ | ||
50 | static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn, | ||
51 | unsigned int domid) | ||
52 | { | ||
53 | int rc; | ||
54 | struct xen_add_to_physmap_range xatp = { | ||
55 | .domid = DOMID_SELF, | ||
56 | .foreign_domid = domid, | ||
57 | .size = 1, | ||
58 | .space = XENMAPSPACE_gmfn_foreign, | ||
59 | }; | ||
60 | xen_ulong_t idx = fgmfn; | ||
61 | xen_pfn_t gpfn = lpfn; | ||
62 | |||
63 | set_xen_guest_handle(xatp.idxs, &idx); | ||
64 | set_xen_guest_handle(xatp.gpfns, &gpfn); | ||
65 | |||
66 | rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp); | ||
67 | if (rc) { | ||
68 | pr_warn("Failed to map pfn to mfn rc:%d pfn:%lx mfn:%lx\n", | ||
69 | rc, lpfn, fgmfn); | ||
70 | return 1; | ||
71 | } | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | struct remap_data { | ||
76 | xen_pfn_t fgmfn; /* foreign domain's gmfn */ | ||
77 | pgprot_t prot; | ||
78 | domid_t domid; | ||
79 | struct vm_area_struct *vma; | ||
80 | int index; | ||
81 | struct page **pages; | ||
82 | struct xen_remap_mfn_info *info; | ||
83 | }; | ||
84 | |||
85 | static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr, | ||
86 | void *data) | ||
87 | { | ||
88 | struct remap_data *info = data; | ||
89 | struct page *page = info->pages[info->index++]; | ||
90 | unsigned long pfn = page_to_pfn(page); | ||
91 | pte_t pte = pfn_pte(pfn, info->prot); | ||
92 | |||
93 | if (map_foreign_page(pfn, info->fgmfn, info->domid)) | ||
94 | return -EFAULT; | ||
95 | set_pte_at(info->vma->vm_mm, addr, ptep, pte); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
41 | int xen_remap_domain_mfn_range(struct vm_area_struct *vma, | 100 | int xen_remap_domain_mfn_range(struct vm_area_struct *vma, |
42 | unsigned long addr, | 101 | unsigned long addr, |
43 | unsigned long mfn, int nr, | 102 | xen_pfn_t mfn, int nr, |
44 | pgprot_t prot, unsigned domid) | 103 | pgprot_t prot, unsigned domid, |
104 | struct page **pages) | ||
45 | { | 105 | { |
46 | return -ENOSYS; | 106 | int err; |
107 | struct remap_data data; | ||
108 | |||
109 | /* TBD: Batching, current sole caller only does page at a time */ | ||
110 | if (nr > 1) | ||
111 | return -EINVAL; | ||
112 | |||
113 | data.fgmfn = mfn; | ||
114 | data.prot = prot; | ||
115 | data.domid = domid; | ||
116 | data.vma = vma; | ||
117 | data.index = 0; | ||
118 | data.pages = pages; | ||
119 | err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT, | ||
120 | remap_pte_fn, &data); | ||
121 | return err; | ||
47 | } | 122 | } |
48 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); | 123 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); |
49 | 124 | ||
125 | int xen_unmap_domain_mfn_range(struct vm_area_struct *vma, | ||
126 | int nr, struct page **pages) | ||
127 | { | ||
128 | int i; | ||
129 | |||
130 | for (i = 0; i < nr; i++) { | ||
131 | struct xen_remove_from_physmap xrp; | ||
132 | unsigned long rc, pfn; | ||
133 | |||
134 | pfn = page_to_pfn(pages[i]); | ||
135 | |||
136 | xrp.domid = DOMID_SELF; | ||
137 | xrp.gpfn = pfn; | ||
138 | rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp); | ||
139 | if (rc) { | ||
140 | pr_warn("Failed to unmap pfn:%lx rc:%ld\n", | ||
141 | pfn, rc); | ||
142 | return rc; | ||
143 | } | ||
144 | } | ||
145 | return 0; | ||
146 | } | ||
147 | EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); | ||
148 | |||
50 | /* | 149 | /* |
51 | * see Documentation/devicetree/bindings/arm/xen.txt for the | 150 | * see Documentation/devicetree/bindings/arm/xen.txt for the |
52 | * documentation of the Xen Device Tree format. | 151 | * documentation of the Xen Device Tree format. |
@@ -148,21 +247,3 @@ static int __init xen_init_events(void) | |||
148 | return 0; | 247 | return 0; |
149 | } | 248 | } |
150 | postcore_initcall(xen_init_events); | 249 | postcore_initcall(xen_init_events); |
151 | |||
152 | /* XXX: only until balloon is properly working */ | ||
153 | int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem) | ||
154 | { | ||
155 | *pages = alloc_pages(highmem ? GFP_HIGHUSER : GFP_KERNEL, | ||
156 | get_order(nr_pages)); | ||
157 | if (*pages == NULL) | ||
158 | return -ENOMEM; | ||
159 | return 0; | ||
160 | } | ||
161 | EXPORT_SYMBOL_GPL(alloc_xenballooned_pages); | ||
162 | |||
163 | void free_xenballooned_pages(int nr_pages, struct page **pages) | ||
164 | { | ||
165 | kfree(*pages); | ||
166 | *pages = NULL; | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(free_xenballooned_pages); | ||
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h index 54d52ff1304a..fd9cb7695b5f 100644 --- a/arch/x86/include/asm/xen/interface.h +++ b/arch/x86/include/asm/xen/interface.h | |||
@@ -63,6 +63,7 @@ DEFINE_GUEST_HANDLE(void); | |||
63 | DEFINE_GUEST_HANDLE(uint64_t); | 63 | DEFINE_GUEST_HANDLE(uint64_t); |
64 | DEFINE_GUEST_HANDLE(uint32_t); | 64 | DEFINE_GUEST_HANDLE(uint32_t); |
65 | DEFINE_GUEST_HANDLE(xen_pfn_t); | 65 | DEFINE_GUEST_HANDLE(xen_pfn_t); |
66 | DEFINE_GUEST_HANDLE(xen_ulong_t); | ||
66 | #endif | 67 | #endif |
67 | 68 | ||
68 | #ifndef HYPERVISOR_VIRT_START | 69 | #ifndef HYPERVISOR_VIRT_START |
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index fdce49c7aff6..c31ee77e1ec1 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig | |||
@@ -6,6 +6,7 @@ config XEN | |||
6 | bool "Xen guest support" | 6 | bool "Xen guest support" |
7 | select PARAVIRT | 7 | select PARAVIRT |
8 | select PARAVIRT_CLOCK | 8 | select PARAVIRT_CLOCK |
9 | select XEN_HAVE_PVMMU | ||
9 | depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) | 10 | depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) |
10 | depends on X86_CMPXCHG && X86_TSC | 11 | depends on X86_CMPXCHG && X86_TSC |
11 | help | 12 | help |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 6226c99729b9..fd8393f55069 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -2478,8 +2478,10 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token, | |||
2478 | 2478 | ||
2479 | int xen_remap_domain_mfn_range(struct vm_area_struct *vma, | 2479 | int xen_remap_domain_mfn_range(struct vm_area_struct *vma, |
2480 | unsigned long addr, | 2480 | unsigned long addr, |
2481 | unsigned long mfn, int nr, | 2481 | xen_pfn_t mfn, int nr, |
2482 | pgprot_t prot, unsigned domid) | 2482 | pgprot_t prot, unsigned domid, |
2483 | struct page **pages) | ||
2484 | |||
2483 | { | 2485 | { |
2484 | struct remap_data rmd; | 2486 | struct remap_data rmd; |
2485 | struct mmu_update mmu_update[REMAP_BATCH_SIZE]; | 2487 | struct mmu_update mmu_update[REMAP_BATCH_SIZE]; |
@@ -2523,3 +2525,14 @@ out: | |||
2523 | return err; | 2525 | return err; |
2524 | } | 2526 | } |
2525 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); | 2527 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); |
2528 | |||
2529 | /* Returns: 0 success */ | ||
2530 | int xen_unmap_domain_mfn_range(struct vm_area_struct *vma, | ||
2531 | int numpgs, struct page **pages) | ||
2532 | { | ||
2533 | if (!pages || !xen_feature(XENFEAT_auto_translated_physmap)) | ||
2534 | return 0; | ||
2535 | |||
2536 | return -EINVAL; | ||
2537 | } | ||
2538 | EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); | ||