RE: page allocation/attributes question (i386/x86_64 specific)

From: Stuart_Hayes
Date: Fri Jun 24 2005 - 13:32:09 EST


Rik Van Riel wrote:
> On Wed, 22 Jun 2005 Stuart_Hayes@xxxxxxxx wrote:
>
>> 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)?
>
> I suspect it should.

(Copying Andi Kleen & Andrea Arcangeli since they were involved in a
previous discussion of this. I'm trying to fix the NX handling when
change_page_attr() is called in i386.)

After looking into it further, I agree completely. I found a thread in
which this was discussed
(http://marc.theaimsgroup.com/?l=linux-kernel&m=109964359124731&w=2),
and discovered that this has been addressed in the X86_64 kernel.

I modified pageattr.c so that small pages would inherit the _PAGE_NX
setting from the large page when split_large_page() is called, and it
works... but un-doing the change_page_attr() is still a problem:

I wrote a test module that calls __get_free_pages() to get a single
page. The page I got was part of a large page, which was executable.

I then did change_page_attr(page,PAGE_KERNEL_NOCACHE)--with my patch to
pageattr.c, this worked fine. The large page was split, and the other
511 new PTEs were still executable, though my page was no longer
executable (since PAGE_KERNEL_NOCACHE has _PAGE_NX set).

However, when I used "change_page_attr()" to change the page to
PAGE_KERNEL, it did just that. But PAGE_KERNEL has the _PAGE_NX bit set
and isn't executable. And, since PAGE_KERNEL (with _PAGE_NX set) didn't
match the original pages attributes, the 512 PTEs weren't reverted back
into a large page. (Also, __change_page_attr() did *another* get_page()
on the page containing these 512 PTEs, so now the page_count has gone up
to 3, instead of going back down to 1 (or staying at 2).)

Is the function that calls "change_page_attr()" expected to look at the
attributes of the page before calling change_page_attr(), so it knows
how to un-change the attributes when it is finished with the page (since
PAGE_KERNEL isn't always what the page was originally)?

Or should "change_page_attr()" ignore the NX bit in the "pgprot_t prot"
parameter that's passed to it, and just inherit NX from the
large/existing page? Then change_page_attr(page,PAGE_KERNEL) could be
used to undo changes, but change_page_attr() couldn't be used to modify
the NX bit.

Thanks
Stuart
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/