Skip to content

Commit 0b1ef4f

Browse files
xzpeterakpm00
authored andcommitted
mm/debug_vm_pgtable: drop RANDOM_ORVALUE trick
Macro RANDOM_ORVALUE was used to make sure the pgtable entry will be populated with !none data in clear tests. The RANDOM_ORVALUE tried to cover mostly all the bits in a pgtable entry, even if there's no discussion on whether all the bits will be vaild. Both S390 and PPC64 have their own masks to avoid touching some bits. Now it's the turn for x86_64. The issue is there's a recent report from Mikhail Gavrilov showing that this can cause a warning with the newly added pte set check in commit 8430557 on writable v.s. userfaultfd-wp bit, even though the check itself was valid, the random pte is not. We can choose to mask more bits out. However the need to have such random bits setup is questionable, as now it's already guaranteed to be true on below: - For pte level, the pgtable entry will be installed with value from pfn_pte(), where pfn points to a valid page. Hence the pte will be !none already if populated with pfn_pte(). - For upper-than-pte level, the pgtable entry should contain a directory entry always, which is also !none. All the cases look like good enough to test a pxx_clear() helper. Instead of extending the bitmask, drop the "set random bits" trick completely. Add some warning guards to make sure the entries will be !none before clear(). Link: https://lkml.kernel.org/r/[email protected] Fixes: 8430557 ("mm/page_table_check: support userfault wr-protect entries") Signed-off-by: Peter Xu <[email protected]> Reported-by: Mikhail Gavrilov <[email protected]> Link: https://lore.kernel.org/r/CABXGCsMB9A8-X+Np_Q+fWLURYL_0t3Y-MdoNabDM-Lzk58-DGA@mail.gmail.com Tested-by: Mikhail Gavrilov <[email protected]> Reviewed-by: Pasha Tatashin <[email protected]> Acked-by: David Hildenbrand <[email protected]> Cc: Aneesh Kumar K.V <[email protected]> Cc: Gavin Shan <[email protected]> Cc: Anshuman Khandual <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent cfdd12b commit 0b1ef4f

File tree

1 file changed

+5
-26
lines changed

1 file changed

+5
-26
lines changed

mm/debug_vm_pgtable.c

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,7 @@
4040
* Please refer Documentation/mm/arch_pgtable_helpers.rst for the semantics
4141
* expectations that are being validated here. All future changes in here
4242
* or the documentation need to be in sync.
43-
*
44-
* On s390 platform, the lower 4 bits are used to identify given page table
45-
* entry type. But these bits might affect the ability to clear entries with
46-
* pxx_clear() because of how dynamic page table folding works on s390. So
47-
* while loading up the entries do not change the lower 4 bits. It does not
48-
* have affect any other platform. Also avoid the 62nd bit on ppc64 that is
49-
* used to mark a pte entry.
5043
*/
51-
#define S390_SKIP_MASK GENMASK(3, 0)
52-
#if __BITS_PER_LONG == 64
53-
#define PPC64_SKIP_MASK GENMASK(62, 62)
54-
#else
55-
#define PPC64_SKIP_MASK 0x0
56-
#endif
57-
#define ARCH_SKIP_MASK (S390_SKIP_MASK | PPC64_SKIP_MASK)
58-
#define RANDOM_ORVALUE (GENMASK(BITS_PER_LONG - 1, 0) & ~ARCH_SKIP_MASK)
5944
#define RANDOM_NZVALUE GENMASK(7, 0)
6045

6146
struct pgtable_debug_args {
@@ -511,8 +496,7 @@ static void __init pud_clear_tests(struct pgtable_debug_args *args)
511496
return;
512497

513498
pr_debug("Validating PUD clear\n");
514-
pud = __pud(pud_val(pud) | RANDOM_ORVALUE);
515-
WRITE_ONCE(*args->pudp, pud);
499+
WARN_ON(pud_none(pud));
516500
pud_clear(args->pudp);
517501
pud = READ_ONCE(*args->pudp);
518502
WARN_ON(!pud_none(pud));
@@ -548,8 +532,7 @@ static void __init p4d_clear_tests(struct pgtable_debug_args *args)
548532
return;
549533

550534
pr_debug("Validating P4D clear\n");
551-
p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE);
552-
WRITE_ONCE(*args->p4dp, p4d);
535+
WARN_ON(p4d_none(p4d));
553536
p4d_clear(args->p4dp);
554537
p4d = READ_ONCE(*args->p4dp);
555538
WARN_ON(!p4d_none(p4d));
@@ -582,8 +565,7 @@ static void __init pgd_clear_tests(struct pgtable_debug_args *args)
582565
return;
583566

584567
pr_debug("Validating PGD clear\n");
585-
pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE);
586-
WRITE_ONCE(*args->pgdp, pgd);
568+
WARN_ON(pgd_none(pgd));
587569
pgd_clear(args->pgdp);
588570
pgd = READ_ONCE(*args->pgdp);
589571
WARN_ON(!pgd_none(pgd));
@@ -634,10 +616,8 @@ static void __init pte_clear_tests(struct pgtable_debug_args *args)
634616
if (WARN_ON(!args->ptep))
635617
return;
636618

637-
#ifndef CONFIG_RISCV
638-
pte = __pte(pte_val(pte) | RANDOM_ORVALUE);
639-
#endif
640619
set_pte_at(args->mm, args->vaddr, args->ptep, pte);
620+
WARN_ON(pte_none(pte));
641621
flush_dcache_page(page);
642622
barrier();
643623
ptep_clear(args->mm, args->vaddr, args->ptep);
@@ -650,8 +630,7 @@ static void __init pmd_clear_tests(struct pgtable_debug_args *args)
650630
pmd_t pmd = READ_ONCE(*args->pmdp);
651631

652632
pr_debug("Validating PMD clear\n");
653-
pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE);
654-
WRITE_ONCE(*args->pmdp, pmd);
633+
WARN_ON(pmd_none(pmd));
655634
pmd_clear(args->pmdp);
656635
pmd = READ_ONCE(*args->pmdp);
657636
WARN_ON(!pmd_none(pmd));

0 commit comments

Comments
 (0)