Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

riscv: Fix missing PAGE_PFN_MASK

There are a bunch of functions that use the PFN from a page table entry
that end up with the svpbmt upper-bits because they are missing the newly
introduced PAGE_PFN_MASK which leads to wrong addresses conversions and
then crash: fix this by adding this mask.

Fixes: 100631b48ded ("riscv: Fix accessing pfn bits in PTEs for non-32bit variants")
Signed-off-by: Alexandre Ghiti <alexandre.ghiti@canonical.com>
Signed-off-by: Anup Patel <anup@brainfault.org>

authored by

Alexandre Ghiti and committed by
Anup Patel
88573389 32346491

+10 -10
+6 -6
arch/riscv/include/asm/pgtable-64.h
··· 175 175 176 176 static inline unsigned long _pud_pfn(pud_t pud) 177 177 { 178 - return pud_val(pud) >> _PAGE_PFN_SHIFT; 178 + return __page_val_to_pfn(pud_val(pud)); 179 179 } 180 180 181 181 static inline pmd_t *pud_pgtable(pud_t pud) ··· 278 278 279 279 static inline unsigned long _p4d_pfn(p4d_t p4d) 280 280 { 281 - return p4d_val(p4d) >> _PAGE_PFN_SHIFT; 281 + return __page_val_to_pfn(p4d_val(p4d)); 282 282 } 283 283 284 284 static inline pud_t *p4d_pgtable(p4d_t p4d) 285 285 { 286 286 if (pgtable_l4_enabled) 287 - return (pud_t *)pfn_to_virt(p4d_val(p4d) >> _PAGE_PFN_SHIFT); 287 + return (pud_t *)pfn_to_virt(__page_val_to_pfn(p4d_val(p4d))); 288 288 289 289 return (pud_t *)pud_pgtable((pud_t) { p4d_val(p4d) }); 290 290 } ··· 292 292 293 293 static inline struct page *p4d_page(p4d_t p4d) 294 294 { 295 - return pfn_to_page(p4d_val(p4d) >> _PAGE_PFN_SHIFT); 295 + return pfn_to_page(__page_val_to_pfn(p4d_val(p4d))); 296 296 } 297 297 298 298 #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) ··· 347 347 static inline p4d_t *pgd_pgtable(pgd_t pgd) 348 348 { 349 349 if (pgtable_l5_enabled) 350 - return (p4d_t *)pfn_to_virt(pgd_val(pgd) >> _PAGE_PFN_SHIFT); 350 + return (p4d_t *)pfn_to_virt(__page_val_to_pfn(pgd_val(pgd))); 351 351 352 352 return (p4d_t *)p4d_pgtable((p4d_t) { pgd_val(pgd) }); 353 353 } ··· 355 355 356 356 static inline struct page *pgd_page(pgd_t pgd) 357 357 { 358 - return pfn_to_page(pgd_val(pgd) >> _PAGE_PFN_SHIFT); 358 + return pfn_to_page(__page_val_to_pfn(pgd_val(pgd))); 359 359 } 360 360 #define pgd_page(pgd) pgd_page(pgd) 361 361
+3 -3
arch/riscv/include/asm/pgtable.h
··· 261 261 262 262 static inline unsigned long _pgd_pfn(pgd_t pgd) 263 263 { 264 - return pgd_val(pgd) >> _PAGE_PFN_SHIFT; 264 + return __page_val_to_pfn(pgd_val(pgd)); 265 265 } 266 266 267 267 static inline struct page *pmd_page(pmd_t pmd) ··· 590 590 return __pmd(pmd_val(pmd) & ~(_PAGE_PRESENT|_PAGE_PROT_NONE)); 591 591 } 592 592 593 - #define __pmd_to_phys(pmd) (pmd_val(pmd) >> _PAGE_PFN_SHIFT << PAGE_SHIFT) 593 + #define __pmd_to_phys(pmd) (__page_val_to_pfn(pmd_val(pmd)) << PAGE_SHIFT) 594 594 595 595 static inline unsigned long pmd_pfn(pmd_t pmd) 596 596 { 597 597 return ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT); 598 598 } 599 599 600 - #define __pud_to_phys(pud) (pud_val(pud) >> _PAGE_PFN_SHIFT << PAGE_SHIFT) 600 + #define __pud_to_phys(pud) (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT) 601 601 602 602 static inline unsigned long pud_pfn(pud_t pud) 603 603 {
+1 -1
arch/riscv/kvm/mmu.c
··· 54 54 55 55 static inline unsigned long gstage_pte_page_vaddr(pte_t pte) 56 56 { 57 - return (unsigned long)pfn_to_virt(pte_val(pte) >> _PAGE_PFN_SHIFT); 57 + return (unsigned long)pfn_to_virt(__page_val_to_pfn(pte_val(pte))); 58 58 } 59 59 60 60 static int gstage_page_size_to_level(unsigned long page_size, u32 *out_level)