aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pageattr.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-05-08 04:50:00 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-08 04:50:00 -0400
commitf066a155334642b8a206eec625b1925d88c48aeb (patch)
treecb12975e60b70d1dae3b7397bab955de78a4d01e /arch/x86/mm/pageattr.c
parente7c064889606aab3569669078c69b87b2c527e72 (diff)
parent33df4db04a79660150e1948e3296eeb451ac121b (diff)
Merge branch 'x86/urgent' into x86/xen
Conflicts: arch/frv/include/asm/pgtable.h arch/x86/include/asm/required-features.h arch/x86/xen/mmu.c Merge reason: x86/xen was on a .29 base still, move it to a fresher branch and pick up Xen fixes as well, plus resolve conflicts Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r--arch/x86/mm/pageattr.c127
1 files changed, 77 insertions, 50 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 660cac75ae11..b81b41a0481f 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -931,71 +931,94 @@ int _set_memory_uc(unsigned long addr, int numpages)
931 931
932int set_memory_uc(unsigned long addr, int numpages) 932int set_memory_uc(unsigned long addr, int numpages)
933{ 933{
934 int ret;
935
934 /* 936 /*
935 * for now UC MINUS. see comments in ioremap_nocache() 937 * for now UC MINUS. see comments in ioremap_nocache()
936 */ 938 */
937 if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE, 939 ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
938 _PAGE_CACHE_UC_MINUS, NULL)) 940 _PAGE_CACHE_UC_MINUS, NULL);
939 return -EINVAL; 941 if (ret)
942 goto out_err;
943
944 ret = _set_memory_uc(addr, numpages);
945 if (ret)
946 goto out_free;
940 947
941 return _set_memory_uc(addr, numpages); 948 return 0;
949
950out_free:
951 free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
952out_err:
953 return ret;
942} 954}
943EXPORT_SYMBOL(set_memory_uc); 955EXPORT_SYMBOL(set_memory_uc);
944 956
945int set_memory_array_uc(unsigned long *addr, int addrinarray) 957int set_memory_array_uc(unsigned long *addr, int addrinarray)
946{ 958{
947 unsigned long start; 959 int i, j;
948 unsigned long end; 960 int ret;
949 int i; 961
950 /* 962 /*
951 * for now UC MINUS. see comments in ioremap_nocache() 963 * for now UC MINUS. see comments in ioremap_nocache()
952 */ 964 */
953 for (i = 0; i < addrinarray; i++) { 965 for (i = 0; i < addrinarray; i++) {
954 start = __pa(addr[i]); 966 ret = reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE,
955 for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) { 967 _PAGE_CACHE_UC_MINUS, NULL);
956 if (end != __pa(addr[i + 1])) 968 if (ret)
957 break; 969 goto out_free;
958 i++;
959 }
960 if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
961 goto out;
962 } 970 }
963 971
964 return change_page_attr_set(addr, addrinarray, 972 ret = change_page_attr_set(addr, addrinarray,
965 __pgprot(_PAGE_CACHE_UC_MINUS), 1); 973 __pgprot(_PAGE_CACHE_UC_MINUS), 1);
966out: 974 if (ret)
967 for (i = 0; i < addrinarray; i++) { 975 goto out_free;
968 unsigned long tmp = __pa(addr[i]); 976
969 977 return 0;
970 if (tmp == start) 978
971 break; 979out_free:
972 for (end = tmp + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) { 980 for (j = 0; j < i; j++)
973 if (end != __pa(addr[i + 1])) 981 free_memtype(__pa(addr[j]), __pa(addr[j]) + PAGE_SIZE);
974 break; 982
975 i++; 983 return ret;
976 }
977 free_memtype(tmp, end);
978 }
979 return -EINVAL;
980} 984}
981EXPORT_SYMBOL(set_memory_array_uc); 985EXPORT_SYMBOL(set_memory_array_uc);
982 986
983int _set_memory_wc(unsigned long addr, int numpages) 987int _set_memory_wc(unsigned long addr, int numpages)
984{ 988{
985 return change_page_attr_set(&addr, numpages, 989 int ret;
990 ret = change_page_attr_set(&addr, numpages,
991 __pgprot(_PAGE_CACHE_UC_MINUS), 0);
992
993 if (!ret) {
994 ret = change_page_attr_set(&addr, numpages,
986 __pgprot(_PAGE_CACHE_WC), 0); 995 __pgprot(_PAGE_CACHE_WC), 0);
996 }
997 return ret;
987} 998}
988 999
989int set_memory_wc(unsigned long addr, int numpages) 1000int set_memory_wc(unsigned long addr, int numpages)
990{ 1001{
1002 int ret;
1003
991 if (!pat_enabled) 1004 if (!pat_enabled)
992 return set_memory_uc(addr, numpages); 1005 return set_memory_uc(addr, numpages);
993 1006
994 if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE, 1007 ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
995 _PAGE_CACHE_WC, NULL)) 1008 _PAGE_CACHE_WC, NULL);
996 return -EINVAL; 1009 if (ret)
1010 goto out_err;
1011
1012 ret = _set_memory_wc(addr, numpages);
1013 if (ret)
1014 goto out_free;
1015
1016 return 0;
997 1017
998 return _set_memory_wc(addr, numpages); 1018out_free:
1019 free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
1020out_err:
1021 return ret;
999} 1022}
1000EXPORT_SYMBOL(set_memory_wc); 1023EXPORT_SYMBOL(set_memory_wc);
1001 1024
@@ -1007,29 +1030,31 @@ int _set_memory_wb(unsigned long addr, int numpages)
1007 1030
1008int set_memory_wb(unsigned long addr, int numpages) 1031int set_memory_wb(unsigned long addr, int numpages)
1009{ 1032{
1010 free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE); 1033 int ret;
1034
1035 ret = _set_memory_wb(addr, numpages);
1036 if (ret)
1037 return ret;
1011 1038
1012 return _set_memory_wb(addr, numpages); 1039 free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
1040 return 0;
1013} 1041}
1014EXPORT_SYMBOL(set_memory_wb); 1042EXPORT_SYMBOL(set_memory_wb);
1015 1043
1016int set_memory_array_wb(unsigned long *addr, int addrinarray) 1044int set_memory_array_wb(unsigned long *addr, int addrinarray)
1017{ 1045{
1018 int i; 1046 int i;
1047 int ret;
1019 1048
1020 for (i = 0; i < addrinarray; i++) { 1049 ret = change_page_attr_clear(addr, addrinarray,
1021 unsigned long start = __pa(addr[i]);
1022 unsigned long end;
1023
1024 for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
1025 if (end != __pa(addr[i + 1]))
1026 break;
1027 i++;
1028 }
1029 free_memtype(start, end);
1030 }
1031 return change_page_attr_clear(addr, addrinarray,
1032 __pgprot(_PAGE_CACHE_MASK), 1); 1050 __pgprot(_PAGE_CACHE_MASK), 1);
1051 if (ret)
1052 return ret;
1053
1054 for (i = 0; i < addrinarray; i++)
1055 free_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE);
1056
1057 return 0;
1033} 1058}
1034EXPORT_SYMBOL(set_memory_array_wb); 1059EXPORT_SYMBOL(set_memory_array_wb);
1035 1060
@@ -1122,6 +1147,8 @@ int set_pages_array_wb(struct page **pages, int addrinarray)
1122 1147
1123 retval = cpa_clear_pages_array(pages, addrinarray, 1148 retval = cpa_clear_pages_array(pages, addrinarray,
1124 __pgprot(_PAGE_CACHE_MASK)); 1149 __pgprot(_PAGE_CACHE_MASK));
1150 if (retval)
1151 return retval;
1125 1152
1126 for (i = 0; i < addrinarray; i++) { 1153 for (i = 0; i < addrinarray; i++) {
1127 start = (unsigned long)page_address(pages[i]); 1154 start = (unsigned long)page_address(pages[i]);
@@ -1129,7 +1156,7 @@ int set_pages_array_wb(struct page **pages, int addrinarray)
1129 free_memtype(start, end); 1156 free_memtype(start, end);
1130 } 1157 }
1131 1158
1132 return retval; 1159 return 0;
1133} 1160}
1134EXPORT_SYMBOL(set_pages_array_wb); 1161EXPORT_SYMBOL(set_pages_array_wb);
1135 1162