lkml.org 
[lkml]   [2007]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 10/28]xen: ignore RW mapping of RO pages in pagetable_init
    When setting up the initial pagetable, which includes mappings of all
    low physical memory, ignore a mapping which tries to set the RW bit on
    an RO pte. An RO pte indicates a page which is part of the current
    pagetable, and so it cannot be allowed to become RW.

    Once xen_pagetable_setup_done is called, set_pte reverts to its normal
    behaviour.

    Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
    Acked-by: Chris Wright <chrisw@sous-sol.org>
    Cc: ebiederm@xmission.com (Eric W. Biederman)

    ---
    arch/i386/xen/enlighten.c | 27 +++++++++++++++++++++++++--
    1 file changed, 25 insertions(+), 2 deletions(-)

    ===================================================================
    --- a/arch/i386/xen/enlighten.c
    +++ b/arch/i386/xen/enlighten.c
    @@ -635,7 +635,7 @@ static void xen_write_cr3(unsigned long

    /* Early in boot, while setting up the initial pagetable, assume
    everything is pinned. */
    -static void xen_alloc_pt_init(struct mm_struct *mm, u32 pfn)
    +static __init void xen_alloc_pt_init(struct mm_struct *mm, u32 pfn)
    {
    BUG_ON(mem_map); /* should only be used early */
    make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
    @@ -687,9 +687,31 @@ static void *xen_kmap_atomic_pte(struct
    }
    #endif

    +static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
    +{
    + /* If there's an existing pte, then don't allow _PAGE_RW to be set */
    + if (pte_val_ma(*ptep) & _PAGE_PRESENT)
    + pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
    + pte_val_ma(pte));
    +
    + return pte;
    +}
    +
    +/* Init-time set_pte while constructing initial pagetables, which
    + doesn't allow RO pagetable pages to be remapped RW */
    +static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
    +{
    + pte = mask_rw_pte(ptep, pte);
    +
    + xen_set_pte(ptep, pte);
    +}
    +
    static __init void xen_pagetable_setup_start(pgd_t *base)
    {
    pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
    +
    + /* special set_pte for pagetable initialization */
    + paravirt_ops.set_pte = xen_set_pte_init;

    init_mm.pgd = base;
    /*
    @@ -737,6 +759,7 @@ static __init void xen_pagetable_setup_d
    /* This will work as long as patching hasn't happened yet
    (which it hasn't) */
    paravirt_ops.alloc_pt = xen_alloc_pt;
    + paravirt_ops.set_pte = xen_set_pte;

    if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    /*
    @@ -919,7 +942,7 @@ static const struct paravirt_ops xen_par
    .dup_mmap = xen_dup_mmap,
    .exit_mmap = xen_exit_mmap,

    - .set_pte = xen_set_pte,
    + .set_pte = NULL, /* see xen_pagetable_setup_* */
    .set_pte_at = xen_set_pte_at,
    .set_pmd = xen_set_pmd,

    --

    -
    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/

    \
     
     \ /
      Last update: 2007-05-11 21:15    [W:0.020 / U:29.444 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site