x86: Unification patches etc
cover x86: Unification patches etc
Some patches that have so far not been merged. Various fixes after running this on a variety of configurations. Builds on 8 different 32 bit / 64 bit configs.
PATCH 1/6 x86: Unify current.h
Simply stitch these together. There are just two definitions that are shared but the file is resonably small and putting these things together shows that further unifications requires a unification of the per cpu / pda handling between both arches.
--- include/asm-x86/current.h | 42 ++++++++++++++++++++++++++++++++++++++---- include/asm-x86/current_32.h | 17 ----------------- include/asm-x86/current_64.h | 27 --------------------------- 3 files changed, 38 insertions(+), 48 deletions(-)
include/asm-x86/current.h +38 -4
@@ -1,5 +1,39 @@ +#ifndef _X86_CURRENT_H +#define _X86_CURRENT_H +#ifdef CONFIG_X86_32 -# include "current_32.h" -#else -# include "current_64.h" -#endif +#include <linux/compiler.h> +#include <asm/percpu.h> + +struct task_struct ; + +DECLARE_PER_CPU(struct task_struct *, current_task); +static __always_inline struct task_struct *get_current(void) +{ +return x86_read_percpu (current_task); +} + +#else /* X86_32 */ + +#ifndef __ASSEMBLY__ +#include <asm/pda.h> + +struct task_struct ; + +static __always_inline struct task_struct *get_current(void) +{ +return read_pda (pcurrent); +} + +#else /* __ASSEMBLY__ */ + +#include <asm/asm-offsets.h> +#define GET_CURRENT (reg) movq %gs:(pda_pcurrent),reg + +#endif /* __ASSEMBLY__ */ + +#endif /* X86_32 */ + +#define current get_current() + +#endif /* X86_CURRENT_H */
include/asm-x86/current_32.h deleted +0 -17
@@ -1,17 +0,0 @@ -#ifndef _I386_CURRENT_H -#define _I386_CURRENT_H - -#include <linux/compiler.h> -#include <asm/percpu.h> - -struct task_struct ; - -DECLARE_PER_CPU(struct task_struct *, current_task); -static __always_inline struct task_struct *get_current(void) -{ -return x86_read_percpu (current_task); -} - -#define current get_current() - -#endif /* !(_I386_CURRENT_H) */
include/asm-x86/current_64.h deleted +0 -27
@@ -1,27 +0,0 @@ -#ifndef _X86_64_CURRENT_H -#define _X86_64_CURRENT_H - -#if !defined(__ASSEMBLY__) -struct task_struct ; - -#include <asm/pda.h> - -static inline struct task_struct *get_current (void ) -{ -struct task_struct *t =read_pda (pcurrent); -return t; -} - -#define current get_current() - -#else - -#ifndef ASM_OFFSET_H -#include <asm/asm-offsets.h> -#endif - -#define GET_CURRENT (reg) movq %gs:(pda_pcurrent),reg - -#endif - -#endif /* !(_X86_64_CURRENT_H) */
Ingo Molnar
AppliedRe: [patch 1/6] x86: Unify current.h
Quoted 4 lines · Christoph Lameter
Simply stitch these together. There are just two definitions that are shared but the file is resonably small and putting these things together shows that further unifications requires a unification of the per cpu / pda handling between both arches.
applied, thanks.
Ingo
PATCH 2/6 x86: e820.h unification
In reply to Christoph LameterThe first patch simply puts both 32 and 64 bit headers into one header file. The #ifdef sequence at the top is shared.
--- include/asm-x86/e820.h | 103 +++++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/e820_32.h | 50 ---------------------- include/asm-x86/e820_64.h | 56 ------------------------- 3 files changed, 101 insertions(+), 108 deletions(-)
include/asm-x86/e820.h +101 -2
@@ -30,9 +30,108 @@ struct e820map {#ifdef __KERNEL__#ifdef CONFIG_X86_32 -# include "e820_32.h" +/* +* structures and definitions for the int 15, ax=e820 memory map +* scheme. +* +* In a nutshell, arch/i386/boot/setup.S populates a scratch table +* in the empty_zero_block that contains a list of usable address/size +* duples. In arch/i386/kernel/setup.c, this information is +* transferred into the e820map, and in arch/i386/mm/init.c, that +* new information is used to mark pages reserved or not. +* +*/ +#include <linux/ioport.h> + +#define HIGH_MEMORY (1024*1024) + +#ifndef __ASSEMBLY__ + +extern void setup_memory_map (void ); +extern void finish_e820_parsing (void ); + +extern struct e820map e820; +extern void update_e820 (void ); + +extern int e820_all_mapped (unsigned long start,unsigned long end, +unsigned type); +extern int e820_any_mapped (u64 start,u64 end,unsigned type); +extern void propagate_e820_map (void ); +extern void register_bootmem_low_pages (unsigned long max_low_pfn); +extern void add_memory_region (unsigned long long start, +unsigned long long size,int type); +extern u64 update_memory_range (u64 start,u64 size,unsigned old_type, +unsigned new_type); +extern void e820_register_memory (void ); +extern void limit_regions (unsigned long long size); +extern void print_memory_map (char *who); +extern void init_iomem_resources (struct resource *code_resource, +struct resource *data_resource, +struct resource *bss_resource); + +#if defined(CONFIG_PM ) && defined(CONFIG_HIBERNATION ) +extern void e820_mark_nosave_regions (void );#else -# include "e820_64.h" +static inline void e820_mark_nosave_regions (void ) +{ +} +#endif + + +#endif /*!__ASSEMBLY__*/ +#else /* X86_32 */ +/* +* structures and definitions for the int 15, ax=e820 memory map +* scheme. +* +* In a nutshell, setup.S populates a scratch table in the +* empty_zero_block that contains a list of usable address/size +* duples. setup.c, this information is transferred into the e820map, +* and in init.c/numa.c, that new information is used to mark pages +* reserved or not. +*/ +#include <linux/ioport.h> + +#ifndef __ASSEMBLY__ +extern unsigned long find_e820_area (unsigned long start,unsigned long end, +unsigned long size,unsigned long align); +extern unsigned long find_e820_area_size (unsigned long start, +unsigned long *sizep, +unsigned long align); +extern void add_memory_region (unsigned long start,unsigned long size, +int type); +extern u64 update_memory_range (u64 start,u64 size,unsigned old_type, +unsigned new_type); +extern void setup_memory_region (void ); +extern void contig_e820_setup (void ); +extern unsigned long e820_end_of_ram (void ); +extern void e820_reserve_resources (void ); +extern void e820_mark_nosave_regions (void ); +extern int e820_any_mapped (unsigned long start,unsigned long end, +unsigned type); +extern int e820_all_mapped (unsigned long start,unsigned long end, +unsigned type); +extern int e820_any_non_reserved (unsigned long start,unsigned long end); +extern int is_memory_any_valid (unsigned long start,unsigned long end); +extern int e820_all_non_reserved (unsigned long start,unsigned long end); +extern int is_memory_all_valid (unsigned long start,unsigned long end); +extern unsigned long e820_hole_size (unsigned long start,unsigned long end); + +extern void e820_setup_gap (void ); +extern void e820_register_active_regions (int nid,unsigned long start_pfn, +unsigned long end_pfn); + +extern void finish_e820_parsing (void ); + +extern struct e820map e820; +extern void update_e820 (void ); + +extern void reserve_early (unsigned long start,unsigned long end,char *name); +extern void free_early (unsigned long start,unsigned long end); +extern void early_res_to_bootmem (unsigned long start,unsigned long end); + +#endif /*!__ASSEMBLY__*/ +#endif #endif /* __KERNEL__ */
include/asm-x86/e820_32.h deleted +0 -50
50 lines not on this page · raw message
include/asm-x86/e820_64.h deleted +0 -56
56 lines not on this page · raw message
PATCH 3/6 x86: e820 unification: Extract shared comments
In reply to Christoph LameterThe introductory comments are basically the same. Take the 64 bit version.
--- include/asm-x86/e820.h | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-)
include/asm-x86/e820.h +7 -19
@@ -29,20 +29,20 @@ struct e820map {#define BIOS_END 0x00100000#ifdef __KERNEL__ -#ifdef CONFIG_X86_32 +/* * structures and definitions for the int 15, ax=e820 memory map * scheme. * -* In a nutshell, arch/i386/boot/setup.S populates a scratch table -* in the empty_zero_block that contains a list of usable address/size -* duples. In arch/i386/kernel/setup.c, this information is -* transferred into the e820map, and in arch/i386/mm/init.c, that -* new information is used to mark pages reserved or not. -* +* In a nutshell, setup.S populates a scratch table in the +* empty_zero_block that contains a list of usable address/size +* duples. setup.c, this information is transferred into the e820map, +* and in init.c/numa.c, that new information is used to mark pages +* reserved or not. */ #include <linux/ioport.h> +#ifdef CONFIG_X86_32 #define HIGH_MEMORY (1024*1024)#ifndef __ASSEMBLY__
@@ -80,18 +80,6 @@ static inline void e820_mark_nosave_regi#endif /*!__ASSEMBLY__*/ #else /* X86_32 */ -/* -* structures and definitions for the int 15, ax=e820 memory map -* scheme. -* -* In a nutshell, setup.S populates a scratch table in the -* empty_zero_block that contains a list of usable address/size -* duples. setup.c, this information is transferred into the e820map, -* and in init.c/numa.c, that new information is used to mark pages -* reserved or not. -*/ -#include <linux/ioport.h> -#ifndef __ASSEMBLY__extern unsigned long find_e820_area (unsigned long start,unsigned long end,unsigned long size,unsigned long align);
PATCH 4/6 x86: e820 unification: Common #ifdef __ASSEMBLY
In reply to Christoph LameterBoth include files use #ifdef __ASSEMBLY__ which can be moved outside of the #ifdef CONFIG_X86_32.
--- include/asm-x86/e820.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
include/asm-x86/e820.h +3 -7
@@ -42,11 +42,11 @@ struct e820map {*/ #include <linux/ioport.h> +#ifndef __ASSEMBLY__ +#ifdef CONFIG_X86_32 #define HIGH_MEMORY (1024*1024) -#ifndef __ASSEMBLY__ -extern void setup_memory_map (void );extern void finish_e820_parsing (void );
@@ -77,10 +77,7 @@ static inline void e820_mark_nosave_regi }#endif - -#endif /*!__ASSEMBLY__*/ #else /* X86_32 */ -#ifndef __ASSEMBLY__extern unsigned long find_e820_area (unsigned long start,unsigned long end,unsigned long size,unsigned long align); extern unsigned long find_e820_area_size(unsigned long start,
@@ -118,9 +115,8 @@ extern void reserve_early(unsigned longextern void free_early (unsigned long start,unsigned long end);extern void early_res_to_bootmem (unsigned long start,unsigned long end); +#endif /* X86_32 */ #endif /*!__ASSEMBLY__*/ - -#endif #endif /* __KERNEL__ */ #endif /* __ASM_E820_H */
PATCH 5/6 x86: e820 unification: Extract common functions
In reply to Christoph LameterExtract the common functions to the common area.
The parameters of e820_any_mapped vary between 32 and 64 bit. Convert them to u64 so that they match.
Same issue is there for add_memory_region(). 32 bit uses unsigned long long there. Convert both platforms to use u64.
--- arch/x86/kernel/e820_32.c | 3 -- arch/x86/kernel/e820_64.c | 4 +-- include/asm-x86/e820.h | 50 ++++++++++++++++------------------------------ 3 files changed, 21 insertions(+), 36 deletions(-)
include/asm-x86/e820.h +18 -32
@@ -44,32 +44,18 @@ struct e820map {#ifndef __ASSEMBLY__ -#ifdef CONFIG_X86_32 -#define HIGH_MEMORY (1024*1024) - -extern void setup_memory_map (void );extern void finish_e820_parsing (void ); -extern struct e820map e820;extern void update_e820 (void ); -extern int e820_all_mapped (unsigned long start,unsigned long end,unsigned type);extern int e820_any_mapped (u64 start,u64 end,unsigned type); -extern void propagate_e820_map (void ); -extern void register_bootmem_low_pages (unsigned long max_low_pfn); -extern void add_memory_region (unsigned long long start, -unsigned long long size,int type); -extern u64 update_memory_range (u64 start,u64 size,unsigned old_type, +extern void add_memory_region (u64 start,u64 size,int type); +extern void update_memory_range (u64 start,u64 size,unsigned old_type,unsigned new_type); -extern void e820_register_memory (void ); -extern void limit_regions (unsigned long long size); -extern void print_memory_map (char *who); -extern void init_iomem_resources (struct resource *code_resource, -struct resource *data_resource, -struct resource *bss_resource); -#if defined(CONFIG_PM ) && defined(CONFIG_HIBERNATION ) +#if defined(CONFIG_X86_64 ) || \ + (defined(CONFIG_PM ) && defined(CONFIG_HIBERNATION ))extern void e820_mark_nosave_regions (void );#else static inline void e820_mark_nosave_regions (void )
@@ -77,25 +63,30 @@ static inline void e820_mark_nosave_regi }#endif +#ifdef CONFIG_X86_32 +#define HIGH_MEMORY (1024*1024) + +extern void setup_memory_map (void ); + +extern void propagate_e820_map (void ); +extern void register_bootmem_low_pages (unsigned long max_low_pfn); +extern void e820_register_memory (void ); +extern void limit_regions (unsigned long long size); +extern void print_memory_map (char *who); +extern void init_iomem_resources (struct resource *code_resource, +struct resource *data_resource, +struct resource *bss_resource); +#else /* X86_32 */ extern unsigned long find_e820_area (unsigned long start,unsigned long end,unsigned long size,unsigned long align);extern unsigned long find_e820_area_size (unsigned long start,unsigned long *sizep,unsigned long align); -extern void add_memory_region (unsigned long start,unsigned long size, -int type); -extern u64 update_memory_range (u64 start,u64 size,unsigned old_type, -unsigned new_type);extern void setup_memory_region (void );extern void contig_e820_setup (void );extern unsigned long e820_end_of_ram (void );extern void e820_reserve_resources (void ); -extern void e820_mark_nosave_regions (void ); -extern int e820_any_mapped (unsigned long start,unsigned long end, -unsigned type); -extern int e820_all_mapped (unsigned long start,unsigned long end, -unsigned type);extern int e820_any_non_reserved (unsigned long start,unsigned long end);extern int is_memory_any_valid (unsigned long start,unsigned long end);extern int e820_all_non_reserved (unsigned long start,unsigned long end);
@@ -106,11 +97,6 @@ extern void e820_setup_gap(void);extern void e820_register_active_regions (int nid,unsigned long start_pfn,unsigned long end_pfn); -extern void finish_e820_parsing (void ); - -extern struct e820map e820; -extern void update_e820 (void ); -extern void reserve_early (unsigned long start,unsigned long end,char *name);extern void free_early (unsigned long start,unsigned long end);extern void early_res_to_bootmem (unsigned long start,unsigned long end);
arch/x86/kernel/e820_64.c +2 -2
@@ -181,7 +181,7 @@ again:* with type. */ int -e820_any_mapped (unsigned long start,unsigned long end,unsigned type) +e820_any_mapped (u64 start,u64 end,unsigned type) {int i;
@@ -437,7 +437,7 @@ e820_register_active_regions(int nid, un/* * Add a memory region to the kernel e820 map. */ -void __init add_memory_region (unsigned long start,unsigned long size,int type) +void __init add_memory_region (u64 start,u64 size,int type) {int x = e820.nr_map;
arch/x86/kernel/e820_32.c +1 -2
@@ -255,8 +255,7 @@ void __init e820_mark_nosave_regions(voi }#endif -void __init add_memory_region (unsigned long long start, -unsigned long long size,int type) +void __init add_memory_region (u64 start,u64 size,int type) {int x;
PATCH 6/6 x86: Add checks for virtual addresses in __phys_addr()
In reply to Christoph LameterAdd checks to insure that virtual addresses are not used in invalid contexts.
--- arch/x86/mm/ioremap.c | 15 +++++++-------- include/asm-x86/page_32.h | 7 ++++++- 2 files changed, 13 insertions(+), 9 deletions(-)
arch/x86/mm/ioremap.c +7 -8
@@ -21,29 +21,28 @@#include <asm/pgalloc.h> #include <asm/pat.h> -#ifdef CONFIG_X86_64 +#if defined(CONFIG_DEBUG_VM ) || defined(CONFIG_X86_64 )unsigned long __phys_addr (unsigned long x) { +VM_BUG_ON (is_vmalloc_addr ((void *)x)); +#ifdef CONFIG_X86_64 if (x >= __START_KERNEL_map)return x - __START_KERNEL_map + phys_base; +#endif return x -PAGE_OFFSET ; }EXPORT_SYMBOL (__phys_addr); +#endif static inline int phys_addr_valid (unsigned long addr) { +#ifdef CONFIG_X86_64 return addr < (1UL << boot_cpu_data.x86_phys_bits); -} -#else - -static inline int phys_addr_valid (unsigned long addr) -{return 1 ; -} -#endif +}int page_is_ram (unsigned long pagenr) {
include/asm-x86/page_32.h +6 -1
@@ -64,7 +64,12 @@ typedef struct page *pgtable_t;#endif #ifndef __ASSEMBLY__ -#define __phys_addr (x) ((x) - PAGE_OFFSET) +#ifdef CONFIG_DEBUG_VM +unsigned long __phys_addr(unsigned long x) +#else +#define __phys_addr (x) ((x) - PAGE_OFFSET) +#endif +#define __phys_reloc_hide (x) RELOC_HIDE((x), 0)#ifdef CONFIG_FLATMEM
Re: [patch 6/6] x86: Add checks for virtual addresses in __phys_addr()
Quoted 55 lines · Christoph Lameter
Add checks to insure that virtual addresses are not used in invalid contexts.
Signed-off-by Christoph Lameter <[email protected]>--- arch/x86/mm/ioremap.c | 15 +++++++-------- include/asm-x86/page_32.h | 7 ++++++- 2 files changed, 13 insertions(+), 9 deletions(-)Index:
linux-2.6/arch/x86/mm/ioremap.c
===================================================================arch/x86/mm/ioremap.c +7
-8@@ -21,29 +21,28 @@#include <asm/pgalloc.h> #include <asm/pat.h> -#ifdef CONFIG_X86_64 +#if defined(CONFIG_DEBUG_VM ) || defined(CONFIG_X86_64 )unsigned long __phys_addr (unsigned long x) { +VM_BUG_ON (is_vmalloc_addr ((void *)x)); +#ifdef CONFIG_X86_64 if (x >= __START_KERNEL_map)return x - __START_KERNEL_map + phys_base; +#endif return x -PAGE_OFFSET ; }EXPORT_SYMBOL (__phys_addr); +#endif static inline int phys_addr_valid (unsigned long addr) { +#ifdef CONFIG_X86_64 return addr < (1UL << boot_cpu_data.x86_phys_bits); -} -#else - -static inline int phys_addr_valid (unsigned long addr) -{return 1 ; -} -#endif +}int page_is_ram (unsigned long pagenr) {Index:
linux-2.6/include/asm-x86/page_32.h
===================================================================
include/asm-x86/page_32.h typedef struct page *pgtable_t; · line 68
Quoted 6 lines
include/asm-x86/page_32.h +2
-1@@ -64,7 +64,12 @@ typedef struct page *pgtable_t;#endif #ifndef __ASSEMBLY__ -#define __phys_addr (x) ((x) - PAGE_OFFSET) +#ifdef CONFIG_DEBUG_VM +unsigned long __phys_addr (unsigned long x)
Should this have read:
include/asm-x86/page_32.h typedef struct page *pgtable_t; · line 69
Quoted 1 line
include/asm-x86/page_32.h +1
-0+extern unsigned long __phys_addr (unsigned long x);
?
Looks like a prototype with a missing ';'.
And x86 uses extern for prototypes in .h files (most of the time).
Sam
Re: [patch 6/6] x86: Add checks for virtual addresses in __phys_addr()
Quoted 7 lines · Sam Ravnborg
Should this have read:
Quoted 1 line
+extern unsigned long
__phys_addr(unsigned long x);?
Looks like a prototype with a missing ';'.
And x86 uses extern for prototypes in .h files (most of the time).
Right. And this means that I did not test a 32 bit config with CONFIG_VM_DEBUG on this one. The run of the mill stuff did not do it. Sigh.
This patch fixes the compile:
--- include/asm-x86/page_32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/asm-x86/page_32.h +1 -1
@@ -65,7 +65,7 @@ typedef struct page *pgtable_t;#ifndef __ASSEMBLY__#ifdef CONFIG_DEBUG_VM -unsigned long __phys_addr(unsigned long x) +extern unsigned long __phys_addr (unsigned long x);#else #define __phys_addr (x) ((x) - PAGE_OFFSET)#endif
Re: [patch 6/6] x86: Add checks for virtual addresses in __phys_addr()
We also need to address this issue with __pa expected to be a constant in 32 bit code. Sigh.
--- arch/x86/kernel/doublefault_32.c | 2 +- include/asm-x86/page_32.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
include/asm-x86/page_32.h +1 -1
@@ -65,7 +65,7 @@ typedef struct page *pgtable_t;#ifndef __ASSEMBLY__#ifdef CONFIG_DEBUG_VM -unsigned long __phys_addr(unsigned long x) +extern unsigned long __phys_addr (unsigned long x);#else #define __phys_addr (x) ((x) - PAGE_OFFSET)#endif
arch/x86/kernel/doublefault_32.c +1 -1
@@ -66,6 +66,6 @@ struct tss_struct doublefault_tss __cach .ds = __USER_DS, .fs = __KERNEL_PERCPU, - .__cr3 = __pa(swapper_pg_dir) + .__cr3 = (unsigned long)swapper_pg_dir - PAGE_OFFSET } };
Re: [patch 6/6] x86: Add checks for virtual addresses in __phys_addr()
Quoted 2 lines · Christoph Lameter
We also need to address this issue with
__paexpected to be a constant in 32 bit code. Sigh.
hm, even with all the fixlets it breaks with:
http://redhat.com/~mingo/misc/config-Tue_May_13_14_17_44_CEST_2008.bad
arch/x86/kernel/e820_32.c:586: error: static declaration of 'print_memory_map' follows non-static declaration include/asm/e820.h:75: error: previous declaration of 'print_memory_map' was here
Ingo