Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8523acfe authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Ingo Molnar
Browse files

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=13884



Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Acked-by: default avatarSuresh 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: default avatarIngo Molnar <mingo@elte.hu>
parent bdc6340f
Loading
Loading
Loading
Loading
+21 −9
Original line number Original line Diff line number Diff line
@@ -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)
	 * 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)
	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)
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)
		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);
	}
	}