| .. | .. |
|---|
| 783 | 783 | } |
|---|
| 784 | 784 | |
|---|
| 785 | 785 | static void remove_pte_table(pte_t *pte_start, unsigned long addr, |
|---|
| 786 | | - unsigned long end) |
|---|
| 786 | + unsigned long end, bool direct) |
|---|
| 787 | 787 | { |
|---|
| 788 | | - unsigned long next; |
|---|
| 788 | + unsigned long next, pages = 0; |
|---|
| 789 | 789 | pte_t *pte; |
|---|
| 790 | 790 | |
|---|
| 791 | 791 | pte = pte_start + pte_index(addr); |
|---|
| .. | .. |
|---|
| 807 | 807 | } |
|---|
| 808 | 808 | |
|---|
| 809 | 809 | pte_clear(&init_mm, addr, pte); |
|---|
| 810 | + pages++; |
|---|
| 810 | 811 | } |
|---|
| 812 | + if (direct) |
|---|
| 813 | + update_page_count(mmu_virtual_psize, -pages); |
|---|
| 811 | 814 | } |
|---|
| 812 | 815 | |
|---|
| 813 | 816 | static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr, |
|---|
| 814 | | - unsigned long end) |
|---|
| 817 | + unsigned long end, bool direct) |
|---|
| 815 | 818 | { |
|---|
| 816 | | - unsigned long next; |
|---|
| 819 | + unsigned long next, pages = 0; |
|---|
| 817 | 820 | pte_t *pte_base; |
|---|
| 818 | 821 | pmd_t *pmd; |
|---|
| 819 | 822 | |
|---|
| .. | .. |
|---|
| 831 | 834 | continue; |
|---|
| 832 | 835 | } |
|---|
| 833 | 836 | pte_clear(&init_mm, addr, (pte_t *)pmd); |
|---|
| 837 | + pages++; |
|---|
| 834 | 838 | continue; |
|---|
| 835 | 839 | } |
|---|
| 836 | 840 | |
|---|
| 837 | 841 | pte_base = (pte_t *)pmd_page_vaddr(*pmd); |
|---|
| 838 | | - remove_pte_table(pte_base, addr, next); |
|---|
| 842 | + remove_pte_table(pte_base, addr, next, direct); |
|---|
| 839 | 843 | free_pte_table(pte_base, pmd); |
|---|
| 840 | 844 | } |
|---|
| 845 | + if (direct) |
|---|
| 846 | + update_page_count(MMU_PAGE_2M, -pages); |
|---|
| 841 | 847 | } |
|---|
| 842 | 848 | |
|---|
| 843 | 849 | static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr, |
|---|
| 844 | | - unsigned long end) |
|---|
| 850 | + unsigned long end, bool direct) |
|---|
| 845 | 851 | { |
|---|
| 846 | | - unsigned long next; |
|---|
| 852 | + unsigned long next, pages = 0; |
|---|
| 847 | 853 | pmd_t *pmd_base; |
|---|
| 848 | 854 | pud_t *pud; |
|---|
| 849 | 855 | |
|---|
| .. | .. |
|---|
| 861 | 867 | continue; |
|---|
| 862 | 868 | } |
|---|
| 863 | 869 | pte_clear(&init_mm, addr, (pte_t *)pud); |
|---|
| 870 | + pages++; |
|---|
| 864 | 871 | continue; |
|---|
| 865 | 872 | } |
|---|
| 866 | 873 | |
|---|
| 867 | | - pmd_base = (pmd_t *)pud_page_vaddr(*pud); |
|---|
| 868 | | - remove_pmd_table(pmd_base, addr, next); |
|---|
| 874 | + pmd_base = pud_pgtable(*pud); |
|---|
| 875 | + remove_pmd_table(pmd_base, addr, next, direct); |
|---|
| 869 | 876 | free_pmd_table(pmd_base, pud); |
|---|
| 870 | 877 | } |
|---|
| 878 | + if (direct) |
|---|
| 879 | + update_page_count(MMU_PAGE_1G, -pages); |
|---|
| 871 | 880 | } |
|---|
| 872 | 881 | |
|---|
| 873 | | -static void __meminit remove_pagetable(unsigned long start, unsigned long end) |
|---|
| 882 | +static void __meminit remove_pagetable(unsigned long start, unsigned long end, |
|---|
| 883 | + bool direct) |
|---|
| 874 | 884 | { |
|---|
| 875 | 885 | unsigned long addr, next; |
|---|
| 876 | 886 | pud_t *pud_base; |
|---|
| .. | .. |
|---|
| 898 | 908 | continue; |
|---|
| 899 | 909 | } |
|---|
| 900 | 910 | |
|---|
| 901 | | - pud_base = (pud_t *)p4d_page_vaddr(*p4d); |
|---|
| 902 | | - remove_pud_table(pud_base, addr, next); |
|---|
| 911 | + pud_base = p4d_pgtable(*p4d); |
|---|
| 912 | + remove_pud_table(pud_base, addr, next, direct); |
|---|
| 903 | 913 | free_pud_table(pud_base, p4d); |
|---|
| 904 | 914 | } |
|---|
| 905 | 915 | |
|---|
| .. | .. |
|---|
| 922 | 932 | |
|---|
| 923 | 933 | int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end) |
|---|
| 924 | 934 | { |
|---|
| 925 | | - remove_pagetable(start, end); |
|---|
| 935 | + remove_pagetable(start, end, true); |
|---|
| 926 | 936 | return 0; |
|---|
| 927 | 937 | } |
|---|
| 928 | 938 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
|---|
| .. | .. |
|---|
| 958 | 968 | #ifdef CONFIG_MEMORY_HOTPLUG |
|---|
| 959 | 969 | void __meminit radix__vmemmap_remove_mapping(unsigned long start, unsigned long page_size) |
|---|
| 960 | 970 | { |
|---|
| 961 | | - remove_pagetable(start, start + page_size); |
|---|
| 971 | + remove_pagetable(start, start + page_size, false); |
|---|
| 962 | 972 | } |
|---|
| 963 | 973 | #endif |
|---|
| 964 | 974 | #endif |
|---|
| .. | .. |
|---|
| 1064 | 1074 | pte_t entry, unsigned long address, int psize) |
|---|
| 1065 | 1075 | { |
|---|
| 1066 | 1076 | struct mm_struct *mm = vma->vm_mm; |
|---|
| 1067 | | - unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | |
|---|
| 1068 | | - _PAGE_RW | _PAGE_EXEC); |
|---|
| 1077 | + unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY | |
|---|
| 1078 | + _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); |
|---|
| 1069 | 1079 | |
|---|
| 1070 | 1080 | unsigned long change = pte_val(entry) ^ pte_val(*ptep); |
|---|
| 1071 | 1081 | /* |
|---|
| .. | .. |
|---|
| 1156 | 1166 | pmd_t *pmd; |
|---|
| 1157 | 1167 | int i; |
|---|
| 1158 | 1168 | |
|---|
| 1159 | | - pmd = (pmd_t *)pud_page_vaddr(*pud); |
|---|
| 1169 | + pmd = pud_pgtable(*pud); |
|---|
| 1160 | 1170 | pud_clear(pud); |
|---|
| 1161 | 1171 | |
|---|
| 1162 | 1172 | flush_tlb_kernel_range(addr, addr + PUD_SIZE); |
|---|