Konrad Rzeszutek Wilk
2012-Jul-26 20:34 UTC
[PATCH] documentation, refactor, and cleanups (v2) for 3.7
Attached are four patches that documented a bit more the P2M and MMU code. And as well make some of the code cleaner and easier to read.
Konrad Rzeszutek Wilk
2012-Jul-26 20:34 UTC
[PATCH 1/4] xen/p2m: Fix the comment describing the P2M tree.
It mixed up the p2m_mid_missing with p2m_missing. Also remove some extra spaces. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- arch/x86/xen/p2m.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 64effdc..e4adbfb 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -22,7 +22,7 @@ * * P2M_PER_PAGE depends on the architecture, as a mfn is always * unsigned long (8 bytes on 64-bit, 4 bytes on 32), leading to - * 512 and 1024 entries respectively. + * 512 and 1024 entries respectively. * * In short, these structures contain the Machine Frame Number (MFN) of the PFN. * @@ -139,11 +139,11 @@ * / | ~0, ~0, .... | * | \---------------/ * | - * p2m_missing p2m_missing - * /------------------\ /------------\ - * | [p2m_mid_missing]+---->| ~0, ~0, ~0 | - * | [p2m_mid_missing]+---->| ..., ~0 | - * \------------------/ \------------/ + * p2m_mid_missing p2m_missing + * /-----------------\ /------------\ + * | [p2m_missing] +---->| ~0, ~0, ~0 | + * | [p2m_missing] +---->| ..., ~0 | + * \-----------------/ \------------/ * * where ~0 is INVALID_P2M_ENTRY. IDENTITY is (PFN | IDENTITY_BIT) */ @@ -423,7 +423,7 @@ static void free_p2m_page(void *p) free_page((unsigned long)p); } -/* +/* * Fully allocate the p2m structure for a given pfn. We need to check * that both the top and mid levels are allocated, and make sure the * parallel mfn tree is kept in sync. We may race with other cpus, so -- 1.7.7.6
Konrad Rzeszutek Wilk
2012-Jul-26 20:34 UTC
[PATCH 2/4] xen/x86: Use memblock_reserve for sensitive areas.
instead of a big memblock_reserve. This way we can be more selective in freeing regions (and it also makes it easier to understand where is what). [v1: Move the auto_translate_physmap to proper line] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- arch/x86/xen/enlighten.c | 38 ++++++++++++++++++++++++++++++++++++++ arch/x86/xen/p2m.c | 5 +++++ arch/x86/xen/setup.c | 9 --------- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ff962d4..9b1afa4 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -998,7 +998,44 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) return ret; } +static void __init xen_reserve_mfn(unsigned long mfn) +{ + unsigned long pfn; + + if (!mfn) + return; + pfn = mfn_to_pfn(mfn); + if (phys_to_machine_mapping_valid(pfn)) + memblock_reserve(PFN_PHYS(pfn), PAGE_SIZE); +} +static void __init xen_reserve_internals(void) +{ + unsigned long size; + + if (!xen_pv_domain()) + return; + + memblock_reserve(__pa(xen_start_info), PAGE_SIZE); + + xen_reserve_mfn(PFN_DOWN(xen_start_info->shared_info)); + xen_reserve_mfn(xen_start_info->store_mfn); + if (!xen_initial_domain()) + xen_reserve_mfn(xen_start_info->console.domU.mfn); + + if (xen_feature(XENFEAT_auto_translated_physmap)) + return; + + /* + * ALIGN up to compensate for the p2m_page pointing to an array that + * can partially filled (look in xen_build_dynamic_phys_to_machine). + */ + + size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long)); + memblock_reserve(__pa(xen_start_info->mfn_list), size); + + /* The pagetables are reserved in mmu.c */ +} void xen_setup_shared_info(void) { if (!xen_feature(XENFEAT_auto_translated_physmap)) { @@ -1362,6 +1399,7 @@ asmlinkage void __init xen_start_kernel(void) xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); + xen_reserve_internals(); /* Allocate and initialize top and mid mfn levels for p2m structure */ xen_build_mfn_list_list(); diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index e4adbfb..6a2bfa4 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -388,6 +388,11 @@ void __init xen_build_dynamic_phys_to_machine(void) } m2p_override_init(); + + /* NOTE: We cannot call memblock_reserve here for the mfn_list as there + * isn''t enough pieces to make it work (for one - we are still using the + * Xen provided pagetable). Do it later in xen_reserve_internals. + */ } unsigned long get_phys_to_machine(unsigned long pfn) diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index a4790bf..9efca75 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -424,15 +424,6 @@ char * __init xen_memory_setup(void) e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_RESERVED); - /* - * Reserve Xen bits: - * - mfn_list - * - xen_start_info - * See comment above "struct start_info" in <xen/interface/xen.h> - */ - memblock_reserve(__pa(xen_start_info->mfn_list), - xen_start_info->pt_base - xen_start_info->mfn_list); - sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); return "Xen"; -- 1.7.7.6
Konrad Rzeszutek Wilk
2012-Jul-26 20:34 UTC
[PATCH 3/4] xen/mmu: The xen_setup_kernel_pagetable doesn''t need to return anything.
We don''t need to return the new PGD - as we do not use it. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- arch/x86/xen/enlighten.c | 5 +---- arch/x86/xen/mmu.c | 10 ++-------- arch/x86/xen/xen-ops.h | 2 +- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 9b1afa4..2b67948 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1295,7 +1295,6 @@ asmlinkage void __init xen_start_kernel(void) { struct physdev_set_iopl set_iopl; int rc; - pgd_t *pgd; if (!xen_start_info) return; @@ -1387,8 +1386,6 @@ asmlinkage void __init xen_start_kernel(void) acpi_numa = -1; #endif - pgd = (pgd_t *)xen_start_info->pt_base; - /* Don''t do the full vcpu_info placement stuff until we have a possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; @@ -1397,7 +1394,7 @@ asmlinkage void __init xen_start_kernel(void) early_boot_irqs_disabled = true; xen_raw_console_write("mapping kernel into physical memory\n"); - pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); + xen_setup_kernel_pagetable((pgd_t *)xen_start_info->pt_base, xen_start_info->nr_pages); xen_reserve_internals(); /* Allocate and initialize top and mid mfn levels for p2m structure */ diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 3a73785..4ac21a4 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1719,8 +1719,7 @@ static void convert_pfn_mfn(void *v) * of the physical mapping once some sort of allocator has been set * up. */ -pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, - unsigned long max_pfn) +void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) { pud_t *l3; pmd_t *l2; @@ -1781,8 +1780,6 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, memblock_reserve(__pa(xen_start_info->pt_base), xen_start_info->nr_pt_frames * PAGE_SIZE); - - return pgd; } #else /* !CONFIG_X86_64 */ static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD); @@ -1825,8 +1822,7 @@ static void __init xen_write_cr3_init(unsigned long cr3) pv_mmu_ops.write_cr3 = &xen_write_cr3; } -pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, - unsigned long max_pfn) +void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) { pmd_t *kernel_pmd; @@ -1858,8 +1854,6 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, memblock_reserve(__pa(xen_start_info->pt_base), xen_start_info->nr_pt_frames * PAGE_SIZE); - - return initial_page_table; } #endif /* CONFIG_X86_64 */ diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 202d4c1..2230f57 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -27,7 +27,7 @@ void xen_setup_mfn_list_list(void); void xen_setup_shared_info(void); void xen_build_mfn_list_list(void); void xen_setup_machphys_mapping(void); -pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); +void xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); void xen_reserve_top(void); extern unsigned long xen_max_p2m_pfn; -- 1.7.7.6
Konrad Rzeszutek Wilk
2012-Jul-26 20:34 UTC
[PATCH 4/4] xen/mmu: Provide comments describing the _ka and _va aliasing issue
Which is that the level2_kernel_pgt (__ka virtual addresses) and level2_ident_pgt (__va virtual address) contain the same PMD entries. So if you modify a PTE in __ka, it will be reflected in __va (and vice-versa). Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- arch/x86/xen/mmu.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 4ac21a4..6ba6100 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1734,19 +1734,36 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) init_level4_pgt[0] = __pgd(0); /* Pre-constructed entries are in pfn, so convert to mfn */ + /* L4[272] -> level3_ident_pgt + * L4[511] -> level3_kernel_pgt */ convert_pfn_mfn(init_level4_pgt); + + /* L3_i[0] -> level2_ident_pgt */ convert_pfn_mfn(level3_ident_pgt); + /* L3_k[510] -> level2_kernel_pgt + * L3_i[511] -> level2_fixmap_pgt */ convert_pfn_mfn(level3_kernel_pgt); + /* We get [511][511] and have Xen''s version of level2_kernel_pgt */ l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd); l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud); + /* Graft it onto L4[272][0]. Note that we creating an aliasing problem: + * Both L4[272][0] and L4[511][511] have entries that point to the same + * L2 (PMD) tables. Meaning that if you modify it in __va space + * it will be also modified in the __ka space! (But if you just + * modify the PMD table to point to other PTE''s or none, then you + * are OK - which is what cleanup_highmap does) */ memcpy(level2_ident_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD); + /* Graft it onto L4[511][511] */ memcpy(level2_kernel_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD); + /* Get [511][510] and graft that in level2_fixmap_pgt */ l3 = m2v(pgd[pgd_index(__START_KERNEL_map + PMD_SIZE)].pgd); l2 = m2v(l3[pud_index(__START_KERNEL_map + PMD_SIZE)].pud); memcpy(level2_fixmap_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD); + /* Note that we don''t do anything with level1_fixmap_pgt which + * we don''t need. */ /* Set up identity map */ xen_map_identity_early(level2_ident_pgt, max_pfn); -- 1.7.7.6
Stefano Stabellini
2012-Jul-27 10:36 UTC
Re: [PATCH 3/4] xen/mmu: The xen_setup_kernel_pagetable doesn''t need to return anything.
On Thu, 26 Jul 2012, Konrad Rzeszutek Wilk wrote:> We don''t need to return the new PGD - as we do not use it. > > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>> arch/x86/xen/enlighten.c | 5 +---- > arch/x86/xen/mmu.c | 10 ++-------- > arch/x86/xen/xen-ops.h | 2 +- > 3 files changed, 4 insertions(+), 13 deletions(-) > > diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c > index 9b1afa4..2b67948 100644 > --- a/arch/x86/xen/enlighten.c > +++ b/arch/x86/xen/enlighten.c > @@ -1295,7 +1295,6 @@ asmlinkage void __init xen_start_kernel(void) > { > struct physdev_set_iopl set_iopl; > int rc; > - pgd_t *pgd; > > if (!xen_start_info) > return; > @@ -1387,8 +1386,6 @@ asmlinkage void __init xen_start_kernel(void) > acpi_numa = -1; > #endif > > - pgd = (pgd_t *)xen_start_info->pt_base; > - > /* Don''t do the full vcpu_info placement stuff until we have a > possible map and a non-dummy shared_info. */ > per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; > @@ -1397,7 +1394,7 @@ asmlinkage void __init xen_start_kernel(void) > early_boot_irqs_disabled = true; > > xen_raw_console_write("mapping kernel into physical memory\n"); > - pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); > + xen_setup_kernel_pagetable((pgd_t *)xen_start_info->pt_base, xen_start_info->nr_pages); > > xen_reserve_internals(); > /* Allocate and initialize top and mid mfn levels for p2m structure */ > diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c > index 3a73785..4ac21a4 100644 > --- a/arch/x86/xen/mmu.c > +++ b/arch/x86/xen/mmu.c > @@ -1719,8 +1719,7 @@ static void convert_pfn_mfn(void *v) > * of the physical mapping once some sort of allocator has been set > * up. > */ > -pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, > - unsigned long max_pfn) > +void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) > { > pud_t *l3; > pmd_t *l2; > @@ -1781,8 +1780,6 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, > > memblock_reserve(__pa(xen_start_info->pt_base), > xen_start_info->nr_pt_frames * PAGE_SIZE); > - > - return pgd; > } > #else /* !CONFIG_X86_64 */ > static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD); > @@ -1825,8 +1822,7 @@ static void __init xen_write_cr3_init(unsigned long cr3) > pv_mmu_ops.write_cr3 = &xen_write_cr3; > } > > -pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, > - unsigned long max_pfn) > +void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) > { > pmd_t *kernel_pmd; > > @@ -1858,8 +1854,6 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, > > memblock_reserve(__pa(xen_start_info->pt_base), > xen_start_info->nr_pt_frames * PAGE_SIZE); > - > - return initial_page_table; > } > #endif /* CONFIG_X86_64 */ > > diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h > index 202d4c1..2230f57 100644 > --- a/arch/x86/xen/xen-ops.h > +++ b/arch/x86/xen/xen-ops.h > @@ -27,7 +27,7 @@ void xen_setup_mfn_list_list(void); > void xen_setup_shared_info(void); > void xen_build_mfn_list_list(void); > void xen_setup_machphys_mapping(void); > -pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); > +void xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); > void xen_reserve_top(void); > extern unsigned long xen_max_p2m_pfn; > > -- > 1.7.7.6 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ >
Stefano Stabellini
2012-Jul-27 10:49 UTC
Re: [PATCH 2/4] xen/x86: Use memblock_reserve for sensitive areas.
On Thu, 26 Jul 2012, Konrad Rzeszutek Wilk wrote:> instead of a big memblock_reserve. This way we can be more > selective in freeing regions (and it also makes it easier > to understand where is what). > > [v1: Move the auto_translate_physmap to proper line] > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> > --- > arch/x86/xen/enlighten.c | 38 ++++++++++++++++++++++++++++++++++++++ > arch/x86/xen/p2m.c | 5 +++++ > arch/x86/xen/setup.c | 9 --------- > 3 files changed, 43 insertions(+), 9 deletions(-) > > diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c > index ff962d4..9b1afa4 100644 > --- a/arch/x86/xen/enlighten.c > +++ b/arch/x86/xen/enlighten.c > @@ -998,7 +998,44 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) > > return ret; > } > +static void __init xen_reserve_mfn(unsigned long mfn) > +{ > + unsigned long pfn; > + > + if (!mfn) > + return; > + pfn = mfn_to_pfn(mfn); > + if (phys_to_machine_mapping_valid(pfn)) > + memblock_reserve(PFN_PHYS(pfn), PAGE_SIZE); > +}If the mfn is not in the m2p xen_reserve_mfn won''t do anything. It is worth writing it down in a comment.> +static void __init xen_reserve_internals(void) > +{ > + unsigned long size; > + > + if (!xen_pv_domain()) > + return; > + > + memblock_reserve(__pa(xen_start_info), PAGE_SIZE);xen_start_info is not in the m2p, so you cannot use xen_reserve_mfn> + xen_reserve_mfn(PFN_DOWN(xen_start_info->shared_info)); > + xen_reserve_mfn(xen_start_info->store_mfn);Are we sure that shared_info points to an mfn that is in the m2p (rather than a special mfn not present in the list)?> + if (!xen_initial_domain()) > + xen_reserve_mfn(xen_start_info->console.domU.mfn); > + > + if (xen_feature(XENFEAT_auto_translated_physmap)) > + return; > + > + /* > + * ALIGN up to compensate for the p2m_page pointing to an array that > + * can partially filled (look in xen_build_dynamic_phys_to_machine). > + */ > + > + size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long)); > + memblock_reserve(__pa(xen_start_info->mfn_list), size);I take that here you are using memblock_reserve again, rather than xen_reserve_mfn, because the corresponding mfn is not in the m2p?> + /* The pagetables are reserved in mmu.c */ > +} > void xen_setup_shared_info(void) > { > if (!xen_feature(XENFEAT_auto_translated_physmap)) { > @@ -1362,6 +1399,7 @@ asmlinkage void __init xen_start_kernel(void) > xen_raw_console_write("mapping kernel into physical memory\n"); > pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); > > + xen_reserve_internals(); > /* Allocate and initialize top and mid mfn levels for p2m structure */ > xen_build_mfn_list_list(); > > diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c > index e4adbfb..6a2bfa4 100644 > --- a/arch/x86/xen/p2m.c > +++ b/arch/x86/xen/p2m.c > @@ -388,6 +388,11 @@ void __init xen_build_dynamic_phys_to_machine(void) > } > > m2p_override_init(); > + > + /* NOTE: We cannot call memblock_reserve here for the mfn_list as there > + * isn''t enough pieces to make it work (for one - we are still using the > + * Xen provided pagetable). Do it later in xen_reserve_internals. > + */ > } > > unsigned long get_phys_to_machine(unsigned long pfn) > diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c > index a4790bf..9efca75 100644 > --- a/arch/x86/xen/setup.c > +++ b/arch/x86/xen/setup.c > @@ -424,15 +424,6 @@ char * __init xen_memory_setup(void) > e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, > E820_RESERVED); > > - /* > - * Reserve Xen bits: > - * - mfn_list > - * - xen_start_info > - * See comment above "struct start_info" in <xen/interface/xen.h> > - */ > - memblock_reserve(__pa(xen_start_info->mfn_list), > - xen_start_info->pt_base - xen_start_info->mfn_list); > - > sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); > > return "Xen"; > -- > 1.7.7.6 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ >
Konrad Rzeszutek Wilk
2012-Jul-27 17:45 UTC
Re: [Xen-devel] [PATCH 2/4] xen/x86: Use memblock_reserve for sensitive areas.
On Fri, Jul 27, 2012 at 11:49:02AM +0100, Stefano Stabellini wrote:> On Thu, 26 Jul 2012, Konrad Rzeszutek Wilk wrote: > > instead of a big memblock_reserve. This way we can be more > > selective in freeing regions (and it also makes it easier > > to understand where is what). > > > > [v1: Move the auto_translate_physmap to proper line] > > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> > > --- > > arch/x86/xen/enlighten.c | 38 ++++++++++++++++++++++++++++++++++++++ > > arch/x86/xen/p2m.c | 5 +++++ > > arch/x86/xen/setup.c | 9 --------- > > 3 files changed, 43 insertions(+), 9 deletions(-) > > > > diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c > > index ff962d4..9b1afa4 100644 > > --- a/arch/x86/xen/enlighten.c > > +++ b/arch/x86/xen/enlighten.c > > @@ -998,7 +998,44 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) > > > > return ret; > > } > > +static void __init xen_reserve_mfn(unsigned long mfn) > > +{ > > + unsigned long pfn; > > + > > + if (!mfn) > > + return; > > + pfn = mfn_to_pfn(mfn); > > + if (phys_to_machine_mapping_valid(pfn)) > > + memblock_reserve(PFN_PHYS(pfn), PAGE_SIZE); > > +} > > If the mfn is not in the m2p xen_reserve_mfn won''t do anything. It is > worth writing it down in a comment.Meaning in a printk?> > > > +static void __init xen_reserve_internals(void) > > +{ > > + unsigned long size; > > + > > + if (!xen_pv_domain()) > > + return; > > + > > + memblock_reserve(__pa(xen_start_info), PAGE_SIZE); > > xen_start_info is not in the m2p, so you cannot use xen_reserve_mfnIt seems to work for me. For both the toolstack created guests and dom0. Let me double check thought.> > > > + xen_reserve_mfn(PFN_DOWN(xen_start_info->shared_info)); > > + xen_reserve_mfn(xen_start_info->store_mfn); > > Are we sure that shared_info points to an mfn that is in the m2p (rather > than a special mfn not present in the list)? > > > > + if (!xen_initial_domain()) > > + xen_reserve_mfn(xen_start_info->console.domU.mfn); > > + > > + if (xen_feature(XENFEAT_auto_translated_physmap)) > > + return; > > + > > + /* > > + * ALIGN up to compensate for the p2m_page pointing to an array that > > + * can partially filled (look in xen_build_dynamic_phys_to_machine). > > + */ > > + > > + size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long)); > > + memblock_reserve(__pa(xen_start_info->mfn_list), size); > > I take that here you are using memblock_reserve again, rather than > xen_reserve_mfn, because the corresponding mfn is not in the m2p?<nods> Well, they are - but they are 55555555..> > > > + /* The pagetables are reserved in mmu.c */ > > +} > > void xen_setup_shared_info(void) > > { > > if (!xen_feature(XENFEAT_auto_translated_physmap)) { > > @@ -1362,6 +1399,7 @@ asmlinkage void __init xen_start_kernel(void) > > xen_raw_console_write("mapping kernel into physical memory\n"); > > pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); > > > > + xen_reserve_internals(); > > /* Allocate and initialize top and mid mfn levels for p2m structure */ > > xen_build_mfn_list_list(); > > > > diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c > > index e4adbfb..6a2bfa4 100644 > > --- a/arch/x86/xen/p2m.c > > +++ b/arch/x86/xen/p2m.c > > @@ -388,6 +388,11 @@ void __init xen_build_dynamic_phys_to_machine(void) > > } > > > > m2p_override_init(); > > + > > + /* NOTE: We cannot call memblock_reserve here for the mfn_list as there > > + * isn''t enough pieces to make it work (for one - we are still using the > > + * Xen provided pagetable). Do it later in xen_reserve_internals. > > + */ > > } > > > > unsigned long get_phys_to_machine(unsigned long pfn) > > diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c > > index a4790bf..9efca75 100644 > > --- a/arch/x86/xen/setup.c > > +++ b/arch/x86/xen/setup.c > > @@ -424,15 +424,6 @@ char * __init xen_memory_setup(void) > > e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, > > E820_RESERVED); > > > > - /* > > - * Reserve Xen bits: > > - * - mfn_list > > - * - xen_start_info > > - * See comment above "struct start_info" in <xen/interface/xen.h> > > - */ > > - memblock_reserve(__pa(xen_start_info->mfn_list), > > - xen_start_info->pt_base - xen_start_info->mfn_list); > > - > > sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); > > > > return "Xen"; > > -- > > 1.7.7.6 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > Please read the FAQ at http://www.tux.org/lkml/ > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel
Stefano Stabellini
2012-Jul-30 14:43 UTC
Re: [Xen-devel] [PATCH 2/4] xen/x86: Use memblock_reserve for sensitive areas.
On Fri, 27 Jul 2012, Konrad Rzeszutek Wilk wrote:> On Fri, Jul 27, 2012 at 11:49:02AM +0100, Stefano Stabellini wrote: > > On Thu, 26 Jul 2012, Konrad Rzeszutek Wilk wrote: > > > instead of a big memblock_reserve. This way we can be more > > > selective in freeing regions (and it also makes it easier > > > to understand where is what). > > > > > > [v1: Move the auto_translate_physmap to proper line] > > > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> > > > --- > > > arch/x86/xen/enlighten.c | 38 ++++++++++++++++++++++++++++++++++++++ > > > arch/x86/xen/p2m.c | 5 +++++ > > > arch/x86/xen/setup.c | 9 --------- > > > 3 files changed, 43 insertions(+), 9 deletions(-) > > > > > > diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c > > > index ff962d4..9b1afa4 100644 > > > --- a/arch/x86/xen/enlighten.c > > > +++ b/arch/x86/xen/enlighten.c > > > @@ -998,7 +998,44 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) > > > > > > return ret; > > > } > > > +static void __init xen_reserve_mfn(unsigned long mfn) > > > +{ > > > + unsigned long pfn; > > > + > > > + if (!mfn) > > > + return; > > > + pfn = mfn_to_pfn(mfn); > > > + if (phys_to_machine_mapping_valid(pfn)) > > > + memblock_reserve(PFN_PHYS(pfn), PAGE_SIZE); > > > +} > > > > If the mfn is not in the m2p xen_reserve_mfn won''t do anything. It is > > worth writing it down in a comment. > > Meaning in a printk?I meant a comment in the code.> > > +static void __init xen_reserve_internals(void) > > > +{ > > > + unsigned long size; > > > + > > > + if (!xen_pv_domain()) > > > + return; > > > + > > > + memblock_reserve(__pa(xen_start_info), PAGE_SIZE); > > > > xen_start_info is not in the m2p, so you cannot use xen_reserve_mfn > > It seems to work for me. For both the toolstack created guests > and dom0. Let me double check thought.I was just thinking out loud: you are calling memblock_reserve rather than xen_reserve_mfn, because xen_reserve_mfn wouldn''t work in this case as xen_start_info is not in the m2p.