lkml.org 
[lkml]   [2009]   [Aug]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 39/74] x86: Fix CPA memtype reserving in the set_pages_array*() cases
    2.6.30-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Thomas Hellstrom <thellstrom@vmware.com>

    commit 8523acfe40efc1a8d3da8f473ca67cb195b06f0c upstream.

    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: Thomas Hellstrom <thellstrom@vmware.com>
    Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
    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: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    arch/x86/mm/pageattr.c | 30 +++++++++++++++++++++---------
    1 file changed, 21 insertions(+), 9 deletions(-)

    --- a/arch/x86/mm/pageattr.c
    +++ b/arch/x86/mm/pageattr.c
    @@ -590,9 +590,12 @@ static int __change_page_attr(struct cpa
    unsigned int level;
    pte_t *kpte, old_pte;

    - if (cpa->flags & CPA_PAGES_ARRAY)
    - address = (unsigned long)page_address(cpa->pages[cpa->curpage]);
    - else if (cpa->flags & CPA_ARRAY)
    + if (cpa->flags & CPA_PAGES_ARRAY) {
    + struct page *page = cpa->pages[cpa->curpage];
    + if (unlikely(PageHighMem(page)))
    + return 0;
    + address = (unsigned long)page_address(page);
    + } else if (cpa->flags & CPA_ARRAY)
    address = cpa->vaddr[cpa->curpage];
    else
    address = *cpa->vaddr;
    @@ -695,9 +698,12 @@ static int cpa_process_alias(struct cpa_
    * No need to redo, when the primary call touched the direct
    * mapping already:
    */
    - if (cpa->flags & CPA_PAGES_ARRAY)
    - vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]);
    - else if (cpa->flags & CPA_ARRAY)
    + if (cpa->flags & CPA_PAGES_ARRAY) {
    + struct page *page = cpa->pages[cpa->curpage];
    + if (unlikely(PageHighMem(page)))
    + return 0;
    + vaddr = (unsigned long)page_address(page);
    + } else if (cpa->flags & CPA_ARRAY)
    vaddr = cpa->vaddr[cpa->curpage];
    else
    vaddr = *cpa->vaddr;
    @@ -1118,7 +1124,9 @@ int set_pages_array_uc(struct page **pag
    int free_idx;

    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;
    if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
    goto err_out;
    @@ -1131,7 +1139,9 @@ int set_pages_array_uc(struct page **pag
    err_out:
    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;
    free_memtype(start, end);
    }
    @@ -1160,7 +1170,9 @@ int set_pages_array_wb(struct page **pag
    return retval;

    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;
    free_memtype(start, end);
    }



    \
     
     \ /
      Last update: 2009-08-13 22:27    [W:0.024 / U:33.056 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site