diff options
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r-- | arch/x86/mm/pageattr.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index c106f7852424..dce282f65700 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -592,9 +592,12 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) | |||
592 | unsigned int level; | 592 | unsigned int level; |
593 | pte_t *kpte, old_pte; | 593 | pte_t *kpte, old_pte; |
594 | 594 | ||
595 | if (cpa->flags & CPA_PAGES_ARRAY) | 595 | if (cpa->flags & CPA_PAGES_ARRAY) { |
596 | address = (unsigned long)page_address(cpa->pages[cpa->curpage]); | 596 | struct page *page = cpa->pages[cpa->curpage]; |
597 | else if (cpa->flags & CPA_ARRAY) | 597 | if (unlikely(PageHighMem(page))) |
598 | return 0; | ||
599 | address = (unsigned long)page_address(page); | ||
600 | } else if (cpa->flags & CPA_ARRAY) | ||
598 | address = cpa->vaddr[cpa->curpage]; | 601 | address = cpa->vaddr[cpa->curpage]; |
599 | else | 602 | else |
600 | address = *cpa->vaddr; | 603 | address = *cpa->vaddr; |
@@ -698,9 +701,12 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
698 | * No need to redo, when the primary call touched the direct | 701 | * No need to redo, when the primary call touched the direct |
699 | * mapping already: | 702 | * mapping already: |
700 | */ | 703 | */ |
701 | if (cpa->flags & CPA_PAGES_ARRAY) | 704 | if (cpa->flags & CPA_PAGES_ARRAY) { |
702 | vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]); | 705 | struct page *page = cpa->pages[cpa->curpage]; |
703 | else if (cpa->flags & CPA_ARRAY) | 706 | if (unlikely(PageHighMem(page))) |
707 | return 0; | ||
708 | vaddr = (unsigned long)page_address(page); | ||
709 | } else if (cpa->flags & CPA_ARRAY) | ||
704 | vaddr = cpa->vaddr[cpa->curpage]; | 710 | vaddr = cpa->vaddr[cpa->curpage]; |
705 | else | 711 | else |
706 | vaddr = *cpa->vaddr; | 712 | vaddr = *cpa->vaddr; |
@@ -998,12 +1004,15 @@ EXPORT_SYMBOL(set_memory_array_uc); | |||
998 | int _set_memory_wc(unsigned long addr, int numpages) | 1004 | int _set_memory_wc(unsigned long addr, int numpages) |
999 | { | 1005 | { |
1000 | int ret; | 1006 | int ret; |
1007 | unsigned long addr_copy = addr; | ||
1008 | |||
1001 | ret = change_page_attr_set(&addr, numpages, | 1009 | ret = change_page_attr_set(&addr, numpages, |
1002 | __pgprot(_PAGE_CACHE_UC_MINUS), 0); | 1010 | __pgprot(_PAGE_CACHE_UC_MINUS), 0); |
1003 | |||
1004 | if (!ret) { | 1011 | if (!ret) { |
1005 | ret = change_page_attr_set(&addr, numpages, | 1012 | ret = change_page_attr_set_clr(&addr_copy, numpages, |
1006 | __pgprot(_PAGE_CACHE_WC), 0); | 1013 | __pgprot(_PAGE_CACHE_WC), |
1014 | __pgprot(_PAGE_CACHE_MASK), | ||
1015 | 0, 0, NULL); | ||
1007 | } | 1016 | } |
1008 | return ret; | 1017 | return ret; |
1009 | } | 1018 | } |
@@ -1120,7 +1129,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray) | |||
1120 | int free_idx; | 1129 | int free_idx; |
1121 | 1130 | ||
1122 | for (i = 0; i < addrinarray; i++) { | 1131 | for (i = 0; i < addrinarray; i++) { |
1123 | start = (unsigned long)page_address(pages[i]); | 1132 | if (PageHighMem(pages[i])) |
1133 | continue; | ||
1134 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; | ||
1124 | end = start + PAGE_SIZE; | 1135 | end = start + PAGE_SIZE; |
1125 | if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) | 1136 | if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) |
1126 | goto err_out; | 1137 | goto err_out; |
@@ -1133,7 +1144,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray) | |||
1133 | err_out: | 1144 | err_out: |
1134 | free_idx = i; | 1145 | free_idx = i; |
1135 | for (i = 0; i < free_idx; i++) { | 1146 | for (i = 0; i < free_idx; i++) { |
1136 | start = (unsigned long)page_address(pages[i]); | 1147 | if (PageHighMem(pages[i])) |
1148 | continue; | ||
1149 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; | ||
1137 | end = start + PAGE_SIZE; | 1150 | end = start + PAGE_SIZE; |
1138 | free_memtype(start, end); | 1151 | free_memtype(start, end); |
1139 | } | 1152 | } |
@@ -1162,7 +1175,9 @@ int set_pages_array_wb(struct page **pages, int addrinarray) | |||
1162 | return retval; | 1175 | return retval; |
1163 | 1176 | ||
1164 | for (i = 0; i < addrinarray; i++) { | 1177 | for (i = 0; i < addrinarray; i++) { |
1165 | start = (unsigned long)page_address(pages[i]); | 1178 | if (PageHighMem(pages[i])) |
1179 | continue; | ||
1180 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; | ||
1166 | end = start + PAGE_SIZE; | 1181 | end = start + PAGE_SIZE; |
1167 | free_memtype(start, end); | 1182 | free_memtype(start, end); |
1168 | } | 1183 | } |