diff options
-rw-r--r-- | arch/x86/xen/enlighten.c | 14 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 39 | ||||
-rw-r--r-- | arch/x86/xen/mmu.h | 8 |
3 files changed, 50 insertions, 11 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index b94f63ac228b..ed9f04b3836d 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -901,6 +901,14 @@ static __init void xen_pagetable_setup_done(pgd_t *base) | |||
901 | pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base))); | 901 | pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base))); |
902 | } | 902 | } |
903 | 903 | ||
904 | static __init void xen_post_allocator_init(void) | ||
905 | { | ||
906 | pv_mmu_ops.set_pmd = xen_set_pmd; | ||
907 | pv_mmu_ops.set_pud = xen_set_pud; | ||
908 | |||
909 | xen_mark_init_mm_pinned(); | ||
910 | } | ||
911 | |||
904 | /* This is called once we have the cpu_possible_map */ | 912 | /* This is called once we have the cpu_possible_map */ |
905 | void xen_setup_vcpu_info_placement(void) | 913 | void xen_setup_vcpu_info_placement(void) |
906 | { | 914 | { |
@@ -988,7 +996,7 @@ static const struct pv_init_ops xen_init_ops __initdata = { | |||
988 | .banner = xen_banner, | 996 | .banner = xen_banner, |
989 | .memory_setup = xen_memory_setup, | 997 | .memory_setup = xen_memory_setup, |
990 | .arch_setup = xen_arch_setup, | 998 | .arch_setup = xen_arch_setup, |
991 | .post_allocator_init = xen_mark_init_mm_pinned, | 999 | .post_allocator_init = xen_post_allocator_init, |
992 | }; | 1000 | }; |
993 | 1001 | ||
994 | static const struct pv_time_ops xen_time_ops __initdata = { | 1002 | static const struct pv_time_ops xen_time_ops __initdata = { |
@@ -1100,7 +1108,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
1100 | 1108 | ||
1101 | .set_pte = NULL, /* see xen_pagetable_setup_* */ | 1109 | .set_pte = NULL, /* see xen_pagetable_setup_* */ |
1102 | .set_pte_at = xen_set_pte_at, | 1110 | .set_pte_at = xen_set_pte_at, |
1103 | .set_pmd = xen_set_pmd, | 1111 | .set_pmd = xen_set_pmd_hyper, |
1104 | 1112 | ||
1105 | .pte_val = xen_pte_val, | 1113 | .pte_val = xen_pte_val, |
1106 | .pte_flags = native_pte_val, | 1114 | .pte_flags = native_pte_val, |
@@ -1111,7 +1119,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
1111 | 1119 | ||
1112 | .set_pte_atomic = xen_set_pte_atomic, | 1120 | .set_pte_atomic = xen_set_pte_atomic, |
1113 | .set_pte_present = xen_set_pte_at, | 1121 | .set_pte_present = xen_set_pte_at, |
1114 | .set_pud = xen_set_pud, | 1122 | .set_pud = xen_set_pud_hyper, |
1115 | .pte_clear = xen_pte_clear, | 1123 | .pte_clear = xen_pte_clear, |
1116 | .pmd_clear = xen_pmd_clear, | 1124 | .pmd_clear = xen_pmd_clear, |
1117 | 1125 | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 17f374eb1faa..4fa0934db925 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -223,7 +223,14 @@ void make_lowmem_page_readwrite(void *vaddr) | |||
223 | } | 223 | } |
224 | 224 | ||
225 | 225 | ||
226 | void xen_set_pmd(pmd_t *ptr, pmd_t val) | 226 | static bool page_pinned(void *ptr) |
227 | { | ||
228 | struct page *page = virt_to_page(ptr); | ||
229 | |||
230 | return PagePinned(page); | ||
231 | } | ||
232 | |||
233 | void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val) | ||
227 | { | 234 | { |
228 | struct multicall_space mcs; | 235 | struct multicall_space mcs; |
229 | struct mmu_update *u; | 236 | struct mmu_update *u; |
@@ -241,6 +248,18 @@ void xen_set_pmd(pmd_t *ptr, pmd_t val) | |||
241 | preempt_enable(); | 248 | preempt_enable(); |
242 | } | 249 | } |
243 | 250 | ||
251 | void xen_set_pmd(pmd_t *ptr, pmd_t val) | ||
252 | { | ||
253 | /* If page is not pinned, we can just update the entry | ||
254 | directly */ | ||
255 | if (!page_pinned(ptr)) { | ||
256 | *ptr = val; | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | xen_set_pmd_hyper(ptr, val); | ||
261 | } | ||
262 | |||
244 | /* | 263 | /* |
245 | * Associate a virtual page frame with a given physical page frame | 264 | * Associate a virtual page frame with a given physical page frame |
246 | * and protection flags for that frame. | 265 | * and protection flags for that frame. |
@@ -348,7 +367,7 @@ pmdval_t xen_pmd_val(pmd_t pmd) | |||
348 | return ret; | 367 | return ret; |
349 | } | 368 | } |
350 | 369 | ||
351 | void xen_set_pud(pud_t *ptr, pud_t val) | 370 | void xen_set_pud_hyper(pud_t *ptr, pud_t val) |
352 | { | 371 | { |
353 | struct multicall_space mcs; | 372 | struct multicall_space mcs; |
354 | struct mmu_update *u; | 373 | struct mmu_update *u; |
@@ -366,6 +385,18 @@ void xen_set_pud(pud_t *ptr, pud_t val) | |||
366 | preempt_enable(); | 385 | preempt_enable(); |
367 | } | 386 | } |
368 | 387 | ||
388 | void xen_set_pud(pud_t *ptr, pud_t val) | ||
389 | { | ||
390 | /* If page is not pinned, we can just update the entry | ||
391 | directly */ | ||
392 | if (!page_pinned(ptr)) { | ||
393 | *ptr = val; | ||
394 | return; | ||
395 | } | ||
396 | |||
397 | xen_set_pud_hyper(ptr, val); | ||
398 | } | ||
399 | |||
369 | void xen_set_pte(pte_t *ptep, pte_t pte) | 400 | void xen_set_pte(pte_t *ptep, pte_t pte) |
370 | { | 401 | { |
371 | ptep->pte_high = pte.pte_high; | 402 | ptep->pte_high = pte.pte_high; |
@@ -387,7 +418,7 @@ void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | |||
387 | 418 | ||
388 | void xen_pmd_clear(pmd_t *pmdp) | 419 | void xen_pmd_clear(pmd_t *pmdp) |
389 | { | 420 | { |
390 | xen_set_pmd(pmdp, __pmd(0)); | 421 | set_pmd(pmdp, __pmd(0)); |
391 | } | 422 | } |
392 | 423 | ||
393 | pmd_t xen_make_pmd(pmdval_t pmd) | 424 | pmd_t xen_make_pmd(pmdval_t pmd) |
@@ -758,7 +789,7 @@ void xen_exit_mmap(struct mm_struct *mm) | |||
758 | spin_lock(&mm->page_table_lock); | 789 | spin_lock(&mm->page_table_lock); |
759 | 790 | ||
760 | /* pgd may not be pinned in the error exit path of execve */ | 791 | /* pgd may not be pinned in the error exit path of execve */ |
761 | if (PagePinned(virt_to_page(mm->pgd))) | 792 | if (page_pinned(mm->pgd)) |
762 | xen_pgd_unpin(mm->pgd); | 793 | xen_pgd_unpin(mm->pgd); |
763 | 794 | ||
764 | spin_unlock(&mm->page_table_lock); | 795 | spin_unlock(&mm->page_table_lock); |
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h index 5fe961caffd4..e3dd09e25c63 100644 --- a/arch/x86/xen/mmu.h +++ b/arch/x86/xen/mmu.h | |||
@@ -25,10 +25,6 @@ enum pt_level { | |||
25 | 25 | ||
26 | void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); | 26 | void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); |
27 | 27 | ||
28 | void xen_set_pte(pte_t *ptep, pte_t pteval); | ||
29 | void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, | ||
30 | pte_t *ptep, pte_t pteval); | ||
31 | void xen_set_pmd(pmd_t *pmdp, pmd_t pmdval); | ||
32 | 28 | ||
33 | void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next); | 29 | void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next); |
34 | void xen_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm); | 30 | void xen_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm); |
@@ -45,10 +41,14 @@ pte_t xen_make_pte(pteval_t); | |||
45 | pmd_t xen_make_pmd(pmdval_t); | 41 | pmd_t xen_make_pmd(pmdval_t); |
46 | pgd_t xen_make_pgd(pgdval_t); | 42 | pgd_t xen_make_pgd(pgdval_t); |
47 | 43 | ||
44 | void xen_set_pte(pte_t *ptep, pte_t pteval); | ||
48 | void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, | 45 | void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, |
49 | pte_t *ptep, pte_t pteval); | 46 | pte_t *ptep, pte_t pteval); |
50 | void xen_set_pte_atomic(pte_t *ptep, pte_t pte); | 47 | void xen_set_pte_atomic(pte_t *ptep, pte_t pte); |
48 | void xen_set_pmd(pmd_t *pmdp, pmd_t pmdval); | ||
51 | void xen_set_pud(pud_t *ptr, pud_t val); | 49 | void xen_set_pud(pud_t *ptr, pud_t val); |
50 | void xen_set_pmd_hyper(pmd_t *pmdp, pmd_t pmdval); | ||
51 | void xen_set_pud_hyper(pud_t *ptr, pud_t val); | ||
52 | void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); | 52 | void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); |
53 | void xen_pmd_clear(pmd_t *pmdp); | 53 | void xen_pmd_clear(pmd_t *pmdp); |
54 | 54 | ||