Clean up asm/bugs.h, identify_cpu() and update COMPAT_VDSO
Subsystems (3)
cover Clean up asm/bugs.h, identify_cpu() and update COMPAT_VDSO
Hi Andi,
Four patches:
- clean up asm/bugs.h, by moving all the C code into its own C file
- split identify_cpu() into boot and secondary variants, so that boot-time setup functions can be marked __init
- repost of the COMPAT_VDSO patches with a bit more robustness from unknown DT_tags, and functions marked __init, since all this is boot-time only setup.
Thanks,
J
PATCH 1/4 Clean up asm-i386/bugs.h
Most of asm-i386/bugs.h is code which should be in a C file, so put it there.
--- arch/i386/kernel/cpu/Makefile | 2 arch/i386/kernel/cpu/bugs.c | 191 +++++++++++++++++++++++++++++++++++++++ include/asm-i386/alternative.h | 1 include/asm-i386/bugs.h | 194 ---------------------------------------- 4 files changed, 197 insertions(+), 191 deletions(-)
===================================================================
arch/i386/kernel/cpu/Makefile +1 -1
@@ -2,7 +2,7 @@ # Makefile for x86-compatible CPU details and quirks # -obj-y := common.o proc.o +obj-y := common.o proc.o bugs.o obj-y += amd.o obj-y += cyrix.o
===================================================================
arch/i386/kernel/cpu/bugs.c new file +191 -0
191 lines not on this page · raw message
===================================================================
include/asm-i386/alternative.h +1 -0
@@ -14,6 +14,7 @@ struct alt_instr {u8 pad; }; +extern void alternative_instructions (void );extern void apply_alternatives (struct alt_instr *start,struct alt_instr *end);struct module ;
===================================================================
include/asm-i386/bugs.h +4 -190
202 lines not on this page · raw message
PATCH 2/4 clean up identify_cpu
In reply to Jeremy Fitzhardingeidentify_cpu() is used to identify both the boot CPU and secondary CPUs, but it performs some actions which only apply to the boot CPU. Those functions are therefore really __init functions, but because they're called by identify_cpu(), they must be marked __cpuinit.
This patch splits identify_cpu() into identify_boot_cpu() and identify_secondary_cpu(), and calls the appropriate init functions from each. Also, identify_boot_cpu() and all the functions it dominates are marked __init.
--- arch/i386/kernel/cpu/common.c | 25 ++++++++++++++++--------- arch/i386/kernel/cpu/mtrr/main.c | 4 ++-- arch/i386/kernel/smpboot.c | 2 +- arch/i386/kernel/sysenter.c | 2 +- include/asm-i386/processor.h | 3 ++- 5 files changed, 22 insertions(+), 14 deletions(-)
===================================================================
arch/i386/kernel/cpu/common.c +16 -9
@@ -390,7 +390,7 @@ __setup("serialnumber", x86_serial_nr_se/* * This does the hard work of actually picking apart the CPU stuff... */ -void __cpuinit identify_cpu (struct cpuinfo_x86 *c) +static void __cpuinit identify_cpu (struct cpuinfo_x86 *c) {int i;
@@ -501,15 +501,22 @@ void __cpuinit identify_cpu(struct cpuin/* Init Machine Check Exception if available. */ mcheck_init (c); - -if (c == &boot_cpu_data) -sysenter_setup (); +} + +void __init identify_boot_cpu (void ) +{ +identify_cpu (&boot_cpu_data); +sysenter_setup ();enable_sep_cpu (); - -if (c == &boot_cpu_data) -mtrr_bp_init (); -else -mtrr_ap_init (); +mtrr_bp_init (); +} + +void __cpuinit identify_secondary_cpu (struct cpuinfo_x86 *c) +{ +BUG_ON (c == &boot_cpu_data); +identify_cpu (c); +enable_sep_cpu (); +mtrr_ap_init (); }#ifdef CONFIG_X86_HT
===================================================================
arch/i386/kernel/cpu/mtrr/main.c +2 -2
@@ -571,7 +571,7 @@ extern void cyrix_init_mtrr(void);extern void cyrix_init_mtrr (void );extern void centaur_init_mtrr (void ); -static void __cpuinit init_ifs (void ) +static void __init init_ifs (void ) {#ifndef CONFIG_X86_64 amd_init_mtrr ();
@@ -639,7 +639,7 @@ static struct sysdev_driver mtrr_sysdev_* initialized (i.e. before smp_init()). * */ -void __cpuinit mtrr_bp_init (void ) +void __init mtrr_bp_init (void ) {init_ifs ();
===================================================================
arch/i386/kernel/smpboot.c +1 -1
@@ -157,7 +157,7 @@ static void __cpuinit smp_store_cpu_info *c = boot_cpu_data;if (id!=0 ) -identify_cpu (c); +identify_secondary_cpu (c);/* * Mask B, Pentium, but not Pentium MMX */
===================================================================
arch/i386/kernel/sysenter.c +1 -1
@@ -68,7 +68,7 @@ extern const char vsyscall_sysenter_starextern const char vsyscall_sysenter_start, vsyscall_sysenter_end;static struct page *syscall_pages[1 ]; -int __cpuinit sysenter_setup (void ) +int __init sysenter_setup (void ) {void *syscall_page = (void *)get_zeroed_page (GFP_ATOMIC ); syscall_pages[0 ] =virt_to_page (syscall_page);
===================================================================
include/asm-i386/processor.h +2 -1
@@ -116,7 +116,8 @@ extern char ignore_fpu_irq;void __init cpu_detect (struct cpuinfo_x86 *c); -extern void identify_cpu (struct cpuinfo_x86 *); +extern void identify_boot_cpu (void ); +extern void identify_secondary_cpu (struct cpuinfo_x86 *);extern void print_cpu_info (struct cpuinfo_x86 *);extern unsigned int init_intel_cacheinfo (struct cpuinfo_x86 *c);extern unsigned short num_cache_leaves;
Re: [patch 2/4] clean up identify_cpu
Quoted 9 lines · On Fri, 06 Apr 2007 15:41:54 -0700 Jeremy Fitzhardinge <[email protected]> wrote:
identify_cpu()is used to identify both the boot CPU and secondary CPUs, but it performs some actions which only apply to the boot CPU. Those functions are therefore really__initfunctions, but because they're called byidentify_cpu(), they must be marked__cpuinit.This patch splits
identify_cpu()intoidentify_boot_cpu()andidentify_secondary_cpu(), and calls the appropriate init functions from each. Also,identify_boot_cpu()and all the functions it dominates are marked__init.
x86_64 uses this too.
WARNING: arch/x86_64/kernel/built-in.o - Section mismatch: reference to .init.text:mtrr_bp_init from .text.identify_cpu after 'identify_cpu' (at offset 0x655)
Re: [patch 2/4] clean up identify_cpu
Quoted 4 lines · Andrew Morton
x86_64uses this too.WARNING:
arch/x86_64/kernel/built-in.o- Section mismatch: reference to .init.text:mtrr_bp_init from .text.identify_cpu after 'identify_cpu' (at offset0x655)
OK, two patches to follow: a x86-64 variant of the bugs.h cleanup, and a replacement for this patch. I don't have a x86-64 compile environment on hand, so the 64 bits are completely untested, but they *look* they should work.
J
Re: [patch 2/4] clean up identify_cpu
Quoted 2 lines · On Sat, 07 Apr 2007 10:20:17 -0700 Jeremy Fitzhardinge <[email protected]> wrote:
I don't have a x86-64 compile environment on
hand, so the 64 bits are completely untested
Re: [patch 2/4] clean up identify_cpu
Quoted 6 lines · Andrew Morton
Quoted 2 lines · On Sat, 07 Apr 2007 10:20:17 -0700 Jeremy Fitzhardinge <[email protected]> wrote:
I don't have a x86-64 compile environment on
hand, so the 64 bits are completely untested
Does the alpha toolchain work for you?
For defconfig I get:
CC arch/alpha/kernel/core_cia.o
{standard input}: Assembler messages:
{standard input}:351: Error: macro requires $at register while noat in effect {standard input}:376: Error: macro requires $at register while noat in effect {standard input}:400: Error: macro requires $at register while noat in effect {standard input}:419: Error: macro requires $at register while noat in effect {standard input}:474: Error: macro requires $at register while noat in effect {standard input}:499: Error: macro requires $at register while noat in effect {standard input}:523: Error: macro requires $at register while noat in effect {standard input}:542: Error: macro requires $at register while noat in effect make[2]: *** [arch/alpha/kernel/core_cia.o] Error 1
make[1]: *** [arch/alpha/kernel] Error 2
make: *** [_all] Error 2
Same happens when I compile the same version direct from Dan's crosstool.
Sam
Re: [patch 2/4] clean up identify_cpu
Quoted 9 lines · On Sat, 7 Apr 2007 20:39:16 +0200 Sam Ravnborg <[email protected]> wrote:
Quoted 6 lines · Andrew Morton
Quoted 2 lines · On Sat, 07 Apr 2007 10:20:17 -0700 Jeremy Fitzhardinge <[email protected]> wrote:
I don't have a x86-64 compile environment on
hand, so the 64 bits are completely untestedDoes the alpha toolchain work for you?
Seems not.
Quoted 15 lines
For defconfig I get:
CCarch/alpha/kernel/core_cia.o
{standard input}: Assembler messages:
{standard input}:351: Error: macro requires $at register while noat in effect {standard input}:376: Error: macro requires $at register while noat in effect {standard input}:400: Error: macro requires $at register while noat in effect {standard input}:419: Error: macro requires $at register while noat in effect {standard input}:474: Error: macro requires $at register while noat in effect {standard input}:499: Error: macro requires $at register while noat in effect {standard input}:523: Error: macro requires $at register while noat in effect {standard input}:542: Error: macro requires $at register while noat in effect make[2]: *** [arch/alpha/kernel/core_cia.o] Error 1
make[1]: *** [arch/alpha/kernel] Error 2
make: *** [_all] Error 2
Quoted 2 lines
Same happens when I compile the same version direct from Dan's crosstool.
Me too. I always do allmodconfig with alpha, and allmodconfig doesn't include that file.
PATCH 3/4 Relocate VDSO ELF headers to match mapped location with COMPAT_VDSO
In reply to Jeremy FitzhardingeSome versions of libc can't deal with a VDSO which doesn't have its ELF headers matching its mapped address. COMPAT_VDSO maps the VDSO at a specific system-wide fixed address. Previously this was all done at build time, on the grounds that the fixed VDSO address is always at the top of the address space. However, a hypervisor may reserve some of that address space, pushing the fixmap address down.
This patch does the adjustment dynamically at runtime, depending on the runtime location of the VDSO fixmap.
[ Patch has been through several hands: Jan Beulich wrote the orignal
version; Zach reworked it, and Jeremy converted it to relocate phdrs as well as sections. ]
--- arch/i386/kernel/entry.S | 4 - arch/i386/kernel/sysenter.c | 170 +++++++++++++++++++++++++++++++++++++++---- arch/i386/mm/pgtable.c | 6 - include/asm-i386/elf.h | 28 ++----- include/asm-i386/fixmap.h | 8 -- include/linux/elf.h | 17 ++++ 6 files changed, 184 insertions(+), 49 deletions(-)
===================================================================
arch/i386/kernel/entry.S +0 -4
@@ -305,16 +305,12 @@ sysenter_past_esp: pushl $(__USER_CS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET cs, 0*/ -#ifndef CONFIG_COMPAT_VDSO /* * Push current_thread_info()->sysenter_return to the stack. * A tiny bit of offset fixup is necessary - 4*4 means the 4 words * pushed above; +8 corresponds to copy_thread's esp0 setting. */ pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) -#else - pushl $SYSENTER_RETURN -#endif CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eip, 0
===================================================================
arch/i386/kernel/sysenter.c +155 -15
200 lines not on this page · raw message
===================================================================
arch/i386/mm/pgtable.c +0 -6
@@ -144,10 +144,8 @@ void set_pmd_pfn(unsigned long vaddr, un }static int fixmaps; -#ifndef CONFIG_COMPAT_VDSO unsigned long __FIXADDR_TOP =0xfffff000 ;EXPORT_SYMBOL (__FIXADDR_TOP); -#endif void __set_fixmap (enum fixed_addresses idx,unsigned long phys,pgprot_t flags) {
@@ -173,12 +171,8 @@ void reserve_top_address(unsigned long rBUG_ON (fixmaps >0 );printk (KERN_INFO "Reserving virtual address space above 0x%08x\n" , (int )-reserve); -#ifdef CONFIG_COMPAT_VDSO -BUG_ON (reserve !=0 ); -#else __FIXADDR_TOP = -reserve -PAGE_SIZE ; __VMALLOC_RESERVE += reserve; -#endif }pte_t *pte_alloc_one_kernel (struct mm_struct *mm,unsigned long address)
===================================================================
include/asm-i386/elf.h +10 -18
@@ -133,39 +133,31 @@ extern int dump_task_extended_fpu (struc#define ELF_CORE_COPY_XFPREGS (tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)#define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) -#define VDSO_BASE ((unsigned long)current->mm->context.vdso) - -#ifdef CONFIG_COMPAT_VDSO -# define VDSO_COMPAT_BASE VDSO_HIGH_BASE -# define VDSO_PRELINK VDSO_HIGH_BASE -#else -# define VDSO_COMPAT_BASE VDSO_BASE -# define VDSO_PRELINK 0 -#endif +#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) +#define VDSO_PRELINK 0#define VDSO_SYM (x) \ - (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) + (VDSO_CURRENT_BASE + (unsigned long)(x) - VDSO_PRELINK)#define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) -#define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE) +#define VDSO_EHDR ((const struct elfhdr *) VDSO_CURRENT_BASE)extern void __kernel_vsyscall;#define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) -#ifndef CONFIG_COMPAT_VDSO +struct linux_binprm ; +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES -struct linux_binprm ;extern int arch_setup_additional_pages (struct linux_binprm *bprm,int executable_stack); -#endif extern unsigned int vdso_enabled; -#define ARCH_DLINFO \ -do if (vdso_enabled) { \ - NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \ +#define ARCH_DLINFO \ +do if (vdso_enabled) { \ + NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ } while (0)#endif
===================================================================
include/asm-i386/fixmap.h +2 -6
@@ -19,13 +19,9 @@* Leave one empty page between vmalloc'ed areas and * the start of the fixmap. */ -#ifndef CONFIG_COMPAT_VDSO extern unsigned long __FIXADDR_TOP; -#else -#define __FIXADDR_TOP 0xfffff000 -#define FIXADDR_USER_START __fix_to_virt(FIX_VDSO) -#define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1) -#endif +#define FIXADDR_USER_START __fix_to_virt(FIX_VDSO) +#define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1)#ifndef __ASSEMBLY__#include <linux/kernel.h>
===================================================================
include/linux/elf.h +17 -0
@@ -83,6 +83,23 @@ typedef __s64 Elf64_Sxword;#define DT_DEBUG 21#define DT_TEXTREL 22#define DT_JMPREL 23 +#define DT_ENCODING 32 +#define OLD_DT_LOOS 0x60000000 +#define DT_LOOS 0x6000000d +#define DT_HIOS 0x6ffff000 +#define DT_VALRNGLO 0x6ffffd00 +#define DT_VALRNGHI 0x6ffffdff +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_VERSYM 0x6ffffff0 +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa +#define DT_FLAGS_1 0x6ffffffb +#define DT_VERDEF 0x6ffffffc +#define DT_VERDEFNUM 0x6ffffffd +#define DT_VERNEED 0x6ffffffe +#define DT_VERNEEDNUM 0x6fffffff +#define OLD_DT_HIOS 0x6fffffff#define DT_LOPROC 0x70000000#define DT_HIPROC 0x7fffffff
PATCH 4/4 Make COMPAT_VDSO runtime selectable.
In reply to Jeremy FitzhardingeNow that relocation of the VDSO for COMPAT_VDSO users is done at runtime rather than compile time, it is possible to enable/disable compat mode at runtime.
This patch allows you to enable COMPAT_VDSO mode with "vdso=2" on the kernel command line, or via sysctl. (Switching on a running system shouldn't be done lightly; any process which was relying on the compat VDSO will be upset if it goes away.)
The COMPAT_VDSO config option still exists, but if enabled it just makes vdso_enabled default to VDSO_COMPAT.
--- Documentation/kernel-parameters.txt | 1 arch/i386/kernel/sysenter.c | 141 +++++++++++++++++++++++------------ include/asm-i386/page.h | 2 3 files changed, 94 insertions(+), 50 deletions(-)
===================================================================
Documentation/kernel-parameters.txt +1 -0
@@ -1807,6 +1807,7 @@ and is between 256 and 4096 characters. [USBHID] The interval which mice are to be polled at. vdso= [IA-32,SH] + vdso=2: enable compat VDSO (default with COMPAT_VDSO) vdso=1: enable VDSO (default) vdso=0: disable VDSO mapping
===================================================================
arch/i386/kernel/sysenter.c +93 -48
210 lines not on this page · raw message
===================================================================
include/asm-i386/page.h +0 -2
@@ -143,9 +143,7 @@ extern int page_is_ram(unsigned long pag#include <asm-generic/memory_model.h> #include <asm-generic/page.h> -#ifndef CONFIG_COMPAT_VDSO #define __HAVE_ARCH_GATE_AREA 1 -#endif #endif /* __KERNEL__ */ #endif /* _I386_PAGE_H */