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