Messages in this thread Patch in this message | | | From | Naoki Hayama <> | Subject | [PATCH] riscv: Fix superpage handling in kernel_page_present() | Date | Tue, 26 Oct 2021 20:59:47 +0900 |
| |
Add checks by p*d_leaf() functions. Though we don't have to use pgd_leaf() and p4d_leaf() as of now, I include them in this patch for the future compatibility.
I tested this patch on HiFive Unmatched.
Signed-off-by: Naoki Hayama <naoki.hayama@lineo.co.jp> --- arch/riscv/mm/pageattr.c | 44 +++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c index 5e49e4b4a4cc..125eea4d13c7 100644 --- a/arch/riscv/mm/pageattr.c +++ b/arch/riscv/mm/pageattr.c @@ -208,28 +208,40 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) bool kernel_page_present(struct page *page) { unsigned long addr = (unsigned long)page_address(page); - pgd_t *pgd; - pud_t *pud; - p4d_t *p4d; - pmd_t *pmd; - pte_t *pte; - - pgd = pgd_offset_k(addr); - if (!pgd_present(*pgd)) + pgd_t *pgdp, pgd; + p4d_t *p4dp, p4d; + pud_t *pudp, pud; + pmd_t *pmdp, pmd; + pte_t *ptep; + + pgdp = pgd_offset_k(addr); + pgd = READ_ONCE(*pgdp); + if (!pgd_present(pgd)) return false; + if (pgd_leaf(pgd)) + return true; - p4d = p4d_offset(pgd, addr); - if (!p4d_present(*p4d)) + p4dp = p4d_offset(pgdp, addr); + p4d = READ_ONCE(*p4dp); + if (!p4d_present(p4d)) return false; + if (p4d_leaf(p4d)) + return true; - pud = pud_offset(p4d, addr); - if (!pud_present(*pud)) + pudp = pud_offset(p4dp, addr); + pud = READ_ONCE(*pudp); + if (!pud_present(pud)) return false; + if (pud_leaf(pud)) + return true; - pmd = pmd_offset(pud, addr); - if (!pmd_present(*pmd)) + pmdp = pmd_offset(pudp, addr); + pmd = READ_ONCE(*pmdp); + if (!pmd_present(pmd)) return false; + if (pmd_leaf(pmd)) + return true; - pte = pte_offset_kernel(pmd, addr); - return pte_present(*pte); + ptep = pte_offset_kernel(pmdp, addr); + return pte_present(READ_ONCE(*ptep)); } -- 2.17.1
| |