diff options
| -rw-r--r-- | arch/x86/kernel/doublefault_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/mm/ioremap.c | 31 | ||||
| -rw-r--r-- | include/asm-x86/mmzone_64.h | 2 | ||||
| -rw-r--r-- | include/asm-x86/page_32.h | 3 | ||||
| -rw-r--r-- | include/linux/mm.h | 7 | ||||
| -rw-r--r-- | include/linux/mmdebug.h | 18 | ||||
| -rw-r--r-- | lib/Kconfig.debug | 9 | ||||
| -rw-r--r-- | mm/vmalloc.c | 5 | 
8 files changed, 61 insertions, 16 deletions
diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c index a47798b59f0..395acb12b0d 100644 --- a/arch/x86/kernel/doublefault_32.c +++ b/arch/x86/kernel/doublefault_32.c @@ -66,6 +66,6 @@ struct tss_struct doublefault_tss __cacheline_aligned = {  		.ds		= __USER_DS,  		.fs		= __KERNEL_PERCPU, -		.__cr3		= __pa(swapper_pg_dir) +		.__cr3		= __phys_addr_const((unsigned long)swapper_pg_dir)  	}  }; diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 2b2bb3f9b68..a78ffef62a2 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -23,18 +23,26 @@  #ifdef CONFIG_X86_64 -unsigned long __phys_addr(unsigned long x) +static inline int phys_addr_valid(unsigned long addr)  { -	if (x >= __START_KERNEL_map) -		return x - __START_KERNEL_map + phys_base; -	return x - PAGE_OFFSET; +	return addr < (1UL << boot_cpu_data.x86_phys_bits);  } -EXPORT_SYMBOL(__phys_addr); -static inline int phys_addr_valid(unsigned long addr) +unsigned long __phys_addr(unsigned long x)  { -	return addr < (1UL << boot_cpu_data.x86_phys_bits); +	if (x >= __START_KERNEL_map) { +		x -= __START_KERNEL_map; +		VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE); +		x += phys_base; +	} else { +		VIRTUAL_BUG_ON(x < PAGE_OFFSET); +		x -= PAGE_OFFSET; +		VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM : +					!phys_addr_valid(x)); +	} +	return x;  } +EXPORT_SYMBOL(__phys_addr);  #else @@ -43,6 +51,15 @@ static inline int phys_addr_valid(unsigned long addr)  	return 1;  } +unsigned long __phys_addr(unsigned long x) +{ +	/* VMALLOC_* aren't constants; not available at the boot time */ +	VIRTUAL_BUG_ON(x < PAGE_OFFSET || (system_state != SYSTEM_BOOTING && +					is_vmalloc_addr((void *)x))); +	return x - PAGE_OFFSET; +} +EXPORT_SYMBOL(__phys_addr); +  #endif  int page_is_ram(unsigned long pagenr) diff --git a/include/asm-x86/mmzone_64.h b/include/asm-x86/mmzone_64.h index 594bd0dc1d0..facde3e5314 100644 --- a/include/asm-x86/mmzone_64.h +++ b/include/asm-x86/mmzone_64.h @@ -7,7 +7,7 @@  #ifdef CONFIG_NUMA -#define VIRTUAL_BUG_ON(x) +#include <linux/mmdebug.h>  #include <asm/smp.h> diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index 424e82f8ae2..9159bfb9dcf 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -64,7 +64,8 @@ typedef struct page *pgtable_t;  #endif  #ifndef __ASSEMBLY__ -#define __phys_addr(x)		((x) - PAGE_OFFSET) +#define __phys_addr_const(x)	((x) - PAGE_OFFSET) +extern unsigned long __phys_addr(unsigned long);  #define __phys_reloc_hide(x)	RELOC_HIDE((x), 0)  #ifdef CONFIG_FLATMEM diff --git a/include/linux/mm.h b/include/linux/mm.h index 586a943cab0..3414a8813e9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -7,6 +7,7 @@  #include <linux/gfp.h>  #include <linux/list.h> +#include <linux/mmdebug.h>  #include <linux/mmzone.h>  #include <linux/rbtree.h>  #include <linux/prio_tree.h> @@ -210,12 +211,6 @@ struct inode;   */  #include <linux/page-flags.h> -#ifdef CONFIG_DEBUG_VM -#define VM_BUG_ON(cond) BUG_ON(cond) -#else -#define VM_BUG_ON(condition) do { } while(0) -#endif -  /*   * Methods to modify the page usage count.   * diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h new file mode 100644 index 00000000000..860ed1a71bb --- /dev/null +++ b/include/linux/mmdebug.h @@ -0,0 +1,18 @@ +#ifndef LINUX_MM_DEBUG_H +#define LINUX_MM_DEBUG_H 1 + +#include <linux/autoconf.h> + +#ifdef CONFIG_DEBUG_VM +#define VM_BUG_ON(cond) BUG_ON(cond) +#else +#define VM_BUG_ON(cond) do { } while(0) +#endif + +#ifdef CONFIG_DEBUG_VIRTUAL +#define VIRTUAL_BUG_ON(cond) BUG_ON(cond) +#else +#define VIRTUAL_BUG_ON(cond) do { } while(0) +#endif + +#endif diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d2099f41aa1..9d9dc0ddf13 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -469,6 +469,15 @@ config DEBUG_VM  	  If unsure, say N. +config DEBUG_VIRTUAL +	bool "Debug VM translations" +	depends on DEBUG_KERNEL && X86 +	help +	  Enable some costly sanity checks in virtual to page code. This can +	  catch mistakes with virt_to_page() and friends. + +	  If unsure, say N. +  config DEBUG_WRITECOUNT  	bool "Debug filesystem writers count"  	depends on DEBUG_KERNEL diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 6e45b0f3d12..dc41e9c8ca6 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -180,6 +180,11 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)  	pmd_t *pmd;  	pte_t *ptep, pte; +	/* XXX we might need to change this if we add VIRTUAL_BUG_ON for +	 * architectures that do not vmalloc module space */ +	VIRTUAL_BUG_ON(!is_vmalloc_addr(vmalloc_addr) && +			!is_module_address(addr)); +  	if (!pgd_none(*pgd)) {  		pud = pud_offset(pgd, addr);  		if (!pud_none(*pud)) {  |