提交 8523acfe 编写于 作者: T Thomas Hellstrom 提交者: Ingo Molnar

x86: Fix CPA memtype reserving in the set_pages_array*() cases

The code was incorrectly reserving memtypes using the page
virtual address instead of the physical address. Furthermore,
the code was not ignoring highmem pages as it ought to.

( upstream does not pass in highmem pages yet - but upcoming
  graphics code will do it and there's no reason to not handle
  this properly in the CPA APIs.)

Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=13884Signed-off-by: NThomas Hellstrom <thellstrom@vmware.com>
Acked-by: NSuresh Siddha <suresh.b.siddha@intel.com>
Cc: <stable@kernel.org>
Cc: dri-devel@lists.sourceforge.net
Cc: venkatesh.pallipadi@intel.com
LKML-Reference: <1249284345-7654-1-git-send-email-thellstrom@vmware.com>
Signed-off-by: NIngo Molnar <mingo@elte.hu>
上级 bdc6340f
...@@ -591,9 +591,12 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) ...@@ -591,9 +591,12 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
unsigned int level; unsigned int level;
pte_t *kpte, old_pte; pte_t *kpte, old_pte;
if (cpa->flags & CPA_PAGES_ARRAY) if (cpa->flags & CPA_PAGES_ARRAY) {
address = (unsigned long)page_address(cpa->pages[cpa->curpage]); struct page *page = cpa->pages[cpa->curpage];
else if (cpa->flags & CPA_ARRAY) if (unlikely(PageHighMem(page)))
return 0;
address = (unsigned long)page_address(page);
} else if (cpa->flags & CPA_ARRAY)
address = cpa->vaddr[cpa->curpage]; address = cpa->vaddr[cpa->curpage];
else else
address = *cpa->vaddr; address = *cpa->vaddr;
...@@ -697,9 +700,12 @@ static int cpa_process_alias(struct cpa_data *cpa) ...@@ -697,9 +700,12 @@ static int cpa_process_alias(struct cpa_data *cpa)
* No need to redo, when the primary call touched the direct * No need to redo, when the primary call touched the direct
* mapping already: * mapping already:
*/ */
if (cpa->flags & CPA_PAGES_ARRAY) if (cpa->flags & CPA_PAGES_ARRAY) {
vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]); struct page *page = cpa->pages[cpa->curpage];
else if (cpa->flags & CPA_ARRAY) if (unlikely(PageHighMem(page)))
return 0;
vaddr = (unsigned long)page_address(page);
} else if (cpa->flags & CPA_ARRAY)
vaddr = cpa->vaddr[cpa->curpage]; vaddr = cpa->vaddr[cpa->curpage];
else else
vaddr = *cpa->vaddr; vaddr = *cpa->vaddr;
...@@ -1122,7 +1128,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray) ...@@ -1122,7 +1128,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray)
int free_idx; int free_idx;
for (i = 0; i < addrinarray; i++) { for (i = 0; i < addrinarray; i++) {
start = (unsigned long)page_address(pages[i]); if (PageHighMem(pages[i]))
continue;
start = page_to_pfn(pages[i]) << PAGE_SHIFT;
end = start + PAGE_SIZE; end = start + PAGE_SIZE;
if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
goto err_out; goto err_out;
...@@ -1135,7 +1143,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray) ...@@ -1135,7 +1143,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray)
err_out: err_out:
free_idx = i; free_idx = i;
for (i = 0; i < free_idx; i++) { for (i = 0; i < free_idx; i++) {
start = (unsigned long)page_address(pages[i]); if (PageHighMem(pages[i]))
continue;
start = page_to_pfn(pages[i]) << PAGE_SHIFT;
end = start + PAGE_SIZE; end = start + PAGE_SIZE;
free_memtype(start, end); free_memtype(start, end);
} }
...@@ -1164,7 +1174,9 @@ int set_pages_array_wb(struct page **pages, int addrinarray) ...@@ -1164,7 +1174,9 @@ int set_pages_array_wb(struct page **pages, int addrinarray)
return retval; return retval;
for (i = 0; i < addrinarray; i++) { for (i = 0; i < addrinarray; i++) {
start = (unsigned long)page_address(pages[i]); if (PageHighMem(pages[i]))
continue;
start = page_to_pfn(pages[i]) << PAGE_SHIFT;
end = start + PAGE_SIZE; end = start + PAGE_SIZE;
free_memtype(start, end); free_memtype(start, end);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册