From 2bd3a99c9d1851182f73d0a024dc5bdb0a470e8c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 20 May 2008 08:26:17 +0100 Subject: x86: define PTE_MASK in a universally useful way Define PTE_MASK so that it contains a meaningful value for all x86 pagetable configurations. Previously it was defined as a "long" which means that it was too short to cover a 32-bit PAE pte entry. It is now defined as a pteval_t, which is an integer type long enough to contain a full pte (or pmd, pud, pgd). This fixes an Xorg crash on 32-bit x86 with PAE due to corruption of the NX bit in mprotect due to the incorrect type/value of PTE_MASK reported by Hugh Dickins: "Yes, thanks Jeremy: I've checked that each stage builds and runs X on my boxes here, x86_32 and x86_32+PAE and x86_64. (So even 1/8 is enough to fix the PAT pte_modify issue, though 2/8 then fixes compiler warnings.)" Signed-off-by: Jeremy Fitzhardinge Tested-by: Hugh Dickins Signed-off-by: Linus Torvalds --- include/asm-x86/page.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'include/asm-x86/page.h') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index b381f4a..76b35e6 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -10,8 +10,13 @@ #ifdef __KERNEL__ -#define PHYSICAL_PAGE_MASK (PAGE_MASK & __PHYSICAL_MASK) -#define PTE_MASK (_AT(long, PHYSICAL_PAGE_MASK)) +/* Cast PAGE_MASK to a signed type so that it is sign-extended if + virtual addresses are 32-bits but physical addresses are larger + (ie, 32-bit PAE). */ +#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK) + +/* PTE_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */ +#define PTE_MASK ((pteval_t)PHYSICAL_PAGE_MASK) #define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT) #define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1)) @@ -24,8 +29,8 @@ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define __PHYSICAL_MASK _AT(phys_addr_t, (_AC(1,ULL) << __PHYSICAL_MASK_SHIFT) - 1) -#define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1) +#define __PHYSICAL_MASK ((((phys_addr_t)1) << __PHYSICAL_MASK_SHIFT) - 1) +#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) #ifndef __ASSEMBLY__ #include -- cgit v1.1 From 1bb271db63c356212564aad050b2cf026f800858 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 20 May 2008 08:26:18 +0100 Subject: x86: fix warning on 32-bit non-PAE Fix the warning: include2/asm/pgtable.h: In function `pte_modify': include2/asm/pgtable.h:290: warning: left shift count >= width of type On 32-bit PAE the virtual and physical addresses are both 32-bits, so it ends up evaluating 1<<32. Do the shift as a 64-bit shift then cast to the appropriate size. This should all be done at compile time, and so have no effect on generated code. Signed-off-by: Jeremy Fitzhardinge Tested-by: Hugh Dickins Signed-off-by: Linus Torvalds --- include/asm-x86/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86/page.h') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 76b35e6..223146d 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -29,7 +29,7 @@ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define __PHYSICAL_MASK ((((phys_addr_t)1) << __PHYSICAL_MASK_SHIFT) - 1) +#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1) #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) #ifndef __ASSEMBLY__ -- cgit v1.1 From c57c05d0032cd5a500c5eba18ede4867a6d2cd5f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 20 May 2008 08:26:19 +0100 Subject: x86: rearrange __(VIRTUAL|PHYSICAL)_MASK Put the definitions of __(VIRTUAL|PHYSICAL)_MASK before their uses. Signed-off-by: Jeremy Fitzhardinge Tested-by: Hugh Dickins Signed-off-by: Linus Torvalds --- include/asm-x86/page.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/asm-x86/page.h') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 223146d..dc936dd 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -10,6 +10,9 @@ #ifdef __KERNEL__ +#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1) +#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) + /* Cast PAGE_MASK to a signed type so that it is sign-extended if virtual addresses are 32-bits but physical addresses are larger (ie, 32-bit PAE). */ @@ -29,9 +32,6 @@ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1) -#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) - #ifndef __ASSEMBLY__ #include #endif -- cgit v1.1 From 635ee418381566f03819408e1303ef21fcf2d41c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 12 May 2008 15:43:35 +0200 Subject: x86: create prototype for (un)map_devmem Global functions need a prototype. Add it. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/page.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include/asm-x86/page.h') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index dc936dd..ed16509 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -51,8 +51,15 @@ #ifndef __ASSEMBLY__ +typedef struct { pgdval_t pgd; } pgd_t; +typedef struct { pgprotval_t pgprot; } pgprot_t; + extern int page_is_ram(unsigned long pagenr); extern int devmem_is_allowed(unsigned long pagenr); +extern void map_devmem(unsigned long pfn, unsigned long size, + pgprot_t vma_prot); +extern void unmap_devmem(unsigned long pfn, unsigned long size, + pgprot_t vma_prot); extern unsigned long max_pfn_mapped; @@ -74,9 +81,6 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE -typedef struct { pgdval_t pgd; } pgd_t; -typedef struct { pgprotval_t pgprot; } pgprot_t; - static inline pgd_t native_make_pgd(pgdval_t val) { return (pgd_t) { val }; -- cgit v1.1 From a15af1c9ea2750a9ff01e51615c45950bad8221b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 26 May 2008 23:31:06 +0100 Subject: x86/paravirt: add pte_flags to just get pte flags Add pte_flags() to extract the flags from a pte. This is a special case of pte_val() which is only guaranteed to return the pte's flags correctly; the page number may be corrupted or missing. The intent is to allow paravirt implementations to return pte flags without having to do any translation of the page number (most notably, Xen). Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86/page.h') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index dc936dd..a1e2b947 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -160,6 +160,7 @@ static inline pteval_t native_pte_val(pte_t pte) #endif #define pte_val(x) native_pte_val(x) +#define pte_flags(x) native_pte_val(x) #define __pte(x) native_make_pte(x) #endif /* CONFIG_PARAVIRT */ -- cgit v1.1