lkml.org 
[lkml]   [2008]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] [33/36] CPA: Make kernel_text test match boot mapping initialization
    Date

    The boot direct mapping initialization used a different test to check if a
    page was part of the kernel mapping than c_p_a(). Make them use
    a common function.

    Also round up to a large page size to be sure and check for the beginning
    of the kernel address to handle highly loaded kernels better.

    This gives a small semantic change of NX applying to always 2MB areas
    on !PSE && NX systems, but that's an obscure case even considering
    DEBUG_PAGEALLOC.

    Signed-off-by: Andi Kleen <ak@suse.de>
    Acked-by: Jan Beulich <jbeulich@novell.com>

    ---
    arch/x86/mm/init_32.c | 16 ++--------------
    arch/x86/mm/pageattr_32.c | 9 ++++++++-
    include/asm-x86/pgtable_32.h | 2 +-
    3 files changed, 11 insertions(+), 16 deletions(-)

    Index: linux/arch/x86/mm/pageattr_32.c
    ===================================================================
    --- linux.orig/arch/x86/mm/pageattr_32.c
    +++ linux/arch/x86/mm/pageattr_32.c
    @@ -184,6 +184,13 @@ static int cache_attr_changed(pte_t pte,
    return a != (pgprot_val(prot) & _PAGE_CACHE);
    }

    +int text_address(unsigned long addr)
    +{
    + unsigned long start = ((unsigned long)&_text) & LARGE_PAGE_MASK;
    + unsigned long end = ((unsigned long)&__init_end) & LARGE_PAGE_MASK;
    + return addr >= start && addr < end + LARGE_PAGE_SIZE;
    +}
    +
    /*
    * Mark the address for flushing later in global_tlb_flush().
    *
    @@ -238,7 +245,7 @@ __change_page_attr(struct page *page, pg
    set_tlb_flush(address, cache_attr_changed(*kpte, prot, level),
    level < 3);

    - if ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
    + if (text_address(address))
    ref_prot = PAGE_KERNEL_EXEC;

    ref_prot = canon_pgprot(ref_prot);
    Index: linux/arch/x86/mm/init_32.c
    ===================================================================
    --- linux.orig/arch/x86/mm/init_32.c
    +++ linux/arch/x86/mm/init_32.c
    @@ -136,13 +136,6 @@ static void __init page_table_range_init
    }
    }

    -static inline int is_kernel_text(unsigned long addr)
    -{
    - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
    - return 1;
    - return 0;
    -}
    -
    /*
    * This maps the physical memory to kernel virtual address space, a total
    * of max_low_pfn pages, by creating page tables starting from address
    @@ -176,14 +169,9 @@ static void __init kernel_physical_mappi
    */
    if (cpu_has_pse &&
    is_memory_all_valid(paddr, paddr + PMD_SIZE)) {
    - unsigned int address2;
    pgprot_t prot = PAGE_KERNEL_LARGE;

    - address2 = (pfn + PTRS_PER_PTE) * PAGE_SIZE +
    - PAGE_OFFSET - 1;
    -
    - if (is_kernel_text(address) ||
    - is_kernel_text(address2))
    + if (text_address(address))
    prot = PAGE_KERNEL_LARGE_EXEC;

    set_pmd(pmd, pfn_pmd(pfn, prot));
    @@ -216,7 +204,7 @@ static void __init kernel_physical_mappi
    continue;
    }

    - if (is_kernel_text(address))
    + if (text_address(address))
    prot = PAGE_KERNEL_EXEC;

    set_pte(pte, pfn_pte(pfn, prot));
    Index: linux/include/asm-x86/pgtable_32.h
    ===================================================================
    --- linux.orig/include/asm-x86/pgtable_32.h
    +++ linux/include/asm-x86/pgtable_32.h
    @@ -34,7 +34,7 @@ void check_pgt_cache(void);
    void pmd_ctor(struct kmem_cache *, void *);
    void pgtable_cache_init(void);
    void paging_init(void);
    -
    +int text_address(unsigned long);

    /*
    * The Linux x86 paging architecture is 'compile-time dual-mode', it

    \
     
     \ /
      Last update: 2008-01-16 23:29    [W:0.048 / U:59.468 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site