diff options
author | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2009-03-17 16:30:55 -0400 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2009-03-30 12:25:32 -0400 |
commit | 4185f35404dc96f8525298c7c548aee419f3b3f4 (patch) | |
tree | 47a41bb11ee58db4c6ff9d1ba2e96a734eda2f5a | |
parent | 5f241e65f2be4661a33e1937e1c829252a80b2b8 (diff) |
xen/mmu: some early pagetable cleanups
1. make sure early-allocated ptes are pinned, so they can be later
unpinned
2. don't pin pmd+pud, just make them RO
3. scatter some __inits around
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
-rw-r--r-- | arch/x86/xen/mmu.c | 40 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 2 |
2 files changed, 28 insertions, 14 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 67d2ab45cd90..df87c803cecc 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1013,7 +1013,7 @@ static __init int xen_mark_pinned(struct mm_struct *mm, struct page *page, | |||
1013 | return 0; | 1013 | return 0; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | void __init xen_mark_init_mm_pinned(void) | 1016 | static void __init xen_mark_init_mm_pinned(void) |
1017 | { | 1017 | { |
1018 | xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); | 1018 | xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); |
1019 | } | 1019 | } |
@@ -1461,6 +1461,15 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) | |||
1461 | } | 1461 | } |
1462 | #endif | 1462 | #endif |
1463 | 1463 | ||
1464 | static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) | ||
1465 | { | ||
1466 | struct mmuext_op op; | ||
1467 | op.cmd = cmd; | ||
1468 | op.arg1.mfn = pfn_to_mfn(pfn); | ||
1469 | if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) | ||
1470 | BUG(); | ||
1471 | } | ||
1472 | |||
1464 | /* Early in boot, while setting up the initial pagetable, assume | 1473 | /* Early in boot, while setting up the initial pagetable, assume |
1465 | everything is pinned. */ | 1474 | everything is pinned. */ |
1466 | static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) | 1475 | static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) |
@@ -1469,22 +1478,29 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) | |||
1469 | BUG_ON(mem_map); /* should only be used early */ | 1478 | BUG_ON(mem_map); /* should only be used early */ |
1470 | #endif | 1479 | #endif |
1471 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); | 1480 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); |
1481 | pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); | ||
1482 | } | ||
1483 | |||
1484 | /* Used for pmd and pud */ | ||
1485 | static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn) | ||
1486 | { | ||
1487 | #ifdef CONFIG_FLATMEM | ||
1488 | BUG_ON(mem_map); /* should only be used early */ | ||
1489 | #endif | ||
1490 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); | ||
1472 | } | 1491 | } |
1473 | 1492 | ||
1474 | /* Early release_pte assumes that all pts are pinned, since there's | 1493 | /* Early release_pte assumes that all pts are pinned, since there's |
1475 | only init_mm and anything attached to that is pinned. */ | 1494 | only init_mm and anything attached to that is pinned. */ |
1476 | static void xen_release_pte_init(unsigned long pfn) | 1495 | static __init void xen_release_pte_init(unsigned long pfn) |
1477 | { | 1496 | { |
1497 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); | ||
1478 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); | 1498 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
1479 | } | 1499 | } |
1480 | 1500 | ||
1481 | static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) | 1501 | static __init void xen_release_pmd_init(unsigned long pfn) |
1482 | { | 1502 | { |
1483 | struct mmuext_op op; | 1503 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
1484 | op.cmd = cmd; | ||
1485 | op.arg1.mfn = pfn_to_mfn(pfn); | ||
1486 | if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) | ||
1487 | BUG(); | ||
1488 | } | 1504 | } |
1489 | 1505 | ||
1490 | /* This needs to make sure the new pte page is pinned iff its being | 1506 | /* This needs to make sure the new pte page is pinned iff its being |
@@ -1873,9 +1889,9 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
1873 | 1889 | ||
1874 | .alloc_pte = xen_alloc_pte_init, | 1890 | .alloc_pte = xen_alloc_pte_init, |
1875 | .release_pte = xen_release_pte_init, | 1891 | .release_pte = xen_release_pte_init, |
1876 | .alloc_pmd = xen_alloc_pte_init, | 1892 | .alloc_pmd = xen_alloc_pmd_init, |
1877 | .alloc_pmd_clone = paravirt_nop, | 1893 | .alloc_pmd_clone = paravirt_nop, |
1878 | .release_pmd = xen_release_pte_init, | 1894 | .release_pmd = xen_release_pmd_init, |
1879 | 1895 | ||
1880 | #ifdef CONFIG_HIGHPTE | 1896 | #ifdef CONFIG_HIGHPTE |
1881 | .kmap_atomic_pte = xen_kmap_atomic_pte, | 1897 | .kmap_atomic_pte = xen_kmap_atomic_pte, |
@@ -1914,8 +1930,8 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
1914 | .make_pud = PV_CALLEE_SAVE(xen_make_pud), | 1930 | .make_pud = PV_CALLEE_SAVE(xen_make_pud), |
1915 | .set_pgd = xen_set_pgd_hyper, | 1931 | .set_pgd = xen_set_pgd_hyper, |
1916 | 1932 | ||
1917 | .alloc_pud = xen_alloc_pte_init, | 1933 | .alloc_pud = xen_alloc_pmd_init, |
1918 | .release_pud = xen_release_pte_init, | 1934 | .release_pud = xen_release_pmd_init, |
1919 | #endif /* PAGETABLE_LEVELS == 4 */ | 1935 | #endif /* PAGETABLE_LEVELS == 4 */ |
1920 | 1936 | ||
1921 | .activate_mm = xen_activate_mm, | 1937 | .activate_mm = xen_activate_mm, |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index f897cdffccb6..5c50a1017a37 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -56,8 +56,6 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id); | |||
56 | 56 | ||
57 | bool xen_vcpu_stolen(int vcpu); | 57 | bool xen_vcpu_stolen(int vcpu); |
58 | 58 | ||
59 | void xen_mark_init_mm_pinned(void); | ||
60 | |||
61 | void xen_setup_vcpu_info_placement(void); | 59 | void xen_setup_vcpu_info_placement(void); |
62 | 60 | ||
63 | #ifdef CONFIG_SMP | 61 | #ifdef CONFIG_SMP |