diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-05-08 04:50:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-08 04:50:00 -0400 |
commit | f066a155334642b8a206eec625b1925d88c48aeb (patch) | |
tree | cb12975e60b70d1dae3b7397bab955de78a4d01e /arch/x86/mm/pageattr.c | |
parent | e7c064889606aab3569669078c69b87b2c527e72 (diff) | |
parent | 33df4db04a79660150e1948e3296eeb451ac121b (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.c | 127 |
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 | ||
932 | int set_memory_uc(unsigned long addr, int numpages) | 932 | int 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 | |||
950 | out_free: | ||
951 | free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE); | ||
952 | out_err: | ||
953 | return ret; | ||
942 | } | 954 | } |
943 | EXPORT_SYMBOL(set_memory_uc); | 955 | EXPORT_SYMBOL(set_memory_uc); |
944 | 956 | ||
945 | int set_memory_array_uc(unsigned long *addr, int addrinarray) | 957 | int 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); |
966 | out: | 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; | 979 | out_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 | } |
981 | EXPORT_SYMBOL(set_memory_array_uc); | 985 | EXPORT_SYMBOL(set_memory_array_uc); |
982 | 986 | ||
983 | int _set_memory_wc(unsigned long addr, int numpages) | 987 | int _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 | ||
989 | int set_memory_wc(unsigned long addr, int numpages) | 1000 | int 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); | 1018 | out_free: |
1019 | free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE); | ||
1020 | out_err: | ||
1021 | return ret; | ||
999 | } | 1022 | } |
1000 | EXPORT_SYMBOL(set_memory_wc); | 1023 | EXPORT_SYMBOL(set_memory_wc); |
1001 | 1024 | ||
@@ -1007,29 +1030,31 @@ int _set_memory_wb(unsigned long addr, int numpages) | |||
1007 | 1030 | ||
1008 | int set_memory_wb(unsigned long addr, int numpages) | 1031 | int 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 | } |
1014 | EXPORT_SYMBOL(set_memory_wb); | 1042 | EXPORT_SYMBOL(set_memory_wb); |
1015 | 1043 | ||
1016 | int set_memory_array_wb(unsigned long *addr, int addrinarray) | 1044 | int 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 | } |
1034 | EXPORT_SYMBOL(set_memory_array_wb); | 1059 | EXPORT_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 | } |
1134 | EXPORT_SYMBOL(set_pages_array_wb); | 1161 | EXPORT_SYMBOL(set_pages_array_wb); |
1135 | 1162 | ||