|
45 | 45 | #include <asm/memblock.h>
|
46 | 46 | #include <asm/mmu_context.h>
|
47 | 47 | #include <asm/ptdump.h>
|
| 48 | +#include <asm/tlbflush.h> |
48 | 49 |
|
49 | 50 | #define NO_BLOCK_MAPPINGS BIT(0)
|
50 | 51 | #define NO_CONT_MAPPINGS BIT(1)
|
@@ -977,12 +978,51 @@ int pmd_clear_huge(pmd_t *pmdp)
|
977 | 978 | return 1;
|
978 | 979 | }
|
979 | 980 |
|
980 |
| -int pud_free_pmd_page(pud_t *pud, unsigned long addr) |
| 981 | +int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr) |
981 | 982 | {
|
982 |
| - return pud_none(*pud); |
| 983 | + pte_t *table; |
| 984 | + pmd_t pmd; |
| 985 | + |
| 986 | + pmd = READ_ONCE(*pmdp); |
| 987 | + |
| 988 | + /* No-op for empty entry and WARN_ON for valid entry */ |
| 989 | + if (!pmd_present(pmd) || !pmd_table(pmd)) { |
| 990 | + VM_WARN_ON(!pmd_table(pmd)); |
| 991 | + return 1; |
| 992 | + } |
| 993 | + |
| 994 | + table = pte_offset_kernel(pmdp, addr); |
| 995 | + pmd_clear(pmdp); |
| 996 | + __flush_tlb_kernel_pgtable(addr); |
| 997 | + pte_free_kernel(NULL, table); |
| 998 | + return 1; |
983 | 999 | }
|
984 | 1000 |
|
985 |
| -int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) |
| 1001 | +int pud_free_pmd_page(pud_t *pudp, unsigned long addr) |
986 | 1002 | {
|
987 |
| - return pmd_none(*pmd); |
| 1003 | + pmd_t *table; |
| 1004 | + pmd_t *pmdp; |
| 1005 | + pud_t pud; |
| 1006 | + unsigned long next, end; |
| 1007 | + |
| 1008 | + pud = READ_ONCE(*pudp); |
| 1009 | + |
| 1010 | + /* No-op for empty entry and WARN_ON for valid entry */ |
| 1011 | + if (!pud_present(pud) || !pud_table(pud)) { |
| 1012 | + VM_WARN_ON(!pud_table(pud)); |
| 1013 | + return 1; |
| 1014 | + } |
| 1015 | + |
| 1016 | + table = pmd_offset(pudp, addr); |
| 1017 | + pmdp = table; |
| 1018 | + next = addr; |
| 1019 | + end = addr + PUD_SIZE; |
| 1020 | + do { |
| 1021 | + pmd_free_pte_page(pmdp, next); |
| 1022 | + } while (pmdp++, next += PMD_SIZE, next != end); |
| 1023 | + |
| 1024 | + pud_clear(pudp); |
| 1025 | + __flush_tlb_kernel_pgtable(addr); |
| 1026 | + pmd_free(NULL, table); |
| 1027 | + return 1; |
988 | 1028 | }
|
0 commit comments