aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/pageattr.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index fed6ba2a8e7e..497108825da9 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -942,21 +942,38 @@ EXPORT_SYMBOL(set_memory_uc);
942 942
943int set_memory_array_uc(unsigned long *addr, int addrinarray) 943int set_memory_array_uc(unsigned long *addr, int addrinarray)
944{ 944{
945 unsigned long start;
946 unsigned long end;
945 int i; 947 int i;
946 /* 948 /*
947 * for now UC MINUS. see comments in ioremap_nocache() 949 * for now UC MINUS. see comments in ioremap_nocache()
948 */ 950 */
949 for (i = 0; i < addrinarray; i++) { 951 for (i = 0; i < addrinarray; i++) {
950 if (reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE, 952 start = __pa(addr[i]);
951 _PAGE_CACHE_UC_MINUS, NULL)) 953 for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
954 if (end != __pa(addr[i + 1]))
955 break;
956 i++;
957 }
958 if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
952 goto out; 959 goto out;
953 } 960 }
954 961
955 return change_page_attr_set(addr, addrinarray, 962 return change_page_attr_set(addr, addrinarray,
956 __pgprot(_PAGE_CACHE_UC_MINUS), 1); 963 __pgprot(_PAGE_CACHE_UC_MINUS), 1);
957out: 964out:
958 while (--i >= 0) 965 for (i = 0; i < addrinarray; i++) {
959 free_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE); 966 unsigned long tmp = __pa(addr[i]);
967
968 if (tmp == start)
969 break;
970 for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
971 if (end != __pa(addr[i + 1]))
972 break;
973 i++;
974 }
975 free_memtype(tmp, end);
976 }
960 return -EINVAL; 977 return -EINVAL;
961} 978}
962EXPORT_SYMBOL(set_memory_array_uc); 979EXPORT_SYMBOL(set_memory_array_uc);
@@ -997,9 +1014,18 @@ EXPORT_SYMBOL(set_memory_wb);
997int set_memory_array_wb(unsigned long *addr, int addrinarray) 1014int set_memory_array_wb(unsigned long *addr, int addrinarray)
998{ 1015{
999 int i; 1016 int i;
1000 for (i = 0; i < addrinarray; i++)
1001 free_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE);
1002 1017
1018 for (i = 0; i < addrinarray; i++) {
1019 unsigned long start = __pa(addr[i]);
1020 unsigned long end;
1021
1022 for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
1023 if (end != __pa(addr[i + 1]))
1024 break;
1025 i++;
1026 }
1027 free_memtype(start, end);
1028 }
1003 return change_page_attr_clear(addr, addrinarray, 1029 return change_page_attr_clear(addr, addrinarray,
1004 __pgprot(_PAGE_CACHE_MASK), 1); 1030 __pgprot(_PAGE_CACHE_MASK), 1);
1005} 1031}