Re: [PATCH RFC v3 2/4] mm/pgtable: Make pfn_pte() filter out huge page attributes

Yin Tirui
2026-03-10T03:32:38Z

On 3/5/2026 6:05 PM, Jürgen Groß wrote:
>> Hi Willy and Jürgen,
>>
>> Following up on the x86 _PAGE_PSE and _PAGE_PAT aliasing issue.
>>
>> To achieve the goal of keeping pfn_pte() pure and completely
>> eradicating the pte_clrhuge() anti-pattern, we need a way to ensure
>> pfn_pte() never receives a pgprot with the huge bit set.
>>
>> @Jürgen:
>> Just to be absolutely certain: is there any safe way to filter out the
>> huge page attributes directly inside x86's pfn_pte() without breaking
>> PAT? Or does the hardware bit-aliasing make this strictly impossible
>> at the pfn_pte() level?
>
> There is no huge bit at the PTE level. It is existing only at the PMD
> and the
> PUD level.
>
> So: yes, it is absolutely impossible to filter it out, as the bit has a
> different meaning in "real" PTEs (with "PTE" having the meaning: a
> translation
> entry in a page referenced by a PMD entry not having the PSE bit set).
>
Hi Jürgen,

Thank you for your confirmation.

>>
>> @Willy @Jürgen:
>> Assuming it is impossible to filter this safely inside pfn_pte() on
>> x86, we must translate the pgprot before passing it down. To maintain
>> strict type-safety and still drop pte_clrhuge(), I plan to introduce
>> two arch-neutral wrappers:
>>
>> x86:
>> /* Translates large prot to 4K. Shifts PAT back to bit 7, inherently
>> clearing _PAGE_PSE */
>> #define pgprot_huge_to_pte(prot)    pgprot_large_2_4k(prot)
>> /* Translates 4K prot to large. Shifts PAT to bit 12, strictly sets
>> _PAGE_PSE */
>> #define pgprot_pte_to_huge(prot)
>> __pgprot(pgprot_val(pgprot_4k_2_large(prot)) | _PAGE_PSE)
>
> Seems to be okay.
While the wrapper approach handles the aliasing, Willy recently
suggested taking it a step further by embedding this translation
directly into `pfn_pmd()` and `pmd_pgprot()`.

I am going to explore this embedded approach for the v4 respin.

--
Yin Tirui