Skip to content

Commit 6a7ed40

Browse files
committed
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>
2 parents a7be94a + f832da0 commit 6a7ed40

File tree

11 files changed

+246
-33
lines changed

11 files changed

+246
-33
lines changed

arch/arm/include/asm/xen/interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ DEFINE_GUEST_HANDLE(void);
4949
DEFINE_GUEST_HANDLE(uint64_t);
5050
DEFINE_GUEST_HANDLE(uint32_t);
5151
DEFINE_GUEST_HANDLE(xen_pfn_t);
52+
DEFINE_GUEST_HANDLE(xen_ulong_t);
5253

5354
/* Maximum number of virtual CPUs in multi-processor guests. */
5455
#define MAX_VIRT_CPUS 1

arch/arm/xen/enlighten.c

Lines changed: 102 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <xen/features.h>
99
#include <xen/platform_pci.h>
1010
#include <xen/xenbus.h>
11+
#include <xen/page.h>
12+
#include <xen/xen-ops.h>
1113
#include <asm/xen/hypervisor.h>
1214
#include <asm/xen/hypercall.h>
1315
#include <linux/interrupt.h>
@@ -17,6 +19,8 @@
1719
#include <linux/of_irq.h>
1820
#include <linux/of_address.h>
1921

22+
#include <linux/mm.h>
23+
2024
struct start_info _xen_start_info;
2125
struct start_info *xen_start_info = &_xen_start_info;
2226
EXPORT_SYMBOL_GPL(xen_start_info);
@@ -29,6 +33,10 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
2933

3034
DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
3135

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+
3240
/* TODO: to be removed */
3341
__read_mostly int xen_have_vector_callback;
3442
EXPORT_SYMBOL_GPL(xen_have_vector_callback);
@@ -38,15 +46,106 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
3846

3947
static __read_mostly int xen_events_irq = -1;
4048

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+
41100
int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
42101
unsigned long addr,
43-
unsigned long mfn, int nr,
44-
pgprot_t prot, unsigned domid)
102+
xen_pfn_t mfn, int nr,
103+
pgprot_t prot, unsigned domid,
104+
struct page **pages)
45105
{
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;
47122
}
48123
EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
49124

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+
50149
/*
51150
* see Documentation/devicetree/bindings/arm/xen.txt for the
52151
* documentation of the Xen Device Tree format.
@@ -148,21 +247,3 @@ static int __init xen_init_events(void)
148247
return 0;
149248
}
150249
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);

arch/x86/include/asm/xen/interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ DEFINE_GUEST_HANDLE(void);
6363
DEFINE_GUEST_HANDLE(uint64_t);
6464
DEFINE_GUEST_HANDLE(uint32_t);
6565
DEFINE_GUEST_HANDLE(xen_pfn_t);
66+
DEFINE_GUEST_HANDLE(xen_ulong_t);
6667
#endif
6768

6869
#ifndef HYPERVISOR_VIRT_START

arch/x86/xen/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ config XEN
66
bool "Xen guest support"
77
select PARAVIRT
88
select PARAVIRT_CLOCK
9+
select XEN_HAVE_PVMMU
910
depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
1011
depends on X86_CMPXCHG && X86_TSC
1112
help

arch/x86/xen/mmu.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,8 +2478,10 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
24782478

24792479
int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
24802480
unsigned long addr,
2481-
unsigned long mfn, int nr,
2482-
pgprot_t prot, unsigned domid)
2481+
xen_pfn_t mfn, int nr,
2482+
pgprot_t prot, unsigned domid,
2483+
struct page **pages)
2484+
24832485
{
24842486
struct remap_data rmd;
24852487
struct mmu_update mmu_update[REMAP_BATCH_SIZE];
@@ -2523,3 +2525,14 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
25232525
return err;
25242526
}
25252527
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);

drivers/xen/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,7 @@ config XEN_MCE_LOG
206206
Allow kernel fetching MCE error from Xen platform and
207207
converting it into Linux mcelog format for mcelog tools
208208

209+
config XEN_HAVE_PVMMU
210+
bool
211+
209212
endmenu

drivers/xen/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
ifneq ($(CONFIG_ARM),y)
2-
obj-y += manage.o balloon.o
2+
obj-y += manage.o
33
obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
44
endif
5-
obj-y += grant-table.o features.o events.o
5+
obj-y += grant-table.o features.o events.o balloon.o
66
obj-y += xenbus/
77

88
nostackp := $(call cc-option, -fno-stack-protector)

drivers/xen/balloon.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
359359

360360
set_phys_to_machine(pfn, frame_list[i]);
361361

362+
#ifdef CONFIG_XEN_HAVE_PVMMU
362363
/* Link back into the page tables if not highmem. */
363364
if (xen_pv_domain() && !PageHighMem(page)) {
364365
int ret;
@@ -368,6 +369,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
368369
0);
369370
BUG_ON(ret);
370371
}
372+
#endif
371373

372374
/* Relinquish the page back to the allocator. */
373375
ClearPageReserved(page);
@@ -416,13 +418,14 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
416418

417419
scrub_page(page);
418420

421+
#ifdef CONFIG_XEN_HAVE_PVMMU
419422
if (xen_pv_domain() && !PageHighMem(page)) {
420423
ret = HYPERVISOR_update_va_mapping(
421424
(unsigned long)__va(pfn << PAGE_SHIFT),
422425
__pte_ma(0), 0);
423426
BUG_ON(ret);
424427
}
425-
428+
#endif
426429
}
427430

428431
/* Ensure that ballooned highmem pages don't have kmaps. */

0 commit comments

Comments
 (0)