I have a question regarding page attributes on i386/x86_64 platforms:
Supopse a function requests a page with __get_free_pages(), and the page
that's returned is actually part of a large (2MB) page that has a single
pte (or pmd, I guess) to control it.
Suppose this function then calls change_page_attr() to, say, modify the
caching policy for that page. Since the page is part of a large 2MB
page (PAGE_PSE is set), change_page_attr() calls split_large_page() to
create 512 new PTEs, since the caching policy is only being changed on
the single 4K page, and not for the entire 2MB large page.
When split_large_page() creates the 512 new PTEs, it assigns the
requested attributes to the page in question, but it sets all of the
other 511 PTEs the PAGE_KERNEL attributes. It never checks what
attributes were set for the large page--it just assumes that the other
511 pages should have PAGE_KERNEL attributes.
My question is this: when split_large_page() is called, should it make
the other 511 PTEs inherit the page attributes from the large page (with
the exception of PAGE_PSE, obviously)?
There appears to be a bug (at least in certain 2.6 kernel versions)
where __get_free_pages() returns a page that's in a large page that is
executable (it doesn't have the PAGE_NX bit set)... but, after
change_page_attr() is called, the other 511 pages, which contain kernel
code, are no longer executable (because they were set to PAGE_KERNEL,
which has PAGE_NX set).
I've copied the split_large_page() code below for reference.
Thanks,
Stuart
static struct page *split_large_page(unsigned long address, pgprot_t
prot)
{
int i;
unsigned long addr;
struct page *base;
pte_t *pbase;
spin_unlock_irq(&cpa_lock);
base = alloc_pages(GFP_KERNEL, 0);
spin_lock_irq(&cpa_lock);
if (!base)
return NULL;
address = __pa(address);
addr = address & LARGE_PAGE_MASK;
pbase = (pte_t *)page_address(base);
for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
pbase[i] = pfn_pte(addr >> PAGE_SHIFT,
addr == address ? prot :
PAGE_KERNEL);
}
return base;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]