diff options
author | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2009-03-17 16:30:55 -0400 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2009-04-08 17:25:45 -0400 |
commit | b96229b50d71c548302053c244b89572a5264c0b (patch) | |
tree | c45ae08d83489b5f3f2c870fb3824679c166808a /arch | |
parent | b40bf53effc0338ad7926aa1abce703af372cbd4 (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>
Diffstat (limited to 'arch')
-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 6e58acd4d00d..4db24e1393a2 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1019,7 +1019,7 @@ static __init int xen_mark_pinned(struct mm_struct *mm, struct page *page, | |||
1019 | return 0; | 1019 | return 0; |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | void __init xen_mark_init_mm_pinned(void) | 1022 | static void __init xen_mark_init_mm_pinned(void) |
1023 | { | 1023 | { |
1024 | xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); | 1024 | xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); |
1025 | } | 1025 | } |
@@ -1470,6 +1470,15 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) | |||
1470 | } | 1470 | } |
1471 | #endif | 1471 | #endif |
1472 | 1472 | ||
1473 | static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) | ||
1474 | { | ||
1475 | struct mmuext_op op; | ||
1476 | op.cmd = cmd; | ||
1477 | op.arg1.mfn = pfn_to_mfn(pfn); | ||
1478 | if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) | ||
1479 | BUG(); | ||
1480 | } | ||
1481 | |||
1473 | /* Early in boot, while setting up the initial pagetable, assume | 1482 | /* Early in boot, while setting up the initial pagetable, assume |
1474 | everything is pinned. */ | 1483 | everything is pinned. */ |
1475 | static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) | 1484 | static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) |
@@ -1478,22 +1487,29 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) | |||
1478 | BUG_ON(mem_map); /* should only be used early */ | 1487 | BUG_ON(mem_map); /* should only be used early */ |
1479 | #endif | 1488 | #endif |
1480 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); | 1489 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); |
1490 | pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); | ||
1491 | } | ||
1492 | |||
1493 | /* Used for pmd and pud */ | ||
1494 | static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn) | ||
1495 | { | ||
1496 | #ifdef CONFIG_FLATMEM | ||
1497 | BUG_ON(mem_map); /* should only be used early */ | ||
1498 | #endif | ||
1499 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); | ||
1481 | } | 1500 | } |
1482 | 1501 | ||
1483 | /* Early release_pte assumes that all pts are pinned, since there's | 1502 | /* Early release_pte assumes that all pts are pinned, since there's |
1484 | only init_mm and anything attached to that is pinned. */ | 1503 | only init_mm and anything attached to that is pinned. */ |
1485 | static void xen_release_pte_init(unsigned long pfn) | 1504 | static __init void xen_release_pte_init(unsigned long pfn) |
1486 | { | 1505 | { |
1506 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); | ||
1487 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); | 1507 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
1488 | } | 1508 | } |
1489 | 1509 | ||
1490 | static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) | 1510 | static __init void xen_release_pmd_init(unsigned long pfn) |
1491 | { | 1511 | { |
1492 | struct mmuext_op op; | 1512 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
1493 | op.cmd = cmd; | ||
1494 | op.arg1.mfn = pfn_to_mfn(pfn); | ||
1495 | if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) | ||
1496 | BUG(); | ||
1497 | } | 1513 | } |
1498 | 1514 | ||
1499 | /* This needs to make sure the new pte page is pinned iff its being | 1515 | /* This needs to make sure the new pte page is pinned iff its being |
@@ -1874,9 +1890,9 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
1874 | 1890 | ||
1875 | .alloc_pte = xen_alloc_pte_init, | 1891 | .alloc_pte = xen_alloc_pte_init, |
1876 | .release_pte = xen_release_pte_init, | 1892 | .release_pte = xen_release_pte_init, |
1877 | .alloc_pmd = xen_alloc_pte_init, | 1893 | .alloc_pmd = xen_alloc_pmd_init, |
1878 | .alloc_pmd_clone = paravirt_nop, | 1894 | .alloc_pmd_clone = paravirt_nop, |
1879 | .release_pmd = xen_release_pte_init, | 1895 | .release_pmd = xen_release_pmd_init, |
1880 | 1896 | ||
1881 | #ifdef CONFIG_HIGHPTE | 1897 | #ifdef CONFIG_HIGHPTE |
1882 | .kmap_atomic_pte = xen_kmap_atomic_pte, | 1898 | .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 2f5ef2632ea2..20139464943c 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -57,8 +57,6 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id); | |||
57 | 57 | ||
58 | bool xen_vcpu_stolen(int vcpu); | 58 | bool xen_vcpu_stolen(int vcpu); |
59 | 59 | ||
60 | void xen_mark_init_mm_pinned(void); | ||
61 | |||
62 | void xen_setup_vcpu_info_placement(void); | 60 | void xen_setup_vcpu_info_placement(void); |
63 | 61 | ||
64 | #ifdef CONFIG_SMP | 62 | #ifdef CONFIG_SMP |