Commit afca0357 authored by Paul Mundt's avatar Paul Mundt

sh: Correct pte_page() breakage.

As noted by David:

pte_page() is a macro defined as follows;

    include/asm-sh/pgtable.h
    #define pte_page(x)    phys_to_page(pte_val(x)&PTE_PHYS_MASK)

    include/asm-sh/page.h
    #define phys_to_page(phys)    (pfn_to_page(phys >> PAGE_SHIFT))

So as you can see the phys_to_page() macro doesn't wrap the 'phys'
parameter in parentheses so we end up with;

    pte_val(x)&PTE_PHYS_MASK >> PAGE_SHIFT

Which is not what we wanted as '>>' has a higher precedence than bitwise
AND. I dug into the git repository and I believe this bug was added with
this commit (104b8dea);

2006-03-27 KAMEZAWA Hiroyuki [PATCH] unify pfn_to_page: sh pfn_to_page

-#define phys_to_page(phys)     (mem_map + (((phys)-__MEMORY_START) >>
PAGE_SHIFT))
-#define page_to_phys(page)     (((page - mem_map) << PAGE_SHIFT) +
__MEMORY_START)
+#define phys_to_page(phys)     (pfn_to_page(phys >> PAGE_SHIFT))
+#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
Reported-by: default avatarDavid ADDISON <david.addison@st.com>
Reported-by: default avatarKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent ad07b100
...@@ -128,7 +128,6 @@ typedef struct { unsigned long pgd; } pgd_t; ...@@ -128,7 +128,6 @@ typedef struct { unsigned long pgd; } pgd_t;
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
#define phys_to_page(phys) (pfn_to_page(phys >> PAGE_SHIFT))
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
/* PFN start number, because of __MEMORY_START */ /* PFN start number, because of __MEMORY_START */
......
...@@ -399,7 +399,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte) ...@@ -399,7 +399,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) #define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK)
#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
#define pte_page(x) phys_to_page(pte_val(x)&PTE_PHYS_MASK) #define pte_page(x) pfn_to_page(pte_pfn(x))
/* /*
* The following only work if pte_present() is true. * The following only work if pte_present() is true.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment