.. | .. |
---|
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); |
---|