Re: BUG in x86_64 hugepage support

Nishanth Aravamudan
2006-03-15T07:31:33Z

On 14.03.2006 [23:08:57 -0800], Chen, Kenneth W wrote:
> Nishanth Aravamudan wrote on Tuesday, March 14, 2006 8:36 PM
> > > I think _PAGE_PSE bit should be in _PAGE_CHG_MASK.
> >
> > I can try a kernel with just the _PAGE_PSE bit added to _PAGE_CHG_MASK
> > and see if that helps. I think it will still BUG() in my case, however,
> > as __LARGE_PTE is 10000001, so only setting the 8th bit will be
> > insufficient. So maybe there is also something wrong with what is being
> > generated by pgprot_val(newprot)? I will try adding some more debugging
> > output to see what is happening in pte_modify.
>
> Forget about preserving _PAGE_PSE BIT, It won't work. I just realized that
> _PAGE_PROTNONE clashes with _PAGE_PSE (both use bit 7). Still thinking ...

And here I was rather proud of the following patch :)

I figured, if we know that we're dealing with a hugepage pte, then we
probably can set _PAGE_PSE in newprot, no? This fixes the BUGs here, but
may have side affects I'm unaware of (and I was unable to test on an
i386 kernel, since all of a sudden -mm decided to stop building with
Ubuntu's biarch gcc -- another topic altogether).

Here's the patch I used.

Description: We currently fail mprotect testing in libhugetlbfs because
the PSE bit in the hugepage PTEs gets unset. In the case where we know
that a filled hugetlb PTE is going to have its protection changed, make
sure it stays a hugetlb PTE by setting the PSE bit in the new protection
flags.

Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>

diff -urpN 2.6.16-rc6-mm1/mm/hugetlb.c 2.6.16-rc6-mm1-dev/mm/hugetlb.c
--- 2.6.16-rc6-mm1/mm/hugetlb.c 2006-03-14 22:49:44.000000000 -0800
+++ 2.6.16-rc6-mm1-dev/mm/hugetlb.c 2006-03-14 22:51:31.000000000 -0800
@@ -740,6 +740,7 @@ void hugetlb_change_protection(struct vm
continue;
if (!pte_none(*ptep)) {
pte = huge_ptep_get_and_clear(mm, address, ptep);
+ pgprot_val(newprot) |= _PAGE_PSE;
pte = pte_modify(pte, newprot);
set_huge_pte_at(mm, address, ptep, pte);
lazy_mmu_prot_update(pte);