diff options
| -rw-r--r-- | arch/x86/mm/pageattr.c | 38 |
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 | ||
| 943 | int set_memory_array_uc(unsigned long *addr, int addrinarray) | 943 | int 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); |
| 957 | out: | 964 | out: |
| 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 | } |
| 962 | EXPORT_SYMBOL(set_memory_array_uc); | 979 | EXPORT_SYMBOL(set_memory_array_uc); |
| @@ -997,9 +1014,18 @@ EXPORT_SYMBOL(set_memory_wb); | |||
| 997 | int set_memory_array_wb(unsigned long *addr, int addrinarray) | 1014 | int 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 | } |
