aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2009-03-17 16:30:55 -0400
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2009-04-08 17:25:45 -0400
commitb96229b50d71c548302053c244b89572a5264c0b (patch)
treec45ae08d83489b5f3f2c870fb3824679c166808a /arch/x86/xen
parentb40bf53effc0338ad7926aa1abce703af372cbd4 (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/x86/xen')
-rw-r--r--arch/x86/xen/mmu.c40
-rw-r--r--arch/x86/xen/xen-ops.h2
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
1022void __init xen_mark_init_mm_pinned(void) 1022static 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
1473static 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. */
1475static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) 1484static __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 */
1494static __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. */
1485static void xen_release_pte_init(unsigned long pfn) 1504static __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
1490static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) 1510static __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
58bool xen_vcpu_stolen(int vcpu); 58bool xen_vcpu_stolen(int vcpu);
59 59
60void xen_mark_init_mm_pinned(void);
61
62void xen_setup_vcpu_info_placement(void); 60void xen_setup_vcpu_info_placement(void);
63 61
64#ifdef CONFIG_SMP 62#ifdef CONFIG_SMP