From df619e6bafeb8e129aba3173d384544d7fa6e3c2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:30:02 +0100 Subject: x86: offer is_hpet_enabled() on !CONFIG_HPET_TIMER too offer is_hpet_enabled() on !CONFIG_HPET_TIMER too. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/hpet.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h index ad8d6e75878..624f600f716 100644 --- a/include/asm-x86/hpet.h +++ b/include/asm-x86/hpet.h @@ -80,10 +80,11 @@ extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); #endif /* CONFIG_HPET_EMULATE_RTC */ -#else +#else /* CONFIG_HPET_TIMER */ static inline int hpet_enable(void) { return 0; } static inline unsigned long hpet_readl(unsigned long a) { return 0; } +static inline int is_hpet_enabled(void) { return 0; } -#endif /* CONFIG_HPET_TIMER */ +#endif #endif /* ASM_X86_HPET_H */ -- cgit v1.2.2 From 5c9c9bec0589be696c70c5efb448b17d5ab720e2 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 30 Jan 2008 13:30:04 +0100 Subject: x86: hibernation: document __save_processor_state() on x86 Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it. Sigend-off-by: Rafael J. Wysocki Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/suspend_64.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/suspend_64.h b/include/asm-x86/suspend_64.h index c505a76bcf6..4404668f9aa 100644 --- a/include/asm-x86/suspend_64.h +++ b/include/asm-x86/suspend_64.h @@ -15,7 +15,14 @@ arch_prepare_suspend(void) return 0; } -/* Image of the saved processor state. If you touch this, fix acpi/wakeup.S. */ +/* + * Image of the saved processor state, used by the low level ACPI suspend to + * RAM code and by the low level hibernation code. + * + * If you modify it, fix arch/x86/kernel/acpi/wakeup_64.S and make sure that + * __save/__restore_processor_state(), defined in arch/x86/kernel/suspend_64.c, + * still work as required. + */ struct saved_context { struct pt_regs regs; u16 ds, es, fs, gs, ss; -- cgit v1.2.2 From b02aae9cf52956dfe1bec73f77f81a3d05d3902b Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 30 Jan 2008 13:30:05 +0100 Subject: x86: provide a DMI based port 0x80 I/O delay override. x86: provide a DMI based port 0x80 I/O delay override. Certain (HP) laptops experience trouble from our port 0x80 I/O delay writes. This patch provides for a DMI based switch to the "alternate diagnostic port" 0xed (as used by some BIOSes as well) for these. David P. Reed confirmed that port 0xed works for him and provides a proper delay. The symptoms of _not_ working are a hanging machine, with "hwclock" use being a direct trigger. Earlier versions of this attempted to simply use udelay(2), with the 2 being a value tested to be a nicely conservative upper-bound with help from many on the linux-kernel mailinglist but that approach has two problems. First, pre-loops_per_jiffy calibration (which is post PIT init while some implementations of the PIT are actually one of the historically problematic devices that need the delay) udelay() isn't particularly well-defined. We could initialise loops_per_jiffy conservatively (and based on CPU family so as to not unduly delay old machines) which would sort of work, but... Second, delaying isn't the only effect that a write to port 0x80 has. It's also a PCI posting barrier which some devices may be explicitly or implicitly relying on. Alan Cox did a survey and found evidence that additionally some drivers may be racy on SMP without the bus locking outb. Switching to an inb() makes the timing too unpredictable and as such, this DMI based switch should be the safest approach for now. Any more invasive changes should get more rigid testing first. It's moreover only very few machines with the problem and a DMI based hack seems to fit that situation. This also introduces a command-line parameter "io_delay" to override the DMI based choice again: io_delay= where "standard" means using the standard port 0x80 and "alternate" port 0xed. This retains the udelay method as a config (CONFIG_UDELAY_IO_DELAY) and command-line ("io_delay=udelay") choice for testing purposes as well. This does not change the io_delay() in the boot code which is using the same port 0x80 I/O delay but those do not appear to be a problem as David P. Reed reported the problem was already gone after using the udelay version. He moreover reported that booting with "acpi=off" also fixed things and seeing as how ACPI isn't touched until after this DMI based I/O port switch I believe it's safe to leave the ones in the boot code be. The DMI strings from David's HP Pavilion dv9000z are in there already and we need to get/verify the DMI info from other machines with the problem, notably the HP Pavilion dv6000z. This patch is partly based on earlier patches from Pavel Machek and David P. Reed. Signed-off-by: Rene Herman Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/io_32.h | 8 ++++++-- include/asm-x86/io_64.h | 33 ++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 13 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index fe881cd1e6f..a8d25c38b91 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h @@ -250,10 +250,14 @@ static inline void flush_write_buffers(void) #endif /* __KERNEL__ */ -static inline void native_io_delay(void) +#ifndef CONFIG_UDELAY_IO_DELAY +extern void io_delay_init(void); +#else +static inline void io_delay_init(void) { - asm volatile("outb %%al,$0x80" : : : "memory"); } +#endif +extern void native_io_delay(void); #if defined(CONFIG_PARAVIRT) #include diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h index a037b079433..5bebaf96169 100644 --- a/include/asm-x86/io_64.h +++ b/include/asm-x86/io_64.h @@ -35,13 +35,24 @@ * - Arnaldo Carvalho de Melo */ -#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +#ifndef CONFIG_UDELAY_IO_DELAY +extern void io_delay_init(void); +#else +static inline void io_delay_init(void) +{ +} +#endif +extern void native_io_delay(void); +static inline void slow_down_io(void) +{ + native_io_delay(); #ifdef REALLY_SLOW_IO -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO -#else -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO + native_io_delay(); + native_io_delay(); + native_io_delay(); #endif +} /* * Talk about misusing macros.. @@ -50,21 +61,21 @@ static inline void out##s(unsigned x value, unsigned short port) { #define __OUT2(s,s1,s2) \ -__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" +__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" : : "a" (value), "Nd" (port)) #define __OUT(s,s1,x) \ -__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ -__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \ +__OUT1(s,x) __OUT2(s,s1,"w"); } \ +__OUT1(s##_p,x) __OUT2(s,s1,"w"); slow_down_io(); } #define __IN1(s) \ static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; #define __IN2(s,s1,s2) \ -__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" : "=a" (_v) : "Nd" (port)) -#define __IN(s,s1,i...) \ -__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ -__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +#define __IN(s,s1) \ +__IN1(s) __IN2(s,s1,"w"); return _v; } \ +__IN1(s##_p) __IN2(s,s1,"w"); slow_down_io(); return _v; } #define __INS(s) \ static inline void ins##s(unsigned short port, void * addr, unsigned long count) \ -- cgit v1.2.2 From 6e7c402590b75b6b45138792445ee0f0315a8473 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:30:05 +0100 Subject: x86: various changes and cleanups to in_p/out_p delay details various changes to the in_p/out_p delay details: - add the io_delay=none method - make each method selectable from the kernel config - simplify the delay code a bit by getting rid of an indirect function call - add the /proc/sys/kernel/io_delay_type sysctl - change 'io_delay=standard|alternate' to io_delay=0x80 and io_delay=0xed - make the io delay config not depend on CONFIG_DEBUG_KERNEL Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Tested-by: "David P. Reed" --- include/asm-x86/io_32.h | 10 +++------- include/asm-x86/io_64.h | 10 +++------- 2 files changed, 6 insertions(+), 14 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index a8d25c38b91..2a04bd17eac 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h @@ -250,15 +250,11 @@ static inline void flush_write_buffers(void) #endif /* __KERNEL__ */ -#ifndef CONFIG_UDELAY_IO_DELAY -extern void io_delay_init(void); -#else -static inline void io_delay_init(void) -{ -} -#endif extern void native_io_delay(void); +extern int io_delay_type; +extern void io_delay_init(void); + #if defined(CONFIG_PARAVIRT) #include #else diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h index 5bebaf96169..dbcc03aa1c6 100644 --- a/include/asm-x86/io_64.h +++ b/include/asm-x86/io_64.h @@ -35,15 +35,11 @@ * - Arnaldo Carvalho de Melo */ -#ifndef CONFIG_UDELAY_IO_DELAY -extern void io_delay_init(void); -#else -static inline void io_delay_init(void) -{ -} -#endif extern void native_io_delay(void); +extern int io_delay_type; +extern void io_delay_init(void); + static inline void slow_down_io(void) { native_io_delay(); -- cgit v1.2.2 From 53d517cdbaac704352b3d0c10fecb99e0b54572e Mon Sep 17 00:00:00 2001 From: Guillaume Chazarain Date: Wed, 30 Jan 2008 13:30:06 +0100 Subject: x86: scale cyc_2_nsec according to CPU frequency scale the sched_clock() cyc_2_nsec scaling factor according to CPU frequency changes. [ mingo@elte.hu: simplified it and fixed it for SMP. ] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/timer.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/timer.h b/include/asm-x86/timer.h index 0db7e994fb8..4f6fcb050c1 100644 --- a/include/asm-x86/timer.h +++ b/include/asm-x86/timer.h @@ -2,6 +2,7 @@ #define _ASMi386_TIMER_H #include #include +#include #define TICK_SIZE (tick_nsec / 1000) @@ -16,7 +17,7 @@ extern int recalibrate_cpu_khz(void); #define calculate_cpu_khz() native_calculate_cpu_khz() #endif -/* Accellerators for sched_clock() +/* Accelerators for sched_clock() * convert from cycles(64bits) => nanoseconds (64bits) * basic equation: * ns = cycles / (freq / ns_per_sec) @@ -31,20 +32,32 @@ extern int recalibrate_cpu_khz(void); * And since SC is a constant power of two, we can convert the div * into a shift. * - * We can use khz divisor instead of mhz to keep a better percision, since + * We can use khz divisor instead of mhz to keep a better precision, since * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. * (mathieu.desnoyers@polymtl.ca) * * -johnstul@us.ibm.com "math is hard, lets go shopping!" */ -extern unsigned long cyc2ns_scale __read_mostly; + +DECLARE_PER_CPU(unsigned long, cyc2ns); #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ -static inline unsigned long long cycles_2_ns(unsigned long long cyc) +static inline unsigned long long __cycles_2_ns(unsigned long long cyc) { - return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; + return cyc * per_cpu(cyc2ns, smp_processor_id()) >> CYC2NS_SCALE_FACTOR; } +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + unsigned long long ns; + unsigned long flags; + + local_irq_save(flags); + ns = __cycles_2_ns(cyc); + local_irq_restore(flags); + + return ns; +} #endif -- cgit v1.2.2 From e845c06bced7f5f325e0f9aefd3207cd45c21ff2 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:30:06 +0100 Subject: x86: add Create , with common definitions suitable for assembly unification. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/asm.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/asm-x86/asm.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/asm.h b/include/asm-x86/asm.h new file mode 100644 index 00000000000..b5006eb9acb --- /dev/null +++ b/include/asm-x86/asm.h @@ -0,0 +1,18 @@ +#ifndef _ASM_X86_ASM_H +#define _ASM_X86_ASM_H + +#ifdef CONFIG_X86_32 +/* 32 bits */ + +# define _ASM_PTR " .long " +# define _ASM_ALIGN " .balign 4 " + +#else +/* 64 bits */ + +# define _ASM_PTR " .quad " +# define _ASM_ALIGN " .balign 8 " + +#endif /* CONFIG_X86_32 */ + +#endif /* _ASM_X86_ASM_H */ -- cgit v1.2.2 From 7b11fb51567dedeaf6dc03f0135c0a8bb2399818 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:30:07 +0100 Subject: x86: unify asm/cpufeature.h asm/cpufeature.h was already almost unified; this completes the job. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 191 +++++++++++++++++++++++++++++++++++++++- include/asm-x86/cpufeature_32.h | 176 ------------------------------------ include/asm-x86/cpufeature_64.h | 30 ------- 3 files changed, 187 insertions(+), 210 deletions(-) delete mode 100644 include/asm-x86/cpufeature_32.h delete mode 100644 include/asm-x86/cpufeature_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index b7160a4598d..4c7875554d0 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -1,5 +1,188 @@ -#ifdef CONFIG_X86_32 -# include "cpufeature_32.h" -#else -# include "cpufeature_64.h" +/* + * Defines x86 CPU feature bits + */ +#ifndef _ASM_X86_CPUFEATURE_H +#define _ASM_X86_CPUFEATURE_H + +#ifndef __ASSEMBLY__ +#include #endif +#include + +#define NCAPINTS 8 /* N 32-bit words worth of info */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ +#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ +#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */ +#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */ +#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */ +#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */ +#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */ +#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */ +#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */ +#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */ +#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */ +#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */ +#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */ +#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */ +#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */ +#define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ +#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */ +#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ +#define X86_FEATURE_PN (0*32+18) /* Processor serial number */ +#define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ +#define X86_FEATURE_DS (0*32+21) /* Debug Store */ +#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ +#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ +#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ + /* of FPU context), and CR4.OSFXSR available */ +#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */ +#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */ +#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */ +#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */ +#define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */ +#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */ + +/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ +/* Don't duplicate feature flags which are redundant with Intel! */ +#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */ +#define X86_FEATURE_MP (1*32+19) /* MP Capable. */ +#define X86_FEATURE_NX (1*32+20) /* Execute Disable */ +#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ +#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */ +#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ +#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ +#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */ + +/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ +#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */ +#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */ +#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */ + +/* Other features, Linux-defined mapping, word 3 */ +/* This range is used for feature bits which conflict or are synthesized */ +#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */ +#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */ +#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ +#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ +/* cpu types for specific tunings: */ +#define X86_FEATURE_K8 (3*32+ 4) /* Opteron, Athlon64 */ +#define X86_FEATURE_K7 (3*32+ 5) /* Athlon */ +#define X86_FEATURE_P3 (3*32+ 6) /* P3 */ +#define X86_FEATURE_P4 (3*32+ 7) /* P4 */ +#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ +#define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */ +#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ +#define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */ +#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ +#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ +/* 14 free */ +#define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ +#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ +#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ +#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */ +#define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */ +#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */ +#define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */ +#define X86_FEATURE_CID (4*32+10) /* Context ID */ +#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ +#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ +#define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */ + +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ +#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ +#define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */ +#define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */ +#define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ +#define X86_FEATURE_ACE2 (5*32+ 8) /* Advanced Cryptography Engine v2 */ +#define X86_FEATURE_ACE2_EN (5*32+ 9) /* ACE v2 enabled */ +#define X86_FEATURE_PHE (5*32+ 10) /* PadLock Hash Engine */ +#define X86_FEATURE_PHE_EN (5*32+ 11) /* PHE enabled */ +#define X86_FEATURE_PMM (5*32+ 12) /* PadLock Montgomery Multiplier */ +#define X86_FEATURE_PMM_EN (5*32+ 13) /* PMM enabled */ + +/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ +#define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ +#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */ + +/* + * Auxiliary flags: Linux defined - For features scattered in various + * CPUID levels like 0x6, 0xA etc + */ +#define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */ + +#define cpu_has(c, bit) \ + (__builtin_constant_p(bit) && \ + ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \ + (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \ + (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \ + (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \ + (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \ + (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \ + (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \ + (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ) \ + ? 1 : \ + test_bit(bit, (c)->x86_capability)) +#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit) + +#define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) +#define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) +#define cpu_has_de boot_cpu_has(X86_FEATURE_DE) +#define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) +#define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) +#define cpu_has_pae boot_cpu_has(X86_FEATURE_PAE) +#define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) +#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC) +#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP) +#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR) +#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX) +#define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR) +#define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) +#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) +#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) +#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) +#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) +#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) +#define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR) +#define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR) +#define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR) +#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) +#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) +#define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT) +#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN) +#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2) +#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN) +#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE) +#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN) +#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM) +#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) +#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) +#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) +#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) +#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) + +#ifdef CONFIG_X86_64 + +#undef cpu_has_vme +#define cpu_has_vme 0 + +#undef cpu_has_pae +#define cpu_has_pae ___BUG___ + +#undef cpu_has_mp +#define cpu_has_mp 1 + +#undef cpu_has_k6_mtrr +#define cpu_has_k6_mtrr 0 + +#undef cpu_has_cyrix_arr +#define cpu_has_cyrix_arr 0 + +#undef cpu_has_centaur_mcr +#define cpu_has_centaur_mcr 0 + +#endif /* CONFIG_X86_64 */ + +#endif /* _ASM_X86_CPUFEATURE_H */ diff --git a/include/asm-x86/cpufeature_32.h b/include/asm-x86/cpufeature_32.h deleted file mode 100644 index f17e688dfb0..00000000000 --- a/include/asm-x86/cpufeature_32.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * cpufeature.h - * - * Defines x86 CPU feature bits - */ - -#ifndef __ASM_I386_CPUFEATURE_H -#define __ASM_I386_CPUFEATURE_H - -#ifndef __ASSEMBLY__ -#include -#endif -#include - -#define NCAPINTS 8 /* N 32-bit words worth of info */ - -/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ -#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ -#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */ -#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */ -#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */ -#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */ -#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */ -#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */ -#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */ -#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */ -#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */ -#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */ -#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */ -#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */ -#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */ -#define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ -#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */ -#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ -#define X86_FEATURE_PN (0*32+18) /* Processor serial number */ -#define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ -#define X86_FEATURE_DS (0*32+21) /* Debug Store */ -#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ -#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ -#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ - /* of FPU context), and CR4.OSFXSR available */ -#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */ -#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */ -#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */ -#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */ -#define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */ -#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */ - -/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ -/* Don't duplicate feature flags which are redundant with Intel! */ -#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */ -#define X86_FEATURE_MP (1*32+19) /* MP Capable. */ -#define X86_FEATURE_NX (1*32+20) /* Execute Disable */ -#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ -#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */ -#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ -#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ -#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */ - -/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ -#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */ -#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */ -#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */ - -/* Other features, Linux-defined mapping, word 3 */ -/* This range is used for feature bits which conflict or are synthesized */ -#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */ -#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */ -#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ -#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ -/* cpu types for specific tunings: */ -#define X86_FEATURE_K8 (3*32+ 4) /* Opteron, Athlon64 */ -#define X86_FEATURE_K7 (3*32+ 5) /* Athlon */ -#define X86_FEATURE_P3 (3*32+ 6) /* P3 */ -#define X86_FEATURE_P4 (3*32+ 7) /* P4 */ -#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ -#define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */ -#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ -#define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */ -#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ -#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ -/* 14 free */ -#define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ -#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ - -/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ -#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ -#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */ -#define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */ -#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */ -#define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */ -#define X86_FEATURE_CID (4*32+10) /* Context ID */ -#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ -#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ -#define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */ - -/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ -#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ -#define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */ -#define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */ -#define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ -#define X86_FEATURE_ACE2 (5*32+ 8) /* Advanced Cryptography Engine v2 */ -#define X86_FEATURE_ACE2_EN (5*32+ 9) /* ACE v2 enabled */ -#define X86_FEATURE_PHE (5*32+ 10) /* PadLock Hash Engine */ -#define X86_FEATURE_PHE_EN (5*32+ 11) /* PHE enabled */ -#define X86_FEATURE_PMM (5*32+ 12) /* PadLock Montgomery Multiplier */ -#define X86_FEATURE_PMM_EN (5*32+ 13) /* PMM enabled */ - -/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ -#define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ -#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */ - -/* - * Auxiliary flags: Linux defined - For features scattered in various - * CPUID levels like 0x6, 0xA etc - */ -#define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */ - -#define cpu_has(c, bit) \ - (__builtin_constant_p(bit) && \ - ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \ - (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \ - (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \ - (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \ - (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \ - (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \ - (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \ - (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ) \ - ? 1 : \ - test_bit(bit, (c)->x86_capability)) -#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit) - -#define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) -#define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) -#define cpu_has_de boot_cpu_has(X86_FEATURE_DE) -#define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) -#define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) -#define cpu_has_pae boot_cpu_has(X86_FEATURE_PAE) -#define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) -#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC) -#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP) -#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR) -#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX) -#define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR) -#define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) -#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) -#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) -#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) -#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) -#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) -#define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR) -#define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR) -#define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR) -#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) -#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) -#define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT) -#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN) -#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2) -#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN) -#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE) -#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN) -#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM) -#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) -#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) -#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) -#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) -#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) - -#endif /* __ASM_I386_CPUFEATURE_H */ - -/* - * Local Variables: - * mode:c - * comment-column:42 - * End: - */ diff --git a/include/asm-x86/cpufeature_64.h b/include/asm-x86/cpufeature_64.h deleted file mode 100644 index e18496b7b85..00000000000 --- a/include/asm-x86/cpufeature_64.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * cpufeature_32.h - * - * Defines x86 CPU feature bits - */ - -#ifndef __ASM_X8664_CPUFEATURE_H -#define __ASM_X8664_CPUFEATURE_H - -#include "cpufeature_32.h" - -#undef cpu_has_vme -#define cpu_has_vme 0 - -#undef cpu_has_pae -#define cpu_has_pae ___BUG___ - -#undef cpu_has_mp -#define cpu_has_mp 1 /* XXX */ - -#undef cpu_has_k6_mtrr -#define cpu_has_k6_mtrr 0 - -#undef cpu_has_cyrix_arr -#define cpu_has_cyrix_arr 0 - -#undef cpu_has_centaur_mcr -#define cpu_has_centaur_mcr 0 - -#endif /* __ASM_X8664_CPUFEATURE_H */ -- cgit v1.2.2 From 4edc8f5454814201d2fb222354284365b4f0537c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:13 +0100 Subject: x86: clean up include/asm-x86/desc_64.h White space and coding style clenaup. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/desc_64.h | 97 +++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 45 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 7d9c938e69f..bb2009ecbbc 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -1,4 +1,4 @@ -/* Written 2000 by Andi Kleen */ +/* Written 2000 by Andi Kleen */ #ifndef __ARCH_DESC_H #define __ARCH_DESC_H @@ -35,7 +35,7 @@ static inline unsigned long __store_tr(void) * something other than this. */ extern struct desc_struct default_ldt[]; -extern struct gate_struct idt_table[]; +extern struct gate_struct idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; /* the cpu gdt accessor */ @@ -51,40 +51,45 @@ static inline void store_gdt(struct desc_ptr *ptr) asm("sgdt %w0":"=m" (*ptr)); } -static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) +static inline void _set_gate(void *adr, unsigned type, unsigned long func, + unsigned dpl, unsigned ist) { - struct gate_struct s; - s.offset_low = PTR_LOW(func); + struct gate_struct s; + + s.offset_low = PTR_LOW(func); s.segment = __KERNEL_CS; - s.ist = ist; + s.ist = ist; s.p = 1; - s.dpl = dpl; + s.dpl = dpl; s.zero0 = 0; - s.zero1 = 0; - s.type = type; - s.offset_middle = PTR_MIDDLE(func); - s.offset_high = PTR_HIGH(func); - /* does not need to be atomic because it is only done once at setup time */ - memcpy(adr, &s, 16); -} - -static inline void set_intr_gate(int nr, void *func) -{ + s.zero1 = 0; + s.type = type; + s.offset_middle = PTR_MIDDLE(func); + s.offset_high = PTR_HIGH(func); + /* + * does not need to be atomic because it is only done once at + * setup time + */ + memcpy(adr, &s, 16); +} + +static inline void set_intr_gate(int nr, void *func) +{ BUG_ON((unsigned)nr > 0xFF); - _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0); -} + _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0); +} -static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) -{ +static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) +{ BUG_ON((unsigned)nr > 0xFF); - _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, ist); -} + _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, ist); +} -static inline void set_system_gate(int nr, void *func) -{ +static inline void set_system_gate(int nr, void *func) +{ BUG_ON((unsigned)nr > 0xFF); - _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); -} + _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); +} static inline void set_system_gate_ist(int nr, void *func, unsigned ist) { @@ -101,24 +106,25 @@ static inline void store_idt(struct desc_ptr *dtr) asm("sidt %w0":"=m" (*dtr)); } -static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, - unsigned size) -{ +static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, + unsigned type, unsigned size) +{ struct ldttss_desc d; - memset(&d,0,sizeof(d)); + + memset(&d, 0, sizeof(d)); d.limit0 = size & 0xFFFF; - d.base0 = PTR_LOW(tss); - d.base1 = PTR_MIDDLE(tss) & 0xFF; + d.base0 = PTR_LOW(tss); + d.base1 = PTR_MIDDLE(tss) & 0xFF; d.type = type; - d.p = 1; + d.p = 1; d.limit1 = (size >> 16) & 0xF; - d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; - d.base3 = PTR_HIGH(tss); - memcpy(ptr, &d, 16); + d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; + d.base3 = PTR_HIGH(tss); + memcpy(ptr, &d, 16); } static inline void set_tss_desc(unsigned cpu, void *addr) -{ +{ /* * sizeof(unsigned long) coming from an extra "long" at the end * of the iobitmap. See tss_struct definition in processor.h @@ -129,18 +135,18 @@ static inline void set_tss_desc(unsigned cpu, void *addr) set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_TSS], (unsigned long)addr, DESC_TSS, IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); -} +} static inline void set_ldt_desc(unsigned cpu, void *addr, int size) -{ +{ set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_LDT], (unsigned long)addr, DESC_LDT, size * 8 - 1); } #define LDT_entry_a(info) \ ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) -/* Don't allow setting of the lm bit. It is useless anyways because - 64bit system calls require __USER_CS. */ +/* Don't allow setting of the lm bit. It is useless anyways because + 64bit system calls require __USER_CS. */ #define LDT_entry_b(info) \ (((info)->base_addr & 0xff000000) | \ (((info)->base_addr & 0x00ff0000) >> 16) | \ @@ -172,12 +178,12 @@ static inline void load_TLS(struct thread_struct *t, unsigned int cpu) for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) gdt[i] = t->tls_array[i]; -} +} /* * load one particular LDT into the current CPU */ -static inline void load_LDT_nolock (mm_context_t *pc, int cpu) +static inline void load_LDT_nolock(mm_context_t *pc, int cpu) { int count = pc->size; @@ -185,7 +191,7 @@ static inline void load_LDT_nolock (mm_context_t *pc, int cpu) clear_LDT(); return; } - + set_ldt_desc(cpu, pc->ldt, count); load_LDT_desc(); } @@ -193,6 +199,7 @@ static inline void load_LDT_nolock (mm_context_t *pc, int cpu) static inline void load_LDT(mm_context_t *pc) { int cpu = get_cpu(); + load_LDT_nolock(pc, cpu); put_cpu(); } -- cgit v1.2.2 From fc2d625c4fac18e672a3b7c61af5de22d7ab7d87 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:13 +0100 Subject: x86: introduce ldt_write accessor Create a ldt write accessor like the 32 bit one. Preparatory patch for merging ldt.c and anyway necessary for 64bit paravirt ops. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/desc_64.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index bb2009ecbbc..7d48df72aef 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -38,6 +38,15 @@ extern struct desc_struct default_ldt[]; extern struct gate_struct idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; +static inline void write_ldt_entry(struct desc_struct *ldt, + int entry, u32 entry_low, u32 entry_high) +{ + __u32 *lp = (__u32 *)((entry << 3) + (char *)ldt); + + lp[0] = entry_low; + lp[1] = entry_high; +} + /* the cpu gdt accessor */ #define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) -- cgit v1.2.2 From 2d539553c96771bc8f77156f27500d35e1fe114c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:14 +0100 Subject: x86: unify include/asm-x86/apicdef_32/64.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/apicdef.h | 399 ++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/apicdef_32.h | 375 ---------------------------------------- include/asm-x86/apicdef_64.h | 392 ------------------------------------------ 3 files changed, 397 insertions(+), 769 deletions(-) delete mode 100644 include/asm-x86/apicdef_32.h delete mode 100644 include/asm-x86/apicdef_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h index 4542c220bf4..83ac1e6e362 100644 --- a/include/asm-x86/apicdef.h +++ b/include/asm-x86/apicdef.h @@ -1,5 +1,400 @@ +#ifndef _ASM_X86_APICDEF_H +#define _ASM_X86_APICDEF_H + +/* + * Constants for various Intel APICs. (local APIC, IOAPIC, etc.) + * + * Alan Cox , 1995. + * Ingo Molnar , 1999, 2000 + */ + +#define APIC_DEFAULT_PHYS_BASE 0xfee00000 + +#define APIC_ID 0x20 + +#ifdef CONFIG_X86_64 +# define APIC_ID_MASK (0xFFu<<24) +# define GET_APIC_ID(x) (((x)>>24)&0xFFu) +# define SET_APIC_ID(x) (((x)<<24)) +#endif + +#define APIC_LVR 0x30 +#define APIC_LVR_MASK 0xFF00FF +#define GET_APIC_VERSION(x) ((x)&0xFFu) +#define GET_APIC_MAXLVT(x) (((x)>>16)&0xFFu) +#define APIC_INTEGRATED(x) ((x)&0xF0u) +#define APIC_XAPIC(x) ((x) >= 0x14) +#define APIC_TASKPRI 0x80 +#define APIC_TPRI_MASK 0xFFu +#define APIC_ARBPRI 0x90 +#define APIC_ARBPRI_MASK 0xFFu +#define APIC_PROCPRI 0xA0 +#define APIC_EOI 0xB0 +#define APIC_EIO_ACK 0x0 +#define APIC_RRR 0xC0 +#define APIC_LDR 0xD0 +#define APIC_LDR_MASK (0xFFu<<24) +#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFFu) +#define SET_APIC_LOGICAL_ID(x) (((x)<<24)) +#define APIC_ALL_CPUS 0xFFu +#define APIC_DFR 0xE0 +#define APIC_DFR_CLUSTER 0x0FFFFFFFul +#define APIC_DFR_FLAT 0xFFFFFFFFul +#define APIC_SPIV 0xF0 +#define APIC_SPIV_FOCUS_DISABLED (1<<9) +#define APIC_SPIV_APIC_ENABLED (1<<8) +#define APIC_ISR 0x100 +#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */ +#define APIC_TMR 0x180 +#define APIC_IRR 0x200 +#define APIC_ESR 0x280 +#define APIC_ESR_SEND_CS 0x00001 +#define APIC_ESR_RECV_CS 0x00002 +#define APIC_ESR_SEND_ACC 0x00004 +#define APIC_ESR_RECV_ACC 0x00008 +#define APIC_ESR_SENDILL 0x00020 +#define APIC_ESR_RECVILL 0x00040 +#define APIC_ESR_ILLREGA 0x00080 +#define APIC_ICR 0x300 +#define APIC_DEST_SELF 0x40000 +#define APIC_DEST_ALLINC 0x80000 +#define APIC_DEST_ALLBUT 0xC0000 +#define APIC_ICR_RR_MASK 0x30000 +#define APIC_ICR_RR_INVALID 0x00000 +#define APIC_ICR_RR_INPROG 0x10000 +#define APIC_ICR_RR_VALID 0x20000 +#define APIC_INT_LEVELTRIG 0x08000 +#define APIC_INT_ASSERT 0x04000 +#define APIC_ICR_BUSY 0x01000 +#define APIC_DEST_LOGICAL 0x00800 +#define APIC_DEST_PHYSICAL 0x00000 +#define APIC_DM_FIXED 0x00000 +#define APIC_DM_LOWEST 0x00100 +#define APIC_DM_SMI 0x00200 +#define APIC_DM_REMRD 0x00300 +#define APIC_DM_NMI 0x00400 +#define APIC_DM_INIT 0x00500 +#define APIC_DM_STARTUP 0x00600 +#define APIC_DM_EXTINT 0x00700 +#define APIC_VECTOR_MASK 0x000FF +#define APIC_ICR2 0x310 +#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF) +#define SET_APIC_DEST_FIELD(x) ((x)<<24) +#define APIC_LVTT 0x320 +#define APIC_LVTTHMR 0x330 +#define APIC_LVTPC 0x340 +#define APIC_LVT0 0x350 +#define APIC_LVT_TIMER_BASE_MASK (0x3<<18) +#define GET_APIC_TIMER_BASE(x) (((x)>>18)&0x3) +#define SET_APIC_TIMER_BASE(x) (((x)<<18)) +#define APIC_TIMER_BASE_CLKIN 0x0 +#define APIC_TIMER_BASE_TMBASE 0x1 +#define APIC_TIMER_BASE_DIV 0x2 +#define APIC_LVT_TIMER_PERIODIC (1<<17) +#define APIC_LVT_MASKED (1<<16) +#define APIC_LVT_LEVEL_TRIGGER (1<<15) +#define APIC_LVT_REMOTE_IRR (1<<14) +#define APIC_INPUT_POLARITY (1<<13) +#define APIC_SEND_PENDING (1<<12) +#define APIC_MODE_MASK 0x700 +#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) +#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) +#define APIC_MODE_FIXED 0x0 +#define APIC_MODE_NMI 0x4 +#define APIC_MODE_EXTINT 0x7 +#define APIC_LVT1 0x360 +#define APIC_LVTERR 0x370 +#define APIC_TMICT 0x380 +#define APIC_TMCCT 0x390 +#define APIC_TDCR 0x3E0 +#define APIC_TDR_DIV_TMBASE (1<<2) +#define APIC_TDR_DIV_1 0xB +#define APIC_TDR_DIV_2 0x0 +#define APIC_TDR_DIV_4 0x1 +#define APIC_TDR_DIV_8 0x2 +#define APIC_TDR_DIV_16 0x3 +#define APIC_TDR_DIV_32 0x8 +#define APIC_TDR_DIV_64 0x9 +#define APIC_TDR_DIV_128 0xA +#define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) + #ifdef CONFIG_X86_32 -# include "apicdef_32.h" +# define MAX_IO_APICS 64 #else -# include "apicdef_64.h" +# define MAX_IO_APICS 128 +# define MAX_LOCAL_APIC 256 +#endif + +/* + * All x86-64 systems are xAPIC compatible. + * In the following, "apicid" is a physical APIC ID. + */ +#define XAPIC_DEST_CPUS_SHIFT 4 +#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1) +#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT) +#define APIC_CLUSTER(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK) +#define APIC_CLUSTERID(apicid) (APIC_CLUSTER(apicid) >> XAPIC_DEST_CPUS_SHIFT) +#define APIC_CPUID(apicid) ((apicid) & XAPIC_DEST_CPUS_MASK) +#define NUM_APIC_CLUSTERS ((BAD_APICID + 1) >> XAPIC_DEST_CPUS_SHIFT) + +/* + * the local APIC register structure, memory mapped. Not terribly well + * tested, but we might eventually use this one in the future - the + * problem why we cannot use it right now is the P5 APIC, it has an + * errata which cannot take 8-bit reads and writes, only 32-bit ones ... + */ +#define u32 unsigned int + +struct local_apic { + +/*000*/ struct { u32 __reserved[4]; } __reserved_01; + +/*010*/ struct { u32 __reserved[4]; } __reserved_02; + +/*020*/ struct { /* APIC ID Register */ + u32 __reserved_1 : 24, + phys_apic_id : 4, + __reserved_2 : 4; + u32 __reserved[3]; + } id; + +/*030*/ const + struct { /* APIC Version Register */ + u32 version : 8, + __reserved_1 : 8, + max_lvt : 8, + __reserved_2 : 8; + u32 __reserved[3]; + } version; + +/*040*/ struct { u32 __reserved[4]; } __reserved_03; + +/*050*/ struct { u32 __reserved[4]; } __reserved_04; + +/*060*/ struct { u32 __reserved[4]; } __reserved_05; + +/*070*/ struct { u32 __reserved[4]; } __reserved_06; + +/*080*/ struct { /* Task Priority Register */ + u32 priority : 8, + __reserved_1 : 24; + u32 __reserved_2[3]; + } tpr; + +/*090*/ const + struct { /* Arbitration Priority Register */ + u32 priority : 8, + __reserved_1 : 24; + u32 __reserved_2[3]; + } apr; + +/*0A0*/ const + struct { /* Processor Priority Register */ + u32 priority : 8, + __reserved_1 : 24; + u32 __reserved_2[3]; + } ppr; + +/*0B0*/ struct { /* End Of Interrupt Register */ + u32 eoi; + u32 __reserved[3]; + } eoi; + +/*0C0*/ struct { u32 __reserved[4]; } __reserved_07; + +/*0D0*/ struct { /* Logical Destination Register */ + u32 __reserved_1 : 24, + logical_dest : 8; + u32 __reserved_2[3]; + } ldr; + +/*0E0*/ struct { /* Destination Format Register */ + u32 __reserved_1 : 28, + model : 4; + u32 __reserved_2[3]; + } dfr; + +/*0F0*/ struct { /* Spurious Interrupt Vector Register */ + u32 spurious_vector : 8, + apic_enabled : 1, + focus_cpu : 1, + __reserved_2 : 22; + u32 __reserved_3[3]; + } svr; + +/*100*/ struct { /* In Service Register */ +/*170*/ u32 bitfield; + u32 __reserved[3]; + } isr [8]; + +/*180*/ struct { /* Trigger Mode Register */ +/*1F0*/ u32 bitfield; + u32 __reserved[3]; + } tmr [8]; + +/*200*/ struct { /* Interrupt Request Register */ +/*270*/ u32 bitfield; + u32 __reserved[3]; + } irr [8]; + +/*280*/ union { /* Error Status Register */ + struct { + u32 send_cs_error : 1, + receive_cs_error : 1, + send_accept_error : 1, + receive_accept_error : 1, + __reserved_1 : 1, + send_illegal_vector : 1, + receive_illegal_vector : 1, + illegal_register_address : 1, + __reserved_2 : 24; + u32 __reserved_3[3]; + } error_bits; + struct { + u32 errors; + u32 __reserved_3[3]; + } all_errors; + } esr; + +/*290*/ struct { u32 __reserved[4]; } __reserved_08; + +/*2A0*/ struct { u32 __reserved[4]; } __reserved_09; + +/*2B0*/ struct { u32 __reserved[4]; } __reserved_10; + +/*2C0*/ struct { u32 __reserved[4]; } __reserved_11; + +/*2D0*/ struct { u32 __reserved[4]; } __reserved_12; + +/*2E0*/ struct { u32 __reserved[4]; } __reserved_13; + +/*2F0*/ struct { u32 __reserved[4]; } __reserved_14; + +/*300*/ struct { /* Interrupt Command Register 1 */ + u32 vector : 8, + delivery_mode : 3, + destination_mode : 1, + delivery_status : 1, + __reserved_1 : 1, + level : 1, + trigger : 1, + __reserved_2 : 2, + shorthand : 2, + __reserved_3 : 12; + u32 __reserved_4[3]; + } icr1; + +/*310*/ struct { /* Interrupt Command Register 2 */ + union { + u32 __reserved_1 : 24, + phys_dest : 4, + __reserved_2 : 4; + u32 __reserved_3 : 24, + logical_dest : 8; + } dest; + u32 __reserved_4[3]; + } icr2; + +/*320*/ struct { /* LVT - Timer */ + u32 vector : 8, + __reserved_1 : 4, + delivery_status : 1, + __reserved_2 : 3, + mask : 1, + timer_mode : 1, + __reserved_3 : 14; + u32 __reserved_4[3]; + } lvt_timer; + +/*330*/ struct { /* LVT - Thermal Sensor */ + u32 vector : 8, + delivery_mode : 3, + __reserved_1 : 1, + delivery_status : 1, + __reserved_2 : 3, + mask : 1, + __reserved_3 : 15; + u32 __reserved_4[3]; + } lvt_thermal; + +/*340*/ struct { /* LVT - Performance Counter */ + u32 vector : 8, + delivery_mode : 3, + __reserved_1 : 1, + delivery_status : 1, + __reserved_2 : 3, + mask : 1, + __reserved_3 : 15; + u32 __reserved_4[3]; + } lvt_pc; + +/*350*/ struct { /* LVT - LINT0 */ + u32 vector : 8, + delivery_mode : 3, + __reserved_1 : 1, + delivery_status : 1, + polarity : 1, + remote_irr : 1, + trigger : 1, + mask : 1, + __reserved_2 : 15; + u32 __reserved_3[3]; + } lvt_lint0; + +/*360*/ struct { /* LVT - LINT1 */ + u32 vector : 8, + delivery_mode : 3, + __reserved_1 : 1, + delivery_status : 1, + polarity : 1, + remote_irr : 1, + trigger : 1, + mask : 1, + __reserved_2 : 15; + u32 __reserved_3[3]; + } lvt_lint1; + +/*370*/ struct { /* LVT - Error */ + u32 vector : 8, + __reserved_1 : 4, + delivery_status : 1, + __reserved_2 : 3, + mask : 1, + __reserved_3 : 15; + u32 __reserved_4[3]; + } lvt_error; + +/*380*/ struct { /* Timer Initial Count Register */ + u32 initial_count; + u32 __reserved_2[3]; + } timer_icr; + +/*390*/ const + struct { /* Timer Current Count Register */ + u32 curr_count; + u32 __reserved_2[3]; + } timer_ccr; + +/*3A0*/ struct { u32 __reserved[4]; } __reserved_16; + +/*3B0*/ struct { u32 __reserved[4]; } __reserved_17; + +/*3C0*/ struct { u32 __reserved[4]; } __reserved_18; + +/*3D0*/ struct { u32 __reserved[4]; } __reserved_19; + +/*3E0*/ struct { /* Timer Divide Configuration Register */ + u32 divisor : 4, + __reserved_1 : 28; + u32 __reserved_2[3]; + } timer_dcr; + +/*3F0*/ struct { u32 __reserved[4]; } __reserved_20; + +} __attribute__ ((packed)); + +#undef u32 + +#define BAD_APICID 0xFFu + #endif diff --git a/include/asm-x86/apicdef_32.h b/include/asm-x86/apicdef_32.h deleted file mode 100644 index 9f6995341fd..00000000000 --- a/include/asm-x86/apicdef_32.h +++ /dev/null @@ -1,375 +0,0 @@ -#ifndef __ASM_APICDEF_H -#define __ASM_APICDEF_H - -/* - * Constants for various Intel APICs. (local APIC, IOAPIC, etc.) - * - * Alan Cox , 1995. - * Ingo Molnar , 1999, 2000 - */ - -#define APIC_DEFAULT_PHYS_BASE 0xfee00000 - -#define APIC_ID 0x20 -#define APIC_LVR 0x30 -#define APIC_LVR_MASK 0xFF00FF -#define GET_APIC_VERSION(x) ((x)&0xFF) -#define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF) -#define APIC_INTEGRATED(x) ((x)&0xF0) -#define APIC_XAPIC(x) ((x) >= 0x14) -#define APIC_TASKPRI 0x80 -#define APIC_TPRI_MASK 0xFF -#define APIC_ARBPRI 0x90 -#define APIC_ARBPRI_MASK 0xFF -#define APIC_PROCPRI 0xA0 -#define APIC_EOI 0xB0 -#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */ -#define APIC_RRR 0xC0 -#define APIC_LDR 0xD0 -#define APIC_LDR_MASK (0xFF<<24) -#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) -#define SET_APIC_LOGICAL_ID(x) (((x)<<24)) -#define APIC_ALL_CPUS 0xFF -#define APIC_DFR 0xE0 -#define APIC_DFR_CLUSTER 0x0FFFFFFFul -#define APIC_DFR_FLAT 0xFFFFFFFFul -#define APIC_SPIV 0xF0 -#define APIC_SPIV_FOCUS_DISABLED (1<<9) -#define APIC_SPIV_APIC_ENABLED (1<<8) -#define APIC_ISR 0x100 -#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */ -#define APIC_TMR 0x180 -#define APIC_IRR 0x200 -#define APIC_ESR 0x280 -#define APIC_ESR_SEND_CS 0x00001 -#define APIC_ESR_RECV_CS 0x00002 -#define APIC_ESR_SEND_ACC 0x00004 -#define APIC_ESR_RECV_ACC 0x00008 -#define APIC_ESR_SENDILL 0x00020 -#define APIC_ESR_RECVILL 0x00040 -#define APIC_ESR_ILLREGA 0x00080 -#define APIC_ICR 0x300 -#define APIC_DEST_SELF 0x40000 -#define APIC_DEST_ALLINC 0x80000 -#define APIC_DEST_ALLBUT 0xC0000 -#define APIC_ICR_RR_MASK 0x30000 -#define APIC_ICR_RR_INVALID 0x00000 -#define APIC_ICR_RR_INPROG 0x10000 -#define APIC_ICR_RR_VALID 0x20000 -#define APIC_INT_LEVELTRIG 0x08000 -#define APIC_INT_ASSERT 0x04000 -#define APIC_ICR_BUSY 0x01000 -#define APIC_DEST_LOGICAL 0x00800 -#define APIC_DM_FIXED 0x00000 -#define APIC_DM_LOWEST 0x00100 -#define APIC_DM_SMI 0x00200 -#define APIC_DM_REMRD 0x00300 -#define APIC_DM_NMI 0x00400 -#define APIC_DM_INIT 0x00500 -#define APIC_DM_STARTUP 0x00600 -#define APIC_DM_EXTINT 0x00700 -#define APIC_VECTOR_MASK 0x000FF -#define APIC_ICR2 0x310 -#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF) -#define SET_APIC_DEST_FIELD(x) ((x)<<24) -#define APIC_LVTT 0x320 -#define APIC_LVTTHMR 0x330 -#define APIC_LVTPC 0x340 -#define APIC_LVT0 0x350 -#define APIC_LVT_TIMER_BASE_MASK (0x3<<18) -#define GET_APIC_TIMER_BASE(x) (((x)>>18)&0x3) -#define SET_APIC_TIMER_BASE(x) (((x)<<18)) -#define APIC_TIMER_BASE_CLKIN 0x0 -#define APIC_TIMER_BASE_TMBASE 0x1 -#define APIC_TIMER_BASE_DIV 0x2 -#define APIC_LVT_TIMER_PERIODIC (1<<17) -#define APIC_LVT_MASKED (1<<16) -#define APIC_LVT_LEVEL_TRIGGER (1<<15) -#define APIC_LVT_REMOTE_IRR (1<<14) -#define APIC_INPUT_POLARITY (1<<13) -#define APIC_SEND_PENDING (1<<12) -#define APIC_MODE_MASK 0x700 -#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) -#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) -#define APIC_MODE_FIXED 0x0 -#define APIC_MODE_NMI 0x4 -#define APIC_MODE_EXTINT 0x7 -#define APIC_LVT1 0x360 -#define APIC_LVTERR 0x370 -#define APIC_TMICT 0x380 -#define APIC_TMCCT 0x390 -#define APIC_TDCR 0x3E0 -#define APIC_TDR_DIV_TMBASE (1<<2) -#define APIC_TDR_DIV_1 0xB -#define APIC_TDR_DIV_2 0x0 -#define APIC_TDR_DIV_4 0x1 -#define APIC_TDR_DIV_8 0x2 -#define APIC_TDR_DIV_16 0x3 -#define APIC_TDR_DIV_32 0x8 -#define APIC_TDR_DIV_64 0x9 -#define APIC_TDR_DIV_128 0xA - -#define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) - -#define MAX_IO_APICS 64 - -/* - * the local APIC register structure, memory mapped. Not terribly well - * tested, but we might eventually use this one in the future - the - * problem why we cannot use it right now is the P5 APIC, it has an - * errata which cannot take 8-bit reads and writes, only 32-bit ones ... - */ -#define u32 unsigned int - - -struct local_apic { - -/*000*/ struct { u32 __reserved[4]; } __reserved_01; - -/*010*/ struct { u32 __reserved[4]; } __reserved_02; - -/*020*/ struct { /* APIC ID Register */ - u32 __reserved_1 : 24, - phys_apic_id : 4, - __reserved_2 : 4; - u32 __reserved[3]; - } id; - -/*030*/ const - struct { /* APIC Version Register */ - u32 version : 8, - __reserved_1 : 8, - max_lvt : 8, - __reserved_2 : 8; - u32 __reserved[3]; - } version; - -/*040*/ struct { u32 __reserved[4]; } __reserved_03; - -/*050*/ struct { u32 __reserved[4]; } __reserved_04; - -/*060*/ struct { u32 __reserved[4]; } __reserved_05; - -/*070*/ struct { u32 __reserved[4]; } __reserved_06; - -/*080*/ struct { /* Task Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } tpr; - -/*090*/ const - struct { /* Arbitration Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } apr; - -/*0A0*/ const - struct { /* Processor Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } ppr; - -/*0B0*/ struct { /* End Of Interrupt Register */ - u32 eoi; - u32 __reserved[3]; - } eoi; - -/*0C0*/ struct { u32 __reserved[4]; } __reserved_07; - -/*0D0*/ struct { /* Logical Destination Register */ - u32 __reserved_1 : 24, - logical_dest : 8; - u32 __reserved_2[3]; - } ldr; - -/*0E0*/ struct { /* Destination Format Register */ - u32 __reserved_1 : 28, - model : 4; - u32 __reserved_2[3]; - } dfr; - -/*0F0*/ struct { /* Spurious Interrupt Vector Register */ - u32 spurious_vector : 8, - apic_enabled : 1, - focus_cpu : 1, - __reserved_2 : 22; - u32 __reserved_3[3]; - } svr; - -/*100*/ struct { /* In Service Register */ -/*170*/ u32 bitfield; - u32 __reserved[3]; - } isr [8]; - -/*180*/ struct { /* Trigger Mode Register */ -/*1F0*/ u32 bitfield; - u32 __reserved[3]; - } tmr [8]; - -/*200*/ struct { /* Interrupt Request Register */ -/*270*/ u32 bitfield; - u32 __reserved[3]; - } irr [8]; - -/*280*/ union { /* Error Status Register */ - struct { - u32 send_cs_error : 1, - receive_cs_error : 1, - send_accept_error : 1, - receive_accept_error : 1, - __reserved_1 : 1, - send_illegal_vector : 1, - receive_illegal_vector : 1, - illegal_register_address : 1, - __reserved_2 : 24; - u32 __reserved_3[3]; - } error_bits; - struct { - u32 errors; - u32 __reserved_3[3]; - } all_errors; - } esr; - -/*290*/ struct { u32 __reserved[4]; } __reserved_08; - -/*2A0*/ struct { u32 __reserved[4]; } __reserved_09; - -/*2B0*/ struct { u32 __reserved[4]; } __reserved_10; - -/*2C0*/ struct { u32 __reserved[4]; } __reserved_11; - -/*2D0*/ struct { u32 __reserved[4]; } __reserved_12; - -/*2E0*/ struct { u32 __reserved[4]; } __reserved_13; - -/*2F0*/ struct { u32 __reserved[4]; } __reserved_14; - -/*300*/ struct { /* Interrupt Command Register 1 */ - u32 vector : 8, - delivery_mode : 3, - destination_mode : 1, - delivery_status : 1, - __reserved_1 : 1, - level : 1, - trigger : 1, - __reserved_2 : 2, - shorthand : 2, - __reserved_3 : 12; - u32 __reserved_4[3]; - } icr1; - -/*310*/ struct { /* Interrupt Command Register 2 */ - union { - u32 __reserved_1 : 24, - phys_dest : 4, - __reserved_2 : 4; - u32 __reserved_3 : 24, - logical_dest : 8; - } dest; - u32 __reserved_4[3]; - } icr2; - -/*320*/ struct { /* LVT - Timer */ - u32 vector : 8, - __reserved_1 : 4, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - timer_mode : 1, - __reserved_3 : 14; - u32 __reserved_4[3]; - } lvt_timer; - -/*330*/ struct { /* LVT - Thermal Sensor */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_thermal; - -/*340*/ struct { /* LVT - Performance Counter */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_pc; - -/*350*/ struct { /* LVT - LINT0 */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - polarity : 1, - remote_irr : 1, - trigger : 1, - mask : 1, - __reserved_2 : 15; - u32 __reserved_3[3]; - } lvt_lint0; - -/*360*/ struct { /* LVT - LINT1 */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - polarity : 1, - remote_irr : 1, - trigger : 1, - mask : 1, - __reserved_2 : 15; - u32 __reserved_3[3]; - } lvt_lint1; - -/*370*/ struct { /* LVT - Error */ - u32 vector : 8, - __reserved_1 : 4, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_error; - -/*380*/ struct { /* Timer Initial Count Register */ - u32 initial_count; - u32 __reserved_2[3]; - } timer_icr; - -/*390*/ const - struct { /* Timer Current Count Register */ - u32 curr_count; - u32 __reserved_2[3]; - } timer_ccr; - -/*3A0*/ struct { u32 __reserved[4]; } __reserved_16; - -/*3B0*/ struct { u32 __reserved[4]; } __reserved_17; - -/*3C0*/ struct { u32 __reserved[4]; } __reserved_18; - -/*3D0*/ struct { u32 __reserved[4]; } __reserved_19; - -/*3E0*/ struct { /* Timer Divide Configuration Register */ - u32 divisor : 4, - __reserved_1 : 28; - u32 __reserved_2[3]; - } timer_dcr; - -/*3F0*/ struct { u32 __reserved[4]; } __reserved_20; - -} __attribute__ ((packed)); - -#undef u32 - -#endif diff --git a/include/asm-x86/apicdef_64.h b/include/asm-x86/apicdef_64.h deleted file mode 100644 index 1dd40067c67..00000000000 --- a/include/asm-x86/apicdef_64.h +++ /dev/null @@ -1,392 +0,0 @@ -#ifndef __ASM_APICDEF_H -#define __ASM_APICDEF_H - -/* - * Constants for various Intel APICs. (local APIC, IOAPIC, etc.) - * - * Alan Cox , 1995. - * Ingo Molnar , 1999, 2000 - */ - -#define APIC_DEFAULT_PHYS_BASE 0xfee00000 - -#define APIC_ID 0x20 -#define APIC_ID_MASK (0xFFu<<24) -#define GET_APIC_ID(x) (((x)>>24)&0xFFu) -#define SET_APIC_ID(x) (((x)<<24)) -#define APIC_LVR 0x30 -#define APIC_LVR_MASK 0xFF00FF -#define GET_APIC_VERSION(x) ((x)&0xFFu) -#define GET_APIC_MAXLVT(x) (((x)>>16)&0xFFu) -#define APIC_INTEGRATED(x) ((x)&0xF0u) -#define APIC_TASKPRI 0x80 -#define APIC_TPRI_MASK 0xFFu -#define APIC_ARBPRI 0x90 -#define APIC_ARBPRI_MASK 0xFFu -#define APIC_PROCPRI 0xA0 -#define APIC_EOI 0xB0 -#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */ -#define APIC_RRR 0xC0 -#define APIC_LDR 0xD0 -#define APIC_LDR_MASK (0xFFu<<24) -#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFFu) -#define SET_APIC_LOGICAL_ID(x) (((x)<<24)) -#define APIC_ALL_CPUS 0xFFu -#define APIC_DFR 0xE0 -#define APIC_DFR_CLUSTER 0x0FFFFFFFul -#define APIC_DFR_FLAT 0xFFFFFFFFul -#define APIC_SPIV 0xF0 -#define APIC_SPIV_FOCUS_DISABLED (1<<9) -#define APIC_SPIV_APIC_ENABLED (1<<8) -#define APIC_ISR 0x100 -#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */ -#define APIC_TMR 0x180 -#define APIC_IRR 0x200 -#define APIC_ESR 0x280 -#define APIC_ESR_SEND_CS 0x00001 -#define APIC_ESR_RECV_CS 0x00002 -#define APIC_ESR_SEND_ACC 0x00004 -#define APIC_ESR_RECV_ACC 0x00008 -#define APIC_ESR_SENDILL 0x00020 -#define APIC_ESR_RECVILL 0x00040 -#define APIC_ESR_ILLREGA 0x00080 -#define APIC_ICR 0x300 -#define APIC_DEST_SELF 0x40000 -#define APIC_DEST_ALLINC 0x80000 -#define APIC_DEST_ALLBUT 0xC0000 -#define APIC_ICR_RR_MASK 0x30000 -#define APIC_ICR_RR_INVALID 0x00000 -#define APIC_ICR_RR_INPROG 0x10000 -#define APIC_ICR_RR_VALID 0x20000 -#define APIC_INT_LEVELTRIG 0x08000 -#define APIC_INT_ASSERT 0x04000 -#define APIC_ICR_BUSY 0x01000 -#define APIC_DEST_LOGICAL 0x00800 -#define APIC_DEST_PHYSICAL 0x00000 -#define APIC_DM_FIXED 0x00000 -#define APIC_DM_LOWEST 0x00100 -#define APIC_DM_SMI 0x00200 -#define APIC_DM_REMRD 0x00300 -#define APIC_DM_NMI 0x00400 -#define APIC_DM_INIT 0x00500 -#define APIC_DM_STARTUP 0x00600 -#define APIC_DM_EXTINT 0x00700 -#define APIC_VECTOR_MASK 0x000FF -#define APIC_ICR2 0x310 -#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF) -#define SET_APIC_DEST_FIELD(x) ((x)<<24) -#define APIC_LVTT 0x320 -#define APIC_LVTTHMR 0x330 -#define APIC_LVTPC 0x340 -#define APIC_LVT0 0x350 -#define APIC_LVT_TIMER_BASE_MASK (0x3<<18) -#define GET_APIC_TIMER_BASE(x) (((x)>>18)&0x3) -#define SET_APIC_TIMER_BASE(x) (((x)<<18)) -#define APIC_TIMER_BASE_CLKIN 0x0 -#define APIC_TIMER_BASE_TMBASE 0x1 -#define APIC_TIMER_BASE_DIV 0x2 -#define APIC_LVT_TIMER_PERIODIC (1<<17) -#define APIC_LVT_MASKED (1<<16) -#define APIC_LVT_LEVEL_TRIGGER (1<<15) -#define APIC_LVT_REMOTE_IRR (1<<14) -#define APIC_INPUT_POLARITY (1<<13) -#define APIC_SEND_PENDING (1<<12) -#define APIC_MODE_MASK 0x700 -#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) -#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) -#define APIC_MODE_FIXED 0x0 -#define APIC_MODE_NMI 0x4 -#define APIC_MODE_EXTINT 0x7 -#define APIC_LVT1 0x360 -#define APIC_LVTERR 0x370 -#define APIC_TMICT 0x380 -#define APIC_TMCCT 0x390 -#define APIC_TDCR 0x3E0 -#define APIC_TDR_DIV_TMBASE (1<<2) -#define APIC_TDR_DIV_1 0xB -#define APIC_TDR_DIV_2 0x0 -#define APIC_TDR_DIV_4 0x1 -#define APIC_TDR_DIV_8 0x2 -#define APIC_TDR_DIV_16 0x3 -#define APIC_TDR_DIV_32 0x8 -#define APIC_TDR_DIV_64 0x9 -#define APIC_TDR_DIV_128 0xA - -#define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) - -#define MAX_IO_APICS 128 -#define MAX_LOCAL_APIC 256 - -/* - * All x86-64 systems are xAPIC compatible. - * In the following, "apicid" is a physical APIC ID. - */ -#define XAPIC_DEST_CPUS_SHIFT 4 -#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1) -#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT) -#define APIC_CLUSTER(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK) -#define APIC_CLUSTERID(apicid) (APIC_CLUSTER(apicid) >> XAPIC_DEST_CPUS_SHIFT) -#define APIC_CPUID(apicid) ((apicid) & XAPIC_DEST_CPUS_MASK) -#define NUM_APIC_CLUSTERS ((BAD_APICID + 1) >> XAPIC_DEST_CPUS_SHIFT) - -/* - * the local APIC register structure, memory mapped. Not terribly well - * tested, but we might eventually use this one in the future - the - * problem why we cannot use it right now is the P5 APIC, it has an - * errata which cannot take 8-bit reads and writes, only 32-bit ones ... - */ -#define u32 unsigned int - -struct local_apic { - -/*000*/ struct { u32 __reserved[4]; } __reserved_01; - -/*010*/ struct { u32 __reserved[4]; } __reserved_02; - -/*020*/ struct { /* APIC ID Register */ - u32 __reserved_1 : 24, - phys_apic_id : 4, - __reserved_2 : 4; - u32 __reserved[3]; - } id; - -/*030*/ const - struct { /* APIC Version Register */ - u32 version : 8, - __reserved_1 : 8, - max_lvt : 8, - __reserved_2 : 8; - u32 __reserved[3]; - } version; - -/*040*/ struct { u32 __reserved[4]; } __reserved_03; - -/*050*/ struct { u32 __reserved[4]; } __reserved_04; - -/*060*/ struct { u32 __reserved[4]; } __reserved_05; - -/*070*/ struct { u32 __reserved[4]; } __reserved_06; - -/*080*/ struct { /* Task Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } tpr; - -/*090*/ const - struct { /* Arbitration Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } apr; - -/*0A0*/ const - struct { /* Processor Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } ppr; - -/*0B0*/ struct { /* End Of Interrupt Register */ - u32 eoi; - u32 __reserved[3]; - } eoi; - -/*0C0*/ struct { u32 __reserved[4]; } __reserved_07; - -/*0D0*/ struct { /* Logical Destination Register */ - u32 __reserved_1 : 24, - logical_dest : 8; - u32 __reserved_2[3]; - } ldr; - -/*0E0*/ struct { /* Destination Format Register */ - u32 __reserved_1 : 28, - model : 4; - u32 __reserved_2[3]; - } dfr; - -/*0F0*/ struct { /* Spurious Interrupt Vector Register */ - u32 spurious_vector : 8, - apic_enabled : 1, - focus_cpu : 1, - __reserved_2 : 22; - u32 __reserved_3[3]; - } svr; - -/*100*/ struct { /* In Service Register */ -/*170*/ u32 bitfield; - u32 __reserved[3]; - } isr [8]; - -/*180*/ struct { /* Trigger Mode Register */ -/*1F0*/ u32 bitfield; - u32 __reserved[3]; - } tmr [8]; - -/*200*/ struct { /* Interrupt Request Register */ -/*270*/ u32 bitfield; - u32 __reserved[3]; - } irr [8]; - -/*280*/ union { /* Error Status Register */ - struct { - u32 send_cs_error : 1, - receive_cs_error : 1, - send_accept_error : 1, - receive_accept_error : 1, - __reserved_1 : 1, - send_illegal_vector : 1, - receive_illegal_vector : 1, - illegal_register_address : 1, - __reserved_2 : 24; - u32 __reserved_3[3]; - } error_bits; - struct { - u32 errors; - u32 __reserved_3[3]; - } all_errors; - } esr; - -/*290*/ struct { u32 __reserved[4]; } __reserved_08; - -/*2A0*/ struct { u32 __reserved[4]; } __reserved_09; - -/*2B0*/ struct { u32 __reserved[4]; } __reserved_10; - -/*2C0*/ struct { u32 __reserved[4]; } __reserved_11; - -/*2D0*/ struct { u32 __reserved[4]; } __reserved_12; - -/*2E0*/ struct { u32 __reserved[4]; } __reserved_13; - -/*2F0*/ struct { u32 __reserved[4]; } __reserved_14; - -/*300*/ struct { /* Interrupt Command Register 1 */ - u32 vector : 8, - delivery_mode : 3, - destination_mode : 1, - delivery_status : 1, - __reserved_1 : 1, - level : 1, - trigger : 1, - __reserved_2 : 2, - shorthand : 2, - __reserved_3 : 12; - u32 __reserved_4[3]; - } icr1; - -/*310*/ struct { /* Interrupt Command Register 2 */ - union { - u32 __reserved_1 : 24, - phys_dest : 4, - __reserved_2 : 4; - u32 __reserved_3 : 24, - logical_dest : 8; - } dest; - u32 __reserved_4[3]; - } icr2; - -/*320*/ struct { /* LVT - Timer */ - u32 vector : 8, - __reserved_1 : 4, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - timer_mode : 1, - __reserved_3 : 14; - u32 __reserved_4[3]; - } lvt_timer; - -/*330*/ struct { /* LVT - Thermal Sensor */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_thermal; - -/*340*/ struct { /* LVT - Performance Counter */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_pc; - -/*350*/ struct { /* LVT - LINT0 */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - polarity : 1, - remote_irr : 1, - trigger : 1, - mask : 1, - __reserved_2 : 15; - u32 __reserved_3[3]; - } lvt_lint0; - -/*360*/ struct { /* LVT - LINT1 */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - polarity : 1, - remote_irr : 1, - trigger : 1, - mask : 1, - __reserved_2 : 15; - u32 __reserved_3[3]; - } lvt_lint1; - -/*370*/ struct { /* LVT - Error */ - u32 vector : 8, - __reserved_1 : 4, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_error; - -/*380*/ struct { /* Timer Initial Count Register */ - u32 initial_count; - u32 __reserved_2[3]; - } timer_icr; - -/*390*/ const - struct { /* Timer Current Count Register */ - u32 curr_count; - u32 __reserved_2[3]; - } timer_ccr; - -/*3A0*/ struct { u32 __reserved[4]; } __reserved_16; - -/*3B0*/ struct { u32 __reserved[4]; } __reserved_17; - -/*3C0*/ struct { u32 __reserved[4]; } __reserved_18; - -/*3D0*/ struct { u32 __reserved[4]; } __reserved_19; - -/*3E0*/ struct { /* Timer Divide Configuration Register */ - u32 divisor : 4, - __reserved_1 : 28; - u32 __reserved_2[3]; - } timer_dcr; - -/*3F0*/ struct { u32 __reserved[4]; } __reserved_20; - -} __attribute__ ((packed)); - -#undef u32 - -#define BAD_APICID 0xFFu - -#endif -- cgit v1.2.2 From cff90dbfe41f2c8eabe2d0a7e379829f4a9980af Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:14 +0100 Subject: x86: prepare unification of include/asm-x86/apic_32/64.h White space and coding style clenaup. Move the K8 local apic defines to apicdef.h, where they belong Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/apic_32.h | 49 ++++++++++++++++++++++------------------------- include/asm-x86/apic_64.h | 39 ++++++++++++++++--------------------- include/asm-x86/apicdef.h | 10 +++++++++- 3 files changed, 48 insertions(+), 50 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic_32.h b/include/asm-x86/apic_32.h index be158b27d54..f909e2daf22 100644 --- a/include/asm-x86/apic_32.h +++ b/include/asm-x86/apic_32.h @@ -17,8 +17,6 @@ #define APIC_VERBOSE 1 #define APIC_DEBUG 2 -extern int apic_verbosity; - /* * Define the default level of output to be very little * This can be turned up by using apic=verbose for more @@ -35,6 +33,11 @@ extern void generic_apic_probe(void); #ifdef CONFIG_X86_LOCAL_APIC +extern int apic_verbosity; +extern int timer_over_8254; +extern int local_apic_timer_c2_ok; +extern int local_apic_timer_disabled; + /* * Basic functions accessing APICs. */ @@ -65,9 +68,9 @@ static __inline fastcall unsigned long native_apic_read(unsigned long reg) return *((volatile unsigned long *)(APIC_BASE+reg)); } -void apic_wait_icr_idle(void); -unsigned long safe_apic_wait_icr_idle(void); -int get_physical_broadcast(void); +extern void apic_wait_icr_idle(void); +extern unsigned long safe_apic_wait_icr_idle(void); +extern int get_physical_broadcast(void); #ifdef CONFIG_X86_GOOD_APIC # define FORCE_READ_AROUND_WRITE 0 @@ -94,30 +97,24 @@ static inline void ack_APIC_irq(void) extern int lapic_get_maxlvt(void); extern void clear_local_APIC(void); -extern void connect_bsp_APIC (void); -extern void disconnect_bsp_APIC (int virt_wire_setup); -extern void disable_local_APIC (void); -extern void lapic_shutdown (void); -extern int verify_local_APIC (void); -extern void cache_APIC_registers (void); -extern void sync_Arb_IDs (void); -extern void init_bsp_APIC (void); -extern void setup_local_APIC (void); -extern void init_apic_mappings (void); -extern void smp_local_timer_interrupt (void); -extern void setup_boot_APIC_clock (void); -extern void setup_secondary_APIC_clock (void); -extern int APIC_init_uniprocessor (void); - -extern void enable_NMI_through_LVT0 (void * dummy); +extern void connect_bsp_APIC(void); +extern void disconnect_bsp_APIC(int virt_wire_setup); +extern void disable_local_APIC(void); +extern void lapic_shutdown(void); +extern int verify_local_APIC(void); +extern void cache_APIC_registers(void); +extern void sync_Arb_IDs(void); +extern void init_bsp_APIC(void); +extern void setup_local_APIC(void); +extern void init_apic_mappings(void); +extern void smp_local_timer_interrupt(void); +extern void setup_boot_APIC_clock(void); +extern void setup_secondary_APIC_clock(void); +extern int APIC_init_uniprocessor(void); +extern void enable_NMI_through_LVT0(void *dummy); #define ARCH_APICTIMER_STOPS_ON_C3 1 -extern int timer_over_8254; -extern int local_apic_timer_c2_ok; - -extern int local_apic_timer_disabled; - #else /* !CONFIG_X86_LOCAL_APIC */ static inline void lapic_shutdown(void) { } #define local_apic_timer_c2_ok 1 diff --git a/include/asm-x86/apic_64.h b/include/asm-x86/apic_64.h index 2747a11a2b1..9a0ec02a49a 100644 --- a/include/asm-x86/apic_64.h +++ b/include/asm-x86/apic_64.h @@ -64,22 +64,22 @@ static inline void ack_APIC_irq(void) apic_write(APIC_EOI, 0); } -extern int get_maxlvt (void); -extern void clear_local_APIC (void); -extern void connect_bsp_APIC (void); -extern void disconnect_bsp_APIC (int virt_wire_setup); -extern void disable_local_APIC (void); -extern void lapic_shutdown (void); -extern int verify_local_APIC (void); -extern void cache_APIC_registers (void); -extern void sync_Arb_IDs (void); -extern void init_bsp_APIC (void); -extern void setup_local_APIC (void); -extern void init_apic_mappings (void); -extern void smp_local_timer_interrupt (void); -extern void setup_boot_APIC_clock (void); -extern void setup_secondary_APIC_clock (void); -extern int APIC_init_uniprocessor (void); +extern int get_maxlvt(void); +extern void clear_local_APIC(void); +extern void connect_bsp_APIC(void); +extern void disconnect_bsp_APIC(int virt_wire_setup); +extern void disable_local_APIC(void); +extern void lapic_shutdown(void); +extern int verify_local_APIC(void); +extern void cache_APIC_registers(void); +extern void sync_Arb_IDs(void); +extern void init_bsp_APIC(void); +extern void setup_local_APIC(void); +extern void init_apic_mappings(void); +extern void smp_local_timer_interrupt(void); +extern void setup_boot_APIC_clock(void); +extern void setup_secondary_APIC_clock(void); +extern int APIC_init_uniprocessor(void); extern void setup_apic_routing(void); extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, @@ -87,13 +87,6 @@ extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, extern int apic_is_clustered_box(void); -#define K8_APIC_EXT_LVT_BASE 0x500 -#define K8_APIC_EXT_INT_MSG_FIX 0x0 -#define K8_APIC_EXT_INT_MSG_SMI 0x2 -#define K8_APIC_EXT_INT_MSG_NMI 0x4 -#define K8_APIC_EXT_INT_MSG_EXT 0x7 -#define K8_APIC_EXT_LVT_ENTRY_THRESHOLD 0 - #define ARCH_APICTIMER_STOPS_ON_C3 1 extern unsigned boot_cpu_id; diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h index 83ac1e6e362..5f7abe9b5f8 100644 --- a/include/asm-x86/apicdef.h +++ b/include/asm-x86/apicdef.h @@ -98,7 +98,7 @@ #define APIC_SEND_PENDING (1<<12) #define APIC_MODE_MASK 0x700 #define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) -#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) +#define SET_APIC_DELIVERY_MODE(x, y) (((x)&~0x700)|((y)<<8)) #define APIC_MODE_FIXED 0x0 #define APIC_MODE_NMI 0x4 #define APIC_MODE_EXTINT 0x7 @@ -116,6 +116,14 @@ #define APIC_TDR_DIV_32 0x8 #define APIC_TDR_DIV_64 0x9 #define APIC_TDR_DIV_128 0xA + +#define K8_APIC_EXT_LVT_BASE 0x500 +#define K8_APIC_EXT_INT_MSG_FIX 0x0 +#define K8_APIC_EXT_INT_MSG_SMI 0x2 +#define K8_APIC_EXT_INT_MSG_NMI 0x4 +#define K8_APIC_EXT_INT_MSG_EXT 0x7 +#define K8_APIC_EXT_LVT_ENTRY_THRESHOLD 0 + #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) #ifdef CONFIG_X86_32 -- cgit v1.2.2 From 37e650c7c8a27de533d409b53c29f4135dcc7af6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:14 +0100 Subject: x86: rename get_maxlvt to lapic_get_maxlvt Use the same name for the 32 and 64 bit variant. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/apic_64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic_64.h b/include/asm-x86/apic_64.h index 9a0ec02a49a..b5f850f2511 100644 --- a/include/asm-x86/apic_64.h +++ b/include/asm-x86/apic_64.h @@ -64,7 +64,7 @@ static inline void ack_APIC_irq(void) apic_write(APIC_EOI, 0); } -extern int get_maxlvt(void); +extern int lapic_get_maxlvt(void); extern void clear_local_APIC(void); extern void connect_bsp_APIC(void); extern void disconnect_bsp_APIC(int virt_wire_setup); -- cgit v1.2.2 From 3c6bb07ac1b4174318606a26f0de8ceb9f6d8133 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:15 +0100 Subject: x86: use u32 for safe_apic_wait_icr_idle() Preperatory patch for merging apic headers. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/apic_64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic_64.h b/include/asm-x86/apic_64.h index b5f850f2511..7bfad022417 100644 --- a/include/asm-x86/apic_64.h +++ b/include/asm-x86/apic_64.h @@ -49,7 +49,7 @@ static __inline unsigned int apic_read(unsigned long reg) } extern void apic_wait_icr_idle(void); -extern unsigned int safe_apic_wait_icr_idle(void); +extern u32 safe_apic_wait_icr_idle(void); static inline void ack_APIC_irq(void) { -- cgit v1.2.2 From 42e0a9aa5d467188687c6b705412578e53c14af6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:15 +0100 Subject: x86: use u32 for some lapic functions Use u32 so 32 and 64bit have the same interface. Andrew Morton: xen, lguest build fixes Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/apic_32.h | 16 +++++++--------- include/asm-x86/apic_64.h | 6 +++--- include/asm-x86/paravirt.h | 12 ++++++------ 3 files changed, 16 insertions(+), 18 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic_32.h b/include/asm-x86/apic_32.h index f909e2daf22..649e9a6f668 100644 --- a/include/asm-x86/apic_32.h +++ b/include/asm-x86/apic_32.h @@ -51,25 +51,23 @@ extern int local_apic_timer_disabled; #define setup_secondary_clock setup_secondary_APIC_clock #endif -static __inline fastcall void native_apic_write(unsigned long reg, - unsigned long v) +static __inline fastcall void native_apic_write(unsigned long reg, u32 v) { - *((volatile unsigned long *)(APIC_BASE+reg)) = v; + *((volatile u32 *)(APIC_BASE + reg)) = v; } -static __inline fastcall void native_apic_write_atomic(unsigned long reg, - unsigned long v) +static __inline fastcall void native_apic_write_atomic(unsigned long reg, u32 v) { - xchg((volatile unsigned long *)(APIC_BASE+reg), v); + (void) xchg((u32 *)(APIC_BASE + reg), v); } -static __inline fastcall unsigned long native_apic_read(unsigned long reg) +static __inline fastcall u32 native_apic_read(unsigned long reg) { - return *((volatile unsigned long *)(APIC_BASE+reg)); + return *((volatile u32 *)(APIC_BASE + reg)); } extern void apic_wait_icr_idle(void); -extern unsigned long safe_apic_wait_icr_idle(void); +extern u32 safe_apic_wait_icr_idle(void); extern int get_physical_broadcast(void); #ifdef CONFIG_X86_GOOD_APIC diff --git a/include/asm-x86/apic_64.h b/include/asm-x86/apic_64.h index 7bfad022417..9d0c06c4df9 100644 --- a/include/asm-x86/apic_64.h +++ b/include/asm-x86/apic_64.h @@ -38,14 +38,14 @@ struct pt_regs; * Basic functions accessing APICs. */ -static __inline void apic_write(unsigned long reg, unsigned int v) +static __inline void apic_write(unsigned long reg, u32 v) { *((volatile unsigned int *)(APIC_BASE+reg)) = v; } -static __inline unsigned int apic_read(unsigned long reg) +static __inline u32 apic_read(unsigned long reg) { - return *((volatile unsigned int *)(APIC_BASE+reg)); + return *((volatile u32 *)(APIC_BASE+reg)); } extern void apic_wait_icr_idle(void); diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index f59d370c5df..19fd3e67b08 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -150,9 +150,9 @@ struct pv_apic_ops { * Direct APIC operations, principally for VMI. Ideally * these shouldn't be in this interface. */ - void (*apic_write)(unsigned long reg, unsigned long v); - void (*apic_write_atomic)(unsigned long reg, unsigned long v); - unsigned long (*apic_read)(unsigned long reg); + void (*apic_write)(unsigned long reg, u32 v); + void (*apic_write_atomic)(unsigned long reg, u32 v); + u32 (*apic_read)(unsigned long reg); void (*setup_boot_clock)(void); void (*setup_secondary_clock)(void); @@ -690,17 +690,17 @@ static inline void slow_down_io(void) { /* * Basic functions accessing APICs. */ -static inline void apic_write(unsigned long reg, unsigned long v) +static inline void apic_write(unsigned long reg, u32 v) { PVOP_VCALL2(pv_apic_ops.apic_write, reg, v); } -static inline void apic_write_atomic(unsigned long reg, unsigned long v) +static inline void apic_write_atomic(unsigned long reg, u32 v) { PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v); } -static inline unsigned long apic_read(unsigned long reg) +static inline u32 apic_read(unsigned long reg) { return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg); } -- cgit v1.2.2 From 67c5fc5c330f63360e26609534b219df1aaa03ca Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:15 +0100 Subject: x86: merge apic_32/64.h Unify apic.h variants. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/apic.h | 140 +++++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/apic_32.h | 122 ---------------------------------------- include/asm-x86/apic_64.h | 95 ------------------------------- 3 files changed, 137 insertions(+), 220 deletions(-) delete mode 100644 include/asm-x86/apic_32.h delete mode 100644 include/asm-x86/apic_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 9fbcc0bd2ac..c064c1f84ba 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -1,5 +1,139 @@ -#ifdef CONFIG_X86_32 -# include "apic_32.h" +#ifndef _ASM_X86_APIC_H +#define _ASM_X86_APIC_H + +#include +#include +#include +#include +#include +#include + +#define ARCH_APICTIMER_STOPS_ON_C3 1 + +#define Dprintk(x...) + +/* + * Debugging macros + */ +#define APIC_QUIET 0 +#define APIC_VERBOSE 1 +#define APIC_DEBUG 2 + +/* + * Define the default level of output to be very little + * This can be turned up by using apic=verbose for more + * information and apic=debug for _lots_ of information. + * apic_verbosity is defined in apic.c + */ +#define apic_printk(v, s, a...) do { \ + if ((v) <= apic_verbosity) \ + printk(s, ##a); \ + } while (0) + + +extern void generic_apic_probe(void); + +#ifdef CONFIG_X86_LOCAL_APIC + +extern int apic_verbosity; +extern int timer_over_8254; +extern int local_apic_timer_c2_ok; +extern int local_apic_timer_disabled; + +extern int apic_runs_main_timer; +extern int ioapic_force; +extern int disable_apic_timer; +extern unsigned boot_cpu_id; + +/* + * Basic functions accessing APICs. + */ +#ifdef CONFIG_PARAVIRT +#include #else -# include "apic_64.h" +#define apic_write native_apic_write +#define apic_write_atomic native_apic_write_atomic +#define apic_read native_apic_read +#define setup_boot_clock setup_boot_APIC_clock +#define setup_secondary_clock setup_secondary_APIC_clock #endif + +static inline fastcall void native_apic_write(unsigned long reg, u32 v) +{ + *((volatile u32 *)(APIC_BASE + reg)) = v; +} + +static inline fastcall void native_apic_write_atomic(unsigned long reg, u32 v) +{ + (void) xchg((u32*)(APIC_BASE + reg), v); +} + +static inline fastcall u32 native_apic_read(unsigned long reg) +{ + return *((volatile u32 *)(APIC_BASE + reg)); +} + +extern void apic_wait_icr_idle(void); +extern u32 safe_apic_wait_icr_idle(void); +extern int get_physical_broadcast(void); + +#ifdef CONFIG_X86_GOOD_APIC +# define FORCE_READ_AROUND_WRITE 0 +# define apic_read_around(x) +# define apic_write_around(x, y) apic_write((x), (y)) +#else +# define FORCE_READ_AROUND_WRITE 1 +# define apic_read_around(x) apic_read(x) +# define apic_write_around(x, y) apic_write_atomic((x), (y)) +#endif + +static inline void ack_APIC_irq(void) +{ + /* + * ack_APIC_irq() actually gets compiled as a single instruction: + * - a single rmw on Pentium/82489DX + * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC) + * ... yummie. + */ + + /* Docs say use 0 for future compatibility */ + apic_write_around(APIC_EOI, 0); +} + +extern int lapic_get_maxlvt(void); +extern void clear_local_APIC(void); +extern void connect_bsp_APIC(void); +extern void disconnect_bsp_APIC(int virt_wire_setup); +extern void disable_local_APIC(void); +extern void lapic_shutdown(void); +extern int verify_local_APIC(void); +extern void cache_APIC_registers(void); +extern void sync_Arb_IDs(void); +extern void init_bsp_APIC(void); +extern void setup_local_APIC(void); +extern void init_apic_mappings(void); +extern void smp_local_timer_interrupt(void); +extern void setup_boot_APIC_clock(void); +extern void setup_secondary_APIC_clock(void); +extern int APIC_init_uniprocessor(void); +extern void enable_NMI_through_LVT0(void *dummy); + +/* + * On 32bit this is mach-xxx local + */ +#ifdef CONFIG_X86_64 +extern void setup_apic_routing(void); +#endif + +extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, + unsigned char msg_type, unsigned char mask); + +extern int apic_is_clustered_box(void); + +#else /* !CONFIG_X86_LOCAL_APIC */ +static inline void lapic_shutdown(void) { } +#define local_apic_timer_c2_ok 1 + +#endif /* !CONFIG_X86_LOCAL_APIC */ + +#endif /* __ASM_APIC_H */ diff --git a/include/asm-x86/apic_32.h b/include/asm-x86/apic_32.h deleted file mode 100644 index 649e9a6f668..00000000000 --- a/include/asm-x86/apic_32.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef __ASM_APIC_H -#define __ASM_APIC_H - -#include -#include -#include -#include -#include -#include - -#define Dprintk(x...) - -/* - * Debugging macros - */ -#define APIC_QUIET 0 -#define APIC_VERBOSE 1 -#define APIC_DEBUG 2 - -/* - * Define the default level of output to be very little - * This can be turned up by using apic=verbose for more - * information and apic=debug for _lots_ of information. - * apic_verbosity is defined in apic.c - */ -#define apic_printk(v, s, a...) do { \ - if ((v) <= apic_verbosity) \ - printk(s, ##a); \ - } while (0) - - -extern void generic_apic_probe(void); - -#ifdef CONFIG_X86_LOCAL_APIC - -extern int apic_verbosity; -extern int timer_over_8254; -extern int local_apic_timer_c2_ok; -extern int local_apic_timer_disabled; - -/* - * Basic functions accessing APICs. - */ -#ifdef CONFIG_PARAVIRT -#include -#else -#define apic_write native_apic_write -#define apic_write_atomic native_apic_write_atomic -#define apic_read native_apic_read -#define setup_boot_clock setup_boot_APIC_clock -#define setup_secondary_clock setup_secondary_APIC_clock -#endif - -static __inline fastcall void native_apic_write(unsigned long reg, u32 v) -{ - *((volatile u32 *)(APIC_BASE + reg)) = v; -} - -static __inline fastcall void native_apic_write_atomic(unsigned long reg, u32 v) -{ - (void) xchg((u32 *)(APIC_BASE + reg), v); -} - -static __inline fastcall u32 native_apic_read(unsigned long reg) -{ - return *((volatile u32 *)(APIC_BASE + reg)); -} - -extern void apic_wait_icr_idle(void); -extern u32 safe_apic_wait_icr_idle(void); -extern int get_physical_broadcast(void); - -#ifdef CONFIG_X86_GOOD_APIC -# define FORCE_READ_AROUND_WRITE 0 -# define apic_read_around(x) -# define apic_write_around(x,y) apic_write((x),(y)) -#else -# define FORCE_READ_AROUND_WRITE 1 -# define apic_read_around(x) apic_read(x) -# define apic_write_around(x,y) apic_write_atomic((x),(y)) -#endif - -static inline void ack_APIC_irq(void) -{ - /* - * ack_APIC_irq() actually gets compiled as a single instruction: - * - a single rmw on Pentium/82489DX - * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC) - * ... yummie. - */ - - /* Docs say use 0 for future compatibility */ - apic_write_around(APIC_EOI, 0); -} - -extern int lapic_get_maxlvt(void); -extern void clear_local_APIC(void); -extern void connect_bsp_APIC(void); -extern void disconnect_bsp_APIC(int virt_wire_setup); -extern void disable_local_APIC(void); -extern void lapic_shutdown(void); -extern int verify_local_APIC(void); -extern void cache_APIC_registers(void); -extern void sync_Arb_IDs(void); -extern void init_bsp_APIC(void); -extern void setup_local_APIC(void); -extern void init_apic_mappings(void); -extern void smp_local_timer_interrupt(void); -extern void setup_boot_APIC_clock(void); -extern void setup_secondary_APIC_clock(void); -extern int APIC_init_uniprocessor(void); -extern void enable_NMI_through_LVT0(void *dummy); - -#define ARCH_APICTIMER_STOPS_ON_C3 1 - -#else /* !CONFIG_X86_LOCAL_APIC */ -static inline void lapic_shutdown(void) { } -#define local_apic_timer_c2_ok 1 - -#endif /* !CONFIG_X86_LOCAL_APIC */ - -#endif /* __ASM_APIC_H */ diff --git a/include/asm-x86/apic_64.h b/include/asm-x86/apic_64.h deleted file mode 100644 index 9d0c06c4df9..00000000000 --- a/include/asm-x86/apic_64.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef __ASM_APIC_H -#define __ASM_APIC_H - -#include -#include -#include -#include -#include - -#define Dprintk(x...) - -/* - * Debugging macros - */ -#define APIC_QUIET 0 -#define APIC_VERBOSE 1 -#define APIC_DEBUG 2 - -extern int apic_verbosity; -extern int apic_runs_main_timer; -extern int ioapic_force; -extern int disable_apic_timer; - -/* - * Define the default level of output to be very little - * This can be turned up by using apic=verbose for more - * information and apic=debug for _lots_ of information. - * apic_verbosity is defined in apic.c - */ -#define apic_printk(v, s, a...) do { \ - if ((v) <= apic_verbosity) \ - printk(s, ##a); \ - } while (0) - -struct pt_regs; - -/* - * Basic functions accessing APICs. - */ - -static __inline void apic_write(unsigned long reg, u32 v) -{ - *((volatile unsigned int *)(APIC_BASE+reg)) = v; -} - -static __inline u32 apic_read(unsigned long reg) -{ - return *((volatile u32 *)(APIC_BASE+reg)); -} - -extern void apic_wait_icr_idle(void); -extern u32 safe_apic_wait_icr_idle(void); - -static inline void ack_APIC_irq(void) -{ - /* - * ack_APIC_irq() actually gets compiled as a single instruction: - * - a single rmw on Pentium/82489DX - * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC) - * ... yummie. - */ - - /* Docs say use 0 for future compatibility */ - apic_write(APIC_EOI, 0); -} - -extern int lapic_get_maxlvt(void); -extern void clear_local_APIC(void); -extern void connect_bsp_APIC(void); -extern void disconnect_bsp_APIC(int virt_wire_setup); -extern void disable_local_APIC(void); -extern void lapic_shutdown(void); -extern int verify_local_APIC(void); -extern void cache_APIC_registers(void); -extern void sync_Arb_IDs(void); -extern void init_bsp_APIC(void); -extern void setup_local_APIC(void); -extern void init_apic_mappings(void); -extern void smp_local_timer_interrupt(void); -extern void setup_boot_APIC_clock(void); -extern void setup_secondary_APIC_clock(void); -extern int APIC_init_uniprocessor(void); -extern void setup_apic_routing(void); - -extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, - unsigned char msg_type, unsigned char mask); - -extern int apic_is_clustered_box(void); - -#define ARCH_APICTIMER_STOPS_ON_C3 1 - -extern unsigned boot_cpu_id; -extern int local_apic_timer_c2_ok; - -#endif /* __ASM_APIC_H */ -- cgit v1.2.2 From 63fefb7d5bac6e65b5df2b7eb4aa56bb4bbadd48 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:15 +0100 Subject: x86: remove duplicated declarations Remove declarations which are made already in the appropriate header file. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/io_apic_64.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_apic_64.h b/include/asm-x86/io_apic_64.h index e2c13675ee4..762a841b939 100644 --- a/include/asm-x86/io_apic_64.h +++ b/include/asm-x86/io_apic_64.h @@ -129,10 +129,4 @@ extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int); extern int sis_apic_bug; /* dummy */ -void enable_NMI_through_LVT0 (void * dummy); - -extern spinlock_t i8259A_lock; - -extern int timer_over_8254; - #endif -- cgit v1.2.2 From 376ff0352c24a5fa47f1250dd60937b5a9077672 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:16 +0100 Subject: x86: move acpi and pci declarations Move acpi/pci related declarations to the correct headers and remove the duplicate. Build fix from: Andrew Morton Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/acpi_32.h | 2 -- include/asm-x86/pci.h | 4 +++- include/asm-x86/proto.h | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/acpi_32.h b/include/asm-x86/acpi_32.h index 723493e6c85..3cce5a0f2d9 100644 --- a/include/asm-x86/acpi_32.h +++ b/include/asm-x86/acpi_32.h @@ -81,8 +81,6 @@ int __acpi_release_global_lock(unsigned int *lock); :"=r"(n_hi), "=r"(n_lo) \ :"0"(n_hi), "1"(n_lo)) -extern void early_quirks(void); - #ifdef CONFIG_ACPI extern int acpi_lapic; extern int acpi_ioapic; diff --git a/include/asm-x86/pci.h b/include/asm-x86/pci.h index e8836196634..6983730d86f 100644 --- a/include/asm-x86/pci.h +++ b/include/asm-x86/pci.h @@ -66,6 +66,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, #ifdef CONFIG_PCI +extern void early_quirks(void); static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -73,9 +74,10 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#else +static inline void early_quirks(void) { } #endif - #endif /* __KERNEL__ */ #ifdef CONFIG_X86_32 diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index dabba55f7ed..64fe816ea37 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -58,8 +58,6 @@ extern void show_registers(struct pt_regs *regs); extern void exception_table_check(void); -extern void acpi_reserve_bootmem(void); - extern void swap_low_mappings(void); extern void __show_regs(struct pt_regs * regs); @@ -69,7 +67,6 @@ extern void syscall32_cpu_init(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); -extern void early_quirks(void); extern void check_efer(void); extern void select_idle_routine(const struct cpuinfo_x86 *c); -- cgit v1.2.2 From 8c61b900ebb8ec5918ffd776ba1a61a5f022566d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:16 +0100 Subject: x86: make early_indentify_cpu static early_indentify_cpu is only used in setup_64.c Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/proto.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 64fe816ea37..9e3d51fd91a 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -40,8 +40,6 @@ extern int nohpet; extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); -extern void early_identify_cpu(struct cpuinfo_x86 *c); - extern int k8_scan_nodes(unsigned long start, unsigned long end); extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); -- cgit v1.2.2 From fc36367211931cd503f050e4ceff5d9864cec817 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:16 +0100 Subject: x86: move idle related declarations Move idle related declarations to processor_64.h, where the the others are as well. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/processor_64.h | 4 ++++ include/asm-x86/proto.h | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index e4f19970a82..6b96e1f12a4 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -434,6 +434,10 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx) extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); +extern int force_mwait; + +extern void select_idle_routine(const struct cpuinfo_x86 *c); + #define stack_current() \ ({ \ struct thread_info *ti; \ diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 9e3d51fd91a..77b4177d17f 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -67,8 +67,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long en extern void check_efer(void); -extern void select_idle_routine(const struct cpuinfo_x86 *c); - extern unsigned long table_start, table_end; extern int exception_trace; @@ -80,8 +78,6 @@ extern int notsc_setup(char *); extern int gsi_irq_sharing(int gsi); -extern int force_mwait; - long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1)) -- cgit v1.2.2 From c9ff03428f24219b927d9d9d3c0c581622967794 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:16 +0100 Subject: x86: move k8 related declarations Move k8 related declarations to k8.h and fix numa_64.c Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/k8.h | 1 + include/asm-x86/proto.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/k8.h b/include/asm-x86/k8.h index 699dd6961ed..452e2b696ff 100644 --- a/include/asm-x86/k8.h +++ b/include/asm-x86/k8.h @@ -10,5 +10,6 @@ extern struct pci_dev **k8_northbridges; extern int num_k8_northbridges; extern int cache_k8_northbridges(void); extern void k8_flush_garts(void); +extern int k8_scan_nodes(unsigned long start, unsigned long end); #endif diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 77b4177d17f..9b96dae5b7a 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -40,8 +40,6 @@ extern int nohpet; extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); -extern int k8_scan_nodes(unsigned long start, unsigned long end); - extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); extern unsigned long numa_free_all_bootmem(void); -- cgit v1.2.2 From 718fc13b4675470ea191522ef98b02a55d990fa1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:17 +0100 Subject: x86: move debug related declarations to kdebug.h Move them and fixup some users. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/arch_hooks.h | 5 +---- include/asm-x86/kdebug.h | 5 +++++ include/asm-x86/processor_32.h | 1 - include/asm-x86/proto.h | 8 -------- include/asm-x86/system_32.h | 1 - 5 files changed, 6 insertions(+), 14 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/arch_hooks.h b/include/asm-x86/arch_hooks.h index a8c1fca9726..768aee8a04e 100644 --- a/include/asm-x86/arch_hooks.h +++ b/include/asm-x86/arch_hooks.h @@ -6,7 +6,7 @@ /* * linux/include/asm/arch_hooks.h * - * define the architecture specific hooks + * define the architecture specific hooks */ /* these aren't arch hooks, they are generic routines @@ -24,7 +24,4 @@ extern void trap_init_hook(void); extern void time_init_hook(void); extern void mca_nmi_hook(void); -extern int setup_early_printk(char *); -extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); - #endif diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index e2f9b62e535..49e5c91d490 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -22,10 +22,15 @@ enum die_val { DIE_PAGE_FAULT, }; +extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); extern void printk_address(unsigned long address); extern void die(const char *,struct pt_regs *,long); extern void __die(const char *,struct pt_regs *,long); extern void show_registers(struct pt_regs *regs); +extern void __show_registers(struct pt_regs *, int all); +extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long *); +extern void __show_regs(struct pt_regs *regs); +extern void show_regs(struct pt_regs *regs); extern void dump_pagetable(unsigned long); extern unsigned long oops_begin(void); extern void oops_end(unsigned long); diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 13976b08683..58880a1ddd6 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -423,7 +423,6 @@ extern void prepare_to_copy(struct task_struct *tsk); extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); extern unsigned long thread_saved_pc(struct task_struct *tsk); -void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack); unsigned long get_wchan(struct task_struct *p); diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 9b96dae5b7a..b10cd1b8208 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -38,8 +38,6 @@ extern u32 pmtmr_ioport; #endif extern int nohpet; -extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); - extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); extern unsigned long numa_free_all_bootmem(void); @@ -49,16 +47,10 @@ extern void load_gs_index(unsigned gs); extern unsigned long end_pfn_map; -extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long * rsp); -extern void show_registers(struct pt_regs *regs); - extern void exception_table_check(void); extern void swap_low_mappings(void); -extern void __show_regs(struct pt_regs * regs); -extern void show_regs(struct pt_regs * regs); - extern void syscall32_cpu_init(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index ef8468883ba..db6283eb5e4 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -315,6 +315,5 @@ extern unsigned long arch_align_stack(unsigned long sp); extern void free_init_pages(char *what, unsigned long begin, unsigned long end); void default_idle(void); -void __show_registers(struct pt_regs *, int all); #endif -- cgit v1.2.2 From af7a78e9258ffcca681e080cbc857f854869144f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:17 +0100 Subject: x86: move mce related declarations Move the mce related declarations where they belong, fix the users and remove 32bit dependency in mce.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/mce.h | 14 +++++++------- include/asm-x86/proto.h | 1 - 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mce.h b/include/asm-x86/mce.h index df304fd89c2..e6ff507a73b 100644 --- a/include/asm-x86/mce.h +++ b/include/asm-x86/mce.h @@ -85,14 +85,7 @@ struct mce_log { #ifdef __KERNEL__ #ifdef CONFIG_X86_32 -#ifdef CONFIG_X86_MCE -extern void mcheck_init(struct cpuinfo_x86 *c); -#else -#define mcheck_init(c) do {} while(0) -#endif - extern int mce_disabled; - #else /* CONFIG_X86_32 */ #include @@ -121,6 +114,13 @@ extern int mce_notify_user(void); #endif /* !CONFIG_X86_32 */ + + +#ifdef CONFIG_X86_MCE +extern void mcheck_init(struct cpuinfo_x86 *c); +#else +#define mcheck_init(c) do { } while (0) +#endif extern void stop_mce(void); extern void restart_mce(void); diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index b10cd1b8208..02420dea73c 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -13,7 +13,6 @@ extern void pda_init(int); extern void early_idt_handler(void); -extern void mcheck_init(struct cpuinfo_x86 *c); extern void init_memory_mapping(unsigned long start, unsigned long end); extern void system_call(void); -- cgit v1.2.2 From aaa64e04f9af8c05a10ab3d67df44154742d15cf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:17 +0100 Subject: x86: move numa related declarations More stuff shuffeled to the correct place Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/numa_64.h | 6 ++++++ include/asm-x86/proto.h | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index 0cc5c97a7fc..e6bc0b5dfe3 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h @@ -21,6 +21,12 @@ extern void srat_reserve_add_area(int nodeid); extern int hotadd_percent; extern unsigned char apicid_to_node[MAX_LOCAL_APIC]; + +extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); +extern unsigned long numa_free_all_bootmem(void); +extern void setup_node_bootmem(int nodeid, unsigned long start, + unsigned long end); + #ifdef CONFIG_NUMA extern void __init init_cpu_to_node(void); diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 02420dea73c..71a419c6e04 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -37,9 +37,6 @@ extern u32 pmtmr_ioport; #endif extern int nohpet; -extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); -extern unsigned long numa_free_all_bootmem(void); - extern void reserve_bootmem_generic(unsigned long phys, unsigned len); extern void load_gs_index(unsigned gs); @@ -52,8 +49,6 @@ extern void swap_low_mappings(void); extern void syscall32_cpu_init(void); -extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); - extern void check_efer(void); extern unsigned long table_start, table_end; -- cgit v1.2.2 From a89518b882283fdb3e11fb6d1929dc874b380ca8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:17 +0100 Subject: x86: move page related declaration end_pfn is in page.h, so end_pfn_map has a place there as well Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/page_64.h | 1 + include/asm-x86/proto.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index c3b52bcb171..6fdc904a5fa 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -41,6 +41,7 @@ #ifndef __ASSEMBLY__ extern unsigned long end_pfn; +extern unsigned long end_pfn_map; void clear_page(void *); void copy_page(void *, void *); diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 71a419c6e04..7ff3d765de0 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -41,8 +41,6 @@ extern void reserve_bootmem_generic(unsigned long phys, unsigned len); extern void load_gs_index(unsigned gs); -extern unsigned long end_pfn_map; - extern void exception_table_check(void); extern void swap_low_mappings(void); -- cgit v1.2.2 From 40fec50ac4dd436b06630f415789e57200c5b06f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:18 +0100 Subject: x86: move pda related declaration pda has its own header file as well. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/pda.h | 1 + include/asm-x86/proto.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pda.h b/include/asm-x86/pda.h index 35962bbe5e7..3d9dd653628 100644 --- a/include/asm-x86/pda.h +++ b/include/asm-x86/pda.h @@ -40,6 +40,7 @@ struct x8664_pda { extern struct x8664_pda *_cpu_pda[]; extern struct x8664_pda boot_cpu_pda[]; +extern void pda_init(int); #define cpu_pda(i) (_cpu_pda[i]) diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 7ff3d765de0..8ed1ebf666b 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -9,7 +9,6 @@ struct cpuinfo_x86; struct pt_regs; extern void start_kernel(void); -extern void pda_init(int); extern void early_idt_handler(void); -- cgit v1.2.2 From 80ca9c98f50c11b63b87971594d7e38cba0bbcef Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:18 +0100 Subject: x86: move tsc related declarations tsc has also it's own header file. Nuke the stupid 64 bit ifdef while at it. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/proto.h | 3 --- include/asm-x86/tsc.h | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 8ed1ebf666b..a47e526716f 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -51,11 +51,8 @@ extern void check_efer(void); extern unsigned long table_start, table_end; extern int exception_trace; -extern unsigned cpu_khz; -extern unsigned tsc_khz; extern int reboot_force; -extern int notsc_setup(char *); extern int gsi_irq_sharing(int gsi); diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index 6baab30dc2c..d7b1c4e7a10 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -73,8 +73,7 @@ int check_tsc_unstable(void); extern void check_tsc_sync_source(int cpu); extern void check_tsc_sync_target(void); -#ifdef CONFIG_X86_64 extern void tsc_calibrate(void); -#endif +extern int notsc_setup(char *); #endif -- cgit v1.2.2 From 70a20025632ca320316b5068326784d07c8ff351 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:18 +0100 Subject: x86: move pmtmr related declarations Move more stuff out of proto.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/proto.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index a47e526716f..9074aa7ebc6 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -25,15 +25,6 @@ extern void ia32_sysenter_target(void); extern void config_acpi_tables(void); extern void ia32_syscall(void); -extern int pmtimer_mark_offset(void); -extern void pmtimer_resume(void); -extern void pmtimer_wait(unsigned); -extern unsigned int do_gettimeoffset_pm(void); -#ifdef CONFIG_X86_PM_TIMER -extern u32 pmtmr_ioport; -#else -#define pmtmr_ioport 0 -#endif extern int nohpet; extern void reserve_bootmem_generic(unsigned long phys, unsigned len); -- cgit v1.2.2 From 6fc30f9e292d2275248b6ee5ca903248b66efca1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:18 +0100 Subject: x86: remove obsolete nohpet declaration Lonely user is hpet.c, so no need to declare it elsewhere. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/proto.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 9074aa7ebc6..4eddf276180 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -25,8 +25,6 @@ extern void ia32_sysenter_target(void); extern void config_acpi_tables(void); extern void ia32_syscall(void); -extern int nohpet; - extern void reserve_bootmem_generic(unsigned long phys, unsigned len); extern void load_gs_index(unsigned gs); -- cgit v1.2.2 From eaf76e8b93dd5e7a53e2cd6db53f3ca18ca0fe4c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:19 +0100 Subject: x86: remove duplicate start_kernel declaration start_kernel is already declared in a generic header file. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/proto.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 4eddf276180..5a45478b5d3 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -8,8 +8,6 @@ struct cpuinfo_x86; struct pt_regs; -extern void start_kernel(void); - extern void early_idt_handler(void); extern void init_memory_mapping(unsigned long start, unsigned long end); -- cgit v1.2.2 From 84c873ed2a00eab3e8ac49dc7889d7aad142ce22 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:19 +0100 Subject: x86: remove obsolte declarations from proto.h Nuke duplicate and obsolete crap from this ugly dump bin. There are still some entries left which need to be sorted out, but I'm tired of that puzzle game right now. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/proto.h | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 5a45478b5d3..3c6fb89f112 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -5,44 +5,27 @@ /* misc architecture specific prototypes */ -struct cpuinfo_x86; -struct pt_regs; - extern void early_idt_handler(void); extern void init_memory_mapping(unsigned long start, unsigned long end); -extern void system_call(void); -extern int kernel_syscall(void); +extern void system_call(void); extern void syscall_init(void); extern void ia32_syscall(void); -extern void ia32_cstar_target(void); -extern void ia32_sysenter_target(void); - -extern void config_acpi_tables(void); -extern void ia32_syscall(void); +extern void ia32_cstar_target(void); +extern void ia32_sysenter_target(void); extern void reserve_bootmem_generic(unsigned long phys, unsigned len); -extern void load_gs_index(unsigned gs); - -extern void exception_table_check(void); - -extern void swap_low_mappings(void); - extern void syscall32_cpu_init(void); extern void check_efer(void); extern unsigned long table_start, table_end; -extern int exception_trace; - extern int reboot_force; -extern int gsi_irq_sharing(int gsi); - long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1)) -- cgit v1.2.2 From 3e35a0e525253837fc0ea4d0e060de3302bd9537 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:19 +0100 Subject: x86: move ioapic code where it belongs The commit 399287229c775a8962a852a761d65dc9475dec7c hacked the ioapic resource mapping into apic.c for no good reason. Move the code into io_apic_64.c where it belongs. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/io_apic_64.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_apic_64.h b/include/asm-x86/io_apic_64.h index 762a841b939..3e3c2114d93 100644 --- a/include/asm-x86/io_apic_64.h +++ b/include/asm-x86/io_apic_64.h @@ -127,6 +127,8 @@ extern int io_apic_get_redir_entries (int ioapic); extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int); #endif +extern void ioapic_init_mappings(void); + extern int sis_apic_bug; /* dummy */ #endif -- cgit v1.2.2 From 3a12d93dc0b46bc710317272bf91640d7a8b6f18 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:20 +0100 Subject: x86: make smp_local_timer_interrupt() static Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/apic.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index c064c1f84ba..d0a221fa1fc 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -112,7 +112,6 @@ extern void sync_Arb_IDs(void); extern void init_bsp_APIC(void); extern void setup_local_APIC(void); extern void init_apic_mappings(void); -extern void smp_local_timer_interrupt(void); extern void setup_boot_APIC_clock(void); extern void setup_secondary_APIC_clock(void); extern int APIC_init_uniprocessor(void); -- cgit v1.2.2 From 2f2239d1d53b06dd475634f79e1905f3775fcedc Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:20 +0100 Subject: x86: prepare merging futex_32/64.h Replace .quad/.long with a define and use the same asm syntax for i386 and x86. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/futex_32.h | 64 ++++++++++++++++++++++------------------------ include/asm-x86/futex_64.h | 24 +++++++++-------- 2 files changed, 44 insertions(+), 44 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/futex_32.h b/include/asm-x86/futex_32.h index 438ef0ec710..c80013e19c2 100644 --- a/include/asm-x86/futex_32.h +++ b/include/asm-x86/futex_32.h @@ -4,6 +4,8 @@ #ifdef __KERNEL__ #include + +#include #include #include #include @@ -17,13 +19,13 @@ jmp 2b\n\ .previous\n\ .section __ex_table,\"a\"\n\ - .align 8\n\ - .long 1b,3b\n\ + .align 8\n" \ + _ASM_PTR "1b,3b\n \ .previous" \ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ : "i" (-EFAULT), "0" (oparg), "1" (0)) -#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ __asm__ __volatile ( \ "1: movl %2, %0\n\ movl %0, %3\n" \ @@ -35,8 +37,8 @@ jmp 3b\n\ .previous\n\ .section __ex_table,\"a\"\n\ - .align 8\n\ - .long 1b,4b,2b,4b\n\ + .align 8\n" \ + _ASM_PTR "1b,4b,2b,4b\n \ .previous" \ : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \ "=&r" (tem) \ @@ -56,36 +58,32 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; +#ifndef CONFIG_X86_BSWAP + if (op == FUTEX_OP_SET && boot_cpu_data.x86 == 3) + return -ENOSYS; +#endif + pagefault_disable(); - if (op == FUTEX_OP_SET) + switch (op) { + case FUTEX_OP_SET: __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); - else { -#ifndef CONFIG_X86_BSWAP - if (boot_cpu_data.x86 == 3) - ret = -ENOSYS; - else -#endif - switch (op) { - case FUTEX_OP_ADD: - __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, - oldval, uaddr, oparg); - break; - case FUTEX_OP_OR: - __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, - oparg); - break; - case FUTEX_OP_ANDN: - __futex_atomic_op2("andl %4, %3", ret, oldval, uaddr, - ~oparg); - break; - case FUTEX_OP_XOR: - __futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, - oparg); - break; - default: - ret = -ENOSYS; - } + break; + case FUTEX_OP_ADD: + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval, + uaddr, oparg); + break; + case FUTEX_OP_OR: + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg); + break; + case FUTEX_OP_ANDN: + __futex_atomic_op2("andl %4, %3", ret, oldval, uaddr, ~oparg); + break; + case FUTEX_OP_XOR: + __futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, oparg); + break; + default: + ret = -ENOSYS; } pagefault_enable(); @@ -120,7 +118,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) " .section __ex_table, \"a\" \n" " .align 8 \n" - " .long 1b,3b \n" + _ASM_PTR " 1b,3b \n" " .previous \n" : "=a" (oldval), "+m" (*uaddr) diff --git a/include/asm-x86/futex_64.h b/include/asm-x86/futex_64.h index 5cdfb08013c..02964d225d1 100644 --- a/include/asm-x86/futex_64.h +++ b/include/asm-x86/futex_64.h @@ -4,6 +4,8 @@ #ifdef __KERNEL__ #include + +#include #include #include #include @@ -16,13 +18,13 @@ jmp 2b\n\ .previous\n\ .section __ex_table,\"a\"\n\ - .align 8\n\ - .quad 1b,3b\n\ + .align 8\n" \ + _ASM_PTR "1b,3b\n \ .previous" \ - : "=r" (oldval), "=r" (ret), "=m" (*uaddr) \ - : "i" (-EFAULT), "m" (*uaddr), "0" (oparg), "1" (0)) + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ + : "i" (-EFAULT), "0" (oparg), "1" (0)) -#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ __asm__ __volatile ( \ "1: movl %2, %0\n\ movl %0, %3\n" \ @@ -34,12 +36,12 @@ jmp 3b\n\ .previous\n\ .section __ex_table,\"a\"\n\ - .align 8\n\ - .quad 1b,4b,2b,4b\n\ + .align 8\n" \ + _ASM_PTR "1b,4b,2b,4b\n \ .previous" \ - : "=&a" (oldval), "=&r" (ret), "=m" (*uaddr), \ + : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \ "=&r" (tem) \ - : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0)) + : "r" (oparg), "i" (-EFAULT), "1" (0)) static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) @@ -110,10 +112,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) " .section __ex_table, \"a\" \n" " .align 8 \n" - " .quad 1b,3b \n" + _ASM_PTR " 1b,3b \n" " .previous \n" - : "=a" (oldval), "=m" (*uaddr) + : "=a" (oldval), "+m" (*uaddr) : "i" (-EFAULT), "r" (newval), "0" (oldval) : "memory" ); -- cgit v1.2.2 From 2f18e47c89f1a29cc815cd225b72dd7fd86acffe Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:20 +0100 Subject: x86: merge futex_32/64.h Finally merge them together. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/futex.h | 138 +++++++++++++++++++++++++++++++++++++++++++-- include/asm-x86/futex_32.h | 133 ------------------------------------------- include/asm-x86/futex_64.h | 127 ----------------------------------------- 3 files changed, 134 insertions(+), 264 deletions(-) delete mode 100644 include/asm-x86/futex_32.h delete mode 100644 include/asm-x86/futex_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h index 1f4610e0c61..62828d63f1b 100644 --- a/include/asm-x86/futex.h +++ b/include/asm-x86/futex.h @@ -1,5 +1,135 @@ -#ifdef CONFIG_X86_32 -# include "futex_32.h" -#else -# include "futex_64.h" +#ifndef _ASM_X86_FUTEX_H +#define _ASM_X86_FUTEX_H + +#ifdef __KERNEL__ + +#include + +#include +#include +#include +#include +#include + +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \ + __asm__ __volatile( \ +"1: " insn "\n" \ +"2: .section .fixup,\"ax\"\n \ +3: mov %3, %1\n \ + jmp 2b\n \ + .previous\n \ + .section __ex_table,\"a\"\n \ + .align 8\n" \ + _ASM_PTR "1b,3b\n \ + .previous" \ + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ + : "i" (-EFAULT), "0" (oparg), "1" (0)) + +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ + __asm__ __volatile( \ +"1: movl %2, %0\n \ + movl %0, %3\n" \ + insn "\n" \ +"2: " LOCK_PREFIX "cmpxchgl %3, %2\n \ + jnz 1b\n \ +3: .section .fixup,\"ax\"\n \ +4: mov %5, %1\n \ + jmp 3b\n \ + .previous\n \ + .section __ex_table,\"a\"\n \ + .align 8\n" \ + _ASM_PTR "1b,4b,2b,4b\n \ + .previous" \ + : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \ + "=&r" (tem) \ + : "r" (oparg), "i" (-EFAULT), "1" (0)) + +static inline int +futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +{ + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; + int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret, tem; + + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) + oparg = 1 << oparg; + + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + +#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP) + /* Real i386 machines can only support FUTEX_OP_SET */ + if (op != FUTEX_OP_SET && boot_cpu_data.x86 == 3) + return -ENOSYS; +#endif + + pagefault_disable(); + + switch (op) { + case FUTEX_OP_SET: + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); + break; + case FUTEX_OP_ADD: + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval, + uaddr, oparg); + break; + case FUTEX_OP_OR: + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg); + break; + case FUTEX_OP_ANDN: + __futex_atomic_op2("andl %4, %3", ret, oldval, uaddr, ~oparg); + break; + case FUTEX_OP_XOR: + __futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, oparg); + break; + default: + ret = -ENOSYS; + } + + pagefault_enable(); + + if (!ret) { + switch (cmp) { + case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; + case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; + case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; + case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; + case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; + case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; + default: ret = -ENOSYS; + } + } + return ret; +} + +static inline int +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) +{ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + + __asm__ __volatile__( + "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n" + + "2: .section .fixup, \"ax\" \n" + "3: mov %2, %0 \n" + " jmp 2b \n" + " .previous \n" + + " .section __ex_table, \"a\" \n" + " .align 8 \n" + _ASM_PTR " 1b,3b \n" + " .previous \n" + + : "=a" (oldval), "+m" (*uaddr) + : "i" (-EFAULT), "r" (newval), "0" (oldval) + : "memory" + ); + + return oldval; +} + +#endif #endif diff --git a/include/asm-x86/futex_32.h b/include/asm-x86/futex_32.h deleted file mode 100644 index c80013e19c2..00000000000 --- a/include/asm-x86/futex_32.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#ifdef __KERNEL__ - -#include - -#include -#include -#include -#include -#include - -#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \ - __asm__ __volatile ( \ -"1: " insn "\n" \ -"2: .section .fixup,\"ax\"\n\ -3: mov %3, %1\n\ - jmp 2b\n\ - .previous\n\ - .section __ex_table,\"a\"\n\ - .align 8\n" \ - _ASM_PTR "1b,3b\n \ - .previous" \ - : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ - : "i" (-EFAULT), "0" (oparg), "1" (0)) - -#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ - __asm__ __volatile ( \ -"1: movl %2, %0\n\ - movl %0, %3\n" \ - insn "\n" \ -"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\ - jnz 1b\n\ -3: .section .fixup,\"ax\"\n\ -4: mov %5, %1\n\ - jmp 3b\n\ - .previous\n\ - .section __ex_table,\"a\"\n\ - .align 8\n" \ - _ASM_PTR "1b,4b,2b,4b\n \ - .previous" \ - : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \ - "=&r" (tem) \ - : "r" (oparg), "i" (-EFAULT), "1" (0)) - -static inline int -futex_atomic_op_inuser (int encoded_op, int __user *uaddr) -{ - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; - int oldval = 0, ret, tem; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - -#ifndef CONFIG_X86_BSWAP - if (op == FUTEX_OP_SET && boot_cpu_data.x86 == 3) - return -ENOSYS; -#endif - - pagefault_disable(); - - switch (op) { - case FUTEX_OP_SET: - __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); - break; - case FUTEX_OP_ADD: - __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval, - uaddr, oparg); - break; - case FUTEX_OP_OR: - __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg); - break; - case FUTEX_OP_ANDN: - __futex_atomic_op2("andl %4, %3", ret, oldval, uaddr, ~oparg); - break; - case FUTEX_OP_XOR: - __futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, oparg); - break; - default: - ret = -ENOSYS; - } - - pagefault_enable(); - - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } - return ret; -} - -static inline int -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) -{ - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - - __asm__ __volatile__( - "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n" - - "2: .section .fixup, \"ax\" \n" - "3: mov %2, %0 \n" - " jmp 2b \n" - " .previous \n" - - " .section __ex_table, \"a\" \n" - " .align 8 \n" - _ASM_PTR " 1b,3b \n" - " .previous \n" - - : "=a" (oldval), "+m" (*uaddr) - : "i" (-EFAULT), "r" (newval), "0" (oldval) - : "memory" - ); - - return oldval; -} - -#endif -#endif diff --git a/include/asm-x86/futex_64.h b/include/asm-x86/futex_64.h deleted file mode 100644 index 02964d225d1..00000000000 --- a/include/asm-x86/futex_64.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#ifdef __KERNEL__ - -#include - -#include -#include -#include -#include - -#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \ - __asm__ __volatile ( \ -"1: " insn "\n" \ -"2: .section .fixup,\"ax\"\n\ -3: mov %3, %1\n\ - jmp 2b\n\ - .previous\n\ - .section __ex_table,\"a\"\n\ - .align 8\n" \ - _ASM_PTR "1b,3b\n \ - .previous" \ - : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ - : "i" (-EFAULT), "0" (oparg), "1" (0)) - -#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ - __asm__ __volatile ( \ -"1: movl %2, %0\n\ - movl %0, %3\n" \ - insn "\n" \ -"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\ - jnz 1b\n\ -3: .section .fixup,\"ax\"\n\ -4: mov %5, %1\n\ - jmp 3b\n\ - .previous\n\ - .section __ex_table,\"a\"\n\ - .align 8\n" \ - _ASM_PTR "1b,4b,2b,4b\n \ - .previous" \ - : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \ - "=&r" (tem) \ - : "r" (oparg), "i" (-EFAULT), "1" (0)) - -static inline int -futex_atomic_op_inuser (int encoded_op, int __user *uaddr) -{ - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; - int oldval = 0, ret, tem; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - - pagefault_disable(); - - switch (op) { - case FUTEX_OP_SET: - __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); - break; - case FUTEX_OP_ADD: - __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval, - uaddr, oparg); - break; - case FUTEX_OP_OR: - __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg); - break; - case FUTEX_OP_ANDN: - __futex_atomic_op2("andl %4, %3", ret, oldval, uaddr, ~oparg); - break; - case FUTEX_OP_XOR: - __futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, oparg); - break; - default: - ret = -ENOSYS; - } - - pagefault_enable(); - - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } - return ret; -} - -static inline int -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) -{ - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - - __asm__ __volatile__( - "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n" - - "2: .section .fixup, \"ax\" \n" - "3: mov %2, %0 \n" - " jmp 2b \n" - " .previous \n" - - " .section __ex_table, \"a\" \n" - " .align 8 \n" - _ASM_PTR " 1b,3b \n" - " .previous \n" - - : "=a" (oldval), "+m" (*uaddr) - : "i" (-EFAULT), "r" (newval), "0" (oldval) - : "memory" - ); - - return oldval; -} - -#endif -#endif -- cgit v1.2.2 From f28b8d608829aecd7343015a0df89f6b6e89d391 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:20 +0100 Subject: x86: merge include/asm-x86/dma.h Almost identical. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/dma.h | 318 ++++++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/dma_32.h | 297 ------------------------------------------- include/asm-x86/dma_64.h | 304 -------------------------------------------- 3 files changed, 316 insertions(+), 603 deletions(-) delete mode 100644 include/asm-x86/dma_32.h delete mode 100644 include/asm-x86/dma_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/dma.h b/include/asm-x86/dma.h index 9f936c61a4e..e9733ce8988 100644 --- a/include/asm-x86/dma.h +++ b/include/asm-x86/dma.h @@ -1,5 +1,319 @@ +/* + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef _ASM_X86_DMA_H +#define _ASM_X86_DMA_H + +#include /* And spinlocks */ +#include /* need byte IO */ +#include + + +#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER +#define dma_outb outb_p +#else +#define dma_outb outb +#endif + +#define dma_inb inb + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + #ifdef CONFIG_X86_32 -# include "dma_32.h" + +/* The maximum address that we can perform a DMA transfer to on this platform */ +#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) + +#else + +/* 16MB ISA DMA zone */ +#define MAX_DMA_PFN ((16*1024*1024) >> PAGE_SHIFT) + +/* 4GB broken PCI/AGP hardware bus master zone */ +#define MAX_DMA32_PFN ((4UL*1024*1024*1024) >> PAGE_SHIFT) + +/* Compat define for old dma zone */ +#define MAX_DMA_ADDRESS ((unsigned long)__va(MAX_DMA_PFN << PAGE_SHIFT)) + +#endif + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_PAGE_0 0x87 /* DMA page registers */ +#define DMA_PAGE_1 0x83 +#define DMA_PAGE_2 0x81 +#define DMA_PAGE_3 0x82 +#define DMA_PAGE_5 0x8B +#define DMA_PAGE_6 0x89 +#define DMA_PAGE_7 0x8A + +/* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_READ 0x44 +/* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 +/* pass thru DREQ->HRQ, DACK<-HLDA only */ +#define DMA_MODE_CASCADE 0xC0 + +#define DMA_AUTOINIT 0x10 + + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr <= 3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr <= 3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr <= 3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr <= 3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr & 3), DMA2_MODE_REG); +} + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + switch (dmanr) { + case 0: + dma_outb(pagenr, DMA_PAGE_0); + break; + case 1: + dma_outb(pagenr, DMA_PAGE_1); + break; + case 2: + dma_outb(pagenr, DMA_PAGE_2); + break; + case 3: + dma_outb(pagenr, DMA_PAGE_3); + break; + case 5: + dma_outb(pagenr & 0xfe, DMA_PAGE_5); + break; + case 6: + dma_outb(pagenr & 0xfe, DMA_PAGE_6); + break; + case 7: + dma_outb(pagenr & 0xfe, DMA_PAGE_7); + break; + } +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + set_dma_page(dmanr, a>>16); + if (dmanr <= 3) { + dma_outb(a & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE); + dma_outb((a >> 8) & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE); + } else { + dma_outb((a >> 1) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); + dma_outb((a >> 9) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); + } +} + + +/* Set transfer size (max 64k for DMA0..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb(count & 0xff, ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); + dma_outb((count >> 8) & 0xff, + ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); + } else { + dma_outb((count >> 1) & 0xff, + ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); + dma_outb((count >> 9) & 0xff, + ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port; + /* using short to get 16-bit wrap around */ + unsigned short count; + + io_port = (dmanr <= 3) ? ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE + : ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr <= 3) ? count : (count << 1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char *device_id); +extern void free_dma(unsigned int dmanr); + +/* From PCI */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; #else -# include "dma_64.h" +#define isa_dma_bridge_buggy (0) #endif + +#endif /* _ASM_X86_DMA_H */ diff --git a/include/asm-x86/dma_32.h b/include/asm-x86/dma_32.h deleted file mode 100644 index d23aac8e1a5..00000000000 --- a/include/asm-x86/dma_32.h +++ /dev/null @@ -1,297 +0,0 @@ -/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ - * linux/include/asm/dma.h: Defines for using and allocating dma channels. - * Written by Hennus Bergman, 1992. - * High DMA channel support & info by Hannu Savolainen - * and John Boyd, Nov. 1992. - */ - -#ifndef _ASM_DMA_H -#define _ASM_DMA_H - -#include /* And spinlocks */ -#include /* need byte IO */ -#include - - -#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER -#define dma_outb outb_p -#else -#define dma_outb outb -#endif - -#define dma_inb inb - -/* - * NOTES about DMA transfers: - * - * controller 1: channels 0-3, byte operations, ports 00-1F - * controller 2: channels 4-7, word operations, ports C0-DF - * - * - ALL registers are 8 bits only, regardless of transfer size - * - channel 4 is not used - cascades 1 into 2. - * - channels 0-3 are byte - addresses/counts are for physical bytes - * - channels 5-7 are word - addresses/counts are for physical words - * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries - * - transfer count loaded to registers is 1 less than actual count - * - controller 2 offsets are all even (2x offsets for controller 1) - * - page registers for 5-7 don't use data bit 0, represent 128K pages - * - page registers for 0-3 use bit 0, represent 64K pages - * - * DMA transfers are limited to the lower 16MB of _physical_ memory. - * Note that addresses loaded into registers must be _physical_ addresses, - * not logical addresses (which may differ if paging is active). - * - * Address mapping for channels 0-3: - * - * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Address mapping for channels 5-7: - * - * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) - * | ... | \ \ ... \ \ \ ... \ \ - * | ... | \ \ ... \ \ \ ... \ (not used) - * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses - * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at - * the hardware level, so odd-byte transfers aren't possible). - * - * Transfer count (_not # bytes_) is limited to 64K, represented as actual - * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. - * - */ - -#define MAX_DMA_CHANNELS 8 - -/* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) - -/* 8237 DMA controllers */ -#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ -#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ - -/* DMA controller registers */ -#define DMA1_CMD_REG 0x08 /* command register (w) */ -#define DMA1_STAT_REG 0x08 /* status register (r) */ -#define DMA1_REQ_REG 0x09 /* request register (w) */ -#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ -#define DMA1_MODE_REG 0x0B /* mode register (w) */ -#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ -#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ -#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ -#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ -#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ - -#define DMA2_CMD_REG 0xD0 /* command register (w) */ -#define DMA2_STAT_REG 0xD0 /* status register (r) */ -#define DMA2_REQ_REG 0xD2 /* request register (w) */ -#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ -#define DMA2_MODE_REG 0xD6 /* mode register (w) */ -#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ -#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ -#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ -#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ -#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ - -#define DMA_ADDR_0 0x00 /* DMA address registers */ -#define DMA_ADDR_1 0x02 -#define DMA_ADDR_2 0x04 -#define DMA_ADDR_3 0x06 -#define DMA_ADDR_4 0xC0 -#define DMA_ADDR_5 0xC4 -#define DMA_ADDR_6 0xC8 -#define DMA_ADDR_7 0xCC - -#define DMA_CNT_0 0x01 /* DMA count registers */ -#define DMA_CNT_1 0x03 -#define DMA_CNT_2 0x05 -#define DMA_CNT_3 0x07 -#define DMA_CNT_4 0xC2 -#define DMA_CNT_5 0xC6 -#define DMA_CNT_6 0xCA -#define DMA_CNT_7 0xCE - -#define DMA_PAGE_0 0x87 /* DMA page registers */ -#define DMA_PAGE_1 0x83 -#define DMA_PAGE_2 0x81 -#define DMA_PAGE_3 0x82 -#define DMA_PAGE_5 0x8B -#define DMA_PAGE_6 0x89 -#define DMA_PAGE_7 0x8A - -#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ -#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ -#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ - -#define DMA_AUTOINIT 0x10 - - -extern spinlock_t dma_spin_lock; - -static __inline__ unsigned long claim_dma_lock(void) -{ - unsigned long flags; - spin_lock_irqsave(&dma_spin_lock, flags); - return flags; -} - -static __inline__ void release_dma_lock(unsigned long flags) -{ - spin_unlock_irqrestore(&dma_spin_lock, flags); -} - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr, DMA1_MASK_REG); - else - dma_outb(dmanr & 3, DMA2_MASK_REG); -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr | 4, DMA1_MASK_REG); - else - dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); -} - -/* Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while holding the DMA lock ! --- - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(0, DMA1_CLEAR_FF_REG); - else - dma_outb(0, DMA2_CLEAR_FF_REG); -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - if (dmanr<=3) - dma_outb(mode | dmanr, DMA1_MODE_REG); - else - dma_outb(mode | (dmanr&3), DMA2_MODE_REG); -} - -/* Set only the page register bits of the transfer address. - * This is used for successive transfers when we know the contents of - * the lower 16 bits of the DMA current address register, but a 64k boundary - * may have been crossed. - */ -static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) -{ - switch(dmanr) { - case 0: - dma_outb(pagenr, DMA_PAGE_0); - break; - case 1: - dma_outb(pagenr, DMA_PAGE_1); - break; - case 2: - dma_outb(pagenr, DMA_PAGE_2); - break; - case 3: - dma_outb(pagenr, DMA_PAGE_3); - break; - case 5: - dma_outb(pagenr & 0xfe, DMA_PAGE_5); - break; - case 6: - dma_outb(pagenr & 0xfe, DMA_PAGE_6); - break; - case 7: - dma_outb(pagenr & 0xfe, DMA_PAGE_7); - break; - } -} - - -/* Set transfer address & page bits for specific DMA channel. - * Assumes dma flipflop is clear. - */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - set_dma_page(dmanr, a>>16); - if (dmanr <= 3) { - dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - } else { - dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - } -} - - -/* Set transfer size (max 64k for DMA0..3, 128k for DMA5..7) for - * a specific DMA channel. - * You must ensure the parameters are valid. - * NOTE: from a manual: "the number of transfers is one more - * than the initial word count"! This is taken into account. - * Assumes dma flip-flop is clear. - * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - count--; - if (dmanr <= 3) { - dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - } else { - dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - } -} - - -/* Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * If called before the channel has been used, it may return 1. - * Otherwise, it returns the number of _bytes_ left to transfer. - * - * Assumes DMA flip-flop is clear. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE - : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; - - /* using short to get 16-bit wrap around */ - unsigned short count; - - count = 1 + dma_inb(io_port); - count += dma_inb(io_port) << 8; - - return (dmanr<=3)? count : (count<<1); -} - - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -/* From PCI */ - -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) -#endif - -#endif /* _ASM_DMA_H */ diff --git a/include/asm-x86/dma_64.h b/include/asm-x86/dma_64.h deleted file mode 100644 index a37c16f0628..00000000000 --- a/include/asm-x86/dma_64.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * linux/include/asm/dma.h: Defines for using and allocating dma channels. - * Written by Hennus Bergman, 1992. - * High DMA channel support & info by Hannu Savolainen - * and John Boyd, Nov. 1992. - */ - -#ifndef _ASM_DMA_H -#define _ASM_DMA_H - -#include /* And spinlocks */ -#include /* need byte IO */ -#include - - -#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER -#define dma_outb outb_p -#else -#define dma_outb outb -#endif - -#define dma_inb inb - -/* - * NOTES about DMA transfers: - * - * controller 1: channels 0-3, byte operations, ports 00-1F - * controller 2: channels 4-7, word operations, ports C0-DF - * - * - ALL registers are 8 bits only, regardless of transfer size - * - channel 4 is not used - cascades 1 into 2. - * - channels 0-3 are byte - addresses/counts are for physical bytes - * - channels 5-7 are word - addresses/counts are for physical words - * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries - * - transfer count loaded to registers is 1 less than actual count - * - controller 2 offsets are all even (2x offsets for controller 1) - * - page registers for 5-7 don't use data bit 0, represent 128K pages - * - page registers for 0-3 use bit 0, represent 64K pages - * - * DMA transfers are limited to the lower 16MB of _physical_ memory. - * Note that addresses loaded into registers must be _physical_ addresses, - * not logical addresses (which may differ if paging is active). - * - * Address mapping for channels 0-3: - * - * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Address mapping for channels 5-7: - * - * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) - * | ... | \ \ ... \ \ \ ... \ \ - * | ... | \ \ ... \ \ \ ... \ (not used) - * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses - * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at - * the hardware level, so odd-byte transfers aren't possible). - * - * Transfer count (_not # bytes_) is limited to 64K, represented as actual - * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. - * - */ - -#define MAX_DMA_CHANNELS 8 - - -/* 16MB ISA DMA zone */ -#define MAX_DMA_PFN ((16*1024*1024) >> PAGE_SHIFT) - -/* 4GB broken PCI/AGP hardware bus master zone */ -#define MAX_DMA32_PFN ((4UL*1024*1024*1024) >> PAGE_SHIFT) - -/* Compat define for old dma zone */ -#define MAX_DMA_ADDRESS ((unsigned long)__va(MAX_DMA_PFN << PAGE_SHIFT)) - -/* 8237 DMA controllers */ -#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ -#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ - -/* DMA controller registers */ -#define DMA1_CMD_REG 0x08 /* command register (w) */ -#define DMA1_STAT_REG 0x08 /* status register (r) */ -#define DMA1_REQ_REG 0x09 /* request register (w) */ -#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ -#define DMA1_MODE_REG 0x0B /* mode register (w) */ -#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ -#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ -#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ -#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ -#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ - -#define DMA2_CMD_REG 0xD0 /* command register (w) */ -#define DMA2_STAT_REG 0xD0 /* status register (r) */ -#define DMA2_REQ_REG 0xD2 /* request register (w) */ -#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ -#define DMA2_MODE_REG 0xD6 /* mode register (w) */ -#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ -#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ -#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ -#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ -#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ - -#define DMA_ADDR_0 0x00 /* DMA address registers */ -#define DMA_ADDR_1 0x02 -#define DMA_ADDR_2 0x04 -#define DMA_ADDR_3 0x06 -#define DMA_ADDR_4 0xC0 -#define DMA_ADDR_5 0xC4 -#define DMA_ADDR_6 0xC8 -#define DMA_ADDR_7 0xCC - -#define DMA_CNT_0 0x01 /* DMA count registers */ -#define DMA_CNT_1 0x03 -#define DMA_CNT_2 0x05 -#define DMA_CNT_3 0x07 -#define DMA_CNT_4 0xC2 -#define DMA_CNT_5 0xC6 -#define DMA_CNT_6 0xCA -#define DMA_CNT_7 0xCE - -#define DMA_PAGE_0 0x87 /* DMA page registers */ -#define DMA_PAGE_1 0x83 -#define DMA_PAGE_2 0x81 -#define DMA_PAGE_3 0x82 -#define DMA_PAGE_5 0x8B -#define DMA_PAGE_6 0x89 -#define DMA_PAGE_7 0x8A - -#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ -#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ -#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ - -#define DMA_AUTOINIT 0x10 - - -extern spinlock_t dma_spin_lock; - -static __inline__ unsigned long claim_dma_lock(void) -{ - unsigned long flags; - spin_lock_irqsave(&dma_spin_lock, flags); - return flags; -} - -static __inline__ void release_dma_lock(unsigned long flags) -{ - spin_unlock_irqrestore(&dma_spin_lock, flags); -} - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr, DMA1_MASK_REG); - else - dma_outb(dmanr & 3, DMA2_MASK_REG); -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr | 4, DMA1_MASK_REG); - else - dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); -} - -/* Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while holding the DMA lock ! --- - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(0, DMA1_CLEAR_FF_REG); - else - dma_outb(0, DMA2_CLEAR_FF_REG); -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - if (dmanr<=3) - dma_outb(mode | dmanr, DMA1_MODE_REG); - else - dma_outb(mode | (dmanr&3), DMA2_MODE_REG); -} - -/* Set only the page register bits of the transfer address. - * This is used for successive transfers when we know the contents of - * the lower 16 bits of the DMA current address register, but a 64k boundary - * may have been crossed. - */ -static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) -{ - switch(dmanr) { - case 0: - dma_outb(pagenr, DMA_PAGE_0); - break; - case 1: - dma_outb(pagenr, DMA_PAGE_1); - break; - case 2: - dma_outb(pagenr, DMA_PAGE_2); - break; - case 3: - dma_outb(pagenr, DMA_PAGE_3); - break; - case 5: - dma_outb(pagenr & 0xfe, DMA_PAGE_5); - break; - case 6: - dma_outb(pagenr & 0xfe, DMA_PAGE_6); - break; - case 7: - dma_outb(pagenr & 0xfe, DMA_PAGE_7); - break; - } -} - - -/* Set transfer address & page bits for specific DMA channel. - * Assumes dma flipflop is clear. - */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - set_dma_page(dmanr, a>>16); - if (dmanr <= 3) { - dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - } else { - dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - } -} - - -/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for - * a specific DMA channel. - * You must ensure the parameters are valid. - * NOTE: from a manual: "the number of transfers is one more - * than the initial word count"! This is taken into account. - * Assumes dma flip-flop is clear. - * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - count--; - if (dmanr <= 3) { - dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - } else { - dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - } -} - - -/* Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * If called before the channel has been used, it may return 1. - * Otherwise, it returns the number of _bytes_ left to transfer. - * - * Assumes DMA flip-flop is clear. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE - : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; - - /* using short to get 16-bit wrap around */ - unsigned short count; - - count = 1 + dma_inb(io_port); - count += dma_inb(io_port) << 8; - - return (dmanr<=3)? count : (count<<1); -} - - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -/* From PCI */ - -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) -#endif - -#endif /* _ASM_DMA_H */ -- cgit v1.2.2 From 3ebc51d7c95425c3b4667fa042576fb1c6e2ea16 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:21 +0100 Subject: x86: merge include/asm-x86/scatterlist.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/scatterlist.h | 34 ++++++++++++++++++++++++++++++++-- include/asm-x86/scatterlist_32.h | 28 ---------------------------- include/asm-x86/scatterlist_64.h | 29 ----------------------------- 3 files changed, 32 insertions(+), 59 deletions(-) delete mode 100644 include/asm-x86/scatterlist_32.h delete mode 100644 include/asm-x86/scatterlist_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/scatterlist.h b/include/asm-x86/scatterlist.h index 3a1e76257a2..d13c197866d 100644 --- a/include/asm-x86/scatterlist.h +++ b/include/asm-x86/scatterlist.h @@ -1,5 +1,35 @@ +#ifndef _ASM_X86_SCATTERLIST_H +#define _ASM_X86_SCATTERLIST_H + +#include + +struct scatterlist { +#ifdef CONFIG_DEBUG_SG + unsigned long sg_magic; +#endif + unsigned long page_link; + unsigned int offset; + unsigned int length; + dma_addr_t dma_address; +#ifdef CONFIG_X86_64 + unsigned int dma_length; +#endif +}; + +#define ARCH_HAS_SG_CHAIN +#define ISA_DMA_THRESHOLD (0x00ffffff) + +/* + * These macros should be used after a pci_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns. + */ +#define sg_dma_address(sg) ((sg)->dma_address) #ifdef CONFIG_X86_32 -# include "scatterlist_32.h" +# define sg_dma_len(sg) ((sg)->length) #else -# include "scatterlist_64.h" +# define sg_dma_len(sg) ((sg)->dma_length) +#endif + #endif diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h deleted file mode 100644 index 0e7d997a34b..00000000000 --- a/include/asm-x86/scatterlist_32.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _I386_SCATTERLIST_H -#define _I386_SCATTERLIST_H - -#include - -struct scatterlist { -#ifdef CONFIG_DEBUG_SG - unsigned long sg_magic; -#endif - unsigned long page_link; - unsigned int offset; - dma_addr_t dma_address; - unsigned int length; -}; - -#define ARCH_HAS_SG_CHAIN - -/* These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns. - */ -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) - -#define ISA_DMA_THRESHOLD (0x00ffffff) - -#endif /* !(_I386_SCATTERLIST_H) */ diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h deleted file mode 100644 index 1847c72befe..00000000000 --- a/include/asm-x86/scatterlist_64.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _X8664_SCATTERLIST_H -#define _X8664_SCATTERLIST_H - -#include - -struct scatterlist { -#ifdef CONFIG_DEBUG_SG - unsigned long sg_magic; -#endif - unsigned long page_link; - unsigned int offset; - unsigned int length; - dma_addr_t dma_address; - unsigned int dma_length; -}; - -#define ARCH_HAS_SG_CHAIN - -#define ISA_DMA_THRESHOLD (0x00ffffff) - -/* These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns. - */ -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->dma_length) - -#endif -- cgit v1.2.2 From 6ce60b07e670e800c4c5cfe984ed5188e7a64135 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:26 +0100 Subject: x86: unify mc146818rtc.h - prepare for sharing rtc code Unify mc146818rtc.h by adding the rtc_cmos_read/write functions to time_64.c. This is a preparatory patch to finaly share the rtc code, which is unsurprisingly similar. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/mc146818rtc.h | 98 ++++++++++++++++++++++++++++++++++++++-- include/asm-x86/mc146818rtc_32.h | 97 --------------------------------------- include/asm-x86/mc146818rtc_64.h | 29 ------------ 3 files changed, 95 insertions(+), 129 deletions(-) delete mode 100644 include/asm-x86/mc146818rtc_32.h delete mode 100644 include/asm-x86/mc146818rtc_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/mc146818rtc.h b/include/asm-x86/mc146818rtc.h index 5c2bb66caf1..9d39436df23 100644 --- a/include/asm-x86/mc146818rtc.h +++ b/include/asm-x86/mc146818rtc.h @@ -1,5 +1,97 @@ -#ifdef CONFIG_X86_32 -# include "mc146818rtc_32.h" +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include +#include +#include +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +#if defined(CONFIG_X86_32) && defined(__HAVE_ARCH_CMPXCHG) +/* + * This lock provides nmi access to the CMOS/RTC registers. It has some + * special properties. It is owned by a CPU and stores the index register + * currently being accessed (if owned). The idea here is that it works + * like a normal lock (normally). However, in an NMI, the NMI code will + * first check to see if its CPU owns the lock, meaning that the NMI + * interrupted during the read/write of the device. If it does, it goes ahead + * and performs the access and then restores the index register. If it does + * not, it locks normally. + * + * Note that since we are working with NMIs, we need this lock even in + * a non-SMP machine just to mark that the lock is owned. + * + * This only works with compare-and-swap. There is no other way to + * atomically claim the lock and set the owner. + */ +#include +extern volatile unsigned long cmos_lock; + +/* + * All of these below must be called with interrupts off, preempt + * disabled, etc. + */ + +static inline void lock_cmos(unsigned char reg) +{ + unsigned long new; + new = ((smp_processor_id()+1) << 8) | reg; + for (;;) { + if (cmos_lock) { + cpu_relax(); + continue; + } + if (__cmpxchg(&cmos_lock, 0, new, sizeof(cmos_lock)) == 0) + return; + } +} + +static inline void unlock_cmos(void) +{ + cmos_lock = 0; +} +static inline int do_i_have_lock_cmos(void) +{ + return (cmos_lock >> 8) == (smp_processor_id()+1); +} +static inline unsigned char current_lock_cmos_reg(void) +{ + return cmos_lock & 0xff; +} +#define lock_cmos_prefix(reg) \ + do { \ + unsigned long cmos_flags; \ + local_irq_save(cmos_flags); \ + lock_cmos(reg) +#define lock_cmos_suffix(reg) \ + unlock_cmos(); \ + local_irq_restore(cmos_flags); \ + } while (0) #else -# include "mc146818rtc_64.h" +#define lock_cmos_prefix(reg) do {} while (0) +#define lock_cmos_suffix(reg) do {} while (0) +#define lock_cmos(reg) +#define unlock_cmos() +#define do_i_have_lock_cmos() 0 +#define current_lock_cmos_reg() 0 #endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) rtc_cmos_read(addr) +#define CMOS_WRITE(val, addr) rtc_cmos_write(val, addr) +unsigned char rtc_cmos_read(unsigned char addr); +void rtc_cmos_write(unsigned char val, unsigned char addr); + +#define RTC_IRQ 8 + +#endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-x86/mc146818rtc_32.h b/include/asm-x86/mc146818rtc_32.h deleted file mode 100644 index 1613b42eaf5..00000000000 --- a/include/asm-x86/mc146818rtc_32.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Machine dependent access functions for RTC registers. - */ -#ifndef _ASM_MC146818RTC_H -#define _ASM_MC146818RTC_H - -#include -#include -#include -#include - -#ifndef RTC_PORT -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ -#endif - -#ifdef __HAVE_ARCH_CMPXCHG -/* - * This lock provides nmi access to the CMOS/RTC registers. It has some - * special properties. It is owned by a CPU and stores the index register - * currently being accessed (if owned). The idea here is that it works - * like a normal lock (normally). However, in an NMI, the NMI code will - * first check to see if its CPU owns the lock, meaning that the NMI - * interrupted during the read/write of the device. If it does, it goes ahead - * and performs the access and then restores the index register. If it does - * not, it locks normally. - * - * Note that since we are working with NMIs, we need this lock even in - * a non-SMP machine just to mark that the lock is owned. - * - * This only works with compare-and-swap. There is no other way to - * atomically claim the lock and set the owner. - */ -#include -extern volatile unsigned long cmos_lock; - -/* - * All of these below must be called with interrupts off, preempt - * disabled, etc. - */ - -static inline void lock_cmos(unsigned char reg) -{ - unsigned long new; - new = ((smp_processor_id()+1) << 8) | reg; - for (;;) { - if (cmos_lock) { - cpu_relax(); - continue; - } - if (__cmpxchg(&cmos_lock, 0, new, sizeof(cmos_lock)) == 0) - return; - } -} - -static inline void unlock_cmos(void) -{ - cmos_lock = 0; -} -static inline int do_i_have_lock_cmos(void) -{ - return (cmos_lock >> 8) == (smp_processor_id()+1); -} -static inline unsigned char current_lock_cmos_reg(void) -{ - return cmos_lock & 0xff; -} -#define lock_cmos_prefix(reg) \ - do { \ - unsigned long cmos_flags; \ - local_irq_save(cmos_flags); \ - lock_cmos(reg) -#define lock_cmos_suffix(reg) \ - unlock_cmos(); \ - local_irq_restore(cmos_flags); \ - } while (0) -#else -#define lock_cmos_prefix(reg) do {} while (0) -#define lock_cmos_suffix(reg) do {} while (0) -#define lock_cmos(reg) -#define unlock_cmos() -#define do_i_have_lock_cmos() 0 -#define current_lock_cmos_reg() 0 -#endif - -/* - * The yet supported machines all access the RTC index register via - * an ISA port access but the way to access the date register differs ... - */ -#define CMOS_READ(addr) rtc_cmos_read(addr) -#define CMOS_WRITE(val, addr) rtc_cmos_write(val, addr) -unsigned char rtc_cmos_read(unsigned char addr); -void rtc_cmos_write(unsigned char val, unsigned char addr); - -#define RTC_IRQ 8 - -#endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-x86/mc146818rtc_64.h b/include/asm-x86/mc146818rtc_64.h deleted file mode 100644 index d6e3009430c..00000000000 --- a/include/asm-x86/mc146818rtc_64.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Machine dependent access functions for RTC registers. - */ -#ifndef _ASM_MC146818RTC_H -#define _ASM_MC146818RTC_H - -#include - -#ifndef RTC_PORT -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ -#endif - -/* - * The yet supported machines all access the RTC index register via - * an ISA port access but the way to access the date register differs ... - */ -#define CMOS_READ(addr) ({ \ -outb_p((addr),RTC_PORT(0)); \ -inb_p(RTC_PORT(1)); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -outb_p((addr),RTC_PORT(0)); \ -outb_p((val),RTC_PORT(1)); \ -}) - -#define RTC_IRQ 8 - -#endif /* _ASM_MC146818RTC_H */ -- cgit v1.2.2 From fe599f9fbc5d470ec5b55d08f2bbb991ddecbbc8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:26 +0100 Subject: x86: isolate the rtc code for sharing The mach-default/mach_time.h code inline is moved to arch/x86/kernel/rtc.c and the header files are adjusted. Shrink the 3 dozen includes to the ones we really need. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/mach-default/mach_time.h | 111 ------------------------------- include/asm-x86/mc146818rtc.h | 3 + include/asm-x86/time.h | 2 +- 3 files changed, 4 insertions(+), 112 deletions(-) delete mode 100644 include/asm-x86/mach-default/mach_time.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/mach-default/mach_time.h b/include/asm-x86/mach-default/mach_time.h deleted file mode 100644 index 31eb5de6f3d..00000000000 --- a/include/asm-x86/mach-default/mach_time.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * include/asm-i386/mach-default/mach_time.h - * - * Machine specific set RTC function for generic. - * Split out from time.c by Osamu Tomita - */ -#ifndef _MACH_TIME_H -#define _MACH_TIME_H - -#include - -/* for check timing call set_rtc_mmss() 500ms */ -/* used in arch/i386/time.c::do_timer_interrupt() */ -#define USEC_AFTER 500000 -#define USEC_BEFORE 500000 - -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you'll only notice that after reboot! - */ -static inline int mach_set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; -} - -static inline unsigned long mach_get_cmos_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - - do { - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - - year += 1900; - if (year < 1970) - year += 100; - - return mktime(year, mon, day, hour, min, sec); -} - -#endif /* !_MACH_TIME_H */ diff --git a/include/asm-x86/mc146818rtc.h b/include/asm-x86/mc146818rtc.h index 9d39436df23..cdd9f965835 100644 --- a/include/asm-x86/mc146818rtc.h +++ b/include/asm-x86/mc146818rtc.h @@ -92,6 +92,9 @@ static inline unsigned char current_lock_cmos_reg(void) unsigned char rtc_cmos_read(unsigned char addr); void rtc_cmos_write(unsigned char val, unsigned char addr); +extern int mach_set_rtc_mmss(unsigned long nowtime); +extern unsigned long mach_get_cmos_time(void); + #define RTC_IRQ 8 #endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-x86/time.h b/include/asm-x86/time.h index eac011366dc..b3f94cd81ac 100644 --- a/include/asm-x86/time.h +++ b/include/asm-x86/time.h @@ -2,7 +2,7 @@ #define _ASMi386_TIME_H #include -#include "mach_time.h" +#include static inline unsigned long native_get_wallclock(void) { -- cgit v1.2.2 From a72368dd37f6ae333fbab03598e46a995d91decc Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:28 +0100 Subject: x86: remove dead code and exports No users. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/idle.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/idle.h b/include/asm-x86/idle.h index 6bd47dcf206..d240e5b30a4 100644 --- a/include/asm-x86/idle.h +++ b/include/asm-x86/idle.h @@ -6,7 +6,6 @@ struct notifier_block; void idle_notifier_register(struct notifier_block *n); -void idle_notifier_unregister(struct notifier_block *n); void enter_idle(void); void exit_idle(void); -- cgit v1.2.2 From 3abf024d2abb79614d8c4cb25a70d5596f77d0ad Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:28 +0100 Subject: x86: nuke a ton of unused exports Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/bug.h | 3 --- include/asm-x86/mmu_context_64.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/bug.h b/include/asm-x86/bug.h index fd8bdc639c4..8d477a20139 100644 --- a/include/asm-x86/bug.h +++ b/include/asm-x86/bug.h @@ -33,9 +33,6 @@ } while(0) #endif -void out_of_line_bug(void); -#else /* CONFIG_BUG */ -static inline void out_of_line_bug(void) { } #endif /* !CONFIG_BUG */ #include diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h index 0cce83a7837..29f95c3acc2 100644 --- a/include/asm-x86/mmu_context_64.h +++ b/include/asm-x86/mmu_context_64.h @@ -49,7 +49,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, else { write_pda(mmu_state, TLBSTATE_OK); if (read_pda(active_mm) != next) - out_of_line_bug(); + BUG(); if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { /* We were in lazy tlb mode and leave_mm disabled * tlb flush IPI delivery. We must reload CR3 -- cgit v1.2.2 From 99122a3fe74c4918cdc86a8d6d63b40240fa8881 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 30 Jan 2008 13:30:28 +0100 Subject: x86: remove more bogus filenames in comments. Signed-off-by: Dave Jones Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/acpi_32.h | 4 +--- include/asm-x86/acpi_64.h | 4 +--- include/asm-x86/checksum_64.h | 2 +- include/asm-x86/i387_32.h | 2 -- include/asm-x86/i387_64.h | 2 -- include/asm-x86/ia32_unistd.h | 2 +- include/asm-x86/ide.h | 2 -- include/asm-x86/irqflags_32.h | 2 -- include/asm-x86/irqflags_64.h | 2 -- include/asm-x86/mach-default/apm.h | 2 -- include/asm-x86/mach-default/mach_timer.h | 2 -- include/asm-x86/mach-default/mach_traps.h | 2 -- include/asm-x86/nmi_32.h | 3 --- include/asm-x86/nmi_64.h | 3 --- include/asm-x86/processor_32.h | 2 -- include/asm-x86/processor_64.h | 2 -- include/asm-x86/rio.h | 4 ++-- include/asm-x86/rwsem.h | 2 +- include/asm-x86/topology_32.h | 2 -- include/asm-x86/xor_32.h | 2 -- include/asm-x86/xor_64.h | 2 -- 21 files changed, 7 insertions(+), 43 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/acpi_32.h b/include/asm-x86/acpi_32.h index 3cce5a0f2d9..c8afeea0b80 100644 --- a/include/asm-x86/acpi_32.h +++ b/include/asm-x86/acpi_32.h @@ -1,9 +1,7 @@ /* - * asm-i386/acpi.h - * * Copyright (C) 2001 Paul Diefenbaugh * Copyright (C) 2001 Patrick Mochel - * + * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This program is free software; you can redistribute it and/or modify diff --git a/include/asm-x86/acpi_64.h b/include/asm-x86/acpi_64.h index 98173357dd8..58114ed0802 100644 --- a/include/asm-x86/acpi_64.h +++ b/include/asm-x86/acpi_64.h @@ -1,9 +1,7 @@ /* - * asm-x86_64/acpi.h - * * Copyright (C) 2001 Paul Diefenbaugh * Copyright (C) 2001 Patrick Mochel - * + * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This program is free software; you can redistribute it and/or modify diff --git a/include/asm-x86/checksum_64.h b/include/asm-x86/checksum_64.h index 419fe88a034..e5f79997dec 100644 --- a/include/asm-x86/checksum_64.h +++ b/include/asm-x86/checksum_64.h @@ -4,7 +4,7 @@ /* * Checksums for x86-64 * Copyright 2002 by Andi Kleen, SuSE Labs - * with some code from asm-i386/checksum.h + * with some code from asm-x86/checksum.h */ #include diff --git a/include/asm-x86/i387_32.h b/include/asm-x86/i387_32.h index cdd1e248e3b..9ac2502cdd3 100644 --- a/include/asm-x86/i387_32.h +++ b/include/asm-x86/i387_32.h @@ -1,6 +1,4 @@ /* - * include/asm-i386/i387.h - * * Copyright (C) 1994 Linus Torvalds * * Pentium III FXSR, SSE support diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h index 3a4ffba3d6b..12edb9f2d75 100644 --- a/include/asm-x86/i387_64.h +++ b/include/asm-x86/i387_64.h @@ -1,6 +1,4 @@ /* - * include/asm-x86_64/i387.h - * * Copyright (C) 1994 Linus Torvalds * * Pentium III FXSR, SSE support diff --git a/include/asm-x86/ia32_unistd.h b/include/asm-x86/ia32_unistd.h index 5b52ce50733..61cea9e7c5c 100644 --- a/include/asm-x86/ia32_unistd.h +++ b/include/asm-x86/ia32_unistd.h @@ -5,7 +5,7 @@ * This file contains the system call numbers of the ia32 port, * this is for the kernel only. * Only add syscalls here where some part of the kernel needs to know - * the number. This should be otherwise in sync with asm-i386/unistd.h. -AK + * the number. This should be otherwise in sync with asm-x86/unistd_32.h. -AK */ #define __NR_ia32_restart_syscall 0 diff --git a/include/asm-x86/ide.h b/include/asm-x86/ide.h index 42130adf9c7..c2552d8bebf 100644 --- a/include/asm-x86/ide.h +++ b/include/asm-x86/ide.h @@ -1,6 +1,4 @@ /* - * linux/include/asm-i386/ide.h - * * Copyright (C) 1994-1996 Linus Torvalds & authors */ diff --git a/include/asm-x86/irqflags_32.h b/include/asm-x86/irqflags_32.h index 4c7720089cb..98b21b9bdce 100644 --- a/include/asm-x86/irqflags_32.h +++ b/include/asm-x86/irqflags_32.h @@ -1,6 +1,4 @@ /* - * include/asm-i386/irqflags.h - * * IRQ flags handling * * This file gets included from lowlevel asm headers too, to provide diff --git a/include/asm-x86/irqflags_64.h b/include/asm-x86/irqflags_64.h index bb9163bb29d..38c07db733c 100644 --- a/include/asm-x86/irqflags_64.h +++ b/include/asm-x86/irqflags_64.h @@ -1,6 +1,4 @@ /* - * include/asm-x86_64/irqflags.h - * * IRQ flags handling * * This file gets included from lowlevel asm headers too, to provide diff --git a/include/asm-x86/mach-default/apm.h b/include/asm-x86/mach-default/apm.h index 1f730b8bd1f..989f34c37d3 100644 --- a/include/asm-x86/mach-default/apm.h +++ b/include/asm-x86/mach-default/apm.h @@ -1,6 +1,4 @@ /* - * include/asm-i386/mach-default/apm.h - * * Machine specific APM BIOS functions for generic. * Split out from apm.c by Osamu Tomita */ diff --git a/include/asm-x86/mach-default/mach_timer.h b/include/asm-x86/mach-default/mach_timer.h index 807992fd417..4b76e536cd9 100644 --- a/include/asm-x86/mach-default/mach_timer.h +++ b/include/asm-x86/mach-default/mach_timer.h @@ -1,6 +1,4 @@ /* - * include/asm-i386/mach-default/mach_timer.h - * * Machine specific calibrate_tsc() for generic. * Split out from timer_tsc.c by Osamu Tomita */ diff --git a/include/asm-x86/mach-default/mach_traps.h b/include/asm-x86/mach-default/mach_traps.h index 625438b8a6e..2fe7705c048 100644 --- a/include/asm-x86/mach-default/mach_traps.h +++ b/include/asm-x86/mach-default/mach_traps.h @@ -1,6 +1,4 @@ /* - * include/asm-i386/mach-default/mach_traps.h - * * Machine specific NMI handling for generic. * Split out from traps.c by Osamu Tomita */ diff --git a/include/asm-x86/nmi_32.h b/include/asm-x86/nmi_32.h index 70a958a8e38..7206c7e8a38 100644 --- a/include/asm-x86/nmi_32.h +++ b/include/asm-x86/nmi_32.h @@ -1,6 +1,3 @@ -/* - * linux/include/asm-i386/nmi.h - */ #ifndef ASM_NMI_H #define ASM_NMI_H diff --git a/include/asm-x86/nmi_64.h b/include/asm-x86/nmi_64.h index 65b6acf3bb5..92f36fb1dc6 100644 --- a/include/asm-x86/nmi_64.h +++ b/include/asm-x86/nmi_64.h @@ -1,6 +1,3 @@ -/* - * linux/include/asm-i386/nmi.h - */ #ifndef ASM_NMI_H #define ASM_NMI_H diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 58880a1ddd6..3b51a18f16d 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -1,6 +1,4 @@ /* - * include/asm-i386/processor.h - * * Copyright (C) 1994 Linus Torvalds */ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 6b96e1f12a4..6c0d96a7af6 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -1,6 +1,4 @@ /* - * include/asm-x86_64/processor.h - * * Copyright (C) 1994 Linus Torvalds */ diff --git a/include/asm-x86/rio.h b/include/asm-x86/rio.h index c7350f6d201..97cdcc9887b 100644 --- a/include/asm-x86/rio.h +++ b/include/asm-x86/rio.h @@ -1,6 +1,6 @@ /* - * Derived from include/asm-i386/mach-summit/mach_mpparse.h - * and include/asm-i386/mach-default/bios_ebda.h + * Derived from include/asm-x86/mach-summit/mach_mpparse.h + * and include/asm-x86/mach-default/bios_ebda.h * * Author: Laurent Vivier */ diff --git a/include/asm-x86/rwsem.h b/include/asm-x86/rwsem.h index 041906f3c6d..a7e7e14cb43 100644 --- a/include/asm-x86/rwsem.h +++ b/include/asm-x86/rwsem.h @@ -2,7 +2,7 @@ * * Written by David Howells (dhowells@redhat.com). * - * Derived from asm-i386/semaphore.h + * Derived from asm-x86/semaphore.h * * * The MSW of the count is the negated number of active writers and waiting diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h index 9040f5a6127..fdca80a851e 100644 --- a/include/asm-x86/topology_32.h +++ b/include/asm-x86/topology_32.h @@ -1,6 +1,4 @@ /* - * linux/include/asm-i386/topology.h - * * Written by: Matthew Dobson, IBM Corporation * * Copyright (C) 2002, IBM Corp. diff --git a/include/asm-x86/xor_32.h b/include/asm-x86/xor_32.h index 23c86cef3b2..a41ef1bdd42 100644 --- a/include/asm-x86/xor_32.h +++ b/include/asm-x86/xor_32.h @@ -1,6 +1,4 @@ /* - * include/asm-i386/xor.h - * * Optimized RAID-5 checksumming functions for MMX and SSE. * * This program is free software; you can redistribute it and/or modify diff --git a/include/asm-x86/xor_64.h b/include/asm-x86/xor_64.h index f942fcc2183..1eee7fcb242 100644 --- a/include/asm-x86/xor_64.h +++ b/include/asm-x86/xor_64.h @@ -1,6 +1,4 @@ /* - * include/asm-x86_64/xor.h - * * Optimized RAID-5 checksumming functions for MMX and SSE. * * This program is free software; you can redistribute it and/or modify -- cgit v1.2.2 From f20ebee41882d28c965166e56c1331fbd28778bb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:29 +0100 Subject: x86: move 8259 defines to i8259.h Move the i8259 defines and remove the now io_ports.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/i8259.h | 17 ++++++++++++++++- include/asm-x86/mach-default/io_ports.h | 25 ------------------------- 2 files changed, 16 insertions(+), 26 deletions(-) delete mode 100644 include/asm-x86/mach-default/io_ports.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/i8259.h b/include/asm-x86/i8259.h index 29d8f9a6b3f..cabcc6cf392 100644 --- a/include/asm-x86/i8259.h +++ b/include/asm-x86/i8259.h @@ -3,10 +3,25 @@ extern unsigned int cached_irq_mask; -#define __byte(x,y) (((unsigned char *) &(y))[x]) +#define __byte(x,y) (((unsigned char *) &(y))[x]) #define cached_master_mask (__byte(0, cached_irq_mask)) #define cached_slave_mask (__byte(1, cached_irq_mask)) +/* i8259A PIC registers */ +#define PIC_MASTER_CMD 0x20 +#define PIC_MASTER_IMR 0x21 +#define PIC_MASTER_ISR PIC_MASTER_CMD +#define PIC_MASTER_POLL PIC_MASTER_ISR +#define PIC_MASTER_OCW3 PIC_MASTER_ISR +#define PIC_SLAVE_CMD 0xa0 +#define PIC_SLAVE_IMR 0xa1 + +/* i8259A PIC related value */ +#define PIC_CASCADE_IR 2 +#define MASTER_ICW4_DEFAULT 0x01 +#define SLAVE_ICW4_DEFAULT 0x01 +#define PIC_ICW4_AEOI 2 + extern spinlock_t i8259A_lock; extern void init_8259A(int auto_eoi); diff --git a/include/asm-x86/mach-default/io_ports.h b/include/asm-x86/mach-default/io_ports.h deleted file mode 100644 index 48540ba9716..00000000000 --- a/include/asm-x86/mach-default/io_ports.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/i386/mach-generic/io_ports.h - * - * Machine specific IO port address definition for generic. - * Written by Osamu Tomita - */ -#ifndef _MACH_IO_PORTS_H -#define _MACH_IO_PORTS_H - -/* i8259A PIC registers */ -#define PIC_MASTER_CMD 0x20 -#define PIC_MASTER_IMR 0x21 -#define PIC_MASTER_ISR PIC_MASTER_CMD -#define PIC_MASTER_POLL PIC_MASTER_ISR -#define PIC_MASTER_OCW3 PIC_MASTER_ISR -#define PIC_SLAVE_CMD 0xa0 -#define PIC_SLAVE_IMR 0xa1 - -/* i8259A PIC related value */ -#define PIC_CASCADE_IR 2 -#define MASTER_ICW4_DEFAULT 0x01 -#define SLAVE_ICW4_DEFAULT 0x01 -#define PIC_ICW4_AEOI 2 - -#endif /* !_MACH_IO_PORTS_H */ -- cgit v1.2.2 From 1d8a1f6b51f6b195dfdcf05821be97edede5664a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:30:30 +0100 Subject: x86: prepare merger of Prepare for merging by making the 32- and 64-bit versions textually identical. This involves: - removing arbitrary header inclusion differences - reorganizing the 32-bit version slightly to match the 64-bit version - using to unify the assembly code - renaming struct paravirt_patch to struct paravirt_patch_site in the 64-bit version to match the 32-bit version; there are no references to struct paravirt_patch elsewhere in the tree. Signed-off-by: H. Peter Anvin Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/alternative_32.h | 131 +++++++++++++++++++++------------------ include/asm-x86/alternative_64.h | 84 +++++++++++++------------ 2 files changed, 112 insertions(+), 103 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/alternative_32.h b/include/asm-x86/alternative_32.h index bda6c810c0f..4919b5ee8b9 100644 --- a/include/asm-x86/alternative_32.h +++ b/include/asm-x86/alternative_32.h @@ -1,23 +1,63 @@ #ifndef _I386_ALTERNATIVE_H #define _I386_ALTERNATIVE_H -#include -#include #include +#include +#include + +/* + * Alternative inline assembly for SMP. + * + * The LOCK_PREFIX macro defined here replaces the LOCK and + * LOCK_PREFIX macros used everywhere in the source tree. + * + * SMP alternatives use the same data structures as the other + * alternatives and the X86_FEATURE_UP flag to indicate the case of a + * UP system running a SMP kernel. The existing apply_alternatives() + * works fine for patching a SMP kernel for UP. + * + * The SMP alternative tables can be kept after boot and contain both + * UP and SMP versions of the instructions to allow switching back to + * SMP at runtime, when hotplugging in a new CPU, which is especially + * useful in virtualized environments. + * + * The very common lock prefix is handled as special case in a + * separate table which is a pure address list without replacement ptr + * and size information. That keeps the table sizes small. + */ + +#ifdef CONFIG_SMP +#define LOCK_PREFIX \ + ".section .smp_locks,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661f\n" /* address */ \ + ".previous\n" \ + "661:\n\tlock; " + +#else /* ! CONFIG_SMP */ +#define LOCK_PREFIX "" +#endif + +/* This must be included *after* the definition of LOCK_PREFIX */ +#include struct alt_instr { - u8 *instr; /* original instruction */ + u8 *instr; /* original instruction */ u8 *replacement; u8 cpuid; /* cpuid bit set for replacement */ u8 instrlen; /* length of original instruction */ - u8 replacementlen; /* length of new instruction, <= instrlen */ - u8 pad; + u8 replacementlen; /* length of new instruction, <= instrlen */ + u8 pad1; +#ifdef CONFIG_X86_64 + u32 pad2; +#endif }; extern void alternative_instructions(void); extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); struct module; + #ifdef CONFIG_SMP extern void alternatives_smp_module_add(struct module *mod, char *name, void *locks, void *locks_end, @@ -45,17 +85,17 @@ static inline void alternatives_smp_switch(int smp) {} * without volatile and memory clobber. */ #define alternative(oldinstr, newinstr, feature) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ + asm volatile ("661:\n\t" oldinstr "\n662:\n" \ ".section .altinstructions,\"a\"\n" \ - " .align 4\n" \ - " .long 661b\n" /* label */ \ - " .long 663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ ".previous\n" \ ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */\ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ ".previous" :: "i" (feature) : "memory") /* @@ -66,35 +106,35 @@ static inline void alternatives_smp_switch(int smp) {} * Argument numbers start with 1. * Best is to use constraints that are fixed size (like (%1) ... "r") * If you use variable sized constraints like "m" or "g" in the - * replacement maake sure to pad to the worst case length. + * replacement make sure to pad to the worst case length. */ #define alternative_input(oldinstr, newinstr, feature, input...) \ asm volatile ("661:\n\t" oldinstr "\n662:\n" \ ".section .altinstructions,\"a\"\n" \ - " .align 4\n" \ - " .long 661b\n" /* label */ \ - " .long 663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ ".previous\n" \ ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */\ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ ".previous" :: "i" (feature), ##input) /* Like alternative_input, but with a single output argument */ -#define alternative_io(oldinstr, newinstr, feature, output, input...) \ +#define alternative_io(oldinstr, newinstr, feature, output, input...) \ asm volatile ("661:\n\t" oldinstr "\n662:\n" \ ".section .altinstructions,\"a\"\n" \ - " .align 4\n" \ - " .long 661b\n" /* label */ \ - " .long 663f\n" /* new instruction */ \ - " .byte %c[feat]\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c[feat]\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ ".previous\n" \ ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ ".previous" : output : [feat] "i" (feature), ##input) /* @@ -103,39 +143,6 @@ static inline void alternatives_smp_switch(int smp) {} */ #define ASM_OUTPUT2(a, b) a, b -/* - * Alternative inline assembly for SMP. - * - * The LOCK_PREFIX macro defined here replaces the LOCK and - * LOCK_PREFIX macros used everywhere in the source tree. - * - * SMP alternatives use the same data structures as the other - * alternatives and the X86_FEATURE_UP flag to indicate the case of a - * UP system running a SMP kernel. The existing apply_alternatives() - * works fine for patching a SMP kernel for UP. - * - * The SMP alternative tables can be kept after boot and contain both - * UP and SMP versions of the instructions to allow switching back to - * SMP at runtime, when hotplugging in a new CPU, which is especially - * useful in virtualized environments. - * - * The very common lock prefix is handled as special case in a - * separate table which is a pure address list without replacement ptr - * and size information. That keeps the table sizes small. - */ - -#ifdef CONFIG_SMP -#define LOCK_PREFIX \ - ".section .smp_locks,\"a\"\n" \ - " .align 4\n" \ - " .long 661f\n" /* address */ \ - ".previous\n" \ - "661:\n\tlock; " - -#else /* ! CONFIG_SMP */ -#define LOCK_PREFIX "" -#endif - struct paravirt_patch_site; #ifdef CONFIG_PARAVIRT void apply_paravirt(struct paravirt_patch_site *start, diff --git a/include/asm-x86/alternative_64.h b/include/asm-x86/alternative_64.h index ab161e81015..50efcebae33 100644 --- a/include/asm-x86/alternative_64.h +++ b/include/asm-x86/alternative_64.h @@ -1,10 +1,9 @@ #ifndef _X86_64_ALTERNATIVE_H #define _X86_64_ALTERNATIVE_H -#ifdef __KERNEL__ - #include #include +#include /* * Alternative inline assembly for SMP. @@ -30,10 +29,10 @@ #ifdef CONFIG_SMP #define LOCK_PREFIX \ ".section .smp_locks,\"a\"\n" \ - " .align 8\n" \ - " .quad 661f\n" /* address */ \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661f\n" /* address */ \ ".previous\n" \ - "661:\n\tlock; " + "661:\n\tlock; " #else /* ! CONFIG_SMP */ #define LOCK_PREFIX "" @@ -43,12 +42,15 @@ #include struct alt_instr { - u8 *instr; /* original instruction */ + u8 *instr; /* original instruction */ u8 *replacement; u8 cpuid; /* cpuid bit set for replacement */ u8 instrlen; /* length of original instruction */ - u8 replacementlen; /* length of new instruction, <= instrlen */ - u8 pad[5]; + u8 replacementlen; /* length of new instruction, <= instrlen */ + u8 pad1; +#ifdef CONFIG_X86_64 + u32 pad2; +#endif }; extern void alternative_instructions(void); @@ -68,9 +70,7 @@ static inline void alternatives_smp_module_add(struct module *mod, char *name, void *text, void *text_end) {} static inline void alternatives_smp_module_del(struct module *mod) {} static inline void alternatives_smp_switch(int smp) {} -#endif - -#endif +#endif /* CONFIG_SMP */ /* * Alternative instructions for different CPU types or capabilities. @@ -84,18 +84,18 @@ static inline void alternatives_smp_switch(int smp) {} * For non barrier like inlines please define new variants * without volatile and memory clobber. */ -#define alternative(oldinstr, newinstr, feature) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - " .align 8\n" \ - " .quad 661b\n" /* label */ \ - " .quad 663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ +#define alternative(oldinstr, newinstr, feature) \ + asm volatile ("661:\n\t" oldinstr "\n662:\n" \ + ".section .altinstructions,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ ".previous\n" \ ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ ".previous" :: "i" (feature) : "memory") /* @@ -111,30 +111,30 @@ static inline void alternatives_smp_switch(int smp) {} #define alternative_input(oldinstr, newinstr, feature, input...) \ asm volatile ("661:\n\t" oldinstr "\n662:\n" \ ".section .altinstructions,\"a\"\n" \ - " .align 8\n" \ - " .quad 661b\n" /* label */ \ - " .quad 663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ ".previous\n" \ ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ ".previous" :: "i" (feature), ##input) /* Like alternative_input, but with a single output argument */ -#define alternative_io(oldinstr, newinstr, feature, output, input...) \ +#define alternative_io(oldinstr, newinstr, feature, output, input...) \ asm volatile ("661:\n\t" oldinstr "\n662:\n" \ ".section .altinstructions,\"a\"\n" \ - " .align 8\n" \ - " .quad 661b\n" /* label */ \ - " .quad 663f\n" /* new instruction */ \ - " .byte %c[feat]\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c[feat]\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ ".previous\n" \ ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ ".previous" : output : [feat] "i" (feature), ##input) /* @@ -143,15 +143,17 @@ static inline void alternatives_smp_switch(int smp) {} */ #define ASM_OUTPUT2(a, b) a, b -struct paravirt_patch; +struct paravirt_patch_site; #ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end); +void apply_paravirt(struct paravirt_patch_site *start, + struct paravirt_patch_site *end); #else static inline void -apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) +apply_paravirt(struct paravirt_patch_site *start, + struct paravirt_patch_site *end) {} -#define __parainstructions NULL -#define __parainstructions_end NULL +#define __parainstructions NULL +#define __parainstructions_end NULL #endif extern void text_poke(void *addr, unsigned char *opcode, int len); -- cgit v1.2.2 From 6b59257082e136fbbce1aa017575a451c0df0592 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:30:30 +0100 Subject: x86: actually merge This actually merges into . Signed-off-by: H. Peter Anvin Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/alternative.h | 162 ++++++++++++++++++++++++++++++++++++++- include/asm-x86/alternative_32.h | 161 -------------------------------------- include/asm-x86/alternative_64.h | 161 -------------------------------------- 3 files changed, 159 insertions(+), 325 deletions(-) delete mode 100644 include/asm-x86/alternative_32.h delete mode 100644 include/asm-x86/alternative_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/alternative.h b/include/asm-x86/alternative.h index 9eef6a32a13..d8bacf3c4b0 100644 --- a/include/asm-x86/alternative.h +++ b/include/asm-x86/alternative.h @@ -1,5 +1,161 @@ -#ifdef CONFIG_X86_32 -# include "alternative_32.h" +#ifndef _ASM_X86_ALTERNATIVE_H +#define _ASM_X86_ALTERNATIVE_H + +#include +#include +#include + +/* + * Alternative inline assembly for SMP. + * + * The LOCK_PREFIX macro defined here replaces the LOCK and + * LOCK_PREFIX macros used everywhere in the source tree. + * + * SMP alternatives use the same data structures as the other + * alternatives and the X86_FEATURE_UP flag to indicate the case of a + * UP system running a SMP kernel. The existing apply_alternatives() + * works fine for patching a SMP kernel for UP. + * + * The SMP alternative tables can be kept after boot and contain both + * UP and SMP versions of the instructions to allow switching back to + * SMP at runtime, when hotplugging in a new CPU, which is especially + * useful in virtualized environments. + * + * The very common lock prefix is handled as special case in a + * separate table which is a pure address list without replacement ptr + * and size information. That keeps the table sizes small. + */ + +#ifdef CONFIG_SMP +#define LOCK_PREFIX \ + ".section .smp_locks,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661f\n" /* address */ \ + ".previous\n" \ + "661:\n\tlock; " + +#else /* ! CONFIG_SMP */ +#define LOCK_PREFIX "" +#endif + +/* This must be included *after* the definition of LOCK_PREFIX */ +#include + +struct alt_instr { + u8 *instr; /* original instruction */ + u8 *replacement; + u8 cpuid; /* cpuid bit set for replacement */ + u8 instrlen; /* length of original instruction */ + u8 replacementlen; /* length of new instruction, <= instrlen */ + u8 pad1; +#ifdef CONFIG_X86_64 + u32 pad2; +#endif +}; + +extern void alternative_instructions(void); +extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); + +struct module; + +#ifdef CONFIG_SMP +extern void alternatives_smp_module_add(struct module *mod, char *name, + void *locks, void *locks_end, + void *text, void *text_end); +extern void alternatives_smp_module_del(struct module *mod); +extern void alternatives_smp_switch(int smp); +#else +static inline void alternatives_smp_module_add(struct module *mod, char *name, + void *locks, void *locks_end, + void *text, void *text_end) {} +static inline void alternatives_smp_module_del(struct module *mod) {} +static inline void alternatives_smp_switch(int smp) {} +#endif /* CONFIG_SMP */ + +/* + * Alternative instructions for different CPU types or capabilities. + * + * This allows to use optimized instructions even on generic binary + * kernels. + * + * length of oldinstr must be longer or equal the length of newinstr + * It can be padded with nops as needed. + * + * For non barrier like inlines please define new variants + * without volatile and memory clobber. + */ +#define alternative(oldinstr, newinstr, feature) \ + asm volatile ("661:\n\t" oldinstr "\n662:\n" \ + ".section .altinstructions,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .altinstr_replacement,\"ax\"\n" \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + ".previous" :: "i" (feature) : "memory") + +/* + * Alternative inline assembly with input. + * + * Pecularities: + * No memory clobber here. + * Argument numbers start with 1. + * Best is to use constraints that are fixed size (like (%1) ... "r") + * If you use variable sized constraints like "m" or "g" in the + * replacement make sure to pad to the worst case length. + */ +#define alternative_input(oldinstr, newinstr, feature, input...) \ + asm volatile ("661:\n\t" oldinstr "\n662:\n" \ + ".section .altinstructions,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .altinstr_replacement,\"ax\"\n" \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + ".previous" :: "i" (feature), ##input) + +/* Like alternative_input, but with a single output argument */ +#define alternative_io(oldinstr, newinstr, feature, output, input...) \ + asm volatile ("661:\n\t" oldinstr "\n662:\n" \ + ".section .altinstructions,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR "661b\n" /* label */ \ + _ASM_PTR "663f\n" /* new instruction */ \ + " .byte %c[feat]\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .altinstr_replacement,\"ax\"\n" \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + ".previous" : output : [feat] "i" (feature), ##input) + +/* + * use this macro(s) if you need more than one output parameter + * in alternative_io + */ +#define ASM_OUTPUT2(a, b) a, b + +struct paravirt_patch_site; +#ifdef CONFIG_PARAVIRT +void apply_paravirt(struct paravirt_patch_site *start, + struct paravirt_patch_site *end); #else -# include "alternative_64.h" +static inline void +apply_paravirt(struct paravirt_patch_site *start, + struct paravirt_patch_site *end) +{} +#define __parainstructions NULL +#define __parainstructions_end NULL #endif + +extern void text_poke(void *addr, unsigned char *opcode, int len); + +#endif /* _ASM_X86_ALTERNATIVE_H */ diff --git a/include/asm-x86/alternative_32.h b/include/asm-x86/alternative_32.h deleted file mode 100644 index 4919b5ee8b9..00000000000 --- a/include/asm-x86/alternative_32.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef _I386_ALTERNATIVE_H -#define _I386_ALTERNATIVE_H - -#include -#include -#include - -/* - * Alternative inline assembly for SMP. - * - * The LOCK_PREFIX macro defined here replaces the LOCK and - * LOCK_PREFIX macros used everywhere in the source tree. - * - * SMP alternatives use the same data structures as the other - * alternatives and the X86_FEATURE_UP flag to indicate the case of a - * UP system running a SMP kernel. The existing apply_alternatives() - * works fine for patching a SMP kernel for UP. - * - * The SMP alternative tables can be kept after boot and contain both - * UP and SMP versions of the instructions to allow switching back to - * SMP at runtime, when hotplugging in a new CPU, which is especially - * useful in virtualized environments. - * - * The very common lock prefix is handled as special case in a - * separate table which is a pure address list without replacement ptr - * and size information. That keeps the table sizes small. - */ - -#ifdef CONFIG_SMP -#define LOCK_PREFIX \ - ".section .smp_locks,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661f\n" /* address */ \ - ".previous\n" \ - "661:\n\tlock; " - -#else /* ! CONFIG_SMP */ -#define LOCK_PREFIX "" -#endif - -/* This must be included *after* the definition of LOCK_PREFIX */ -#include - -struct alt_instr { - u8 *instr; /* original instruction */ - u8 *replacement; - u8 cpuid; /* cpuid bit set for replacement */ - u8 instrlen; /* length of original instruction */ - u8 replacementlen; /* length of new instruction, <= instrlen */ - u8 pad1; -#ifdef CONFIG_X86_64 - u32 pad2; -#endif -}; - -extern void alternative_instructions(void); -extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); - -struct module; - -#ifdef CONFIG_SMP -extern void alternatives_smp_module_add(struct module *mod, char *name, - void *locks, void *locks_end, - void *text, void *text_end); -extern void alternatives_smp_module_del(struct module *mod); -extern void alternatives_smp_switch(int smp); -#else -static inline void alternatives_smp_module_add(struct module *mod, char *name, - void *locks, void *locks_end, - void *text, void *text_end) {} -static inline void alternatives_smp_module_del(struct module *mod) {} -static inline void alternatives_smp_switch(int smp) {} -#endif /* CONFIG_SMP */ - -/* - * Alternative instructions for different CPU types or capabilities. - * - * This allows to use optimized instructions even on generic binary - * kernels. - * - * length of oldinstr must be longer or equal the length of newinstr - * It can be padded with nops as needed. - * - * For non barrier like inlines please define new variants - * without volatile and memory clobber. - */ -#define alternative(oldinstr, newinstr, feature) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661b\n" /* label */ \ - _ASM_PTR "663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ - ".previous\n" \ - ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ - ".previous" :: "i" (feature) : "memory") - -/* - * Alternative inline assembly with input. - * - * Pecularities: - * No memory clobber here. - * Argument numbers start with 1. - * Best is to use constraints that are fixed size (like (%1) ... "r") - * If you use variable sized constraints like "m" or "g" in the - * replacement make sure to pad to the worst case length. - */ -#define alternative_input(oldinstr, newinstr, feature, input...) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661b\n" /* label */ \ - _ASM_PTR "663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ - ".previous\n" \ - ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ - ".previous" :: "i" (feature), ##input) - -/* Like alternative_input, but with a single output argument */ -#define alternative_io(oldinstr, newinstr, feature, output, input...) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661b\n" /* label */ \ - _ASM_PTR "663f\n" /* new instruction */ \ - " .byte %c[feat]\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ - ".previous\n" \ - ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ - ".previous" : output : [feat] "i" (feature), ##input) - -/* - * use this macro(s) if you need more than one output parameter - * in alternative_io - */ -#define ASM_OUTPUT2(a, b) a, b - -struct paravirt_patch_site; -#ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch_site *start, - struct paravirt_patch_site *end); -#else -static inline void -apply_paravirt(struct paravirt_patch_site *start, - struct paravirt_patch_site *end) -{} -#define __parainstructions NULL -#define __parainstructions_end NULL -#endif - -extern void text_poke(void *addr, unsigned char *opcode, int len); - -#endif /* _I386_ALTERNATIVE_H */ diff --git a/include/asm-x86/alternative_64.h b/include/asm-x86/alternative_64.h deleted file mode 100644 index 50efcebae33..00000000000 --- a/include/asm-x86/alternative_64.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef _X86_64_ALTERNATIVE_H -#define _X86_64_ALTERNATIVE_H - -#include -#include -#include - -/* - * Alternative inline assembly for SMP. - * - * The LOCK_PREFIX macro defined here replaces the LOCK and - * LOCK_PREFIX macros used everywhere in the source tree. - * - * SMP alternatives use the same data structures as the other - * alternatives and the X86_FEATURE_UP flag to indicate the case of a - * UP system running a SMP kernel. The existing apply_alternatives() - * works fine for patching a SMP kernel for UP. - * - * The SMP alternative tables can be kept after boot and contain both - * UP and SMP versions of the instructions to allow switching back to - * SMP at runtime, when hotplugging in a new CPU, which is especially - * useful in virtualized environments. - * - * The very common lock prefix is handled as special case in a - * separate table which is a pure address list without replacement ptr - * and size information. That keeps the table sizes small. - */ - -#ifdef CONFIG_SMP -#define LOCK_PREFIX \ - ".section .smp_locks,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661f\n" /* address */ \ - ".previous\n" \ - "661:\n\tlock; " - -#else /* ! CONFIG_SMP */ -#define LOCK_PREFIX "" -#endif - -/* This must be included *after* the definition of LOCK_PREFIX */ -#include - -struct alt_instr { - u8 *instr; /* original instruction */ - u8 *replacement; - u8 cpuid; /* cpuid bit set for replacement */ - u8 instrlen; /* length of original instruction */ - u8 replacementlen; /* length of new instruction, <= instrlen */ - u8 pad1; -#ifdef CONFIG_X86_64 - u32 pad2; -#endif -}; - -extern void alternative_instructions(void); -extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); - -struct module; - -#ifdef CONFIG_SMP -extern void alternatives_smp_module_add(struct module *mod, char *name, - void *locks, void *locks_end, - void *text, void *text_end); -extern void alternatives_smp_module_del(struct module *mod); -extern void alternatives_smp_switch(int smp); -#else -static inline void alternatives_smp_module_add(struct module *mod, char *name, - void *locks, void *locks_end, - void *text, void *text_end) {} -static inline void alternatives_smp_module_del(struct module *mod) {} -static inline void alternatives_smp_switch(int smp) {} -#endif /* CONFIG_SMP */ - -/* - * Alternative instructions for different CPU types or capabilities. - * - * This allows to use optimized instructions even on generic binary - * kernels. - * - * length of oldinstr must be longer or equal the length of newinstr - * It can be padded with nops as needed. - * - * For non barrier like inlines please define new variants - * without volatile and memory clobber. - */ -#define alternative(oldinstr, newinstr, feature) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661b\n" /* label */ \ - _ASM_PTR "663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ - ".previous\n" \ - ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ - ".previous" :: "i" (feature) : "memory") - -/* - * Alternative inline assembly with input. - * - * Pecularities: - * No memory clobber here. - * Argument numbers start with 1. - * Best is to use constraints that are fixed size (like (%1) ... "r") - * If you use variable sized constraints like "m" or "g" in the - * replacement make sure to pad to the worst case length. - */ -#define alternative_input(oldinstr, newinstr, feature, input...) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661b\n" /* label */ \ - _ASM_PTR "663f\n" /* new instruction */ \ - " .byte %c0\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ - ".previous\n" \ - ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ - ".previous" :: "i" (feature), ##input) - -/* Like alternative_input, but with a single output argument */ -#define alternative_io(oldinstr, newinstr, feature, output, input...) \ - asm volatile ("661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661b\n" /* label */ \ - _ASM_PTR "663f\n" /* new instruction */ \ - " .byte %c[feat]\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ - ".previous\n" \ - ".section .altinstr_replacement,\"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ - ".previous" : output : [feat] "i" (feature), ##input) - -/* - * use this macro(s) if you need more than one output parameter - * in alternative_io - */ -#define ASM_OUTPUT2(a, b) a, b - -struct paravirt_patch_site; -#ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch_site *start, - struct paravirt_patch_site *end); -#else -static inline void -apply_paravirt(struct paravirt_patch_site *start, - struct paravirt_patch_site *end) -{} -#define __parainstructions NULL -#define __parainstructions_end NULL -#endif - -extern void text_poke(void *addr, unsigned char *opcode, int len); - -#endif /* _X86_64_ALTERNATIVE_H */ -- cgit v1.2.2 From 013d23e1567c4cebee0a2db5c8fa97b91b34ac2a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 30 Jan 2008 13:30:30 +0100 Subject: x86 e820_64.c: make 2 functions static This patch makes the following needlessly global functions static: - e820_print_map() - early_panic() Signed-off-by: Adrian Bunk Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/e820_64.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h index 0bd4787a5d5..e535e6044e2 100644 --- a/include/asm-x86/e820_64.h +++ b/include/asm-x86/e820_64.h @@ -21,7 +21,6 @@ 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 void e820_print_map(char *who); 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 unsigned long e820_hole_size(unsigned long start, unsigned long end); -- cgit v1.2.2 From 867ab545668385b903f9379019000383675c49b3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 30 Jan 2008 13:30:31 +0100 Subject: x86: nmi_64.c: make code static This patch makes the following needlessly global code static: - panic_on_timeout - setup_nmi_watchdog() Signed-off-by: Adrian Bunk Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/nmi_64.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/nmi_64.h b/include/asm-x86/nmi_64.h index 92f36fb1dc6..2eeb74e5f3f 100644 --- a/include/asm-x86/nmi_64.h +++ b/include/asm-x86/nmi_64.h @@ -38,7 +38,6 @@ extern void die_nmi(char *str, struct pt_regs *regs, int do_panic); #define get_nmi_reason() inb(0x61) -extern int panic_on_timeout; extern int unknown_nmi_panic; extern int nmi_watchdog_enabled; @@ -57,7 +56,6 @@ extern void enable_timer_nmi_watchdog(void); extern int nmi_watchdog_tick (struct pt_regs * regs, unsigned reason); extern void nmi_watchdog_default(void); -extern int setup_nmi_watchdog(char *); extern atomic_t nmi_active; extern unsigned int nmi_watchdog; -- cgit v1.2.2 From 3e7593966be6f6d29a15138c0c96b961d437f2f5 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 30 Jan 2008 13:30:31 +0100 Subject: x86: pci-dma_64.c: cleanups This patch contains the following cleanups: - make the needlessly global iommu_setup() static - remove the unused EXPORT_SYMBOL(iommu_merge) Signed-off-by: Adrian Bunk Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pci_64.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pci_64.h b/include/asm-x86/pci_64.h index ef54226a932..37469031453 100644 --- a/include/asm-x86/pci_64.h +++ b/include/asm-x86/pci_64.h @@ -26,7 +26,6 @@ extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int l extern void pci_iommu_alloc(void); -extern int iommu_setup(char *opt); /* The PCI address space does equal the physical memory * address space. The networking and block device layers use -- cgit v1.2.2 From 2d2ee8de5f6d26ef2942e0b449aa68d9236d5777 Mon Sep 17 00:00:00 2001 From: Paul Jimenez Date: Wed, 30 Jan 2008 13:30:31 +0100 Subject: x86: mtrr use type bool [RESEND AGAIN] This is a janitorish patch to 1) remove private TRUE/FALSE #def's in favor of using the standard enum from linux/stddef.h and 2) switch the variables holding those values to type 'bool' (from linux/types.h) since it both seems more appropriate and allows for potentially better optimization. As a truly minor aside, I removed a couple of comments documenting a 'do_safe' parameter that seems to no longer exist. Signed-off-by: Paul Jimenez Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mtrr.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mtrr.h b/include/asm-x86/mtrr.h index e8320e4e6ca..262670e4207 100644 --- a/include/asm-x86/mtrr.h +++ b/include/asm-x86/mtrr.h @@ -89,9 +89,9 @@ struct mtrr_gentry extern void mtrr_save_fixed_ranges(void *); extern void mtrr_save_state(void); extern int mtrr_add (unsigned long base, unsigned long size, - unsigned int type, char increment); + unsigned int type, bool increment); extern int mtrr_add_page (unsigned long base, unsigned long size, - unsigned int type, char increment); + unsigned int type, bool increment); extern int mtrr_del (int reg, unsigned long base, unsigned long size); extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); @@ -101,12 +101,12 @@ extern void mtrr_bp_init(void); #define mtrr_save_fixed_ranges(arg) do {} while (0) #define mtrr_save_state() do {} while (0) static __inline__ int mtrr_add (unsigned long base, unsigned long size, - unsigned int type, char increment) + unsigned int type, bool increment) { return -ENODEV; } static __inline__ int mtrr_add_page (unsigned long base, unsigned long size, - unsigned int type, char increment) + unsigned int type, bool increment) { return -ENODEV; } -- cgit v1.2.2 From c9cce83dd1d59f52e2c8f8c7d265ba4854c40785 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Wed, 30 Jan 2008 13:30:32 +0100 Subject: x86: remove extern declarations for code, data, bss resources This patch removes the extern struct resource declarations for data_resource, code_resource and bss_resource on x86 and declares that three structures as static as done on other architectures like IA64. On i386, these structures are moved to setup_32.c (from e820_32.c) because that's code that is not specific to e820 and also required on EFI systems. That makes the "extern" reference superfluous. On x86_64, data_resource, code_resource and bss_resource are passed to e820_reserve_resources() as arguments just as done on i386 and IA64. That also avoids the "extern" reference and it's possible to make it static. Signed-off-by: Bernhard Walle Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/e820_32.h | 6 ++++++ include/asm-x86/e820_64.h | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h index 03f60c690c8..ae5ea19623f 100644 --- a/include/asm-x86/e820_32.h +++ b/include/asm-x86/e820_32.h @@ -12,6 +12,8 @@ #ifndef __E820_HEADER #define __E820_HEADER +#include + #define HIGH_MEMORY (1024*1024) #ifndef __ASSEMBLY__ @@ -26,6 +28,9 @@ 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 legacy_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); @@ -35,5 +40,6 @@ static inline void e820_mark_nosave_regions(void) } #endif + #endif/*!__ASSEMBLY__*/ #endif/*__E820_HEADER*/ diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h index e535e6044e2..1c7ba880417 100644 --- a/include/asm-x86/e820_64.h +++ b/include/asm-x86/e820_64.h @@ -11,6 +11,8 @@ #ifndef __E820_HEADER #define __E820_HEADER +#include + #ifndef __ASSEMBLY__ extern unsigned long find_e820_area(unsigned long start, unsigned long end, unsigned size); @@ -19,7 +21,8 @@ extern void add_memory_region(unsigned long start, unsigned long size, 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_reserve_resources(struct resource *code_resource, + struct resource *data_resource, struct resource *bss_resource); 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); -- cgit v1.2.2 From ec12fa5c80126b252ebcb474d12c832ec4647daa Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 30 Jan 2008 13:30:32 +0100 Subject: x86: bitops_32.h style cleanups Coding style cleanups in x86/bitops_32.h: - drop space in "* addr" - whitespace & indentation fixes - spello fixes Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/bitops_32.h | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h index 0b40f6d20be..5a29cce6a91 100644 --- a/include/asm-x86/bitops_32.h +++ b/include/asm-x86/bitops_32.h @@ -37,7 +37,7 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static inline void set_bit(int nr, volatile unsigned long * addr) +static inline void set_bit(int nr, volatile unsigned long *addr) { __asm__ __volatile__( LOCK_PREFIX "btsl %1,%0" @@ -54,7 +54,7 @@ static inline void set_bit(int nr, volatile unsigned long * addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static inline void __set_bit(int nr, volatile unsigned long * addr) +static inline void __set_bit(int nr, volatile unsigned long *addr) { __asm__( "btsl %1,%0" @@ -72,7 +72,7 @@ static inline void __set_bit(int nr, volatile unsigned long * addr) * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -static inline void clear_bit(int nr, volatile unsigned long * addr) +static inline void clear_bit(int nr, volatile unsigned long *addr) { __asm__ __volatile__( LOCK_PREFIX "btrl %1,%0" @@ -94,7 +94,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad clear_bit(nr, addr); } -static inline void __clear_bit(int nr, volatile unsigned long * addr) +static inline void __clear_bit(int nr, volatile unsigned long *addr) { __asm__ __volatile__( "btrl %1,%0" @@ -132,7 +132,7 @@ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long * * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static inline void __change_bit(int nr, volatile unsigned long * addr) +static inline void __change_bit(int nr, volatile unsigned long *addr) { __asm__ __volatile__( "btcl %1,%0" @@ -150,7 +150,7 @@ static inline void __change_bit(int nr, volatile unsigned long * addr) * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static inline void change_bit(int nr, volatile unsigned long * addr) +static inline void change_bit(int nr, volatile unsigned long *addr) { __asm__ __volatile__( LOCK_PREFIX "btcl %1,%0" @@ -167,7 +167,7 @@ static inline void change_bit(int nr, volatile unsigned long * addr) * It may be reordered on other architectures than x86. * It also implies a memory barrier. */ -static inline int test_and_set_bit(int nr, volatile unsigned long * addr) +static inline int test_and_set_bit(int nr, volatile unsigned long *addr) { int oldbit; @@ -199,7 +199,7 @@ static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -static inline int __test_and_set_bit(int nr, volatile unsigned long * addr) +static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) { int oldbit; @@ -219,7 +219,7 @@ static inline int __test_and_set_bit(int nr, volatile unsigned long * addr) * It can be reorderdered on other architectures other than x86. * It also implies a memory barrier. */ -static inline int test_and_clear_bit(int nr, volatile unsigned long * addr) +static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) { int oldbit; @@ -270,7 +270,7 @@ static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_change_bit(int nr, volatile unsigned long* addr) +static inline int test_and_change_bit(int nr, volatile unsigned long *addr) { int oldbit; @@ -287,7 +287,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long* addr) * @nr: bit number to test * @addr: Address to start counting from */ -static int test_bit(int nr, const volatile void * addr); +static int test_bit(int nr, const volatile void *addr); #endif static __always_inline int constant_test_bit(int nr, const volatile unsigned long *addr) @@ -295,7 +295,7 @@ static __always_inline int constant_test_bit(int nr, const volatile unsigned lon return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; } -static inline int variable_test_bit(int nr, const volatile unsigned long * addr) +static inline int variable_test_bit(int nr, const volatile unsigned long *addr) { int oldbit; @@ -306,10 +306,10 @@ static inline int variable_test_bit(int nr, const volatile unsigned long * addr) return oldbit; } -#define test_bit(nr,addr) \ -(__builtin_constant_p(nr) ? \ - constant_test_bit((nr),(addr)) : \ - variable_test_bit((nr),(addr))) +#define test_bit(nr, addr) \ + (__builtin_constant_p(nr) ? \ + constant_test_bit((nr), (addr)) : \ + variable_test_bit((nr), (addr))) #undef ADDR @@ -318,7 +318,7 @@ static inline int variable_test_bit(int nr, const volatile unsigned long * addr) * @addr: The address to start the search at * @size: The maximum size to search * - * Returns the bit-number of the first zero bit, not the number of the byte + * Returns the bit number of the first zero bit, not the number of the byte * containing a bit. */ static inline int find_first_zero_bit(const unsigned long *addr, unsigned size) @@ -348,7 +348,7 @@ static inline int find_first_zero_bit(const unsigned long *addr, unsigned size) /** * find_next_zero_bit - find the first zero bit in a memory region * @addr: The address to base the search on - * @offset: The bitnumber to start searching at + * @offset: The bit number to start searching at * @size: The maximum size to search */ int find_next_zero_bit(const unsigned long *addr, int size, int offset); @@ -372,7 +372,7 @@ static inline unsigned long __ffs(unsigned long word) * @addr: The address to start the search at * @size: The maximum size to search * - * Returns the bit-number of the first set bit, not the number of the byte + * Returns the bit number of the first set bit, not the number of the byte * containing a bit. */ static inline unsigned find_first_bit(const unsigned long *addr, unsigned size) @@ -391,7 +391,7 @@ static inline unsigned find_first_bit(const unsigned long *addr, unsigned size) /** * find_next_bit - find the first set bit in a memory region * @addr: The address to base the search on - * @offset: The bitnumber to start searching at + * @offset: The bit number to start searching at * @size: The maximum size to search */ int find_next_bit(const unsigned long *addr, int size, int offset); @@ -460,10 +460,10 @@ static inline int fls(int x) #include -#define ext2_set_bit_atomic(lock,nr,addr) \ - test_and_set_bit((nr),(unsigned long*)addr) -#define ext2_clear_bit_atomic(lock,nr, addr) \ - test_and_clear_bit((nr),(unsigned long*)addr) +#define ext2_set_bit_atomic(lock, nr, addr) \ + test_and_set_bit((nr), (unsigned long *)addr) +#define ext2_clear_bit_atomic(lock, nr, addr) \ + test_and_clear_bit((nr), (unsigned long *)addr) #include -- cgit v1.2.2 From 6ea8bad1c06c8ccde381f1c848afe6a245bb33b5 Mon Sep 17 00:00:00 2001 From: "clameter@sgi.com" Date: Wed, 30 Jan 2008 13:30:32 +0100 Subject: x86: clean up stack allocation and free Clean up the allocation and freeing of stacks a bit by using a __GFP_ZERO flag instead of memset. Signed-off-by: Christoph Lameter Cc: Andi Kleen Cc: Mike Travis Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/thread_info_64.h | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h index 7f6ee68f000..1ac23c15723 100644 --- a/include/asm-x86/thread_info_64.h +++ b/include/asm-x86/thread_info_64.h @@ -74,20 +74,14 @@ static inline struct thread_info *stack_thread_info(void) /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE -#define alloc_thread_info(tsk) \ - ({ \ - struct thread_info *ret; \ - \ - ret = ((struct thread_info *) __get_free_pages(GFP_KERNEL,THREAD_ORDER)); \ - if (ret) \ - memset(ret, 0, THREAD_SIZE); \ - ret; \ - }) +#define THREAD_FLAGS (GFP_KERNEL | __GFP_ZERO) #else -#define alloc_thread_info(tsk) \ - ((struct thread_info *) __get_free_pages(GFP_KERNEL,THREAD_ORDER)) +#define THREAD_FLAGS GFP_KERNEL #endif +#define alloc_thread_info(tsk) \ + ((struct thread_info *) __get_free_pages(THREAD_FLAGS, THREAD_ORDER)) + #define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER) #else /* !__ASSEMBLY__ */ -- cgit v1.2.2 From 6abcd98ffafbff81f0bfd7ee1d129e634af13245 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:30:33 +0100 Subject: x86: irqflags consolidation This patch consolidates the irqflags include files containing common paravirt definitions. The native definition for interrupt handling, halt, and such, are the same for 32 and 64 bit, and they are kept in irqflags.h. the differences are split in the arch-specific files. The syscall function, irq_enable_sysexit, has a very specific i386 naming, and its name is then changed to a more general one. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Steven Rostedt Acked-by: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/irqflags.h | 246 +++++++++++++++++++++++++++++++++++++++++- include/asm-x86/irqflags_32.h | 195 --------------------------------- include/asm-x86/irqflags_64.h | 174 ------------------------------ include/asm-x86/paravirt.h | 9 +- 4 files changed, 248 insertions(+), 376 deletions(-) delete mode 100644 include/asm-x86/irqflags_32.h delete mode 100644 include/asm-x86/irqflags_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h index 1b695ff5268..92021c1ffa3 100644 --- a/include/asm-x86/irqflags.h +++ b/include/asm-x86/irqflags.h @@ -1,5 +1,245 @@ -#ifdef CONFIG_X86_32 -# include "irqflags_32.h" +#ifndef _X86_IRQFLAGS_H_ +#define _X86_IRQFLAGS_H_ + +#include + +#ifndef __ASSEMBLY__ +/* + * Interrupt control: + */ + +static inline unsigned long native_save_fl(void) +{ + unsigned long flags; + + __asm__ __volatile__( + "# __raw_save_flags\n\t" + "pushf ; pop %0" + : "=g" (flags) + : /* no input */ + : "memory" + ); + + return flags; +} + +static inline void native_restore_fl(unsigned long flags) +{ + __asm__ __volatile__( + "push %0 ; popf" + : /* no output */ + :"g" (flags) + :"memory", "cc" + ); +} + +static inline void native_irq_disable(void) +{ + asm volatile("cli": : :"memory"); +} + +static inline void native_irq_enable(void) +{ + asm volatile("sti": : :"memory"); +} + +static inline void native_safe_halt(void) +{ + asm volatile("sti; hlt": : :"memory"); +} + +static inline void native_halt(void) +{ + asm volatile("hlt": : :"memory"); +} + +#endif + +#ifdef CONFIG_PARAVIRT +#include +#else +#ifndef __ASSEMBLY__ + +static inline unsigned long __raw_local_save_flags(void) +{ + return native_save_fl(); +} + +static inline void raw_local_irq_restore(unsigned long flags) +{ + native_restore_fl(flags); +} + +static inline void raw_local_irq_disable(void) +{ + native_irq_disable(); +} + +static inline void raw_local_irq_enable(void) +{ + native_irq_enable(); +} + +/* + * Used in the idle loop; sti takes one instruction cycle + * to complete: + */ +static inline void raw_safe_halt(void) +{ + native_safe_halt(); +} + +/* + * Used when interrupts are already enabled or to + * shutdown the processor: + */ +static inline void halt(void) +{ + native_halt(); +} + +/* + * For spinlocks, etc: + */ +static inline unsigned long __raw_local_irq_save(void) +{ + unsigned long flags = __raw_local_save_flags(); + + raw_local_irq_disable(); + + return flags; +} +#else + +#define ENABLE_INTERRUPTS(x) sti +#define DISABLE_INTERRUPTS(x) cli + +#ifdef CONFIG_X86_64 +#define INTERRUPT_RETURN iretq +#define ENABLE_INTERRUPTS_SYSCALL_RET \ + movq %gs:pda_oldrsp, %rsp; \ + swapgs; \ + sysretq; +#else +#define INTERRUPT_RETURN iret +#define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit +#define GET_CR0_INTO_EAX movl %cr0, %eax +#endif + + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_PARAVIRT */ + +#ifndef __ASSEMBLY__ +#define raw_local_save_flags(flags) \ + do { (flags) = __raw_local_save_flags(); } while (0) + +#define raw_local_irq_save(flags) \ + do { (flags) = __raw_local_irq_save(); } while (0) + +static inline int raw_irqs_disabled_flags(unsigned long flags) +{ + return !(flags & X86_EFLAGS_IF); +} + +static inline int raw_irqs_disabled(void) +{ + unsigned long flags = __raw_local_save_flags(); + + return raw_irqs_disabled_flags(flags); +} + +/* + * makes the traced hardirq state match with the machine state + * + * should be a rarely used function, only in places where its + * otherwise impossible to know the irq state, like in traps. + */ +static inline void trace_hardirqs_fixup_flags(unsigned long flags) +{ + if (raw_irqs_disabled_flags(flags)) + trace_hardirqs_off(); + else + trace_hardirqs_on(); +} + +static inline void trace_hardirqs_fixup(void) +{ + unsigned long flags = __raw_local_save_flags(); + + trace_hardirqs_fixup_flags(flags); +} + #else -# include "irqflags_64.h" + +#ifdef CONFIG_X86_64 +/* + * Currently paravirt can't handle swapgs nicely when we + * don't have a stack we can rely on (such as a user space + * stack). So we either find a way around these or just fault + * and emulate if a guest tries to call swapgs directly. + * + * Either way, this is a good way to document that we don't + * have a reliable stack. x86_64 only. + */ +#define SWAPGS_UNSAFE_STACK swapgs +#define ARCH_TRACE_IRQS_ON call trace_hardirqs_on_thunk +#define ARCH_TRACE_IRQS_OFF call trace_hardirqs_off_thunk +#define ARCH_LOCKDEP_SYS_EXIT call lockdep_sys_exit_thunk +#define ARCH_LOCKDEP_SYS_EXIT_IRQ \ + TRACE_IRQS_ON; \ + sti; \ + SAVE_REST; \ + LOCKDEP_SYS_EXIT; \ + RESTORE_REST; \ + cli; \ + TRACE_IRQS_OFF; + +#else +#define ARCH_TRACE_IRQS_ON \ + pushl %eax; \ + pushl %ecx; \ + pushl %edx; \ + call trace_hardirqs_on; \ + popl %edx; \ + popl %ecx; \ + popl %eax; + +#define ARCH_TRACE_IRQS_OFF \ + pushl %eax; \ + pushl %ecx; \ + pushl %edx; \ + call trace_hardirqs_off; \ + popl %edx; \ + popl %ecx; \ + popl %eax; + +#define ARCH_LOCKDEP_SYS_EXIT \ + pushl %eax; \ + pushl %ecx; \ + pushl %edx; \ + call lockdep_sys_exit; \ + popl %edx; \ + popl %ecx; \ + popl %eax; + +#define ARCH_LOCKDEP_SYS_EXIT_IRQ +#endif + +#ifdef CONFIG_TRACE_IRQFLAGS +# define TRACE_IRQS_ON ARCH_TRACE_IRQS_ON +# define TRACE_IRQS_OFF ARCH_TRACE_IRQS_OFF +#else +# define TRACE_IRQS_ON +# define TRACE_IRQS_OFF +#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define LOCKDEP_SYS_EXIT ARCH_LOCKDEP_SYS_EXIT +# define LOCKDEP_SYS_EXIT_IRQ ARCH_LOCKDEP_SYS_EXIT_IRQ +# else +# define LOCKDEP_SYS_EXIT +# define LOCKDEP_SYS_EXIT_IRQ +# endif + +#endif /* __ASSEMBLY__ */ #endif diff --git a/include/asm-x86/irqflags_32.h b/include/asm-x86/irqflags_32.h deleted file mode 100644 index 98b21b9bdce..00000000000 --- a/include/asm-x86/irqflags_32.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * IRQ flags handling - * - * This file gets included from lowlevel asm headers too, to provide - * wrapped versions of the local_irq_*() APIs, based on the - * raw_local_irq_*() functions from the lowlevel headers. - */ -#ifndef _ASM_IRQFLAGS_H -#define _ASM_IRQFLAGS_H -#include - -#ifndef __ASSEMBLY__ -static inline unsigned long native_save_fl(void) -{ - unsigned long f; - asm volatile("pushfl ; popl %0":"=g" (f): /* no input */); - return f; -} - -static inline void native_restore_fl(unsigned long f) -{ - asm volatile("pushl %0 ; popfl": /* no output */ - :"g" (f) - :"memory", "cc"); -} - -static inline void native_irq_disable(void) -{ - asm volatile("cli": : :"memory"); -} - -static inline void native_irq_enable(void) -{ - asm volatile("sti": : :"memory"); -} - -static inline void native_safe_halt(void) -{ - asm volatile("sti; hlt": : :"memory"); -} - -static inline void native_halt(void) -{ - asm volatile("hlt": : :"memory"); -} -#endif /* __ASSEMBLY__ */ - -#ifdef CONFIG_PARAVIRT -#include -#else -#ifndef __ASSEMBLY__ - -static inline unsigned long __raw_local_save_flags(void) -{ - return native_save_fl(); -} - -static inline void raw_local_irq_restore(unsigned long flags) -{ - native_restore_fl(flags); -} - -static inline void raw_local_irq_disable(void) -{ - native_irq_disable(); -} - -static inline void raw_local_irq_enable(void) -{ - native_irq_enable(); -} - -/* - * Used in the idle loop; sti takes one instruction cycle - * to complete: - */ -static inline void raw_safe_halt(void) -{ - native_safe_halt(); -} - -/* - * Used when interrupts are already enabled or to - * shutdown the processor: - */ -static inline void halt(void) -{ - native_halt(); -} - -/* - * For spinlocks, etc: - */ -static inline unsigned long __raw_local_irq_save(void) -{ - unsigned long flags = __raw_local_save_flags(); - - raw_local_irq_disable(); - - return flags; -} - -#else -#define DISABLE_INTERRUPTS(clobbers) cli -#define ENABLE_INTERRUPTS(clobbers) sti -#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit -#define INTERRUPT_RETURN iret -#define GET_CR0_INTO_EAX movl %cr0, %eax -#endif /* __ASSEMBLY__ */ -#endif /* CONFIG_PARAVIRT */ - -#ifndef __ASSEMBLY__ -#define raw_local_save_flags(flags) \ - do { (flags) = __raw_local_save_flags(); } while (0) - -#define raw_local_irq_save(flags) \ - do { (flags) = __raw_local_irq_save(); } while (0) - -static inline int raw_irqs_disabled_flags(unsigned long flags) -{ - return !(flags & X86_EFLAGS_IF); -} - -static inline int raw_irqs_disabled(void) -{ - unsigned long flags = __raw_local_save_flags(); - - return raw_irqs_disabled_flags(flags); -} - -/* - * makes the traced hardirq state match with the machine state - * - * should be a rarely used function, only in places where its - * otherwise impossible to know the irq state, like in traps. - */ -static inline void trace_hardirqs_fixup_flags(unsigned long flags) -{ - if (raw_irqs_disabled_flags(flags)) - trace_hardirqs_off(); - else - trace_hardirqs_on(); -} - -static inline void trace_hardirqs_fixup(void) -{ - unsigned long flags = __raw_local_save_flags(); - - trace_hardirqs_fixup_flags(flags); -} -#endif /* __ASSEMBLY__ */ - -/* - * Do the CPU's IRQ-state tracing from assembly code. We call a - * C function, so save all the C-clobbered registers: - */ -#ifdef CONFIG_TRACE_IRQFLAGS - -# define TRACE_IRQS_ON \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call trace_hardirqs_on; \ - popl %edx; \ - popl %ecx; \ - popl %eax; - -# define TRACE_IRQS_OFF \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call trace_hardirqs_off; \ - popl %edx; \ - popl %ecx; \ - popl %eax; - -#else -# define TRACE_IRQS_ON -# define TRACE_IRQS_OFF -#endif - -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# define LOCKDEP_SYS_EXIT \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call lockdep_sys_exit; \ - popl %edx; \ - popl %ecx; \ - popl %eax; -#else -# define LOCKDEP_SYS_EXIT -#endif - -#endif diff --git a/include/asm-x86/irqflags_64.h b/include/asm-x86/irqflags_64.h deleted file mode 100644 index 38c07db733c..00000000000 --- a/include/asm-x86/irqflags_64.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * IRQ flags handling - * - * This file gets included from lowlevel asm headers too, to provide - * wrapped versions of the local_irq_*() APIs, based on the - * raw_local_irq_*() functions from the lowlevel headers. - */ -#ifndef _ASM_IRQFLAGS_H -#define _ASM_IRQFLAGS_H -#include - -#ifndef __ASSEMBLY__ -/* - * Interrupt control: - */ - -static inline unsigned long __raw_local_save_flags(void) -{ - unsigned long flags; - - __asm__ __volatile__( - "# __raw_save_flags\n\t" - "pushfq ; popq %q0" - : "=g" (flags) - : /* no input */ - : "memory" - ); - - return flags; -} - -#define raw_local_save_flags(flags) \ - do { (flags) = __raw_local_save_flags(); } while (0) - -static inline void raw_local_irq_restore(unsigned long flags) -{ - __asm__ __volatile__( - "pushq %0 ; popfq" - : /* no output */ - :"g" (flags) - :"memory", "cc" - ); -} - -#ifdef CONFIG_X86_VSMP - -/* - * Interrupt control for the VSMP architecture: - */ - -static inline void raw_local_irq_disable(void) -{ - unsigned long flags = __raw_local_save_flags(); - - raw_local_irq_restore((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC); -} - -static inline void raw_local_irq_enable(void) -{ - unsigned long flags = __raw_local_save_flags(); - - raw_local_irq_restore((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC)); -} - -static inline int raw_irqs_disabled_flags(unsigned long flags) -{ - return !(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC); -} - -#else /* CONFIG_X86_VSMP */ - -static inline void raw_local_irq_disable(void) -{ - __asm__ __volatile__("cli" : : : "memory"); -} - -static inline void raw_local_irq_enable(void) -{ - __asm__ __volatile__("sti" : : : "memory"); -} - -static inline int raw_irqs_disabled_flags(unsigned long flags) -{ - return !(flags & X86_EFLAGS_IF); -} - -#endif - -/* - * For spinlocks, etc.: - */ - -static inline unsigned long __raw_local_irq_save(void) -{ - unsigned long flags = __raw_local_save_flags(); - - raw_local_irq_disable(); - - return flags; -} - -#define raw_local_irq_save(flags) \ - do { (flags) = __raw_local_irq_save(); } while (0) - -static inline int raw_irqs_disabled(void) -{ - unsigned long flags = __raw_local_save_flags(); - - return raw_irqs_disabled_flags(flags); -} - -/* - * makes the traced hardirq state match with the machine state - * - * should be a rarely used function, only in places where its - * otherwise impossible to know the irq state, like in traps. - */ -static inline void trace_hardirqs_fixup_flags(unsigned long flags) -{ - if (raw_irqs_disabled_flags(flags)) - trace_hardirqs_off(); - else - trace_hardirqs_on(); -} - -static inline void trace_hardirqs_fixup(void) -{ - unsigned long flags = __raw_local_save_flags(); - - trace_hardirqs_fixup_flags(flags); -} -/* - * Used in the idle loop; sti takes one instruction cycle - * to complete: - */ -static inline void raw_safe_halt(void) -{ - __asm__ __volatile__("sti; hlt" : : : "memory"); -} - -/* - * Used when interrupts are already enabled or to - * shutdown the processor: - */ -static inline void halt(void) -{ - __asm__ __volatile__("hlt": : :"memory"); -} - -#else /* __ASSEMBLY__: */ -# ifdef CONFIG_TRACE_IRQFLAGS -# define TRACE_IRQS_ON call trace_hardirqs_on_thunk -# define TRACE_IRQS_OFF call trace_hardirqs_off_thunk -# else -# define TRACE_IRQS_ON -# define TRACE_IRQS_OFF -# endif -# ifdef CONFIG_DEBUG_LOCK_ALLOC -# define LOCKDEP_SYS_EXIT call lockdep_sys_exit_thunk -# define LOCKDEP_SYS_EXIT_IRQ \ - TRACE_IRQS_ON; \ - sti; \ - SAVE_REST; \ - LOCKDEP_SYS_EXIT; \ - RESTORE_REST; \ - cli; \ - TRACE_IRQS_OFF; -# else -# define LOCKDEP_SYS_EXIT -# define LOCKDEP_SYS_EXIT_IRQ -# endif -#endif - -#endif diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 19fd3e67b08..be7b934f6c5 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -121,7 +121,7 @@ struct pv_cpu_ops { u64 (*read_pmc)(void); /* These two are jmp to, not actually called. */ - void (*irq_enable_sysexit)(void); + void (*irq_enable_syscall_ret)(void); void (*iret)(void); struct pv_lazy_ops lazy_mode; @@ -1138,9 +1138,10 @@ static inline unsigned long __raw_local_irq_save(void) call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \ popl %edx; popl %ecx; popl %eax) -#define ENABLE_INTERRUPTS_SYSEXIT \ - PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\ - jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit) +#define ENABLE_INTERRUPTS_SYSCALL_RET \ + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\ + CLBR_NONE, \ + jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret) #define GET_CR0_INTO_EAX \ push %ecx; push %edx; \ -- cgit v1.2.2 From 2fed0c507cf0101d511366f36e8573f403dbfea5 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:30:33 +0100 Subject: x86: consolidate spinlock.h The cli and sti instructions need to be replaced by paravirt hooks. For the i386 architecture, this is already done. The code requirements aren't much different from x86_64 POV, so this part is consolidated in the common header Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Steven Rostedt Acked-by: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/spinlock.h | 14 +++++++++ include/asm-x86/spinlock_32.h | 71 ++++++++++++++++--------------------------- include/asm-x86/spinlock_64.h | 37 ++++++++++++++-------- 3 files changed, 64 insertions(+), 58 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h index d74d85e71dc..e1d555a3dfe 100644 --- a/include/asm-x86/spinlock.h +++ b/include/asm-x86/spinlock.h @@ -1,5 +1,19 @@ +#ifndef _X86_SPINLOCK_H_ +#define _X86_SPINLOCK_H_ + +#ifdef CONFIG_PARAVIRT +#include +#else +#define CLI_STRING "cli" +#define STI_STRING "sti" +#define CLI_STI_CLOBBERS +#define CLI_STI_INPUT_ARGS +#endif /* CONFIG_PARAVIRT */ + #ifdef CONFIG_X86_32 # include "spinlock_32.h" #else # include "spinlock_64.h" #endif + +#endif diff --git a/include/asm-x86/spinlock_32.h b/include/asm-x86/spinlock_32.h index d3bcebed60c..c42c3f12d7c 100644 --- a/include/asm-x86/spinlock_32.h +++ b/include/asm-x86/spinlock_32.h @@ -5,16 +5,6 @@ #include #include #include -#include - -#ifdef CONFIG_PARAVIRT -#include -#else -#define CLI_STRING "cli" -#define STI_STRING "sti" -#define CLI_STI_CLOBBERS -#define CLI_STI_INPUT_ARGS -#endif /* CONFIG_PARAVIRT */ /* * Your basic SMP spinlocks, allowing only a single CPU anywhere @@ -27,23 +17,24 @@ * (the type definitions are in asm/spinlock_types.h) */ -static inline int __raw_spin_is_locked(raw_spinlock_t *x) +static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { - return *(volatile signed char *)(&(x)->slock) <= 0; + return *(volatile signed char *)(&(lock)->slock) <= 0; } static inline void __raw_spin_lock(raw_spinlock_t *lock) { - asm volatile("\n1:\t" - LOCK_PREFIX " ; decb %0\n\t" - "jns 3f\n" - "2:\t" - "rep;nop\n\t" - "cmpb $0,%0\n\t" - "jle 2b\n\t" - "jmp 1b\n" - "3:\n\t" - : "+m" (lock->slock) : : "memory"); + asm volatile( + "\n1:\t" + LOCK_PREFIX " ; decb %0\n\t" + "jns 3f\n" + "2:\t" + "rep;nop\n\t" + "cmpb $0,%0\n\t" + "jle 2b\n\t" + "jmp 1b\n" + "3:\n\t" + : "+m" (lock->slock) : : "memory"); } /* @@ -55,7 +46,8 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. */ #ifndef CONFIG_PROVE_LOCKING -static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, + unsigned long flags) { asm volatile( "\n1:\t" @@ -79,18 +71,20 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla "5:\n\t" : [slock] "+m" (lock->slock) : [flags] "r" (flags) - CLI_STI_INPUT_ARGS + CLI_STI_INPUT_ARGS : "memory" CLI_STI_CLOBBERS); } #endif static inline int __raw_spin_trylock(raw_spinlock_t *lock) { - char oldval; + signed char oldval; + asm volatile( "xchgb %b0,%1" :"=q" (oldval), "+m" (lock->slock) :"0" (0) : "memory"); + return oldval > 0; } @@ -112,7 +106,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - char oldval = 1; + unsigned char oldval = 1; asm volatile("xchgb %b0, %1" : "=q" (oldval), "+m" (lock->slock) @@ -139,31 +133,16 @@ static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) * * On x86, we implement read-write locks as a 32-bit counter * with the high bit (sign) being the "contended" bit. - * - * The inline assembly is non-obvious. Think about it. - * - * Changed to use the same technique as rw semaphores. See - * semaphore.h for details. -ben - * - * the helpers are in arch/i386/kernel/semaphore.c */ -/** - * read_can_lock - would read_trylock() succeed? - * @lock: the rwlock in question. - */ -static inline int __raw_read_can_lock(raw_rwlock_t *x) +static inline int __raw_read_can_lock(raw_rwlock_t *lock) { - return (int)(x)->lock > 0; + return (int)(lock)->lock > 0; } -/** - * write_can_lock - would write_trylock() succeed? - * @lock: the rwlock in question. - */ -static inline int __raw_write_can_lock(raw_rwlock_t *x) +static inline int __raw_write_can_lock(raw_rwlock_t *lock) { - return (x)->lock == RW_LOCK_BIAS; + return (lock)->lock == RW_LOCK_BIAS; } static inline void __raw_read_lock(raw_rwlock_t *rw) @@ -187,6 +166,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) static inline int __raw_read_trylock(raw_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; + atomic_dec(count); if (atomic_read(count) >= 0) return 1; @@ -197,6 +177,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *lock) static inline int __raw_write_trylock(raw_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; + if (atomic_sub_and_test(RW_LOCK_BIAS, count)) return 1; atomic_add(RW_LOCK_BIAS, count); diff --git a/include/asm-x86/spinlock_64.h b/include/asm-x86/spinlock_64.h index 88bf981e73c..3b5adf92ad0 100644 --- a/include/asm-x86/spinlock_64.h +++ b/include/asm-x86/spinlock_64.h @@ -33,14 +33,21 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) "cmpl $0,%0\n\t" "jle 3b\n\t" "jmp 1b\n" - "2:\t" : "=m" (lock->slock) : : "memory"); + "2:\t" + : "=m" (lock->slock) : : "memory"); } /* - * Same as __raw_spin_lock, but reenable interrupts during spinning. + * It is easier for the lock validator if interrupts are not re-enabled + * in the middle of a lock-acquire. This is a performance feature anyway + * so we turn it off: + * + * NOTE: there's an irqs-on section here, which normally would have to be + * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. */ #ifndef CONFIG_PROVE_LOCKING -static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, + unsigned long flags) { asm volatile( "\n1:\t" @@ -48,12 +55,12 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla "jns 5f\n" "testl $0x200, %1\n\t" /* interrupts were disabled? */ "jz 4f\n\t" - "sti\n" + STI_STRING "\n" "3:\t" "rep;nop\n\t" "cmpl $0, %0\n\t" "jle 3b\n\t" - "cli\n\t" + CLI_STRING "\n\t" "jmp 1b\n" "4:\t" "rep;nop\n\t" @@ -61,7 +68,9 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla "jg 1b\n\t" "jmp 4b\n" "5:\n\t" - : "+m" (lock->slock) : "r" ((unsigned)flags) : "memory"); + : "+m" (lock->slock) + : "r" ((unsigned)flags) CLI_STI_INPUT_ARGS + : "memory" CLI_STI_CLOBBERS); } #endif @@ -79,7 +88,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - asm volatile("movl $1,%0" :"=m" (lock->slock) :: "memory"); + asm volatile("movl $1,%0" : "=m" (lock->slock) :: "memory"); } static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) @@ -114,18 +123,18 @@ static inline int __raw_write_can_lock(raw_rwlock_t *lock) static inline void __raw_read_lock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" "jns 1f\n" - "call __read_lock_failed\n" + "call __read_lock_failed\n\t" "1:\n" ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); } static inline void __raw_write_lock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "subl %1,(%0)\n\t" + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" "jz 1f\n" - "\tcall __write_lock_failed\n\t" + "call __write_lock_failed\n\t" "1:\n" ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); } @@ -133,6 +142,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) static inline int __raw_read_trylock(raw_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; + atomic_dec(count); if (atomic_read(count) >= 0) return 1; @@ -143,6 +153,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *lock) static inline int __raw_write_trylock(raw_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; + if (atomic_sub_and_test(RW_LOCK_BIAS, count)) return 1; atomic_add(RW_LOCK_BIAS, count); @@ -151,12 +162,12 @@ static inline int __raw_write_trylock(raw_rwlock_t *lock) static inline void __raw_read_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX " ; incl %0" :"=m" (rw->lock) : : "memory"); + asm volatile(LOCK_PREFIX "incl %0" :"=m" (rw->lock) : : "memory"); } static inline void __raw_write_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX " ; addl $" RW_LOCK_BIAS_STR ",%0" + asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",%0" : "=m" (rw->lock) : : "memory"); } -- cgit v1.2.2 From a33fff3a033f2e8a930067ad608c21e1f86bffab Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:34 +0100 Subject: x86: fix asm constraints in spinlock_32/64.h Use the correct constraints for the spinlock assembler functions. read (modify) write functions need "+m" instead of "=m" Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/spinlock_32.h | 2 +- include/asm-x86/spinlock_64.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/spinlock_32.h b/include/asm-x86/spinlock_32.h index c42c3f12d7c..fca124a1103 100644 --- a/include/asm-x86/spinlock_32.h +++ b/include/asm-x86/spinlock_32.h @@ -99,7 +99,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - asm volatile("movb $1,%0" : "+m" (lock->slock) :: "memory"); + asm volatile("movb $1,%0" : "=m" (lock->slock) :: "memory"); } #else diff --git a/include/asm-x86/spinlock_64.h b/include/asm-x86/spinlock_64.h index 3b5adf92ad0..e81f6c18d87 100644 --- a/include/asm-x86/spinlock_64.h +++ b/include/asm-x86/spinlock_64.h @@ -34,7 +34,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) "jle 3b\n\t" "jmp 1b\n" "2:\t" - : "=m" (lock->slock) : : "memory"); + : "+m" (lock->slock) : : "memory"); } /* @@ -80,7 +80,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) asm volatile( "xchgl %0,%1" - :"=q" (oldval), "=m" (lock->slock) + :"=q" (oldval), "+m" (lock->slock) :"0" (0) : "memory"); return oldval > 0; @@ -162,13 +162,13 @@ static inline int __raw_write_trylock(raw_rwlock_t *lock) static inline void __raw_read_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "incl %0" :"=m" (rw->lock) : : "memory"); + asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); } static inline void __raw_write_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",%0" - : "=m" (rw->lock) : : "memory"); + asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ", %0" + : "+m" (rw->lock) : : "memory"); } #define _raw_spin_relax(lock) cpu_relax() -- cgit v1.2.2 From 6514f93a2ce643ef5914eae7ce49b978e1d356aa Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:34 +0100 Subject: x86: use immediates instead of RW_LOCK_BIAS_STR Use immediate instead of the RW_LOCK_BIAS_STR. Makes the code more readable and gets rid of the string constant. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/rwlock.h | 1 - include/asm-x86/spinlock_32.h | 8 ++++---- include/asm-x86/spinlock_64.h | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/rwlock.h b/include/asm-x86/rwlock.h index f2b64a429e6..6a8c0d64510 100644 --- a/include/asm-x86/rwlock.h +++ b/include/asm-x86/rwlock.h @@ -2,7 +2,6 @@ #define _ASM_X86_RWLOCK_H #define RW_LOCK_BIAS 0x01000000 -#define RW_LOCK_BIAS_STR "0x01000000" /* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */ diff --git a/include/asm-x86/spinlock_32.h b/include/asm-x86/spinlock_32.h index fca124a1103..e7a14ab906e 100644 --- a/include/asm-x86/spinlock_32.h +++ b/include/asm-x86/spinlock_32.h @@ -156,11 +156,11 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) static inline void __raw_write_lock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" "jz 1f\n" "call __write_lock_failed\n\t" "1:\n" - ::"a" (rw) : "memory"); + ::"a" (rw), "i" (RW_LOCK_BIAS) : "memory"); } static inline int __raw_read_trylock(raw_rwlock_t *lock) @@ -191,8 +191,8 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) static inline void __raw_write_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ", %0" - : "+m" (rw->lock) : : "memory"); + asm volatile(LOCK_PREFIX "addl %1, %0" + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); } #define _raw_spin_relax(lock) cpu_relax() diff --git a/include/asm-x86/spinlock_64.h b/include/asm-x86/spinlock_64.h index e81f6c18d87..ab50e7f5105 100644 --- a/include/asm-x86/spinlock_64.h +++ b/include/asm-x86/spinlock_64.h @@ -127,7 +127,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) "jns 1f\n" "call __read_lock_failed\n\t" "1:\n" - ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); + ::"D" (rw) : "memory"); } static inline void __raw_write_lock(raw_rwlock_t *rw) @@ -167,8 +167,8 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) static inline void __raw_write_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ", %0" - : "+m" (rw->lock) : : "memory"); + asm volatile(LOCK_PREFIX "addl %1, %0" + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); } #define _raw_spin_relax(lock) cpu_relax() -- cgit v1.2.2 From 3b23ed84ec34f04f54f7d5b1e35f258d64a7a5fb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:34 +0100 Subject: x86: spinlock_32/64 match the jump labels and symbols Match the jump labels in the 32/64 variants and switch the 64bit version to symbols, so the functions are almost identical except for the operand size now. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/spinlock_32.h | 1 - include/asm-x86/spinlock_64.h | 21 +++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/spinlock_32.h b/include/asm-x86/spinlock_32.h index e7a14ab906e..4ef626d5368 100644 --- a/include/asm-x86/spinlock_32.h +++ b/include/asm-x86/spinlock_32.h @@ -53,7 +53,6 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, "\n1:\t" LOCK_PREFIX " ; decb %[slock]\n\t" "jns 5f\n" - "2:\t" "testl $0x200, %[flags]\n\t" "jz 4f\n\t" STI_STRING "\n" diff --git a/include/asm-x86/spinlock_64.h b/include/asm-x86/spinlock_64.h index ab50e7f5105..19d483c8018 100644 --- a/include/asm-x86/spinlock_64.h +++ b/include/asm-x86/spinlock_64.h @@ -27,13 +27,13 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) asm volatile( "\n1:\t" LOCK_PREFIX " ; decl %0\n\t" - "jns 2f\n" - "3:\n" + "jns 3f\n" + "2:\t" "rep;nop\n\t" "cmpl $0,%0\n\t" - "jle 3b\n\t" + "jle 2b\n\t" "jmp 1b\n" - "2:\t" + "3:\n\t" : "+m" (lock->slock) : : "memory"); } @@ -51,25 +51,26 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, { asm volatile( "\n1:\t" - LOCK_PREFIX " ; decl %0\n\t" + LOCK_PREFIX " ; decl %[slock]\n\t" "jns 5f\n" - "testl $0x200, %1\n\t" /* interrupts were disabled? */ + "testl $0x200, %[flags]\n\t" "jz 4f\n\t" STI_STRING "\n" "3:\t" "rep;nop\n\t" - "cmpl $0, %0\n\t" + "cmpl $0, %[slock]\n\t" "jle 3b\n\t" CLI_STRING "\n\t" "jmp 1b\n" "4:\t" "rep;nop\n\t" - "cmpl $0, %0\n\t" + "cmpl $0, %[slock]\n\t" "jg 1b\n\t" "jmp 4b\n" "5:\n\t" - : "+m" (lock->slock) - : "r" ((unsigned)flags) CLI_STI_INPUT_ARGS + : [slock] "+m" (lock->slock) + : [flags] "r" ((unsigned)flags) + CLI_STI_INPUT_ARGS : "memory" CLI_STI_CLOBBERS); } #endif -- cgit v1.2.2 From cf244e30f5b50763cbe85f7de30923d12999e38d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:34 +0100 Subject: x86: spinlock_32/64 substitute types and instructions Use _slock_t for the spinlock data types and replace the instructions by string defines, which makes the code of 32/64 bit versions more or less identical. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/spinlock_32.h | 31 +++++++++++++++++++------------ include/asm-x86/spinlock_64.h | 31 +++++++++++++++++++------------ 2 files changed, 38 insertions(+), 24 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/spinlock_32.h b/include/asm-x86/spinlock_32.h index 4ef626d5368..2de9b8b8990 100644 --- a/include/asm-x86/spinlock_32.h +++ b/include/asm-x86/spinlock_32.h @@ -17,20 +17,27 @@ * (the type definitions are in asm/spinlock_types.h) */ +typedef char _slock_t; +#define LOCK_INS_DEC "decb" +#define LOCK_INS_XCH "xchgb" +#define LOCK_INS_MOV "movb" +#define LOCK_INS_CMP "cmpb" +#define LOCK_PTR_REG "a" + static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { - return *(volatile signed char *)(&(lock)->slock) <= 0; + return *(volatile _slock_t *)(&(lock)->slock) <= 0; } static inline void __raw_spin_lock(raw_spinlock_t *lock) { asm volatile( "\n1:\t" - LOCK_PREFIX " ; decb %0\n\t" + LOCK_PREFIX " ; " LOCK_INS_DEC " %0\n\t" "jns 3f\n" "2:\t" "rep;nop\n\t" - "cmpb $0,%0\n\t" + LOCK_INS_CMP " $0,%0\n\t" "jle 2b\n\t" "jmp 1b\n" "3:\n\t" @@ -51,25 +58,25 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, { asm volatile( "\n1:\t" - LOCK_PREFIX " ; decb %[slock]\n\t" + LOCK_PREFIX " ; " LOCK_INS_DEC " %[slock]\n\t" "jns 5f\n" "testl $0x200, %[flags]\n\t" "jz 4f\n\t" STI_STRING "\n" "3:\t" "rep;nop\n\t" - "cmpb $0, %[slock]\n\t" + LOCK_INS_CMP " $0, %[slock]\n\t" "jle 3b\n\t" CLI_STRING "\n\t" "jmp 1b\n" "4:\t" "rep;nop\n\t" - "cmpb $0, %[slock]\n\t" + LOCK_INS_CMP " $0, %[slock]\n\t" "jg 1b\n\t" "jmp 4b\n" "5:\n\t" : [slock] "+m" (lock->slock) - : [flags] "r" (flags) + : [flags] "r" ((u32)flags) CLI_STI_INPUT_ARGS : "memory" CLI_STI_CLOBBERS); } @@ -77,10 +84,10 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, static inline int __raw_spin_trylock(raw_spinlock_t *lock) { - signed char oldval; + _slock_t oldval; asm volatile( - "xchgb %b0,%1" + LOCK_INS_XCH " %0,%1" :"=q" (oldval), "+m" (lock->slock) :"0" (0) : "memory"); @@ -98,7 +105,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - asm volatile("movb $1,%0" : "=m" (lock->slock) :: "memory"); + asm volatile(LOCK_INS_MOV " $1,%0" : "=m" (lock->slock) :: "memory"); } #else @@ -150,7 +157,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) "jns 1f\n" "call __read_lock_failed\n\t" "1:\n" - ::"a" (rw) : "memory"); + ::LOCK_PTR_REG (rw) : "memory"); } static inline void __raw_write_lock(raw_rwlock_t *rw) @@ -159,7 +166,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) "jz 1f\n" "call __write_lock_failed\n\t" "1:\n" - ::"a" (rw), "i" (RW_LOCK_BIAS) : "memory"); + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); } static inline int __raw_read_trylock(raw_rwlock_t *lock) diff --git a/include/asm-x86/spinlock_64.h b/include/asm-x86/spinlock_64.h index 19d483c8018..f5ba90b7335 100644 --- a/include/asm-x86/spinlock_64.h +++ b/include/asm-x86/spinlock_64.h @@ -17,20 +17,27 @@ * (the type definitions are in asm/spinlock_types.h) */ +typedef int _slock_t; +#define LOCK_INS_DEC "decl" +#define LOCK_INS_XCH "xchgl" +#define LOCK_INS_MOV "movl" +#define LOCK_INS_CMP "cmpl" +#define LOCK_PTR_REG "D" + static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { - return *(volatile signed int *)(&(lock)->slock) <= 0; + return *(volatile _slock_t *)(&(lock)->slock) <= 0; } static inline void __raw_spin_lock(raw_spinlock_t *lock) { asm volatile( "\n1:\t" - LOCK_PREFIX " ; decl %0\n\t" + LOCK_PREFIX " ; " LOCK_INS_DEC " %0\n\t" "jns 3f\n" "2:\t" "rep;nop\n\t" - "cmpl $0,%0\n\t" + LOCK_INS_CMP " $0,%0\n\t" "jle 2b\n\t" "jmp 1b\n" "3:\n\t" @@ -51,25 +58,25 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, { asm volatile( "\n1:\t" - LOCK_PREFIX " ; decl %[slock]\n\t" + LOCK_PREFIX " ; " LOCK_INS_DEC " %[slock]\n\t" "jns 5f\n" "testl $0x200, %[flags]\n\t" "jz 4f\n\t" STI_STRING "\n" "3:\t" "rep;nop\n\t" - "cmpl $0, %[slock]\n\t" + LOCK_INS_CMP " $0, %[slock]\n\t" "jle 3b\n\t" CLI_STRING "\n\t" "jmp 1b\n" "4:\t" "rep;nop\n\t" - "cmpl $0, %[slock]\n\t" + LOCK_INS_CMP " $0, %[slock]\n\t" "jg 1b\n\t" "jmp 4b\n" "5:\n\t" : [slock] "+m" (lock->slock) - : [flags] "r" ((unsigned)flags) + : [flags] "r" ((u32)flags) CLI_STI_INPUT_ARGS : "memory" CLI_STI_CLOBBERS); } @@ -77,10 +84,10 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, static inline int __raw_spin_trylock(raw_spinlock_t *lock) { - int oldval; + _slock_t oldval; asm volatile( - "xchgl %0,%1" + LOCK_INS_XCH " %0,%1" :"=q" (oldval), "+m" (lock->slock) :"0" (0) : "memory"); @@ -89,7 +96,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - asm volatile("movl $1,%0" : "=m" (lock->slock) :: "memory"); + asm volatile(LOCK_INS_MOV " $1,%0" : "=m" (lock->slock) :: "memory"); } static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) @@ -128,7 +135,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) "jns 1f\n" "call __read_lock_failed\n\t" "1:\n" - ::"D" (rw) : "memory"); + ::LOCK_PTR_REG (rw) : "memory"); } static inline void __raw_write_lock(raw_rwlock_t *rw) @@ -137,7 +144,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) "jz 1f\n" "call __write_lock_failed\n\t" "1:\n" - ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); } static inline int __raw_read_trylock(raw_rwlock_t *lock) -- cgit v1.2.2 From 1075cf7a959f72833e54dd2d4f885617e58e3e0a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:34 +0100 Subject: x86: merge spinlock.h variants Merge them finally together Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/spinlock.h | 211 +++++++++++++++++++++++++++++++++++++++++- include/asm-x86/spinlock_32.h | 208 ----------------------------------------- include/asm-x86/spinlock_64.h | 186 ------------------------------------- 3 files changed, 209 insertions(+), 396 deletions(-) delete mode 100644 include/asm-x86/spinlock_32.h delete mode 100644 include/asm-x86/spinlock_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h index e1d555a3dfe..afd4b80ff0a 100644 --- a/include/asm-x86/spinlock.h +++ b/include/asm-x86/spinlock.h @@ -1,6 +1,22 @@ #ifndef _X86_SPINLOCK_H_ #define _X86_SPINLOCK_H_ +#include +#include +#include +#include + +/* + * Your basic SMP spinlocks, allowing only a single CPU anywhere + * + * Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + * + * (the type definitions are in asm/spinlock_types.h) + */ + #ifdef CONFIG_PARAVIRT #include #else @@ -11,9 +27,200 @@ #endif /* CONFIG_PARAVIRT */ #ifdef CONFIG_X86_32 -# include "spinlock_32.h" +typedef char _slock_t; +# define LOCK_INS_DEC "decb" +# define LOCK_INS_XCH "xchgb" +# define LOCK_INS_MOV "movb" +# define LOCK_INS_CMP "cmpb" +# define LOCK_PTR_REG "a" #else -# include "spinlock_64.h" +typedef int _slock_t; +# define LOCK_INS_DEC "decl" +# define LOCK_INS_XCH "xchgl" +# define LOCK_INS_MOV "movl" +# define LOCK_INS_CMP "cmpl" +# define LOCK_PTR_REG "D" +#endif + +static inline int __raw_spin_is_locked(raw_spinlock_t *lock) +{ + return *(volatile _slock_t *)(&(lock)->slock) <= 0; +} + +static inline void __raw_spin_lock(raw_spinlock_t *lock) +{ + asm volatile( + "\n1:\t" + LOCK_PREFIX " ; " LOCK_INS_DEC " %0\n\t" + "jns 3f\n" + "2:\t" + "rep;nop\n\t" + LOCK_INS_CMP " $0,%0\n\t" + "jle 2b\n\t" + "jmp 1b\n" + "3:\n\t" + : "+m" (lock->slock) : : "memory"); +} + +/* + * It is easier for the lock validator if interrupts are not re-enabled + * in the middle of a lock-acquire. This is a performance feature anyway + * so we turn it off: + * + * NOTE: there's an irqs-on section here, which normally would have to be + * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. + */ +#ifndef CONFIG_PROVE_LOCKING +static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, + unsigned long flags) +{ + asm volatile( + "\n1:\t" + LOCK_PREFIX " ; " LOCK_INS_DEC " %[slock]\n\t" + "jns 5f\n" + "testl $0x200, %[flags]\n\t" + "jz 4f\n\t" + STI_STRING "\n" + "3:\t" + "rep;nop\n\t" + LOCK_INS_CMP " $0, %[slock]\n\t" + "jle 3b\n\t" + CLI_STRING "\n\t" + "jmp 1b\n" + "4:\t" + "rep;nop\n\t" + LOCK_INS_CMP " $0, %[slock]\n\t" + "jg 1b\n\t" + "jmp 4b\n" + "5:\n\t" + : [slock] "+m" (lock->slock) + : [flags] "r" ((u32)flags) + CLI_STI_INPUT_ARGS + : "memory" CLI_STI_CLOBBERS); +} +#endif + +static inline int __raw_spin_trylock(raw_spinlock_t *lock) +{ + _slock_t oldval; + + asm volatile( + LOCK_INS_XCH " %0,%1" + :"=q" (oldval), "+m" (lock->slock) + :"0" (0) : "memory"); + + return oldval > 0; +} + +/* + * __raw_spin_unlock based on writing $1 to the low byte. + * This method works. Despite all the confusion. + * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there) + * (PPro errata 66, 92) + */ +#if defined(X86_64) || \ + (!defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)) + +static inline void __raw_spin_unlock(raw_spinlock_t *lock) +{ + asm volatile(LOCK_INS_MOV " $1,%0" : "=m" (lock->slock) :: "memory"); +} + +#else + +static inline void __raw_spin_unlock(raw_spinlock_t *lock) +{ + unsigned char oldval = 1; + + asm volatile("xchgb %b0, %1" + : "=q" (oldval), "+m" (lock->slock) + : "0" (oldval) : "memory"); +} + #endif +static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) +{ + while (__raw_spin_is_locked(lock)) + cpu_relax(); +} + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + * + * On x86, we implement read-write locks as a 32-bit counter + * with the high bit (sign) being the "contended" bit. + */ + +static inline int __raw_read_can_lock(raw_rwlock_t *lock) +{ + return (int)(lock)->lock > 0; +} + +static inline int __raw_write_can_lock(raw_rwlock_t *lock) +{ + return (lock)->lock == RW_LOCK_BIAS; +} + +static inline void __raw_read_lock(raw_rwlock_t *rw) +{ + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" + "jns 1f\n" + "call __read_lock_failed\n\t" + "1:\n" + ::LOCK_PTR_REG (rw) : "memory"); +} + +static inline void __raw_write_lock(raw_rwlock_t *rw) +{ + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" + "jz 1f\n" + "call __write_lock_failed\n\t" + "1:\n" + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); +} + +static inline int __raw_read_trylock(raw_rwlock_t *lock) +{ + atomic_t *count = (atomic_t *)lock; + + atomic_dec(count); + if (atomic_read(count) >= 0) + return 1; + atomic_inc(count); + return 0; +} + +static inline int __raw_write_trylock(raw_rwlock_t *lock) +{ + atomic_t *count = (atomic_t *)lock; + + if (atomic_sub_and_test(RW_LOCK_BIAS, count)) + return 1; + atomic_add(RW_LOCK_BIAS, count); + return 0; +} + +static inline void __raw_read_unlock(raw_rwlock_t *rw) +{ + asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); +} + +static inline void __raw_write_unlock(raw_rwlock_t *rw) +{ + asm volatile(LOCK_PREFIX "addl %1, %0" + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); +} + +#define _raw_spin_relax(lock) cpu_relax() +#define _raw_read_relax(lock) cpu_relax() +#define _raw_write_relax(lock) cpu_relax() + #endif diff --git a/include/asm-x86/spinlock_32.h b/include/asm-x86/spinlock_32.h deleted file mode 100644 index 2de9b8b8990..00000000000 --- a/include/asm-x86/spinlock_32.h +++ /dev/null @@ -1,208 +0,0 @@ -#ifndef __ASM_SPINLOCK_H -#define __ASM_SPINLOCK_H - -#include -#include -#include -#include - -/* - * Your basic SMP spinlocks, allowing only a single CPU anywhere - * - * Simple spin lock operations. There are two variants, one clears IRQ's - * on the local processor, one does not. - * - * We make no fairness assumptions. They have a cost. - * - * (the type definitions are in asm/spinlock_types.h) - */ - -typedef char _slock_t; -#define LOCK_INS_DEC "decb" -#define LOCK_INS_XCH "xchgb" -#define LOCK_INS_MOV "movb" -#define LOCK_INS_CMP "cmpb" -#define LOCK_PTR_REG "a" - -static inline int __raw_spin_is_locked(raw_spinlock_t *lock) -{ - return *(volatile _slock_t *)(&(lock)->slock) <= 0; -} - -static inline void __raw_spin_lock(raw_spinlock_t *lock) -{ - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; " LOCK_INS_DEC " %0\n\t" - "jns 3f\n" - "2:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0,%0\n\t" - "jle 2b\n\t" - "jmp 1b\n" - "3:\n\t" - : "+m" (lock->slock) : : "memory"); -} - -/* - * It is easier for the lock validator if interrupts are not re-enabled - * in the middle of a lock-acquire. This is a performance feature anyway - * so we turn it off: - * - * NOTE: there's an irqs-on section here, which normally would have to be - * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. - */ -#ifndef CONFIG_PROVE_LOCKING -static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, - unsigned long flags) -{ - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; " LOCK_INS_DEC " %[slock]\n\t" - "jns 5f\n" - "testl $0x200, %[flags]\n\t" - "jz 4f\n\t" - STI_STRING "\n" - "3:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0, %[slock]\n\t" - "jle 3b\n\t" - CLI_STRING "\n\t" - "jmp 1b\n" - "4:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0, %[slock]\n\t" - "jg 1b\n\t" - "jmp 4b\n" - "5:\n\t" - : [slock] "+m" (lock->slock) - : [flags] "r" ((u32)flags) - CLI_STI_INPUT_ARGS - : "memory" CLI_STI_CLOBBERS); -} -#endif - -static inline int __raw_spin_trylock(raw_spinlock_t *lock) -{ - _slock_t oldval; - - asm volatile( - LOCK_INS_XCH " %0,%1" - :"=q" (oldval), "+m" (lock->slock) - :"0" (0) : "memory"); - - return oldval > 0; -} - -/* - * __raw_spin_unlock based on writing $1 to the low byte. - * This method works. Despite all the confusion. - * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there) - * (PPro errata 66, 92) - */ - -#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE) - -static inline void __raw_spin_unlock(raw_spinlock_t *lock) -{ - asm volatile(LOCK_INS_MOV " $1,%0" : "=m" (lock->slock) :: "memory"); -} - -#else - -static inline void __raw_spin_unlock(raw_spinlock_t *lock) -{ - unsigned char oldval = 1; - - asm volatile("xchgb %b0, %1" - : "=q" (oldval), "+m" (lock->slock) - : "0" (oldval) : "memory"); -} - -#endif - -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) -{ - while (__raw_spin_is_locked(lock)) - cpu_relax(); -} - -/* - * Read-write spinlocks, allowing multiple readers - * but only one writer. - * - * NOTE! it is quite common to have readers in interrupts - * but no interrupt writers. For those circumstances we - * can "mix" irq-safe locks - any writer needs to get a - * irq-safe write-lock, but readers can get non-irqsafe - * read-locks. - * - * On x86, we implement read-write locks as a 32-bit counter - * with the high bit (sign) being the "contended" bit. - */ - -static inline int __raw_read_can_lock(raw_rwlock_t *lock) -{ - return (int)(lock)->lock > 0; -} - -static inline int __raw_write_can_lock(raw_rwlock_t *lock) -{ - return (lock)->lock == RW_LOCK_BIAS; -} - -static inline void __raw_read_lock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" - "jns 1f\n" - "call __read_lock_failed\n\t" - "1:\n" - ::LOCK_PTR_REG (rw) : "memory"); -} - -static inline void __raw_write_lock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" - "jz 1f\n" - "call __write_lock_failed\n\t" - "1:\n" - ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); -} - -static inline int __raw_read_trylock(raw_rwlock_t *lock) -{ - atomic_t *count = (atomic_t *)lock; - - atomic_dec(count); - if (atomic_read(count) >= 0) - return 1; - atomic_inc(count); - return 0; -} - -static inline int __raw_write_trylock(raw_rwlock_t *lock) -{ - atomic_t *count = (atomic_t *)lock; - - if (atomic_sub_and_test(RW_LOCK_BIAS, count)) - return 1; - atomic_add(RW_LOCK_BIAS, count); - return 0; -} - -static inline void __raw_read_unlock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); -} - -static inline void __raw_write_unlock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX "addl %1, %0" - : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); -} - -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() - -#endif /* __ASM_SPINLOCK_H */ diff --git a/include/asm-x86/spinlock_64.h b/include/asm-x86/spinlock_64.h deleted file mode 100644 index f5ba90b7335..00000000000 --- a/include/asm-x86/spinlock_64.h +++ /dev/null @@ -1,186 +0,0 @@ -#ifndef __ASM_SPINLOCK_H -#define __ASM_SPINLOCK_H - -#include -#include -#include -#include - -/* - * Your basic SMP spinlocks, allowing only a single CPU anywhere - * - * Simple spin lock operations. There are two variants, one clears IRQ's - * on the local processor, one does not. - * - * We make no fairness assumptions. They have a cost. - * - * (the type definitions are in asm/spinlock_types.h) - */ - -typedef int _slock_t; -#define LOCK_INS_DEC "decl" -#define LOCK_INS_XCH "xchgl" -#define LOCK_INS_MOV "movl" -#define LOCK_INS_CMP "cmpl" -#define LOCK_PTR_REG "D" - -static inline int __raw_spin_is_locked(raw_spinlock_t *lock) -{ - return *(volatile _slock_t *)(&(lock)->slock) <= 0; -} - -static inline void __raw_spin_lock(raw_spinlock_t *lock) -{ - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; " LOCK_INS_DEC " %0\n\t" - "jns 3f\n" - "2:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0,%0\n\t" - "jle 2b\n\t" - "jmp 1b\n" - "3:\n\t" - : "+m" (lock->slock) : : "memory"); -} - -/* - * It is easier for the lock validator if interrupts are not re-enabled - * in the middle of a lock-acquire. This is a performance feature anyway - * so we turn it off: - * - * NOTE: there's an irqs-on section here, which normally would have to be - * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. - */ -#ifndef CONFIG_PROVE_LOCKING -static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, - unsigned long flags) -{ - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; " LOCK_INS_DEC " %[slock]\n\t" - "jns 5f\n" - "testl $0x200, %[flags]\n\t" - "jz 4f\n\t" - STI_STRING "\n" - "3:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0, %[slock]\n\t" - "jle 3b\n\t" - CLI_STRING "\n\t" - "jmp 1b\n" - "4:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0, %[slock]\n\t" - "jg 1b\n\t" - "jmp 4b\n" - "5:\n\t" - : [slock] "+m" (lock->slock) - : [flags] "r" ((u32)flags) - CLI_STI_INPUT_ARGS - : "memory" CLI_STI_CLOBBERS); -} -#endif - -static inline int __raw_spin_trylock(raw_spinlock_t *lock) -{ - _slock_t oldval; - - asm volatile( - LOCK_INS_XCH " %0,%1" - :"=q" (oldval), "+m" (lock->slock) - :"0" (0) : "memory"); - - return oldval > 0; -} - -static inline void __raw_spin_unlock(raw_spinlock_t *lock) -{ - asm volatile(LOCK_INS_MOV " $1,%0" : "=m" (lock->slock) :: "memory"); -} - -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) -{ - while (__raw_spin_is_locked(lock)) - cpu_relax(); -} - -/* - * Read-write spinlocks, allowing multiple readers - * but only one writer. - * - * NOTE! it is quite common to have readers in interrupts - * but no interrupt writers. For those circumstances we - * can "mix" irq-safe locks - any writer needs to get a - * irq-safe write-lock, but readers can get non-irqsafe - * read-locks. - * - * On x86, we implement read-write locks as a 32-bit counter - * with the high bit (sign) being the "contended" bit. - */ - -static inline int __raw_read_can_lock(raw_rwlock_t *lock) -{ - return (int)(lock)->lock > 0; -} - -static inline int __raw_write_can_lock(raw_rwlock_t *lock) -{ - return (lock)->lock == RW_LOCK_BIAS; -} - -static inline void __raw_read_lock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" - "jns 1f\n" - "call __read_lock_failed\n\t" - "1:\n" - ::LOCK_PTR_REG (rw) : "memory"); -} - -static inline void __raw_write_lock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" - "jz 1f\n" - "call __write_lock_failed\n\t" - "1:\n" - ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); -} - -static inline int __raw_read_trylock(raw_rwlock_t *lock) -{ - atomic_t *count = (atomic_t *)lock; - - atomic_dec(count); - if (atomic_read(count) >= 0) - return 1; - atomic_inc(count); - return 0; -} - -static inline int __raw_write_trylock(raw_rwlock_t *lock) -{ - atomic_t *count = (atomic_t *)lock; - - if (atomic_sub_and_test(RW_LOCK_BIAS, count)) - return 1; - atomic_add(RW_LOCK_BIAS, count); - return 0; -} - -static inline void __raw_read_unlock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); -} - -static inline void __raw_write_unlock(raw_rwlock_t *rw) -{ - asm volatile(LOCK_PREFIX "addl %1, %0" - : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); -} - -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() - -#endif /* __ASM_SPINLOCK_H */ -- cgit v1.2.2 From 0b9c99b6f21c2e9e00938e9c57942ed71bfe4d21 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:35 +0100 Subject: x86: cleanup tlbflush.h variants Bring the tlbflush.h variants into sync to prepare merging and paravirt support. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 9 ++++ include/asm-x86/tlbflush_32.h | 120 ++++++++++++++++++------------------------ include/asm-x86/tlbflush_64.h | 78 ++++++++++++++++++++------- 3 files changed, 118 insertions(+), 89 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 4c7875554d0..acbf6681740 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -163,6 +163,12 @@ #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) #define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) +#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64) +# define cpu_has_invlpg 1 +#else +# define cpu_has_invlpg (boot_cpu_data.x86 > 3) +#endif + #ifdef CONFIG_X86_64 #undef cpu_has_vme @@ -183,6 +189,9 @@ #undef cpu_has_centaur_mcr #define cpu_has_centaur_mcr 0 +#undef cpu_has_pge +#define cpu_has_pge 1 + #endif /* CONFIG_X86_64 */ #endif /* _ASM_X86_CPUFEATURE_H */ diff --git a/include/asm-x86/tlbflush_32.h b/include/asm-x86/tlbflush_32.h index 2bd5b95e204..9e07cc8f2d9 100644 --- a/include/asm-x86/tlbflush_32.h +++ b/include/asm-x86/tlbflush_32.h @@ -1,8 +1,11 @@ -#ifndef _I386_TLBFLUSH_H -#define _I386_TLBFLUSH_H +#ifndef _X86_TLBFLUSH_H +#define _X86_TLBFLUSH_H #include +#include + #include +#include #ifdef CONFIG_PARAVIRT #include @@ -12,62 +15,41 @@ #define __flush_tlb_single(addr) __native_flush_tlb_single(addr) #endif -#define __native_flush_tlb() \ - do { \ - unsigned int tmpreg; \ - \ - __asm__ __volatile__( \ - "movl %%cr3, %0; \n" \ - "movl %0, %%cr3; # flush TLB \n" \ - : "=r" (tmpreg) \ - :: "memory"); \ - } while (0) +static inline void __native_flush_tlb(void) +{ + write_cr3(read_cr3()); +} -/* - * Global pages have to be flushed a bit differently. Not a real - * performance problem because this does not happen often. - */ -#define __native_flush_tlb_global() \ - do { \ - unsigned int tmpreg, cr4, cr4_orig; \ - \ - __asm__ __volatile__( \ - "movl %%cr4, %2; # turn off PGE \n" \ - "movl %2, %1; \n" \ - "andl %3, %1; \n" \ - "movl %1, %%cr4; \n" \ - "movl %%cr3, %0; \n" \ - "movl %0, %%cr3; # flush TLB \n" \ - "movl %2, %%cr4; # turn PGE back on \n" \ - : "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig) \ - : "i" (~X86_CR4_PGE) \ - : "memory"); \ - } while (0) - -#define __native_flush_tlb_single(addr) \ - __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory") - -# define __flush_tlb_all() \ - do { \ - if (cpu_has_pge) \ - __flush_tlb_global(); \ - else \ - __flush_tlb(); \ - } while (0) - -#define cpu_has_invlpg (boot_cpu_data.x86 > 3) - -#ifdef CONFIG_X86_INVLPG -# define __flush_tlb_one(addr) __flush_tlb_single(addr) -#else -# define __flush_tlb_one(addr) \ - do { \ - if (cpu_has_invlpg) \ - __flush_tlb_single(addr); \ - else \ - __flush_tlb(); \ - } while (0) -#endif +static inline void __native_flush_tlb_global(void) +{ + unsigned long cr4 = read_cr4(); + + /* clear PGE */ + write_cr4(cr4 & ~X86_CR4_PGE); + /* write old PGE again and flush TLBs */ + write_cr4(cr4); +} + +static inline void __native_flush_tlb_single(unsigned long addr) +{ + __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory"); +} + +static inline void __flush_tlb_all(void) +{ + if (cpu_has_pge) + __flush_tlb_global(); + else + __flush_tlb(); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (cpu_has_invlpg) + __flush_tlb_single(addr); + else + __flush_tlb(); +} /* * TLB flushing: @@ -86,11 +68,8 @@ #define TLB_FLUSH_ALL 0xffffffff - #ifndef CONFIG_SMP -#include - #define flush_tlb() __flush_tlb() #define flush_tlb_all() __flush_tlb_all() #define local_flush_tlb() __flush_tlb() @@ -102,21 +81,22 @@ static inline void flush_tlb_mm(struct mm_struct *mm) } static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr) + unsigned long addr) { if (vma->vm_mm == current->active_mm) __flush_tlb_one(addr); } static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) + unsigned long start, unsigned long end) { if (vma->vm_mm == current->active_mm) __flush_tlb(); } static inline void native_flush_tlb_others(const cpumask_t *cpumask, - struct mm_struct *mm, unsigned long va) + struct mm_struct *mm, + unsigned long va) { } @@ -124,8 +104,7 @@ static inline void native_flush_tlb_others(const cpumask_t *cpumask, #include -#define local_flush_tlb() \ - __flush_tlb() +#define local_flush_tlb() __flush_tlb() extern void flush_tlb_all(void); extern void flush_tlb_current_task(void); @@ -134,7 +113,8 @@ extern void flush_tlb_page(struct vm_area_struct *, unsigned long); #define flush_tlb() flush_tlb_current_task() -static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end) +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) { flush_tlb_mm(vma->vm_mm); } @@ -152,17 +132,17 @@ struct tlb_state char __cacheline_padding[L1_CACHE_BYTES-8]; }; DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); + #endif /* SMP */ #ifndef CONFIG_PARAVIRT -#define flush_tlb_others(mask, mm, va) \ - native_flush_tlb_others(&mask, mm, va) +#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(&mask, mm, va) #endif static inline void flush_tlb_kernel_range(unsigned long start, - unsigned long end) + unsigned long end) { flush_tlb_all(); } -#endif /* _I386_TLBFLUSH_H */ +#endif /* _X86_TLBFLUSH_H */ diff --git a/include/asm-x86/tlbflush_64.h b/include/asm-x86/tlbflush_64.h index 7731fd23d57..0bed440ba9f 100644 --- a/include/asm-x86/tlbflush_64.h +++ b/include/asm-x86/tlbflush_64.h @@ -1,26 +1,55 @@ -#ifndef _X8664_TLBFLUSH_H -#define _X8664_TLBFLUSH_H +#ifndef _X86_TLBFLUSH_H +#define _X86_TLBFLUSH_H #include #include + #include #include -static inline void __flush_tlb(void) +#ifdef CONFIG_PARAVIRT +#include +#else +#define __flush_tlb() __native_flush_tlb() +#define __flush_tlb_global() __native_flush_tlb_global() +#define __flush_tlb_single(addr) __native_flush_tlb_single(addr) +#endif + +static inline void __native_flush_tlb(void) { write_cr3(read_cr3()); } -static inline void __flush_tlb_all(void) +static inline void __native_flush_tlb_global(void) { unsigned long cr4 = read_cr4(); - write_cr4(cr4 & ~X86_CR4_PGE); /* clear PGE */ - write_cr4(cr4); /* write old PGE again and flush TLBs */ + + /* clear PGE */ + write_cr4(cr4 & ~X86_CR4_PGE); + /* write old PGE again and flush TLBs */ + write_cr4(cr4); } -#define __flush_tlb_one(addr) \ - __asm__ __volatile__("invlpg (%0)" :: "r" (addr) : "memory") +static inline void __native_flush_tlb_single(unsigned long addr) +{ + __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory"); +} + +static inline void __flush_tlb_all(void) +{ + if (cpu_has_pge) + __flush_tlb_global(); + else + __flush_tlb(); +} +static inline void __flush_tlb_one(unsigned long addr) +{ + if (cpu_has_invlpg) + __flush_tlb_single(addr); + else + __flush_tlb(); +} /* * TLB flushing: @@ -37,6 +66,8 @@ static inline void __flush_tlb_all(void) * range a few INVLPGs in a row are a win. */ +#define TLB_FLUSH_ALL -1ULL + #ifndef CONFIG_SMP #define flush_tlb() __flush_tlb() @@ -50,25 +81,30 @@ static inline void flush_tlb_mm(struct mm_struct *mm) } static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr) + unsigned long addr) { if (vma->vm_mm == current->active_mm) __flush_tlb_one(addr); } static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) + unsigned long start, unsigned long end) { if (vma->vm_mm == current->active_mm) __flush_tlb(); } -#else +static inline void native_flush_tlb_others(const cpumask_t *cpumask, + struct mm_struct *mm, + unsigned long va) +{ +} + +#else /* SMP */ #include -#define local_flush_tlb() \ - __flush_tlb() +#define local_flush_tlb() __flush_tlb() extern void flush_tlb_all(void); extern void flush_tlb_current_task(void); @@ -77,24 +113,28 @@ extern void flush_tlb_page(struct vm_area_struct *, unsigned long); #define flush_tlb() flush_tlb_current_task() -static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end) +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) { flush_tlb_mm(vma->vm_mm); } +void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm, + unsigned long va); + #define TLBSTATE_OK 1 #define TLBSTATE_LAZY 2 -/* Roughly an IPI every 20MB with 4k pages for freeing page table - ranges. Cost is about 42k of memory for each CPU. */ -#define ARCH_FREE_PTE_NR 5350 +#endif /* SMP */ +#ifndef CONFIG_PARAVIRT +#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(&mask, mm, va) #endif static inline void flush_tlb_kernel_range(unsigned long start, - unsigned long end) + unsigned long end) { flush_tlb_all(); } -#endif /* _X8664_TLBFLUSH_H */ +#endif /* _X86_TLBFLUSH_H */ -- cgit v1.2.2 From d291cf83639a0e0b67ff783b6ed29c0a747d4901 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:35 +0100 Subject: x86: merge tlbflush.h variants The delta is now minimal. Merge them Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/tlbflush.h | 157 +++++++++++++++++++++++++++++++++++++++++- include/asm-x86/tlbflush_32.h | 148 --------------------------------------- include/asm-x86/tlbflush_64.h | 140 ------------------------------------- 3 files changed, 155 insertions(+), 290 deletions(-) delete mode 100644 include/asm-x86/tlbflush_32.h delete mode 100644 include/asm-x86/tlbflush_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/tlbflush.h b/include/asm-x86/tlbflush.h index 9af4cc83a1a..3998709ed63 100644 --- a/include/asm-x86/tlbflush.h +++ b/include/asm-x86/tlbflush.h @@ -1,5 +1,158 @@ +#ifndef _ASM_X86_TLBFLUSH_H +#define _ASM_X86_TLBFLUSH_H + +#include +#include + +#include +#include + +#ifdef CONFIG_PARAVIRT +#include +#else +#define __flush_tlb() __native_flush_tlb() +#define __flush_tlb_global() __native_flush_tlb_global() +#define __flush_tlb_single(addr) __native_flush_tlb_single(addr) +#endif + +static inline void __native_flush_tlb(void) +{ + write_cr3(read_cr3()); +} + +static inline void __native_flush_tlb_global(void) +{ + unsigned long cr4 = read_cr4(); + + /* clear PGE */ + write_cr4(cr4 & ~X86_CR4_PGE); + /* write old PGE again and flush TLBs */ + write_cr4(cr4); +} + +static inline void __native_flush_tlb_single(unsigned long addr) +{ + __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory"); +} + +static inline void __flush_tlb_all(void) +{ + if (cpu_has_pge) + __flush_tlb_global(); + else + __flush_tlb(); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (cpu_has_invlpg) + __flush_tlb_single(addr); + else + __flush_tlb(); +} + #ifdef CONFIG_X86_32 -# include "tlbflush_32.h" +# define TLB_FLUSH_ALL 0xffffffff #else -# include "tlbflush_64.h" +# define TLB_FLUSH_ALL -1ULL +#endif + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_others(cpumask, mm, va) flushes TLBs on other cpus + * + * ..but the i386 has somewhat limited tlb flushing capabilities, + * and page-granular flushes are available only on i486 and up. + * + * x86-64 can only flush individual pages or full VMs. For a range flush + * we always do the full VM. Might be worth trying if for a small + * range a few INVLPGs in a row are a win. + */ + +#ifndef CONFIG_SMP + +#define flush_tlb() __flush_tlb() +#define flush_tlb_all() __flush_tlb_all() +#define local_flush_tlb() __flush_tlb() + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->active_mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + if (vma->vm_mm == current->active_mm) + __flush_tlb_one(addr); +} + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + if (vma->vm_mm == current->active_mm) + __flush_tlb(); +} + +static inline void native_flush_tlb_others(const cpumask_t *cpumask, + struct mm_struct *mm, + unsigned long va) +{ +} + +#else /* SMP */ + +#include + +#define local_flush_tlb() __flush_tlb() + +extern void flush_tlb_all(void); +extern void flush_tlb_current_task(void); +extern void flush_tlb_mm(struct mm_struct *); +extern void flush_tlb_page(struct vm_area_struct *, unsigned long); + +#define flush_tlb() flush_tlb_current_task() + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + flush_tlb_mm(vma->vm_mm); +} + +void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm, + unsigned long va); + +#define TLBSTATE_OK 1 +#define TLBSTATE_LAZY 2 + +#ifdef CONFIG_X86_32 +struct tlb_state +{ + struct mm_struct *active_mm; + int state; + char __cacheline_padding[L1_CACHE_BYTES-8]; +}; +DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); +#endif + +#endif /* SMP */ + +#ifndef CONFIG_PARAVIRT +#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(&mask, mm, va) #endif + +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) +{ + flush_tlb_all(); +} + +#endif /* _ASM_X86_TLBFLUSH_H */ diff --git a/include/asm-x86/tlbflush_32.h b/include/asm-x86/tlbflush_32.h deleted file mode 100644 index 9e07cc8f2d9..00000000000 --- a/include/asm-x86/tlbflush_32.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef _X86_TLBFLUSH_H -#define _X86_TLBFLUSH_H - -#include -#include - -#include -#include - -#ifdef CONFIG_PARAVIRT -#include -#else -#define __flush_tlb() __native_flush_tlb() -#define __flush_tlb_global() __native_flush_tlb_global() -#define __flush_tlb_single(addr) __native_flush_tlb_single(addr) -#endif - -static inline void __native_flush_tlb(void) -{ - write_cr3(read_cr3()); -} - -static inline void __native_flush_tlb_global(void) -{ - unsigned long cr4 = read_cr4(); - - /* clear PGE */ - write_cr4(cr4 & ~X86_CR4_PGE); - /* write old PGE again and flush TLBs */ - write_cr4(cr4); -} - -static inline void __native_flush_tlb_single(unsigned long addr) -{ - __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory"); -} - -static inline void __flush_tlb_all(void) -{ - if (cpu_has_pge) - __flush_tlb_global(); - else - __flush_tlb(); -} - -static inline void __flush_tlb_one(unsigned long addr) -{ - if (cpu_has_invlpg) - __flush_tlb_single(addr); - else - __flush_tlb(); -} - -/* - * TLB flushing: - * - * - flush_tlb() flushes the current mm struct TLBs - * - flush_tlb_all() flushes all processes TLBs - * - flush_tlb_mm(mm) flushes the specified mm context TLB's - * - flush_tlb_page(vma, vmaddr) flushes one page - * - flush_tlb_range(vma, start, end) flushes a range of pages - * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages - * - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus - * - * ..but the i386 has somewhat limited tlb flushing capabilities, - * and page-granular flushes are available only on i486 and up. - */ - -#define TLB_FLUSH_ALL 0xffffffff - -#ifndef CONFIG_SMP - -#define flush_tlb() __flush_tlb() -#define flush_tlb_all() __flush_tlb_all() -#define local_flush_tlb() __flush_tlb() - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm == current->active_mm) - __flush_tlb(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr) -{ - if (vma->vm_mm == current->active_mm) - __flush_tlb_one(addr); -} - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - if (vma->vm_mm == current->active_mm) - __flush_tlb(); -} - -static inline void native_flush_tlb_others(const cpumask_t *cpumask, - struct mm_struct *mm, - unsigned long va) -{ -} - -#else /* SMP */ - -#include - -#define local_flush_tlb() __flush_tlb() - -extern void flush_tlb_all(void); -extern void flush_tlb_current_task(void); -extern void flush_tlb_mm(struct mm_struct *); -extern void flush_tlb_page(struct vm_area_struct *, unsigned long); - -#define flush_tlb() flush_tlb_current_task() - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - flush_tlb_mm(vma->vm_mm); -} - -void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm, - unsigned long va); - -#define TLBSTATE_OK 1 -#define TLBSTATE_LAZY 2 - -struct tlb_state -{ - struct mm_struct *active_mm; - int state; - char __cacheline_padding[L1_CACHE_BYTES-8]; -}; -DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); - -#endif /* SMP */ - -#ifndef CONFIG_PARAVIRT -#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(&mask, mm, va) -#endif - -static inline void flush_tlb_kernel_range(unsigned long start, - unsigned long end) -{ - flush_tlb_all(); -} - -#endif /* _X86_TLBFLUSH_H */ diff --git a/include/asm-x86/tlbflush_64.h b/include/asm-x86/tlbflush_64.h deleted file mode 100644 index 0bed440ba9f..00000000000 --- a/include/asm-x86/tlbflush_64.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef _X86_TLBFLUSH_H -#define _X86_TLBFLUSH_H - -#include -#include - -#include -#include - -#ifdef CONFIG_PARAVIRT -#include -#else -#define __flush_tlb() __native_flush_tlb() -#define __flush_tlb_global() __native_flush_tlb_global() -#define __flush_tlb_single(addr) __native_flush_tlb_single(addr) -#endif - -static inline void __native_flush_tlb(void) -{ - write_cr3(read_cr3()); -} - -static inline void __native_flush_tlb_global(void) -{ - unsigned long cr4 = read_cr4(); - - /* clear PGE */ - write_cr4(cr4 & ~X86_CR4_PGE); - /* write old PGE again and flush TLBs */ - write_cr4(cr4); -} - -static inline void __native_flush_tlb_single(unsigned long addr) -{ - __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory"); -} - -static inline void __flush_tlb_all(void) -{ - if (cpu_has_pge) - __flush_tlb_global(); - else - __flush_tlb(); -} - -static inline void __flush_tlb_one(unsigned long addr) -{ - if (cpu_has_invlpg) - __flush_tlb_single(addr); - else - __flush_tlb(); -} - -/* - * TLB flushing: - * - * - flush_tlb() flushes the current mm struct TLBs - * - flush_tlb_all() flushes all processes TLBs - * - flush_tlb_mm(mm) flushes the specified mm context TLB's - * - flush_tlb_page(vma, vmaddr) flushes one page - * - flush_tlb_range(vma, start, end) flushes a range of pages - * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages - * - * x86-64 can only flush individual pages or full VMs. For a range flush - * we always do the full VM. Might be worth trying if for a small - * range a few INVLPGs in a row are a win. - */ - -#define TLB_FLUSH_ALL -1ULL - -#ifndef CONFIG_SMP - -#define flush_tlb() __flush_tlb() -#define flush_tlb_all() __flush_tlb_all() -#define local_flush_tlb() __flush_tlb() - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm == current->active_mm) - __flush_tlb(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr) -{ - if (vma->vm_mm == current->active_mm) - __flush_tlb_one(addr); -} - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - if (vma->vm_mm == current->active_mm) - __flush_tlb(); -} - -static inline void native_flush_tlb_others(const cpumask_t *cpumask, - struct mm_struct *mm, - unsigned long va) -{ -} - -#else /* SMP */ - -#include - -#define local_flush_tlb() __flush_tlb() - -extern void flush_tlb_all(void); -extern void flush_tlb_current_task(void); -extern void flush_tlb_mm(struct mm_struct *); -extern void flush_tlb_page(struct vm_area_struct *, unsigned long); - -#define flush_tlb() flush_tlb_current_task() - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - flush_tlb_mm(vma->vm_mm); -} - -void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm, - unsigned long va); - -#define TLBSTATE_OK 1 -#define TLBSTATE_LAZY 2 - -#endif /* SMP */ - -#ifndef CONFIG_PARAVIRT -#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(&mask, mm, va) -#endif - -static inline void flush_tlb_kernel_range(unsigned long start, - unsigned long end) -{ - flush_tlb_all(); -} - -#endif /* _X86_TLBFLUSH_H */ -- cgit v1.2.2 From 64883ab0e3386d72112a9091d886352a7b4b8bf6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:35 +0100 Subject: x86: cleanup mpspec variants Bring the mpspec variants into sync to prepare merging and paravirt support. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mach-bigsmp/mach_apic.h | 12 +- include/asm-x86/mach-default/mach_apic.h | 18 +-- include/asm-x86/mach-es7000/mach_apic.h | 10 +- include/asm-x86/mach-numaq/mach_apic.h | 10 +- include/asm-x86/mach-summit/mach_apic.h | 18 +-- include/asm-x86/mpspec_32.h | 49 ++++---- include/asm-x86/mpspec_64.h | 196 ++++--------------------------- include/asm-x86/mpspec_def.h | 87 ++++++++------ 8 files changed, 131 insertions(+), 269 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mach-bigsmp/mach_apic.h b/include/asm-x86/mach-bigsmp/mach_apic.h index ebd319f838a..6df235e8ea9 100644 --- a/include/asm-x86/mach-bigsmp/mach_apic.h +++ b/include/asm-x86/mach-bigsmp/mach_apic.h @@ -110,13 +110,13 @@ static inline int cpu_to_logical_apicid(int cpu) } static inline int mpc_apic_id(struct mpc_config_processor *m, - struct mpc_config_translation *translation_record) + struct mpc_config_translation *translation_record) { - printk("Processor #%d %ld:%ld APIC version %d\n", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver); + printk("Processor #%d %u:%u APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); return m->mpc_apicid; } diff --git a/include/asm-x86/mach-default/mach_apic.h b/include/asm-x86/mach-default/mach_apic.h index 6db1c3babe9..e3c2c1012c1 100644 --- a/include/asm-x86/mach-default/mach_apic.h +++ b/include/asm-x86/mach-default/mach_apic.h @@ -89,15 +89,15 @@ static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) return physid_mask_of_physid(phys_apicid); } -static inline int mpc_apic_id(struct mpc_config_processor *m, - struct mpc_config_translation *translation_record) -{ - printk("Processor #%d %ld:%ld APIC version %d\n", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver); - return (m->mpc_apicid); +static inline int mpc_apic_id(struct mpc_config_processor *m, + struct mpc_config_translation *translation_record) +{ + printk("Processor #%d %u:%u APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + return m->mpc_apicid; } static inline void setup_portio_remap(void) diff --git a/include/asm-x86/mach-es7000/mach_apic.h b/include/asm-x86/mach-es7000/mach_apic.h index caec64be516..d23011fdf45 100644 --- a/include/asm-x86/mach-es7000/mach_apic.h +++ b/include/asm-x86/mach-es7000/mach_apic.h @@ -131,11 +131,11 @@ static inline int cpu_to_logical_apicid(int cpu) static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused) { - printk("Processor #%d %ld:%ld APIC version %d\n", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver); + printk("Processor #%d %u:%u APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); return (m->mpc_apicid); } diff --git a/include/asm-x86/mach-numaq/mach_apic.h b/include/asm-x86/mach-numaq/mach_apic.h index 5e5e7dd2692..17e183bd39c 100644 --- a/include/asm-x86/mach-numaq/mach_apic.h +++ b/include/asm-x86/mach-numaq/mach_apic.h @@ -101,11 +101,11 @@ static inline int mpc_apic_id(struct mpc_config_processor *m, int quad = translation_record->trans_quad; int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid); - printk("Processor #%d %ld:%ld APIC version %d (quad %d, apic %d)\n", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver, quad, logical_apicid); + printk("Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver, quad, logical_apicid); return logical_apicid; } diff --git a/include/asm-x86/mach-summit/mach_apic.h b/include/asm-x86/mach-summit/mach_apic.h index 732f776aab8..062c97f6100 100644 --- a/include/asm-x86/mach-summit/mach_apic.h +++ b/include/asm-x86/mach-summit/mach_apic.h @@ -126,15 +126,15 @@ static inline physid_mask_t apicid_to_cpu_present(int apicid) return physid_mask_of_physid(0); } -static inline int mpc_apic_id(struct mpc_config_processor *m, - struct mpc_config_translation *translation_record) -{ - printk("Processor #%d %ld:%ld APIC version %d\n", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver); - return (m->mpc_apicid); +static inline int mpc_apic_id(struct mpc_config_processor *m, + struct mpc_config_translation *translation_record) +{ + printk("Processor #%d %u:%u APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + return m->mpc_apicid; } static inline void setup_portio_remap(void) diff --git a/include/asm-x86/mpspec_32.h b/include/asm-x86/mpspec_32.h index f21349399d1..bb73185e6a7 100644 --- a/include/asm-x86/mpspec_32.h +++ b/include/asm-x86/mpspec_32.h @@ -1,34 +1,37 @@ #ifndef __ASM_MPSPEC_H #define __ASM_MPSPEC_H -#include #include #include -extern int mp_bus_id_to_type [MAX_MP_BUSSES]; -extern int mp_bus_id_to_node [MAX_MP_BUSSES]; -extern int mp_bus_id_to_local [MAX_MP_BUSSES]; -extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; +extern int mp_bus_id_to_type[MAX_MP_BUSSES]; +extern int mp_bus_id_to_node[MAX_MP_BUSSES]; +extern int mp_bus_id_to_local[MAX_MP_BUSSES]; +extern int quad_local_to_mp_bus_id[NR_CPUS/4][4]; extern unsigned int def_to_bigsmp; +extern int apic_version[MAX_APICS]; +extern int pic_mode; + +extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; + extern unsigned int boot_cpu_physical_apicid; extern int smp_found_config; -extern void find_smp_config (void); -extern void get_smp_config (void); extern int nr_ioapics; -extern int apic_version [MAX_APICS]; extern int mp_irq_entries; -extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES]; +extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; extern int mpc_default_type; extern unsigned long mp_lapic_addr; -extern int pic_mode; + +extern void find_smp_config (void); +extern void get_smp_config (void); #ifdef CONFIG_ACPI extern void mp_register_lapic (u8 id, u8 enabled); extern void mp_register_lapic_address (u64 address); extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); -extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); +extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, + u32 gsi); extern void mp_config_acpi_legacy_irqs (void); extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low); #endif /* CONFIG_ACPI */ @@ -50,7 +53,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(dst, src) bitmap_complement((dst).mask,(src).mask, MAX_APICS) +#define physids_complement(dst, src) bitmap_complement((dst).mask, (src).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) @@ -58,18 +61,18 @@ typedef struct physid_mask physid_mask_t; #define physids_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) #define physids_coerce(map) ((map).mask[0]) -#define physids_promote(physids) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - __physid_mask.mask[0] = physids; \ - __physid_mask; \ +#define physids_promote(physids) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + __physid_mask.mask[0] = physids; \ + __physid_mask; \ }) -#define physid_mask_of_physid(physid) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - physid_set(physid, __physid_mask); \ - __physid_mask; \ +#define physid_mask_of_physid(physid) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + physid_set(physid, __physid_mask); \ + __physid_mask; \ }) #define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } diff --git a/include/asm-x86/mpspec_64.h b/include/asm-x86/mpspec_64.h index 017fddb61dc..16eab20667c 100644 --- a/include/asm-x86/mpspec_64.h +++ b/include/asm-x86/mpspec_64.h @@ -1,189 +1,35 @@ #ifndef __ASM_MPSPEC_H #define __ASM_MPSPEC_H -/* - * Structure definitions for SMP machines following the - * Intel Multiprocessing Specification 1.1 and 1.4. - */ - -/* - * This tag identifies where the SMP configuration - * information is. - */ - -#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') - -/* - * A maximum of 255 APICs with the current APIC ID architecture. - */ -#define MAX_APICS 255 - -struct intel_mp_floating -{ - char mpf_signature[4]; /* "_MP_" */ - unsigned int mpf_physptr; /* Configuration table address */ - unsigned char mpf_length; /* Our length (paragraphs) */ - unsigned char mpf_specification;/* Specification version */ - unsigned char mpf_checksum; /* Checksum (makes sum 0) */ - unsigned char mpf_feature1; /* Standard or configuration ? */ - unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ - unsigned char mpf_feature3; /* Unused (0) */ - unsigned char mpf_feature4; /* Unused (0) */ - unsigned char mpf_feature5; /* Unused (0) */ -}; - -struct mp_config_table -{ - char mpc_signature[4]; -#define MPC_SIGNATURE "PCMP" - unsigned short mpc_length; /* Size of table */ - char mpc_spec; /* 0x01 */ - char mpc_checksum; - char mpc_oem[8]; - char mpc_productid[12]; - unsigned int mpc_oemptr; /* 0 if not present */ - unsigned short mpc_oemsize; /* 0 if not present */ - unsigned short mpc_oemcount; - unsigned int mpc_lapic; /* APIC address */ - unsigned int reserved; -}; - -/* Followed by entries */ - -#define MP_PROCESSOR 0 -#define MP_BUS 1 -#define MP_IOAPIC 2 -#define MP_INTSRC 3 -#define MP_LINTSRC 4 - -struct mpc_config_processor -{ - unsigned char mpc_type; - unsigned char mpc_apicid; /* Local APIC number */ - unsigned char mpc_apicver; /* Its versions */ - unsigned char mpc_cpuflag; -#define CPU_ENABLED 1 /* Processor is available */ -#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ - unsigned int mpc_cpufeature; -#define CPU_STEPPING_MASK 0x0F -#define CPU_MODEL_MASK 0xF0 -#define CPU_FAMILY_MASK 0xF00 - unsigned int mpc_featureflag; /* CPUID feature value */ - unsigned int mpc_reserved[2]; -}; - -struct mpc_config_bus -{ - unsigned char mpc_type; - unsigned char mpc_busid; - unsigned char mpc_bustype[6]; -}; - -/* List of Bus Type string values, Intel MP Spec. */ -#define BUSTYPE_EISA "EISA" -#define BUSTYPE_ISA "ISA" -#define BUSTYPE_INTERN "INTERN" /* Internal BUS */ -#define BUSTYPE_MCA "MCA" -#define BUSTYPE_VL "VL" /* Local bus */ -#define BUSTYPE_PCI "PCI" -#define BUSTYPE_PCMCIA "PCMCIA" -#define BUSTYPE_CBUS "CBUS" -#define BUSTYPE_CBUSII "CBUSII" -#define BUSTYPE_FUTURE "FUTURE" -#define BUSTYPE_MBI "MBI" -#define BUSTYPE_MBII "MBII" -#define BUSTYPE_MPI "MPI" -#define BUSTYPE_MPSA "MPSA" -#define BUSTYPE_NUBUS "NUBUS" -#define BUSTYPE_TC "TC" -#define BUSTYPE_VME "VME" -#define BUSTYPE_XPRESS "XPRESS" - -struct mpc_config_ioapic -{ - unsigned char mpc_type; - unsigned char mpc_apicid; - unsigned char mpc_apicver; - unsigned char mpc_flags; -#define MPC_APIC_USABLE 0x01 - unsigned int mpc_apicaddr; -}; - -struct mpc_config_intsrc -{ - unsigned char mpc_type; - unsigned char mpc_irqtype; - unsigned short mpc_irqflag; - unsigned char mpc_srcbus; - unsigned char mpc_srcbusirq; - unsigned char mpc_dstapic; - unsigned char mpc_dstirq; -}; - -enum mp_irq_source_types { - mp_INT = 0, - mp_NMI = 1, - mp_SMI = 2, - mp_ExtINT = 3 -}; - -#define MP_IRQDIR_DEFAULT 0 -#define MP_IRQDIR_HIGH 1 -#define MP_IRQDIR_LOW 3 - - -struct mpc_config_lintsrc -{ - unsigned char mpc_type; - unsigned char mpc_irqtype; - unsigned short mpc_irqflag; - unsigned char mpc_srcbusid; - unsigned char mpc_srcbusirq; - unsigned char mpc_destapic; -#define MP_APIC_ALL 0xFF - unsigned char mpc_destapiclint; -}; - -/* - * Default configurations - * - * 1 2 CPU ISA 82489DX - * 2 2 CPU EISA 82489DX neither IRQ 0 timer nor IRQ 13 DMA chaining - * 3 2 CPU EISA 82489DX - * 4 2 CPU MCA 82489DX - * 5 2 CPU ISA+PCI - * 6 2 CPU EISA+PCI - * 7 2 CPU MCA+PCI - */ +#include #define MAX_MP_BUSSES 256 /* Each PCI slot may be a combo card with its own bus. 4 IRQ pins per slot. */ #define MAX_IRQ_SOURCES (MAX_MP_BUSSES * 4) extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; + +extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; extern unsigned int boot_cpu_physical_apicid; extern int smp_found_config; -extern void find_smp_config (void); -extern void get_smp_config (void); extern int nr_ioapics; -extern unsigned char apic_version [MAX_APICS]; extern int mp_irq_entries; -extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES]; +extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; extern int mpc_default_type; extern unsigned long mp_lapic_addr; +extern void find_smp_config (void); +extern void get_smp_config (void); + #ifdef CONFIG_ACPI extern void mp_register_lapic (u8 id, u8 enabled); extern void mp_register_lapic_address (u64 address); - extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); -extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); +extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, + u32 gsi); extern void mp_config_acpi_legacy_irqs (void); -extern int mp_register_gsi (u32 gsi, int triggering, int polarity); -#endif - -extern int using_apic_timer; +extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low); +#endif /* CONFIG_ACPI */ #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) @@ -210,18 +56,18 @@ typedef struct physid_mask physid_mask_t; #define physids_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) #define physids_coerce(map) ((map).mask[0]) -#define physids_promote(physids) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - __physid_mask.mask[0] = physids; \ - __physid_mask; \ +#define physids_promote(physids) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + __physid_mask.mask[0] = physids; \ + __physid_mask; \ }) -#define physid_mask_of_physid(physid) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - physid_set(physid, __physid_mask); \ - __physid_mask; \ +#define physid_mask_of_physid(physid) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + physid_set(physid, __physid_mask); \ + __physid_mask; \ }) #define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } diff --git a/include/asm-x86/mpspec_def.h b/include/asm-x86/mpspec_def.h index 13bafb16e7a..3504617fe64 100644 --- a/include/asm-x86/mpspec_def.h +++ b/include/asm-x86/mpspec_def.h @@ -8,52 +8,68 @@ /* * This tag identifies where the SMP configuration - * information is. + * information is. */ - + #define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') -#define MAX_MPC_ENTRY 1024 -#define MAX_APICS 256 +#ifdef CONFIG_X86_32 +# define MAX_MPC_ENTRY 1024 +# define MAX_APICS 256 +#else +/* + * A maximum of 255 APICs with the current APIC ID architecture. + */ +# define MAX_APICS 255 +#endif struct intel_mp_floating { - char mpf_signature[4]; /* "_MP_" */ - unsigned long mpf_physptr; /* Configuration table address */ + char mpf_signature[4]; /* "_MP_" */ + unsigned int mpf_physptr; /* Configuration table address */ unsigned char mpf_length; /* Our length (paragraphs) */ unsigned char mpf_specification;/* Specification version */ unsigned char mpf_checksum; /* Checksum (makes sum 0) */ - unsigned char mpf_feature1; /* Standard or configuration ? */ + unsigned char mpf_feature1; /* Standard or configuration ? */ unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ unsigned char mpf_feature3; /* Unused (0) */ unsigned char mpf_feature4; /* Unused (0) */ unsigned char mpf_feature5; /* Unused (0) */ }; +#define MPC_SIGNATURE "PCMP" + struct mp_config_table { char mpc_signature[4]; -#define MPC_SIGNATURE "PCMP" unsigned short mpc_length; /* Size of table */ char mpc_spec; /* 0x01 */ char mpc_checksum; char mpc_oem[8]; char mpc_productid[12]; - unsigned long mpc_oemptr; /* 0 if not present */ + unsigned int mpc_oemptr; /* 0 if not present */ unsigned short mpc_oemsize; /* 0 if not present */ unsigned short mpc_oemcount; - unsigned long mpc_lapic; /* APIC address */ - unsigned long reserved; + unsigned int mpc_lapic; /* APIC address */ + unsigned int reserved; }; /* Followed by entries */ -#define MP_PROCESSOR 0 -#define MP_BUS 1 -#define MP_IOAPIC 2 -#define MP_INTSRC 3 -#define MP_LINTSRC 4 -#define MP_TRANSLATION 192 /* Used by IBM NUMA-Q to describe node locality */ +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 +/* Used by IBM NUMA-Q to describe node locality */ +#define MP_TRANSLATION 192 + +#define CPU_ENABLED 1 /* Processor is available */ +#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ + +#define CPU_STEPPING_MASK 0x000F +#define CPU_MODEL_MASK 0x00F0 +#define CPU_FAMILY_MASK 0x0F00 struct mpc_config_processor { @@ -61,14 +77,9 @@ struct mpc_config_processor unsigned char mpc_apicid; /* Local APIC number */ unsigned char mpc_apicver; /* Its versions */ unsigned char mpc_cpuflag; -#define CPU_ENABLED 1 /* Processor is available */ -#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ - unsigned long mpc_cpufeature; -#define CPU_STEPPING_MASK 0x0F -#define CPU_MODEL_MASK 0xF0 -#define CPU_FAMILY_MASK 0xF00 - unsigned long mpc_featureflag; /* CPUID feature value */ - unsigned long mpc_reserved[2]; + unsigned int mpc_cpufeature; + unsigned int mpc_featureflag; /* CPUID feature value */ + unsigned int mpc_reserved[2]; }; struct mpc_config_bus @@ -98,14 +109,15 @@ struct mpc_config_bus #define BUSTYPE_VME "VME" #define BUSTYPE_XPRESS "XPRESS" +#define MPC_APIC_USABLE 0x01 + struct mpc_config_ioapic { unsigned char mpc_type; unsigned char mpc_apicid; unsigned char mpc_apicver; unsigned char mpc_flags; -#define MPC_APIC_USABLE 0x01 - unsigned long mpc_apicaddr; + unsigned int mpc_apicaddr; }; struct mpc_config_intsrc @@ -130,6 +142,7 @@ enum mp_irq_source_types { #define MP_IRQDIR_HIGH 1 #define MP_IRQDIR_LOW 3 +#define MP_APIC_ALL 0xFF struct mpc_config_lintsrc { @@ -138,15 +151,15 @@ struct mpc_config_lintsrc unsigned short mpc_irqflag; unsigned char mpc_srcbusid; unsigned char mpc_srcbusirq; - unsigned char mpc_destapic; -#define MP_APIC_ALL 0xFF + unsigned char mpc_destapic; unsigned char mpc_destapiclint; }; +#define MPC_OEM_SIGNATURE "_OEM" + struct mp_config_oemtable { char oem_signature[4]; -#define MPC_OEM_SIGNATURE "_OEM" unsigned short oem_length; /* Size of table */ char oem_rev; /* 0x01 */ char oem_checksum; @@ -155,13 +168,13 @@ struct mp_config_oemtable struct mpc_config_translation { - unsigned char mpc_type; - unsigned char trans_len; - unsigned char trans_type; - unsigned char trans_quad; - unsigned char trans_global; - unsigned char trans_local; - unsigned short trans_reserved; + unsigned char mpc_type; + unsigned char trans_len; + unsigned char trans_type; + unsigned char trans_quad; + unsigned char trans_global; + unsigned char trans_local; + unsigned short trans_reserved; }; /* -- cgit v1.2.2 From c2805aa1d8ae51c7582d2ccbd736afa545cf5cc4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:35 +0100 Subject: x86: merge mpspec variants The delta is now minimal. Merge them Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mpspec.h | 113 +++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/mpspec_32.h | 84 -------------------------------- include/asm-x86/mpspec_64.h | 79 ------------------------------- 3 files changed, 111 insertions(+), 165 deletions(-) delete mode 100644 include/asm-x86/mpspec_32.h delete mode 100644 include/asm-x86/mpspec_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h index 8f268e8fd2e..a2a6b2ea425 100644 --- a/include/asm-x86/mpspec.h +++ b/include/asm-x86/mpspec.h @@ -1,5 +1,114 @@ +#ifndef _AM_X86_MPSPEC_H +#define _AM_X86_MPSPEC_H + +#include + #ifdef CONFIG_X86_32 -# include "mpspec_32.h" +#include + +extern int mp_bus_id_to_type[MAX_MP_BUSSES]; +extern int mp_bus_id_to_node[MAX_MP_BUSSES]; +extern int mp_bus_id_to_local[MAX_MP_BUSSES]; +extern int quad_local_to_mp_bus_id[NR_CPUS/4][4]; + +extern unsigned int def_to_bigsmp; +extern int apic_version[MAX_APICS]; +extern int pic_mode; + #else -# include "mpspec_64.h" + +#define MAX_MP_BUSSES 256 +/* Each PCI slot may be a combo card with its own bus. 4 IRQ pins per slot. */ +#define MAX_IRQ_SOURCES (MAX_MP_BUSSES * 4) + +extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); + +#endif + +extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; + +extern unsigned int boot_cpu_physical_apicid; +extern int smp_found_config; +extern int nr_ioapics; +extern int mp_irq_entries; +extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; +extern int mpc_default_type; +extern unsigned long mp_lapic_addr; + +extern void find_smp_config(void); +extern void get_smp_config(void); + +#ifdef CONFIG_ACPI +extern void mp_register_lapic(u8 id, u8 enabled); +extern void mp_register_lapic_address(u64 address); +extern void mp_register_ioapic(u8 id, u32 address, u32 gsi_base); +extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, + u32 gsi); +extern void mp_config_acpi_legacy_irqs(void); +extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low); +#endif /* CONFIG_ACPI */ + +#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) + +struct physid_mask +{ + unsigned long mask[PHYSID_ARRAY_SIZE]; +}; + +typedef struct physid_mask physid_mask_t; + +#define physid_set(physid, map) set_bit(physid, (map).mask) +#define physid_clear(physid, map) clear_bit(physid, (map).mask) +#define physid_isset(physid, map) test_bit(physid, (map).mask) +#define physid_test_and_set(physid, map) \ + test_and_set_bit(physid, (map).mask) + +#define physids_and(dst, src1, src2) \ + bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) + +#define physids_or(dst, src1, src2) \ + bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) + +#define physids_clear(map) \ + bitmap_zero((map).mask, MAX_APICS) + +#define physids_complement(dst, src) \ + bitmap_complement((dst).mask, (src).mask, MAX_APICS) + +#define physids_empty(map) \ + bitmap_empty((map).mask, MAX_APICS) + +#define physids_equal(map1, map2) \ + bitmap_equal((map1).mask, (map2).mask, MAX_APICS) + +#define physids_weight(map) \ + bitmap_weight((map).mask, MAX_APICS) + +#define physids_shift_right(d, s, n) \ + bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS) + +#define physids_shift_left(d, s, n) \ + bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) + +#define physids_coerce(map) ((map).mask[0]) + +#define physids_promote(physids) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + __physid_mask.mask[0] = physids; \ + __physid_mask; \ + }) + +#define physid_mask_of_physid(physid) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + physid_set(physid, __physid_mask); \ + __physid_mask; \ + }) + +#define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } +#define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} } + +extern physid_mask_t phys_cpu_present_map; + #endif diff --git a/include/asm-x86/mpspec_32.h b/include/asm-x86/mpspec_32.h deleted file mode 100644 index bb73185e6a7..00000000000 --- a/include/asm-x86/mpspec_32.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __ASM_MPSPEC_H -#define __ASM_MPSPEC_H - -#include -#include - -extern int mp_bus_id_to_type[MAX_MP_BUSSES]; -extern int mp_bus_id_to_node[MAX_MP_BUSSES]; -extern int mp_bus_id_to_local[MAX_MP_BUSSES]; -extern int quad_local_to_mp_bus_id[NR_CPUS/4][4]; - -extern unsigned int def_to_bigsmp; -extern int apic_version[MAX_APICS]; -extern int pic_mode; - -extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; - -extern unsigned int boot_cpu_physical_apicid; -extern int smp_found_config; -extern int nr_ioapics; -extern int mp_irq_entries; -extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; -extern int mpc_default_type; -extern unsigned long mp_lapic_addr; - -extern void find_smp_config (void); -extern void get_smp_config (void); - -#ifdef CONFIG_ACPI -extern void mp_register_lapic (u8 id, u8 enabled); -extern void mp_register_lapic_address (u64 address); -extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); -extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, - u32 gsi); -extern void mp_config_acpi_legacy_irqs (void); -extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low); -#endif /* CONFIG_ACPI */ - -#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) - -struct physid_mask -{ - unsigned long mask[PHYSID_ARRAY_SIZE]; -}; - -typedef struct physid_mask physid_mask_t; - -#define physid_set(physid, map) set_bit(physid, (map).mask) -#define physid_clear(physid, map) clear_bit(physid, (map).mask) -#define physid_isset(physid, map) test_bit(physid, (map).mask) -#define physid_test_and_set(physid, map) test_and_set_bit(physid, (map).mask) - -#define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) -#define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) -#define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(dst, src) bitmap_complement((dst).mask, (src).mask, MAX_APICS) -#define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) -#define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) -#define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) -#define physids_shift_right(d, s, n) bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS) -#define physids_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) -#define physids_coerce(map) ((map).mask[0]) - -#define physids_promote(physids) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - __physid_mask.mask[0] = physids; \ - __physid_mask; \ - }) - -#define physid_mask_of_physid(physid) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - physid_set(physid, __physid_mask); \ - __physid_mask; \ - }) - -#define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } -#define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} } - -extern physid_mask_t phys_cpu_present_map; - -#endif - diff --git a/include/asm-x86/mpspec_64.h b/include/asm-x86/mpspec_64.h deleted file mode 100644 index 16eab20667c..00000000000 --- a/include/asm-x86/mpspec_64.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef __ASM_MPSPEC_H -#define __ASM_MPSPEC_H - -#include - -#define MAX_MP_BUSSES 256 -/* Each PCI slot may be a combo card with its own bus. 4 IRQ pins per slot. */ -#define MAX_IRQ_SOURCES (MAX_MP_BUSSES * 4) -extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); - -extern int mp_bus_id_to_pci_bus[MAX_MP_BUSSES]; - -extern unsigned int boot_cpu_physical_apicid; -extern int smp_found_config; -extern int nr_ioapics; -extern int mp_irq_entries; -extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; -extern int mpc_default_type; -extern unsigned long mp_lapic_addr; - -extern void find_smp_config (void); -extern void get_smp_config (void); - -#ifdef CONFIG_ACPI -extern void mp_register_lapic (u8 id, u8 enabled); -extern void mp_register_lapic_address (u64 address); -extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); -extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, - u32 gsi); -extern void mp_config_acpi_legacy_irqs (void); -extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low); -#endif /* CONFIG_ACPI */ - -#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) - -struct physid_mask -{ - unsigned long mask[PHYSID_ARRAY_SIZE]; -}; - -typedef struct physid_mask physid_mask_t; - -#define physid_set(physid, map) set_bit(physid, (map).mask) -#define physid_clear(physid, map) clear_bit(physid, (map).mask) -#define physid_isset(physid, map) test_bit(physid, (map).mask) -#define physid_test_and_set(physid, map) test_and_set_bit(physid, (map).mask) - -#define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) -#define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) -#define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(dst, src) bitmap_complement((dst).mask, (src).mask, MAX_APICS) -#define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) -#define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) -#define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) -#define physids_shift_right(d, s, n) bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS) -#define physids_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) -#define physids_coerce(map) ((map).mask[0]) - -#define physids_promote(physids) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - __physid_mask.mask[0] = physids; \ - __physid_mask; \ - }) - -#define physid_mask_of_physid(physid) \ - ({ \ - physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ - physid_set(physid, __physid_mask); \ - __physid_mask; \ - }) - -#define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } -#define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} } - -extern physid_mask_t phys_cpu_present_map; - -#endif - -- cgit v1.2.2 From ae9d983be1eefac4b5efad69a188e7ac89a75797 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:36 +0100 Subject: x86: cleanup smp.h variants Bring the smp.h variants into sync to prepare merging and paravirt support. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/apic.h | 1 + include/asm-x86/mpspec.h | 3 + include/asm-x86/smp_32.h | 117 ++++++++++++++++--------------------- include/asm-x86/smp_64.h | 133 ++++++++++++++++-------------------------- include/asm-x86/topology_64.h | 2 - 5 files changed, 104 insertions(+), 152 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index d0a221fa1fc..18d932dff47 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -42,6 +42,7 @@ extern int local_apic_timer_disabled; extern int apic_runs_main_timer; extern int ioapic_force; +extern int disable_apic; extern int disable_apic_timer; extern unsigned boot_cpu_id; diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h index a2a6b2ea425..781ad74ab9e 100644 --- a/include/asm-x86/mpspec.h +++ b/include/asm-x86/mpspec.h @@ -13,8 +13,11 @@ extern int quad_local_to_mp_bus_id[NR_CPUS/4][4]; extern unsigned int def_to_bigsmp; extern int apic_version[MAX_APICS]; +extern u8 apicid_2_node[]; extern int pic_mode; +#define MAX_APICID 256 + #else #define MAX_MP_BUSSES 256 diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h index e10b7affdfe..c69e960429c 100644 --- a/include/asm-x86/smp_32.h +++ b/include/asm-x86/smp_32.h @@ -1,51 +1,41 @@ #ifndef __ASM_SMP_H #define __ASM_SMP_H +#ifndef __ASSEMBLY__ +#include +#include + /* * We need the APIC definitions automatically as part of 'smp.h' */ -#ifndef __ASSEMBLY__ -#include -#include -#include +#ifdef CONFIG_X86_LOCAL_APIC +# include +# include +# ifdef CONFIG_X86_IO_APIC +# include +# endif #endif -#if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__) -#include -#include -#include -#ifdef CONFIG_X86_IO_APIC -#include -#endif -#endif +extern cpumask_t cpu_callout_map; +extern cpumask_t cpu_callin_map; -#define BAD_APICID 0xFFu -#ifdef CONFIG_SMP -#ifndef __ASSEMBLY__ +extern int smp_num_siblings; +extern unsigned int num_processors; -/* - * Private routines/data - */ - extern void smp_alloc_memory(void); -extern int pic_mode; -extern int smp_num_siblings; -DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); -DECLARE_PER_CPU(cpumask_t, cpu_core_map); +extern void lock_ipi_call_lock(void); +extern void unlock_ipi_call_lock(void); extern void (*mtrr_hook) (void); extern void zap_low_mappings (void); -extern void lock_ipi_call_lock(void); -extern void unlock_ipi_call_lock(void); -#define MAX_APICID 256 extern u8 __initdata x86_cpu_to_apicid_init[]; extern void *x86_cpu_to_apicid_ptr; -DECLARE_PER_CPU(u8, x86_cpu_to_apicid); - -#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) -extern void set_cpu_sibling_map(int cpu); +DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); +DECLARE_PER_CPU(cpumask_t, cpu_core_map); +DECLARE_PER_CPU(u8, cpu_llc_id); +DECLARE_PER_CPU(u8, x86_cpu_to_apicid); #ifdef CONFIG_HOTPLUG_CPU extern void cpu_exit_clear(void); @@ -53,6 +43,9 @@ extern void cpu_uninit(void); extern void remove_siblinginfo(int cpu); #endif +/* Globals due to paravirt */ +extern void set_cpu_sibling_map(int cpu); + struct smp_ops { void (*smp_prepare_boot_cpu)(void); @@ -67,6 +60,7 @@ struct smp_ops int wait); }; +#ifdef CONFIG_SMP extern struct smp_ops smp_ops; static inline void smp_prepare_boot_cpu(void) @@ -107,10 +101,12 @@ int native_cpu_up(unsigned int cpunum); void native_smp_cpus_done(unsigned int max_cpus); #ifndef CONFIG_PARAVIRT -#define startup_ipi_hook(phys_apicid, start_eip, start_esp) \ -do { } while (0) +#define startup_ipi_hook(phys_apicid, start_eip, start_esp) do { } while (0) #endif +extern int __cpu_disable(void); +extern void __cpu_die(unsigned int cpu); + /* * This function is needed by all SMP systems. It must _always_ be valid * from the initial startup. We map APIC_BASE very early in page_setup(), @@ -119,9 +115,11 @@ do { } while (0) DECLARE_PER_CPU(int, cpu_number); #define raw_smp_processor_id() (x86_read_percpu(cpu_number)) -extern cpumask_t cpu_callout_map; -extern cpumask_t cpu_callin_map; -extern cpumask_t cpu_possible_map; +#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) + +extern int safe_smp_processor_id(void); + +void __cpuinit smp_store_cpu_info(int id); /* We don't mark CPUs online until __cpu_up(), so we need another measure */ static inline int num_booting_cpus(void) @@ -129,56 +127,39 @@ static inline int num_booting_cpus(void) return cpus_weight(cpu_callout_map); } -extern int safe_smp_processor_id(void); -extern int __cpu_disable(void); -extern void __cpu_die(unsigned int cpu); -extern unsigned int num_processors; - -void __cpuinit smp_store_cpu_info(int id); - -#endif /* !__ASSEMBLY__ */ - #else /* CONFIG_SMP */ #define safe_smp_processor_id() 0 #define cpu_physical_id(cpu) boot_cpu_physical_apicid -#define NO_PROC_ID 0xFF /* No processor magic marker */ - -#endif /* CONFIG_SMP */ - -#ifndef __ASSEMBLY__ +#endif /* !CONFIG_SMP */ #ifdef CONFIG_X86_LOCAL_APIC -#ifdef APIC_DEFINITION +static __inline int logical_smp_processor_id(void) +{ + /* we don't want to mark this access volatile - bad code generation */ + return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR)); +} + +# ifdef APIC_DEFINITION extern int hard_smp_processor_id(void); -#else -#include +# else +# include static inline int hard_smp_processor_id(void) { /* we don't want to mark this access volatile - bad code generation */ - return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)); + return GET_APIC_ID(*(u32 *)(APIC_BASE + APIC_ID)); } -#endif /* APIC_DEFINITION */ +# endif /* APIC_DEFINITION */ #else /* CONFIG_X86_LOCAL_APIC */ -#ifndef CONFIG_SMP -#define hard_smp_processor_id() 0 -#endif +# ifndef CONFIG_SMP +# define hard_smp_processor_id() 0 +# endif #endif /* CONFIG_X86_LOCAL_APIC */ -extern u8 apicid_2_node[]; - -#ifdef CONFIG_X86_LOCAL_APIC -static __inline int logical_smp_processor_id(void) -{ - /* we don't want to mark this access volatile - bad code generation */ - return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); -} -#endif -#endif - +#endif /* !ASSEMBLY */ #endif diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h index ab612b0ff27..2feddda91e1 100644 --- a/include/asm-x86/smp_64.h +++ b/include/asm-x86/smp_64.h @@ -1,130 +1,99 @@ #ifndef __ASM_SMP_H #define __ASM_SMP_H -/* - * We need the APIC definitions automatically as part of 'smp.h' - */ -#include #include -#include #include -extern int disable_apic; -#include +/* + * We need the APIC definitions automatically as part of 'smp.h' + */ #include #include -#include - -#ifdef CONFIG_SMP - +#include #include +#include -struct pt_regs; - -extern cpumask_t cpu_present_mask; -extern cpumask_t cpu_possible_map; -extern cpumask_t cpu_online_map; extern cpumask_t cpu_callout_map; extern cpumask_t cpu_initialized; -/* - * Private routines/data - */ - +extern int smp_num_siblings; +extern unsigned int num_processors; + extern void smp_alloc_memory(void); -extern volatile unsigned long smp_invalidate_needed; extern void lock_ipi_call_lock(void); extern void unlock_ipi_call_lock(void); -extern int smp_num_siblings; -extern void smp_send_reschedule(int cpu); + extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, int wait); -/* - * cpu_sibling_map and cpu_core_map now live - * in the per cpu area - * - * extern cpumask_t cpu_sibling_map[NR_CPUS]; - * extern cpumask_t cpu_core_map[NR_CPUS]; - */ +extern u8 __initdata x86_cpu_to_apicid_init[]; +extern void *x86_cpu_to_apicid_ptr; +extern u8 bios_cpu_apicid[]; + DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); DECLARE_PER_CPU(cpumask_t, cpu_core_map); DECLARE_PER_CPU(u8, cpu_llc_id); +DECLARE_PER_CPU(u8, x86_cpu_to_apicid); -#define SMP_TRAMPOLINE_BASE 0x6000 - -/* - * On x86 all CPUs are mapped 1:1 to the APIC space. - * This simplifies scheduling and IPI sending and - * compresses data structures. - */ - -static inline int num_booting_cpus(void) +static inline int cpu_present_to_apicid(int mps_cpu) { - return cpus_weight(cpu_callout_map); + if (mps_cpu < NR_CPUS) + return (int)bios_cpu_apicid[mps_cpu]; + else + return BAD_APICID; } -#define raw_smp_processor_id() read_pda(cpunumber) +#ifdef CONFIG_SMP + +#define SMP_TRAMPOLINE_BASE 0x6000 extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); extern void prefill_possible_map(void); -extern unsigned num_processors; extern unsigned __cpuinitdata disabled_cpus; -#define NO_PROC_ID 0xFF /* No processor magic marker */ - -#endif /* CONFIG_SMP */ - -#define safe_smp_processor_id() smp_processor_id() +#define raw_smp_processor_id() read_pda(cpunumber) +#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) -static inline int hard_smp_processor_id(void) -{ - /* we don't want to mark this access volatile - bad code generation */ - return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID)); -} +#define stack_smp_processor_id() \ + ({ \ + struct thread_info *ti; \ + __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ + ti->cpu; \ +}) /* - * Some lowlevel functions might want to know about - * the real APIC ID <-> CPU # mapping. + * On x86 all CPUs are mapped 1:1 to the APIC space. This simplifies + * scheduling and IPI sending and compresses data structures. */ -extern u8 __initdata x86_cpu_to_apicid_init[]; -extern void *x86_cpu_to_apicid_ptr; -DECLARE_PER_CPU(u8, x86_cpu_to_apicid); /* physical ID */ -extern u8 bios_cpu_apicid[]; - -static inline int cpu_present_to_apicid(int mps_cpu) +static inline int num_booting_cpus(void) { - if (mps_cpu < NR_CPUS) - return (int)bios_cpu_apicid[mps_cpu]; - else - return BAD_APICID; + return cpus_weight(cpu_callout_map); } -#ifndef CONFIG_SMP +extern void smp_send_reschedule(int cpu); + +#else /* CONFIG_SMP */ + +extern unsigned int boot_cpu_id; +#define cpu_physical_id(cpu) boot_cpu_id #define stack_smp_processor_id() 0 -#define cpu_logical_map(x) (x) -#else -#include -#define stack_smp_processor_id() \ -({ \ - struct thread_info *ti; \ - __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ - ti->cpu; \ -}) -#endif + +#endif /* !CONFIG_SMP */ + +#define safe_smp_processor_id() smp_processor_id() static __inline int logical_smp_processor_id(void) { /* we don't want to mark this access volatile - bad code generation */ - return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); + return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR)); +} + +static inline int hard_smp_processor_id(void) +{ + /* we don't want to mark this access volatile - bad code generation */ + return GET_APIC_ID(*(u32 *)(APIC_BASE + APIC_ID)); } -#ifdef CONFIG_SMP -#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) -#else -extern unsigned int boot_cpu_id; -#define cpu_physical_id(cpu) boot_cpu_id -#endif /* !CONFIG_SMP */ #endif diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h index a718dda037e..407b22d4e3b 100644 --- a/include/asm-x86/topology_64.h +++ b/include/asm-x86/topology_64.h @@ -7,8 +7,6 @@ #include #include -extern cpumask_t cpu_online_map; - extern unsigned char cpu_to_node[]; extern cpumask_t node_to_cpumask[]; -- cgit v1.2.2 From 8a999410135602d98bd007e835dc21c0c279ad72 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:36 +0100 Subject: x86: cleanup acpi_32/64.h Fix coding style to get a readable diff Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/acpi_32.h | 35 ++++++++++++++--------------------- include/asm-x86/acpi_64.h | 41 +++++++++++++++++------------------------ 2 files changed, 31 insertions(+), 45 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/acpi_32.h b/include/asm-x86/acpi_32.h index c8afeea0b80..03612bcf642 100644 --- a/include/asm-x86/acpi_32.h +++ b/include/asm-x86/acpi_32.h @@ -24,11 +24,8 @@ #ifndef _ASM_ACPI_H #define _ASM_ACPI_H -#ifdef __KERNEL__ - #include - -#include /* defines cmpxchg */ +#include #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long @@ -67,17 +64,17 @@ int __acpi_release_global_lock(unsigned int *lock); * Math helper asm macros */ #define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ - asm("divl %2;" \ - :"=a"(q32), "=d"(r32) \ - :"r"(d32), \ - "0"(n_lo), "1"(n_hi)) + asm("divl %2;" \ + :"=a"(q32), "=d"(r32) \ + :"r"(d32), \ + "0"(n_lo), "1"(n_hi)) #define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ - asm("shrl $1,%2;" \ - "rcrl $1,%3;" \ - :"=r"(n_hi), "=r"(n_lo) \ - :"0"(n_hi), "1"(n_lo)) + asm("shrl $1,%2 ;" \ + "rcrl $1,%3;" \ + :"=r"(n_hi), "=r"(n_lo) \ + :"0"(n_hi), "1"(n_lo)) #ifdef CONFIG_ACPI extern int acpi_lapic; @@ -87,6 +84,9 @@ extern int acpi_strict; extern int acpi_disabled; extern int acpi_ht; extern int acpi_pci_disabled; +extern int acpi_skip_timer_override; +extern int acpi_use_timer_override; + static inline void disable_acpi(void) { acpi_disabled = 1; @@ -100,11 +100,6 @@ static inline void disable_acpi(void) extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); -#ifdef CONFIG_X86_IO_APIC -extern int acpi_skip_timer_override; -extern int acpi_use_timer_override; -#endif - static inline void acpi_noirq_set(void) { acpi_noirq = 1; } static inline void acpi_disable_pci(void) { @@ -122,7 +117,7 @@ extern unsigned long acpi_wakeup_address; /* early initialization routine */ extern void acpi_reserve_bootmem(void); -#else /* !CONFIG_ACPI */ +#else /* !CONFIG_ACPI */ #define acpi_lapic 0 #define acpi_ioapic 0 @@ -130,10 +125,8 @@ static inline void acpi_noirq_set(void) { } static inline void acpi_disable_pci(void) { } static inline void disable_acpi(void) { } -#endif /* !CONFIG_ACPI */ +#endif /* !CONFIG_ACPI */ #define ARCH_HAS_POWER_INIT 1 -#endif /*__KERNEL__*/ - #endif /*_ASM_ACPI_H*/ diff --git a/include/asm-x86/acpi_64.h b/include/asm-x86/acpi_64.h index 58114ed0802..b2670c6db8e 100644 --- a/include/asm-x86/acpi_64.h +++ b/include/asm-x86/acpi_64.h @@ -24,8 +24,6 @@ #ifndef _ASM_ACPI_H #define _ASM_ACPI_H -#ifdef __KERNEL__ - #include #include @@ -66,17 +64,17 @@ int __acpi_release_global_lock(unsigned int *lock); * Math helper asm macros */ #define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ - asm("divl %2;" \ - :"=a"(q32), "=d"(r32) \ - :"r"(d32), \ - "0"(n_lo), "1"(n_hi)) + asm("divl %2;" \ + :"=a"(q32), "=d"(r32) \ + :"r"(d32), \ + "0"(n_lo), "1"(n_hi)) #define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ - asm("shrl $1,%2;" \ - "rcrl $1,%3;" \ - :"=r"(n_hi), "=r"(n_lo) \ - :"0"(n_hi), "1"(n_lo)) + asm("shrl $1,%2 ;" \ + "rcrl $1,%3;" \ + :"=r"(n_hi), "=r"(n_lo) \ + :"0"(n_hi), "1"(n_lo)) #ifdef CONFIG_ACPI extern int acpi_lapic; @@ -84,8 +82,11 @@ extern int acpi_ioapic; extern int acpi_noirq; extern int acpi_strict; extern int acpi_disabled; -extern int acpi_pci_disabled; extern int acpi_ht; +extern int acpi_pci_disabled; +extern int acpi_skip_timer_override; +extern int acpi_use_timer_override; + static inline void disable_acpi(void) { acpi_disabled = 1; @@ -98,6 +99,7 @@ static inline void disable_acpi(void) #define FIX_ACPI_PAGES 4 extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); + static inline void acpi_noirq_set(void) { acpi_noirq = 1; } static inline void acpi_disable_pci(void) { @@ -115,7 +117,7 @@ extern unsigned long acpi_wakeup_address; /* early initialization routine */ extern void acpi_reserve_bootmem(void); -#else /* !CONFIG_ACPI */ +#else /* !CONFIG_ACPI */ #define acpi_lapic 0 #define acpi_ioapic 0 @@ -124,19 +126,12 @@ static inline void acpi_disable_pci(void) { } #endif /* !CONFIG_ACPI */ +#define ARCH_HAS_POWER_INIT 1 + +#ifdef CONFIG_ACPI_NUMA extern int acpi_numa; extern int acpi_scan_nodes(unsigned long start, unsigned long end); #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) - -extern int acpi_disabled; -extern int acpi_pci_disabled; - -#define ARCH_HAS_POWER_INIT 1 - -extern int acpi_skip_timer_override; -extern int acpi_use_timer_override; - -#ifdef CONFIG_ACPI_NUMA extern void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes); #else @@ -146,6 +141,4 @@ static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, } #endif -#endif /*__KERNEL__*/ - #endif /*_ASM_ACPI_H*/ -- cgit v1.2.2 From 0b80fc721bed2635c7f0b198e1c862a4596dc2cd Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:36 +0100 Subject: x86: merge acpi_32/64.h Merge the files. [ mingo@elte.hu: build fix ] Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/acpi.h | 148 ++++++++++++++++++++++++++++++++++++++++++++-- include/asm-x86/acpi_32.h | 132 ----------------------------------------- include/asm-x86/acpi_64.h | 144 -------------------------------------------- 3 files changed, 143 insertions(+), 281 deletions(-) delete mode 100644 include/asm-x86/acpi_32.h delete mode 100644 include/asm-x86/acpi_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/acpi.h b/include/asm-x86/acpi.h index f8a89793ac8..c477e574175 100644 --- a/include/asm-x86/acpi.h +++ b/include/asm-x86/acpi.h @@ -1,14 +1,123 @@ #ifndef _ASM_X86_ACPI_H #define _ASM_X86_ACPI_H -#ifdef CONFIG_X86_32 -# include "acpi_32.h" -#else -# include "acpi_64.h" -#endif +/* + * Copyright (C) 2001 Paul Diefenbaugh + * Copyright (C) 2001 Patrick Mochel + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include #include +#define COMPILER_DEPENDENT_INT64 long long +#define COMPILER_DEPENDENT_UINT64 unsigned long long + +/* + * Calling conventions: + * + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) + * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces + */ +#define ACPI_SYSTEM_XFACE +#define ACPI_EXTERNAL_XFACE +#define ACPI_INTERNAL_XFACE +#define ACPI_INTERNAL_VAR_XFACE + +/* Asm macros */ + +#define ACPI_ASM_MACROS +#define BREAKPOINT3 +#define ACPI_DISABLE_IRQS() local_irq_disable() +#define ACPI_ENABLE_IRQS() local_irq_enable() +#define ACPI_FLUSH_CPU_CACHE() wbinvd() + +int __acpi_acquire_global_lock(unsigned int *lock); +int __acpi_release_global_lock(unsigned int *lock); + +#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ + ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) + +#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ + ((Acq) = __acpi_release_global_lock(&facs->global_lock)) + +/* + * Math helper asm macros + */ +#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ + asm("divl %2;" \ + :"=a"(q32), "=d"(r32) \ + :"r"(d32), \ + "0"(n_lo), "1"(n_hi)) + + +#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ + asm("shrl $1,%2 ;" \ + "rcrl $1,%3;" \ + :"=r"(n_hi), "=r"(n_lo) \ + :"0"(n_hi), "1"(n_lo)) + +#ifdef CONFIG_ACPI +extern int acpi_lapic; +extern int acpi_ioapic; +extern int acpi_noirq; +extern int acpi_strict; +extern int acpi_disabled; +extern int acpi_ht; +extern int acpi_pci_disabled; +extern int acpi_skip_timer_override; +extern int acpi_use_timer_override; + +static inline void disable_acpi(void) +{ + acpi_disabled = 1; + acpi_ht = 0; + acpi_pci_disabled = 1; + acpi_noirq = 1; +} + +/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ +#define FIX_ACPI_PAGES 4 + +extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); + +static inline void acpi_noirq_set(void) { acpi_noirq = 1; } +static inline void acpi_disable_pci(void) +{ + acpi_pci_disabled = 1; + acpi_noirq_set(); +} +extern int acpi_irq_balance_set(char *str); + +/* routines for saving/restoring kernel state */ +extern int acpi_save_state_mem(void); +extern void acpi_restore_state_mem(void); + +extern unsigned long acpi_wakeup_address; + +/* early initialization routine */ +extern void acpi_reserve_bootmem(void); + /* * Check if the CPU can handle C2 and deeper */ @@ -29,4 +138,33 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) return max_cstate; } +#else /* !CONFIG_ACPI */ + +#define acpi_lapic 0 +#define acpi_ioapic 0 +static inline void acpi_noirq_set(void) { } +static inline void acpi_disable_pci(void) { } +static inline void disable_acpi(void) { } + +#endif /* !CONFIG_ACPI */ + +#define ARCH_HAS_POWER_INIT 1 + +struct bootnode; + +#ifdef CONFIG_ACPI_NUMA +extern int acpi_numa; +extern int acpi_scan_nodes(unsigned long start, unsigned long end); +#ifdef CONFIG_X86_64 +# define NR_NODE_MEMBLKS (MAX_NUMNODES*2) #endif +extern void __init acpi_fake_nodes(const struct bootnode *fake_nodes, + int num_nodes); +#else +static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, + int num_nodes) +{ +} +#endif + +#endif /*__X86_ASM_ACPI_H*/ diff --git a/include/asm-x86/acpi_32.h b/include/asm-x86/acpi_32.h deleted file mode 100644 index 03612bcf642..00000000000 --- a/include/asm-x86/acpi_32.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2001 Paul Diefenbaugh - * Copyright (C) 2001 Patrick Mochel - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef _ASM_ACPI_H -#define _ASM_ACPI_H - -#include -#include - -#define COMPILER_DEPENDENT_INT64 long long -#define COMPILER_DEPENDENT_UINT64 unsigned long long - -/* - * Calling conventions: - * - * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces - * ACPI_INTERNAL_XFACE - Internal ACPI interfaces - * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces - */ -#define ACPI_SYSTEM_XFACE -#define ACPI_EXTERNAL_XFACE -#define ACPI_INTERNAL_XFACE -#define ACPI_INTERNAL_VAR_XFACE - -/* Asm macros */ - -#define ACPI_ASM_MACROS -#define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() local_irq_disable() -#define ACPI_ENABLE_IRQS() local_irq_enable() -#define ACPI_FLUSH_CPU_CACHE() wbinvd() - -int __acpi_acquire_global_lock(unsigned int *lock); -int __acpi_release_global_lock(unsigned int *lock); - -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) - -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_release_global_lock(&facs->global_lock)) - -/* - * Math helper asm macros - */ -#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ - asm("divl %2;" \ - :"=a"(q32), "=d"(r32) \ - :"r"(d32), \ - "0"(n_lo), "1"(n_hi)) - - -#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ - asm("shrl $1,%2 ;" \ - "rcrl $1,%3;" \ - :"=r"(n_hi), "=r"(n_lo) \ - :"0"(n_hi), "1"(n_lo)) - -#ifdef CONFIG_ACPI -extern int acpi_lapic; -extern int acpi_ioapic; -extern int acpi_noirq; -extern int acpi_strict; -extern int acpi_disabled; -extern int acpi_ht; -extern int acpi_pci_disabled; -extern int acpi_skip_timer_override; -extern int acpi_use_timer_override; - -static inline void disable_acpi(void) -{ - acpi_disabled = 1; - acpi_ht = 0; - acpi_pci_disabled = 1; - acpi_noirq = 1; -} - -/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ -#define FIX_ACPI_PAGES 4 - -extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); - -static inline void acpi_noirq_set(void) { acpi_noirq = 1; } -static inline void acpi_disable_pci(void) -{ - acpi_pci_disabled = 1; - acpi_noirq_set(); -} -extern int acpi_irq_balance_set(char *str); - -/* routines for saving/restoring kernel state */ -extern int acpi_save_state_mem(void); -extern void acpi_restore_state_mem(void); - -extern unsigned long acpi_wakeup_address; - -/* early initialization routine */ -extern void acpi_reserve_bootmem(void); - -#else /* !CONFIG_ACPI */ - -#define acpi_lapic 0 -#define acpi_ioapic 0 -static inline void acpi_noirq_set(void) { } -static inline void acpi_disable_pci(void) { } -static inline void disable_acpi(void) { } - -#endif /* !CONFIG_ACPI */ - -#define ARCH_HAS_POWER_INIT 1 - -#endif /*_ASM_ACPI_H*/ diff --git a/include/asm-x86/acpi_64.h b/include/asm-x86/acpi_64.h deleted file mode 100644 index b2670c6db8e..00000000000 --- a/include/asm-x86/acpi_64.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2001 Paul Diefenbaugh - * Copyright (C) 2001 Patrick Mochel - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef _ASM_ACPI_H -#define _ASM_ACPI_H - -#include -#include - -#define COMPILER_DEPENDENT_INT64 long long -#define COMPILER_DEPENDENT_UINT64 unsigned long long - -/* - * Calling conventions: - * - * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces - * ACPI_INTERNAL_XFACE - Internal ACPI interfaces - * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces - */ -#define ACPI_SYSTEM_XFACE -#define ACPI_EXTERNAL_XFACE -#define ACPI_INTERNAL_XFACE -#define ACPI_INTERNAL_VAR_XFACE - -/* Asm macros */ - -#define ACPI_ASM_MACROS -#define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() local_irq_disable() -#define ACPI_ENABLE_IRQS() local_irq_enable() -#define ACPI_FLUSH_CPU_CACHE() wbinvd() - -int __acpi_acquire_global_lock(unsigned int *lock); -int __acpi_release_global_lock(unsigned int *lock); - -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) - -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_release_global_lock(&facs->global_lock)) - -/* - * Math helper asm macros - */ -#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ - asm("divl %2;" \ - :"=a"(q32), "=d"(r32) \ - :"r"(d32), \ - "0"(n_lo), "1"(n_hi)) - - -#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ - asm("shrl $1,%2 ;" \ - "rcrl $1,%3;" \ - :"=r"(n_hi), "=r"(n_lo) \ - :"0"(n_hi), "1"(n_lo)) - -#ifdef CONFIG_ACPI -extern int acpi_lapic; -extern int acpi_ioapic; -extern int acpi_noirq; -extern int acpi_strict; -extern int acpi_disabled; -extern int acpi_ht; -extern int acpi_pci_disabled; -extern int acpi_skip_timer_override; -extern int acpi_use_timer_override; - -static inline void disable_acpi(void) -{ - acpi_disabled = 1; - acpi_ht = 0; - acpi_pci_disabled = 1; - acpi_noirq = 1; -} - -/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ -#define FIX_ACPI_PAGES 4 - -extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); - -static inline void acpi_noirq_set(void) { acpi_noirq = 1; } -static inline void acpi_disable_pci(void) -{ - acpi_pci_disabled = 1; - acpi_noirq_set(); -} -extern int acpi_irq_balance_set(char *str); - -/* routines for saving/restoring kernel state */ -extern int acpi_save_state_mem(void); -extern void acpi_restore_state_mem(void); - -extern unsigned long acpi_wakeup_address; - -/* early initialization routine */ -extern void acpi_reserve_bootmem(void); - -#else /* !CONFIG_ACPI */ - -#define acpi_lapic 0 -#define acpi_ioapic 0 -static inline void acpi_noirq_set(void) { } -static inline void acpi_disable_pci(void) { } - -#endif /* !CONFIG_ACPI */ - -#define ARCH_HAS_POWER_INIT 1 - -#ifdef CONFIG_ACPI_NUMA -extern int acpi_numa; -extern int acpi_scan_nodes(unsigned long start, unsigned long end); -#define NR_NODE_MEMBLKS (MAX_NUMNODES*2) -extern void __init acpi_fake_nodes(const struct bootnode *fake_nodes, - int num_nodes); -#else -static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, - int num_nodes) -{ -} -#endif - -#endif /*_ASM_ACPI_H*/ -- cgit v1.2.2 From 4757d7d8d00c5f8b2c176ca03b0a8eabbc206664 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:37 +0100 Subject: x86: put all kern_addr_valid() incarnations to pgtable.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/mmzone_32.h | 3 --- include/asm-x86/pgtable_32.h | 8 +++++++- include/asm-x86/sparsemem_32.h | 3 --- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mmzone_32.h b/include/asm-x86/mmzone_32.h index 118e9812778..5d6f4ce6e6d 100644 --- a/include/asm-x86/mmzone_32.h +++ b/include/asm-x86/mmzone_32.h @@ -87,9 +87,6 @@ static inline int pfn_to_nid(unsigned long pfn) __pgdat->node_start_pfn + __pgdat->node_spanned_pages; \ }) -/* XXX: FIXME -- wli */ -#define kern_addr_valid(kaddr) (0) - #ifdef CONFIG_X86_NUMAQ /* we have contiguous memory on NUMA-Q */ #define pfn_valid(pfn) ((pfn) < num_physpages) #else diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index ed3e70d8d04..a8be1ee15a9 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -497,9 +497,15 @@ static inline void paravirt_pagetable_setup_done(pgd_t *base) #endif /* !__ASSEMBLY__ */ +/* + * kern_addr_valid() is (1) for FLATMEM and (0) for + * SPARSEMEM and DISCONTIGMEM + */ #ifdef CONFIG_FLATMEM #define kern_addr_valid(addr) (1) -#endif /* CONFIG_FLATMEM */ +#else +#define kern_addr_valid(kaddr) (0) +#endif #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) diff --git a/include/asm-x86/sparsemem_32.h b/include/asm-x86/sparsemem_32.h index cfeed990585..d89c3210059 100644 --- a/include/asm-x86/sparsemem_32.h +++ b/include/asm-x86/sparsemem_32.h @@ -24,8 +24,5 @@ #define MAX_PHYSMEM_BITS 32 #endif -/* XXX: FIXME -- wli */ -#define kern_addr_valid(kaddr) (0) - #endif /* CONFIG_SPARSEMEM */ #endif /* _I386_SPARSEMEM_H */ -- cgit v1.2.2 From 8a423ff0c4a0472607bbed6790fdaeec54af2ebb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:37 +0100 Subject: x86: merge include/asm-x86/sparsemem.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/mmzone_64.h | 2 ++ include/asm-x86/sparsemem.h | 35 ++++++++++++++++++++++++++++++++--- include/asm-x86/sparsemem_32.h | 28 ---------------------------- include/asm-x86/sparsemem_64.h | 26 -------------------------- 4 files changed, 34 insertions(+), 57 deletions(-) delete mode 100644 include/asm-x86/sparsemem_32.h delete mode 100644 include/asm-x86/sparsemem_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/mmzone_64.h b/include/asm-x86/mmzone_64.h index 19a89377b12..1e0ed34a6ad 100644 --- a/include/asm-x86/mmzone_64.h +++ b/include/asm-x86/mmzone_64.h @@ -41,6 +41,8 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) #define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ NODE_DATA(nid)->node_spanned_pages) +extern int early_pfn_to_nid(unsigned long pfn); + #ifdef CONFIG_DISCONTIGMEM #define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT) diff --git a/include/asm-x86/sparsemem.h b/include/asm-x86/sparsemem.h index 3f203b1d9ee..fa58cd55411 100644 --- a/include/asm-x86/sparsemem.h +++ b/include/asm-x86/sparsemem.h @@ -1,5 +1,34 @@ +#ifndef _ASM_X86_SPARSEMEM_H +#define _ASM_X86_SPARSEMEM_H + +#ifdef CONFIG_SPARSEMEM +/* + * generic non-linear memory support: + * + * 1) we will not split memory into more chunks than will fit into the flags + * field of the struct page + * + * SECTION_SIZE_BITS 2^n: size of each section + * MAX_PHYSADDR_BITS 2^n: max size of physical address space + * MAX_PHYSMEM_BITS 2^n: how much memory we can have in that space + * + */ + #ifdef CONFIG_X86_32 -# include "sparsemem_32.h" -#else -# include "sparsemem_64.h" +# ifdef CONFIG_X86_PAE +# define SECTION_SIZE_BITS 30 +# define MAX_PHYSADDR_BITS 36 +# define MAX_PHYSMEM_BITS 36 +# else +# define SECTION_SIZE_BITS 26 +# define MAX_PHYSADDR_BITS 32 +# define MAX_PHYSMEM_BITS 32 +# endif +#else /* CONFIG_X86_32 */ +# define SECTION_SIZE_BITS 27 /* matt - 128 is convenient right now */ +# define MAX_PHYSADDR_BITS 40 +# define MAX_PHYSMEM_BITS 40 +#endif + +#endif /* CONFIG_SPARSEMEM */ #endif diff --git a/include/asm-x86/sparsemem_32.h b/include/asm-x86/sparsemem_32.h deleted file mode 100644 index d89c3210059..00000000000 --- a/include/asm-x86/sparsemem_32.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _I386_SPARSEMEM_H -#define _I386_SPARSEMEM_H -#ifdef CONFIG_SPARSEMEM - -/* - * generic non-linear memory support: - * - * 1) we will not split memory into more chunks than will fit into the - * flags field of the struct page - */ - -/* - * SECTION_SIZE_BITS 2^N: how big each section will be - * MAX_PHYSADDR_BITS 2^N: how much physical address space we have - * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space - */ -#ifdef CONFIG_X86_PAE -#define SECTION_SIZE_BITS 30 -#define MAX_PHYSADDR_BITS 36 -#define MAX_PHYSMEM_BITS 36 -#else -#define SECTION_SIZE_BITS 26 -#define MAX_PHYSADDR_BITS 32 -#define MAX_PHYSMEM_BITS 32 -#endif - -#endif /* CONFIG_SPARSEMEM */ -#endif /* _I386_SPARSEMEM_H */ diff --git a/include/asm-x86/sparsemem_64.h b/include/asm-x86/sparsemem_64.h deleted file mode 100644 index dabb16714a7..00000000000 --- a/include/asm-x86/sparsemem_64.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _ASM_X86_64_SPARSEMEM_H -#define _ASM_X86_64_SPARSEMEM_H 1 - -#ifdef CONFIG_SPARSEMEM - -/* - * generic non-linear memory support: - * - * 1) we will not split memory into more chunks than will fit into the flags - * field of the struct page - * - * SECTION_SIZE_BITS 2^n: size of each section - * MAX_PHYSADDR_BITS 2^n: max size of physical address space - * MAX_PHYSMEM_BITS 2^n: how much memory we can have in that space - * - */ - -#define SECTION_SIZE_BITS 27 /* matt - 128 is convenient right now */ -#define MAX_PHYSADDR_BITS 40 -#define MAX_PHYSMEM_BITS 40 - -extern int early_pfn_to_nid(unsigned long pfn); - -#endif /* CONFIG_SPARSEMEM */ - -#endif /* _ASM_X86_64_SPARSEMEM_H */ -- cgit v1.2.2 From e1d9197862ff4d950dab45669b7f37b5ec3219d8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:37 +0100 Subject: x86: merge include/asm-x86/sparsemem.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/io_apic.h | 158 ++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/io_apic_32.h | 155 ------------------------------------------ include/asm-x86/io_apic_64.h | 134 ------------------------------------ 3 files changed, 156 insertions(+), 291 deletions(-) delete mode 100644 include/asm-x86/io_apic_32.h delete mode 100644 include/asm-x86/io_apic_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_apic.h b/include/asm-x86/io_apic.h index 88494966bee..0f5b3fef0b0 100644 --- a/include/asm-x86/io_apic.h +++ b/include/asm-x86/io_apic.h @@ -1,5 +1,159 @@ +#ifndef __ASM_IO_APIC_H +#define __ASM_IO_APIC_H + +#include +#include +#include + +/* + * Intel IO-APIC support for SMP and UP systems. + * + * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar + */ + +/* + * The structure of the IO-APIC: + */ +union IO_APIC_reg_00 { + u32 raw; + struct { + u32 __reserved_2 : 14, + LTS : 1, + delivery_type : 1, + __reserved_1 : 8, + ID : 8; + } __attribute__ ((packed)) bits; +}; + +union IO_APIC_reg_01 { + u32 raw; + struct { + u32 version : 8, + __reserved_2 : 7, + PRQ : 1, + entries : 8, + __reserved_1 : 8; + } __attribute__ ((packed)) bits; +}; + +union IO_APIC_reg_02 { + u32 raw; + struct { + u32 __reserved_2 : 24, + arbitration : 4, + __reserved_1 : 4; + } __attribute__ ((packed)) bits; +}; + +union IO_APIC_reg_03 { + u32 raw; + struct { + u32 boot_DT : 1, + __reserved_1 : 31; + } __attribute__ ((packed)) bits; +}; + +enum ioapic_irq_destination_types { + dest_Fixed = 0, + dest_LowestPrio = 1, + dest_SMI = 2, + dest__reserved_1 = 3, + dest_NMI = 4, + dest_INIT = 5, + dest__reserved_2 = 6, + dest_ExtINT = 7 +}; + +struct IO_APIC_route_entry { + __u32 vector : 8, + delivery_mode : 3, /* 000: FIXED + * 001: lowest prio + * 111: ExtINT + */ + dest_mode : 1, /* 0: physical, 1: logical */ + delivery_status : 1, + polarity : 1, + irr : 1, + trigger : 1, /* 0: edge, 1: level */ + mask : 1, /* 0: enabled, 1: disabled */ + __reserved_2 : 15; + #ifdef CONFIG_X86_32 -# include "io_apic_32.h" + union { + struct { + __u32 __reserved_1 : 24, + physical_dest : 4, + __reserved_2 : 4; + } physical; + + struct { + __u32 __reserved_1 : 24, + logical_dest : 8; + } logical; + } dest; #else -# include "io_apic_64.h" + __u32 __reserved_3 : 24, + dest : 8; +#endif + +} __attribute__ ((packed)); + +#ifdef CONFIG_X86_IO_APIC + +/* + * # of IO-APICs and # of IRQ routing registers + */ +extern int nr_ioapics; +extern int nr_ioapic_registers[MAX_IO_APICS]; + +/* + * MP-BIOS irq configuration table structures: + */ + +/* I/O APIC entries */ +extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; + +/* # of MP IRQ source entries */ +extern int mp_irq_entries; + +/* MP IRQ source entries */ +extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; + +/* non-0 if default (table-less) MP configuration */ +extern int mpc_default_type; + +/* Older SiS APIC requires we rewrite the index register */ +extern int sis_apic_bug; + +/* 1 if "noapic" boot option passed */ +extern int skip_ioapic_setup; + +static inline void disable_ioapic_setup(void) +{ + skip_ioapic_setup = 1; +} + +/* + * If we use the IO-APIC for IRQ routing, disable automatic + * assignment of PCI IRQ's. + */ +#define io_apic_assign_pci_irqs \ + (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) + +#ifdef CONFIG_ACPI +extern int io_apic_get_unique_id(int ioapic, int apic_id); +extern int io_apic_get_version(int ioapic); +extern int io_apic_get_redir_entries(int ioapic); +extern int io_apic_set_pci_routing(int ioapic, int pin, int irq, + int edge_level, int active_high_low); +extern int timer_uses_ioapic_pin_0; +#endif /* CONFIG_ACPI */ + +extern int (*ioapic_renumber_irq)(int ioapic, int irq); +extern void ioapic_init_mappings(void); + +#else /* !CONFIG_X86_IO_APIC */ +#define io_apic_assign_pci_irqs 0 +#endif + #endif diff --git a/include/asm-x86/io_apic_32.h b/include/asm-x86/io_apic_32.h deleted file mode 100644 index 3f087883ea4..00000000000 --- a/include/asm-x86/io_apic_32.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef __ASM_IO_APIC_H -#define __ASM_IO_APIC_H - -#include -#include -#include - -/* - * Intel IO-APIC support for SMP and UP systems. - * - * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar - */ - -/* - * The structure of the IO-APIC: - */ -union IO_APIC_reg_00 { - u32 raw; - struct { - u32 __reserved_2 : 14, - LTS : 1, - delivery_type : 1, - __reserved_1 : 8, - ID : 8; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_01 { - u32 raw; - struct { - u32 version : 8, - __reserved_2 : 7, - PRQ : 1, - entries : 8, - __reserved_1 : 8; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_02 { - u32 raw; - struct { - u32 __reserved_2 : 24, - arbitration : 4, - __reserved_1 : 4; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_03 { - u32 raw; - struct { - u32 boot_DT : 1, - __reserved_1 : 31; - } __attribute__ ((packed)) bits; -}; - -enum ioapic_irq_destination_types { - dest_Fixed = 0, - dest_LowestPrio = 1, - dest_SMI = 2, - dest__reserved_1 = 3, - dest_NMI = 4, - dest_INIT = 5, - dest__reserved_2 = 6, - dest_ExtINT = 7 -}; - -struct IO_APIC_route_entry { - __u32 vector : 8, - delivery_mode : 3, /* 000: FIXED - * 001: lowest prio - * 111: ExtINT - */ - dest_mode : 1, /* 0: physical, 1: logical */ - delivery_status : 1, - polarity : 1, - irr : 1, - trigger : 1, /* 0: edge, 1: level */ - mask : 1, /* 0: enabled, 1: disabled */ - __reserved_2 : 15; - - union { struct { __u32 - __reserved_1 : 24, - physical_dest : 4, - __reserved_2 : 4; - } physical; - - struct { __u32 - __reserved_1 : 24, - logical_dest : 8; - } logical; - } dest; - -} __attribute__ ((packed)); - -#ifdef CONFIG_X86_IO_APIC - -/* - * # of IO-APICs and # of IRQ routing registers - */ -extern int nr_ioapics; -extern int nr_ioapic_registers[MAX_IO_APICS]; - -/* - * MP-BIOS irq configuration table structures: - */ - -/* I/O APIC entries */ -extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; - -/* # of MP IRQ source entries */ -extern int mp_irq_entries; - -/* MP IRQ source entries */ -extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; - -/* non-0 if default (table-less) MP configuration */ -extern int mpc_default_type; - -/* Older SiS APIC requires we rewrite the index register */ -extern int sis_apic_bug; - -/* 1 if "noapic" boot option passed */ -extern int skip_ioapic_setup; - -static inline void disable_ioapic_setup(void) -{ - skip_ioapic_setup = 1; -} - -static inline int ioapic_setup_disabled(void) -{ - return skip_ioapic_setup; -} - -/* - * If we use the IO-APIC for IRQ routing, disable automatic - * assignment of PCI IRQ's. - */ -#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) - -#ifdef CONFIG_ACPI -extern int io_apic_get_unique_id (int ioapic, int apic_id); -extern int io_apic_get_version (int ioapic); -extern int io_apic_get_redir_entries (int ioapic); -extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low); -extern int timer_uses_ioapic_pin_0; -#endif /* CONFIG_ACPI */ - -extern int (*ioapic_renumber_irq)(int ioapic, int irq); - -#else /* !CONFIG_X86_IO_APIC */ -#define io_apic_assign_pci_irqs 0 -#endif - -#endif diff --git a/include/asm-x86/io_apic_64.h b/include/asm-x86/io_apic_64.h deleted file mode 100644 index 3e3c2114d93..00000000000 --- a/include/asm-x86/io_apic_64.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef __ASM_IO_APIC_H -#define __ASM_IO_APIC_H - -#include -#include -#include - -/* - * Intel IO-APIC support for SMP and UP systems. - * - * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar - */ - -#define APIC_MISMATCH_DEBUG - -/* - * The structure of the IO-APIC: - */ -union IO_APIC_reg_00 { - u32 raw; - struct { - u32 __reserved_2 : 14, - LTS : 1, - delivery_type : 1, - __reserved_1 : 8, - ID : 8; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_01 { - u32 raw; - struct { - u32 version : 8, - __reserved_2 : 7, - PRQ : 1, - entries : 8, - __reserved_1 : 8; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_02 { - u32 raw; - struct { - u32 __reserved_2 : 24, - arbitration : 4, - __reserved_1 : 4; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_03 { - u32 raw; - struct { - u32 boot_DT : 1, - __reserved_1 : 31; - } __attribute__ ((packed)) bits; -}; - -/* - * # of IO-APICs and # of IRQ routing registers - */ -extern int nr_ioapics; -extern int nr_ioapic_registers[MAX_IO_APICS]; - -enum ioapic_irq_destination_types { - dest_Fixed = 0, - dest_LowestPrio = 1, - dest_SMI = 2, - dest__reserved_1 = 3, - dest_NMI = 4, - dest_INIT = 5, - dest__reserved_2 = 6, - dest_ExtINT = 7 -}; - -struct IO_APIC_route_entry { - __u32 vector : 8, - delivery_mode : 3, /* 000: FIXED - * 001: lowest prio - * 111: ExtINT - */ - dest_mode : 1, /* 0: physical, 1: logical */ - delivery_status : 1, - polarity : 1, - irr : 1, - trigger : 1, /* 0: edge, 1: level */ - mask : 1, /* 0: enabled, 1: disabled */ - __reserved_2 : 15; - - __u32 __reserved_3 : 24, - dest : 8; -} __attribute__ ((packed)); - -/* - * MP-BIOS irq configuration table structures: - */ - -/* I/O APIC entries */ -extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; - -/* # of MP IRQ source entries */ -extern int mp_irq_entries; - -/* MP IRQ source entries */ -extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; - -/* non-0 if default (table-less) MP configuration */ -extern int mpc_default_type; - -/* 1 if "noapic" boot option passed */ -extern int skip_ioapic_setup; - -static inline void disable_ioapic_setup(void) -{ - skip_ioapic_setup = 1; -} - - -/* - * If we use the IO-APIC for IRQ routing, disable automatic - * assignment of PCI IRQ's. - */ -#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) - -#ifdef CONFIG_ACPI -extern int io_apic_get_version (int ioapic); -extern int io_apic_get_redir_entries (int ioapic); -extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int); -#endif - -extern void ioapic_init_mappings(void); - -extern int sis_apic_bug; /* dummy */ - -#endif -- cgit v1.2.2 From 7462894a7cb03b54b9139f31fab5928366752a78 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:38 +0100 Subject: x86: fixup numa 64 namespace Using a variable name, which is the same as a macro name is not really smart. Change the variable names and fixup all users. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/numa_64.h | 2 +- include/asm-x86/topology_64.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index e6bc0b5dfe3..c3c20db1fba 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h @@ -32,7 +32,7 @@ extern void __init init_cpu_to_node(void); static inline void clear_node_cpumask(int cpu) { - clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]); + clear_bit(cpu, &node_to_cpumask_map[cpu_to_node(cpu)]); } #else diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h index 407b22d4e3b..cf529341b16 100644 --- a/include/asm-x86/topology_64.h +++ b/include/asm-x86/topology_64.h @@ -7,8 +7,8 @@ #include #include -extern unsigned char cpu_to_node[]; -extern cpumask_t node_to_cpumask[]; +extern int cpu_to_node_map[]; +extern cpumask_t node_to_cpumask_map[]; #ifdef CONFIG_ACPI_NUMA extern int __node_distance(int, int); @@ -16,10 +16,10 @@ extern int __node_distance(int, int); /* #else fallback version */ #endif -#define cpu_to_node(cpu) (cpu_to_node[cpu]) +#define cpu_to_node(cpu) (cpu_to_node_map[cpu]) #define parent_node(node) (node) -#define node_to_first_cpu(node) (first_cpu(node_to_cpumask[node])) -#define node_to_cpumask(node) (node_to_cpumask[node]) +#define node_to_first_cpu(node) (first_cpu(node_to_cpumask_map[node])) +#define node_to_cpumask(node) (node_to_cpumask_map[node]) #define pcibus_to_node(bus) ((struct pci_sysdata *)((bus)->sysdata))->node #define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus)); -- cgit v1.2.2 From fe21a445b98c9d52f02f3412d7a2fd39784f3b22 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:38 +0100 Subject: x86: adjust numa 32 namespace Use the 64bit numa variable names for numa32 as well. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/topology_32.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h index fdca80a851e..e28dbdcc567 100644 --- a/include/asm-x86/topology_32.h +++ b/include/asm-x86/topology_32.h @@ -39,13 +39,13 @@ #include /* Mappings between logical cpu number and node number */ -extern cpumask_t node_2_cpu_mask[]; -extern int cpu_2_node[]; +extern cpumask_t node_to_cpumask_map[]; +extern int cpu_to_node_map[]; /* Returns the number of the node containing CPU 'cpu' */ static inline int cpu_to_node(int cpu) { - return cpu_2_node[cpu]; + return cpu_to_node_map[cpu]; } /* Returns the number of the node containing Node 'node'. This architecture is flat, @@ -55,7 +55,7 @@ static inline int cpu_to_node(int cpu) /* Returns a bitmask of CPUs on Node 'node'. */ static inline cpumask_t node_to_cpumask(int node) { - return node_2_cpu_mask[node]; + return node_to_cpumask_map[node]; } /* Returns the number of the first CPU on Node 'node'. */ -- cgit v1.2.2 From b4ea9299df1fa04dbd51840f60918a63ff6a8a44 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:38 +0100 Subject: x86: consolidate toloplogy_32/64.h Reorder defines and do white space / coding style cleanups to get a readable diff. Also convert the macros to inline functions. Move the pci related inlines to pci.h Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/pci.h | 13 ++++++++++ include/asm-x86/topology_32.h | 55 +++++++++++++++++++-------------------- include/asm-x86/topology_64.h | 60 +++++++++++++++++++++++++++++-------------- 3 files changed, 80 insertions(+), 48 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pci.h b/include/asm-x86/pci.h index 6983730d86f..c61190cb9e1 100644 --- a/include/asm-x86/pci.h +++ b/include/asm-x86/pci.h @@ -92,6 +92,19 @@ static inline void early_quirks(void) { } /* generic pci stuff */ #include +#ifdef CONFIG_NUMA +/* Returns the node based on pci bus */ +static inline int __pcibus_to_node(struct pci_bus *bus) +{ + struct pci_sysdata *sd = bus->sysdata; + + return sd->node; +} +static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus) +{ + return node_to_cpumask(__pcibus_to_node(bus)); +} +#endif #endif diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h index e28dbdcc567..35b00067587 100644 --- a/include/asm-x86/topology_32.h +++ b/include/asm-x86/topology_32.h @@ -3,7 +3,7 @@ * * Copyright (C) 2002, IBM Corp. * - * All rights reserved. + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,34 +22,27 @@ * * Send feedback to */ -#ifndef _ASM_I386_TOPOLOGY_H -#define _ASM_I386_TOPOLOGY_H - -#ifdef CONFIG_X86_HT -#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) -#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) -#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) -#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) -#endif +#ifndef _ASM_X86_TOPOLOGY_H +#define _ASM_X86_TOPOLOGY_H #ifdef CONFIG_NUMA - -#include - #include +#include /* Mappings between logical cpu number and node number */ -extern cpumask_t node_to_cpumask_map[]; extern int cpu_to_node_map[]; +extern cpumask_t node_to_cpumask_map[]; /* Returns the number of the node containing CPU 'cpu' */ static inline int cpu_to_node(int cpu) -{ +{ return cpu_to_node_map[cpu]; } -/* Returns the number of the node containing Node 'node'. This architecture is flat, - so it is a pretty simple function! */ +/* + * Returns the number of the node containing Node 'node'. This + * architecture is flat, so it is a pretty simple function! + */ #define parent_node(node) (node) /* Returns a bitmask of CPUs on Node 'node'. */ @@ -60,13 +53,14 @@ static inline cpumask_t node_to_cpumask(int node) /* Returns the number of the first CPU on Node 'node'. */ static inline int node_to_first_cpu(int node) -{ +{ cpumask_t mask = node_to_cpumask(node); + return first_cpu(mask); } -#define pcibus_to_node(bus) ((struct pci_sysdata *)((bus)->sysdata))->node -#define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus)) +#define pcibus_to_node(bus) __pcibus_to_node(bus) +#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus) /* sched_domains SD_NODE_INIT for NUMAQ machines */ #define SD_NODE_INIT (struct sched_domain) { \ @@ -99,21 +93,24 @@ extern unsigned long node_remap_size[]; #define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid]) -#else /* !CONFIG_NUMA */ -/* - * Other i386 platforms should define their own version of the - * above macros here. - */ +#else /* CONFIG_NUMA */ #include -#endif /* CONFIG_NUMA */ +#endif extern cpumask_t cpu_coregroup_map(int cpu); +#ifdef CONFIG_X86_HT +#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) +#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) +#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) +#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) +#endif + #ifdef CONFIG_SMP -#define mc_capable() (boot_cpu_data.x86_max_cores > 1) -#define smt_capable() (smp_num_siblings > 1) +#define mc_capable() (boot_cpu_data.x86_max_cores > 1) +#define smt_capable() (smp_num_siblings > 1) #endif -#endif /* _ASM_I386_TOPOLOGY_H */ +#endif diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h index cf529341b16..93de948bd33 100644 --- a/include/asm-x86/topology_64.h +++ b/include/asm-x86/topology_64.h @@ -1,27 +1,47 @@ -#ifndef _ASM_X86_64_TOPOLOGY_H -#define _ASM_X86_64_TOPOLOGY_H - +#ifndef _ASM_X86_TOPOLOGY_H +#define _ASM_X86_TOPOLOGY_H #ifdef CONFIG_NUMA - +#include #include -#include +/* Mappings between logical cpu number and node number */ extern int cpu_to_node_map[]; extern cpumask_t node_to_cpumask_map[]; #ifdef CONFIG_ACPI_NUMA extern int __node_distance(int, int); #define node_distance(a,b) __node_distance(a,b) -/* #else fallback version */ #endif -#define cpu_to_node(cpu) (cpu_to_node_map[cpu]) -#define parent_node(node) (node) -#define node_to_first_cpu(node) (first_cpu(node_to_cpumask_map[node])) -#define node_to_cpumask(node) (node_to_cpumask_map[node]) -#define pcibus_to_node(bus) ((struct pci_sysdata *)((bus)->sysdata))->node -#define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus)); +/* Returns the number of the node containing CPU 'cpu' */ +static inline int cpu_to_node(int cpu) +{ + return cpu_to_node_map[cpu]; +} + +/* + * Returns the number of the node containing Node 'node'. This + * architecture is flat, so it is a pretty simple function! + */ +#define parent_node(node) (node) + +/* Returns a bitmask of CPUs on Node 'node'. */ +static inline cpumask_t node_to_cpumask(int node) +{ + return node_to_cpumask_map[node]; +} + +/* Returns the number of the first CPU on Node 'node'. */ +static inline int node_to_first_cpu(int node) +{ + cpumask_t mask = node_to_cpumask(node); + + return first_cpu(mask); +} + +#define pcibus_to_node(bus) __pcibus_to_node(bus) +#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus) #define numa_node_id() read_pda(nodenumber) @@ -38,12 +58,12 @@ extern int __node_distance(int, int); .cache_nice_tries = 2, \ .busy_idx = 3, \ .idle_idx = 2, \ - .newidle_idx = 0, \ + .newidle_idx = 0, \ .wake_idx = 1, \ .forkexec_idx = 1, \ .flags = SD_LOAD_BALANCE \ - | SD_BALANCE_FORK \ | SD_BALANCE_EXEC \ + | SD_BALANCE_FORK \ | SD_SERIALIZE \ | SD_WAKE_BALANCE, \ .last_balance = jiffies, \ @@ -51,19 +71,21 @@ extern int __node_distance(int, int); .nr_balance_failed = 0, \ } +#else /* CONFIG_NUMA */ + +#include + #endif +extern cpumask_t cpu_coregroup_map(int cpu); + #ifdef CONFIG_SMP #define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) #define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) #define mc_capable() (boot_cpu_data.x86_max_cores > 1) -#define smt_capable() (smp_num_siblings > 1) +#define smt_capable() (smp_num_siblings > 1) #endif -#include - -extern cpumask_t cpu_coregroup_map(int cpu); - #endif -- cgit v1.2.2 From 3367e56f26a3a8647784328ffa846fe8021a5b79 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:38 +0100 Subject: x86: merge topology.h variants Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/topology.h | 143 +++++++++++++++++++++++++++++++++++++++++- include/asm-x86/topology_32.h | 116 ---------------------------------- include/asm-x86/topology_64.h | 91 --------------------------- 3 files changed, 141 insertions(+), 209 deletions(-) delete mode 100644 include/asm-x86/topology_32.h delete mode 100644 include/asm-x86/topology_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index b10fde9798e..9c251604ecc 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -1,5 +1,144 @@ +/* + * Written by: Matthew Dobson, IBM Corporation + * + * Copyright (C) 2002, IBM Corp. + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to + */ +#ifndef _ASM_X86_TOPOLOGY_H +#define _ASM_X86_TOPOLOGY_H + +#ifdef CONFIG_NUMA +#include +#include + +/* Mappings between logical cpu number and node number */ +extern int cpu_to_node_map[]; +extern cpumask_t node_to_cpumask_map[]; + +/* Returns the number of the node containing CPU 'cpu' */ +static inline int cpu_to_node(int cpu) +{ + return cpu_to_node_map[cpu]; +} + +/* + * Returns the number of the node containing Node 'node'. This + * architecture is flat, so it is a pretty simple function! + */ +#define parent_node(node) (node) + +/* Returns a bitmask of CPUs on Node 'node'. */ +static inline cpumask_t node_to_cpumask(int node) +{ + return node_to_cpumask_map[node]; +} + +/* Returns the number of the first CPU on Node 'node'. */ +static inline int node_to_first_cpu(int node) +{ + cpumask_t mask = node_to_cpumask(node); + + return first_cpu(mask); +} + +#define pcibus_to_node(bus) __pcibus_to_node(bus) +#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus) + #ifdef CONFIG_X86_32 -# include "topology_32.h" +extern unsigned long node_start_pfn[]; +extern unsigned long node_end_pfn[]; +extern unsigned long node_remap_size[]; +#define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid]) + +# ifdef CONFIG_X86_HT +# define ENABLE_TOPO_DEFINES +# endif + +# define SD_CACHE_NICE_TRIES 1 +# define SD_IDLE_IDX 1 +# define SD_NEWIDLE_IDX 2 +# define SD_FORKEXEC_IDX 0 + #else -# include "topology_64.h" + +# ifdef CONFIG_SMP +# define ENABLE_TOPO_DEFINES +# endif + +# define SD_CACHE_NICE_TRIES 2 +# define SD_IDLE_IDX 2 +# define SD_NEWIDLE_IDX 0 +# define SD_FORKEXEC_IDX 1 + +#endif + +/* sched_domains SD_NODE_INIT for NUMAQ machines */ +#define SD_NODE_INIT (struct sched_domain) { \ + .span = CPU_MASK_NONE, \ + .parent = NULL, \ + .child = NULL, \ + .groups = NULL, \ + .min_interval = 8, \ + .max_interval = 32, \ + .busy_factor = 32, \ + .imbalance_pct = 125, \ + .cache_nice_tries = SD_CACHE_NICE_TRIES, \ + .busy_idx = 3, \ + .idle_idx = SD_IDLE_IDX, \ + .newidle_idx = SD_NEWIDLE_IDX, \ + .wake_idx = 1, \ + .forkexec_idx = SD_FORKEXEC_IDX, \ + .flags = SD_LOAD_BALANCE \ + | SD_BALANCE_EXEC \ + | SD_BALANCE_FORK \ + | SD_SERIALIZE \ + | SD_WAKE_BALANCE, \ + .last_balance = jiffies, \ + .balance_interval = 1, \ + .nr_balance_failed = 0, \ +} + +#ifdef CONFIG_X86_64_ACPI_NUMA +extern int __node_distance(int, int); +#define node_distance(a, b) __node_distance(a, b) +#endif + +#else /* CONFIG_NUMA */ + +#include + +#endif + +extern cpumask_t cpu_coregroup_map(int cpu); + +#ifdef ENABLE_TOPO_DEFINES +#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) +#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) +#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) +#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) +#endif + +#ifdef CONFIG_SMP +#define mc_capable() (boot_cpu_data.x86_max_cores > 1) +#define smt_capable() (smp_num_siblings > 1) +#endif + #endif diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h deleted file mode 100644 index 35b00067587..00000000000 --- a/include/asm-x86/topology_32.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Written by: Matthew Dobson, IBM Corporation - * - * Copyright (C) 2002, IBM Corp. - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to - */ -#ifndef _ASM_X86_TOPOLOGY_H -#define _ASM_X86_TOPOLOGY_H - -#ifdef CONFIG_NUMA -#include -#include - -/* Mappings between logical cpu number and node number */ -extern int cpu_to_node_map[]; -extern cpumask_t node_to_cpumask_map[]; - -/* Returns the number of the node containing CPU 'cpu' */ -static inline int cpu_to_node(int cpu) -{ - return cpu_to_node_map[cpu]; -} - -/* - * Returns the number of the node containing Node 'node'. This - * architecture is flat, so it is a pretty simple function! - */ -#define parent_node(node) (node) - -/* Returns a bitmask of CPUs on Node 'node'. */ -static inline cpumask_t node_to_cpumask(int node) -{ - return node_to_cpumask_map[node]; -} - -/* Returns the number of the first CPU on Node 'node'. */ -static inline int node_to_first_cpu(int node) -{ - cpumask_t mask = node_to_cpumask(node); - - return first_cpu(mask); -} - -#define pcibus_to_node(bus) __pcibus_to_node(bus) -#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus) - -/* sched_domains SD_NODE_INIT for NUMAQ machines */ -#define SD_NODE_INIT (struct sched_domain) { \ - .span = CPU_MASK_NONE, \ - .parent = NULL, \ - .child = NULL, \ - .groups = NULL, \ - .min_interval = 8, \ - .max_interval = 32, \ - .busy_factor = 32, \ - .imbalance_pct = 125, \ - .cache_nice_tries = 1, \ - .busy_idx = 3, \ - .idle_idx = 1, \ - .newidle_idx = 2, \ - .wake_idx = 1, \ - .flags = SD_LOAD_BALANCE \ - | SD_BALANCE_EXEC \ - | SD_BALANCE_FORK \ - | SD_SERIALIZE \ - | SD_WAKE_BALANCE, \ - .last_balance = jiffies, \ - .balance_interval = 1, \ - .nr_balance_failed = 0, \ -} - -extern unsigned long node_start_pfn[]; -extern unsigned long node_end_pfn[]; -extern unsigned long node_remap_size[]; - -#define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid]) - -#else /* CONFIG_NUMA */ - -#include - -#endif - -extern cpumask_t cpu_coregroup_map(int cpu); - -#ifdef CONFIG_X86_HT -#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) -#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) -#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) -#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) -#endif - -#ifdef CONFIG_SMP -#define mc_capable() (boot_cpu_data.x86_max_cores > 1) -#define smt_capable() (smp_num_siblings > 1) -#endif - -#endif diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h deleted file mode 100644 index 93de948bd33..00000000000 --- a/include/asm-x86/topology_64.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _ASM_X86_TOPOLOGY_H -#define _ASM_X86_TOPOLOGY_H - -#ifdef CONFIG_NUMA -#include -#include - -/* Mappings between logical cpu number and node number */ -extern int cpu_to_node_map[]; -extern cpumask_t node_to_cpumask_map[]; - -#ifdef CONFIG_ACPI_NUMA -extern int __node_distance(int, int); -#define node_distance(a,b) __node_distance(a,b) -#endif - -/* Returns the number of the node containing CPU 'cpu' */ -static inline int cpu_to_node(int cpu) -{ - return cpu_to_node_map[cpu]; -} - -/* - * Returns the number of the node containing Node 'node'. This - * architecture is flat, so it is a pretty simple function! - */ -#define parent_node(node) (node) - -/* Returns a bitmask of CPUs on Node 'node'. */ -static inline cpumask_t node_to_cpumask(int node) -{ - return node_to_cpumask_map[node]; -} - -/* Returns the number of the first CPU on Node 'node'. */ -static inline int node_to_first_cpu(int node) -{ - cpumask_t mask = node_to_cpumask(node); - - return first_cpu(mask); -} - -#define pcibus_to_node(bus) __pcibus_to_node(bus) -#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus) - -#define numa_node_id() read_pda(nodenumber) - -/* sched_domains SD_NODE_INIT for x86_64 machines */ -#define SD_NODE_INIT (struct sched_domain) { \ - .span = CPU_MASK_NONE, \ - .parent = NULL, \ - .child = NULL, \ - .groups = NULL, \ - .min_interval = 8, \ - .max_interval = 32, \ - .busy_factor = 32, \ - .imbalance_pct = 125, \ - .cache_nice_tries = 2, \ - .busy_idx = 3, \ - .idle_idx = 2, \ - .newidle_idx = 0, \ - .wake_idx = 1, \ - .forkexec_idx = 1, \ - .flags = SD_LOAD_BALANCE \ - | SD_BALANCE_EXEC \ - | SD_BALANCE_FORK \ - | SD_SERIALIZE \ - | SD_WAKE_BALANCE, \ - .last_balance = jiffies, \ - .balance_interval = 1, \ - .nr_balance_failed = 0, \ -} - -#else /* CONFIG_NUMA */ - -#include - -#endif - -extern cpumask_t cpu_coregroup_map(int cpu); - -#ifdef CONFIG_SMP -#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) -#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) -#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) -#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) -#define mc_capable() (boot_cpu_data.x86_max_cores > 1) -#define smt_capable() (smp_num_siblings > 1) -#endif - -#endif -- cgit v1.2.2 From 3578facf737dc9a60ed19a83458bd9cfdc2af233 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:38 +0100 Subject: x86: merge resume-trace.h variants Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/asm.h | 2 ++ include/asm-x86/resume-trace.h | 23 +++++++++++++++++++---- include/asm-x86/resume-trace_32.h | 13 ------------- include/asm-x86/resume-trace_64.h | 13 ------------- 4 files changed, 21 insertions(+), 30 deletions(-) delete mode 100644 include/asm-x86/resume-trace_32.h delete mode 100644 include/asm-x86/resume-trace_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/asm.h b/include/asm-x86/asm.h index b5006eb9acb..8661ae75488 100644 --- a/include/asm-x86/asm.h +++ b/include/asm-x86/asm.h @@ -6,12 +6,14 @@ # define _ASM_PTR " .long " # define _ASM_ALIGN " .balign 4 " +# define _ASM_MOV_UL " movl " #else /* 64 bits */ # define _ASM_PTR " .quad " # define _ASM_ALIGN " .balign 8 " +# define _ASM_MOV_UL " movq " #endif /* CONFIG_X86_32 */ diff --git a/include/asm-x86/resume-trace.h b/include/asm-x86/resume-trace.h index 9b6dd093a9f..46f725b0bc8 100644 --- a/include/asm-x86/resume-trace.h +++ b/include/asm-x86/resume-trace.h @@ -1,5 +1,20 @@ -#ifdef CONFIG_X86_32 -# include "resume-trace_32.h" -#else -# include "resume-trace_64.h" +#ifndef _ASM_X86_RESUME_TRACE_H +#define _ASM_X86_RESUME_TRACE_H + +#include + +#define TRACE_RESUME(user) do { \ + if (pm_trace_enabled) { \ + void *tracedata; \ + asm volatile(_ASM_MOV_UL " $1f,%0\n" \ + ".section .tracedata,\"a\"\n" \ + "1:\t.word %c1\n\t" \ + _ASM_PTR " %c2\n" \ + ".previous" \ + :"=r" (tracedata) \ + : "i" (__LINE__), "i" (__FILE__)); \ + generate_resume_trace(tracedata, user); \ + } \ +} while (0) + #endif diff --git a/include/asm-x86/resume-trace_32.h b/include/asm-x86/resume-trace_32.h deleted file mode 100644 index ec9cfd65623..00000000000 --- a/include/asm-x86/resume-trace_32.h +++ /dev/null @@ -1,13 +0,0 @@ -#define TRACE_RESUME(user) do { \ - if (pm_trace_enabled) { \ - void *tracedata; \ - asm volatile("movl $1f,%0\n" \ - ".section .tracedata,\"a\"\n" \ - "1:\t.word %c1\n" \ - "\t.long %c2\n" \ - ".previous" \ - :"=r" (tracedata) \ - : "i" (__LINE__), "i" (__FILE__)); \ - generate_resume_trace(tracedata, user); \ - } \ -} while (0) diff --git a/include/asm-x86/resume-trace_64.h b/include/asm-x86/resume-trace_64.h deleted file mode 100644 index 34bf998fdf6..00000000000 --- a/include/asm-x86/resume-trace_64.h +++ /dev/null @@ -1,13 +0,0 @@ -#define TRACE_RESUME(user) do { \ - if (pm_trace_enabled) { \ - void *tracedata; \ - asm volatile("movq $1f,%0\n" \ - ".section .tracedata,\"a\"\n" \ - "1:\t.word %c1\n" \ - "\t.quad %c2\n" \ - ".previous" \ - :"=r" (tracedata) \ - : "i" (__LINE__), "i" (__FILE__)); \ - generate_resume_trace(tracedata, user); \ - } \ -} while (0) -- cgit v1.2.2 From 1c69524c2e5b83e52a098ebdeb4a8b52169f6a03 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 30 Jan 2008 13:30:39 +0100 Subject: x86: clear IO_APIC before enabing apic error vector. 4 socket quad core, 8 socket quad core will do apic ID lifting for BSP. But io-apic regs for ExtINT still use 0 as dest. so when we enable apic error vector in BSP, we will get one APIC error. CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line) CPU: L2 Cache: 512K (64 bytes/line) CPU 0/4 -> Node 0 CPU: Physical Processor ID: 1 CPU: Processor Core ID: 0 SMP alternatives: switching to UP code ACPI: Core revision 20070126 enabled ExtINT on CPU#0 ESR value after enabling vector: 00000000, after 0000000c APIC error on CPU0: 0c(08) ENABLING IO-APIC IRQs Synchronizing Arb IDs. So move enable_IO_APIC from setup_IO_APIC into setup_local_APIC and call it before enabling the ACPI error vector. [ tglx: arch/x86 adaptation ] Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/hw_irq_64.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/hw_irq_64.h b/include/asm-x86/hw_irq_64.h index a470d59da67..a346159b6ac 100644 --- a/include/asm-x86/hw_irq_64.h +++ b/include/asm-x86/hw_irq_64.h @@ -135,6 +135,7 @@ extern void init_8259A(int aeoi); extern void send_IPI_self(int vector); extern void init_VISWS_APIC_irqs(void); extern void setup_IO_APIC(void); +extern void enable_IO_APIC(void); extern void disable_IO_APIC(void); extern void print_IO_APIC(void); extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); -- cgit v1.2.2 From a860b63c41f241c685245127a3d32f352cb04c12 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 30 Jan 2008 13:30:39 +0100 Subject: x86: store core id bits in cpuinfo_x8 We need to store core id bits to cpuinfo_x86 in early_identify_cpu. So we use it to create acpiid_to_node array in k8topolgy.c Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen Cc: Christoph Lameter Cc: Andi Kleen Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_64.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 6c0d96a7af6..2ae8ceb8a74 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -61,6 +61,7 @@ struct cpuinfo_x86 { int x86_tlbsize; /* number of 4K pages in DTLB/ITLB combined(in pages)*/ __u8 x86_virt_bits, x86_phys_bits; __u8 x86_max_cores; /* cpuid returned max cores value */ + __u8 x86_coreid_bits; /* cpuid returned core id bits */ __u32 x86_power; __u32 extended_cpuid_level; /* Max extended CPUID function supported */ unsigned long loops_per_jiffy; -- cgit v1.2.2 From 739f33b38bf88312447e38ae8b7ac3acdbb72a6b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:30:40 +0100 Subject: x86: untable __init references between IO data Earlier patch added IO APIC setup into local APIC setup. This caused modpost warnings. Fix them by untangling setup_local_APIC() and splitting it into smaller functions. The IO APIC initialization is only called for the BP init. Also removed some outdated debugging code and minor cleanup. [ tglx: arch/x86 adaptation ] Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/apic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 18d932dff47..5e8192d36e5 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -112,6 +112,7 @@ extern void cache_APIC_registers(void); extern void sync_Arb_IDs(void); extern void init_bsp_APIC(void); extern void setup_local_APIC(void); +extern void end_local_APIC_setup(void); extern void init_apic_mappings(void); extern void setup_boot_APIC_clock(void); extern void setup_secondary_APIC_clock(void); -- cgit v1.2.2 From 7b83dae7aa31db4f6d6e78c3c6d490a7ac58699c Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 30 Jan 2008 13:30:40 +0100 Subject: x86: extended interrupt LVT support for AMD Barcelona Also macro definitions in apicdef.h has been updated. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/apic.h | 4 ++-- include/asm-x86/apicdef.h | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 5e8192d36e5..423022759cb 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -126,8 +126,8 @@ extern void enable_NMI_through_LVT0(void *dummy); extern void setup_apic_routing(void); #endif -extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, - unsigned char msg_type, unsigned char mask); +extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask); +extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask); extern int apic_is_clustered_box(void); diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h index 5f7abe9b5f8..550af7a6f88 100644 --- a/include/asm-x86/apicdef.h +++ b/include/asm-x86/apicdef.h @@ -116,13 +116,18 @@ #define APIC_TDR_DIV_32 0x8 #define APIC_TDR_DIV_64 0x9 #define APIC_TDR_DIV_128 0xA - -#define K8_APIC_EXT_LVT_BASE 0x500 -#define K8_APIC_EXT_INT_MSG_FIX 0x0 -#define K8_APIC_EXT_INT_MSG_SMI 0x2 -#define K8_APIC_EXT_INT_MSG_NMI 0x4 -#define K8_APIC_EXT_INT_MSG_EXT 0x7 -#define K8_APIC_EXT_LVT_ENTRY_THRESHOLD 0 +#define APIC_EILVT0 0x500 +#define APIC_EILVT_NR_AMD_K8 1 /* Number of extended interrupts */ +#define APIC_EILVT_NR_AMD_10H 4 +#define APIC_EILVT_LVTOFF(x) (((x)>>4)&0xF) +#define APIC_EILVT_MSG_FIX 0x0 +#define APIC_EILVT_MSG_SMI 0x2 +#define APIC_EILVT_MSG_NMI 0x4 +#define APIC_EILVT_MSG_EXT 0x7 +#define APIC_EILVT_MASKED (1<<16) +#define APIC_EILVT1 0x510 +#define APIC_EILVT2 0x520 +#define APIC_EILVT3 0x530 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) -- cgit v1.2.2 From c1d171a002942ea2d93b4fbd0c9583c56fce0772 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 30 Jan 2008 13:30:40 +0100 Subject: x86: randomize brk Randomize the location of the heap (brk) for i386 and x86_64. The range is randomized in the range starting at current brk location up to 0x02000000 offset for both architectures. This, together with pie-executable-randomization.patch and pie-executable-randomization-fix.patch, should make the address space randomization on i386 and x86_64 complete. Arjan says: This is known to break older versions of some emacs variants, whose dumper code assumed that the last variable declared in the program is equal to the start of the dynamically allocated memory region. (The dumper is the code where emacs effectively dumps core at the end of it's compilation stage; this coredump is then loaded as the main program during normal use) iirc this was 5 years or so; we found this way back when I was at RH and we first did the security stuff there (including this brk randomization). It wasn't all variants of emacs, and it got fixed as a result (I vaguely remember that emacs already had code to deal with it for other archs/oses, just ifdeffed wrongly). It's a rare and wrong assumption as a general thing, just on x86 it mostly happened to be true (but to be honest, it'll break too if gcc does something fancy or if the linker does a non-standard order). Still its something we should at least document. Note 2: afaik it only broke the emacs *build*. I'm not 100% sure about that (it IS 5 years ago) though. [ akpm@linux-foundation.org: deuglification ] Signed-off-by: Jiri Kosina Cc: Arjan van de Ven Cc: Roland McGrath Cc: Jakub Jelinek Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/elf.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index ec42a4d2e83..cd3204ebbbd 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -285,6 +285,9 @@ struct linux_binprm; extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); +extern unsigned long arch_randomize_brk(struct mm_struct *mm); +#define arch_randomize_brk arch_randomize_brk + #endif /* __KERNEL__ */ #endif -- cgit v1.2.2 From 7f3646aa16f496201e045183402c6614fa27b0c7 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:41 +0100 Subject: x86 vDSO: use vdso-syms.lds This patch changes the kernel's references to addresses in the vDSO image to be based on the symbols defined by vdso-syms.lds instead of the old vdso-syms.o symbols. This is all wrapped up in a macro defined by the new asm-x86/vdso.h header; that's the only place in the kernel source that has to know the details of the scheme for getting vDSO symbol values. Signed-off-by: Roland McGrath Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/vdso.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 include/asm-x86/vdso.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/vdso.h b/include/asm-x86/vdso.h new file mode 100644 index 00000000000..9379ec06fd1 --- /dev/null +++ b/include/asm-x86/vdso.h @@ -0,0 +1,14 @@ +#ifndef _ASM_X86_VDSO_H +#define _ASM_X86_VDSO_H 1 + +extern const char VDSO64_PRELINK[]; + +/* + * Given a pointer to the vDSO image, find the pointer to VDSO64_name + * as that symbol is defined in the vDSO sources or linker script. + */ +#define VDSO64_SYMBOL(base, name) ({ \ + extern const char VDSO64_##name[]; \ + (void *) (VDSO64_##name - VDSO64_PRELINK + (unsigned long) (base)); }) + +#endif /* asm-x86/vdso.h */ -- cgit v1.2.2 From 6c3652efcafa6a6d795093362cb4290c84994b5c Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:42 +0100 Subject: x86 vDSO: i386 vdso32 This makes the i386 kernel use the new vDSO build in arch/x86/vdso/vdso32/ to replace the old one from arch/x86/kernel/. Signed-off-by: Roland McGrath Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/elf.h | 13 +++---------- include/asm-x86/vdso.h | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index cd3204ebbbd..70edff2d567 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -78,6 +78,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t; #include #include /* for savesegment */ #include +#include /* * This is used to ensure we don't load something for the wrong architecture. @@ -247,17 +248,9 @@ extern int dump_task_extended_fpu (struct task_struct *, #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) #define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) -#define VDSO_PRELINK 0 -#define VDSO_SYM(x) \ - (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_CURRENT_BASE) - -extern void __kernel_vsyscall; - -#define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) +#define VDSO_ENTRY \ + ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall)) /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ diff --git a/include/asm-x86/vdso.h b/include/asm-x86/vdso.h index 9379ec06fd1..629bcb6e8e4 100644 --- a/include/asm-x86/vdso.h +++ b/include/asm-x86/vdso.h @@ -1,6 +1,7 @@ #ifndef _ASM_X86_VDSO_H #define _ASM_X86_VDSO_H 1 +#ifdef CONFIG_X86_64 extern const char VDSO64_PRELINK[]; /* @@ -10,5 +11,18 @@ extern const char VDSO64_PRELINK[]; #define VDSO64_SYMBOL(base, name) ({ \ extern const char VDSO64_##name[]; \ (void *) (VDSO64_##name - VDSO64_PRELINK + (unsigned long) (base)); }) +#endif + +#if defined CONFIG_X86_32 || defined CONFIG_COMPAT +extern const char VDSO32_PRELINK[]; + +/* + * Given a pointer to the vDSO image, find the pointer to VDSO32_name + * as that symbol is defined in the vDSO sources or linker script. + */ +#define VDSO32_SYMBOL(base, name) ({ \ + extern const char VDSO32_##name[]; \ + (void *) (VDSO32_##name - VDSO32_PRELINK + (unsigned long) (base)); }) +#endif #endif /* asm-x86/vdso.h */ -- cgit v1.2.2 From 36197c92a20c142fc2a068e0366053d770fa0096 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:43 +0100 Subject: x86 vDSO: ia32 sysenter_return This changes the 64-bit kernel's support for the 32-bit sysenter instruction to use stored fields rather than constants for the user-mode return address, as the 32-bit kernel does. This adds a sysenter_return field to struct thread_info, as 32-bit has. There is no observable effect from this yet. It makes the assembly code independent of the 32-bit vDSO mapping address, paving the way for making the vDSO address vary as it does on the 32-bit kernel. [ akpm@linux-foundation.org: build fix on !CONFIG_IA32_EMULATION ] Signed-off-by: Roland McGrath Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/thread_info_64.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h index 1ac23c15723..c8e7736fc79 100644 --- a/include/asm-x86/thread_info_64.h +++ b/include/asm-x86/thread_info_64.h @@ -33,6 +33,9 @@ struct thread_info { mm_segment_t addr_limit; struct restart_block restart_block; +#ifdef CONFIG_IA32_EMULATION + void __user *sysenter_return; +#endif }; #endif -- cgit v1.2.2 From af65d64845a90c8f2fc90b97e2148ff74672e979 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:43 +0100 Subject: x86 vDSO: consolidate vdso32 This makes x86_64's ia32 emulation support share the sources used in the 32-bit kernel for the 32-bit vDSO and much of its setup code. The 32-bit vDSO mapping now behaves the same on x86_64 as on native 32-bit. The abi.syscall32 sysctl on x86_64 now takes the same values that vm.vdso_enabled takes on the 32-bit kernel. That is, 1 means a randomized vDSO location, 2 means the fixed old address. The CONFIG_COMPAT_VDSO option is now available to make this the default setting, the same meaning it has for the 32-bit kernel. (This does not affect the 64-bit vDSO.) The argument vdso32=[012] can be used on both 32-bit and 64-bit kernels to set this paramter at boot time. The vdso=[012] argument still does this same thing on the 32-bit kernel. Signed-off-by: Roland McGrath Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/elf.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index 70edff2d567..60f5101d948 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -74,17 +74,19 @@ typedef struct user_fxsr_struct elf_fpxregset_t; #ifdef __KERNEL__ +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch_ia32(x) \ + (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) + #ifdef CONFIG_X86_32 #include #include /* for savesegment */ #include #include -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) +#define elf_check_arch(x) elf_check_arch_ia32(x) /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx contains a pointer to a function which might be registered using `atexit'. @@ -247,10 +249,6 @@ extern int dump_task_extended_fpu (struct task_struct *, #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) - -#define VDSO_ENTRY \ - ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall)) /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ @@ -262,6 +260,8 @@ do if (vdso_enabled) { \ #else /* CONFIG_X86_32 */ +#define VDSO_HIGH_BASE 0xffffe000U /* CONFIG_COMPAT_VDSO address */ + /* 1GB for 64bit, 8MB for 32bit */ #define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff) @@ -272,6 +272,11 @@ do if (vdso_enabled) { \ #endif /* !CONFIG_X86_32 */ +#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) + +#define VDSO_ENTRY \ + ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall)) + struct linux_binprm; #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 -- cgit v1.2.2 From 16f4bc738d616962a844e80f7b1fcb52c626542a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:44 +0100 Subject: x86 vDSO: ia32 vsyscall removal This removes all the old vsyscall code from arch/x86/ia32/ that is no longer used because arch/x86/vdso/ code has replaced it. Signed-off-by: Roland McGrath Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/Kbuild | 1 - include/asm-x86/vsyscall32.h | 20 -------------------- 2 files changed, 21 deletions(-) delete mode 100644 include/asm-x86/vsyscall32.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild index 12db5a1cdd7..22e3a284c1e 100644 --- a/include/asm-x86/Kbuild +++ b/include/asm-x86/Kbuild @@ -9,7 +9,6 @@ header-y += prctl.h header-y += ptrace-abi.h header-y += sigcontext32.h header-y += ucontext.h -header-y += vsyscall32.h unifdef-y += e820.h unifdef-y += ist.h diff --git a/include/asm-x86/vsyscall32.h b/include/asm-x86/vsyscall32.h deleted file mode 100644 index c631c082f8f..00000000000 --- a/include/asm-x86/vsyscall32.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ASM_VSYSCALL32_H -#define _ASM_VSYSCALL32_H 1 - -/* Values need to match arch/x86_64/ia32/vsyscall.lds */ - -#ifdef __ASSEMBLY__ -#define VSYSCALL32_BASE 0xffffe000 -#define VSYSCALL32_SYSEXIT (VSYSCALL32_BASE + 0x410) -#else -#define VSYSCALL32_BASE 0xffffe000UL -#define VSYSCALL32_END (VSYSCALL32_BASE + PAGE_SIZE) -#define VSYSCALL32_EHDR ((const struct elf32_hdr *) VSYSCALL32_BASE) - -#define VSYSCALL32_VSYSCALL ((void *)VSYSCALL32_BASE + 0x400) -#define VSYSCALL32_SYSEXIT ((void *)VSYSCALL32_BASE + 0x410) -#define VSYSCALL32_SIGRETURN ((void __user *)VSYSCALL32_BASE + 0x500) -#define VSYSCALL32_RTSIGRETURN ((void __user *)VSYSCALL32_BASE + 0x600) -#endif - -#endif -- cgit v1.2.2 From 859c0a5b9ca8eba2d65fa42f02505d76f8a712c7 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:44 +0100 Subject: x86: get_desc_base This defines the get_desc_base function in asm-x86/desc_64.h to match the one in desc_32.h. If these two files ever get merged together, this function could be the same in both. Signed-off-by: Roland McGrath Cc: Andrew Morton Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_64.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 7d48df72aef..230ac6e50a0 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -215,6 +215,16 @@ static inline void load_LDT(mm_context_t *pc) extern struct desc_ptr idt_descr; +static inline unsigned long get_desc_base(const void *ptr) +{ + const u32 *desc = ptr; + unsigned long base; + base = ((desc[0] >> 16) & 0x0000ffff) | + ((desc[1] << 16) & 0x00ff0000) | + (desc[1] & 0xff000000); + return base; +} + #endif /* !__ASSEMBLY__ */ #endif -- cgit v1.2.2 From 12c3cbbb7e3218b1c3ed4c97b3496fc3f94ea967 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:45 +0100 Subject: x86: desc_empty This replaces the desc_empty macro with an inline. It now handles easily any of the four different types used between 32/64 code to refer to these 8 bytes. It's identical in both asm-x86/processor_64.h and asm-x86/processor_32.h, so if these files ever get merged this function can be in the common code. This also removes the desc_equal macro because nothing uses it. Signed-off-by: Roland McGrath Cc: Andrew Morton Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_32.h | 9 +++++---- include/asm-x86/processor_64.h | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 3b51a18f16d..2540bf8d572 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -28,11 +28,12 @@ struct desc_struct { unsigned long a,b; }; -#define desc_empty(desc) \ - (!((desc)->a | (desc)->b)) +static inline int desc_empty(const void *ptr) +{ + const u32 *desc = ptr; + return !(desc[0] | desc[1]); +} -#define desc_equal(desc1, desc2) \ - (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b)) /* * Default implementation of macro that returns current * instruction pointer ("program counter"). diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 2ae8ceb8a74..20d8935d141 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -30,11 +30,11 @@ #define VIP_MASK 0x00100000 /* virtual interrupt pending */ #define ID_MASK 0x00200000 -#define desc_empty(desc) \ - (!((desc)->a | (desc)->b)) - -#define desc_equal(desc1, desc2) \ - (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b)) +static inline int desc_empty(const void *ptr) +{ + const u32 *desc = ptr; + return !(desc[0] | desc[1]); +} /* * Default implementation of macro that returns current -- cgit v1.2.2 From efd1ca52d04d2f6df337a3332cee56cd60e6d4c4 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:46 +0100 Subject: x86: TLS cleanup This consolidates the four different places that implemented the same encoding magic for the GDT-slot 32-bit TLS support. The old tls32.c was renamed and is now only slightly modified to be the shared implementation. Signed-off-by: Roland McGrath Cc: Andrew Morton Cc: Zachary Amsden Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ia32.h | 6 ------ include/asm-x86/ptrace.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ia32.h b/include/asm-x86/ia32.h index 0190b7c4e31..aa9733206e2 100644 --- a/include/asm-x86/ia32.h +++ b/include/asm-x86/ia32.h @@ -159,12 +159,6 @@ struct ustat32 { #define IA32_STACK_TOP IA32_PAGE_OFFSET #ifdef __KERNEL__ -struct user_desc; -struct siginfo_t; -int do_get_thread_area(struct thread_struct *t, struct user_desc __user *info); -int do_set_thread_area(struct thread_struct *t, struct user_desc __user *info); -int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs); - struct linux_binprm; extern int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int exec_stack); diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 51ddb259087..105d1534eaf 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -137,6 +137,17 @@ enum { }; #endif /* __KERNEL__ */ #endif /* !__i386__ */ + +#ifdef __KERNEL__ + +struct user_desc; +extern int do_get_thread_area(struct task_struct *p, int idx, + struct user_desc __user *info); +extern int do_set_thread_area(struct task_struct *p, int idx, + struct user_desc __user *info, int can_allocate); + +#endif /* __KERNEL__ */ + #endif /* !__ASSEMBLY__ */ #endif -- cgit v1.2.2 From b263295dbffd33b0fbff670720fa178c30e3392a Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 30 Jan 2008 13:30:47 +0100 Subject: x86: 64-bit, make sparsemem vmemmap the only memory model Use sparsemem as the only memory model for UP, SMP and NUMA. Measurements indicate that DISCONTIGMEM has a higher overhead than sparsemem. And FLATMEMs benefits are minimal. So I think its best to simply standardize on sparsemem. Results of page allocator tests (test can be had via git from slab git tree branch tests) Measurements in cycle counts. 1000 allocations were performed and then the average cycle count was calculated. Order FlatMem Discontig SparseMem 0 639 665 641 1 567 647 593 2 679 774 692 3 763 967 781 4 961 1501 962 5 1356 2344 1392 6 2224 3982 2336 7 4869 7225 5074 8 12500 14048 12732 9 27926 28223 28165 10 58578 58714 58682 (Note that FlatMem is an SMP config and the rest NUMA configurations) Memory use: SMP Sparsemem ------------- Kernel size: text data bss dec hex filename 3849268 397739 1264856 5511863 541ab7 vmlinux total used free shared buffers cached Mem: 8242252 41164 8201088 0 352 11512 -/+ buffers/cache: 29300 8212952 Swap: 9775512 0 9775512 SMP Flatmem ----------- Kernel size: text data bss dec hex filename 3844612 397739 1264536 5506887 540747 vmlinux So 4.5k growth in text size vs. FLATMEM. total used free shared buffers cached Mem: 8244052 40544 8203508 0 352 11484 -/+ buffers/cache: 28708 8215344 2k growth in overall memory use after boot. NUMA discontig: text data bss dec hex filename 3888124 470659 1276504 5635287 55fcd7 vmlinux total used free shared buffers cached Mem: 8256256 56908 8199348 0 352 11496 -/+ buffers/cache: 45060 8211196 Swap: 9775512 0 9775512 NUMA sparse: text data bss dec hex filename 3896428 470659 1276824 5643911 561e87 vmlinux 8k text growth. Given that we fully inline virt_to_page and friends now that is rather good. total used free shared buffers cached Mem: 8264720 57240 8207480 0 352 11516 -/+ buffers/cache: 45372 8219348 Swap: 9775512 0 9775512 The total available memory is increased by 8k. This patch makes sparsemem the default and removes discontig and flatmem support from x86. [ akpm@linux-foundation.org: allnoconfig build fix ] Acked-by: Andi Kleen Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mmzone_64.h | 6 ------ include/asm-x86/page_64.h | 3 --- 2 files changed, 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mmzone_64.h b/include/asm-x86/mmzone_64.h index 1e0ed34a6ad..b0c25ae111d 100644 --- a/include/asm-x86/mmzone_64.h +++ b/include/asm-x86/mmzone_64.h @@ -43,12 +43,6 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) extern int early_pfn_to_nid(unsigned long pfn); -#ifdef CONFIG_DISCONTIGMEM -#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT) - -extern int pfn_valid(unsigned long pfn); -#endif - #ifdef CONFIG_NUMA_EMU #define FAKE_NODE_MIN_SIZE (64*1024*1024) #define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1uL)) diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index 6fdc904a5fa..d400167c550 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -122,9 +122,6 @@ extern unsigned long __phys_addr(unsigned long); #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #define __boot_va(x) __va(x) #define __boot_pa(x) __pa(x) -#ifdef CONFIG_FLATMEM -#define pfn_valid(pfn) ((pfn) < end_pfn) -#endif #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -- cgit v1.2.2 From 2c0b8a7578f7653e1e5312a5232e8ead563cf477 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 30 Jan 2008 13:30:47 +0100 Subject: x86: fall back on interrupt disable in cmpxchg8b on 80386 and 80486 Actually, on 386, cmpxchg and cmpxchg_local fall back on cmpxchg_386_u8/16/32: it disables interruptions around non atomic updates to mimic the cmpxchg behavior. The comment: /* Poor man's cmpxchg for 386. Unsuitable for SMP */ already present in cmpxchg_386_u32 tells much about how this cmpxchg implementation should not be used in a SMP context. However, the cmpxchg_local can perfectly use this fallback, since it only needs to be atomic wrt the local cpu. This patch adds a cmpxchg_486_u64 and uses it as a fallback for cmpxchg64 and cmpxchg64_local on 80386 and 80486. Q: but why is it called cmpxchg_486 when the other functions are called A: Because the standard cmpxchg is missing only on 386, but cmpxchg8b is missing both on 386 and 486. Citing Intel's Instruction set reference: cmpxchg: This instruction is not supported on Intel processors earlier than the Intel486 processors. cmpxchg8b: This instruction encoding is not supported on Intel processors earlier than the Pentium processors. Q: What's the reason to have cmpxchg64_local on 32 bit architectures? Without that need all this would just be a few simple defines. A: cmpxchg64_local on 32 bits architectures takes unsigned long long parameters, but cmpxchg_local only takes longs. Since we have cmpxchg8b to execute a 8 byte cmpxchg atomically on pentium and +, it makes sense to provide a flavor of cmpxchg and cmpxchg_local using this instruction. Also, for 32 bits architectures lacking the 64 bits atomic cmpxchg, it makes sense _not_ to define cmpxchg64 while cmpxchg could still be available. Moreover, the fallback for cmpxchg8b on i386 for 386 and 486 is a However, cmpxchg64_local will be emulated by disabling interrupts on all architectures where it is not supported atomically. Therefore, we *could* turn cmpxchg64_local into a cmpxchg_local, but it would make the 386/486 fallbacks ugly, make its design different from cmpxchg/cmpxchg64 (which really depends on atomic operations and cannot be emulated) and require the __cmpxchg_local to be expressed as a macro rather than an inline function so the parameters would not be fixed to unsigned long long in every case. So I think cmpxchg64_local makes sense there, but I am open to suggestions. Q: Are there any callers? A: I am actually using it in LTTng in my timestamping code. I use it to work around CPUs with asynchronous TSCs. I need to update 64 bits values atomically on this 32 bits architecture. Changelog: - Ran though checkpatch. Signed-off-by: Mathieu Desnoyers Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cmpxchg_32.h | 122 ++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 43 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cmpxchg_32.h b/include/asm-x86/cmpxchg_32.h index f86ede28f6d..cea1dae288a 100644 --- a/include/asm-x86/cmpxchg_32.h +++ b/include/asm-x86/cmpxchg_32.h @@ -105,15 +105,24 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz #ifdef CONFIG_X86_CMPXCHG #define __HAVE_ARCH_CMPXCHG 1 -#define cmpxchg(ptr,o,n)\ - ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ - (unsigned long)(n),sizeof(*(ptr)))) -#define sync_cmpxchg(ptr,o,n)\ - ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\ - (unsigned long)(n),sizeof(*(ptr)))) -#define cmpxchg_local(ptr,o,n)\ - ((__typeof__(*(ptr)))__cmpxchg_local((ptr),(unsigned long)(o),\ - (unsigned long)(n),sizeof(*(ptr)))) +#define cmpxchg(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) +#define sync_cmpxchg(ptr, o, n) \ + ((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) +#endif + +#ifdef CONFIG_X86_CMPXCHG64 +#define cmpxchg64(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg64((ptr), (unsigned long long)(o), \ + (unsigned long long)(n))) +#define cmpxchg64_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg64_local((ptr), (unsigned long long)(o),\ + (unsigned long long)(n))) #endif static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, @@ -203,6 +212,34 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, return old; } +static inline unsigned long long __cmpxchg64(volatile void *ptr, + unsigned long long old, unsigned long long new) +{ + unsigned long long prev; + __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3" + : "=A"(prev) + : "b"((unsigned long)new), + "c"((unsigned long)(new >> 32)), + "m"(*__xg(ptr)), + "0"(old) + : "memory"); + return prev; +} + +static inline unsigned long long __cmpxchg64_local(volatile void *ptr, + unsigned long long old, unsigned long long new) +{ + unsigned long long prev; + __asm__ __volatile__("cmpxchg8b %3" + : "=A"(prev) + : "b"((unsigned long)new), + "c"((unsigned long)(new >> 32)), + "m"(*__xg(ptr)), + "0"(old) + : "memory"); + return prev; +} + #ifndef CONFIG_X86_CMPXCHG /* * Building a kernel capable running on 80386. It may be necessary to @@ -228,7 +265,7 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old, return old; } -#define cmpxchg(ptr,o,n) \ +#define cmpxchg(ptr, o, n) \ ({ \ __typeof__(*(ptr)) __ret; \ if (likely(boot_cpu_data.x86 > 3)) \ @@ -239,7 +276,7 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old, (unsigned long)(n), sizeof(*(ptr))); \ __ret; \ }) -#define cmpxchg_local(ptr,o,n) \ +#define cmpxchg_local(ptr, o, n) \ ({ \ __typeof__(*(ptr)) __ret; \ if (likely(boot_cpu_data.x86 > 3)) \ @@ -252,38 +289,37 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old, }) #endif -static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old, - unsigned long long new) -{ - unsigned long long prev; - __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3" - : "=A"(prev) - : "b"((unsigned long)new), - "c"((unsigned long)(new >> 32)), - "m"(*__xg(ptr)), - "0"(old) - : "memory"); - return prev; -} +#ifndef CONFIG_X86_CMPXCHG64 +/* + * Building a kernel capable running on 80386 and 80486. It may be necessary + * to simulate the cmpxchg8b on the 80386 and 80486 CPU. + */ -static inline unsigned long long __cmpxchg64_local(volatile void *ptr, - unsigned long long old, unsigned long long new) -{ - unsigned long long prev; - __asm__ __volatile__("cmpxchg8b %3" - : "=A"(prev) - : "b"((unsigned long)new), - "c"((unsigned long)(new >> 32)), - "m"(*__xg(ptr)), - "0"(old) - : "memory"); - return prev; -} +extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64); + +#define cmpxchg64(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) __ret; \ + if (likely(boot_cpu_data.x86 > 4)) \ + __ret = __cmpxchg64((ptr), (unsigned long long)(o), \ + (unsigned long long)(n)); \ + else \ + __ret = cmpxchg_486_u64((ptr), (unsigned long long)(o), \ + (unsigned long long)(n)); \ + __ret; \ +}) +#define cmpxchg64_local(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) __ret; \ + if (likely(boot_cpu_data.x86 > 4)) \ + __ret = __cmpxchg64_local((ptr), (unsigned long long)(o), \ + (unsigned long long)(n)); \ + else \ + __ret = cmpxchg_486_u64((ptr), (unsigned long long)(o), \ + (unsigned long long)(n)); \ + __ret; \ +}) + +#endif -#define cmpxchg64(ptr,o,n)\ - ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\ - (unsigned long long)(n))) -#define cmpxchg64_local(ptr,o,n)\ - ((__typeof__(*(ptr)))__cmpxchg64_local((ptr),(unsigned long long)(o),\ - (unsigned long long)(n))) #endif -- cgit v1.2.2 From 2608a6584a0a32d3251dfafad31d9f8b2c784466 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:48 +0100 Subject: x86: segment selector macros This copies into asm-x86/segment_64.h some macros from asm-x86/segment_32.h for dissecting segment selectors. This lets other code use these macros uniformly on 32/64-bit rather than duplicating the constants elsewhere. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/segment_64.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/segment_64.h b/include/asm-x86/segment_64.h index 04b8ab21328..dce74210134 100644 --- a/include/asm-x86/segment_64.h +++ b/include/asm-x86/segment_64.h @@ -50,4 +50,15 @@ #define GDT_SIZE (GDT_ENTRIES * 8) #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) +/* Bottom two bits of selector give the ring privilege level */ +#define SEGMENT_RPL_MASK 0x3 +/* Bit 2 is table indicator (LDT/GDT) */ +#define SEGMENT_TI_MASK 0x4 + +/* User mode is privilege level 3 */ +#define USER_RPL 0x3 +/* LDT segment has TI set, GDT has it cleared */ +#define SEGMENT_LDT 0x4 +#define SEGMENT_GDT 0x0 + #endif -- cgit v1.2.2 From 7f232343e0ea37ffc0a552cdbd4825482c949281 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:48 +0100 Subject: x86: arch_has_single_step This defines the new standard arch_has_single_step macro. It makes the existing set_singlestep and clear_singlestep entry points global, and renames them to the new standard names user_enable_single_step and user_disable_single_step, respectively. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 105d1534eaf..fe75422f034 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -140,6 +140,13 @@ enum { #ifdef __KERNEL__ +/* + * These are defined as per linux/ptrace.h, which see. + */ +#define arch_has_single_step() (1) +extern void user_enable_single_step(struct task_struct *); +extern void user_disable_single_step(struct task_struct *); + struct user_desc; extern int do_get_thread_area(struct task_struct *p, int idx, struct user_desc __user *info); -- cgit v1.2.2 From e1f287735c1e58c653b516931b5d3dd899edcb77 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:50 +0100 Subject: x86 single_step: TIF_FORCED_TF This changes the single-step support to use a new thread_info flag TIF_FORCED_TF instead of the PT_DTRACE flag in task_struct.ptrace. This keeps arch implementation uses out of this non-arch field. This changes the ptrace access to eflags to mask TF and maintain the TIF_FORCED_TF flag directly if userland sets TF, instead of relying on ptrace_signal_deliver. The 64-bit and 32-bit kernels are harmonized on this same behavior. The ptrace_signal_deliver approach works now, but this change makes the low-level register access code reliable when called from different contexts than a ptrace stop, which will be possible in the future. The 64-bit do_debug exception handler is also changed not to clear TF from user-mode registers. This matches the 32-bit kernel's behavior. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/signal.h | 11 ++--------- include/asm-x86/thread_info_32.h | 2 ++ include/asm-x86/thread_info_64.h | 2 ++ 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/signal.h b/include/asm-x86/signal.h index 987a422a2c7..aee7eca585a 100644 --- a/include/asm-x86/signal.h +++ b/include/asm-x86/signal.h @@ -245,21 +245,14 @@ static __inline__ int sigfindinword(unsigned long word) struct pt_regs; -#define ptrace_signal_deliver(regs, cookie) \ - do { \ - if (current->ptrace & PT_DTRACE) { \ - current->ptrace &= ~PT_DTRACE; \ - (regs)->eflags &= ~TF_MASK; \ - } \ - } while (0) - #else /* __i386__ */ #undef __HAVE_ARCH_SIG_BITOPS +#endif /* !__i386__ */ + #define ptrace_signal_deliver(regs, cookie) do { } while (0) -#endif /* !__i386__ */ #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h index a516e9192f1..009ecc6ad38 100644 --- a/include/asm-x86/thread_info_32.h +++ b/include/asm-x86/thread_info_32.h @@ -138,6 +138,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_IO_BITMAP 18 /* uses I/O bitmap */ #define TIF_FREEZE 19 /* is freezing for suspend */ #define TIF_NOTSC 20 /* TSC is not accessible in userland */ +#define TIF_FORCED_TF 21 /* true if TF in eflags artificially */ #define _TIF_SYSCALL_TRACE (1< Date: Wed, 30 Jan 2008 13:30:52 +0100 Subject: x86: x86-64 ptrace debugreg cleanup This cleans up the 64-bit ptrace code to separate the guts of the debug register access from the implementation of PTRACE_PEEKUSR and PTRACE_POKEUSR. The new functions ptrace_[gs]et_debugreg are made global so that the ia32 code can later be changed to call them too. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index fe75422f034..d223decd7b0 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -110,6 +110,9 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where); struct task_struct; +extern unsigned long ptrace_get_debugreg(struct task_struct *child, int n); +extern int ptrace_set_debugreg(struct task_struct *child, int n, unsigned long); + extern unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs); -- cgit v1.2.2 From d2499d8b6c94df02629631807dd96deae7aa7637 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:54 +0100 Subject: x86: debugctlmsr constants This adds constant macros for a few of the bits in MSR_IA32_DEBUGCTLMSR. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr-index.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr-index.h b/include/asm-x86/msr-index.h index a4944732be0..4045bbe4737 100644 --- a/include/asm-x86/msr-index.h +++ b/include/asm-x86/msr-index.h @@ -63,6 +63,13 @@ #define MSR_IA32_LASTINTFROMIP 0x000001dd #define MSR_IA32_LASTINTTOIP 0x000001de +/* DEBUGCTLMSR bits (others vary by model): */ +#define _DEBUGCTLMSR_LBR 0 /* last branch recording */ +#define _DEBUGCTLMSR_BTF 1 /* single-step on branches */ + +#define DEBUGCTLMSR_LBR (1UL << _DEBUGCTLMSR_LBR) +#define DEBUGCTLMSR_BTF (1UL << _DEBUGCTLMSR_BTF) + #define MSR_IA32_MC0_CTL 0x00000400 #define MSR_IA32_MC0_STATUS 0x00000401 #define MSR_IA32_MC0_ADDR 0x00000402 -- cgit v1.2.2 From 7e9916040b3020d0f36d68bb7512e3b80b623097 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:54 +0100 Subject: x86: debugctlmsr context switch This adds low-level support for a per-thread value of MSR_IA32_DEBUGCTLMSR. The per-thread value is switched in when TIF_DEBUGCTLMSR is set. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_32.h | 2 ++ include/asm-x86/processor_64.h | 2 ++ include/asm-x86/thread_info_32.h | 6 ++++-- include/asm-x86/thread_info_64.h | 4 +++- 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 2540bf8d572..3c67eacb316 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -368,6 +368,8 @@ struct thread_struct { unsigned long iopl; /* max allowed port in the bitmap, in bytes: */ unsigned long io_bitmap_max; +/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ + unsigned long debugctlmsr; }; #define INIT_THREAD { \ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 20d8935d141..e7bea4fed64 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -238,6 +238,8 @@ struct thread_struct { int ioperm; unsigned long *io_bitmap_ptr; unsigned io_bitmap_max; +/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ + unsigned long debugctlmsr; /* cached TLS descriptors. */ u64 tls_array[GDT_ENTRY_TLS_ENTRIES]; } __attribute__((aligned(16))); diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h index 009ecc6ad38..306fc80800e 100644 --- a/include/asm-x86/thread_info_32.h +++ b/include/asm-x86/thread_info_32.h @@ -139,6 +139,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_FREEZE 19 /* is freezing for suspend */ #define TIF_NOTSC 20 /* TSC is not accessible in userland */ #define TIF_FORCED_TF 21 /* true if TF in eflags artificially */ +#define TIF_DEBUGCTLMSR 22 /* uses thread_struct.debugctlmsr */ #define _TIF_SYSCALL_TRACE (1< Date: Wed, 30 Jan 2008 13:30:54 +0100 Subject: x86: debugctlmsr arch_has_block_step This implements user-mode step-until-branch on x86 using the BTF bit in MSR_IA32_DEBUGCTLMSR. It's just like single-step, only less so. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index d223decd7b0..04204f35929 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -150,6 +150,13 @@ enum { extern void user_enable_single_step(struct task_struct *); extern void user_disable_single_step(struct task_struct *); +extern void user_enable_block_step(struct task_struct *); +#ifdef CONFIG_X86_DEBUGCTLMSR +#define arch_has_block_step() (1) +#else +#define arch_has_block_step() (boot_cpu_data.x86 >= 6) +#endif + struct user_desc; extern int do_get_thread_area(struct task_struct *p, int idx, struct user_desc __user *info); -- cgit v1.2.2 From 0fa376e027f0bd71368e1485f863f0dff8f7c897 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:55 +0100 Subject: x86: PTRACE_SINGLEBLOCK This adds the PTRACE_SINGLEBLOCK request on x86, matching the ia64 feature. The implementation comes from the generic ptrace code and relies on the low-level machine support provided by arch_has_block_step() et al. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace-abi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 7524e123383..adce6b51df2 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -78,4 +78,6 @@ # define PTRACE_SYSEMU_SINGLESTEP 32 #endif +#define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ + #endif -- cgit v1.2.2 From 1c54d77078056cde0f195b1a982cb681850efc08 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:30:55 +0100 Subject: x86: partial unification of asm-x86/bitops.h This unifies the set/clear/test bit functions of asm/bitops.h. I have not attempted to merge the bit-finding functions, since they rely on the machine word size and can't be easily restructured to work generically without a lot of #ifdefs. In particular, the 64-bit code can assume the presence of conditional move instructions, whereas 32-bit needs to be more careful. The inline assembly for the bit operations has been changed to remove explicit sizing hints on the instructions, so the assembler will pick the appropriate instruction forms depending on the architecture and the context. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Cc: Linus Torvalds Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/bitops.h | 315 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/bitops_32.h | 308 ------------------------------------------- include/asm-x86/bitops_64.h | 297 ----------------------------------------- 3 files changed, 315 insertions(+), 605 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index 07e3f6d4fe4..c6dd7e259b4 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h @@ -1,5 +1,320 @@ +#ifndef _ASM_X86_BITOPS_H +#define _ASM_X86_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +#ifndef _LINUX_BITOPS_H +#error only can be included directly +#endif + +#include +#include + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) +/* Technically wrong, but this avoids compilation errors on some gcc + versions. */ +#define ADDR "=m" (*(volatile long *) addr) +#else +#define ADDR "+m" (*(volatile long *) addr) +#endif + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * + * Note: there are no guarantees that this function will not be reordered + * on non x86 architectures, so if you are writing portable code, + * make sure not to rely on its reordering guarantees. + * + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void set_bit(int nr, volatile unsigned long *addr) +{ + asm volatile(LOCK_PREFIX "bts %1,%0" + : ADDR + : "Ir" (nr) : "memory"); +} + +/** + * __set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static inline void __set_bit(int nr, volatile unsigned long *addr) +{ + asm volatile("bts %1,%0" + : ADDR + : "Ir" (nr) : "memory"); +} + + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static inline void clear_bit(int nr, volatile unsigned long *addr) +{ + asm volatile(LOCK_PREFIX "btr %1,%0" + : ADDR + : "Ir" (nr)); +} + +/* + * clear_bit_unlock - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and implies release semantics before the memory + * operation. It can be used for an unlock. + */ +static inline void clear_bit_unlock(unsigned nr, volatile unsigned long *addr) +{ + barrier(); + clear_bit(nr, addr); +} + +static inline void __clear_bit(int nr, volatile unsigned long *addr) +{ + asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); +} + +/* + * __clear_bit_unlock - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * __clear_bit() is non-atomic and implies release semantics before the memory + * operation. It can be used for an unlock if no other CPUs can concurrently + * modify other bits in the word. + * + * No memory barrier is required here, because x86 cannot reorder stores past + * older loads. Same principle as spin_unlock. + */ +static inline void __clear_bit_unlock(unsigned nr, volatile unsigned long *addr) +{ + barrier(); + __clear_bit(nr, addr); +} + +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/** + * __change_bit - Toggle a bit in memory + * @nr: the bit to change + * @addr: the address to start counting from + * + * Unlike change_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static inline void __change_bit(int nr, volatile unsigned long *addr) +{ + asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); +} + +/** + * change_bit - Toggle a bit in memory + * @nr: Bit to change + * @addr: Address to start counting from + * + * change_bit() is atomic and may not be reordered. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void change_bit(int nr, volatile unsigned long *addr) +{ + asm volatile(LOCK_PREFIX "btc %1,%0" + : ADDR : "Ir" (nr)); +} + +/** + * test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static inline int test_and_set_bit(int nr, volatile unsigned long *addr) +{ + int oldbit; + + asm volatile(LOCK_PREFIX "bts %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit), ADDR + : "Ir" (nr) : "memory"); + + return oldbit; +} + +/** + * test_and_set_bit_lock - Set a bit and return its old value for lock + * @nr: Bit to set + * @addr: Address to count from + * + * This is the same as test_and_set_bit on x86. + */ +static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) +{ + return test_and_set_bit(nr, addr); +} + +/** + * __test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) +{ + int oldbit; + + asm("bts %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit), ADDR + : "Ir" (nr)); + return oldbit; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to clear + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + int oldbit; + + asm volatile(LOCK_PREFIX "btr %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit), ADDR + : "Ir" (nr) : "memory"); + + return oldbit; +} + +/** + * __test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to clear + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + int oldbit; + + asm volatile("btr %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit), ADDR + : "Ir" (nr)); + return oldbit; +} + +/* WARNING: non atomic and it can be reordered! */ +static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) +{ + int oldbit; + + asm volatile("btc %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit), ADDR + : "Ir" (nr) : "memory"); + + return oldbit; +} + +/** + * test_and_change_bit - Change a bit and return its old value + * @nr: Bit to change + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static inline int test_and_change_bit(int nr, volatile unsigned long *addr) +{ + int oldbit; + + asm volatile(LOCK_PREFIX "btc %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit), ADDR + : "Ir" (nr) : "memory"); + + return oldbit; +} + +static inline int constant_test_bit(int nr, const volatile unsigned long *addr) +{ + return ((1UL << (nr % BITS_PER_LONG)) & (addr[nr / BITS_PER_LONG])) != 0; +} + +static inline int variable_test_bit(int nr, volatile const unsigned long *addr) +{ + int oldbit; + + asm volatile("bt %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit) + : "m" (*addr), "Ir" (nr)); + + return oldbit; +} + +#if 0 /* Fool kernel-doc since it doesn't do macros yet */ +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static int test_bit(int nr, const volatile unsigned long *addr); +#endif + +#define test_bit(nr,addr) \ + (__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + +#undef ADDR + #ifdef CONFIG_X86_32 # include "bitops_32.h" #else # include "bitops_64.h" #endif + +#endif /* _ASM_X86_BITOPS_H */ diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h index 5a29cce6a91..e4d75fcf9c0 100644 --- a/include/asm-x86/bitops_32.h +++ b/include/asm-x86/bitops_32.h @@ -5,314 +5,6 @@ * Copyright 1992, Linus Torvalds. */ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - -#include -#include - -/* - * These have to be done with inline assembly: that way the bit-setting - * is guaranteed to be atomic. All bit operations return 0 if the bit - * was cleared before the operation and != 0 if it was not. - * - * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). - */ - -#define ADDR (*(volatile long *) addr) - -/** - * set_bit - Atomically set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * This function is atomic and may not be reordered. See __set_bit() - * if you do not require the atomic guarantees. - * - * Note: there are no guarantees that this function will not be reordered - * on non x86 architectures, so if you are writing portable code, - * make sure not to rely on its reordering guarantees. - * - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static inline void set_bit(int nr, volatile unsigned long *addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btsl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -} - -/** - * __set_bit - Set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * Unlike set_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static inline void __set_bit(int nr, volatile unsigned long *addr) -{ - __asm__( - "btsl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -} - -/** - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and may not be reordered. However, it does - * not contain a memory barrier, so if it is used for locking purposes, - * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() - * in order to ensure changes are visible on other processors. - */ -static inline void clear_bit(int nr, volatile unsigned long *addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btrl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -} - -/* - * clear_bit_unlock - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and implies release semantics before the memory - * operation. It can be used for an unlock. - */ -static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) -{ - barrier(); - clear_bit(nr, addr); -} - -static inline void __clear_bit(int nr, volatile unsigned long *addr) -{ - __asm__ __volatile__( - "btrl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -} - -/* - * __clear_bit_unlock - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * __clear_bit() is non-atomic and implies release semantics before the memory - * operation. It can be used for an unlock if no other CPUs can concurrently - * modify other bits in the word. - * - * No memory barrier is required here, because x86 cannot reorder stores past - * older loads. Same principle as spin_unlock. - */ -static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) -{ - barrier(); - __clear_bit(nr, addr); -} - -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() - -/** - * __change_bit - Toggle a bit in memory - * @nr: the bit to change - * @addr: the address to start counting from - * - * Unlike change_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static inline void __change_bit(int nr, volatile unsigned long *addr) -{ - __asm__ __volatile__( - "btcl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -} - -/** - * change_bit - Toggle a bit in memory - * @nr: Bit to change - * @addr: Address to start counting from - * - * change_bit() is atomic and may not be reordered. It may be - * reordered on other architectures than x86. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static inline void change_bit(int nr, volatile unsigned long *addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btcl %1,%0" - :"+m" (ADDR) - :"Ir" (nr)); -} - -/** - * test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It may be reordered on other architectures than x86. - * It also implies a memory barrier. - */ -static inline int test_and_set_bit(int nr, volatile unsigned long *addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -/** - * test_and_set_bit_lock - Set a bit and return its old value for lock - * @nr: Bit to set - * @addr: Address to count from - * - * This is the same as test_and_set_bit on x86. - */ -static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) -{ - return test_and_set_bit(nr, addr); -} - -/** - * __test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) -{ - int oldbit; - - __asm__( - "btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr)); - return oldbit; -} - -/** - * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It can be reorderdered on other architectures other than x86. - * It also implies a memory barrier. - */ -static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -/** - * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) -{ - int oldbit; - - __asm__( - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr)); - return oldbit; -} - -/* WARNING: non atomic and it can be reordered! */ -static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) -{ - int oldbit; - - __asm__ __volatile__( - "btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -/** - * test_and_change_bit - Change a bit and return its old value - * @nr: Bit to change - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static inline int test_and_change_bit(int nr, volatile unsigned long *addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -#if 0 /* Fool kernel-doc since it doesn't do macros yet */ -/** - * test_bit - Determine whether a bit is set - * @nr: bit number to test - * @addr: Address to start counting from - */ -static int test_bit(int nr, const volatile void *addr); -#endif - -static __always_inline int constant_test_bit(int nr, const volatile unsigned long *addr) -{ - return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; -} - -static inline int variable_test_bit(int nr, const volatile unsigned long *addr) -{ - int oldbit; - - __asm__ __volatile__( - "btl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit) - :"m" (ADDR),"Ir" (nr)); - return oldbit; -} - -#define test_bit(nr, addr) \ - (__builtin_constant_p(nr) ? \ - constant_test_bit((nr), (addr)) : \ - variable_test_bit((nr), (addr))) - -#undef ADDR - /** * find_first_zero_bit - find the first zero bit in a memory region * @addr: The address to start the search at diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h index 766bcc0470a..48adbf56ca6 100644 --- a/include/asm-x86/bitops_64.h +++ b/include/asm-x86/bitops_64.h @@ -5,303 +5,6 @@ * Copyright 1992, Linus Torvalds. */ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - -#include - -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) -/* Technically wrong, but this avoids compilation errors on some gcc - versions. */ -#define ADDR "=m" (*(volatile long *) addr) -#else -#define ADDR "+m" (*(volatile long *) addr) -#endif - -/** - * set_bit - Atomically set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * This function is atomic and may not be reordered. See __set_bit() - * if you do not require the atomic guarantees. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static inline void set_bit(int nr, volatile void *addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btsl %1,%0" - :ADDR - :"dIr" (nr) : "memory"); -} - -/** - * __set_bit - Set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * Unlike set_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static inline void __set_bit(int nr, volatile void *addr) -{ - __asm__ volatile( - "btsl %1,%0" - :ADDR - :"dIr" (nr) : "memory"); -} - -/** - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and may not be reordered. However, it does - * not contain a memory barrier, so if it is used for locking purposes, - * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() - * in order to ensure changes are visible on other processors. - */ -static inline void clear_bit(int nr, volatile void *addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btrl %1,%0" - :ADDR - :"dIr" (nr)); -} - -/* - * clear_bit_unlock - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and implies release semantics before the memory - * operation. It can be used for an unlock. - */ -static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) -{ - barrier(); - clear_bit(nr, addr); -} - -static inline void __clear_bit(int nr, volatile void *addr) -{ - __asm__ __volatile__( - "btrl %1,%0" - :ADDR - :"dIr" (nr)); -} - -/* - * __clear_bit_unlock - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * __clear_bit() is non-atomic and implies release semantics before the memory - * operation. It can be used for an unlock if no other CPUs can concurrently - * modify other bits in the word. - * - * No memory barrier is required here, because x86 cannot reorder stores past - * older loads. Same principle as spin_unlock. - */ -static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) -{ - barrier(); - __clear_bit(nr, addr); -} - -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() - -/** - * __change_bit - Toggle a bit in memory - * @nr: the bit to change - * @addr: the address to start counting from - * - * Unlike change_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static inline void __change_bit(int nr, volatile void *addr) -{ - __asm__ __volatile__( - "btcl %1,%0" - :ADDR - :"dIr" (nr)); -} - -/** - * change_bit - Toggle a bit in memory - * @nr: Bit to change - * @addr: Address to start counting from - * - * change_bit() is atomic and may not be reordered. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static inline void change_bit(int nr, volatile void *addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btcl %1,%0" - :ADDR - :"dIr" (nr)); -} - -/** - * test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static inline int test_and_set_bit(int nr, volatile void *addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),ADDR - :"dIr" (nr) : "memory"); - return oldbit; -} - -/** - * test_and_set_bit_lock - Set a bit and return its old value for lock - * @nr: Bit to set - * @addr: Address to count from - * - * This is the same as test_and_set_bit on x86. - */ -static inline int test_and_set_bit_lock(int nr, volatile void *addr) -{ - return test_and_set_bit(nr, addr); -} - -/** - * __test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static inline int __test_and_set_bit(int nr, volatile void *addr) -{ - int oldbit; - - __asm__( - "btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),ADDR - :"dIr" (nr)); - return oldbit; -} - -/** - * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static inline int test_and_clear_bit(int nr, volatile void *addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),ADDR - :"dIr" (nr) : "memory"); - return oldbit; -} - -/** - * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static inline int __test_and_clear_bit(int nr, volatile void *addr) -{ - int oldbit; - - __asm__( - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),ADDR - :"dIr" (nr)); - return oldbit; -} - -/* WARNING: non atomic and it can be reordered! */ -static inline int __test_and_change_bit(int nr, volatile void *addr) -{ - int oldbit; - - __asm__ __volatile__( - "btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),ADDR - :"dIr" (nr) : "memory"); - return oldbit; -} - -/** - * test_and_change_bit - Change a bit and return its old value - * @nr: Bit to change - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static inline int test_and_change_bit(int nr, volatile void *addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),ADDR - :"dIr" (nr) : "memory"); - return oldbit; -} - -#if 0 /* Fool kernel-doc since it doesn't do macros yet */ -/** - * test_bit - Determine whether a bit is set - * @nr: bit number to test - * @addr: Address to start counting from - */ -static int test_bit(int nr, const volatile void *addr); -#endif - -static inline int constant_test_bit(int nr, const volatile void *addr) -{ - return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; -} - -static inline int variable_test_bit(int nr, volatile const void *addr) -{ - int oldbit; - - __asm__ __volatile__( - "btl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit) - :"m" (*(volatile long *)addr),"dIr" (nr)); - return oldbit; -} - -#define test_bit(nr,addr) \ -(__builtin_constant_p(nr) ? \ - constant_test_bit((nr),(addr)) : \ - variable_test_bit((nr),(addr))) - -#undef ADDR - extern long find_first_zero_bit(const unsigned long *addr, unsigned long size); extern long find_next_zero_bit(const unsigned long *addr, long size, long offset); extern long find_first_bit(const unsigned long *addr, unsigned long size); -- cgit v1.2.2 From 5548fecdff5617ba3a2f09f0e585e1ac6e1bd25c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:30:55 +0100 Subject: x86: clean up bitops-related warnings Add casts to appropriate places to silence spurious bitops warnings. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 2 +- include/asm-x86/numa_64.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index acbf6681740..761922972f6 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -124,7 +124,7 @@ (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \ (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ) \ ? 1 : \ - test_bit(bit, (c)->x86_capability)) + test_bit(bit, (unsigned long *)(c)->x86_capability)) #define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit) #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index c3c20db1fba..4449889bb0c 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h @@ -32,7 +32,7 @@ extern void __init init_cpu_to_node(void); static inline void clear_node_cpumask(int cpu) { - clear_bit(cpu, &node_to_cpumask_map[cpu_to_node(cpu)]); + clear_bit(cpu, (unsigned long *)&node_to_cpumask_map[cpu_to_node(cpu)]); } #else -- cgit v1.2.2 From 53756d3722172815f52272b28c6d5d5e9639adde Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:30:55 +0100 Subject: x86: add set/clear_cpu_cap operations The patch to suppress bitops-related warnings added a pile of ugly casts. Many of these were related to the management of x86 CPU capabilities. Clean these up by adding specific set/clear_cpu_cap macros, and use them consistently. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 761922972f6..87dd900154d 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -124,9 +124,12 @@ (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \ (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ) \ ? 1 : \ - test_bit(bit, (unsigned long *)(c)->x86_capability)) + test_bit(bit, (unsigned long *)((c)->x86_capability))) #define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit) +#define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability)) +#define clear_cpu_cap(c, bit) clear_bit(bit, (unsigned long *)((c)->x86_capability)) + #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) #define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) #define cpu_has_de boot_cpu_has(X86_FEATURE_DE) -- cgit v1.2.2 From 65ea5b0349903585bfed9720fa06f5edb4f1cd25 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:30:56 +0100 Subject: x86: rename the struct pt_regs members for 32/64-bit consistency We have a lot of code which differs only by the naming of specific members of structures that contain registers. In order to enable additional unifications, this patch drops the e- or r- size prefix from the register names in struct pt_regs, and drops the x- prefixes for segment registers on the 32-bit side. This patch also performs the equivalent renames in some additional places that might be candidates for unification in the future. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/compat.h | 2 +- include/asm-x86/elf.h | 66 +++++++++++++++++----------------- include/asm-x86/kexec_32.h | 36 +++++++++---------- include/asm-x86/kexec_64.h | 20 +++++------ include/asm-x86/kprobes_32.h | 2 +- include/asm-x86/kprobes_64.h | 2 +- include/asm-x86/mce.h | 4 +-- include/asm-x86/processor_32.h | 20 +++++------ include/asm-x86/processor_64.h | 8 ++--- include/asm-x86/ptrace.h | 80 +++++++++++++++++++++++++++++++++++------- 10 files changed, 147 insertions(+), 93 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/compat.h b/include/asm-x86/compat.h index 66ba7987184..b270ee04959 100644 --- a/include/asm-x86/compat.h +++ b/include/asm-x86/compat.h @@ -207,7 +207,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) static __inline__ void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = task_pt_regs(current); - return (void __user *)regs->rsp - len; + return (void __user *)regs->sp - len; } static inline int is_compat_task(void) diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index 60f5101d948..5e5705bf082 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -99,32 +99,32 @@ typedef struct user_fxsr_struct elf_fpxregset_t; just to make things more deterministic. */ #define ELF_PLAT_INIT(_r, load_addr) do { \ - _r->ebx = 0; _r->ecx = 0; _r->edx = 0; \ - _r->esi = 0; _r->edi = 0; _r->ebp = 0; \ - _r->eax = 0; \ + _r->bx = 0; _r->cx = 0; _r->dx = 0; \ + _r->si = 0; _r->di = 0; _r->bp = 0; \ + _r->ax = 0; \ } while (0) /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is now struct_user_regs, they are different) */ #define ELF_CORE_COPY_REGS(pr_reg, regs) \ - pr_reg[0] = regs->ebx; \ - pr_reg[1] = regs->ecx; \ - pr_reg[2] = regs->edx; \ - pr_reg[3] = regs->esi; \ - pr_reg[4] = regs->edi; \ - pr_reg[5] = regs->ebp; \ - pr_reg[6] = regs->eax; \ - pr_reg[7] = regs->xds & 0xffff; \ - pr_reg[8] = regs->xes & 0xffff; \ - pr_reg[9] = regs->xfs & 0xffff; \ + pr_reg[0] = regs->bx; \ + pr_reg[1] = regs->cx; \ + pr_reg[2] = regs->dx; \ + pr_reg[3] = regs->si; \ + pr_reg[4] = regs->di; \ + pr_reg[5] = regs->bp; \ + pr_reg[6] = regs->ax; \ + pr_reg[7] = regs->ds & 0xffff; \ + pr_reg[8] = regs->es & 0xffff; \ + pr_reg[9] = regs->fs & 0xffff; \ savesegment(gs,pr_reg[10]); \ - pr_reg[11] = regs->orig_eax; \ - pr_reg[12] = regs->eip; \ - pr_reg[13] = regs->xcs & 0xffff; \ - pr_reg[14] = regs->eflags; \ - pr_reg[15] = regs->esp; \ - pr_reg[16] = regs->xss & 0xffff; + pr_reg[11] = regs->orig_ax; \ + pr_reg[12] = regs->ip; \ + pr_reg[13] = regs->cs & 0xffff; \ + pr_reg[14] = regs->flags; \ + pr_reg[15] = regs->sp; \ + pr_reg[16] = regs->ss & 0xffff; #define ELF_PLATFORM (utsname()->machine) #define set_personality_64bit() do { } while (0) @@ -142,9 +142,9 @@ extern unsigned int vdso_enabled; #define ELF_PLAT_INIT(_r, load_addr) do { \ struct task_struct *cur = current; \ - (_r)->rbx = 0; (_r)->rcx = 0; (_r)->rdx = 0; \ - (_r)->rsi = 0; (_r)->rdi = 0; (_r)->rbp = 0; \ - (_r)->rax = 0; \ + (_r)->bx = 0; (_r)->cx = 0; (_r)->dx = 0; \ + (_r)->si = 0; (_r)->di = 0; (_r)->bp = 0; \ + (_r)->ax = 0; \ (_r)->r8 = 0; \ (_r)->r9 = 0; \ (_r)->r10 = 0; \ @@ -169,22 +169,22 @@ extern unsigned int vdso_enabled; (pr_reg)[1] = (regs)->r14; \ (pr_reg)[2] = (regs)->r13; \ (pr_reg)[3] = (regs)->r12; \ - (pr_reg)[4] = (regs)->rbp; \ - (pr_reg)[5] = (regs)->rbx; \ + (pr_reg)[4] = (regs)->bp; \ + (pr_reg)[5] = (regs)->bx; \ (pr_reg)[6] = (regs)->r11; \ (pr_reg)[7] = (regs)->r10; \ (pr_reg)[8] = (regs)->r9; \ (pr_reg)[9] = (regs)->r8; \ - (pr_reg)[10] = (regs)->rax; \ - (pr_reg)[11] = (regs)->rcx; \ - (pr_reg)[12] = (regs)->rdx; \ - (pr_reg)[13] = (regs)->rsi; \ - (pr_reg)[14] = (regs)->rdi; \ - (pr_reg)[15] = (regs)->orig_rax; \ - (pr_reg)[16] = (regs)->rip; \ + (pr_reg)[10] = (regs)->ax; \ + (pr_reg)[11] = (regs)->cx; \ + (pr_reg)[12] = (regs)->dx; \ + (pr_reg)[13] = (regs)->si; \ + (pr_reg)[14] = (regs)->di; \ + (pr_reg)[15] = (regs)->orig_ax; \ + (pr_reg)[16] = (regs)->ip; \ (pr_reg)[17] = (regs)->cs; \ - (pr_reg)[18] = (regs)->eflags; \ - (pr_reg)[19] = (regs)->rsp; \ + (pr_reg)[18] = (regs)->flags; \ + (pr_reg)[19] = (regs)->sp; \ (pr_reg)[20] = (regs)->ss; \ (pr_reg)[21] = current->thread.fs; \ (pr_reg)[22] = current->thread.gs; \ diff --git a/include/asm-x86/kexec_32.h b/include/asm-x86/kexec_32.h index 4b9dc9e6b70..ff39d2f8802 100644 --- a/include/asm-x86/kexec_32.h +++ b/include/asm-x86/kexec_32.h @@ -45,7 +45,7 @@ /* We can also handle crash dumps from 64 bit kernel. */ #define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64) -/* CPU does not save ss and esp on stack if execution is already +/* CPU does not save ss and sp on stack if execution is already * running in kernel mode at the time of NMI occurrence. This code * fixes it. */ @@ -53,16 +53,16 @@ static inline void crash_fixup_ss_esp(struct pt_regs *newregs, struct pt_regs *oldregs) { memcpy(newregs, oldregs, sizeof(*newregs)); - newregs->esp = (unsigned long)&(oldregs->esp); + newregs->sp = (unsigned long)&(oldregs->sp); __asm__ __volatile__( "xorl %%eax, %%eax\n\t" "movw %%ss, %%ax\n\t" - :"=a"(newregs->xss)); + :"=a"(newregs->ss)); } /* * This function is responsible for capturing register states if coming - * via panic otherwise just fix up the ss and esp if coming via kernel + * via panic otherwise just fix up the ss and sp if coming via kernel * mode exception. */ static inline void crash_setup_regs(struct pt_regs *newregs, @@ -71,21 +71,21 @@ static inline void crash_setup_regs(struct pt_regs *newregs, if (oldregs) crash_fixup_ss_esp(newregs, oldregs); else { - __asm__ __volatile__("movl %%ebx,%0" : "=m"(newregs->ebx)); - __asm__ __volatile__("movl %%ecx,%0" : "=m"(newregs->ecx)); - __asm__ __volatile__("movl %%edx,%0" : "=m"(newregs->edx)); - __asm__ __volatile__("movl %%esi,%0" : "=m"(newregs->esi)); - __asm__ __volatile__("movl %%edi,%0" : "=m"(newregs->edi)); - __asm__ __volatile__("movl %%ebp,%0" : "=m"(newregs->ebp)); - __asm__ __volatile__("movl %%eax,%0" : "=m"(newregs->eax)); - __asm__ __volatile__("movl %%esp,%0" : "=m"(newregs->esp)); - __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(newregs->xss)); - __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(newregs->xcs)); - __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(newregs->xds)); - __asm__ __volatile__("movw %%es, %%ax;" :"=a"(newregs->xes)); - __asm__ __volatile__("pushfl; popl %0" :"=m"(newregs->eflags)); + __asm__ __volatile__("movl %%ebx,%0" : "=m"(newregs->bx)); + __asm__ __volatile__("movl %%ecx,%0" : "=m"(newregs->cx)); + __asm__ __volatile__("movl %%edx,%0" : "=m"(newregs->dx)); + __asm__ __volatile__("movl %%esi,%0" : "=m"(newregs->si)); + __asm__ __volatile__("movl %%edi,%0" : "=m"(newregs->di)); + __asm__ __volatile__("movl %%ebp,%0" : "=m"(newregs->bp)); + __asm__ __volatile__("movl %%eax,%0" : "=m"(newregs->ax)); + __asm__ __volatile__("movl %%esp,%0" : "=m"(newregs->sp)); + __asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss)); + __asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs)); + __asm__ __volatile__("movl %%ds, %%eax;" :"=a"(newregs->ds)); + __asm__ __volatile__("movl %%es, %%eax;" :"=a"(newregs->es)); + __asm__ __volatile__("pushfl; popl %0" :"=m"(newregs->flags)); - newregs->eip = (unsigned long)current_text_addr(); + newregs->ip = (unsigned long)current_text_addr(); } } asmlinkage NORET_TYPE void diff --git a/include/asm-x86/kexec_64.h b/include/asm-x86/kexec_64.h index 738e581b67f..b5f989b15c0 100644 --- a/include/asm-x86/kexec_64.h +++ b/include/asm-x86/kexec_64.h @@ -60,14 +60,14 @@ static inline void crash_setup_regs(struct pt_regs *newregs, if (oldregs) memcpy(newregs, oldregs, sizeof(*newregs)); else { - __asm__ __volatile__("movq %%rbx,%0" : "=m"(newregs->rbx)); - __asm__ __volatile__("movq %%rcx,%0" : "=m"(newregs->rcx)); - __asm__ __volatile__("movq %%rdx,%0" : "=m"(newregs->rdx)); - __asm__ __volatile__("movq %%rsi,%0" : "=m"(newregs->rsi)); - __asm__ __volatile__("movq %%rdi,%0" : "=m"(newregs->rdi)); - __asm__ __volatile__("movq %%rbp,%0" : "=m"(newregs->rbp)); - __asm__ __volatile__("movq %%rax,%0" : "=m"(newregs->rax)); - __asm__ __volatile__("movq %%rsp,%0" : "=m"(newregs->rsp)); + __asm__ __volatile__("movq %%rbx,%0" : "=m"(newregs->bx)); + __asm__ __volatile__("movq %%rcx,%0" : "=m"(newregs->cx)); + __asm__ __volatile__("movq %%rdx,%0" : "=m"(newregs->dx)); + __asm__ __volatile__("movq %%rsi,%0" : "=m"(newregs->si)); + __asm__ __volatile__("movq %%rdi,%0" : "=m"(newregs->di)); + __asm__ __volatile__("movq %%rbp,%0" : "=m"(newregs->bp)); + __asm__ __volatile__("movq %%rax,%0" : "=m"(newregs->ax)); + __asm__ __volatile__("movq %%rsp,%0" : "=m"(newregs->sp)); __asm__ __volatile__("movq %%r8,%0" : "=m"(newregs->r8)); __asm__ __volatile__("movq %%r9,%0" : "=m"(newregs->r9)); __asm__ __volatile__("movq %%r10,%0" : "=m"(newregs->r10)); @@ -78,9 +78,9 @@ static inline void crash_setup_regs(struct pt_regs *newregs, __asm__ __volatile__("movq %%r15,%0" : "=m"(newregs->r15)); __asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss)); __asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs)); - __asm__ __volatile__("pushfq; popq %0" :"=m"(newregs->eflags)); + __asm__ __volatile__("pushfq; popq %0" :"=m"(newregs->flags)); - newregs->rip = (unsigned long)current_text_addr(); + newregs->ip = (unsigned long)current_text_addr(); } } diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h index 9fe8f3bddfd..2f38315bc39 100644 --- a/include/asm-x86/kprobes_32.h +++ b/include/asm-x86/kprobes_32.h @@ -84,7 +84,7 @@ struct kprobe_ctlblk { */ static inline void restore_interrupts(struct pt_regs *regs) { - if (regs->eflags & IF_MASK) + if (regs->flags & IF_MASK) local_irq_enable(); } diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h index 743d76218fc..8c919d35cdd 100644 --- a/include/asm-x86/kprobes_64.h +++ b/include/asm-x86/kprobes_64.h @@ -77,7 +77,7 @@ struct kprobe_ctlblk { */ static inline void restore_interrupts(struct pt_regs *regs) { - if (regs->eflags & IF_MASK) + if (regs->flags & IF_MASK) local_irq_enable(); } diff --git a/include/asm-x86/mce.h b/include/asm-x86/mce.h index e6ff507a73b..94f1fd79e22 100644 --- a/include/asm-x86/mce.h +++ b/include/asm-x86/mce.h @@ -13,7 +13,7 @@ #define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */ #define MCG_STATUS_RIPV (1UL<<0) /* restart ip valid */ -#define MCG_STATUS_EIPV (1UL<<1) /* eip points to correct instruction */ +#define MCG_STATUS_EIPV (1UL<<1) /* ip points to correct instruction */ #define MCG_STATUS_MCIP (1UL<<2) /* machine check in progress */ #define MCI_STATUS_VAL (1UL<<63) /* valid error */ @@ -30,7 +30,7 @@ struct mce { __u64 misc; __u64 addr; __u64 mcgstatus; - __u64 rip; + __u64 ip; __u64 tsc; /* cpu time stamp counter */ __u64 res1; /* for future extension */ __u64 res2; /* dito. */ diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 3c67eacb316..c85400fe58c 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -398,14 +398,14 @@ struct thread_struct { #define start_thread(regs, new_eip, new_esp) do { \ __asm__("movl %0,%%gs": :"r" (0)); \ - regs->xfs = 0; \ + regs->fs = 0; \ set_fs(USER_DS); \ - regs->xds = __USER_DS; \ - regs->xes = __USER_DS; \ - regs->xss = __USER_DS; \ - regs->xcs = __USER_CS; \ - regs->eip = new_eip; \ - regs->esp = new_esp; \ + regs->ds = __USER_DS; \ + regs->es = __USER_DS; \ + regs->ss = __USER_DS; \ + regs->cs = __USER_CS; \ + regs->ip = new_eip; \ + regs->sp = new_esp; \ } while (0) /* Forward declaration, a strange C thing */ @@ -440,7 +440,7 @@ unsigned long get_wchan(struct task_struct *p); * is accessable even if the CPU haven't stored the SS/ESP registers * on the stack (interrupt gate does not save these registers * when switching to the same priv ring). - * Therefore beware: accessing the xss/esp fields of the + * Therefore beware: accessing the ss/esp fields of the * "struct pt_regs" is possible, but they may contain the * completely wrong values. */ @@ -451,8 +451,8 @@ unsigned long get_wchan(struct task_struct *p); __regs__ - 1; \ }) -#define KSTK_EIP(task) (task_pt_regs(task)->eip) -#define KSTK_ESP(task) (task_pt_regs(task)->esp) +#define KSTK_EIP(task) (task_pt_regs(task)->ip) +#define KSTK_ESP(task) (task_pt_regs(task)->sp) struct microcode_header { diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index e7bea4fed64..797770113e6 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -258,12 +258,12 @@ struct thread_struct { #define start_thread(regs,new_rip,new_rsp) do { \ asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \ load_gs_index(0); \ - (regs)->rip = (new_rip); \ - (regs)->rsp = (new_rsp); \ + (regs)->ip = (new_rip); \ + (regs)->sp = (new_rsp); \ write_pda(oldrsp, (new_rsp)); \ (regs)->cs = __USER_CS; \ (regs)->ss = __USER_DS; \ - (regs)->eflags = 0x200; \ + (regs)->flags = 0x200; \ set_fs(USER_DS); \ } while(0) @@ -297,7 +297,7 @@ extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); extern unsigned long get_wchan(struct task_struct *p); #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1) -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip) +#define KSTK_EIP(tsk) (task_pt_regs(tsk)->ip) #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 04204f35929..9187b2fab75 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -10,6 +10,8 @@ /* this struct defines the way the registers are stored on the stack during a system call. */ +#ifndef __KERNEL__ + struct pt_regs { long ebx; long ecx; @@ -21,7 +23,7 @@ struct pt_regs { int xds; int xes; int xfs; - /* int xgs; */ + /* int gs; */ long orig_eax; long eip; int xcs; @@ -30,7 +32,27 @@ struct pt_regs { int xss; }; -#ifdef __KERNEL__ +#else /* __KERNEL__ */ + +struct pt_regs { + long bx; + long cx; + long dx; + long si; + long di; + long bp; + long ax; + int ds; + int es; + int fs; + /* int gs; */ + long orig_ax; + long ip; + int cs; + long flags; + long sp; + int ss; +}; #include #include @@ -47,27 +69,30 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int erro */ static inline int user_mode(struct pt_regs *regs) { - return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL; + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; } static inline int user_mode_vm(struct pt_regs *regs) { - return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; + return ((regs->cs & SEGMENT_RPL_MASK) | + (regs->flags & VM_MASK)) >= USER_RPL; } static inline int v8086_mode(struct pt_regs *regs) { - return (regs->eflags & VM_MASK); + return (regs->flags & VM_MASK); } -#define instruction_pointer(regs) ((regs)->eip) -#define frame_pointer(regs) ((regs)->ebp) +#define instruction_pointer(regs) ((regs)->ip) +#define frame_pointer(regs) ((regs)->bp) #define stack_pointer(regs) ((unsigned long)(regs)) -#define regs_return_value(regs) ((regs)->eax) +#define regs_return_value(regs) ((regs)->ax) extern unsigned long profile_pc(struct pt_regs *regs); #endif /* __KERNEL__ */ #else /* __i386__ */ +#ifndef __KERNEL__ + struct pt_regs { unsigned long r15; unsigned long r14; @@ -96,14 +121,43 @@ struct pt_regs { /* top of stack page */ }; -#ifdef __KERNEL__ +#else /* __KERNEL__ */ + +struct pt_regs { + unsigned long r15; + unsigned long r14; + unsigned long r13; + unsigned long r12; + unsigned long bp; + unsigned long bx; +/* arguments: non interrupts/non tracing syscalls only save upto here*/ + unsigned long r11; + unsigned long r10; + unsigned long r9; + unsigned long r8; + unsigned long ax; + unsigned long cx; + unsigned long dx; + unsigned long si; + unsigned long di; + unsigned long orig_ax; +/* end of arguments */ +/* cpu exception frame or undefined */ + unsigned long ip; + unsigned long cs; + unsigned long flags; + unsigned long sp; + unsigned long ss; +/* top of stack page */ +}; #define user_mode(regs) (!!((regs)->cs & 3)) #define user_mode_vm(regs) user_mode(regs) -#define instruction_pointer(regs) ((regs)->rip) -#define frame_pointer(regs) ((regs)->rbp) -#define stack_pointer(regs) ((regs)->rsp) -#define regs_return_value(regs) ((regs)->rax) +#define v8086_mode(regs) 0 /* No V86 mode support in long mode */ +#define instruction_pointer(regs) ((regs)->ip) +#define frame_pointer(regs) ((regs)->bp) +#define stack_pointer(regs) ((regs)->sp) +#define regs_return_value(regs) ((regs)->ax) extern unsigned long profile_pc(struct pt_regs *regs); void signal_fault(struct pt_regs *regs, void __user *frame, char *where); -- cgit v1.2.2 From 153d5f2e5787c74e9cbb6b6687c9b04be1b59893 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:30:56 +0100 Subject: x86: use generic register names in struct user_regs_struct Switch struct user_regs_struct (defined in , which is no longer exported to userspace) to using register names without e- or r-prefixes for both 32 and 64 bit x86. This is intended as a preliminary step in unifying this code between architectures. Also, be a bit more strict in truncating 32-bit "extended" segment register values to 16 bits. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/user_32.h | 24 +++++++++++++++++------- include/asm-x86/user_64.h | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 17 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/user_32.h b/include/asm-x86/user_32.h index 0e85d2a5e33..ed8b8fc6906 100644 --- a/include/asm-x86/user_32.h +++ b/include/asm-x86/user_32.h @@ -75,13 +75,23 @@ struct user_fxsr_struct { * doesn't use the extra segment registers) */ struct user_regs_struct { - long ebx, ecx, edx, esi, edi, ebp, eax; - unsigned short ds, __ds, es, __es; - unsigned short fs, __fs, gs, __gs; - long orig_eax, eip; - unsigned short cs, __cs; - long eflags, esp; - unsigned short ss, __ss; + unsigned long bx; + unsigned long cx; + unsigned long dx; + unsigned long si; + unsigned long di; + unsigned long bp; + unsigned long ax; + unsigned long ds; + unsigned long es; + unsigned long fs; + unsigned long gs; + unsigned long orig_ax; + unsigned long ip; + unsigned long cs; + unsigned long flags; + unsigned long sp; + unsigned long ss; }; /* When the kernel dumps core, it starts by dumping the user struct - diff --git a/include/asm-x86/user_64.h b/include/asm-x86/user_64.h index 12785c649ac..a5449d456cc 100644 --- a/include/asm-x86/user_64.h +++ b/include/asm-x86/user_64.h @@ -40,13 +40,13 @@ * and both the standard and SIMD floating point data can be accessed via * the new ptrace requests. In either case, changes to the FPU environment * will be reflected in the task's state as expected. - * + * * x86-64 support by Andi Kleen. */ /* This matches the 64bit FXSAVE format as defined by AMD. It is the same as the 32bit format defined by Intel, except that the selector:offset pairs for - data and eip are replaced with flat 64bit pointers. */ + data and eip are replaced with flat 64bit pointers. */ struct user_i387_struct { unsigned short cwd; unsigned short swd; @@ -65,13 +65,34 @@ struct user_i387_struct { * Segment register layout in coredumps. */ struct user_regs_struct { - unsigned long r15,r14,r13,r12,rbp,rbx,r11,r10; - unsigned long r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax; - unsigned long rip,cs,eflags; - unsigned long rsp,ss; - unsigned long fs_base, gs_base; - unsigned long ds,es,fs,gs; -}; + unsigned long r15; + unsigned long r14; + unsigned long r13; + unsigned long r12; + unsigned long bp; + unsigned long bx; + unsigned long r11; + unsigned long r10; + unsigned long r9; + unsigned long r8; + unsigned long ax; + unsigned long cx; + unsigned long dx; + unsigned long si; + unsigned long di; + unsigned long orig_ax; + unsigned long ip; + unsigned long cs; + unsigned long flags; + unsigned long sp; + unsigned long ss; + unsigned long fs_base; + unsigned long gs_base; + unsigned long ds; + unsigned long es; + unsigned long fs; + unsigned long gs; +}; /* When the kernel dumps core, it starts by dumping the user struct - this will be used by gdb to figure out where the data and stack segments @@ -94,7 +115,7 @@ struct user{ This is actually the bottom of the stack, the top of the stack is always found in the esp register. */ - long int signal; /* Signal that caused the core dump. */ + long int signal; /* Signal that caused the core dump. */ int reserved; /* No longer used */ int pad1; struct user_pt_regs * u_ar0; /* Used by gdb to help find the values for */ -- cgit v1.2.2 From 742fa54a62be6a263df14a553bf832724471dfbe Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:30:56 +0100 Subject: x86: use generic register names in struct sigcontext Switch struct sigcontext (defined in ) to using register names withut e- or r-prefixes for both 32- and 64-bit x86. This is intended as a preliminary step in unifying this code between architectures. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/sigcontext.h | 42 +++++++++++++++++++++--------------------- include/asm-x86/sigcontext32.h | 22 +++++++++++----------- 2 files changed, 32 insertions(+), 32 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/sigcontext.h b/include/asm-x86/sigcontext.h index c047f9dc342..681deade5f0 100644 --- a/include/asm-x86/sigcontext.h +++ b/include/asm-x86/sigcontext.h @@ -63,20 +63,20 @@ struct sigcontext { unsigned short fs, __fsh; unsigned short es, __esh; unsigned short ds, __dsh; - unsigned long edi; - unsigned long esi; - unsigned long ebp; - unsigned long esp; - unsigned long ebx; - unsigned long edx; - unsigned long ecx; - unsigned long eax; + unsigned long di; + unsigned long si; + unsigned long bp; + unsigned long sp; + unsigned long bx; + unsigned long dx; + unsigned long cx; + unsigned long ax; unsigned long trapno; unsigned long err; - unsigned long eip; + unsigned long ip; unsigned short cs, __csh; - unsigned long eflags; - unsigned long esp_at_signal; + unsigned long flags; + unsigned long sp_at_signal; unsigned short ss, __ssh; struct _fpstate __user * fpstate; unsigned long oldmask; @@ -111,16 +111,16 @@ struct sigcontext { unsigned long r13; unsigned long r14; unsigned long r15; - unsigned long rdi; - unsigned long rsi; - unsigned long rbp; - unsigned long rbx; - unsigned long rdx; - unsigned long rax; - unsigned long rcx; - unsigned long rsp; - unsigned long rip; - unsigned long eflags; /* RFLAGS */ + unsigned long di; + unsigned long si; + unsigned long bp; + unsigned long bx; + unsigned long dx; + unsigned long ax; + unsigned long cx; + unsigned long sp; + unsigned long ip; + unsigned long flags; unsigned short cs; unsigned short gs; unsigned short fs; diff --git a/include/asm-x86/sigcontext32.h b/include/asm-x86/sigcontext32.h index 3d657038ab7..6ffab4fd593 100644 --- a/include/asm-x86/sigcontext32.h +++ b/include/asm-x86/sigcontext32.h @@ -48,20 +48,20 @@ struct sigcontext_ia32 { unsigned short fs, __fsh; unsigned short es, __esh; unsigned short ds, __dsh; - unsigned int edi; - unsigned int esi; - unsigned int ebp; - unsigned int esp; - unsigned int ebx; - unsigned int edx; - unsigned int ecx; - unsigned int eax; + unsigned int di; + unsigned int si; + unsigned int bp; + unsigned int sp; + unsigned int bx; + unsigned int dx; + unsigned int cx; + unsigned int ax; unsigned int trapno; unsigned int err; - unsigned int eip; + unsigned int ip; unsigned short cs, __csh; - unsigned int eflags; - unsigned int esp_at_signal; + unsigned int flags; + unsigned int sp_at_signal; unsigned short ss, __ssh; unsigned int fpstate; /* really (struct _fpstate_ia32 *) */ unsigned int oldmask; -- cgit v1.2.2 From 35d0991ffa544945d2e1992169c097286b7c0bfb Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:57 +0100 Subject: x86: eflags enum This removes the EF_* enum from . It is no longer used, and duplicates the X86_EFLAGS_* constants from . Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 9187b2fab75..1b7a8b8d6f6 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -170,28 +170,6 @@ extern int ptrace_set_debugreg(struct task_struct *child, int n, unsigned long); extern unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs); -enum { - EF_CF = 0x00000001, - EF_PF = 0x00000004, - EF_AF = 0x00000010, - EF_ZF = 0x00000040, - EF_SF = 0x00000080, - EF_TF = 0x00000100, - EF_IE = 0x00000200, - EF_DF = 0x00000400, - EF_OF = 0x00000800, - EF_IOPL = 0x00003000, - EF_IOPL_RING0 = 0x00000000, - EF_IOPL_RING1 = 0x00001000, - EF_IOPL_RING2 = 0x00002000, - EF_NT = 0x00004000, /* nested task */ - EF_RF = 0x00010000, /* resume */ - EF_VM = 0x00020000, /* virtual mode */ - EF_AC = 0x00040000, /* alignment */ - EF_VIF = 0x00080000, /* virtual interrupt */ - EF_VIP = 0x00100000, /* virtual interrupt pending */ - EF_ID = 0x00200000, /* id */ -}; #endif /* __KERNEL__ */ #endif /* !__i386__ */ -- cgit v1.2.2 From 0f5340933f9bacb403f49baaf8073320e3984841 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:59 +0100 Subject: x86: x86-32 thread_struct.debugreg This replaces the debugreg[7] member of thread_struct with individual members debugreg0, etc. This saves two words for the dummies 4 and 5, and harmonizes the code between 32 and 64. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_32.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index c85400fe58c..d50a4b48d44 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -353,7 +353,12 @@ struct thread_struct { unsigned long fs; unsigned long gs; /* Hardware debugging registers */ - unsigned long debugreg[8]; /* %%db0-7 debug registers */ + unsigned long debugreg0; + unsigned long debugreg1; + unsigned long debugreg2; + unsigned long debugreg3; + unsigned long debugreg6; + unsigned long debugreg7; /* fault info */ unsigned long cr2, trap_no, error_code; /* floating point info */ -- cgit v1.2.2 From cbc9d9d98215f08ed998228e7bce88502d1ce360 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:02 +0100 Subject: x86: x86 ptrace merge complete This switches over the 64-bit build to use the shared ptrace code, instead of the old ptrace_64.c and arch/x86/ia32/ptrace32.c code. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 1b7a8b8d6f6..9228870f615 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -164,9 +164,6 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where); struct task_struct; -extern unsigned long ptrace_get_debugreg(struct task_struct *child, int n); -extern int ptrace_set_debugreg(struct task_struct *child, int n, unsigned long); - extern unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs); -- cgit v1.2.2 From faca62273b602ab482fb7d3d940dbf41ef08b00e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:31:02 +0100 Subject: x86: use generic register name in the thread and tss structures This changes size-specific register names (eip/rip, esp/rsp, etc.) to generic names in the thread and tss structures. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 6 +++--- include/asm-x86/processor_32.h | 37 +++++++++++++++++-------------------- include/asm-x86/processor_64.h | 20 ++++++++++---------- include/asm-x86/system_32.h | 4 ++-- include/asm-x86/system_64.h | 2 +- 5 files changed, 33 insertions(+), 36 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index be7b934f6c5..d1780e32722 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -101,7 +101,7 @@ struct pv_cpu_ops { int entrynum, u32 low, u32 high); void (*write_idt_entry)(struct desc_struct *, int entrynum, u32 low, u32 high); - void (*load_esp0)(struct tss_struct *tss, struct thread_struct *t); + void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t); void (*set_iopl_mask)(unsigned mask); @@ -449,10 +449,10 @@ static inline int paravirt_enabled(void) return pv_info.paravirt_enabled; } -static inline void load_esp0(struct tss_struct *tss, +static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread) { - PVOP_VCALL2(pv_cpu_ops.load_esp0, tss, thread); + PVOP_VCALL2(pv_cpu_ops.load_sp0, tss, thread); } #define ARCH_SETUP pv_init_ops.arch_setup(); diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index d50a4b48d44..6846cc34640 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -292,20 +292,17 @@ struct thread_struct; /* This is the TSS defined by the hardware. */ struct i386_hw_tss { unsigned short back_link,__blh; - unsigned long esp0; + unsigned long sp0; unsigned short ss0,__ss0h; - unsigned long esp1; + unsigned long sp1; unsigned short ss1,__ss1h; /* ss1 is used to cache MSR_IA32_SYSENTER_CS */ - unsigned long esp2; + unsigned long sp2; unsigned short ss2,__ss2h; unsigned long __cr3; - unsigned long eip; - unsigned long eflags; - unsigned long eax,ecx,edx,ebx; - unsigned long esp; - unsigned long ebp; - unsigned long esi; - unsigned long edi; + unsigned long ip; + unsigned long flags; + unsigned long ax, cx, dx, bx; + unsigned long sp, bp, si, di; unsigned short es, __esh; unsigned short cs, __csh; unsigned short ss, __ssh; @@ -346,10 +343,10 @@ struct tss_struct { struct thread_struct { /* cached TLS descriptors. */ struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; - unsigned long esp0; + unsigned long sp0; unsigned long sysenter_cs; - unsigned long eip; - unsigned long esp; + unsigned long ip; + unsigned long sp; unsigned long fs; unsigned long gs; /* Hardware debugging registers */ @@ -366,7 +363,7 @@ struct thread_struct { /* virtual 86 mode info */ struct vm86_struct __user * vm86_info; unsigned long screen_bitmap; - unsigned long v86flags, v86mask, saved_esp0; + unsigned long v86flags, v86mask, saved_sp0; unsigned int saved_fs, saved_gs; /* IO permissions */ unsigned long *io_bitmap_ptr; @@ -378,7 +375,7 @@ struct thread_struct { }; #define INIT_THREAD { \ - .esp0 = sizeof(init_stack) + (long)&init_stack, \ + .sp0 = sizeof(init_stack) + (long)&init_stack, \ .vm86_info = NULL, \ .sysenter_cs = __KERNEL_CS, \ .io_bitmap_ptr = NULL, \ @@ -393,7 +390,7 @@ struct thread_struct { */ #define INIT_TSS { \ .x86_tss = { \ - .esp0 = sizeof(init_stack) + (long)&init_stack, \ + .sp0 = sizeof(init_stack) + (long)&init_stack, \ .ss0 = __KERNEL_DS, \ .ss1 = __KERNEL_CS, \ .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ @@ -503,9 +500,9 @@ static inline void rep_nop(void) #define cpu_relax() rep_nop() -static inline void native_load_esp0(struct tss_struct *tss, struct thread_struct *thread) +static inline void native_load_sp0(struct tss_struct *tss, struct thread_struct *thread) { - tss->x86_tss.esp0 = thread->esp0; + tss->x86_tss.sp0 = thread->sp0; /* This can only happen when SEP is enabled, no need to test "SEP"arately */ if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { tss->x86_tss.ss1 = thread->sysenter_cs; @@ -585,9 +582,9 @@ static inline void native_set_iopl_mask(unsigned mask) #define paravirt_enabled() 0 #define __cpuid native_cpuid -static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) +static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread) { - native_load_esp0(tss, thread); + native_load_sp0(tss, thread); } /* diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 797770113e6..0780f3e3fdf 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -177,9 +177,9 @@ union i387_union { struct tss_struct { u32 reserved1; - u64 rsp0; - u64 rsp1; - u64 rsp2; + u64 sp0; + u64 sp1; + u64 sp2; u64 reserved2; u64 ist[7]; u32 reserved3; @@ -216,9 +216,9 @@ DECLARE_PER_CPU(struct orig_ist, orig_ist); #endif struct thread_struct { - unsigned long rsp0; - unsigned long rsp; - unsigned long userrsp; /* Copy from PDA */ + unsigned long sp0; + unsigned long sp; + unsigned long usersp; /* Copy from PDA */ unsigned long fs; unsigned long gs; unsigned short es, ds, fsindex, gsindex; @@ -245,11 +245,11 @@ struct thread_struct { } __attribute__((aligned(16))); #define INIT_THREAD { \ - .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \ + .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } #define INIT_TSS { \ - .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \ + .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } #define INIT_MMAP \ @@ -293,10 +293,10 @@ extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork. */ -#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8)) +#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8)) extern unsigned long get_wchan(struct task_struct *p); -#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1) +#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ip) #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index db6283eb5e4..f5b3f77f531 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -28,9 +28,9 @@ extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struc "1:\t" \ "popl %%ebp\n\t" \ "popfl" \ - :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \ + :"=m" (prev->thread.sp),"=m" (prev->thread.ip), \ "=a" (last),"=S" (esi),"=D" (edi) \ - :"m" (next->thread.esp),"m" (next->thread.eip), \ + :"m" (next->thread.sp),"m" (next->thread.ip), \ "2" (prev), "d" (next)); \ } while (0) diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 6e9e4841a2d..3dcb217a720 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -40,7 +40,7 @@ RESTORE_CONTEXT \ : "=a" (last) \ : [next] "S" (next), [prev] "D" (prev), \ - [threadrsp] "i" (offsetof(struct task_struct, thread.rsp)), \ + [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ [ti_flags] "i" (offsetof(struct thread_info, flags)),\ [tif_fork] "i" (TIF_FORK), \ [thread_info] "i" (offsetof(struct task_struct, stack)), \ -- cgit v1.2.2 From 1c6f70309900c47eeaef12c97b206fcccde1ebe2 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Jan 2008 13:31:02 +0100 Subject: x86: define all _PAGE_* in terms of _PAGE_BIT_* on 64-bit This patch defines the _PAGE_* paging attributes in pgtable_64.h in terms of the former defined _PAGE_BIT_* values. Signed-off-by: Joerg Roedel Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 9b0ff477b39..9d4f11dd566 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -150,19 +150,23 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define _PAGE_BIT_ACCESSED 5 #define _PAGE_BIT_DIRTY 6 #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ +#define _PAGE_BIT_FILE 6 #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ -#define _PAGE_PRESENT 0x001 -#define _PAGE_RW 0x002 -#define _PAGE_USER 0x004 -#define _PAGE_PWT 0x008 -#define _PAGE_PCD 0x010 -#define _PAGE_ACCESSED 0x020 -#define _PAGE_DIRTY 0x040 -#define _PAGE_PSE 0x080 /* 2MB page */ -#define _PAGE_FILE 0x040 /* nonlinear file mapping, saved PTE; unset:swap */ -#define _PAGE_GLOBAL 0x100 /* Global TLB entry */ +#define _PAGE_PRESENT (_AC(1,UL)<<_PAGE_BIT_PRESENT) +#define _PAGE_RW (_AC(1,UL)<<_PAGE_BIT_RW) +#define _PAGE_USER (_AC(1,UL)<<_PAGE_BIT_USER) +#define _PAGE_PWT (_AC(1,UL)<<_PAGE_BIT_PWT) +#define _PAGE_PCD (_AC(1,UL)<<_PAGE_BIT_PCD) +#define _PAGE_ACCESSED (_AC(1,UL)<<_PAGE_BIT_ACCESSED) +#define _PAGE_DIRTY (_AC(1,UL)<<_PAGE_BIT_DIRTY) +/* 2MB page */ +#define _PAGE_PSE (_AC(1,UL)<<_PAGE_BIT_PSE) +/* nonlinear file mapping, saved PTE; unset:swap */ +#define _PAGE_FILE (_AC(1,UL)<<_PAGE_BIT_FILE) +/* Global TLB entry */ +#define _PAGE_GLOBAL (_AC(1,UL)<<_PAGE_BIT_GLOBAL) #define _PAGE_PROTNONE 0x080 /* If not present */ #define _PAGE_NX (_AC(1,UL)<<_PAGE_BIT_NX) @@ -248,8 +252,7 @@ static inline unsigned long pmd_bad(pmd_t pmd) #define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) #define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) -#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) /* FIXME: is this - right? */ +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) /* FIXME: is this right? */ #define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_pfn(x) ((pte_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) -- cgit v1.2.2 From 751de83c0c94a5235f14cff8549d3b39e745eb2b Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:03 +0100 Subject: x86: unify msr smp funcs The functions under #ifdef CONFIG_SMP in msr.h are the same for both x86_64 and i386, and this patches removes one of them, putting them in a single location Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 80b027081b3..5c95d0be113 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -139,29 +139,6 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) } while(0) #endif /* !CONFIG_PARAVIRT */ -#ifdef CONFIG_SMP -void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); -void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); -int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); -int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); -#else /* CONFIG_SMP */ -static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - rdmsr(msr_no, *l, *h); -} -static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) -{ - wrmsr(msr_no, l, h); -} -static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - return rdmsr_safe(msr_no, l, h); -} -static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) -{ - return wrmsr_safe(msr_no, l, h); -} -#endif /* CONFIG_SMP */ #endif /* ! __ASSEMBLY__ */ #endif /* __KERNEL__ */ @@ -327,6 +304,12 @@ static inline unsigned int cpuid_edx(unsigned int op) :"c"(msr), "i"(-EIO), "0"(0)); \ ret__; }) +#endif /* __ASSEMBLY__ */ + +#endif /* !__i386__ */ + +#ifndef __ASSEMBLY__ + #ifdef CONFIG_SMP void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); @@ -351,8 +334,6 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) } #endif /* CONFIG_SMP */ #endif /* __KERNEL__ */ -#endif /* __ASSEMBLY__ */ - -#endif /* !__i386__ */ +#endif /* __ASSEMBLY__ */ #endif -- cgit v1.2.2 From 4e87173eacfd0d798aeeba14026893797826bc93 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:03 +0100 Subject: x86: split get_cycles_sync This patch splits get_cycles_sync() into __get_cycles_sync(), and the rdtscll part. Paravirt guests cannot issue rdtscl directly, as it involves a function call in vdso area. So, using the __get_cycles_sync() base, we introduce vget_cycles_sync, which then calls the native version of rdtscll. Ideally, however, a guest should define its own clocksource, together with a vread function Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/tsc.h | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index d7b1c4e7a10..9b7d264897f 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -33,14 +33,14 @@ static inline cycles_t get_cycles(void) } /* Like get_cycles, but make sure the CPU is synchronized. */ -static __always_inline cycles_t get_cycles_sync(void) +static __always_inline cycles_t __get_cycles_sync(void) { unsigned long long ret; unsigned eax, edx; /* - * Use RDTSCP if possible; it is guaranteed to be synchronous - * and doesn't cause a VMEXIT on Hypervisors + * Use RDTSCP if possible; it is guaranteed to be synchronous + * and doesn't cause a VMEXIT on Hypervisors */ alternative_io(ASM_NOP3, ".byte 0x0f,0x01,0xf9", X86_FEATURE_RDTSCP, ASM_OUTPUT2("=a" (eax), "=d" (edx)), @@ -55,11 +55,40 @@ static __always_inline cycles_t get_cycles_sync(void) */ alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC, "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); - rdtscll(ret); + return 0; +} + +static __always_inline cycles_t get_cycles_sync(void) +{ + unsigned long long ret; + ret = __get_cycles_sync(); + if (!ret) + rdtscll(ret); return ret; } +#ifdef CONFIG_PARAVIRT +/* + * For paravirt guests, some functionalities are executed through function + * pointers in the various pvops structures. + * These function pointers exist inside the kernel and can not + * be accessed by user space. To avoid this, we make a copy of the + * get_cycles_sync (called in kernel) but force the use of native_read_tsc. + * Ideally, the guest should set up it's own clock and vread + */ +static __always_inline long long vget_cycles_sync(void) +{ + unsigned long long ret; + ret = __get_cycles_sync(); + if (!ret) + ret = native_read_tsc(); + return ret; +} +#else +# define vget_cycles_sync() get_cycles_sync() +#endif + extern void tsc_init(void); extern void mark_tsc_unstable(char *reason); extern int unsynchronized_tsc(void); -- cgit v1.2.2 From c758ecf62ad94ddfeb4e7d8a5498bdcb2e3c85db Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:03 +0100 Subject: x86: unify cpuid functions cpuid is not very different between i386 and x86_64. We move away the x86_64 version from msr.h, and unify them at processor.h, where they belong. cpuid() paravirt then comes for free. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 67 ------------------------------------ include/asm-x86/processor.h | 78 ++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 69 ------------------------------------- 3 files changed, 78 insertions(+), 136 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 5c95d0be113..0648b2d57a3 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -203,73 +203,6 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) : "c" (counter)) -static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - __asm__("cpuid" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (op)); -} - -/* Some CPUID calls want 'count' to be placed in ecx */ -static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, - int *edx) -{ - __asm__("cpuid" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (op), "c" (count)); -} - -/* - * CPUID functions returning a single datum - */ -static inline unsigned int cpuid_eax(unsigned int op) -{ - unsigned int eax; - - __asm__("cpuid" - : "=a" (eax) - : "0" (op) - : "bx", "cx", "dx"); - return eax; -} -static inline unsigned int cpuid_ebx(unsigned int op) -{ - unsigned int eax, ebx; - - __asm__("cpuid" - : "=a" (eax), "=b" (ebx) - : "0" (op) - : "cx", "dx" ); - return ebx; -} -static inline unsigned int cpuid_ecx(unsigned int op) -{ - unsigned int eax, ecx; - - __asm__("cpuid" - : "=a" (eax), "=c" (ecx) - : "0" (op) - : "bx", "dx" ); - return ecx; -} -static inline unsigned int cpuid_edx(unsigned int op) -{ - unsigned int eax, edx; - - __asm__("cpuid" - : "=a" (eax), "=d" (edx) - : "0" (op) - : "bx", "cx"); - return edx; -} - #ifdef __KERNEL__ /* wrmsr with exception handling */ diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 46e1c04e309..dea81b70895 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -1,5 +1,83 @@ +#ifndef __ASM_X86_PROCESSOR_H +#define __ASM_X86_PROCESSOR_H + +static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + /* ecx is often an input as well as an output. */ + __asm__("cpuid" + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), + "=d" (*edx) + : "0" (*eax), "2" (*ecx)); +} + + #ifdef CONFIG_X86_32 # include "processor_32.h" #else # include "processor_64.h" #endif + +#ifndef CONFIG_PARAVIRT +#define __cpuid native_cpuid +#endif + +/* + * Generic CPUID function + * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx + * resulting in stale register contents being returned. + */ +static inline void cpuid(unsigned int op, + unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + *eax = op; + *ecx = 0; + __cpuid(eax, ebx, ecx, edx); +} + +/* Some CPUID calls want 'count' to be placed in ecx */ +static inline void cpuid_count(unsigned int op, int count, + unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + *eax = op; + *ecx = count; + __cpuid(eax, ebx, ecx, edx); +} + +/* + * CPUID functions returning a single datum + */ +static inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return eax; +} +static inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return ebx; +} +static inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return ecx; +} +static inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return edx; +} + +#endif diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 6846cc34640..0d83da19812 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -133,18 +133,6 @@ extern void detect_ht(struct cpuinfo_x86 *c); static inline void detect_ht(struct cpuinfo_x86 *c) {} #endif -static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - /* ecx is often an input as well as an output. */ - __asm__("cpuid" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (*eax), "2" (*ecx)); -} - #define load_cr3(pgdir) write_cr3(__pa(pgdir)) /* @@ -580,7 +568,6 @@ static inline void native_set_iopl_mask(unsigned mask) #include #else #define paravirt_enabled() 0 -#define __cpuid native_cpuid static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread) { @@ -598,62 +585,6 @@ static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread #define set_iopl_mask native_set_iopl_mask #endif /* CONFIG_PARAVIRT */ -/* - * Generic CPUID function - * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx - * resulting in stale register contents being returned. - */ -static inline void cpuid(unsigned int op, - unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = 0; - __cpuid(eax, ebx, ecx, edx); -} - -/* Some CPUID calls want 'count' to be placed in ecx */ -static inline void cpuid_count(unsigned int op, int count, - unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = count; - __cpuid(eax, ebx, ecx, edx); -} - -/* - * CPUID functions returning a single datum - */ -static inline unsigned int cpuid_eax(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return eax; -} -static inline unsigned int cpuid_ebx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return ebx; -} -static inline unsigned int cpuid_ecx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return ecx; -} -static inline unsigned int cpuid_edx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return edx; -} - /* generic versions from gas */ #define GENERIC_NOP1 ".byte 0x90\n" #define GENERIC_NOP2 ".byte 0x89,0xf6\n" -- cgit v1.2.2 From 8f12dea6135d0a55b151dcb4c6bbe211f5f8d35d Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:06 +0100 Subject: x86: introduce native_read_tscp Targetting paravirt, this patch introduces native_read_tscp, in place of rdtscp() macro. When in a paravirt guest, this will involve a function call, and thus, cannot be done in the vdso area. These users then have to call the native version directly Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 0648b2d57a3..b6262e99fc8 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -7,6 +7,27 @@ # include #endif +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ +static inline unsigned long long native_read_tscp(int *aux) +{ + unsigned long low, high; + asm volatile (".byte 0x0f,0x01,0xf9" + : "=a" (low), "=d" (high), "=c" (*aux)); + return low | ((u64)high >> 32); +} + +#define rdtscp(low, high, aux) \ + do { \ + unsigned long long _val = native_read_tscp(&(aux)); \ + (low) = (u32)_val; \ + (high) = (u32)(_val >> 32); \ + } while (0) + +#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux)) +#endif +#endif + #ifdef __i386__ #ifdef __KERNEL__ @@ -178,8 +199,6 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) #define rdtscl(low) \ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") -#define rdtscp(low,high,aux) \ - __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) #define rdtscll(val) do { \ unsigned int __a,__d; \ @@ -187,12 +206,6 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ } while(0) -#define rdtscpll(val, aux) do { \ - unsigned long __a, __d; \ - __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ - (val) = (__d << 32) | __a; \ -} while (0) - #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) #define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0) -- cgit v1.2.2 From b8d1fae7dbde6a1227fa142acecb48dc3dd63817 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:07 +0100 Subject: x86: change rdpmc interface the rdpmc instruction gets a counter argument in rcx. However, the i386 version was ignoring it. To make both x86_64 and i386 versions the same, as well as to comply with the instruction semantics, this parameter is added in the i386 version Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 6 +++--- include/asm-x86/paravirt.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index b6262e99fc8..effb7319c0a 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -94,10 +94,10 @@ static inline unsigned long long native_read_tsc(void) return val; } -static inline unsigned long long native_read_pmc(void) +static inline unsigned long long native_read_pmc(int counter) { unsigned long long val; - asm volatile("rdpmc" : "=A" (val)); + asm volatile("rdpmc" : "=A" (val) : "c" (counter)); return val; } @@ -154,7 +154,7 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) #define rdpmc(counter,low,high) \ do { \ - u64 _l = native_read_pmc(); \ + u64 _l = native_read_pmc(counter); \ (low) = (u32)_l; \ (high) = (u32)(_l >> 32); \ } while(0) diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index d1780e32722..4782be68d0f 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -118,7 +118,7 @@ struct pv_cpu_ops { int (*write_msr)(unsigned int msr, u64 val); u64 (*read_tsc)(void); - u64 (*read_pmc)(void); + u64 (*read_pmc)(int counter); /* These two are jmp to, not actually called. */ void (*irq_enable_syscall_ret)(void); -- cgit v1.2.2 From c9dcda5ce46c395c5c99003e259e1973dface640 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:07 +0100 Subject: x86: change write msr functions interface This patche changes the native_write_msr() and friends interface to explicitly take 2 32-bit registers instead of a 64-bit value. The change will ease the merge with 64-bit code. As the 64-bit value will be passed as two registers anyway in i386, the PVOP_CALL interface has to account for that and use low/high parameters It would force the x86_64 version to be different. The change does not make i386 generated code less efficient. As said above, it would get the values from two registers anyway. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 19 ++++++++++--------- include/asm-x86/paravirt.h | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index effb7319c0a..cb722235889 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -63,13 +63,14 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr, return val; } -static inline void native_write_msr(unsigned int msr, unsigned long long val) +static inline void native_write_msr(unsigned int msr, + unsigned low, unsigned high) { - asm volatile("wrmsr" : : "c" (msr), "A"(val)); + asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high)); } static inline int native_write_msr_safe(unsigned int msr, - unsigned long long val) + unsigned low, unsigned high) { int err; asm volatile("2: wrmsr ; xorl %0,%0\n" @@ -82,7 +83,7 @@ static inline int native_write_msr_safe(unsigned int msr, " .long 2b,3b\n\t" ".previous" : "=a" (err) - : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), + : "c" (msr), "0" (low), "d" (high), "i" (-EFAULT)); return err; } @@ -118,20 +119,20 @@ static inline unsigned long long native_read_pmc(int counter) (val2) = (u32)(__val >> 32); \ } while(0) -static inline void wrmsr(u32 __msr, u32 __low, u32 __high) +static inline void wrmsr(unsigned msr, unsigned low, unsigned high) { - native_write_msr(__msr, ((u64)__high << 32) | __low); + native_write_msr(msr, low, high); } #define rdmsrl(msr,val) \ ((val) = native_read_msr(msr)) -#define wrmsrl(msr,val) native_write_msr(msr, val) +#define wrmsrl(msr, val) native_write_msr(msr, (u32)val, (u32)(val >> 32)) /* wrmsr with exception handling */ -static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) +static inline int wrmsr_safe(unsigned msr, unsigned low, unsigned high) { - return native_write_msr_safe(__msr, ((u64)__high << 32) | __low); + return native_write_msr_safe(msr, low, high); } /* rdmsr with exception handling */ diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 4782be68d0f..e95c2a65516 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -115,7 +115,7 @@ struct pv_cpu_ops { /* MSR, PMC and TSR operations. err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ u64 (*read_msr)(unsigned int msr, int *err); - int (*write_msr)(unsigned int msr, u64 val); + int (*write_msr)(unsigned int msr, unsigned low, unsigned high); u64 (*read_tsc)(void); u64 (*read_pmc)(int counter); -- cgit v1.2.2 From 56ec1ddcff967e51d98427e4efcbfc90de67efe3 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:07 +0100 Subject: x86: make fixups wordsize agnostic This patch uses the _ASM_ALIGN and _ASM_PTR macros to make the fixups in native_read/write_msr_safe look the same for x86_64 and i386. Besides using this macros, we also have to take the explicit instruction suffixes out. It's okay because all this instructions uses registers, and can be sized by them. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index cb722235889..792fde2e890 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -33,6 +33,7 @@ static inline unsigned long long native_read_tscp(int *aux) #ifdef __KERNEL__ #ifndef __ASSEMBLY__ +#include #include static inline unsigned long long native_read_msr(unsigned int msr) @@ -48,14 +49,14 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr, { unsigned long long val; - asm volatile("2: rdmsr ; xorl %0,%0\n" + asm volatile("2: rdmsr ; xor %0,%0\n" "1:\n\t" ".section .fixup,\"ax\"\n\t" - "3: movl %3,%0 ; jmp 1b\n\t" + "3: mov %3,%0 ; jmp 1b\n\t" ".previous\n\t" ".section __ex_table,\"a\"\n" - " .align 4\n\t" - " .long 2b,3b\n\t" + _ASM_ALIGN "\n\t" + _ASM_PTR " 2b,3b\n\t" ".previous" : "=r" (*err), "=A" (val) : "c" (msr), "i" (-EFAULT)); @@ -73,14 +74,14 @@ static inline int native_write_msr_safe(unsigned int msr, unsigned low, unsigned high) { int err; - asm volatile("2: wrmsr ; xorl %0,%0\n" + asm volatile("2: wrmsr ; xor %0,%0\n" "1:\n\t" ".section .fixup,\"ax\"\n\t" - "3: movl %4,%0 ; jmp 1b\n\t" + "3: mov %4,%0 ; jmp 1b\n\t" ".previous\n\t" ".section __ex_table,\"a\"\n" - " .align 4\n\t" - " .long 2b,3b\n\t" + _ASM_ALIGN "\n\t" + _ASM_PTR " 2b,3b\n\t" ".previous" : "=a" (err) : "c" (msr), "0" (low), "d" (high), -- cgit v1.2.2 From c210d24986dc19e387c10508c0bc2faadadc1a2e Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:07 +0100 Subject: x86: integrate 32-bit and 64-bit code in msr.h This patches proceeds with the integration of msr.h, making the code unified, instead of having a version for each architecture. We stick with the native_* functions, and then paravirt comes for free. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 167 ++++++++++++++------------------------------------ 1 file changed, 47 insertions(+), 120 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 792fde2e890..040d3910d89 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -9,6 +9,10 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ + +#include +#include + static inline unsigned long long native_read_tscp(int *aux) { unsigned long low, high; @@ -17,37 +21,36 @@ static inline unsigned long long native_read_tscp(int *aux) return low | ((u64)high >> 32); } -#define rdtscp(low, high, aux) \ - do { \ - unsigned long long _val = native_read_tscp(&(aux)); \ - (low) = (u32)_val; \ - (high) = (u32)(_val >> 32); \ - } while (0) - -#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux)) -#endif +/* + * i386 calling convention returns 64-bit value in edx:eax, while + * x86_64 returns at rax. Also, the "A" constraint does not really + * mean rdx:rax in x86_64, so we need specialized behaviour for each + * architecture + */ +#ifdef CONFIG_X86_64 +#define DECLARE_ARGS(val, low, high) unsigned low, high +#define EAX_EDX_VAL(val, low, high) (low | ((u64)(high) << 32)) +#define EAX_EDX_ARGS(val, low, high) "a" (low), "d" (high) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_ARGS(val, low, high) "A" (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) #endif -#ifdef __i386__ - -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ - -#include -#include - static inline unsigned long long native_read_msr(unsigned int msr) { - unsigned long long val; + DECLARE_ARGS(val, low, high); - asm volatile("rdmsr" : "=A" (val) : "c" (msr)); - return val; + asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr)); + return EAX_EDX_VAL(val, low, high); } static inline unsigned long long native_read_msr_safe(unsigned int msr, int *err) { - unsigned long long val; + DECLARE_ARGS(val, low, high); asm volatile("2: rdmsr ; xor %0,%0\n" "1:\n\t" @@ -58,10 +61,9 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr, _ASM_ALIGN "\n\t" _ASM_PTR " 2b,3b\n\t" ".previous" - : "=r" (*err), "=A" (val) + : "=r" (*err), EAX_EDX_RET(val, low, high) : "c" (msr), "i" (-EFAULT)); - - return val; + return EAX_EDX_VAL(val, low, high); } static inline void native_write_msr(unsigned int msr, @@ -91,16 +93,18 @@ static inline int native_write_msr_safe(unsigned int msr, static inline unsigned long long native_read_tsc(void) { - unsigned long long val; - asm volatile("rdtsc" : "=A" (val)); - return val; + DECLARE_ARGS(val, low, high); + + asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); + return EAX_EDX_VAL(val, low, high); } static inline unsigned long long native_read_pmc(int counter) { - unsigned long long val; - asm volatile("rdpmc" : "=A" (val) : "c" (counter)); - return val; + DECLARE_ARGS(val, low, high); + + asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter)); + return EAX_EDX_VAL(val, low, high); } #ifdef CONFIG_PARAVIRT @@ -128,7 +132,8 @@ static inline void wrmsr(unsigned msr, unsigned low, unsigned high) #define rdmsrl(msr,val) \ ((val) = native_read_msr(msr)) -#define wrmsrl(msr, val) native_write_msr(msr, (u32)val, (u32)(val >> 32)) +#define wrmsrl(msr, val) \ + native_write_msr(msr, (u32)((u64)(val)), (u32)((u64)(val) >> 32)) /* wrmsr with exception handling */ static inline int wrmsr_safe(unsigned msr, unsigned low, unsigned high) @@ -160,104 +165,25 @@ static inline int wrmsr_safe(unsigned msr, unsigned low, unsigned high) (low) = (u32)_l; \ (high) = (u32)(_l >> 32); \ } while(0) -#endif /* !CONFIG_PARAVIRT */ - -#endif /* ! __ASSEMBLY__ */ -#endif /* __KERNEL__ */ - -#else /* __i386__ */ - -#ifndef __ASSEMBLY__ -#include -/* - * Access to machine-specific registers (available on 586 and better only) - * Note: the rd* operations modify the parameters directly (without using - * pointer indirection), this allows gcc to optimize better - */ - -#define rdmsr(msr,val1,val2) \ - __asm__ __volatile__("rdmsr" \ - : "=a" (val1), "=d" (val2) \ - : "c" (msr)) - -#define rdmsrl(msr,val) do { unsigned long a__,b__; \ - __asm__ __volatile__("rdmsr" \ - : "=a" (a__), "=d" (b__) \ - : "c" (msr)); \ - val = a__ | (b__<<32); \ -} while(0) - -#define wrmsr(msr,val1,val2) \ - __asm__ __volatile__("wrmsr" \ - : /* no outputs */ \ - : "c" (msr), "a" (val1), "d" (val2)) - -#define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) +#define rdtscp(low, high, aux) \ + do { \ + unsigned long long _val = native_read_tscp(&(aux)); \ + (low) = (u32)_val; \ + (high) = (u32)(_val >> 32); \ + } while (0) -#define rdtsc(low,high) \ - __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) +#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux)) -#define rdtscl(low) \ - __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") +#endif /* !CONFIG_PARAVIRT */ -#define rdtscll(val) do { \ - unsigned int __a,__d; \ - __asm__ __volatile__("rdtsc" : "=a" (__a), "=d" (__d)); \ - (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ -} while(0) +#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) #define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0) -#define rdpmc(counter,low,high) \ - __asm__ __volatile__("rdpmc" \ - : "=a" (low), "=d" (high) \ - : "c" (counter)) - - -#ifdef __KERNEL__ - -/* wrmsr with exception handling */ -#define wrmsr_safe(msr,a,b) ({ int ret__; \ - asm volatile("2: wrmsr ; xorl %0,%0\n" \ - "1:\n\t" \ - ".section .fixup,\"ax\"\n\t" \ - "3: movl %4,%0 ; jmp 1b\n\t" \ - ".previous\n\t" \ - ".section __ex_table,\"a\"\n" \ - " .align 8\n\t" \ - " .quad 2b,3b\n\t" \ - ".previous" \ - : "=a" (ret__) \ - : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \ - ret__; }) - -#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) - -#define rdmsr_safe(msr,a,b) \ - ({ int ret__; \ - asm volatile ("1: rdmsr\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: movl %4,%0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .align 8\n" \ - " .quad 1b,3b\n" \ - ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \ - :"c"(msr), "i"(-EIO), "0"(0)); \ - ret__; }) - -#endif /* __ASSEMBLY__ */ - -#endif /* !__i386__ */ - -#ifndef __ASSEMBLY__ - #ifdef CONFIG_SMP void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); @@ -281,7 +207,8 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) return wrmsr_safe(msr_no, l, h); } #endif /* CONFIG_SMP */ -#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ + #endif -- cgit v1.2.2 From 82f74e7159749cc511ebf5954a7b9ea6ad634949 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:07 +0100 Subject: x86: unify include/asm-x86/linkage_[32|64].h Remove definitions of FASTCALL/fastcall from linkage_32 as compiled with -regparm=3 by default since 2.6.20 and should no longer be needed. CONFIG X86_64 and CONFIG_X86_ALIGNMENT_16 are mutually exclusive as found in Kconfig.cpu so it should be fine to test them separately. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/linkage.h | 21 ++++++++++++++++++--- include/asm-x86/linkage_32.h | 15 --------------- include/asm-x86/linkage_64.h | 6 ------ 3 files changed, 18 insertions(+), 24 deletions(-) delete mode 100644 include/asm-x86/linkage_32.h delete mode 100644 include/asm-x86/linkage_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/linkage.h b/include/asm-x86/linkage.h index 94b257fa870..5a4c9590542 100644 --- a/include/asm-x86/linkage.h +++ b/include/asm-x86/linkage.h @@ -1,5 +1,20 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#ifdef CONFIG_X86_64 +#define __ALIGN .p2align 4,,15 +#define __ALIGN_STR ".p2align 4,,15" +#endif + #ifdef CONFIG_X86_32 -# include "linkage_32.h" -#else -# include "linkage_64.h" +#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) +#define prevent_tail_call(ret) __asm__ ("" : "=r" (ret) : "0" (ret)) +#endif + +#ifdef CONFIG_X86_ALIGNMENT_16 +#define __ALIGN .align 16,0x90 +#define __ALIGN_STR ".align 16,0x90" +#endif + #endif + diff --git a/include/asm-x86/linkage_32.h b/include/asm-x86/linkage_32.h deleted file mode 100644 index f4a6ebac024..00000000000 --- a/include/asm-x86/linkage_32.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) -#define FASTCALL(x) x __attribute__((regparm(3))) -#define fastcall __attribute__((regparm(3))) - -#define prevent_tail_call(ret) __asm__ ("" : "=r" (ret) : "0" (ret)) - -#ifdef CONFIG_X86_ALIGNMENT_16 -#define __ALIGN .align 16,0x90 -#define __ALIGN_STR ".align 16,0x90" -#endif - -#endif diff --git a/include/asm-x86/linkage_64.h b/include/asm-x86/linkage_64.h deleted file mode 100644 index b5f39d0189c..00000000000 --- a/include/asm-x86/linkage_64.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -#define __ALIGN .p2align 4,,15 - -#endif -- cgit v1.2.2 From cc503c1b43e002e3f1fed70f46d947e2bf349bb6 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 30 Jan 2008 13:31:07 +0100 Subject: x86: PIE executable randomization main executable of (specially compiled/linked -pie/-fpie) ET_DYN binaries onto a random address (in cases in which mmap() is allowed to perform a randomization). The code has been extraced from Ingo's exec-shield patch http://people.redhat.com/mingo/exec-shield/ [akpm@linux-foundation.org: fix used-uninitialsied warning] [kamezawa.hiroyu@jp.fujitsu.com: fixed ia32 ELF on x86_64 handling] Signed-off-by: Jiri Kosina Cc: KAMEZAWA Hiroyuki Cc: Arjan van de Ven Cc: Roland McGrath Cc: Jakub Jelinek Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 9d4f11dd566..6cf40dec093 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -413,6 +413,7 @@ pte_t *lookup_address(unsigned long addr); remap_pfn_range(vma, vaddr, pfn, size, prot) #define HAVE_ARCH_UNMAPPED_AREA +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN #define pgtable_cache_init() do { } while (0) #define check_pgt_cache() do { } while (0) -- cgit v1.2.2 From 929fd589135ed417663f1b75b8031c9cf6687700 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: some whitespace cleanups in paging code This patch does some whitespace cleanups in the paging code to fix some checkpatch.pl warnings of my formerly merged cleanup patches. Signed-off-by: Joerg Roedel Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 6cf40dec093..3072619365a 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -154,22 +154,22 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ -#define _PAGE_PRESENT (_AC(1,UL)<<_PAGE_BIT_PRESENT) -#define _PAGE_RW (_AC(1,UL)<<_PAGE_BIT_RW) -#define _PAGE_USER (_AC(1,UL)<<_PAGE_BIT_USER) -#define _PAGE_PWT (_AC(1,UL)<<_PAGE_BIT_PWT) -#define _PAGE_PCD (_AC(1,UL)<<_PAGE_BIT_PCD) -#define _PAGE_ACCESSED (_AC(1,UL)<<_PAGE_BIT_ACCESSED) -#define _PAGE_DIRTY (_AC(1,UL)<<_PAGE_BIT_DIRTY) +#define _PAGE_PRESENT (_AC(1, UL)<<_PAGE_BIT_PRESENT) +#define _PAGE_RW (_AC(1, UL)<<_PAGE_BIT_RW) +#define _PAGE_USER (_AC(1, UL)<<_PAGE_BIT_USER) +#define _PAGE_PWT (_AC(1, UL)<<_PAGE_BIT_PWT) +#define _PAGE_PCD (_AC(1, UL)<<_PAGE_BIT_PCD) +#define _PAGE_ACCESSED (_AC(1, UL)<<_PAGE_BIT_ACCESSED) +#define _PAGE_DIRTY (_AC(1, UL)<<_PAGE_BIT_DIRTY) /* 2MB page */ -#define _PAGE_PSE (_AC(1,UL)<<_PAGE_BIT_PSE) +#define _PAGE_PSE (_AC(1, UL)<<_PAGE_BIT_PSE) /* nonlinear file mapping, saved PTE; unset:swap */ -#define _PAGE_FILE (_AC(1,UL)<<_PAGE_BIT_FILE) +#define _PAGE_FILE (_AC(1, UL)<<_PAGE_BIT_FILE) /* Global TLB entry */ -#define _PAGE_GLOBAL (_AC(1,UL)<<_PAGE_BIT_GLOBAL) +#define _PAGE_GLOBAL (_AC(1, UL)<<_PAGE_BIT_GLOBAL) #define _PAGE_PROTNONE 0x080 /* If not present */ -#define _PAGE_NX (_AC(1,UL)<<_PAGE_BIT_NX) +#define _PAGE_NX (_AC(1, UL)<<_PAGE_BIT_NX) #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) -- cgit v1.2.2 From e34907ae180f4fe6c28bb4516c679c2f81b0c9ed Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: remove volatile keyword from clflush. the p parameter is an explicit memory reference, and is enough to prevent gcc to being nasty here. The volatile seems completely not needed. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system_32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index f5b3f77f531..28978b17b07 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -161,7 +161,7 @@ static inline void native_wbinvd(void) asm volatile("wbinvd": : :"memory"); } -static inline void clflush(volatile void *__p) +static inline void clflush(void *__p) { asm volatile("clflush %0" : "+m" (*(char __force *)__p)); } -- cgit v1.2.2 From d89542229b657bdcce6a6f76168f9098ee3e9344 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: put together equal pieces of system.h This patch puts together pieces of system_{32,64}.h that looks like the same. It's the first step towards integration of this file. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 69 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/system_32.h | 58 ------------------------------------- include/asm-x86/system_64.h | 12 -------- 3 files changed, 69 insertions(+), 70 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 692562b48f2..d0803f8c70c 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -1,5 +1,74 @@ +#ifndef _ASM_X86_SYSTEM_H_ +#define _ASM_X86_SYSTEM_H_ + +#include + #ifdef CONFIG_X86_32 # include "system_32.h" #else # include "system_64.h" #endif + +#ifdef __KERNEL__ +#define _set_base(addr, base) do { unsigned long __pr; \ +__asm__ __volatile__ ("movw %%dx,%1\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %%dl,%2\n\t" \ + "movb %%dh,%3" \ + :"=&d" (__pr) \ + :"m" (*((addr)+2)), \ + "m" (*((addr)+4)), \ + "m" (*((addr)+7)), \ + "0" (base) \ + ); } while (0) + +#define _set_limit(addr, limit) do { unsigned long __lr; \ +__asm__ __volatile__ ("movw %%dx,%1\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %2,%%dh\n\t" \ + "andb $0xf0,%%dh\n\t" \ + "orb %%dh,%%dl\n\t" \ + "movb %%dl,%2" \ + :"=&d" (__lr) \ + :"m" (*(addr)), \ + "m" (*((addr)+6)), \ + "0" (limit) \ + ); } while (0) + +#define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base)) +#define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1)) + +/* + * Save a segment register away + */ +#define savesegment(seg, value) \ + asm volatile("mov %%" #seg ",%0":"=rm" (value)) + +static inline unsigned long get_limit(unsigned long segment) +{ + unsigned long __limit; + __asm__("lsll %1,%0" + :"=r" (__limit):"r" (segment)); + return __limit+1; +} +#endif /* __KERNEL__ */ + +static inline void clflush(void *__p) +{ + asm volatile("clflush %0" : "+m" (*(char __force *)__p)); +} + +#define nop() __asm__ __volatile__ ("nop") + +void disable_hlt(void); +void enable_hlt(void); + +extern int es7000_plat; +void cpu_idle_wait(void); + +extern unsigned long arch_align_stack(unsigned long sp); +extern void free_init_pages(char *what, unsigned long begin, unsigned long end); + +void default_idle(void); + +#endif diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index 28978b17b07..fb457642ac5 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -34,34 +34,6 @@ extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struc "2" (prev), "d" (next)); \ } while (0) -#define _set_base(addr,base) do { unsigned long __pr; \ -__asm__ __volatile__ ("movw %%dx,%1\n\t" \ - "rorl $16,%%edx\n\t" \ - "movb %%dl,%2\n\t" \ - "movb %%dh,%3" \ - :"=&d" (__pr) \ - :"m" (*((addr)+2)), \ - "m" (*((addr)+4)), \ - "m" (*((addr)+7)), \ - "0" (base) \ - ); } while(0) - -#define _set_limit(addr,limit) do { unsigned long __lr; \ -__asm__ __volatile__ ("movw %%dx,%1\n\t" \ - "rorl $16,%%edx\n\t" \ - "movb %2,%%dh\n\t" \ - "andb $0xf0,%%dh\n\t" \ - "orb %%dh,%%dl\n\t" \ - "movb %%dl,%2" \ - :"=&d" (__lr) \ - :"m" (*(addr)), \ - "m" (*((addr)+6)), \ - "0" (limit) \ - ); } while(0) - -#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) ) -#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1) ) - /* * Load a segment. Fall back on loading the zero * segment if something goes wrong.. @@ -83,12 +55,6 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \ ".previous" \ : :"rm" (value)) -/* - * Save a segment register away - */ -#define savesegment(seg, value) \ - asm volatile("mov %%" #seg ",%0":"=rm" (value)) - static inline void native_clts(void) { @@ -161,11 +127,6 @@ static inline void native_wbinvd(void) asm volatile("wbinvd": : :"memory"); } -static inline void clflush(void *__p) -{ - asm volatile("clflush %0" : "+m" (*(char __force *)__p)); -} - #ifdef CONFIG_PARAVIRT #include #else @@ -190,15 +151,6 @@ static inline void clflush(void *__p) #endif /* __KERNEL__ */ -static inline unsigned long get_limit(unsigned long segment) -{ - unsigned long __limit; - __asm__("lsll %1,%0" - :"=r" (__limit):"r" (segment)); - return __limit+1; -} - -#define nop() __asm__ __volatile__ ("nop") /* * Force strict CPU ordering. @@ -305,15 +257,5 @@ static inline unsigned long get_limit(unsigned long segment) * disable hlt during certain critical i/o operations */ #define HAVE_DISABLE_HLT -void disable_hlt(void); -void enable_hlt(void); - -extern int es7000_plat; -void cpu_idle_wait(void); - -extern unsigned long arch_align_stack(unsigned long sp); -extern void free_init_pages(char *what, unsigned long begin, unsigned long end); - -void default_idle(void); #endif diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 3dcb217a720..cc5b2666a04 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -141,13 +141,6 @@ static inline void write_cr8(unsigned long val) #endif /* __KERNEL__ */ -static inline void clflush(volatile void *__p) -{ - asm volatile("clflush %0" : "+m" (*(char __force *)__p)); -} - -#define nop() __asm__ __volatile__ ("nop") - #ifdef CONFIG_SMP #define smp_mb() mb() #define smp_rmb() barrier() @@ -177,9 +170,4 @@ static inline void clflush(volatile void *__p) #include -void cpu_idle_wait(void); - -extern unsigned long arch_align_stack(unsigned long sp); -extern void free_init_pages(char *what, unsigned long begin, unsigned long end); - #endif -- cgit v1.2.2 From a6b4655258efd39b590e519815ed43bb74cd7188 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: unify load_segment macro This patch unifies the load_segment() macro, making them equal in both x86_64 and i386 architectures. The common version goes to system.h, and the old are deleted. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 21 +++++++++++++++++++++ include/asm-x86/system_32.h | 22 ---------------------- include/asm-x86/system_64.h | 20 -------------------- 3 files changed, 21 insertions(+), 42 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index d0803f8c70c..3740bada097 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -38,6 +38,27 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \ #define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base)) #define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1)) +/* + * Load a segment. Fall back on loading the zero + * segment if something goes wrong.. + */ +#define loadsegment(seg, value) \ + asm volatile("\n" \ + "1:\t" \ + "movl %k0,%%" #seg "\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3:\t" \ + "movl %k1, %%" #seg "\n\t" \ + "jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n\t" \ + _ASM_ALIGN "\n\t" \ + _ASM_PTR " 1b,3b\n" \ + ".previous" \ + : :"r" (value), "r" (0)) + + /* * Save a segment register away */ diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index fb457642ac5..8db478984ed 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -34,28 +34,6 @@ extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struc "2" (prev), "d" (next)); \ } while (0) -/* - * Load a segment. Fall back on loading the zero - * segment if something goes wrong.. - */ -#define loadsegment(seg,value) \ - asm volatile("\n" \ - "1:\t" \ - "mov %0,%%" #seg "\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3:\t" \ - "pushl $0\n\t" \ - "popl %%" #seg "\n\t" \ - "jmp 2b\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".align 4\n\t" \ - ".long 1b,3b\n" \ - ".previous" \ - : :"rm" (value)) - - static inline void native_clts(void) { asm volatile ("clts"); diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index cc5b2666a04..0885caace5d 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -49,26 +49,6 @@ extern void load_gs_index(unsigned); -/* - * Load a segment. Fall back on loading the zero - * segment if something goes wrong.. - */ -#define loadsegment(seg,value) \ - asm volatile("\n" \ - "1:\t" \ - "movl %k0,%%" #seg "\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3:\t" \ - "movl %1,%%" #seg "\n\t" \ - "jmp 2b\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".align 8\n\t" \ - ".quad 1b,3b\n" \ - ".previous" \ - : :"r" (value), "r" (0)) - /* * Clear and set 'TS' bit respectively */ -- cgit v1.2.2 From d3ca901f94b3299dfe3a814770d751844608419f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: unify paravirt parts of system.h This patch moves the i386 control registers manipulation functions, wbinvd, and clts functions to system.h. They are essentially the same as in x86_64. With this, system.h paravirt comes for free in x86_64. [ mingo@elte.hu: reintroduced the cr8 bits - needed for resume images ] Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 110 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/system_32.h | 94 ------------------------------------- include/asm-x86/system_64.h | 85 +++++----------------------------- 3 files changed, 122 insertions(+), 167 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 3740bada097..01ba1f8e64d 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -3,6 +3,8 @@ #include +#include + #ifdef CONFIG_X86_32 # include "system_32.h" #else @@ -38,6 +40,8 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \ #define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base)) #define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1)) +extern void load_gs_index(unsigned); + /* * Load a segment. Fall back on loading the zero * segment if something goes wrong.. @@ -72,6 +76,112 @@ static inline unsigned long get_limit(unsigned long segment) :"=r" (__limit):"r" (segment)); return __limit+1; } + +static inline void native_clts(void) +{ + asm volatile ("clts"); +} + +/* + * Volatile isn't enough to prevent the compiler from reordering the + * read/write functions for the control registers and messing everything up. + * A memory clobber would solve the problem, but would prevent reordering of + * all loads stores around it, which can hurt performance. Solution is to + * use a variable and mimic reads and writes to it to enforce serialization + */ +static unsigned long __force_order; + +static inline unsigned long native_read_cr0(void) +{ + unsigned long val; + asm volatile("mov %%cr0,%0\n\t" :"=r" (val), "=m" (__force_order)); + return val; +} + +static inline void native_write_cr0(unsigned long val) +{ + asm volatile("mov %0,%%cr0": :"r" (val), "m" (__force_order)); +} + +static inline unsigned long native_read_cr2(void) +{ + unsigned long val; + asm volatile("mov %%cr2,%0\n\t" :"=r" (val), "=m" (__force_order)); + return val; +} + +static inline void native_write_cr2(unsigned long val) +{ + asm volatile("mov %0,%%cr2": :"r" (val), "m" (__force_order)); +} + +static inline unsigned long native_read_cr3(void) +{ + unsigned long val; + asm volatile("mov %%cr3,%0\n\t" :"=r" (val), "=m" (__force_order)); + return val; +} + +static inline void native_write_cr3(unsigned long val) +{ + asm volatile("mov %0,%%cr3": :"r" (val), "m" (__force_order)); +} + +static inline unsigned long native_read_cr4(void) +{ + unsigned long val; + asm volatile("mov %%cr4,%0\n\t" :"=r" (val), "=m" (__force_order)); + return val; +} + +static inline unsigned long native_read_cr4_safe(void) +{ + unsigned long val; + /* This could fault if %cr4 does not exist. In x86_64, a cr4 always + * exists, so it will never fail. */ +#ifdef CONFIG_X86_32 + asm volatile("1: mov %%cr4, %0 \n" + "2: \n" + ".section __ex_table,\"a\" \n" + ".long 1b,2b \n" + ".previous \n" + : "=r" (val), "=m" (__force_order) : "0" (0)); +#else + val = native_read_cr4(); +#endif + return val; +} + +static inline void native_write_cr4(unsigned long val) +{ + asm volatile("mov %0,%%cr4": :"r" (val), "m" (__force_order)); +} + +static inline void native_wbinvd(void) +{ + asm volatile("wbinvd": : :"memory"); +} +#ifdef CONFIG_PARAVIRT +#include +#else +#define read_cr0() (native_read_cr0()) +#define write_cr0(x) (native_write_cr0(x)) +#define read_cr2() (native_read_cr2()) +#define write_cr2(x) (native_write_cr2(x)) +#define read_cr3() (native_read_cr3()) +#define write_cr3(x) (native_write_cr3(x)) +#define read_cr4() (native_read_cr4()) +#define read_cr4_safe() (native_read_cr4_safe()) +#define write_cr4(x) (native_write_cr4(x)) +#define wbinvd() (native_wbinvd()) + +/* Clear the 'TS' bit */ +#define clts() (native_clts()) + +#endif/* CONFIG_PARAVIRT */ + +#define stts() write_cr0(8 | read_cr0()) + #endif /* __KERNEL__ */ static inline void clflush(void *__p) diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index 8db478984ed..c05568290ad 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -1,7 +1,6 @@ #ifndef __ASM_SYSTEM_H #define __ASM_SYSTEM_H -#include #include #include #include @@ -34,99 +33,6 @@ extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struc "2" (prev), "d" (next)); \ } while (0) -static inline void native_clts(void) -{ - asm volatile ("clts"); -} - -static inline unsigned long native_read_cr0(void) -{ - unsigned long val; - asm volatile("movl %%cr0,%0\n\t" :"=r" (val)); - return val; -} - -static inline void native_write_cr0(unsigned long val) -{ - asm volatile("movl %0,%%cr0": :"r" (val)); -} - -static inline unsigned long native_read_cr2(void) -{ - unsigned long val; - asm volatile("movl %%cr2,%0\n\t" :"=r" (val)); - return val; -} - -static inline void native_write_cr2(unsigned long val) -{ - asm volatile("movl %0,%%cr2": :"r" (val)); -} - -static inline unsigned long native_read_cr3(void) -{ - unsigned long val; - asm volatile("movl %%cr3,%0\n\t" :"=r" (val)); - return val; -} - -static inline void native_write_cr3(unsigned long val) -{ - asm volatile("movl %0,%%cr3": :"r" (val)); -} - -static inline unsigned long native_read_cr4(void) -{ - unsigned long val; - asm volatile("movl %%cr4,%0\n\t" :"=r" (val)); - return val; -} - -static inline unsigned long native_read_cr4_safe(void) -{ - unsigned long val; - /* This could fault if %cr4 does not exist */ - asm volatile("1: movl %%cr4, %0 \n" - "2: \n" - ".section __ex_table,\"a\" \n" - ".long 1b,2b \n" - ".previous \n" - : "=r" (val): "0" (0)); - return val; -} - -static inline void native_write_cr4(unsigned long val) -{ - asm volatile("movl %0,%%cr4": :"r" (val)); -} - -static inline void native_wbinvd(void) -{ - asm volatile("wbinvd": : :"memory"); -} - -#ifdef CONFIG_PARAVIRT -#include -#else -#define read_cr0() (native_read_cr0()) -#define write_cr0(x) (native_write_cr0(x)) -#define read_cr2() (native_read_cr2()) -#define write_cr2(x) (native_write_cr2(x)) -#define read_cr3() (native_read_cr3()) -#define write_cr3(x) (native_write_cr3(x)) -#define read_cr4() (native_read_cr4()) -#define read_cr4_safe() (native_read_cr4_safe()) -#define write_cr4(x) (native_write_cr4(x)) -#define wbinvd() (native_wbinvd()) - -/* Clear the 'TS' bit */ -#define clts() (native_clts()) - -#endif/* CONFIG_PARAVIRT */ - -/* Set the 'TS' bit */ -#define stts() write_cr0(8 | read_cr0()) - #endif /* __KERNEL__ */ diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 0885caace5d..14ad6138439 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -1,7 +1,6 @@ #ifndef __ASM_SYSTEM_H #define __ASM_SYSTEM_H -#include #include #include @@ -47,78 +46,6 @@ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ : "memory", "cc" __EXTRA_CLOBBER) -extern void load_gs_index(unsigned); - -/* - * Clear and set 'TS' bit respectively - */ -#define clts() __asm__ __volatile__ ("clts") - -static inline unsigned long read_cr0(void) -{ - unsigned long cr0; - asm volatile("movq %%cr0,%0" : "=r" (cr0)); - return cr0; -} - -static inline void write_cr0(unsigned long val) -{ - asm volatile("movq %0,%%cr0" :: "r" (val)); -} - -static inline unsigned long read_cr2(void) -{ - unsigned long cr2; - asm volatile("movq %%cr2,%0" : "=r" (cr2)); - return cr2; -} - -static inline void write_cr2(unsigned long val) -{ - asm volatile("movq %0,%%cr2" :: "r" (val)); -} - -static inline unsigned long read_cr3(void) -{ - unsigned long cr3; - asm volatile("movq %%cr3,%0" : "=r" (cr3)); - return cr3; -} - -static inline void write_cr3(unsigned long val) -{ - asm volatile("movq %0,%%cr3" :: "r" (val) : "memory"); -} - -static inline unsigned long read_cr4(void) -{ - unsigned long cr4; - asm volatile("movq %%cr4,%0" : "=r" (cr4)); - return cr4; -} - -static inline void write_cr4(unsigned long val) -{ - asm volatile("movq %0,%%cr4" :: "r" (val) : "memory"); -} - -static inline unsigned long read_cr8(void) -{ - unsigned long cr8; - asm volatile("movq %%cr8,%0" : "=r" (cr8)); - return cr8; -} - -static inline void write_cr8(unsigned long val) -{ - asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); -} - -#define stts() write_cr0(8 | read_cr0()) - -#define wbinvd() \ - __asm__ __volatile__ ("wbinvd": : :"memory") - #endif /* __KERNEL__ */ #ifdef CONFIG_SMP @@ -148,6 +75,18 @@ static inline void write_cr8(unsigned long val) #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0) +static inline unsigned long read_cr8(void) +{ + unsigned long cr8; + asm volatile("movq %%cr8,%0" : "=r" (cr8)); + return cr8; +} + +static inline void write_cr8(unsigned long val) +{ + asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); +} + #include #endif -- cgit v1.2.2 From 62fe164c5b036f4bdb19fbfb8f18a75631e67eee Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: remove unused macro Mr. Grep says warn_if_not_ulong() is not used anymore anywhere in the code. So, we remove it. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system_64.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 14ad6138439..560470ea27c 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -73,8 +73,6 @@ #define read_barrier_depends() do {} while(0) #define set_mb(var, value) do { (void) xchg(&var, value); } while (0) -#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0) - static inline unsigned long read_cr8(void) { unsigned long cr8; -- cgit v1.2.2 From 833d8469b102365f427f7791e79ec1843ff5f164 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: unify smp parts of system.h The memory barrier parts of system.h are not very different between i386 and x86_64, the main difference being the availability of instructions, which we handle with the use of ifdefs. They are consolidated in system.h file, and then removed from the arch-specific headers. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 105 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/system_32.h | 99 ----------------------------------------- include/asm-x86/system_64.h | 25 ----------- 3 files changed, 105 insertions(+), 124 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 01ba1f8e64d..4c15eb11a91 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -202,4 +202,109 @@ extern void free_init_pages(char *what, unsigned long begin, unsigned long end); void default_idle(void); +/* + * Force strict CPU ordering. + * And yes, this is required on UP too when we're talking + * to devices. + */ +#ifdef CONFIG_X86_32 +/* + * For now, "wmb()" doesn't actually do anything, as all + * Intel CPU's follow what Intel calls a *Processor Order*, + * in which all writes are seen in the program order even + * outside the CPU. + * + * I expect future Intel CPU's to have a weaker ordering, + * but I'd also expect them to finally get their act together + * and add some real memory barriers if so. + * + * Some non intel clones support out of order store. wmb() ceases to be a + * nop for these. + */ +#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) +#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) +#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) +#else +#define mb() asm volatile("mfence":::"memory") +#define rmb() asm volatile("lfence":::"memory") +#define wmb() asm volatile("sfence" ::: "memory") +#endif + +/** + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like this where there are no data dependencies. + **/ + +#define read_barrier_depends() do { } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#ifdef CONFIG_X86_PPRO_FENCE +# define smp_rmb() rmb() +#else +# define smp_rmb() barrier() +#endif +#ifdef CONFIG_X86_OOSTORE +# define smp_wmb() wmb() +#else +# define smp_wmb() barrier() +#endif +#define smp_read_barrier_depends() read_barrier_depends() +#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while (0) +#define set_mb(var, value) do { var = value; barrier(); } while (0) +#endif + + #endif diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index c05568290ad..7da0716fb31 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -36,105 +36,6 @@ extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struc #endif /* __KERNEL__ */ -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - * - * For now, "wmb()" doesn't actually do anything, as all - * Intel CPU's follow what Intel calls a *Processor Order*, - * in which all writes are seen in the program order even - * outside the CPU. - * - * I expect future Intel CPU's to have a weaker ordering, - * but I'd also expect them to finally get their act together - * and add some real memory barriers if so. - * - * Some non intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ - - -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while(0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - #include /* diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 560470ea27c..9def35eb75e 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -48,31 +48,6 @@ #endif /* __KERNEL__ */ -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do {} while(0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do {} while(0) -#endif - - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") - -#define read_barrier_depends() do {} while(0) -#define set_mb(var, value) do { (void) xchg(&var, value); } while (0) - static inline unsigned long read_cr8(void) { unsigned long cr8; -- cgit v1.2.2 From 0a3b4d151a8e57f50ce5a12c7ea5ec9965cf0b5a Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: move switch_to macro to system.h This patch moves the switch_to() macro to system.h As those macros are fundamentally different between i386 and x86_64, they are enclosed around an ifdef. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 61 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/system_32.h | 31 ----------------------- include/asm-x86/system_64.h | 43 -------------------------------- 3 files changed, 61 insertions(+), 74 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 4c15eb11a91..ba3403f1d02 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -6,8 +6,69 @@ #include #ifdef CONFIG_X86_32 +#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */ + +struct task_struct; /* one of the stranger aspects of C forward declarations */ +extern struct task_struct *FASTCALL(__switch_to(struct task_struct *prev, + struct task_struct *next)); + +/* + * Saving eflags is important. It switches not only IOPL between tasks, + * it also protects other tasks from NT leaking through sysenter etc. + */ +#define switch_to(prev, next, last) do { \ + unsigned long esi, edi; \ + asm volatile("pushfl\n\t" /* Save flags */ \ + "pushl %%ebp\n\t" \ + "movl %%esp,%0\n\t" /* save ESP */ \ + "movl %5,%%esp\n\t" /* restore ESP */ \ + "movl $1f,%1\n\t" /* save EIP */ \ + "pushl %6\n\t" /* restore EIP */ \ + "jmp __switch_to\n" \ + "1:\t" \ + "popl %%ebp\n\t" \ + "popfl" \ + :"=m" (prev->thread.sp), "=m" (prev->thread.ip), \ + "=a" (last), "=S" (esi), "=D" (edi) \ + :"m" (next->thread.sp), "m" (next->thread.ip), \ + "2" (prev), "d" (next)); \ +} while (0) + # include "system_32.h" #else +#define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t" +#define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t" + +/* frame pointer must be last for get_wchan */ +#define SAVE_CONTEXT "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t" +#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t" + +#define __EXTRA_CLOBBER \ + , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \ + "r12", "r13", "r14", "r15" + +/* Save restore flags to clear handle leaking NT */ +#define switch_to(prev, next, last) \ + asm volatile(SAVE_CONTEXT \ + "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ + "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ + "call __switch_to\n\t" \ + ".globl thread_return\n" \ + "thread_return:\n\t" \ + "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ + "movq %P[thread_info](%%rsi),%%r8\n\t" \ + LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ + "movq %%rax,%%rdi\n\t" \ + "jc ret_from_fork\n\t" \ + RESTORE_CONTEXT \ + : "=a" (last) \ + : [next] "S" (next), [prev] "D" (prev), \ + [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ + [ti_flags] "i" (offsetof(struct thread_info, flags)), \ + [tif_fork] "i" (TIF_FORK), \ + [thread_info] "i" (offsetof(struct task_struct, stack)), \ + [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ + : "memory", "cc" __EXTRA_CLOBBER) # include "system_64.h" #endif diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index 7da0716fb31..83af46443bd 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -5,37 +5,6 @@ #include #include -#ifdef __KERNEL__ -#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */ - -struct task_struct; /* one of the stranger aspects of C forward declarations.. */ -extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next)); - -/* - * Saving eflags is important. It switches not only IOPL between tasks, - * it also protects other tasks from NT leaking through sysenter etc. - */ -#define switch_to(prev,next,last) do { \ - unsigned long esi,edi; \ - asm volatile("pushfl\n\t" /* Save flags */ \ - "pushl %%ebp\n\t" \ - "movl %%esp,%0\n\t" /* save ESP */ \ - "movl %5,%%esp\n\t" /* restore ESP */ \ - "movl $1f,%1\n\t" /* save EIP */ \ - "pushl %6\n\t" /* restore EIP */ \ - "jmp __switch_to\n" \ - "1:\t" \ - "popl %%ebp\n\t" \ - "popfl" \ - :"=m" (prev->thread.sp),"=m" (prev->thread.ip), \ - "=a" (last),"=S" (esi),"=D" (edi) \ - :"m" (next->thread.sp),"m" (next->thread.ip), \ - "2" (prev), "d" (next)); \ -} while (0) - -#endif /* __KERNEL__ */ - - #include /* diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 9def35eb75e..97fa251ccb2 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -4,49 +4,6 @@ #include #include -#ifdef __KERNEL__ - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -#define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t" -#define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t" - -/* frame pointer must be last for get_wchan */ -#define SAVE_CONTEXT "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t" -#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t" - -#define __EXTRA_CLOBBER \ - ,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15" - -/* Save restore flags to clear handle leaking NT */ -#define switch_to(prev,next,last) \ - asm volatile(SAVE_CONTEXT \ - "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ - "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ - "call __switch_to\n\t" \ - ".globl thread_return\n" \ - "thread_return:\n\t" \ - "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ - "movq %P[thread_info](%%rsi),%%r8\n\t" \ - LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ - "movq %%rax,%%rdi\n\t" \ - "jc ret_from_fork\n\t" \ - RESTORE_CONTEXT \ - : "=a" (last) \ - : [next] "S" (next), [prev] "D" (prev), \ - [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ - [ti_flags] "i" (offsetof(struct thread_info, flags)),\ - [tif_fork] "i" (TIF_FORK), \ - [thread_info] "i" (offsetof(struct task_struct, stack)), \ - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ - : "memory", "cc" __EXTRA_CLOBBER) - -#endif /* __KERNEL__ */ static inline unsigned long read_cr8(void) { -- cgit v1.2.2 From d46d7d754014a299fa9b3400d080e09bfe4d629f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:08 +0100 Subject: x86: unify system.h This patch finishes the unification of system.h file. i386 needs a constant to be defined, and it is defined inside an ifdef. Other than that, pretty much nothing but includes are left in the arch specific headers, and they are deleted. [ mingo@elte.hu: 64-bit needs the cr8 access inlines. ] Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 26 ++++++++++++++++++++++++-- include/asm-x86/system_32.h | 15 --------------- 2 files changed, 24 insertions(+), 17 deletions(-) delete mode 100644 include/asm-x86/system_32.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index ba3403f1d02..8a37dad38bc 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -2,8 +2,12 @@ #define _ASM_X86_SYSTEM_H_ #include +#include +#include +#include #include +#include #ifdef CONFIG_X86_32 #define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */ @@ -34,7 +38,10 @@ extern struct task_struct *FASTCALL(__switch_to(struct task_struct *prev, "2" (prev), "d" (next)); \ } while (0) -# include "system_32.h" +/* + * disable hlt during certain critical i/o operations + */ +#define HAVE_DISABLE_HLT #else #define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t" #define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t" @@ -69,7 +76,6 @@ extern struct task_struct *FASTCALL(__switch_to(struct task_struct *prev, [thread_info] "i" (offsetof(struct task_struct, stack)), \ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ : "memory", "cc" __EXTRA_CLOBBER) -# include "system_64.h" #endif #ifdef __KERNEL__ @@ -236,6 +242,22 @@ static inline void native_wbinvd(void) #define write_cr4(x) (native_write_cr4(x)) #define wbinvd() (native_wbinvd()) +#ifdef CONFIG_X86_64 + +static inline unsigned long read_cr8(void) +{ + unsigned long cr8; + asm volatile("movq %%cr8,%0" : "=r" (cr8)); + return cr8; +} + +static inline void write_cr8(unsigned long val) +{ + asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); +} + +#endif + /* Clear the 'TS' bit */ #define clts() (native_clts()) diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h deleted file mode 100644 index 83af46443bd..00000000000 --- a/include/asm-x86/system_32.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __ASM_SYSTEM_H -#define __ASM_SYSTEM_H - -#include -#include -#include - -#include - -/* - * disable hlt during certain critical i/o operations - */ -#define HAVE_DISABLE_HLT - -#endif -- cgit v1.2.2 From eee3af4a2c83a97fff107ddc445d9df6fded9ce4 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:31:09 +0100 Subject: x86, ptrace: support for branch trace store(BTS) Resend using different mail client Changes to the last version: - split implementation into two layers: ds/bts and ptrace - renamed TIF's - save/restore ds save area msr in __switch_to_xtra() - make block-stepping only look at BTF bit Signed-off-by: Markus Metzger Signed-off-by: Suresh Siddha Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ds.h | 65 ++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 3 ++ include/asm-x86/processor_64.h | 3 ++ include/asm-x86/ptrace-abi.h | 52 ++++++++++++++++++++++++++++++++ include/asm-x86/ptrace.h | 11 +++++++ include/asm-x86/thread_info_32.h | 12 ++++++-- include/asm-x86/thread_info_64.h | 9 +++++- 7 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 include/asm-x86/ds.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/ds.h b/include/asm-x86/ds.h new file mode 100644 index 00000000000..edd8467740a --- /dev/null +++ b/include/asm-x86/ds.h @@ -0,0 +1,65 @@ +/* + * Debug Store (DS) support + * + * This provides a low-level interface to the hardware's Debug Store + * feature that is used for last branch recording (LBR) and + * precise-event based sampling (PEBS). + * + * Different architectures use a different DS layout/pointer size. + * The below functions therefore work on a void*. + * + * + * Since there is no user for PEBS, yet, only LBR (or branch + * trace store, BTS) is supported. + * + * + * Copyright (C) 2007 Intel Corporation. + * Markus Metzger , Dec 2007 + */ + +#ifndef _ASM_X86_DS_H +#define _ASM_X86_DS_H + +#include +#include + +struct cpuinfo_x86; + + +/* a branch trace record entry + * + * In order to unify the interface between various processor versions, + * we use the below data structure for all processors. + */ +enum bts_qualifier { + BTS_INVALID = 0, + BTS_BRANCH, + BTS_TASK_ARRIVES, + BTS_TASK_DEPARTS +}; + +struct bts_struct { + enum bts_qualifier qualifier; + union { + /* BTS_BRANCH */ + struct { + long from_ip; + long to_ip; + } lbr; + /* BTS_TASK_ARRIVES or + BTS_TASK_DEPARTS */ + unsigned long long timestamp; + } variant; +}; + + +extern int ds_allocate(void **, size_t); +extern int ds_free(void **); +extern int ds_get_bts_size(void *); +extern int ds_get_bts_index(void *); +extern int ds_read_bts(void *, size_t, struct bts_struct *); +extern int ds_write_bts(void *, const struct bts_struct *); +extern unsigned long ds_debugctl_mask(void); +extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *c); + +#endif /* _ASM_X86_DS_H */ diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 0d83da19812..9c0ab7f26bd 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -360,6 +360,9 @@ struct thread_struct { unsigned long io_bitmap_max; /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ unsigned long debugctlmsr; +/* Debug Store - if not 0 points to a DS Save Area configuration; + * goes into MSR_IA32_DS_AREA */ + unsigned long ds_area_msr; }; #define INIT_THREAD { \ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 0780f3e3fdf..7b7f8a142e2 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -240,6 +240,9 @@ struct thread_struct { unsigned io_bitmap_max; /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ unsigned long debugctlmsr; +/* Debug Store - if not 0 points to a DS Save Area configuration; + * goes into MSR_IA32_DS_AREA */ + unsigned long ds_area_msr; /* cached TLS descriptors. */ u64 tls_array[GDT_ENTRY_TLS_ENTRIES]; } __attribute__((aligned(16))); diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index adce6b51df2..6fadc5214e1 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -80,4 +80,56 @@ #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ +/* Return maximal BTS buffer size in number of records, + if successuf; -1, otherwise. + EOPNOTSUPP...processor does not support bts tracing */ +#define PTRACE_BTS_MAX_BUFFER_SIZE 40 + +/* Allocate new bts buffer (free old one, if exists) of size DATA bts records; + parameter ADDR is ignored. + Return 0, if successful; -1, otherwise. + EOPNOTSUPP...processor does not support bts tracing + EINVAL.......invalid size in records + ENOMEM.......out of memory */ +#define PTRACE_BTS_ALLOCATE_BUFFER 41 + +/* Return the size of the bts buffer in number of bts records, + if successful; -1, otherwise. + EOPNOTSUPP...processor does not support bts tracing + ENXIO........no buffer allocated */ +#define PTRACE_BTS_GET_BUFFER_SIZE 42 + +/* Return the index of the next bts record to be written, + if successful; -1, otherwise. + EOPNOTSUPP...processor does not support bts tracing + ENXIO........no buffer allocated + After the first warp-around, this is the start of the circular bts buffer. */ +#define PTRACE_BTS_GET_INDEX 43 + +/* Read the DATA'th bts record into a ptrace_bts_record buffer provided in ADDR. + Return 0, if successful; -1, otherwise + EOPNOTSUPP...processor does not support bts tracing + ENXIO........no buffer allocated + EINVAL.......invalid index */ +#define PTRACE_BTS_READ_RECORD 44 + +/* Configure last branch trace; the configuration is given as a bit-mask of + PTRACE_BTS_O_* options in DATA; parameter ADDR is ignored. + Return 0, if successful; -1, otherwise + EOPNOTSUPP...processor does not support bts tracing + ENXIO........no buffer allocated */ +#define PTRACE_BTS_CONFIG 45 + +/* Return the configuration as bit-mask of PTRACE_BTS_O_* options + if successful; -1, otherwise. + EOPNOTSUPP...processor does not support bts tracing + ENXIO........no buffer allocated */ +#define PTRACE_BTS_STATUS 46 + +/* Trace configuration options */ +/* Collect last branch trace */ +#define PTRACE_BTS_O_TRACE_TASK 0x1 +/* Take timestamps when the task arrives and departs */ +#define PTRACE_BTS_O_TIMESTAMPS 0x2 + #endif diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 9228870f615..a9a1bab1451 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -4,8 +4,19 @@ #include /* For __user */ #include + #ifndef __ASSEMBLY__ +#ifdef __KERNEL__ + +#include + +struct task_struct; +extern void ptrace_bts_take_timestamp(struct task_struct *, enum bts_qualifier); + +#endif /* __KERNEL__ */ + + #ifdef __i386__ /* this struct defines the way the registers are stored on the stack during a system call. */ diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h index 306fc80800e..5bd508260ff 100644 --- a/include/asm-x86/thread_info_32.h +++ b/include/asm-x86/thread_info_32.h @@ -140,6 +140,8 @@ static inline struct thread_info *current_thread_info(void) #define TIF_NOTSC 20 /* TSC is not accessible in userland */ #define TIF_FORCED_TF 21 /* true if TF in eflags artificially */ #define TIF_DEBUGCTLMSR 22 /* uses thread_struct.debugctlmsr */ +#define TIF_DS_AREA_MSR 23 /* uses thread_struct.ds_area_msr */ +#define TIF_BTS_TRACE_TS 24 /* record scheduling event timestamps */ #define _TIF_SYSCALL_TRACE (1< Date: Wed, 30 Jan 2008 13:31:09 +0100 Subject: x86: put get_kernel_rpl in a common location This macro is useful for both i386 and x86_64, so put it in a common location, where both arches can grab it. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/segment.h | 9 +++++++++ include/asm-x86/segment_32.h | 3 --- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h index 605068280e2..b3a7a3e9fb1 100644 --- a/include/asm-x86/segment.h +++ b/include/asm-x86/segment.h @@ -1,5 +1,14 @@ +#ifndef _ASM_X86_SEGMENT_H_ +#define _ASM_X86_SEGMENT_H_ + #ifdef CONFIG_X86_32 # include "segment_32.h" #else # include "segment_64.h" #endif + +#ifndef CONFIG_PARAVIRT +#define get_kernel_rpl() 0 +#endif + +#endif diff --git a/include/asm-x86/segment_32.h b/include/asm-x86/segment_32.h index 597a47c2515..ff186e34798 100644 --- a/include/asm-x86/segment_32.h +++ b/include/asm-x86/segment_32.h @@ -129,9 +129,6 @@ #define SEGMENT_LDT 0x4 #define SEGMENT_GDT 0x0 -#ifndef CONFIG_PARAVIRT -#define get_kernel_rpl() 0 -#endif /* * Matching rules for certain types of segments. */ -- cgit v1.2.2 From 15ee09b40831ae88eb8a804a647b6935eb8b7114 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:09 +0100 Subject: x86: unify common parts of segment.h Although segment handling in i386 and x86_64 are very different, there's a common part. Put them in segment.h instead of arch specific headers Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/segment.h | 16 ++++++++++++++++ include/asm-x86/segment_32.h | 22 ---------------------- include/asm-x86/segment_64.h | 17 ----------------- 3 files changed, 16 insertions(+), 39 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h index b3a7a3e9fb1..3c9b306bc4b 100644 --- a/include/asm-x86/segment.h +++ b/include/asm-x86/segment.h @@ -11,4 +11,20 @@ #define get_kernel_rpl() 0 #endif +/* User mode is privilege level 3 */ +#define USER_RPL 0x3 +/* LDT segment has TI set, GDT has it cleared */ +#define SEGMENT_LDT 0x4 +#define SEGMENT_GDT 0x0 + +/* Bottom two bits of selector give the ring privilege level */ +#define SEGMENT_RPL_MASK 0x3 +/* Bit 2 is table indicator (LDT/GDT) */ +#define SEGMENT_TI_MASK 0x4 + +#define IDT_ENTRIES 256 +#define GDT_SIZE (GDT_ENTRIES * 8) +#define GDT_ENTRY_TLS_ENTRIES 3 +#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) + #endif diff --git a/include/asm-x86/segment_32.h b/include/asm-x86/segment_32.h index ff186e34798..3e133ad4252 100644 --- a/include/asm-x86/segment_32.h +++ b/include/asm-x86/segment_32.h @@ -45,12 +45,9 @@ * 30 - unused * 31 - TSS for double fault handler */ -#define GDT_ENTRY_TLS_ENTRIES 3 #define GDT_ENTRY_TLS_MIN 6 #define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) -#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) - #define GDT_ENTRY_DEFAULT_USER_CS 14 #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 + 3) @@ -87,7 +84,6 @@ * The GDT has 32 entries */ #define GDT_ENTRIES 32 -#define GDT_SIZE (GDT_ENTRIES * 8) /* Simple and small GDT entries for booting only */ @@ -111,24 +107,6 @@ #define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */ #define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */ -/* - * The interrupt descriptor table has room for 256 idt's, - * the global descriptor table is dependent on the number - * of tasks we can have.. - */ -#define IDT_ENTRIES 256 - -/* Bottom two bits of selector give the ring privilege level */ -#define SEGMENT_RPL_MASK 0x3 -/* Bit 2 is table indicator (LDT/GDT) */ -#define SEGMENT_TI_MASK 0x4 - -/* User mode is privilege level 3 */ -#define USER_RPL 0x3 -/* LDT segment has TI set, GDT has it cleared */ -#define SEGMENT_LDT 0x4 -#define SEGMENT_GDT 0x0 - /* * Matching rules for certain types of segments. */ diff --git a/include/asm-x86/segment_64.h b/include/asm-x86/segment_64.h index dce74210134..5cc7deb8b03 100644 --- a/include/asm-x86/segment_64.h +++ b/include/asm-x86/segment_64.h @@ -33,8 +33,6 @@ #define GDT_ENTRY_TLS_MIN 12 #define GDT_ENTRY_TLS_MAX 14 -#define GDT_ENTRY_TLS_ENTRIES 3 - #define GDT_ENTRY_PER_CPU 15 /* Abused to load per CPU data from limit */ #define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3) @@ -45,20 +43,5 @@ #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) -#define IDT_ENTRIES 256 #define GDT_ENTRIES 16 -#define GDT_SIZE (GDT_ENTRIES * 8) -#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) - -/* Bottom two bits of selector give the ring privilege level */ -#define SEGMENT_RPL_MASK 0x3 -/* Bit 2 is table indicator (LDT/GDT) */ -#define SEGMENT_TI_MASK 0x4 - -/* User mode is privilege level 3 */ -#define USER_RPL 0x3 -/* LDT segment has TI set, GDT has it cleared */ -#define SEGMENT_LDT 0x4 -#define SEGMENT_GDT 0x0 - #endif -- cgit v1.2.2 From b23be399da88a5008b1db4db06f03146b25cdc52 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:09 +0100 Subject: x86: remove arch specific segment headers This file puts the remainder of the arch specificic segment headers in segment.h. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/segment.h | 177 ++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/segment_32.h | 122 ----------------------------- include/asm-x86/segment_64.h | 47 ------------ 3 files changed, 175 insertions(+), 171 deletions(-) delete mode 100644 include/asm-x86/segment_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h index 3c9b306bc4b..c7509df7914 100644 --- a/include/asm-x86/segment.h +++ b/include/asm-x86/segment.h @@ -2,9 +2,182 @@ #define _ASM_X86_SEGMENT_H_ #ifdef CONFIG_X86_32 -# include "segment_32.h" +/* + * The layout of the per-CPU GDT under Linux: + * + * 0 - null + * 1 - reserved + * 2 - reserved + * 3 - reserved + * + * 4 - unused <==== new cacheline + * 5 - unused + * + * ------- start of TLS (Thread-Local Storage) segments: + * + * 6 - TLS segment #1 [ glibc's TLS segment ] + * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] + * 8 - TLS segment #3 + * 9 - reserved + * 10 - reserved + * 11 - reserved + * + * ------- start of kernel segments: + * + * 12 - kernel code segment <==== new cacheline + * 13 - kernel data segment + * 14 - default user CS + * 15 - default user DS + * 16 - TSS + * 17 - LDT + * 18 - PNPBIOS support (16->32 gate) + * 19 - PNPBIOS support + * 20 - PNPBIOS support + * 21 - PNPBIOS support + * 22 - PNPBIOS support + * 23 - APM BIOS support + * 24 - APM BIOS support + * 25 - APM BIOS support + * + * 26 - ESPFIX small SS + * 27 - per-cpu [ offset to per-cpu data area ] + * 28 - unused + * 29 - unused + * 30 - unused + * 31 - TSS for double fault handler + */ +#define GDT_ENTRY_TLS_MIN 6 +#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) + +#define GDT_ENTRY_DEFAULT_USER_CS 14 +#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 + 3) + +#define GDT_ENTRY_DEFAULT_USER_DS 15 +#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS * 8 + 3) + +#define GDT_ENTRY_KERNEL_BASE 12 + +#define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE + 0) +#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8) + +#define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE + 1) +#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8) + +#define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE + 4) +#define GDT_ENTRY_LDT (GDT_ENTRY_KERNEL_BASE + 5) + +#define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 6) +#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 11) + +#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14) +#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) + +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15) +#ifdef CONFIG_SMP +#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8) +#else +#define __KERNEL_PERCPU 0 +#endif + +#define GDT_ENTRY_DOUBLEFAULT_TSS 31 + +/* + * The GDT has 32 entries + */ +#define GDT_ENTRIES 32 + +/* Simple and small GDT entries for booting only */ + +#define GDT_ENTRY_BOOT_CS 2 +#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) + +#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) +#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) + +/* The PnP BIOS entries in the GDT */ +#define GDT_ENTRY_PNPBIOS_CS32 (GDT_ENTRY_PNPBIOS_BASE + 0) +#define GDT_ENTRY_PNPBIOS_CS16 (GDT_ENTRY_PNPBIOS_BASE + 1) +#define GDT_ENTRY_PNPBIOS_DS (GDT_ENTRY_PNPBIOS_BASE + 2) +#define GDT_ENTRY_PNPBIOS_TS1 (GDT_ENTRY_PNPBIOS_BASE + 3) +#define GDT_ENTRY_PNPBIOS_TS2 (GDT_ENTRY_PNPBIOS_BASE + 4) + +/* The PnP BIOS selectors */ +#define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8) /* segment for calling fn */ +#define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8) /* code segment for BIOS */ +#define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */ +#define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */ +#define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */ + +/* Bottom two bits of selector give the ring privilege level */ +#define SEGMENT_RPL_MASK 0x3 +/* Bit 2 is table indicator (LDT/GDT) */ +#define SEGMENT_TI_MASK 0x4 + +/* User mode is privilege level 3 */ +#define USER_RPL 0x3 +/* LDT segment has TI set, GDT has it cleared */ +#define SEGMENT_LDT 0x4 +#define SEGMENT_GDT 0x0 + +/* + * Matching rules for certain types of segments. + */ + +/* Matches only __KERNEL_CS, ignoring PnP / USER / APM segments */ +#define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8) + +/* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */ +#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) + +/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) + + #else -# include "segment_64.h" +#include + +/* Simple and small GDT entries for booting only */ + +#define GDT_ENTRY_BOOT_CS 2 +#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) + +#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) +#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) + +#define __KERNEL_CS 0x10 +#define __KERNEL_DS 0x18 + +#define __KERNEL32_CS 0x08 + +/* + * we cannot use the same code segment descriptor for user and kernel + * -- not even in the long flat mode, because of different DPL /kkeil + * The segment offset needs to contain a RPL. Grr. -AK + * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets) + */ + +#define __USER32_CS 0x23 /* 4*8+3 */ +#define __USER_DS 0x2b /* 5*8+3 */ +#define __USER_CS 0x33 /* 6*8+3 */ +#define __USER32_DS __USER_DS + +#define GDT_ENTRY_TSS 8 /* needs two entries */ +#define GDT_ENTRY_LDT 10 /* needs two entries */ +#define GDT_ENTRY_TLS_MIN 12 +#define GDT_ENTRY_TLS_MAX 14 + +#define GDT_ENTRY_PER_CPU 15 /* Abused to load per CPU data from limit */ +#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3) + +/* TLS indexes for 64bit - hardcoded in arch_prctl */ +#define FS_TLS 0 +#define GS_TLS 1 + +#define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) +#define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) + +#define GDT_ENTRIES 16 + #endif #ifndef CONFIG_PARAVIRT diff --git a/include/asm-x86/segment_32.h b/include/asm-x86/segment_32.h index 3e133ad4252..8b137891791 100644 --- a/include/asm-x86/segment_32.h +++ b/include/asm-x86/segment_32.h @@ -1,123 +1 @@ -#ifndef _ASM_SEGMENT_H -#define _ASM_SEGMENT_H -/* - * The layout of the per-CPU GDT under Linux: - * - * 0 - null - * 1 - reserved - * 2 - reserved - * 3 - reserved - * - * 4 - unused <==== new cacheline - * 5 - unused - * - * ------- start of TLS (Thread-Local Storage) segments: - * - * 6 - TLS segment #1 [ glibc's TLS segment ] - * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] - * 8 - TLS segment #3 - * 9 - reserved - * 10 - reserved - * 11 - reserved - * - * ------- start of kernel segments: - * - * 12 - kernel code segment <==== new cacheline - * 13 - kernel data segment - * 14 - default user CS - * 15 - default user DS - * 16 - TSS - * 17 - LDT - * 18 - PNPBIOS support (16->32 gate) - * 19 - PNPBIOS support - * 20 - PNPBIOS support - * 21 - PNPBIOS support - * 22 - PNPBIOS support - * 23 - APM BIOS support - * 24 - APM BIOS support - * 25 - APM BIOS support - * - * 26 - ESPFIX small SS - * 27 - per-cpu [ offset to per-cpu data area ] - * 28 - unused - * 29 - unused - * 30 - unused - * 31 - TSS for double fault handler - */ -#define GDT_ENTRY_TLS_MIN 6 -#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) - -#define GDT_ENTRY_DEFAULT_USER_CS 14 -#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 + 3) - -#define GDT_ENTRY_DEFAULT_USER_DS 15 -#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS * 8 + 3) - -#define GDT_ENTRY_KERNEL_BASE 12 - -#define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE + 0) -#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8) - -#define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE + 1) -#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8) - -#define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE + 4) -#define GDT_ENTRY_LDT (GDT_ENTRY_KERNEL_BASE + 5) - -#define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 6) -#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 11) - -#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14) -#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) - -#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15) -#ifdef CONFIG_SMP -#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8) -#else -#define __KERNEL_PERCPU 0 -#endif - -#define GDT_ENTRY_DOUBLEFAULT_TSS 31 - -/* - * The GDT has 32 entries - */ -#define GDT_ENTRIES 32 - -/* Simple and small GDT entries for booting only */ - -#define GDT_ENTRY_BOOT_CS 2 -#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) - -#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) -#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) - -/* The PnP BIOS entries in the GDT */ -#define GDT_ENTRY_PNPBIOS_CS32 (GDT_ENTRY_PNPBIOS_BASE + 0) -#define GDT_ENTRY_PNPBIOS_CS16 (GDT_ENTRY_PNPBIOS_BASE + 1) -#define GDT_ENTRY_PNPBIOS_DS (GDT_ENTRY_PNPBIOS_BASE + 2) -#define GDT_ENTRY_PNPBIOS_TS1 (GDT_ENTRY_PNPBIOS_BASE + 3) -#define GDT_ENTRY_PNPBIOS_TS2 (GDT_ENTRY_PNPBIOS_BASE + 4) - -/* The PnP BIOS selectors */ -#define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8) /* segment for calling fn */ -#define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8) /* code segment for BIOS */ -#define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */ -#define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */ -#define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */ - -/* - * Matching rules for certain types of segments. - */ - -/* Matches only __KERNEL_CS, ignoring PnP / USER / APM segments */ -#define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8) - -/* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */ -#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) - -/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) - -#endif diff --git a/include/asm-x86/segment_64.h b/include/asm-x86/segment_64.h deleted file mode 100644 index 5cc7deb8b03..00000000000 --- a/include/asm-x86/segment_64.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _ASM_SEGMENT_H -#define _ASM_SEGMENT_H - -#include - -/* Simple and small GDT entries for booting only */ - -#define GDT_ENTRY_BOOT_CS 2 -#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) - -#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) -#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) - -#define __KERNEL_CS 0x10 -#define __KERNEL_DS 0x18 - -#define __KERNEL32_CS 0x08 - -/* - * we cannot use the same code segment descriptor for user and kernel - * -- not even in the long flat mode, because of different DPL /kkeil - * The segment offset needs to contain a RPL. Grr. -AK - * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets) - */ - -#define __USER32_CS 0x23 /* 4*8+3 */ -#define __USER_DS 0x2b /* 5*8+3 */ -#define __USER_CS 0x33 /* 6*8+3 */ -#define __USER32_DS __USER_DS - -#define GDT_ENTRY_TSS 8 /* needs two entries */ -#define GDT_ENTRY_LDT 10 /* needs two entries */ -#define GDT_ENTRY_TLS_MIN 12 -#define GDT_ENTRY_TLS_MAX 14 - -#define GDT_ENTRY_PER_CPU 15 /* Abused to load per CPU data from limit */ -#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3) - -/* TLS indexes for 64bit - hardcoded in arch_prctl */ -#define FS_TLS 0 -#define GS_TLS 1 - -#define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) -#define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) - -#define GDT_ENTRIES 16 -#endif -- cgit v1.2.2 From 6b4b05bd790389962e6fcfc862562e7fa239c9d2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 30 Jan 2008 13:31:09 +0100 Subject: x64/page.h: convert some macros to inlines Convert clear_page/copy_page macros to inline functions for type-checking. Andrew wants to extirpate these ugly macros. (Ingo too. Thomas as well. Please send us more "kill ugly macros" patches! :-) Signed-off-by: Randy Dunlap Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page_32.h | 39 +++++++++++++++++++++++++++++++++------ include/asm-x86/page_64.h | 21 ++++++++++++++++----- 2 files changed, 49 insertions(+), 11 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index 80ecc66b6d8..c620c934e55 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -12,12 +12,21 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ +#include + #ifdef CONFIG_X86_USE_3DNOW #include -#define clear_page(page) mmx_clear_page((void *)(page)) -#define copy_page(to,from) mmx_copy_page(to,from) +static inline void clear_page(void *page) +{ + mmx_clear_page(page); +} + +static inline void copy_page(void *to, void *from) +{ + mmx_copy_page(to, from); +} #else @@ -26,13 +35,31 @@ * Maybe the K6-III ? */ -#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) -#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) +static inline void clear_page(void *page) +{ + memset(page, 0, PAGE_SIZE); +} + +static inline void copy_page(void *to, void *from) +{ + memcpy(to, from, PAGE_SIZE); +} #endif -#define clear_user_page(page, vaddr, pg) clear_page(page) -#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) +struct page; + +static void inline clear_user_page(void *page, unsigned long vaddr, + struct page *pg) +{ + clear_page(page); +} + +static void inline copy_user_page(void *to, void *from, unsigned long vaddr, + struct page *topage) +{ + copy_page(to, from); +} #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index d400167c550..068b5e4cea4 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -43,11 +43,22 @@ extern unsigned long end_pfn; extern unsigned long end_pfn_map; -void clear_page(void *); -void copy_page(void *, void *); - -#define clear_user_page(page, vaddr, pg) clear_page(page) -#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) +void clear_page(void *page); +void copy_page(void *to, void *from); + +struct page; + +static void inline clear_user_page(void *page, unsigned long vaddr, + struct page *pg) +{ + clear_page(page); +} + +static void inline copy_user_page(void *to, void *from, unsigned long vaddr, + struct page *topage) +{ + copy_page(to, from); +} #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) -- cgit v1.2.2 From 27ec161f93b8f018e0270a5383ea1d1c36f00c8a Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:31:09 +0100 Subject: x86: kill mk_pte_huge It only has a single use, which can be trivially replaced. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 3072619365a..5c252d9fee1 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -355,7 +355,6 @@ static inline int pmd_large(pmd_t pte) { /* page, protection -> pte */ #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -#define mk_pte_huge(entry) (pte_val(entry) |= _PAGE_PRESENT | _PAGE_PSE) /* Change flags of a PTE */ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -- cgit v1.2.2 From ee238e5ca66858f80170f87724f84d67183b069a Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:10 +0100 Subject: x86: prepare time related functions for paravirt This patch add provisions for time related functions so they can be later replaced by paravirt versions. it basically encloses {g,s}et_wallclock inside the already existent functions update_persistent_clock and read_persistent_clock, and defines {s,g}et_wallclock to the core of such functions. it also allow for a later-on-game time initialization, as done by i386. Paravirt guests can set a function to do their own initialization this way. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Steven Rostedt Acked-by: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/time.h | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/time.h b/include/asm-x86/time.h index b3f94cd81ac..68779b048a3 100644 --- a/include/asm-x86/time.h +++ b/include/asm-x86/time.h @@ -1,8 +1,12 @@ -#ifndef _ASMi386_TIME_H -#define _ASMi386_TIME_H +#ifndef _ASMX86_TIME_H +#define _ASMX86_TIME_H + +extern void (*late_time_init)(void); +extern void hpet_time_init(void); -#include #include +#ifdef CONFIG_X86_32 +#include static inline unsigned long native_get_wallclock(void) { @@ -28,8 +32,20 @@ static inline int native_set_wallclock(unsigned long nowtime) return retval; } -extern void (*late_time_init)(void); -extern void hpet_time_init(void); +#else +extern void native_time_init_hook(void); + +static inline unsigned long native_get_wallclock(void) +{ + return mach_get_cmos_time(); +} + +static inline int native_set_wallclock(unsigned long nowtime) +{ + return mach_set_rtc_mmss(nowtime); +} + +#endif #ifdef CONFIG_PARAVIRT #include -- cgit v1.2.2 From ba082427ae6ffbf8e48a26ae4f72f4501a6b80c1 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:10 +0100 Subject: x86: tweak io_64.h for paravirt. We need something here because we can't call in and out instructions directly. However, we have to be careful, because no indirections are allowed in misc_64.c , and paravirt_ops is a kind of one. So just call it directly there Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Steven Rostedt Acked-by: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/io_64.h | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h index dbcc03aa1c6..fef0ce2ced8 100644 --- a/include/asm-x86/io_64.h +++ b/include/asm-x86/io_64.h @@ -40,6 +40,10 @@ extern void native_io_delay(void); extern int io_delay_type; extern void io_delay_init(void); +#if defined(CONFIG_PARAVIRT) +#include +#else + static inline void slow_down_io(void) { native_io_delay(); @@ -49,6 +53,7 @@ static inline void slow_down_io(void) native_io_delay(); #endif } +#endif /* * Talk about misusing macros.. @@ -57,21 +62,32 @@ static inline void slow_down_io(void) static inline void out##s(unsigned x value, unsigned short port) { #define __OUT2(s,s1,s2) \ -__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" : : "a" (value), "Nd" (port)) +__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" + +#ifndef REALLY_SLOW_IO +#define REALLY_SLOW_IO +#define UNSET_REALLY_SLOW_IO +#endif #define __OUT(s,s1,x) \ -__OUT1(s,x) __OUT2(s,s1,"w"); } \ -__OUT1(s##_p,x) __OUT2(s,s1,"w"); slow_down_io(); } +__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ +__OUT1(s##_p, x) __OUT2(s, s1, "w") : : "a" (value), "Nd" (port)); \ + slow_down_io(); } #define __IN1(s) \ static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; #define __IN2(s,s1,s2) \ -__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" : "=a" (_v) : "Nd" (port)) +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" + +#define __IN(s,s1,i...) \ +__IN1(s) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i); return _v; } \ +__IN1(s##_p) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i); \ + slow_down_io(); return _v; } -#define __IN(s,s1) \ -__IN1(s) __IN2(s,s1,"w"); return _v; } \ -__IN1(s##_p) __IN2(s,s1,"w"); slow_down_io(); return _v; } +#ifdef UNSET_REALLY_SLOW_IO +#undef REALLY_SLOW_IO +#endif #define __INS(s) \ static inline void ins##s(unsigned short port, void * addr, unsigned long count) \ -- cgit v1.2.2 From 746ef0cd0c7190d570c65b8e39a4ac67550ae43a Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:11 +0100 Subject: x86: prepare 64-bit architecture initialization for paravirt This patch prepares the x86_64 architecture initialization for paravirt. It requires a memory initialization step, which is done by implementing 64-bit version for machine_specific_memory_setup, and putting an ARCH_SETUP hook, for guest-dependent initialization. This last step is done akin to i386 Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Steven Rostedt Acked-by: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/setup.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h index 24d786e07b4..071e054abd8 100644 --- a/include/asm-x86/setup.h +++ b/include/asm-x86/setup.h @@ -3,6 +3,13 @@ #define COMMAND_LINE_SIZE 2048 +#ifndef __ASSEMBLY__ +char *machine_specific_memory_setup(void); +#ifndef CONFIG_PARAVIRT +#define paravirt_post_allocator_init() do {} while (0) +#endif +#endif /* __ASSEMBLY__ */ + #ifdef __KERNEL__ #ifdef __i386__ @@ -51,9 +58,7 @@ void __init add_memory_region(unsigned long long start, extern unsigned long init_pg_tables_end; -#ifndef CONFIG_PARAVIRT -#define paravirt_post_allocator_init() do {} while (0) -#endif + #endif /* __i386__ */ #endif /* _SETUP */ -- cgit v1.2.2 From 6842ef0e85a9cc1295f3ef933a230f863b01eb0f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:11 +0100 Subject: x86: unify desc_struct This patch aims to make the access of struct desc_struct variables equal across architectures. In this patch, I unify the i386 and x86_64 versions under an anonymous union, keeping the way they are accessed untouched (a and b for 32-bit code, individual bit-fields for 64-bit). This solution is not beautiful, but will allow us to integrate common code that differed by the way descriptors were used. This is to be viewed incrementally. There's simply too much code to be fixed at once. In the future, goal is to set up in a single way of acessing the desc_struct fields. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_defs.h | 25 +++++++++++++++++-------- include/asm-x86/lguest.h | 4 ++-- include/asm-x86/processor_32.h | 5 +---- 3 files changed, 20 insertions(+), 14 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index 08900407009..de47eb0a23a 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -11,17 +11,26 @@ #include +/* + * FIXME: Acessing the desc_struct through its fields is more elegant, + * and should be the one valid thing to do. However, a lot of open code + * still touches the a and b acessors, and doing this allow us to do it + * incrementally. We keep the signature as a struct, rather than an union, + * so we can get rid of it transparently in the future -- glommer + */ // 8 byte segment descriptor struct desc_struct { - u16 limit0; - u16 base0; - unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; - unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8; -} __attribute__((packed)); + union { + struct { unsigned int a, b; }; + struct { + u16 limit0; + u16 base0; + unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1; + unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; + }; -struct n_desc_struct { - unsigned int a,b; -}; + }; +} __attribute__((packed)); enum { GATE_INTERRUPT = 0xE, diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h index ccd33846081..17c908c0ef1 100644 --- a/include/asm-x86/lguest.h +++ b/include/asm-x86/lguest.h @@ -78,8 +78,8 @@ static inline void lguest_set_ts(void) } /* Full 4G segment descriptors, suitable for CS and DS. */ -#define FULL_EXEC_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9b00}) -#define FULL_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9300}) +#define FULL_EXEC_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9b00} } }) +#define FULL_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9300} } }) #endif /* __ASSEMBLY__ */ diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 9c0ab7f26bd..bc48ad64de4 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -20,14 +20,11 @@ #include #include #include +#include /* flag for disabling the tsc */ extern int tsc_disable; -struct desc_struct { - unsigned long a,b; -}; - static inline int desc_empty(const void *ptr) { const u32 *desc = ptr; -- cgit v1.2.2 From 6b68f01baa810e9f63fbf39e9d5c3ef1d94a966f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:12 +0100 Subject: x86: unify struct desc_ptr This patch unifies struct desc_ptr between i386 and x86_64. They can be expressed in the exact same way in C code, only having to change the name of one of them. As Xgt_desc_struct is ugly and big, this is the one that goes away. There's also a padding field in i386, but it is not really needed in the C structure definition. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_32.h | 16 +++++----------- include/asm-x86/lguest.h | 8 ++++---- include/asm-x86/paravirt.h | 18 +++++++++--------- include/asm-x86/processor_32.h | 2 +- include/asm-x86/suspend_32.h | 4 ++-- 5 files changed, 21 insertions(+), 27 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index c547403f341..bc5ca345346 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -12,12 +12,6 @@ #include -struct Xgt_desc_struct { - unsigned short size; - unsigned long address __attribute__((packed)); - unsigned short pad; -} __attribute__ ((packed)); - struct gdt_page { struct desc_struct gdt[GDT_ENTRIES]; @@ -29,7 +23,7 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) return per_cpu(gdt_page, cpu).gdt; } -extern struct Xgt_desc_struct idt_descr; +extern struct desc_ptr idt_descr; extern struct desc_struct idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); @@ -107,22 +101,22 @@ static inline void native_load_tr_desc(void) asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); } -static inline void native_load_gdt(const struct Xgt_desc_struct *dtr) +static inline void native_load_gdt(const struct desc_ptr *dtr) { asm volatile("lgdt %0"::"m" (*dtr)); } -static inline void native_load_idt(const struct Xgt_desc_struct *dtr) +static inline void native_load_idt(const struct desc_ptr *dtr) { asm volatile("lidt %0"::"m" (*dtr)); } -static inline void native_store_gdt(struct Xgt_desc_struct *dtr) +static inline void native_store_gdt(struct desc_ptr *dtr) { asm ("sgdt %0":"=m" (*dtr)); } -static inline void native_store_idt(struct Xgt_desc_struct *dtr) +static inline void native_store_idt(struct desc_ptr *dtr) { asm ("sidt %0":"=m" (*dtr)); } diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h index 17c908c0ef1..3585a1628b5 100644 --- a/include/asm-x86/lguest.h +++ b/include/asm-x86/lguest.h @@ -44,13 +44,13 @@ struct lguest_ro_state { /* Host information we need to restore when we switch back. */ u32 host_cr3; - struct Xgt_desc_struct host_idt_desc; - struct Xgt_desc_struct host_gdt_desc; + struct desc_ptr host_idt_desc; + struct desc_ptr host_gdt_desc; u32 host_sp; /* Fields which are used when guest is running. */ - struct Xgt_desc_struct guest_idt_desc; - struct Xgt_desc_struct guest_gdt_desc; + struct desc_ptr guest_idt_desc; + struct desc_ptr guest_gdt_desc; struct i386_hw_tss guest_tss; struct desc_struct guest_idt[IDT_ENTRIES]; struct desc_struct guest_gdt[GDT_ENTRIES]; diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index e95c2a65516..0333fb6988b 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -20,7 +20,7 @@ struct page; struct thread_struct; -struct Xgt_desc_struct; +struct desc_ptr; struct tss_struct; struct mm_struct; struct desc_struct; @@ -88,10 +88,10 @@ struct pv_cpu_ops { /* Segment descriptor handling */ void (*load_tr_desc)(void); - void (*load_gdt)(const struct Xgt_desc_struct *); - void (*load_idt)(const struct Xgt_desc_struct *); - void (*store_gdt)(struct Xgt_desc_struct *); - void (*store_idt)(struct Xgt_desc_struct *); + void (*load_gdt)(const struct desc_ptr *); + void (*load_idt)(const struct desc_ptr *); + void (*store_gdt)(struct desc_ptr *); + void (*store_idt)(struct desc_ptr *); void (*set_ldt)(const void *desc, unsigned entries); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); @@ -630,11 +630,11 @@ static inline void load_TR_desc(void) { PVOP_VCALL0(pv_cpu_ops.load_tr_desc); } -static inline void load_gdt(const struct Xgt_desc_struct *dtr) +static inline void load_gdt(const struct desc_ptr *dtr) { PVOP_VCALL1(pv_cpu_ops.load_gdt, dtr); } -static inline void load_idt(const struct Xgt_desc_struct *dtr) +static inline void load_idt(const struct desc_ptr *dtr) { PVOP_VCALL1(pv_cpu_ops.load_idt, dtr); } @@ -642,11 +642,11 @@ static inline void set_ldt(const void *addr, unsigned entries) { PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); } -static inline void store_gdt(struct Xgt_desc_struct *dtr) +static inline void store_gdt(struct desc_ptr *dtr) { PVOP_VCALL1(pv_cpu_ops.store_gdt, dtr); } -static inline void store_idt(struct Xgt_desc_struct *dtr) +static inline void store_idt(struct desc_ptr *dtr) { PVOP_VCALL1(pv_cpu_ops.store_idt, dtr); } diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index bc48ad64de4..e5056ab9dd9 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -707,7 +707,7 @@ extern void enable_sep_cpu(void); extern int sysenter_setup(void); /* Defined in head.S */ -extern struct Xgt_desc_struct early_gdt_descr; +extern struct desc_ptr early_gdt_descr; extern void cpu_set_gdt(int); extern void switch_to_new_gdt(void); diff --git a/include/asm-x86/suspend_32.h b/include/asm-x86/suspend_32.h index a2520732ffd..1bbda3ad779 100644 --- a/include/asm-x86/suspend_32.h +++ b/include/asm-x86/suspend_32.h @@ -12,8 +12,8 @@ static inline int arch_prepare_suspend(void) { return 0; } struct saved_context { u16 es, fs, gs, ss; unsigned long cr0, cr2, cr3, cr4; - struct Xgt_desc_struct gdt; - struct Xgt_desc_struct idt; + struct desc_ptr gdt; + struct desc_ptr idt; u16 ldt; u16 tss; unsigned long tr; -- cgit v1.2.2 From f6dc247cac1a8ee64e59019c3b948d23f3b1a36f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:12 +0100 Subject: x86: change gdt acessor macro name This patch changes the name of x86_64 macro used to access the per-cpu gdt. It is now equal to the i386 version, which will allow code to be shared. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_64.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 230ac6e50a0..4d67f61b4c2 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -48,7 +48,7 @@ static inline void write_ldt_entry(struct desc_struct *ldt, } /* the cpu gdt accessor */ -#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) +#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) static inline void load_gdt(const struct desc_ptr *ptr) { @@ -141,15 +141,15 @@ static inline void set_tss_desc(unsigned cpu, void *addr) * -1? seg base+limit should be pointing to the address of the * last valid byte */ - set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_TSS], + set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS], (unsigned long)addr, DESC_TSS, IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); } static inline void set_ldt_desc(unsigned cpu, void *addr, int size) { - set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_LDT], (unsigned long)addr, - DESC_LDT, size * 8 - 1); + set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], + (unsigned long)addr, DESC_LDT, size * 8 - 1); } #define LDT_entry_a(info) \ @@ -183,7 +183,7 @@ static inline void set_ldt_desc(unsigned cpu, void *addr, int size) static inline void load_TLS(struct thread_struct *t, unsigned int cpu) { unsigned int i; - u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN); + u64 *gdt = (u64 *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) gdt[i] = t->tls_array[i]; -- cgit v1.2.2 From 7e6ebe1432b04c2980cd030c9f0d1ed480e1fe4d Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:12 +0100 Subject: x86: removed unused variable This variable is not used anywere, and is then removed Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_64.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 4d67f61b4c2..8bd84a4ef2d 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -30,11 +30,6 @@ static inline unsigned long __store_tr(void) #define store_tr(tr) (tr) = __store_tr() -/* - * This is the ldt that every process will get unless we need - * something other than this. - */ -extern struct desc_struct default_ldt[]; extern struct gate_struct idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; -- cgit v1.2.2 From 010d4f8221cf51a2ab8b037d0149506b397d073f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:12 +0100 Subject: x86: introduce gate_desc type. To account for the differences in gate descriptor in i386 and x86_64 a gate_desc type is introduced. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_32.h | 15 ++++++++------- include/asm-x86/desc_64.h | 4 ++-- include/asm-x86/desc_defs.h | 8 +++++++- 3 files changed, 17 insertions(+), 10 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index bc5ca345346..77f1e5a4ad7 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -3,6 +3,7 @@ #include #include +#include #ifndef __ASSEMBLY__ @@ -24,7 +25,7 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) } extern struct desc_ptr idt_descr; -extern struct desc_struct idt_table[]; +extern gate_desc idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); static inline void pack_descriptor(__u32 *a, __u32 *b, @@ -35,11 +36,11 @@ static inline void pack_descriptor(__u32 *a, __u32 *b, (limit & 0x000f0000) | ((type & 0xff) << 8) | ((flags & 0xf) << 20); } -static inline void pack_gate(__u32 *a, __u32 *b, +static inline void pack_gate(gate_desc *gate, unsigned long base, unsigned short seg, unsigned char type, unsigned char flags) { - *a = (seg << 16) | (base & 0xffff); - *b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff); + gate->a = (seg << 16) | (base & 0xffff); + gate->b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff); } #define DESCTYPE_LDT 0x82 /* present, system, DPL-0, LDT */ @@ -139,9 +140,9 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) { - __u32 a, b; - pack_gate(&a, &b, (unsigned long)addr, seg, type, 0); - write_idt_entry(idt_table, gate, a, b); + gate_desc g; + pack_gate(&g, (unsigned long)addr, seg, type, 0); + write_idt_entry(idt_table, gate, g.a, g.b); } static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 8bd84a4ef2d..887393f044b 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -30,7 +30,7 @@ static inline unsigned long __store_tr(void) #define store_tr(tr) (tr) = __store_tr() -extern struct gate_struct idt_table[]; +extern gate_desc idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt, @@ -58,7 +58,7 @@ static inline void store_gdt(struct desc_ptr *ptr) static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) { - struct gate_struct s; + gate_desc s; s.offset_low = PTR_LOW(func); s.segment = __KERNEL_CS; diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index de47eb0a23a..9732285116a 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -39,7 +39,7 @@ enum { }; // 16byte gate -struct gate_struct { +struct gate_struct64 { u16 offset_low; u16 segment; unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; @@ -67,6 +67,12 @@ struct ldttss_desc { u32 zero1; } __attribute__((packed)); +#ifdef CONFIG_X86_64 +typedef struct gate_struct64 gate_desc; +#else +typedef struct desc_struct gate_desc; +#endif + struct desc_ptr { unsigned short size; unsigned long address; -- cgit v1.2.2 From 8d947344c47a40626730bb80d136d8daac9f2060 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:12 +0100 Subject: x86: change write_idt_entry signature this patch changes write_idt_entry signature. It now takes a gate_desc instead of the a and b parameters. It will allow it to be later unified between i386 and x86_64. Signed-off-by: Glauber de Oliveira Costa CC: Zachary Amsden CC: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_32.h | 10 ++++++++-- include/asm-x86/paravirt.h | 9 +++++---- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 77f1e5a4ad7..54b2314f2dd 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -70,9 +70,15 @@ static inline void pack_gate(gate_desc *gate, #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) #define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) #endif +static inline void native_write_idt_entry(gate_desc *idt, int entry, + const gate_desc *gate) +{ + memcpy(&idt[entry], gate, sizeof(*gate)); +} + static inline void write_dt_entry(struct desc_struct *dt, int entry, u32 entry_low, u32 entry_high) { @@ -142,7 +148,7 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned s { gate_desc g; pack_gate(&g, (unsigned long)addr, seg, type, 0); - write_idt_entry(idt_table, gate, g.a, g.b); + write_idt_entry(idt_table, gate, &g); } static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 0333fb6988b..86a9d7b0920 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -17,6 +17,7 @@ #include #include #include +#include struct page; struct thread_struct; @@ -99,8 +100,8 @@ struct pv_cpu_ops { int entrynum, u32 low, u32 high); void (*write_gdt_entry)(struct desc_struct *, int entrynum, u32 low, u32 high); - void (*write_idt_entry)(struct desc_struct *, - int entrynum, u32 low, u32 high); + void (*write_idt_entry)(gate_desc *, + int entrynum, const gate_desc *gate); void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t); void (*set_iopl_mask)(unsigned mask); @@ -667,9 +668,9 @@ static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high) { PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, low, high); } -static inline void write_idt_entry(void *dt, int entry, u32 low, u32 high) +static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) { - PVOP_VCALL4(pv_cpu_ops.write_idt_entry, dt, entry, low, high); + PVOP_VCALL3(pv_cpu_ops.write_idt_entry, dt, entry, g); } static inline void set_iopl_mask(unsigned mask) { -- cgit v1.2.2 From 25deca53e9b74a899efd3ae1f4493f4f2ce36846 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:13 +0100 Subject: x86: introduce ldt_desc type. this patch introduces ldt_desc type to account for the differences in the ldt descriptor in x86_64 and i386 Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_64.h | 2 +- include/asm-x86/desc_defs.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 887393f044b..c49f928ed8b 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -113,7 +113,7 @@ static inline void store_idt(struct desc_ptr *dtr) static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, unsigned size) { - struct ldttss_desc d; + struct ldttss_desc64 d; memset(&d, 0, sizeof(d)); d.limit0 = size & 0xFFFF; diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index 9732285116a..09ea0524349 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -58,7 +58,7 @@ enum { }; // LDT or TSS descriptor in the GDT. 16 bytes. -struct ldttss_desc { +struct ldttss_desc64 { u16 limit0; u16 base0; unsigned base1 : 8, type : 5, dpl : 2, p : 1; @@ -69,8 +69,10 @@ struct ldttss_desc { #ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc; +typedef struct ldttss_desc64 ldt_desc; #else typedef struct desc_struct gate_desc; +typedef struct desc_struct ldt_desc; #endif struct desc_ptr { -- cgit v1.2.2 From 80fbb69a8d1268ef48dfe21da80e68cb01922f31 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:13 +0100 Subject: x86: introduce fill_ldt This patch introduces fill_ldt(), which populates a ldt descriptor from a user_desc in once, instead of relying in the LDT_entry_a and LDT_entry_b macros Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 29 +++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 15 --------------- include/asm-x86/desc_64.h | 17 ----------------- 3 files changed, 29 insertions(+), 32 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 6065c509226..47086d2d929 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -1,5 +1,34 @@ +#ifndef _ASM_DESC_H_ +#define _ASM_DESC_H_ + +#ifndef __ASSEMBLY__ +#include +#include + +static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) +{ + desc->limit0 = info->limit & 0x0ffff; + desc->base0 = info->base_addr & 0x0000ffff; + + desc->base1 = (info->base_addr & 0x00ff0000) >> 16; + desc->type = (info->read_exec_only ^ 1) << 1; + desc->type |= info->contents << 2; + desc->s = 1; + desc->dpl = 0x3; + desc->p = info->seg_not_present ^ 1; + desc->limit = (info->limit & 0xf0000) >> 16; + desc->avl = info->useable; + desc->d = info->seg_32bit; + desc->g = info->limit_in_pages; + desc->base2 = (info->base_addr & 0xff000000) >> 24; +} + +#endif + #ifdef CONFIG_X86_32 # include "desc_32.h" #else # include "desc_64.h" #endif + +#endif diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 54b2314f2dd..03700991c5d 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -163,21 +163,6 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) - #define LDT_empty(info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \ diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index c49f928ed8b..ba7fb87d10f 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -147,23 +147,6 @@ static inline void set_ldt_desc(unsigned cpu, void *addr, int size) (unsigned long)addr, DESC_LDT, size * 8 - 1); } -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) -/* Don't allow setting of the lm bit. It is useless anyways because - 64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) - #define LDT_empty(info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \ -- cgit v1.2.2 From 18245d5b6e54ca76b60b687e43eb893f9e9dd611 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:13 +0100 Subject: x86: provide tss_desc Provide a new type, tss_desc, to represent the tss descriptor in a unified way accross x86_64 and i386 Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_defs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index 09ea0524349..c811f1e0829 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -70,9 +70,11 @@ struct ldttss_desc64 { #ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc; typedef struct ldttss_desc64 ldt_desc; +typedef struct ldttss_desc64 tss_desc; #else typedef struct desc_struct gate_desc; typedef struct desc_struct ldt_desc; +typedef struct desc_struct tss_desc; #endif struct desc_ptr { -- cgit v1.2.2 From 014b15be30c04622d130946ab7c0a9101b523a8a Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:13 +0100 Subject: x86: change write_gdt_entry signature. This patch changes the write_gdt_entry function signature. Instead of the old "a" and "b" parameters, it now receives a pointer to a desc_struct, and the size of the entry being handled. This is because x86_64 can have some 16-byte entries as well as 8-byte ones. Signed-off-by: Glauber de Oliveira Costa CC: Zachary Amsden CC: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_32.h | 34 ++++++++++++++++++++++------------ include/asm-x86/paravirt.h | 9 ++++++--- 2 files changed, 28 insertions(+), 15 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 03700991c5d..41d8214c617 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -28,12 +28,13 @@ extern struct desc_ptr idt_descr; extern gate_desc idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); -static inline void pack_descriptor(__u32 *a, __u32 *b, +static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, unsigned long limit, unsigned char type, unsigned char flags) { - *a = ((base & 0xffff) << 16) | (limit & 0xffff); - *b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | + desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); + desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | (limit & 0x000f0000) | ((type & 0xff) << 8) | ((flags & 0xf) << 20); + desc->p = 1; } static inline void pack_gate(gate_desc *gate, @@ -69,7 +70,8 @@ static inline void pack_gate(gate_desc *gate, #define set_ldt native_set_ldt #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_gdt_entry(dt, entry, desc, type) \ + native_write_gdt_entry(dt, entry, desc, type) #define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) #endif @@ -79,6 +81,12 @@ static inline void native_write_idt_entry(gate_desc *idt, int entry, memcpy(&idt[entry], gate, sizeof(*gate)); } +static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, + const void *desc, int type) +{ + memcpy(&gdt[entry], desc, sizeof(struct desc_struct)); +} + static inline void write_dt_entry(struct desc_struct *dt, int entry, u32 entry_low, u32 entry_high) { @@ -86,18 +94,20 @@ static inline void write_dt_entry(struct desc_struct *dt, dt[entry].b = entry_high; } + static inline void native_set_ldt(const void *addr, unsigned int entries) { if (likely(entries == 0)) __asm__ __volatile__("lldt %w0"::"q" (0)); else { unsigned cpu = smp_processor_id(); - __u32 a, b; + ldt_desc ldt; - pack_descriptor(&a, &b, (unsigned long)addr, + pack_descriptor(&ldt, (unsigned long)addr, entries * sizeof(struct desc_struct) - 1, - DESCTYPE_LDT, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); + DESC_LDT, 0); + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, + &ldt, DESC_LDT); __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); } } @@ -153,11 +163,11 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned s static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) { - __u32 a, b; - pack_descriptor(&a, &b, (unsigned long)addr, + tss_desc tss; + pack_descriptor(&tss, (unsigned long)addr, offsetof(struct tss_struct, __cacheline_filler) - 1, - DESCTYPE_TSS, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); + DESC_TSS, 0); + write_gdt_entry(get_cpu_gdt_table(cpu), entry, &tss, DESC_TSS); } diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 86a9d7b0920..3f2abf295e2 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -99,7 +99,7 @@ struct pv_cpu_ops { void (*write_ldt_entry)(struct desc_struct *, int entrynum, u32 low, u32 high); void (*write_gdt_entry)(struct desc_struct *, - int entrynum, u32 low, u32 high); + int entrynum, const void *desc, int size); void (*write_idt_entry)(gate_desc *, int entrynum, const gate_desc *gate); void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t); @@ -664,10 +664,13 @@ static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high) { PVOP_VCALL4(pv_cpu_ops.write_ldt_entry, dt, entry, low, high); } -static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high) + +static inline void write_gdt_entry(struct desc_struct *dt, int entry, + void *desc, int type) { - PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, low, high); + PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, desc, type); } + static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) { PVOP_VCALL3(pv_cpu_ops.write_idt_entry, dt, entry, g); -- cgit v1.2.2 From 75b8bb3e56ca09a467fbbe5229bc68627f7445be Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:13 +0100 Subject: x86: change write_ldt_entry signature this patch changes the signature of write_ldt_entry. Signed-off-by: Glauber de Oliveira Costa CC: Zachary Amsden CC: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_32.h | 9 ++++++++- include/asm-x86/desc_64.h | 7 ++----- include/asm-x86/paravirt.h | 10 ++++++---- 3 files changed, 16 insertions(+), 10 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 41d8214c617..92a72b0381e 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -69,12 +69,19 @@ static inline void pack_gate(gate_desc *gate, #define load_TLS(t, cpu) native_load_tls(t, cpu) #define set_ldt native_set_ldt -#define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_ldt_entry(dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc) #define write_gdt_entry(dt, entry, desc, type) \ native_write_gdt_entry(dt, entry, desc, type) #define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) #endif +static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, + const void *desc) +{ + memcpy(&ldt[entry], desc, sizeof(struct desc_struct)); +} + static inline void native_write_idt_entry(gate_desc *idt, int entry, const gate_desc *gate) { diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index ba7fb87d10f..7cdd3f0420f 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -34,12 +34,9 @@ extern gate_desc idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt, - int entry, u32 entry_low, u32 entry_high) + int entry, void *ptr) { - __u32 *lp = (__u32 *)((entry << 3) + (char *)ldt); - - lp[0] = entry_low; - lp[1] = entry_high; + memcpy(&ldt[entry], ptr, 8); } /* the cpu gdt accessor */ diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 3f2abf295e2..4f23f434a1f 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -96,8 +96,8 @@ struct pv_cpu_ops { void (*set_ldt)(const void *desc, unsigned entries); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); - void (*write_ldt_entry)(struct desc_struct *, - int entrynum, u32 low, u32 high); + void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, + const void *desc); void (*write_gdt_entry)(struct desc_struct *, int entrynum, const void *desc, int size); void (*write_idt_entry)(gate_desc *, @@ -660,9 +660,11 @@ static inline void load_TLS(struct thread_struct *t, unsigned cpu) { PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu); } -static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high) + +static inline void write_ldt_entry(struct desc_struct *dt, int entry, + const void *desc) { - PVOP_VCALL4(pv_cpu_ops.write_ldt_entry, dt, entry, low, high); + PVOP_VCALL3(pv_cpu_ops.write_ldt_entry, dt, entry, desc); } static inline void write_gdt_entry(struct desc_struct *dt, int entry, -- cgit v1.2.2 From 59fbed775aa5a6f352bfbde6b40508b541086b7e Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:14 +0100 Subject: x86: move constants to desc_defs.h this patch moves constant definitions regarding descriptor types from desc_32.h to desc_defs.h. The change from defines to enum to comply with previous versions in desc_defs.h Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_32.h | 8 -------- include/asm-x86/desc_defs.h | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 92a72b0381e..14238df87c7 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -44,14 +44,6 @@ static inline void pack_gate(gate_desc *gate, gate->b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff); } -#define DESCTYPE_LDT 0x82 /* present, system, DPL-0, LDT */ -#define DESCTYPE_TSS 0x89 /* present, system, DPL-0, 32-bit TSS */ -#define DESCTYPE_TASK 0x85 /* present, system, DPL-0, task gate */ -#define DESCTYPE_INT 0x8e /* present, system, DPL-0, interrupt gate */ -#define DESCTYPE_TRAP 0x8f /* present, system, DPL-0, trap gate */ -#define DESCTYPE_DPL3 0x60 /* DPL-3 */ -#define DESCTYPE_S 0x10 /* !system */ - #ifdef CONFIG_PARAVIRT #include #else diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index c811f1e0829..79fe59fc50e 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -55,6 +55,11 @@ struct gate_struct64 { enum { DESC_TSS = 0x9, DESC_LDT = 0x2, + DESCTYPE_TASK = 0x85, /* present, system, DPL-0, task gate */ + DESCTYPE_INT = 0x8e, /* present, system, DPL-0, interrupt gate */ + DESCTYPE_TRAP = 0x8f, /* present, system, DPL-0, trap gate */ + DESCTYPE_DPL3 = 0x60, /* DPL-3 */ + DESCTYPE_S = 0x10, /* !system */ }; // LDT or TSS descriptor in the GDT. 16 bytes. -- cgit v1.2.2 From 881c2975d02b6575c417a6eee40868d60a9ecba9 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:14 +0100 Subject: x86: unify non-paravirt parts of desc.h This patch unifies the non-paravirt part of desc_{32,64}.h into desc.h. Most of it, is simply common code, that is moved to the shared header. The only exception is the set_ldt_desc in desc_64.h, which is changed - included its name - to accomodate for the way the ldt is set up in i386. Also, constant definitions used in desc_32.h are moved to desc_defs.h Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 65 +++++++++++++++++++++++++++++++++++++++- include/asm-x86/desc_32.h | 58 ----------------------------------- include/asm-x86/desc_64.h | 55 +++++++--------------------------- include/asm-x86/mmu_context_64.h | 4 +-- 4 files changed, 76 insertions(+), 106 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 47086d2d929..99c4adc851e 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -4,6 +4,7 @@ #ifndef __ASSEMBLY__ #include #include +#include static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) { @@ -23,7 +24,8 @@ static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) desc->base2 = (info->base_addr & 0xff000000) >> 24; } -#endif +extern struct desc_ptr idt_descr; +extern gate_desc idt_table[]; #ifdef CONFIG_X86_32 # include "desc_32.h" @@ -31,4 +33,65 @@ static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) # include "desc_64.h" #endif +#define _LDT_empty(info) (\ + (info)->base_addr == 0 && \ + (info)->limit == 0 && \ + (info)->contents == 0 && \ + (info)->read_exec_only == 1 && \ + (info)->seg_32bit == 0 && \ + (info)->limit_in_pages == 0 && \ + (info)->seg_not_present == 1 && \ + (info)->useable == 0) + +#ifdef CONFIG_X86_64 +#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) +#else +#define LDT_empty(info) (_LDT_empty(info)) +#endif + +static inline void clear_LDT(void) +{ + set_ldt(NULL, 0); +} + +/* + * load one particular LDT into the current CPU + */ +static inline void load_LDT_nolock(mm_context_t *pc) +{ + set_ldt(pc->ldt, pc->size); +} + +static inline void load_LDT(mm_context_t *pc) +{ + preempt_disable(); + load_LDT_nolock(pc); + preempt_enable(); +} + +#else +/* + * GET_DESC_BASE reads the descriptor base of the specified segment. + * + * Args: + * idx - descriptor index + * gdt - GDT pointer + * base - 32bit register to which the base will be written + * lo_w - lo word of the "base" register + * lo_b - lo byte of the "base" register + * hi_b - hi byte of the low word of the "base" register + * + * Example: + * GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) + * Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. + */ +#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \ + movb idx*8+4(gdt), lo_b; \ + movb idx*8+7(gdt), hi_b; \ + shll $16, base; \ + movw idx*8+2(gdt), lo_w; + + +#endif /* __ASSEMBLY__ */ + #endif diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 14238df87c7..01415ad35fd 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -11,8 +11,6 @@ #include #include -#include - struct gdt_page { struct desc_struct gdt[GDT_ENTRIES]; @@ -24,8 +22,6 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) return per_cpu(gdt_page, cpu).gdt; } -extern struct desc_ptr idt_descr; -extern gate_desc idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); static inline void pack_descriptor(struct desc_struct *desc, @@ -172,36 +168,6 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -static inline void clear_LDT(void) -{ - set_ldt(NULL, 0); -} - -/* - * load one particular LDT into the current CPU - */ -static inline void load_LDT_nolock(mm_context_t *pc) -{ - set_ldt(pc->ldt, pc->size); -} - -static inline void load_LDT(mm_context_t *pc) -{ - preempt_disable(); - load_LDT_nolock(pc); - preempt_enable(); -} - static inline unsigned long get_desc_base(unsigned long *desc) { unsigned long base; @@ -210,30 +176,6 @@ static inline unsigned long get_desc_base(unsigned long *desc) (desc[1] & 0xff000000); return base; } - -#else /* __ASSEMBLY__ */ - -/* - * GET_DESC_BASE reads the descriptor base of the specified segment. - * - * Args: - * idx - descriptor index - * gdt - GDT pointer - * base - 32bit register to which the base will be written - * lo_w - lo word of the "base" register - * lo_b - lo byte of the "base" register - * hi_b - hi byte of the low word of the "base" register - * - * Example: - * GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) - * Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. - */ -#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \ - movb idx*8+4(gdt), lo_b; \ - movb idx*8+7(gdt), hi_b; \ - shll $16, base; \ - movw idx*8+2(gdt), lo_w; - #endif /* !__ASSEMBLY__ */ #endif diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 7cdd3f0420f..c037c7d55b9 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -9,16 +9,13 @@ #include #include -#include #include -#include extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; #define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8)) #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8)) -#define clear_LDT() asm volatile("lldt %w0"::"r" (0)) static inline unsigned long __store_tr(void) { @@ -30,7 +27,6 @@ static inline unsigned long __store_tr(void) #define store_tr(tr) (tr) = __store_tr() -extern gate_desc idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt, @@ -138,22 +134,18 @@ static inline void set_tss_desc(unsigned cpu, void *addr) IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); } -static inline void set_ldt_desc(unsigned cpu, void *addr, int size) +static inline void set_ldt(void *addr, int entries) { - set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], - (unsigned long)addr, DESC_LDT, size * 8 - 1); -} + if (likely(entries == 0)) + __asm__ __volatile__("lldt %w0"::"q" (0)); + else { + unsigned cpu = smp_processor_id(); -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 && \ - (info)->lm == 0) + set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], + (unsigned long)addr, DESC_LDT, entries * 8 - 1); + __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); + } +} static inline void load_TLS(struct thread_struct *t, unsigned int cpu) { @@ -164,32 +156,6 @@ static inline void load_TLS(struct thread_struct *t, unsigned int cpu) gdt[i] = t->tls_array[i]; } -/* - * load one particular LDT into the current CPU - */ -static inline void load_LDT_nolock(mm_context_t *pc, int cpu) -{ - int count = pc->size; - - if (likely(!count)) { - clear_LDT(); - return; - } - - set_ldt_desc(cpu, pc->ldt, count); - load_LDT_desc(); -} - -static inline void load_LDT(mm_context_t *pc) -{ - int cpu = get_cpu(); - - load_LDT_nolock(pc, cpu); - put_cpu(); -} - -extern struct desc_ptr idt_descr; - static inline unsigned long get_desc_base(const void *ptr) { const u32 *desc = ptr; @@ -199,7 +165,6 @@ static inline unsigned long get_desc_base(const void *ptr) (desc[1] & 0xff000000); return base; } - #endif /* !__ASSEMBLY__ */ #endif diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h index 29f95c3acc2..98bfe43dd80 100644 --- a/include/asm-x86/mmu_context_64.h +++ b/include/asm-x86/mmu_context_64.h @@ -43,7 +43,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, load_cr3(next->pgd); if (unlikely(next->context.ldt != prev->context.ldt)) - load_LDT_nolock(&next->context, cpu); + load_LDT_nolock(&next->context); } #ifdef CONFIG_SMP else { @@ -56,7 +56,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * to make sure to use no freed page tables. */ load_cr3(next->pgd); - load_LDT_nolock(&next->context, cpu); + load_LDT_nolock(&next->context); } } #endif -- cgit v1.2.2 From 26048d75e8d6c840742468667f4a7ab8c2df74c9 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:14 +0100 Subject: x86: use the same data type for tls_array. This patch changes the type of tls_array in x86_64 to a desc_struct. Now, both i386 and x86_64 tls_array have the same type, and code accessing it can be shared. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc_64.h | 2 +- include/asm-x86/processor_64.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index c037c7d55b9..448f96ed973 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -150,7 +150,7 @@ static inline void set_ldt(void *addr, int entries) static inline void load_TLS(struct thread_struct *t, unsigned int cpu) { unsigned int i; - u64 *gdt = (u64 *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); + struct desc_struct *gdt = (get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) gdt[i] = t->tls_array[i]; diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 7b7f8a142e2..a0a9e551509 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -19,6 +19,7 @@ #include #include #include +#include #define TF_MASK 0x00000100 #define IF_MASK 0x00000200 @@ -244,7 +245,7 @@ struct thread_struct { * goes into MSR_IA32_DS_AREA */ unsigned long ds_area_msr; /* cached TLS descriptors. */ - u64 tls_array[GDT_ENTRY_TLS_ENTRIES]; + struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; } __attribute__((aligned(16))); #define INIT_THREAD { \ -- cgit v1.2.2 From cc6978528cbd475d952e0eb5073375839dfb600e Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:14 +0100 Subject: x86: modify get_desc_base This patch makes get_desc_base() receive a struct desc_struct, and then uses its internal fields to compute the base address. This is done at both i386 and x86_64, and then it is moved to common header Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 5 +++++ include/asm-x86/desc_32.h | 8 -------- include/asm-x86/desc_64.h | 9 --------- 3 files changed, 5 insertions(+), 17 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 99c4adc851e..a6fdd7c7b6b 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -69,6 +69,11 @@ static inline void load_LDT(mm_context_t *pc) preempt_enable(); } +static inline unsigned long get_desc_base(struct desc_struct *desc) +{ + return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); +} + #else /* * GET_DESC_BASE reads the descriptor base of the specified segment. diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 01415ad35fd..8450c2a99c3 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -168,14 +168,6 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -static inline unsigned long get_desc_base(unsigned long *desc) -{ - unsigned long base; - base = ((desc[0] >> 16) & 0x0000ffff) | - ((desc[1] << 16) & 0x00ff0000) | - (desc[1] & 0xff000000); - return base; -} #endif /* !__ASSEMBLY__ */ #endif diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 448f96ed973..a7a6c301c6b 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -156,15 +156,6 @@ static inline void load_TLS(struct thread_struct *t, unsigned int cpu) gdt[i] = t->tls_array[i]; } -static inline unsigned long get_desc_base(const void *ptr) -{ - const u32 *desc = ptr; - unsigned long base; - base = ((desc[0] >> 16) & 0x0000ffff) | - ((desc[1] << 16) & 0x00ff0000) | - (desc[1] & 0xff000000); - return base; -} #endif /* !__ASSEMBLY__ */ #endif -- cgit v1.2.2 From 54cd0eac7286b83ef1a657d2dddd74e0556209e7 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:14 +0100 Subject: x86: unify paravirt pieces of descriptor handling With the types used to access descriptors in x86_64 and i386 now being the same, the code that effectively handles them can now be easily shared. This patch moves the paravirt part of desc_32.h into desc.h, and then, we get paravirt support in x86_64 for free. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 169 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 130 ---------------------------------- include/asm-x86/desc_64.h | 104 +++------------------------ include/asm-x86/desc_defs.h | 6 +- 4 files changed, 183 insertions(+), 226 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index a6fdd7c7b6b..e61a5a38cab 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -5,6 +5,7 @@ #include #include #include +#include static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) { @@ -27,6 +28,174 @@ static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) extern struct desc_ptr idt_descr; extern gate_desc idt_table[]; +#ifdef CONFIG_X86_64 +extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; +extern struct desc_ptr cpu_gdt_descr[]; +/* the cpu gdt accessor */ +#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) +#else +struct gdt_page { + struct desc_struct gdt[GDT_ENTRIES]; +} __attribute__((aligned(PAGE_SIZE))); +DECLARE_PER_CPU(struct gdt_page, gdt_page); + +static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) +{ + return per_cpu(gdt_page, cpu).gdt; +} +#endif + +#ifdef CONFIG_PARAVIRT +#include +#else +#define load_TR_desc() native_load_tr_desc() +#define load_gdt(dtr) native_load_gdt(dtr) +#define load_idt(dtr) native_load_idt(dtr) +#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr)) +#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) + +#define store_gdt(dtr) native_store_gdt(dtr) +#define store_idt(dtr) native_store_idt(dtr) +#define store_tr(tr) (tr = native_store_tr()) +#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt)) + +#define load_TLS(t, cpu) native_load_tls(t, cpu) +#define set_ldt native_set_ldt + +#define write_ldt_entry(dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc) +#define write_gdt_entry(dt, entry, desc, type) \ + native_write_gdt_entry(dt, entry, desc, type) +#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) +#endif + +static inline void native_write_idt_entry(gate_desc *idt, int entry, + const gate_desc *gate) +{ + memcpy(&idt[entry], gate, sizeof(*gate)); +} + +static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, + const void *desc) +{ + memcpy(&ldt[entry], desc, 8); +} + +static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, + const void *desc, int type) +{ + unsigned int size; + switch (type) { + case DESC_TSS: + size = sizeof(tss_desc); + break; + case DESC_LDT: + size = sizeof(ldt_desc); + break; + default: + size = sizeof(struct desc_struct); + break; + } + memcpy(&gdt[entry], desc, size); +} + +static inline void set_tssldt_descriptor(struct ldttss_desc64 *d, + unsigned long tss, unsigned type, + unsigned size) +{ + memset(d, 0, sizeof(*d)); + d->limit0 = size & 0xFFFF; + d->base0 = PTR_LOW(tss); + d->base1 = PTR_MIDDLE(tss) & 0xFF; + d->type = type; + d->p = 1; + d->limit1 = (size >> 16) & 0xF; + d->base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; + d->base3 = PTR_HIGH(tss); +} + +static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, + unsigned long limit, unsigned char type, + unsigned char flags) +{ + desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); + desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | + (limit & 0x000f0000) | ((type & 0xff) << 8) | + ((flags & 0xf) << 20); + desc->p = 1; +} + +static inline void pack_ldt(ldt_desc *ldt, unsigned long addr, + unsigned size) +{ + +#ifdef CONFIG_X86_64 + set_tssldt_descriptor(ldt, + addr, DESC_LDT, size); +#else + pack_descriptor(ldt, (unsigned long)addr, + size, + 0x80 | DESC_LDT, 0); +#endif +} + +static inline void native_set_ldt(const void *addr, unsigned int entries) +{ + if (likely(entries == 0)) + __asm__ __volatile__("lldt %w0"::"q" (0)); + else { + unsigned cpu = smp_processor_id(); + ldt_desc ldt; + + pack_ldt(&ldt, (unsigned long)addr, + entries * sizeof(ldt) - 1); + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, + &ldt, DESC_LDT); + __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); + } +} + +static inline void native_load_tr_desc(void) +{ + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); +} + +static inline void native_load_gdt(const struct desc_ptr *dtr) +{ + asm volatile("lgdt %0"::"m" (*dtr)); +} + +static inline void native_load_idt(const struct desc_ptr *dtr) +{ + asm volatile("lidt %0"::"m" (*dtr)); +} + +static inline void native_store_gdt(struct desc_ptr *dtr) +{ + asm volatile("sgdt %0":"=m" (*dtr)); +} + +static inline void native_store_idt(struct desc_ptr *dtr) +{ + asm volatile("sidt %0":"=m" (*dtr)); +} + +static inline unsigned long native_store_tr(void) +{ + unsigned long tr; + asm volatile("str %0":"=r" (tr)); + return tr; +} + +static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) +{ + unsigned int i; + struct desc_struct *gdt = get_cpu_gdt_table(cpu); + + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; +} + #ifdef CONFIG_X86_32 # include "desc_32.h" #else diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 8450c2a99c3..4bf20b7dd74 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -8,31 +8,10 @@ #ifndef __ASSEMBLY__ #include -#include #include -struct gdt_page -{ - struct desc_struct gdt[GDT_ENTRIES]; -} __attribute__((aligned(PAGE_SIZE))); -DECLARE_PER_CPU(struct gdt_page, gdt_page); - -static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) -{ - return per_cpu(gdt_page, cpu).gdt; -} - extern void set_intr_gate(unsigned int irq, void * addr); -static inline void pack_descriptor(struct desc_struct *desc, - unsigned long base, unsigned long limit, unsigned char type, unsigned char flags) -{ - desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); - desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | - (limit & 0x000f0000) | ((type & 0xff) << 8) | ((flags & 0xf) << 20); - desc->p = 1; -} - static inline void pack_gate(gate_desc *gate, unsigned long base, unsigned short seg, unsigned char type, unsigned char flags) { @@ -40,115 +19,6 @@ static inline void pack_gate(gate_desc *gate, gate->b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff); } -#ifdef CONFIG_PARAVIRT -#include -#else -#define load_TR_desc() native_load_tr_desc() -#define load_gdt(dtr) native_load_gdt(dtr) -#define load_idt(dtr) native_load_idt(dtr) -#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr)) -#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) - -#define store_gdt(dtr) native_store_gdt(dtr) -#define store_idt(dtr) native_store_idt(dtr) -#define store_tr(tr) (tr = native_store_tr()) -#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt)) - -#define load_TLS(t, cpu) native_load_tls(t, cpu) -#define set_ldt native_set_ldt - -#define write_ldt_entry(dt, entry, desc) \ - native_write_ldt_entry(dt, entry, desc) -#define write_gdt_entry(dt, entry, desc, type) \ - native_write_gdt_entry(dt, entry, desc, type) -#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) -#endif - -static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, - const void *desc) -{ - memcpy(&ldt[entry], desc, sizeof(struct desc_struct)); -} - -static inline void native_write_idt_entry(gate_desc *idt, int entry, - const gate_desc *gate) -{ - memcpy(&idt[entry], gate, sizeof(*gate)); -} - -static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, - const void *desc, int type) -{ - memcpy(&gdt[entry], desc, sizeof(struct desc_struct)); -} - -static inline void write_dt_entry(struct desc_struct *dt, - int entry, u32 entry_low, u32 entry_high) -{ - dt[entry].a = entry_low; - dt[entry].b = entry_high; -} - - -static inline void native_set_ldt(const void *addr, unsigned int entries) -{ - if (likely(entries == 0)) - __asm__ __volatile__("lldt %w0"::"q" (0)); - else { - unsigned cpu = smp_processor_id(); - ldt_desc ldt; - - pack_descriptor(&ldt, (unsigned long)addr, - entries * sizeof(struct desc_struct) - 1, - DESC_LDT, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, - &ldt, DESC_LDT); - __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); - } -} - - -static inline void native_load_tr_desc(void) -{ - asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); -} - -static inline void native_load_gdt(const struct desc_ptr *dtr) -{ - asm volatile("lgdt %0"::"m" (*dtr)); -} - -static inline void native_load_idt(const struct desc_ptr *dtr) -{ - asm volatile("lidt %0"::"m" (*dtr)); -} - -static inline void native_store_gdt(struct desc_ptr *dtr) -{ - asm ("sgdt %0":"=m" (*dtr)); -} - -static inline void native_store_idt(struct desc_ptr *dtr) -{ - asm ("sidt %0":"=m" (*dtr)); -} - -static inline unsigned long native_store_tr(void) -{ - unsigned long tr; - asm ("str %0":"=r" (tr)); - return tr; -} - -static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) -{ - unsigned int i; - struct desc_struct *gdt = get_cpu_gdt_table(cpu); - - for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) - gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; -} - static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) { gate_desc g; diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index a7a6c301c6b..b0290c45319 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -8,47 +8,10 @@ #ifndef __ASSEMBLY__ #include -#include #include -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; - -#define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8)) -#define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8)) - -static inline unsigned long __store_tr(void) -{ - unsigned long tr; - - asm volatile ("str %w0":"=r" (tr)); - return tr; -} - -#define store_tr(tr) (tr) = __store_tr() - -extern struct desc_ptr cpu_gdt_descr[]; - -static inline void write_ldt_entry(struct desc_struct *ldt, - int entry, void *ptr) -{ - memcpy(&ldt[entry], ptr, 8); -} - -/* the cpu gdt accessor */ -#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) - -static inline void load_gdt(const struct desc_ptr *ptr) -{ - asm volatile("lgdt %w0"::"m" (*ptr)); -} - -static inline void store_gdt(struct desc_ptr *ptr) -{ - asm("sgdt %w0":"=m" (*ptr)); -} - -static inline void _set_gate(void *adr, unsigned type, unsigned long func, +static inline void _set_gate(int gate, unsigned type, unsigned long func, unsigned dpl, unsigned ist) { gate_desc s; @@ -67,61 +30,37 @@ static inline void _set_gate(void *adr, unsigned type, unsigned long func, * does not need to be atomic because it is only done once at * setup time */ - memcpy(adr, &s, 16); + write_idt_entry(idt_table, gate, &s); } static inline void set_intr_gate(int nr, void *func) { BUG_ON((unsigned)nr > 0xFF); - _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0); + _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 0, 0); } static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) { BUG_ON((unsigned)nr > 0xFF); - _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, ist); + _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 0, ist); } static inline void set_system_gate(int nr, void *func) { BUG_ON((unsigned)nr > 0xFF); - _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); + _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 3, 0); } static inline void set_system_gate_ist(int nr, void *func, unsigned ist) { - _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist); -} - -static inline void load_idt(const struct desc_ptr *ptr) -{ - asm volatile("lidt %w0"::"m" (*ptr)); -} - -static inline void store_idt(struct desc_ptr *dtr) -{ - asm("sidt %w0":"=m" (*dtr)); -} - -static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, - unsigned type, unsigned size) -{ - struct ldttss_desc64 d; - - memset(&d, 0, sizeof(d)); - d.limit0 = size & 0xFFFF; - d.base0 = PTR_LOW(tss); - d.base1 = PTR_MIDDLE(tss) & 0xFF; - d.type = type; - d.p = 1; - d.limit1 = (size >> 16) & 0xF; - d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; - d.base3 = PTR_HIGH(tss); - memcpy(ptr, &d, 16); + _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 3, ist); } static inline void set_tss_desc(unsigned cpu, void *addr) { + struct desc_struct *d = get_cpu_gdt_table(cpu); + tss_desc tss; + /* * sizeof(unsigned long) coming from an extra "long" at the end * of the iobitmap. See tss_struct definition in processor.h @@ -129,31 +68,10 @@ static inline void set_tss_desc(unsigned cpu, void *addr) * -1? seg base+limit should be pointing to the address of the * last valid byte */ - set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS], + set_tssldt_descriptor(&tss, (unsigned long)addr, DESC_TSS, IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); -} - -static inline void set_ldt(void *addr, int entries) -{ - if (likely(entries == 0)) - __asm__ __volatile__("lldt %w0"::"q" (0)); - else { - unsigned cpu = smp_processor_id(); - - set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], - (unsigned long)addr, DESC_LDT, entries * 8 - 1); - __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); - } -} - -static inline void load_TLS(struct thread_struct *t, unsigned int cpu) -{ - unsigned int i; - struct desc_struct *gdt = (get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); - - for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) - gdt[i] = t->tls_array[i]; + write_gdt_entry(d, GDT_ENTRY_TSS, &tss, DESC_TSS); } #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index 79fe59fc50e..ebb64fe3a45 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -48,9 +48,9 @@ struct gate_struct64 { u32 zero1; } __attribute__((packed)); -#define PTR_LOW(x) ((unsigned long)(x) & 0xFFFF) -#define PTR_MIDDLE(x) (((unsigned long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH(x) ((unsigned long)(x) >> 32) +#define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF) +#define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH(x) ((unsigned long long)(x) >> 32) enum { DESC_TSS = 0x9, -- cgit v1.2.2 From 507f90c9f92592e7630b1c1e87bf92d2c9858cc6 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:14 +0100 Subject: x86: move _set_gate and its users to a common location This patch moves _set_gate and its users to desc.h. We can now use common code for x86_64 and i386. [ mingo@elte.hu: set_system_gate() fixes for nasty crashes. ] Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 92 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 16 -------- include/asm-x86/desc_64.h | 45 ---------------------- include/asm-x86/desc_defs.h | 5 +-- 4 files changed, 93 insertions(+), 65 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index e61a5a38cab..d75bc063431 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -33,6 +33,22 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; extern struct desc_ptr cpu_gdt_descr[]; /* the cpu gdt accessor */ #define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) + +static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, + unsigned dpl, unsigned ist, unsigned seg) +{ + gate->offset_low = PTR_LOW(func); + gate->segment = __KERNEL_CS; + gate->ist = ist; + gate->p = 1; + gate->dpl = dpl; + gate->zero0 = 0; + gate->zero1 = 0; + gate->type = type; + gate->offset_middle = PTR_MIDDLE(func); + gate->offset_high = PTR_HIGH(func); +} + #else struct gdt_page { struct desc_struct gdt[GDT_ENTRIES]; @@ -43,6 +59,16 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) { return per_cpu(gdt_page, cpu).gdt; } + +static inline void pack_gate(gate_desc *gate, unsigned char type, + unsigned long base, unsigned dpl, unsigned flags, unsigned short seg) + +{ + gate->a = (seg << 16) | (base & 0xffff); + gate->b = (base & 0xffff0000) | + (((0x80 | type | (dpl << 5)) & 0xff) << 8); +} + #endif #ifdef CONFIG_PARAVIRT @@ -242,6 +268,72 @@ static inline unsigned long get_desc_base(struct desc_struct *desc) { return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); } +static inline void _set_gate(int gate, unsigned type, void *addr, + unsigned dpl, unsigned ist, unsigned seg) +{ + gate_desc s; + pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); + /* + * does not need to be atomic because it is only done once at + * setup time + */ + write_idt_entry(idt_table, gate, &s); +} + +/* + * This needs to use 'idt_table' rather than 'idt', and + * thus use the _nonmapped_ version of the IDT, as the + * Pentium F0 0F bugfix can have resulted in the mapped + * IDT being write-protected. + */ +static inline void set_intr_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); +} + +/* + * This routine sets up an interrupt gate at directory privilege level 3. + */ +static inline void set_system_intr_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); +} + +static inline void set_trap_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS); +} + +static inline void set_system_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); +#ifdef CONFIG_X86_32 + _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS); +#else + _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); +#endif +} + +static inline void set_task_gate(unsigned int n, unsigned int gdt_entry) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3)); +} + +static inline void set_intr_gate_ist(int n, void *addr, unsigned ist) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS); +} + +static inline void set_system_gate_ist(int n, void *addr, unsigned ist) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); +} #else /* diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 4bf20b7dd74..3b112ec186a 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -10,22 +10,6 @@ #include #include -extern void set_intr_gate(unsigned int irq, void * addr); - -static inline void pack_gate(gate_desc *gate, - unsigned long base, unsigned short seg, unsigned char type, unsigned char flags) -{ - gate->a = (seg << 16) | (base & 0xffff); - gate->b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff); -} - -static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) -{ - gate_desc g; - pack_gate(&g, (unsigned long)addr, seg, type, 0); - write_idt_entry(idt_table, gate, &g); -} - static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) { tss_desc tss; diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index b0290c45319..6bc92e6e5cc 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -11,51 +11,6 @@ #include -static inline void _set_gate(int gate, unsigned type, unsigned long func, - unsigned dpl, unsigned ist) -{ - gate_desc s; - - s.offset_low = PTR_LOW(func); - s.segment = __KERNEL_CS; - s.ist = ist; - s.p = 1; - s.dpl = dpl; - s.zero0 = 0; - s.zero1 = 0; - s.type = type; - s.offset_middle = PTR_MIDDLE(func); - s.offset_high = PTR_HIGH(func); - /* - * does not need to be atomic because it is only done once at - * setup time - */ - write_idt_entry(idt_table, gate, &s); -} - -static inline void set_intr_gate(int nr, void *func) -{ - BUG_ON((unsigned)nr > 0xFF); - _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 0, 0); -} - -static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) -{ - BUG_ON((unsigned)nr > 0xFF); - _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 0, ist); -} - -static inline void set_system_gate(int nr, void *func) -{ - BUG_ON((unsigned)nr > 0xFF); - _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 3, 0); -} - -static inline void set_system_gate_ist(int nr, void *func, unsigned ist) -{ - _set_gate(nr, GATE_INTERRUPT, (unsigned long) func, 3, ist); -} - static inline void set_tss_desc(unsigned cpu, void *addr) { struct desc_struct *d = get_cpu_gdt_table(cpu); diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index ebb64fe3a45..e33f078b3e5 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -36,6 +36,7 @@ enum { GATE_INTERRUPT = 0xE, GATE_TRAP = 0xF, GATE_CALL = 0xC, + GATE_TASK = 0x5, }; // 16byte gate @@ -55,10 +56,6 @@ struct gate_struct64 { enum { DESC_TSS = 0x9, DESC_LDT = 0x2, - DESCTYPE_TASK = 0x85, /* present, system, DPL-0, task gate */ - DESCTYPE_INT = 0x8e, /* present, system, DPL-0, interrupt gate */ - DESCTYPE_TRAP = 0x8f, /* present, system, DPL-0, trap gate */ - DESCTYPE_DPL3 = 0x60, /* DPL-3 */ DESCTYPE_S = 0x10, /* !system */ }; -- cgit v1.2.2 From c81c6ca45a69478c7877b729af1942d2b80ef582 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:14 +0100 Subject: x86: unify set_tss_desc This patch unifies the set_tss_desc between i386 and x86_64, which can now have a common implementation. After the old functions are removed from desc_{32,64}.h, nothing important is left, and the files can be removed. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 39 +++++++++++++++++++++++++++++++++------ include/asm-x86/desc_32.h | 27 --------------------------- include/asm-x86/desc_64.h | 33 --------------------------------- 3 files changed, 33 insertions(+), 66 deletions(-) delete mode 100644 include/asm-x86/desc_32.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index d75bc063431..c31715cf221 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -165,6 +165,39 @@ static inline void pack_ldt(ldt_desc *ldt, unsigned long addr, #endif } +static inline void pack_tss(tss_desc *tss, unsigned long addr, + unsigned size, unsigned entry) +{ +#ifdef CONFIG_X86_64 + set_tssldt_descriptor(tss, + addr, entry, size); +#else + pack_descriptor(tss, (unsigned long)addr, + size, + 0x80 | entry, 0); +#endif +} + +static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr) +{ + struct desc_struct *d = get_cpu_gdt_table(cpu); + tss_desc tss; + + /* + * sizeof(unsigned long) coming from an extra "long" at the end + * of the iobitmap. See tss_struct definition in processor.h + * + * -1? seg base+limit should be pointing to the address of the + * last valid byte + */ + pack_tss(&tss, (unsigned long)addr, + IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1, + DESC_TSS); + write_gdt_entry(d, entry, &tss, DESC_TSS); +} + +#define set_tss_desc(cpu, addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) + static inline void native_set_ldt(const void *addr, unsigned int entries) { if (likely(entries == 0)) @@ -222,12 +255,6 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#ifdef CONFIG_X86_32 -# include "desc_32.h" -#else -# include "desc_64.h" -#endif - #define _LDT_empty(info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \ diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h deleted file mode 100644 index 3b112ec186a..00000000000 --- a/include/asm-x86/desc_32.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H - -#include -#include -#include - -#ifndef __ASSEMBLY__ - -#include -#include - -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) -{ - tss_desc tss; - pack_descriptor(&tss, (unsigned long)addr, - offsetof(struct tss_struct, __cacheline_filler) - 1, - DESC_TSS, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), entry, &tss, DESC_TSS); -} - - -#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) - -#endif /* !__ASSEMBLY__ */ - -#endif diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 6bc92e6e5cc..8b137891791 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -1,34 +1 @@ -/* Written 2000 by Andi Kleen */ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H -#include -#include - -#ifndef __ASSEMBLY__ - -#include - -#include - -static inline void set_tss_desc(unsigned cpu, void *addr) -{ - struct desc_struct *d = get_cpu_gdt_table(cpu); - tss_desc tss; - - /* - * sizeof(unsigned long) coming from an extra "long" at the end - * of the iobitmap. See tss_struct definition in processor.h - * - * -1? seg base+limit should be pointing to the address of the - * last valid byte - */ - set_tssldt_descriptor(&tss, - (unsigned long)addr, DESC_TSS, - IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); - write_gdt_entry(d, GDT_ENTRY_TSS, &tss, DESC_TSS); -} - -#endif /* !__ASSEMBLY__ */ - -#endif -- cgit v1.2.2 From 341d8854d38fe6e7655f7748babae5c25a51aa70 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:17 +0100 Subject: x86: remove fastcall from include/asm-x86 Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/apic.h | 6 +++--- include/asm-x86/hw_irq_32.h | 14 +++++++------- include/asm-x86/mutex_32.h | 7 +++---- include/asm-x86/semaphore_32.h | 8 ++++---- 4 files changed, 17 insertions(+), 18 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 423022759cb..72bf09cf13a 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -59,17 +59,17 @@ extern unsigned boot_cpu_id; #define setup_secondary_clock setup_secondary_APIC_clock #endif -static inline fastcall void native_apic_write(unsigned long reg, u32 v) +static inline void native_apic_write(unsigned long reg, u32 v) { *((volatile u32 *)(APIC_BASE + reg)) = v; } -static inline fastcall void native_apic_write_atomic(unsigned long reg, u32 v) +static inline void native_apic_write_atomic(unsigned long reg, u32 v) { (void) xchg((u32*)(APIC_BASE + reg), v); } -static inline fastcall u32 native_apic_read(unsigned long reg) +static inline u32 native_apic_read(unsigned long reg) { return *((volatile u32 *)(APIC_BASE + reg)); } diff --git a/include/asm-x86/hw_irq_32.h b/include/asm-x86/hw_irq_32.h index 0bedbdf5e90..b93e35a708a 100644 --- a/include/asm-x86/hw_irq_32.h +++ b/include/asm-x86/hw_irq_32.h @@ -29,16 +29,16 @@ extern void (*interrupt[NR_IRQS])(void); #ifdef CONFIG_SMP -fastcall void reschedule_interrupt(void); -fastcall void invalidate_interrupt(void); -fastcall void call_function_interrupt(void); +void reschedule_interrupt(void); +void invalidate_interrupt(void); +void call_function_interrupt(void); #endif #ifdef CONFIG_X86_LOCAL_APIC -fastcall void apic_timer_interrupt(void); -fastcall void error_interrupt(void); -fastcall void spurious_interrupt(void); -fastcall void thermal_interrupt(void); +void apic_timer_interrupt(void); +void error_interrupt(void); +void spurious_interrupt(void); +void thermal_interrupt(void); #define platform_legacy_irq(irq) ((irq) < 16) #endif diff --git a/include/asm-x86/mutex_32.h b/include/asm-x86/mutex_32.h index 7a17d9e58ad..bbeefb96ddf 100644 --- a/include/asm-x86/mutex_32.h +++ b/include/asm-x86/mutex_32.h @@ -26,7 +26,7 @@ do { \ unsigned int dummy; \ \ typecheck(atomic_t *, count); \ - typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ + typecheck_fn(void (*)(atomic_t *), fail_fn); \ \ __asm__ __volatile__( \ LOCK_PREFIX " decl (%%eax) \n" \ @@ -51,8 +51,7 @@ do { \ * or anything the slow path function returns */ static inline int -__mutex_fastpath_lock_retval(atomic_t *count, - int fastcall (*fail_fn)(atomic_t *)) +__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) { if (unlikely(atomic_dec_return(count) < 0)) return fail_fn(count); @@ -78,7 +77,7 @@ do { \ unsigned int dummy; \ \ typecheck(atomic_t *, count); \ - typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ + typecheck_fn(void (*)(atomic_t *), fail_fn); \ \ __asm__ __volatile__( \ LOCK_PREFIX " incl (%%eax) \n" \ diff --git a/include/asm-x86/semaphore_32.h b/include/asm-x86/semaphore_32.h index 835c1d751a9..cc826e85323 100644 --- a/include/asm-x86/semaphore_32.h +++ b/include/asm-x86/semaphore_32.h @@ -83,10 +83,10 @@ static inline void init_MUTEX_LOCKED (struct semaphore *sem) sema_init(sem, 0); } -fastcall void __down_failed(void /* special register calling convention */); -fastcall int __down_failed_interruptible(void /* params in registers */); -fastcall int __down_failed_trylock(void /* params in registers */); -fastcall void __up_wakeup(void /* special register calling convention */); +void __down_failed(void /* special register calling convention */); +int __down_failed_interruptible(void /* params in registers */); +int __down_failed_trylock(void /* params in registers */); +void __up_wakeup(void /* special register calling convention */); /* * This is ugly, but we want the default case to fall through. -- cgit v1.2.2 From 1e160cc3f3b5c38bba79c58172e82c1e24934546 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 30 Jan 2008 13:31:17 +0100 Subject: x86: __vdso_getcpu() warning fix arch/x86/vdso/vgetcpu.c: In function '__vdso_getcpu': arch/x86/vdso/vgetcpu.c:22: warning: pointer targets in passing argument 1 of 'native_read_tscp' differ in signedness Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 040d3910d89..088652a62d5 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -13,7 +13,7 @@ #include #include -static inline unsigned long long native_read_tscp(int *aux) +static inline unsigned long long native_read_tscp(unsigned int *aux) { unsigned long low, high; asm volatile (".byte 0x0f,0x01,0xf9" -- cgit v1.2.2 From 5b83683f32b113d07edfb67a33ce389fc624423d Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:31:19 +0100 Subject: x86: EFI runtime service support This patch adds basic runtime services support for EFI x86_64 system. The main file of the patch is the addition of efi_64.c for x86_64. This file is modeled after the EFI IA32 avatar. EFI runtime services initialization are implemented in efi_64.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to EFI firmware services need to follow the EFI calling convention. For this purpose, a set of functions named efi_call ( is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service. The duplicated code between efi_32.c and efi_64.c is placed in efi.c to remove them from efi_32.c. Signed-off-by: Chandramouli Narayanan Signed-off-by: Huang Ying Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/bootparam.h | 5 ++-- include/asm-x86/efi.h | 70 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/fixmap_64.h | 3 ++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 include/asm-x86/efi.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h index 19f3ddf2df4..51151356840 100644 --- a/include/asm-x86/bootparam.h +++ b/include/asm-x86/bootparam.h @@ -54,13 +54,14 @@ struct sys_desc_table { }; struct efi_info { - __u32 _pad1; + __u32 efi_loader_signature; __u32 efi_systab; __u32 efi_memdesc_size; __u32 efi_memdesc_version; __u32 efi_memmap; __u32 efi_memmap_size; - __u32 _pad2[2]; + __u32 efi_systab_hi; + __u32 efi_memmap_hi; }; /* The so-called "zeropage" */ diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h new file mode 100644 index 00000000000..1459d3d5865 --- /dev/null +++ b/include/asm-x86/efi.h @@ -0,0 +1,70 @@ +#ifndef _ASM_X86_EFI_H +#define _ASM_X86_EFI_H + +#ifdef CONFIG_X86_32 +#else /* !CONFIG_X86_32 */ + +#define MAX_EFI_IO_PAGES 100 + +extern u64 efi_call0(void *fp); +extern u64 efi_call1(void *fp, u64 arg1); +extern u64 efi_call2(void *fp, u64 arg1, u64 arg2); +extern u64 efi_call3(void *fp, u64 arg1, u64 arg2, u64 arg3); +extern u64 efi_call4(void *fp, u64 arg1, u64 arg2, u64 arg3, u64 arg4); +extern u64 efi_call5(void *fp, u64 arg1, u64 arg2, u64 arg3, + u64 arg4, u64 arg5); +extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, + u64 arg4, u64 arg5, u64 arg6); + +#define efi_call_phys0(f) \ + efi_call0((void *)(f)) +#define efi_call_phys1(f, a1) \ + efi_call1((void *)(f), (u64)(a1)) +#define efi_call_phys2(f, a1, a2) \ + efi_call2((void *)(f), (u64)(a1), (u64)(a2)) +#define efi_call_phys3(f, a1, a2, a3) \ + efi_call3((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3)) +#define efi_call_phys4(f, a1, a2, a3, a4) \ + efi_call4((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \ + (u64)(a4)) +#define efi_call_phys5(f, a1, a2, a3, a4, a5) \ + efi_call5((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \ + (u64)(a4), (u64)(a5)) +#define efi_call_phys6(f, a1, a2, a3, a4, a5, a6) \ + efi_call6((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \ + (u64)(a4), (u64)(a5), (u64)(a6)) + +#define efi_call_virt0(f) \ + efi_call0((void *)(efi.systab->runtime->f)) +#define efi_call_virt1(f, a1) \ + efi_call1((void *)(efi.systab->runtime->f), (u64)(a1)) +#define efi_call_virt2(f, a1, a2) \ + efi_call2((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2)) +#define efi_call_virt3(f, a1, a2, a3) \ + efi_call3((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + (u64)(a3)) +#define efi_call_virt4(f, a1, a2, a3, a4) \ + efi_call4((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + (u64)(a3), (u64)(a4)) +#define efi_call_virt5(f, a1, a2, a3, a4, a5) \ + efi_call5((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + (u64)(a3), (u64)(a4), (u64)(a5)) +#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ + efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) + +#define efi_early_ioremap(addr, size) early_ioremap(addr, size) +#define efi_early_iounmap(vaddr, size) early_iounmap(vaddr, size) + +extern void *efi_ioremap(unsigned long offset, unsigned long size); + +extern int efi_time; + +#endif /* CONFIG_X86_32 */ + +extern void efi_reserve_bootmem(void); +extern void efi_call_phys_prelog(void); +extern void efi_call_phys_epilog(void); +extern void runtime_code_page_mkexec(void); + +#endif diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h index cdfbe4a6ae6..8f44782e5fe 100644 --- a/include/asm-x86/fixmap_64.h +++ b/include/asm-x86/fixmap_64.h @@ -15,6 +15,7 @@ #include #include #include +#include /* * Here we define all the compile-time 'special' virtual @@ -41,6 +42,8 @@ enum fixed_addresses { FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ FIX_IO_APIC_BASE_0, FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, + FIX_EFI_IO_MAP_LAST_PAGE, + FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE+MAX_EFI_IO_PAGES-1, __end_of_fixed_addresses }; -- cgit v1.2.2 From de18c850af701ac9512b7239e88fa45e4c168771 Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:31:19 +0100 Subject: x86: EFI runtime service support: EFI runtime services This patch adds support for several EFI runtime services for EFI x86_64 system. The EFI support for emergency_restart is added. Signed-off-by: Chandramouli Narayanan Signed-off-by: Huang Ying Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/emergency-restart.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/emergency-restart.h b/include/asm-x86/emergency-restart.h index 680c3956334..54189084462 100644 --- a/include/asm-x86/emergency-restart.h +++ b/include/asm-x86/emergency-restart.h @@ -1,6 +1,15 @@ #ifndef _ASM_EMERGENCY_RESTART_H #define _ASM_EMERGENCY_RESTART_H +enum reboot_type { + BOOT_TRIPLE = 't', + BOOT_KBD = 'k', + BOOT_ACPI = 'a', + BOOT_EFI = 'e' +}; + +extern enum reboot_type reboot_type; + extern void machine_emergency_restart(void); #endif /* _ASM_EMERGENCY_RESTART_H */ -- cgit v1.2.2 From e429795c68d3001ecae74f6465420c9f043b0ece Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:31:19 +0100 Subject: x86: EFI runtime service support: remove duplicated code from efi_32.c This patch removes the duplicated code between efi_32.c and efi.c. Signed-off-by: Huang Ying Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/efi.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h index 1459d3d5865..6d54502755a 100644 --- a/include/asm-x86/efi.h +++ b/include/asm-x86/efi.h @@ -2,6 +2,48 @@ #define _ASM_X86_EFI_H #ifdef CONFIG_X86_32 + +extern unsigned long asmlinkage efi_call_phys(void *, ...); + +#define efi_call_phys0(f) efi_call_phys(f) +#define efi_call_phys1(f, a1) efi_call_phys(f, a1) +#define efi_call_phys2(f, a1, a2) efi_call_phys(f, a1, a2) +#define efi_call_phys3(f, a1, a2, a3) efi_call_phys(f, a1, a2, a3) +#define efi_call_phys4(f, a1, a2, a3, a4) \ + efi_call_phys(f, a1, a2, a3, a4) +#define efi_call_phys5(f, a1, a2, a3, a4, a5) \ + efi_call_phys(f, a1, a2, a3, a4, a5) +#define efi_call_phys6(f, a1, a2, a3, a4, a5, a6) \ + efi_call_phys(f, a1, a2, a3, a4, a5, a6) +/* + * Wrap all the virtual calls in a way that forces the parameters on the stack. + */ + +#define efi_call_virt(f, args...) \ + ((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args) + +#define efi_call_virt0(f) efi_call_virt(f) +#define efi_call_virt1(f, a1) efi_call_virt(f, a1) +#define efi_call_virt2(f, a1, a2) efi_call_virt(f, a1, a2) +#define efi_call_virt3(f, a1, a2, a3) efi_call_virt(f, a1, a2, a3) +#define efi_call_virt4(f, a1, a2, a3, a4) \ + efi_call_virt(f, a1, a2, a3, a4) +#define efi_call_virt5(f, a1, a2, a3, a4, a5) \ + efi_call_virt(f, a1, a2, a3, a4, a5) +#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ + efi_call_virt(f, a1, a2, a3, a4, a5, a6) +/* + * We require an early boot_ioremap mapping mechanism initially + */ +extern void *boot_ioremap(unsigned long, unsigned long); + +#define efi_early_ioremap(addr, size) boot_ioremap(addr, size) +#define efi_early_iounmap(vaddr, size) + +#define efi_ioremap(addr, size) ioremap(addr, size) + +#define end_pfn_map max_low_pfn + #else /* !CONFIG_X86_32 */ #define MAX_EFI_IO_PAGES 100 -- cgit v1.2.2 From 2215e69d2cf5024647f9a034807990590d25dd4e Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:31:19 +0100 Subject: x86 boot: use E820 memory map on EFI 32 platform Because the EFI memory map are converted to e820 memory map in bootloader, the EFI memory map handling code is removed to clean up. Signed-off-by: Huang Ying Cc: Andi Kleen Cc: "H. Peter Anvin" Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/e820_32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h index ae5ea19623f..e2faf5f3a0b 100644 --- a/include/asm-x86/e820_32.h +++ b/include/asm-x86/e820_32.h @@ -28,7 +28,7 @@ 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 legacy_init_iomem_resources(struct resource *code_resource, +extern void init_iomem_resources(struct resource *code_resource, struct resource *data_resource, struct resource *bss_resource); -- cgit v1.2.2 From f6e0eba1b133192e298052d616e9e17356d32517 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:20 +0100 Subject: x86: avoid ifdefs in desc.h, getting rid of pack_ldt and pack_tss By Andi Kleen's suggestion, this patch removes pack_ldt() and pack_tss() wrappers in favour of a general wrapper. It saves us an ifdef and some lines of code, but more importantly, it's more elegant. No functional change is made, although the object code is expected to be different. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 58 ++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 40 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index c31715cf221..e9356a85202 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -125,21 +125,6 @@ static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, memcpy(&gdt[entry], desc, size); } -static inline void set_tssldt_descriptor(struct ldttss_desc64 *d, - unsigned long tss, unsigned type, - unsigned size) -{ - memset(d, 0, sizeof(*d)); - d->limit0 = size & 0xFFFF; - d->base0 = PTR_LOW(tss); - d->base1 = PTR_MIDDLE(tss) & 0xFF; - d->type = type; - d->p = 1; - d->limit1 = (size >> 16) & 0xF; - d->base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; - d->base3 = PTR_HIGH(tss); -} - static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, unsigned long limit, unsigned char type, unsigned char flags) @@ -151,30 +136,24 @@ static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, desc->p = 1; } -static inline void pack_ldt(ldt_desc *ldt, unsigned long addr, - unsigned size) -{ -#ifdef CONFIG_X86_64 - set_tssldt_descriptor(ldt, - addr, DESC_LDT, size); -#else - pack_descriptor(ldt, (unsigned long)addr, - size, - 0x80 | DESC_LDT, 0); -#endif -} - -static inline void pack_tss(tss_desc *tss, unsigned long addr, - unsigned size, unsigned entry) +static inline void set_tssldt_descriptor(void *d, unsigned long addr, + unsigned type, unsigned size) { #ifdef CONFIG_X86_64 - set_tssldt_descriptor(tss, - addr, entry, size); + struct ldttss_desc64 *desc = d; + memset(desc, 0, sizeof(*desc)); + desc->limit0 = size & 0xFFFF; + desc->base0 = PTR_LOW(addr); + desc->base1 = PTR_MIDDLE(addr) & 0xFF; + desc->type = type; + desc->p = 1; + desc->limit1 = (size >> 16) & 0xF; + desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; + desc->base3 = PTR_HIGH(addr); #else - pack_descriptor(tss, (unsigned long)addr, - size, - 0x80 | entry, 0); + + pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); #endif } @@ -190,9 +169,8 @@ static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr) * -1? seg base+limit should be pointing to the address of the * last valid byte */ - pack_tss(&tss, (unsigned long)addr, - IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1, - DESC_TSS); + set_tssldt_descriptor(&tss, (unsigned long)addr, DESC_TSS, + IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); write_gdt_entry(d, entry, &tss, DESC_TSS); } @@ -206,8 +184,8 @@ static inline void native_set_ldt(const void *addr, unsigned int entries) unsigned cpu = smp_processor_id(); ldt_desc ldt; - pack_ldt(&ldt, (unsigned long)addr, - entries * sizeof(ldt) - 1); + set_tssldt_descriptor(&ldt, (unsigned long)addr, + DESC_LDT, entries * sizeof(ldt) - 1); write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, &ldt, DESC_LDT); __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); -- cgit v1.2.2 From 3c68904fee1459b6d51040864e15d19098eedef7 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:31:20 +0100 Subject: x86, ptrace: use jiffies for BTS timestamps Replace sched_clock() with jiffies for BTS timestamps. Signed-off-by: Markus Metzger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ds.h b/include/asm-x86/ds.h index edd8467740a..c9e15381dc7 100644 --- a/include/asm-x86/ds.h +++ b/include/asm-x86/ds.h @@ -48,7 +48,7 @@ struct bts_struct { } lbr; /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */ - unsigned long long timestamp; + unsigned long jiffies; } variant; }; -- cgit v1.2.2 From e4811f2568c55e595a7bf15a3b9aba863b31fb94 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:31:20 +0100 Subject: x86, ptrace: change BTS GET ptrace interface Change the ptrace interface to mimick an array from newst to oldest. Signed-off-by: Markus Metzger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace-abi.h | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 6fadc5214e1..b473ad45e9c 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -99,32 +99,27 @@ ENXIO........no buffer allocated */ #define PTRACE_BTS_GET_BUFFER_SIZE 42 -/* Return the index of the next bts record to be written, - if successful; -1, otherwise. - EOPNOTSUPP...processor does not support bts tracing - ENXIO........no buffer allocated - After the first warp-around, this is the start of the circular bts buffer. */ -#define PTRACE_BTS_GET_INDEX 43 - -/* Read the DATA'th bts record into a ptrace_bts_record buffer provided in ADDR. +/* Read the DATA'th bts record into a ptrace_bts_record buffer + provided in ADDR. + Records are ordered from newest to oldest. Return 0, if successful; -1, otherwise EOPNOTSUPP...processor does not support bts tracing ENXIO........no buffer allocated EINVAL.......invalid index */ -#define PTRACE_BTS_READ_RECORD 44 +#define PTRACE_BTS_READ_RECORD 43 /* Configure last branch trace; the configuration is given as a bit-mask of PTRACE_BTS_O_* options in DATA; parameter ADDR is ignored. Return 0, if successful; -1, otherwise EOPNOTSUPP...processor does not support bts tracing ENXIO........no buffer allocated */ -#define PTRACE_BTS_CONFIG 45 +#define PTRACE_BTS_CONFIG 44 /* Return the configuration as bit-mask of PTRACE_BTS_O_* options if successful; -1, otherwise. EOPNOTSUPP...processor does not support bts tracing ENXIO........no buffer allocated */ -#define PTRACE_BTS_STATUS 46 +#define PTRACE_BTS_STATUS 45 /* Trace configuration options */ /* Collect last branch trace */ -- cgit v1.2.2 From a95d67f87e1a5f1b4429be3ba3bf7b4051657908 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:31:20 +0100 Subject: x86, ptrace: new ptrace BTS API Here's the new ptrace BTS API that supports two different overflow handling mechanisms (wrap-around and buffer-full-signal) to support two different use cases (debugging and profiling). It further combines buffer allocation and configuration. Opens: - memory rlimit - overflow signal What would be the right signal to use? Signed-off-by: Markus Metzger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ds.h | 7 ++++ include/asm-x86/ptrace-abi.h | 94 ++++++++++++++++++++++---------------------- include/asm-x86/ptrace.h | 1 + 3 files changed, 56 insertions(+), 46 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ds.h b/include/asm-x86/ds.h index c9e15381dc7..b84040abee6 100644 --- a/include/asm-x86/ds.h +++ b/include/asm-x86/ds.h @@ -52,11 +52,18 @@ struct bts_struct { } variant; }; +/* Overflow handling mechanisms */ +#define DS_O_SIGNAL 1 /* send overflow signal */ +#define DS_O_WRAP 2 /* wrap around */ extern int ds_allocate(void **, size_t); extern int ds_free(void **); extern int ds_get_bts_size(void *); +extern int ds_get_bts_end(void *); extern int ds_get_bts_index(void *); +extern int ds_set_overflow(void *, int); +extern int ds_get_overflow(void *); +extern int ds_clear(void *); extern int ds_read_bts(void *, size_t, struct bts_struct *); extern int ds_write_bts(void *, const struct bts_struct *); extern unsigned long ds_debugctl_mask(void); diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index b473ad45e9c..cf2fe4633ee 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -80,51 +80,53 @@ #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ -/* Return maximal BTS buffer size in number of records, - if successuf; -1, otherwise. - EOPNOTSUPP...processor does not support bts tracing */ -#define PTRACE_BTS_MAX_BUFFER_SIZE 40 - -/* Allocate new bts buffer (free old one, if exists) of size DATA bts records; - parameter ADDR is ignored. - Return 0, if successful; -1, otherwise. - EOPNOTSUPP...processor does not support bts tracing - EINVAL.......invalid size in records - ENOMEM.......out of memory */ -#define PTRACE_BTS_ALLOCATE_BUFFER 41 - -/* Return the size of the bts buffer in number of bts records, - if successful; -1, otherwise. - EOPNOTSUPP...processor does not support bts tracing - ENXIO........no buffer allocated */ -#define PTRACE_BTS_GET_BUFFER_SIZE 42 - -/* Read the DATA'th bts record into a ptrace_bts_record buffer - provided in ADDR. - Records are ordered from newest to oldest. - Return 0, if successful; -1, otherwise - EOPNOTSUPP...processor does not support bts tracing - ENXIO........no buffer allocated - EINVAL.......invalid index */ -#define PTRACE_BTS_READ_RECORD 43 - -/* Configure last branch trace; the configuration is given as a bit-mask of - PTRACE_BTS_O_* options in DATA; parameter ADDR is ignored. - Return 0, if successful; -1, otherwise - EOPNOTSUPP...processor does not support bts tracing - ENXIO........no buffer allocated */ -#define PTRACE_BTS_CONFIG 44 - -/* Return the configuration as bit-mask of PTRACE_BTS_O_* options - if successful; -1, otherwise. - EOPNOTSUPP...processor does not support bts tracing - ENXIO........no buffer allocated */ -#define PTRACE_BTS_STATUS 45 - -/* Trace configuration options */ -/* Collect last branch trace */ -#define PTRACE_BTS_O_TRACE_TASK 0x1 -/* Take timestamps when the task arrives and departs */ -#define PTRACE_BTS_O_TIMESTAMPS 0x2 +/* configuration/status structure used in PTRACE_BTS_CONFIG and + PTRACE_BTS_STATUS commands. +*/ +struct ptrace_bts_config { + /* requested or actual size of BTS buffer in bytes */ + unsigned long size; + /* bitmask of below flags */ + unsigned long flags; +}; + +#define PTRACE_BTS_O_TRACE 0x1 /* branch trace */ +#define PTRACE_BTS_O_SCHED 0x2 /* scheduling events w/ jiffies */ +#define PTRACE_BTS_O_SIGNAL 0x4 /* send SIG? on buffer overflow + instead of wrapping around */ +#define PTRACE_BTS_O_CUT_SIZE 0x8 /* cut requested size to max available + instead of failing */ + +#define PTRACE_BTS_CONFIG 40 +/* Configure branch trace recording. + DATA is ignored, ADDR points to a struct ptrace_bts_config. + A new buffer is allocated, iff the size changes. +*/ +#define PTRACE_BTS_STATUS 41 +/* Return the current configuration. + DATA is ignored, ADDR points to a struct ptrace_bts_config + that will contain the result. +*/ +#define PTRACE_BTS_SIZE 42 +/* Return the number of available BTS records. + DATA and ADDR are ignored. +*/ +#define PTRACE_BTS_GET 43 +/* Get a single BTS record. + DATA defines the index into the BTS array, where 0 is the newest + entry, and higher indices refer to older entries. + ADDR is pointing to struct bts_struct (see asm/ds.h). +*/ +#define PTRACE_BTS_CLEAR 44 +/* Clear the BTS buffer. + DATA and ADDR are ignored. +*/ +#define PTRACE_BTS_DRAIN 45 +/* Read all available BTS records and clear the buffer. + DATA is ignored. ADDR points to an array of struct bts_struct of + suitable size. + BTS records are read from oldest to newest. + Returns number of BTS records drained. +*/ #endif diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index a9a1bab1451..61946fe8c08 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -9,6 +9,7 @@ #ifdef __KERNEL__ +/* the DS BTS struct is used for ptrace as well */ #include struct task_struct; -- cgit v1.2.2 From 314cdbefd1fd0a7acf3780e9628465b77ea6a836 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 30 Jan 2008 13:31:21 +0100 Subject: x86: FIFO ticket spinlocks Introduce ticket lock spinlocks for x86 which are FIFO. The implementation is described in the comments. The straight-line lock/unlock instruction sequence is slightly slower than the dec based locks on modern x86 CPUs, however the difference is quite small on Core2 and Opteron when working out of cache, and becomes almost insignificant even on P4 when the lock misses cache. trylock is more significantly slower, but they are relatively rare. On an 8 core (2 socket) Opteron, spinlock unfairness is extremely noticable, with a userspace test having a difference of up to 2x runtime per thread, and some threads are starved or "unfairly" granted the lock up to 1 000 000 (!) times. After this patch, all threads appear to finish at exactly the same time. The memory ordering of the lock does conform to x86 standards, and the implementation has been reviewed by Intel and AMD engineers. The algorithm also tells us how many CPUs are contending the lock, so lockbreak becomes trivial and we no longer have to waste 4 bytes per spinlock for it. After this, we can no longer spin on any locks with preempt enabled and cannot reenable interrupts when spinning on an irq safe lock, because at that point we have already taken a ticket and the would deadlock if the same CPU tries to take the lock again. These are questionable anyway: if the lock happens to be called under a preempt or interrupt disabled section, then it will just have the same latency problems. The real fix is to keep critical sections short, and ensure locks are reasonably fair (which this patch does). Signed-off-by: Nick Piggin Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/paravirt.h | 21 ------ include/asm-x86/spinlock.h | 153 +++++++++++++++++++++------------------ include/asm-x86/spinlock_types.h | 2 +- 3 files changed, 82 insertions(+), 94 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 4f23f434a1f..24406703007 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1077,27 +1077,6 @@ static inline unsigned long __raw_local_irq_save(void) return f; } -#define CLI_STRING \ - _paravirt_alt("pushl %%ecx; pushl %%edx;" \ - "call *%[paravirt_cli_opptr];" \ - "popl %%edx; popl %%ecx", \ - "%c[paravirt_cli_type]", "%c[paravirt_clobber]") - -#define STI_STRING \ - _paravirt_alt("pushl %%ecx; pushl %%edx;" \ - "call *%[paravirt_sti_opptr];" \ - "popl %%edx; popl %%ecx", \ - "%c[paravirt_sti_type]", "%c[paravirt_clobber]") - -#define CLI_STI_CLOBBERS , "%eax" -#define CLI_STI_INPUT_ARGS \ - , \ - [paravirt_cli_type] "i" (PARAVIRT_PATCH(pv_irq_ops.irq_disable)), \ - [paravirt_cli_opptr] "m" (pv_irq_ops.irq_disable), \ - [paravirt_sti_type] "i" (PARAVIRT_PATCH(pv_irq_ops.irq_enable)), \ - [paravirt_sti_opptr] "m" (pv_irq_ops.irq_enable), \ - paravirt_clobber(CLBR_EAX) - /* Make sure as little as possible of this mess escapes. */ #undef PARAVIRT_CALL #undef __PVOP_CALL diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h index afd4b80ff0a..97d52b506af 100644 --- a/include/asm-x86/spinlock.h +++ b/include/asm-x86/spinlock.h @@ -5,6 +5,7 @@ #include #include #include +#include /* * Your basic SMP spinlocks, allowing only a single CPU anywhere @@ -12,7 +13,8 @@ * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. * - * We make no fairness assumptions. They have a cost. + * These are fair FIFO ticket locks, which are currently limited to 256 + * CPUs. * * (the type definitions are in asm/spinlock_types.h) */ @@ -42,103 +44,102 @@ typedef int _slock_t; # define LOCK_PTR_REG "D" #endif +#if (NR_CPUS > 256) +#error spinlock supports a maximum of 256 CPUs +#endif + static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { - return *(volatile _slock_t *)(&(lock)->slock) <= 0; + int tmp = *(volatile signed int *)(&(lock)->slock); + + return (((tmp >> 8) & 0xff) != (tmp & 0xff)); } -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline int __raw_spin_is_contended(raw_spinlock_t *lock) { - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; " LOCK_INS_DEC " %0\n\t" - "jns 3f\n" - "2:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0,%0\n\t" - "jle 2b\n\t" - "jmp 1b\n" - "3:\n\t" - : "+m" (lock->slock) : : "memory"); + int tmp = *(volatile signed int *)(&(lock)->slock); + + return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1; } -/* - * It is easier for the lock validator if interrupts are not re-enabled - * in the middle of a lock-acquire. This is a performance feature anyway - * so we turn it off: - * - * NOTE: there's an irqs-on section here, which normally would have to be - * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. - */ -#ifndef CONFIG_PROVE_LOCKING -static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, - unsigned long flags) +static inline void __raw_spin_lock(raw_spinlock_t *lock) { - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; " LOCK_INS_DEC " %[slock]\n\t" - "jns 5f\n" - "testl $0x200, %[flags]\n\t" - "jz 4f\n\t" - STI_STRING "\n" - "3:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0, %[slock]\n\t" - "jle 3b\n\t" - CLI_STRING "\n\t" + short inc = 0x0100; + + /* + * Ticket locks are conceptually two bytes, one indicating the current + * head of the queue, and the other indicating the current tail. The + * lock is acquired by atomically noting the tail and incrementing it + * by one (thus adding ourself to the queue and noting our position), + * then waiting until the head becomes equal to the the initial value + * of the tail. + * + * This uses a 16-bit xadd to increment the tail and also load the + * position of the head, which takes care of memory ordering issues + * and should be optimal for the uncontended case. Note the tail must + * be in the high byte, otherwise the 16-bit wide increment of the low + * byte would carry up and contaminate the high byte. + */ + + __asm__ __volatile__ ( + LOCK_PREFIX "xaddw %w0, %1\n" + "1:\t" + "cmpb %h0, %b0\n\t" + "je 2f\n\t" + "rep ; nop\n\t" + "movb %1, %b0\n\t" + /* don't need lfence here, because loads are in-order */ "jmp 1b\n" - "4:\t" - "rep;nop\n\t" - LOCK_INS_CMP " $0, %[slock]\n\t" - "jg 1b\n\t" - "jmp 4b\n" - "5:\n\t" - : [slock] "+m" (lock->slock) - : [flags] "r" ((u32)flags) - CLI_STI_INPUT_ARGS - : "memory" CLI_STI_CLOBBERS); + "2:" + :"+Q" (inc), "+m" (lock->slock) + : + :"memory", "cc"); } -#endif + +#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) static inline int __raw_spin_trylock(raw_spinlock_t *lock) { - _slock_t oldval; + int tmp; + short new; asm volatile( - LOCK_INS_XCH " %0,%1" - :"=q" (oldval), "+m" (lock->slock) - :"0" (0) : "memory"); - - return oldval > 0; + "movw %2,%w0\n\t" + "cmpb %h0,%b0\n\t" + "jne 1f\n\t" + "movw %w0,%w1\n\t" + "incb %h1\n\t" + "lock ; cmpxchgw %w1,%2\n\t" + "1:" + "sete %b1\n\t" + "movzbl %b1,%0\n\t" + :"=&a" (tmp), "=Q" (new), "+m" (lock->slock) + : + : "memory", "cc"); + + return tmp; } +#if defined(CONFIG_X86_32) && \ + (defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)) /* - * __raw_spin_unlock based on writing $1 to the low byte. - * This method works. Despite all the confusion. - * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there) + * On PPro SMP or if we are using OOSTORE, we use a locked operation to unlock * (PPro errata 66, 92) */ -#if defined(X86_64) || \ - (!defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)) - -static inline void __raw_spin_unlock(raw_spinlock_t *lock) -{ - asm volatile(LOCK_INS_MOV " $1,%0" : "=m" (lock->slock) :: "memory"); -} - +# define UNLOCK_LOCK_PREFIX LOCK_PREFIX #else +# define UNLOCK_LOCK_PREFIX +#endif static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - unsigned char oldval = 1; - - asm volatile("xchgb %b0, %1" - : "=q" (oldval), "+m" (lock->slock) - : "0" (oldval) : "memory"); + __asm__ __volatile__( + UNLOCK_LOCK_PREFIX "incb %0" + :"+m" (lock->slock) + : + :"memory", "cc"); } -#endif - static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) { while (__raw_spin_is_locked(lock)) @@ -159,11 +160,19 @@ static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) * with the high bit (sign) being the "contended" bit. */ +/** + * read_can_lock - would read_trylock() succeed? + * @lock: the rwlock in question. + */ static inline int __raw_read_can_lock(raw_rwlock_t *lock) { return (int)(lock)->lock > 0; } +/** + * write_can_lock - would write_trylock() succeed? + * @lock: the rwlock in question. + */ static inline int __raw_write_can_lock(raw_rwlock_t *lock) { return (lock)->lock == RW_LOCK_BIAS; diff --git a/include/asm-x86/spinlock_types.h b/include/asm-x86/spinlock_types.h index 4da9345c150..9029cf78cf5 100644 --- a/include/asm-x86/spinlock_types.h +++ b/include/asm-x86/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { unsigned int slock; } raw_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 1 } +#define __RAW_SPIN_LOCK_UNLOCKED { 0 } typedef struct { unsigned int lock; -- cgit v1.2.2 From aa470140e86e45723cf8387292edbce9106ddc1f Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 30 Jan 2008 13:31:21 +0100 Subject: x86: kprobe-booster for x86-64 This patch adds kprobe-booster to kprobes_64.c. - Changes are based on x86-32. - Add REX prefix checking code. Signed-off-by: Masami Hiramatsu Signed-off-by: Jim Keniston Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/kprobes_64.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h index 8c919d35cdd..e7e921dac7c 100644 --- a/include/asm-x86/kprobes_64.h +++ b/include/asm-x86/kprobes_64.h @@ -34,6 +34,7 @@ struct kprobe; typedef u8 kprobe_opcode_t; #define BREAKPOINT_INSTRUCTION 0xcc +#define RELATIVEJUMP_INSTRUCTION 0xe9 #define MAX_INSN_SIZE 15 #define MAX_STACK_SIZE 64 #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ @@ -52,6 +53,15 @@ extern void arch_remove_kprobe(struct kprobe *p); struct arch_specific_insn { /* copy of the original instruction */ kprobe_opcode_t *insn; + /* + * boostable = -1: This instruction type is not boostable. + * boostable = 0: This instruction type is boostable. + * boostable = 1: This instruction has been boosted: we have + * added a relative jump after the instruction copy in insn, + * so no single-step and fixup are needed (unless there's + * a post_handler or break_handler). + */ + int boostable; }; struct prev_kprobe { -- cgit v1.2.2 From 8533bbe9f87b01f49ff951f665ea1988252fa3c2 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 30 Jan 2008 13:31:21 +0100 Subject: x86: prepare kprobes code for x86 unification This patch cleanup kprobes code on x86 for unification. This patch is based on Arjan's previous work. - Remove spurious whitespace changes - Add harmless includes - Make the 32/64 files more identical - Generalize structure fields' and local variable name. - Wrap accessing to stack address by macros. - Modify bitmap making macro. - Merge fixup code into is_riprel() and change its name to fix_riprel(). - Set MAX_INSN_SIZE to 16 on both arch. - Use u32 for bitmaps on both architectures. - Clarify some comments. Signed-off-by: Masami Hiramatsu Signed-off-by: Arjan van de Ven Signed-off-by: Jim Keniston Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/kprobes_32.h | 32 ++++++++++++++++++++------------ include/asm-x86/kprobes_64.h | 30 ++++++++++++++++-------------- 2 files changed, 36 insertions(+), 26 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h index 2f38315bc39..94dff09b2eb 100644 --- a/include/asm-x86/kprobes_32.h +++ b/include/asm-x86/kprobes_32.h @@ -2,7 +2,6 @@ #define _ASM_KPROBES_H /* * Kernel Probes (KProbes) - * include/asm-i386/kprobes.h * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,14 +22,17 @@ * 2002-Oct Created by Vamsi Krishna S Kernel * Probes initial implementation ( includes suggestions from * Rusty Russell). + * 2004-Oct Prasanna S Panchamukhi and Jim Keniston + * kenistoj@us.ibm.com adopted from i386. */ #include #include +#include #define __ARCH_WANT_KPROBES_INSN_SLOT -struct kprobe; struct pt_regs; +struct kprobe; typedef u8 kprobe_opcode_t; #define BREAKPOINT_INSTRUCTION 0xcc @@ -38,9 +40,11 @@ typedef u8 kprobe_opcode_t; #define MAX_INSN_SIZE 16 #define MAX_STACK_SIZE 64 #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ - (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) \ + (((unsigned long)current_thread_info()) + THREAD_SIZE \ + - (unsigned long)(ADDR))) \ ? (MAX_STACK_SIZE) \ - : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) + : (((unsigned long)current_thread_info()) + THREAD_SIZE \ + - (unsigned long)(ADDR))) #define ARCH_SUPPORTS_KRETPROBES #define flush_insn_slot(p) do { } while (0) @@ -55,8 +59,12 @@ struct arch_specific_insn { /* copy of the original instruction */ kprobe_opcode_t *insn; /* - * If this flag is not 0, this kprobe can be boost when its - * post_handler and break_handler is not set. + * boostable = -1: This instruction type is not boostable. + * boostable = 0: This instruction type is boostable. + * boostable = 1: This instruction has been boosted: we have + * added a relative jump after the instruction copy in insn, + * so no single-step and fixup are needed (unless there's + * a post_handler or break_handler). */ int boostable; }; @@ -64,16 +72,16 @@ struct arch_specific_insn { struct prev_kprobe { struct kprobe *kp; unsigned long status; - unsigned long old_eflags; - unsigned long saved_eflags; + unsigned long old_flags; + unsigned long saved_flags; }; /* per-cpu kprobe control block */ struct kprobe_ctlblk { unsigned long kprobe_status; - unsigned long kprobe_old_eflags; - unsigned long kprobe_saved_eflags; - unsigned long *jprobe_saved_esp; + unsigned long kprobe_old_flags; + unsigned long kprobe_saved_flags; + unsigned long *jprobe_saved_sp; struct pt_regs jprobe_saved_regs; kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; struct prev_kprobe prev_kprobe; @@ -88,7 +96,7 @@ static inline void restore_interrupts(struct pt_regs *regs) local_irq_enable(); } +extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); -extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); #endif /* _ASM_KPROBES_H */ diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h index e7e921dac7c..94dff09b2eb 100644 --- a/include/asm-x86/kprobes_64.h +++ b/include/asm-x86/kprobes_64.h @@ -2,7 +2,6 @@ #define _ASM_KPROBES_H /* * Kernel Probes (KProbes) - * include/asm-x86_64/kprobes.h * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +19,9 @@ * * Copyright (C) IBM Corporation, 2002, 2004 * + * 2002-Oct Created by Vamsi Krishna S Kernel + * Probes initial implementation ( includes suggestions from + * Rusty Russell). * 2004-Oct Prasanna S Panchamukhi and Jim Keniston * kenistoj@us.ibm.com adopted from i386. */ @@ -35,19 +37,22 @@ struct kprobe; typedef u8 kprobe_opcode_t; #define BREAKPOINT_INSTRUCTION 0xcc #define RELATIVEJUMP_INSTRUCTION 0xe9 -#define MAX_INSN_SIZE 15 +#define MAX_INSN_SIZE 16 #define MAX_STACK_SIZE 64 #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ - (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) \ + (((unsigned long)current_thread_info()) + THREAD_SIZE \ + - (unsigned long)(ADDR))) \ ? (MAX_STACK_SIZE) \ - : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) + : (((unsigned long)current_thread_info()) + THREAD_SIZE \ + - (unsigned long)(ADDR))) #define ARCH_SUPPORTS_KRETPROBES +#define flush_insn_slot(p) do { } while (0) + extern const int kretprobe_blacklist_size; +void arch_remove_kprobe(struct kprobe *p); void kretprobe_trampoline(void); -extern void arch_remove_kprobe(struct kprobe *p); -#define flush_insn_slot(p) do { } while (0) /* Architecture specific copy of original instruction*/ struct arch_specific_insn { @@ -67,16 +72,16 @@ struct arch_specific_insn { struct prev_kprobe { struct kprobe *kp; unsigned long status; - unsigned long old_rflags; - unsigned long saved_rflags; + unsigned long old_flags; + unsigned long saved_flags; }; /* per-cpu kprobe control block */ struct kprobe_ctlblk { unsigned long kprobe_status; - unsigned long kprobe_old_rflags; - unsigned long kprobe_saved_rflags; - unsigned long *jprobe_saved_rsp; + unsigned long kprobe_old_flags; + unsigned long kprobe_saved_flags; + unsigned long *jprobe_saved_sp; struct pt_regs jprobe_saved_regs; kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; struct prev_kprobe prev_kprobe; @@ -91,10 +96,7 @@ static inline void restore_interrupts(struct pt_regs *regs) local_irq_enable(); } -extern int post_kprobe_handler(struct pt_regs *regs); extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); -extern int kprobe_handler(struct pt_regs *regs); - extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); #endif /* _ASM_KPROBES_H */ -- cgit v1.2.2 From d6be29b871e285d33be0e3025929e2d6bcabb0c0 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 30 Jan 2008 13:31:21 +0100 Subject: x86: kprobes code for x86 unification This patch unifies kprobes code. - Unify kprobes_*.h to kprobes.h - Unify kprobes_*.c to kprobes.c (Differences are separated by ifdefs) - Most differences are related to REX prefix and rip relatives. - Two inline assembly code are different. - One difference in kprobe_handlre() - One fixup exception code is different, but it will be unified if mm/extable_*.c are unified. - Merge history logs into arch/x86/kernel/kprobes.c. Signed-off-by: Masami Hiramatsu Signed-off-by: Jim Keniston Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/kprobes.h | 103 ++++++++++++++++++++++++++++++++++++++++--- include/asm-x86/kprobes_32.h | 102 ------------------------------------------ include/asm-x86/kprobes_64.h | 102 ------------------------------------------ 3 files changed, 98 insertions(+), 209 deletions(-) delete mode 100644 include/asm-x86/kprobes_32.h delete mode 100644 include/asm-x86/kprobes_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h index b7bbd25ba2a..6e6371a856e 100644 --- a/include/asm-x86/kprobes.h +++ b/include/asm-x86/kprobes.h @@ -1,5 +1,98 @@ -#ifdef CONFIG_X86_32 -# include "kprobes_32.h" -#else -# include "kprobes_64.h" -#endif +#ifndef _ASM_KPROBES_H +#define _ASM_KPROBES_H +/* + * Kernel Probes (KProbes) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2002, 2004 + * + * See arch/x86/kernel/kprobes.c for x86 kprobes history. + */ +#include +#include +#include + +#define __ARCH_WANT_KPROBES_INSN_SLOT + +struct pt_regs; +struct kprobe; + +typedef u8 kprobe_opcode_t; +#define BREAKPOINT_INSTRUCTION 0xcc +#define RELATIVEJUMP_INSTRUCTION 0xe9 +#define MAX_INSN_SIZE 16 +#define MAX_STACK_SIZE 64 +#define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ + (((unsigned long)current_thread_info()) + THREAD_SIZE \ + - (unsigned long)(ADDR))) \ + ? (MAX_STACK_SIZE) \ + : (((unsigned long)current_thread_info()) + THREAD_SIZE \ + - (unsigned long)(ADDR))) + +#define ARCH_SUPPORTS_KRETPROBES +#define flush_insn_slot(p) do { } while (0) + +extern const int kretprobe_blacklist_size; + +void arch_remove_kprobe(struct kprobe *p); +void kretprobe_trampoline(void); + +/* Architecture specific copy of original instruction*/ +struct arch_specific_insn { + /* copy of the original instruction */ + kprobe_opcode_t *insn; + /* + * boostable = -1: This instruction type is not boostable. + * boostable = 0: This instruction type is boostable. + * boostable = 1: This instruction has been boosted: we have + * added a relative jump after the instruction copy in insn, + * so no single-step and fixup are needed (unless there's + * a post_handler or break_handler). + */ + int boostable; +}; + +struct prev_kprobe { + struct kprobe *kp; + unsigned long status; + unsigned long old_flags; + unsigned long saved_flags; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned long kprobe_status; + unsigned long kprobe_old_flags; + unsigned long kprobe_saved_flags; + unsigned long *jprobe_saved_sp; + struct pt_regs jprobe_saved_regs; + kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; + struct prev_kprobe prev_kprobe; +}; + +/* trap3/1 are intr gates for kprobes. So, restore the status of IF, + * if necessary, before executing the original int3/1 (trap) handler. + */ +static inline void restore_interrupts(struct pt_regs *regs) +{ + if (regs->flags & IF_MASK) + local_irq_enable(); +} + +extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); +extern int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); +#endif /* _ASM_KPROBES_H */ diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h deleted file mode 100644 index 94dff09b2eb..00000000000 --- a/include/asm-x86/kprobes_32.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef _ASM_KPROBES_H -#define _ASM_KPROBES_H -/* - * Kernel Probes (KProbes) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) IBM Corporation, 2002, 2004 - * - * 2002-Oct Created by Vamsi Krishna S Kernel - * Probes initial implementation ( includes suggestions from - * Rusty Russell). - * 2004-Oct Prasanna S Panchamukhi and Jim Keniston - * kenistoj@us.ibm.com adopted from i386. - */ -#include -#include -#include - -#define __ARCH_WANT_KPROBES_INSN_SLOT - -struct pt_regs; -struct kprobe; - -typedef u8 kprobe_opcode_t; -#define BREAKPOINT_INSTRUCTION 0xcc -#define RELATIVEJUMP_INSTRUCTION 0xe9 -#define MAX_INSN_SIZE 16 -#define MAX_STACK_SIZE 64 -#define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ - (((unsigned long)current_thread_info()) + THREAD_SIZE \ - - (unsigned long)(ADDR))) \ - ? (MAX_STACK_SIZE) \ - : (((unsigned long)current_thread_info()) + THREAD_SIZE \ - - (unsigned long)(ADDR))) - -#define ARCH_SUPPORTS_KRETPROBES -#define flush_insn_slot(p) do { } while (0) - -extern const int kretprobe_blacklist_size; - -void arch_remove_kprobe(struct kprobe *p); -void kretprobe_trampoline(void); - -/* Architecture specific copy of original instruction*/ -struct arch_specific_insn { - /* copy of the original instruction */ - kprobe_opcode_t *insn; - /* - * boostable = -1: This instruction type is not boostable. - * boostable = 0: This instruction type is boostable. - * boostable = 1: This instruction has been boosted: we have - * added a relative jump after the instruction copy in insn, - * so no single-step and fixup are needed (unless there's - * a post_handler or break_handler). - */ - int boostable; -}; - -struct prev_kprobe { - struct kprobe *kp; - unsigned long status; - unsigned long old_flags; - unsigned long saved_flags; -}; - -/* per-cpu kprobe control block */ -struct kprobe_ctlblk { - unsigned long kprobe_status; - unsigned long kprobe_old_flags; - unsigned long kprobe_saved_flags; - unsigned long *jprobe_saved_sp; - struct pt_regs jprobe_saved_regs; - kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; - struct prev_kprobe prev_kprobe; -}; - -/* trap3/1 are intr gates for kprobes. So, restore the status of IF, - * if necessary, before executing the original int3/1 (trap) handler. - */ -static inline void restore_interrupts(struct pt_regs *regs) -{ - if (regs->flags & IF_MASK) - local_irq_enable(); -} - -extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); -extern int kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data); -#endif /* _ASM_KPROBES_H */ diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h deleted file mode 100644 index 94dff09b2eb..00000000000 --- a/include/asm-x86/kprobes_64.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef _ASM_KPROBES_H -#define _ASM_KPROBES_H -/* - * Kernel Probes (KProbes) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) IBM Corporation, 2002, 2004 - * - * 2002-Oct Created by Vamsi Krishna S Kernel - * Probes initial implementation ( includes suggestions from - * Rusty Russell). - * 2004-Oct Prasanna S Panchamukhi and Jim Keniston - * kenistoj@us.ibm.com adopted from i386. - */ -#include -#include -#include - -#define __ARCH_WANT_KPROBES_INSN_SLOT - -struct pt_regs; -struct kprobe; - -typedef u8 kprobe_opcode_t; -#define BREAKPOINT_INSTRUCTION 0xcc -#define RELATIVEJUMP_INSTRUCTION 0xe9 -#define MAX_INSN_SIZE 16 -#define MAX_STACK_SIZE 64 -#define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ - (((unsigned long)current_thread_info()) + THREAD_SIZE \ - - (unsigned long)(ADDR))) \ - ? (MAX_STACK_SIZE) \ - : (((unsigned long)current_thread_info()) + THREAD_SIZE \ - - (unsigned long)(ADDR))) - -#define ARCH_SUPPORTS_KRETPROBES -#define flush_insn_slot(p) do { } while (0) - -extern const int kretprobe_blacklist_size; - -void arch_remove_kprobe(struct kprobe *p); -void kretprobe_trampoline(void); - -/* Architecture specific copy of original instruction*/ -struct arch_specific_insn { - /* copy of the original instruction */ - kprobe_opcode_t *insn; - /* - * boostable = -1: This instruction type is not boostable. - * boostable = 0: This instruction type is boostable. - * boostable = 1: This instruction has been boosted: we have - * added a relative jump after the instruction copy in insn, - * so no single-step and fixup are needed (unless there's - * a post_handler or break_handler). - */ - int boostable; -}; - -struct prev_kprobe { - struct kprobe *kp; - unsigned long status; - unsigned long old_flags; - unsigned long saved_flags; -}; - -/* per-cpu kprobe control block */ -struct kprobe_ctlblk { - unsigned long kprobe_status; - unsigned long kprobe_old_flags; - unsigned long kprobe_saved_flags; - unsigned long *jprobe_saved_sp; - struct pt_regs jprobe_saved_regs; - kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; - struct prev_kprobe prev_kprobe; -}; - -/* trap3/1 are intr gates for kprobes. So, restore the status of IF, - * if necessary, before executing the original int3/1 (trap) handler. - */ -static inline void restore_interrupts(struct pt_regs *regs) -{ - if (regs->flags & IF_MASK) - local_irq_enable(); -} - -extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); -extern int kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data); -#endif /* _ASM_KPROBES_H */ -- cgit v1.2.2 From bdb4f156064e5f627213af82292eb8b5cf2dc5aa Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jan 2008 13:31:21 +0100 Subject: i386: hard_{en,dis}able_TSC can be static Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_32.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index e5056ab9dd9..a5560a3b57e 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -206,9 +206,7 @@ extern int bootloader_type; #define HAVE_ARCH_PICK_MMAP_LAYOUT -extern void hard_disable_TSC(void); extern void disable_TSC(void); -extern void hard_enable_TSC(void); /* * Size of io_bitmap. -- cgit v1.2.2 From d88879b2d0225da3ba460bbdb8361bb049653671 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jan 2008 13:31:21 +0100 Subject: x86-64: make pda's cpunumber and nodenumber unsigned This generally allows better code to be generated, since the zero- extension during 32-bit operations comes for free (needed when the result is used as array index or similar), whereas sign extension must be done explicitly and frequently requires a one byte larger instruction due to the necessary rex64 prefix. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pda.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pda.h b/include/asm-x86/pda.h index 3d9dd653628..b620d0c39a9 100644 --- a/include/asm-x86/pda.h +++ b/include/asm-x86/pda.h @@ -15,14 +15,14 @@ struct x8664_pda { unsigned long kernelstack; /* 16 top of kernel stack for current */ unsigned long oldrsp; /* 24 user rsp for system call */ int irqcount; /* 32 Irq nesting counter. Starts with -1 */ - int cpunumber; /* 36 Logical CPU number */ + unsigned int cpunumber; /* 36 Logical CPU number */ #ifdef CONFIG_CC_STACKPROTECTOR unsigned long stack_canary; /* 40 stack canary value */ /* gcc-ABI: this canary MUST be at offset 40!!! */ #endif char *irqstackptr; - int nodenumber; /* number of current node */ + unsigned int nodenumber; /* number of current node */ unsigned int __softirq_pending; unsigned int __nmi_count; /* number of NMI on this CPUs */ short mmu_state; -- cgit v1.2.2 From 22f5991c85dec1281cce5c8df9ee92b43b1738c8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jan 2008 13:31:23 +0100 Subject: x86-64: honor notify_die() returning NOTIFY_STOP This requires making die() return a value, making its callers honor this (and be prepared that it may return), and making oops_end() have two additional parameters. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/kdebug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index 49e5c91d490..a5e5e3b7eb2 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -25,7 +25,7 @@ enum die_val { extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); extern void printk_address(unsigned long address); extern void die(const char *,struct pt_regs *,long); -extern void __die(const char *,struct pt_regs *,long); +extern int __must_check __die(const char *, struct pt_regs *, long); extern void show_registers(struct pt_regs *regs); extern void __show_registers(struct pt_regs *, int all); extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long *); @@ -33,6 +33,6 @@ extern void __show_regs(struct pt_regs *regs); extern void show_regs(struct pt_regs *regs); extern void dump_pagetable(unsigned long); extern unsigned long oops_begin(void); -extern void oops_end(unsigned long); +extern void oops_end(unsigned long, struct pt_regs *, int signr); #endif -- cgit v1.2.2 From 3e7622f9d7807a0a826d042cafc211cd1a29448c Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jan 2008 13:31:23 +0100 Subject: x86: move to .rodata/.init.data The array is never written, and on 64-bits it's not even being used past initial boot. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/hw_irq_32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/hw_irq_32.h b/include/asm-x86/hw_irq_32.h index b93e35a708a..6d65fbb6358 100644 --- a/include/asm-x86/hw_irq_32.h +++ b/include/asm-x86/hw_irq_32.h @@ -26,7 +26,7 @@ * Interrupt entry/exit code at both C and assembly level */ -extern void (*interrupt[NR_IRQS])(void); +extern void (*const interrupt[NR_IRQS])(void); #ifdef CONFIG_SMP void reschedule_interrupt(void); -- cgit v1.2.2 From cae4595764cb3b08f6517e99bac1e3862854b1a1 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jan 2008 13:31:23 +0100 Subject: x86: make __{save,restore}_processor_state static .. allowing to remove their declarations from a global include file (the symbols don't exist for anything but x86). Likewise for 64-bits' fix_processor_context(), just that that one was properly declared in an arch-specific header. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/suspend_64.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/suspend_64.h b/include/asm-x86/suspend_64.h index 4404668f9aa..2eb92cb81a0 100644 --- a/include/asm-x86/suspend_64.h +++ b/include/asm-x86/suspend_64.h @@ -45,8 +45,6 @@ struct saved_context { #define loaddebug(thread,register) \ set_debugreg((thread)->debugreg##register, register) -extern void fix_processor_context(void); - /* routines for saving/restoring kernel state */ extern int acpi_save_state_mem(void); extern char core_restore_code; -- cgit v1.2.2 From e94271017f0933b29362a3c9dea5a6b9d04d98e1 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jan 2008 13:31:24 +0100 Subject: x86: adjust enable_NMI_through_LVT0() Its previous use in a call to on_each_cpu() was pointless, as at the time that code gets executed only one CPU is online. Further, the function can be __cpuinit, and for this to work without CONFIG_HOTPLUG_CPU setup_nmi() must also get an attribute (this one can even be __init; on 64-bits check_timer() also was lacking that attribute). Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/apic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 72bf09cf13a..bcfc07fd366 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -117,7 +117,7 @@ extern void init_apic_mappings(void); extern void setup_boot_APIC_clock(void); extern void setup_secondary_APIC_clock(void); extern int APIC_init_uniprocessor(void); -extern void enable_NMI_through_LVT0(void *dummy); +extern void enable_NMI_through_LVT0(void); /* * On 32bit this is mach-xxx local -- cgit v1.2.2 From ded9aa0db815b4e1271001561e177755cb8b9468 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jan 2008 13:31:24 +0100 Subject: x86: also define AT_VECTOR_SIZE_ARCH The patch introducing this left out x86-64, despite it also having extra entries. [ mingo@elte.hu: re-merged this to after the unification patches. ] Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 8a37dad38bc..6c7d1fda499 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -9,8 +9,14 @@ #include #include +/* entries in ARCH_DLINFO: */ +#ifdef CONFIG_IA32_EMULATION +# define AT_VECTOR_SIZE_ARCH 2 +#else +# define AT_VECTOR_SIZE_ARCH 1 +#endif + #ifdef CONFIG_X86_32 -#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */ struct task_struct; /* one of the stranger aspects of C forward declarations */ extern struct task_struct *FASTCALL(__switch_to(struct task_struct *prev, @@ -56,7 +62,7 @@ extern struct task_struct *FASTCALL(__switch_to(struct task_struct *prev, /* Save restore flags to clear handle leaking NT */ #define switch_to(prev, next, last) \ - asm volatile(SAVE_CONTEXT \ + asm volatile(SAVE_CONTEXT \ "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ "call __switch_to\n\t" \ -- cgit v1.2.2 From fe758fb1192790f8e465a7f59efe47ca73717d3e Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 30 Jan 2008 13:31:25 +0100 Subject: x86: clean up include/asm-x86/pda.h clean up include/asm-x86/pda.h, as suggested by checkpatch.pl. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pda.h | 70 +++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pda.h b/include/asm-x86/pda.h index b620d0c39a9..c0305bff0f1 100644 --- a/include/asm-x86/pda.h +++ b/include/asm-x86/pda.h @@ -7,15 +7,15 @@ #include #include -/* Per processor datastructure. %gs points to it while the kernel runs */ +/* Per processor datastructure. %gs points to it while the kernel runs */ struct x8664_pda { struct task_struct *pcurrent; /* 0 Current process */ unsigned long data_offset; /* 8 Per cpu data offset from linker address */ - unsigned long kernelstack; /* 16 top of kernel stack for current */ - unsigned long oldrsp; /* 24 user rsp for system call */ - int irqcount; /* 32 Irq nesting counter. Starts with -1 */ - unsigned int cpunumber; /* 36 Logical CPU number */ + unsigned long kernelstack; /* 16 top of kernel stack for current */ + unsigned long oldrsp; /* 24 user rsp for system call */ + int irqcount; /* 32 Irq nesting counter. Starts -1 */ + unsigned int cpunumber; /* 36 Logical CPU number */ #ifdef CONFIG_CC_STACKPROTECTOR unsigned long stack_canary; /* 40 stack canary value */ /* gcc-ABI: this canary MUST be at @@ -44,10 +44,10 @@ extern void pda_init(int); #define cpu_pda(i) (_cpu_pda[i]) -/* +/* * There is no fast way to get the base address of the PDA, all the accesses * have to mention %fs/%gs. So it needs to be done this Torvaldian way. - */ + */ extern void __bad_pda_field(void) __attribute__((noreturn)); /* @@ -58,70 +58,70 @@ extern struct x8664_pda _proxy_pda; #define pda_offset(field) offsetof(struct x8664_pda, field) -#define pda_to_op(op,field,val) do { \ +#define pda_to_op(op, field, val) do { \ typedef typeof(_proxy_pda.field) T__; \ if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \ switch (sizeof(_proxy_pda.field)) { \ case 2: \ - asm(op "w %1,%%gs:%c2" : \ + asm(op "w %1,%%gs:%c2" : \ "+m" (_proxy_pda.field) : \ "ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ + "i"(pda_offset(field))); \ + break; \ case 4: \ - asm(op "l %1,%%gs:%c2" : \ + asm(op "l %1,%%gs:%c2" : \ "+m" (_proxy_pda.field) : \ "ri" ((T__)val), \ - "i" (pda_offset(field))); \ + "i" (pda_offset(field))); \ break; \ case 8: \ - asm(op "q %1,%%gs:%c2": \ + asm(op "q %1,%%gs:%c2": \ "+m" (_proxy_pda.field) : \ "ri" ((T__)val), \ - "i"(pda_offset(field))); \ + "i"(pda_offset(field))); \ break; \ - default: \ + default: \ __bad_pda_field(); \ - } \ - } while (0) + } \ + } while (0) #define pda_from_op(op,field) ({ \ typeof(_proxy_pda.field) ret__; \ switch (sizeof(_proxy_pda.field)) { \ - case 2: \ - asm(op "w %%gs:%c1,%0" : \ + case 2: \ + asm(op "w %%gs:%c1,%0" : \ "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ + "i" (pda_offset(field)), \ + "m" (_proxy_pda.field)); \ break; \ case 4: \ asm(op "l %%gs:%c1,%0": \ "=r" (ret__): \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ + "i" (pda_offset(field)), \ + "m" (_proxy_pda.field)); \ break; \ - case 8: \ + case 8: \ asm(op "q %%gs:%c1,%0": \ "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ + "i" (pda_offset(field)), \ + "m" (_proxy_pda.field)); \ break; \ - default: \ + default: \ __bad_pda_field(); \ } \ ret__; }) -#define read_pda(field) pda_from_op("mov",field) -#define write_pda(field,val) pda_to_op("mov",field,val) -#define add_pda(field,val) pda_to_op("add",field,val) -#define sub_pda(field,val) pda_to_op("sub",field,val) -#define or_pda(field,val) pda_to_op("or",field,val) +#define read_pda(field) pda_from_op("mov", field) +#define write_pda(field, val) pda_to_op("mov", field, val) +#define add_pda(field, val) pda_to_op("add", field, val) +#define sub_pda(field, val) pda_to_op("sub", field, val) +#define or_pda(field, val) pda_to_op("or", field, val) /* This is not atomic against other CPUs -- CPU preemption needs to be off */ -#define test_and_clear_bit_pda(bit,field) ({ \ +#define test_and_clear_bit_pda(bit, field) ({ \ int old__; \ asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ - : "=r" (old__), "+m" (_proxy_pda.field) \ + : "=r" (old__), "+m" (_proxy_pda.field) \ : "dIr" (bit), "i" (pda_offset(field)) : "memory"); \ old__; \ }) -- cgit v1.2.2 From 4ad02718345783a3b84bae1895917666b779850d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:26 +0100 Subject: x86: clean up local_{32|64}.h Common prefix from both files moved to local.h Change __inline__ to inline Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/local_32.h | 34 ++++++++++------------------------ include/asm-x86/local_64.h | 25 ++++++------------------- 2 files changed, 16 insertions(+), 43 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/local_32.h b/include/asm-x86/local_32.h index 6e85975b9ed..33d9c7bf463 100644 --- a/include/asm-x86/local_32.h +++ b/include/asm-x86/local_32.h @@ -1,35 +1,21 @@ #ifndef _ARCH_I386_LOCAL_H #define _ARCH_I386_LOCAL_H -#include -#include -#include - -typedef struct -{ - atomic_long_t a; -} local_t; - -#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } - -#define local_read(l) atomic_long_read(&(l)->a) -#define local_set(l,i) atomic_long_set(&(l)->a, (i)) - -static __inline__ void local_inc(local_t *l) +static inline void local_inc(local_t *l) { __asm__ __volatile__( "incl %0" :"+m" (l->a.counter)); } -static __inline__ void local_dec(local_t *l) +static inline void local_dec(local_t *l) { __asm__ __volatile__( "decl %0" :"+m" (l->a.counter)); } -static __inline__ void local_add(long i, local_t *l) +static inline void local_add(long i, local_t *l) { __asm__ __volatile__( "addl %1,%0" @@ -37,7 +23,7 @@ static __inline__ void local_add(long i, local_t *l) :"ir" (i)); } -static __inline__ void local_sub(long i, local_t *l) +static inline void local_sub(long i, local_t *l) { __asm__ __volatile__( "subl %1,%0" @@ -54,7 +40,7 @@ static __inline__ void local_sub(long i, local_t *l) * true if the result is zero, or false for all * other cases. */ -static __inline__ int local_sub_and_test(long i, local_t *l) +static inline int local_sub_and_test(long i, local_t *l) { unsigned char c; @@ -73,7 +59,7 @@ static __inline__ int local_sub_and_test(long i, local_t *l) * returns true if the result is 0, or false for all other * cases. */ -static __inline__ int local_dec_and_test(local_t *l) +static inline int local_dec_and_test(local_t *l) { unsigned char c; @@ -92,7 +78,7 @@ static __inline__ int local_dec_and_test(local_t *l) * and returns true if the result is zero, or false for all * other cases. */ -static __inline__ int local_inc_and_test(local_t *l) +static inline int local_inc_and_test(local_t *l) { unsigned char c; @@ -112,7 +98,7 @@ static __inline__ int local_inc_and_test(local_t *l) * if the result is negative, or false when * result is greater than or equal to zero. */ -static __inline__ int local_add_negative(long i, local_t *l) +static inline int local_add_negative(long i, local_t *l) { unsigned char c; @@ -130,7 +116,7 @@ static __inline__ int local_add_negative(long i, local_t *l) * * Atomically adds @i to @l and returns @i + @l */ -static __inline__ long local_add_return(long i, local_t *l) +static inline long local_add_return(long i, local_t *l) { long __i; #ifdef CONFIG_M386 @@ -156,7 +142,7 @@ no_xadd: /* Legacy 386 processor */ #endif } -static __inline__ long local_sub_return(long i, local_t *l) +static inline long local_sub_return(long i, local_t *l) { return local_add_return(-i,l); } diff --git a/include/asm-x86/local_64.h b/include/asm-x86/local_64.h index e87492bb069..92330f8135f 100644 --- a/include/asm-x86/local_64.h +++ b/include/asm-x86/local_64.h @@ -1,19 +1,6 @@ #ifndef _ARCH_X8664_LOCAL_H #define _ARCH_X8664_LOCAL_H -#include -#include - -typedef struct -{ - atomic_long_t a; -} local_t; - -#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } - -#define local_read(l) atomic_long_read(&(l)->a) -#define local_set(l,i) atomic_long_set(&(l)->a, (i)) - static inline void local_inc(local_t *l) { __asm__ __volatile__( @@ -55,7 +42,7 @@ static inline void local_sub(long i, local_t *l) * true if the result is zero, or false for all * other cases. */ -static __inline__ int local_sub_and_test(long i, local_t *l) +static inline int local_sub_and_test(long i, local_t *l) { unsigned char c; @@ -74,7 +61,7 @@ static __inline__ int local_sub_and_test(long i, local_t *l) * returns true if the result is 0, or false for all other * cases. */ -static __inline__ int local_dec_and_test(local_t *l) +static inline int local_dec_and_test(local_t *l) { unsigned char c; @@ -93,7 +80,7 @@ static __inline__ int local_dec_and_test(local_t *l) * and returns true if the result is zero, or false for all * other cases. */ -static __inline__ int local_inc_and_test(local_t *l) +static inline int local_inc_and_test(local_t *l) { unsigned char c; @@ -113,7 +100,7 @@ static __inline__ int local_inc_and_test(local_t *l) * if the result is negative, or false when * result is greater than or equal to zero. */ -static __inline__ int local_add_negative(long i, local_t *l) +static inline int local_add_negative(long i, local_t *l) { unsigned char c; @@ -131,7 +118,7 @@ static __inline__ int local_add_negative(long i, local_t *l) * * Atomically adds @i to @l and returns @i + @l */ -static __inline__ long local_add_return(long i, local_t *l) +static inline long local_add_return(long i, local_t *l) { long __i = i; __asm__ __volatile__( @@ -141,7 +128,7 @@ static __inline__ long local_add_return(long i, local_t *l) return i + __i; } -static __inline__ long local_sub_return(long i, local_t *l) +static inline long local_sub_return(long i, local_t *l) { return local_add_return(-i,l); } -- cgit v1.2.2 From 992b95920a311db3267659ea17160e4812a05830 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:26 +0100 Subject: x86: fix asm memory constraints in local_64.h Use the shorter +m form rather than =m and m. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/local_64.h | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/local_64.h b/include/asm-x86/local_64.h index 92330f8135f..50e99eddd62 100644 --- a/include/asm-x86/local_64.h +++ b/include/asm-x86/local_64.h @@ -5,32 +5,30 @@ static inline void local_inc(local_t *l) { __asm__ __volatile__( "incq %0" - :"=m" (l->a.counter) - :"m" (l->a.counter)); + :"+m" (l->a.counter)); } static inline void local_dec(local_t *l) { __asm__ __volatile__( "decq %0" - :"=m" (l->a.counter) - :"m" (l->a.counter)); + :"+m" (l->a.counter)); } static inline void local_add(long i, local_t *l) { __asm__ __volatile__( "addq %1,%0" - :"=m" (l->a.counter) - :"ir" (i), "m" (l->a.counter)); + :"+m" (l->a.counter) + :"ir" (i)); } static inline void local_sub(long i, local_t *l) { __asm__ __volatile__( "subq %1,%0" - :"=m" (l->a.counter) - :"ir" (i), "m" (l->a.counter)); + :"+m" (l->a.counter) + :"ir" (i)); } /** @@ -48,8 +46,8 @@ static inline int local_sub_and_test(long i, local_t *l) __asm__ __volatile__( "subq %2,%0; sete %1" - :"=m" (l->a.counter), "=qm" (c) - :"ir" (i), "m" (l->a.counter) : "memory"); + :"+m" (l->a.counter), "=qm" (c) + :"ir" (i) : "memory"); return c; } @@ -67,8 +65,8 @@ static inline int local_dec_and_test(local_t *l) __asm__ __volatile__( "decq %0; sete %1" - :"=m" (l->a.counter), "=qm" (c) - :"m" (l->a.counter) : "memory"); + :"+m" (l->a.counter), "=qm" (c) + : : "memory"); return c != 0; } @@ -86,8 +84,8 @@ static inline int local_inc_and_test(local_t *l) __asm__ __volatile__( "incq %0; sete %1" - :"=m" (l->a.counter), "=qm" (c) - :"m" (l->a.counter) : "memory"); + :"+m" (l->a.counter), "=qm" (c) + : : "memory"); return c != 0; } @@ -106,8 +104,8 @@ static inline int local_add_negative(long i, local_t *l) __asm__ __volatile__( "addq %2,%0; sets %1" - :"=m" (l->a.counter), "=qm" (c) - :"ir" (i), "m" (l->a.counter) : "memory"); + :"+m" (l->a.counter), "=qm" (c) + :"ir" (i) : "memory"); return c; } -- cgit v1.2.2 From 8ee5797a91bdb713b4031741b33bd035f9c43870 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:26 +0100 Subject: x86: introduce asm helpers in local_{32|64}.h Handle the use of long on X86_32 and quad on X86_64 Signed-off-by: Harvey Harrison Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/asm.h | 12 ++++++++++++ include/asm-x86/local_32.h | 18 +++++++++--------- include/asm-x86/local_64.h | 18 +++++++++--------- 3 files changed, 30 insertions(+), 18 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/asm.h b/include/asm-x86/asm.h index 8661ae75488..1a6980a60fc 100644 --- a/include/asm-x86/asm.h +++ b/include/asm-x86/asm.h @@ -8,6 +8,12 @@ # define _ASM_ALIGN " .balign 4 " # define _ASM_MOV_UL " movl " +# define _ASM_INC " incl " +# define _ASM_DEC " decl " +# define _ASM_ADD " addl " +# define _ASM_SUB " subl " +# define _ASM_XADD " xaddl " + #else /* 64 bits */ @@ -15,6 +21,12 @@ # define _ASM_ALIGN " .balign 8 " # define _ASM_MOV_UL " movq " +# define _ASM_INC " incq " +# define _ASM_DEC " decq " +# define _ASM_ADD " addq " +# define _ASM_SUB " subq " +# define _ASM_XADD " xaddq " + #endif /* CONFIG_X86_32 */ #endif /* _ASM_X86_ASM_H */ diff --git a/include/asm-x86/local_32.h b/include/asm-x86/local_32.h index 33d9c7bf463..c219fe56b3d 100644 --- a/include/asm-x86/local_32.h +++ b/include/asm-x86/local_32.h @@ -4,21 +4,21 @@ static inline void local_inc(local_t *l) { __asm__ __volatile__( - "incl %0" + _ASM_INC "%0" :"+m" (l->a.counter)); } static inline void local_dec(local_t *l) { __asm__ __volatile__( - "decl %0" + _ASM_DEC "%0" :"+m" (l->a.counter)); } static inline void local_add(long i, local_t *l) { __asm__ __volatile__( - "addl %1,%0" + _ASM_ADD "%1,%0" :"+m" (l->a.counter) :"ir" (i)); } @@ -26,7 +26,7 @@ static inline void local_add(long i, local_t *l) static inline void local_sub(long i, local_t *l) { __asm__ __volatile__( - "subl %1,%0" + _ASM_SUB "%1,%0" :"+m" (l->a.counter) :"ir" (i)); } @@ -45,7 +45,7 @@ static inline int local_sub_and_test(long i, local_t *l) unsigned char c; __asm__ __volatile__( - "subl %2,%0; sete %1" + _ASM_SUB "%2,%0; sete %1" :"+m" (l->a.counter), "=qm" (c) :"ir" (i) : "memory"); return c; @@ -64,7 +64,7 @@ static inline int local_dec_and_test(local_t *l) unsigned char c; __asm__ __volatile__( - "decl %0; sete %1" + _ASM_DEC "%0; sete %1" :"+m" (l->a.counter), "=qm" (c) : : "memory"); return c != 0; @@ -83,7 +83,7 @@ static inline int local_inc_and_test(local_t *l) unsigned char c; __asm__ __volatile__( - "incl %0; sete %1" + _ASM_INC "%0; sete %1" :"+m" (l->a.counter), "=qm" (c) : : "memory"); return c != 0; @@ -103,7 +103,7 @@ static inline int local_add_negative(long i, local_t *l) unsigned char c; __asm__ __volatile__( - "addl %2,%0; sets %1" + _ASM_ADD "%2,%0; sets %1" :"+m" (l->a.counter), "=qm" (c) :"ir" (i) : "memory"); return c; @@ -127,7 +127,7 @@ static inline long local_add_return(long i, local_t *l) /* Modern 486+ processor */ __i = i; __asm__ __volatile__( - "xaddl %0, %1;" + _ASM_XADD "%0, %1;" :"+r" (i), "+m" (l->a.counter) : : "memory"); return i + __i; diff --git a/include/asm-x86/local_64.h b/include/asm-x86/local_64.h index 50e99eddd62..d685cd7e014 100644 --- a/include/asm-x86/local_64.h +++ b/include/asm-x86/local_64.h @@ -4,21 +4,21 @@ static inline void local_inc(local_t *l) { __asm__ __volatile__( - "incq %0" + _ASM_INC "%0" :"+m" (l->a.counter)); } static inline void local_dec(local_t *l) { __asm__ __volatile__( - "decq %0" + _ASM_DEC "%0" :"+m" (l->a.counter)); } static inline void local_add(long i, local_t *l) { __asm__ __volatile__( - "addq %1,%0" + _ASM_ADD "%1,%0" :"+m" (l->a.counter) :"ir" (i)); } @@ -26,7 +26,7 @@ static inline void local_add(long i, local_t *l) static inline void local_sub(long i, local_t *l) { __asm__ __volatile__( - "subq %1,%0" + _ASM_SUB "%1,%0" :"+m" (l->a.counter) :"ir" (i)); } @@ -45,7 +45,7 @@ static inline int local_sub_and_test(long i, local_t *l) unsigned char c; __asm__ __volatile__( - "subq %2,%0; sete %1" + _ASM_SUB "%2,%0; sete %1" :"+m" (l->a.counter), "=qm" (c) :"ir" (i) : "memory"); return c; @@ -64,7 +64,7 @@ static inline int local_dec_and_test(local_t *l) unsigned char c; __asm__ __volatile__( - "decq %0; sete %1" + _ASM_DEC "%0; sete %1" :"+m" (l->a.counter), "=qm" (c) : : "memory"); return c != 0; @@ -83,7 +83,7 @@ static inline int local_inc_and_test(local_t *l) unsigned char c; __asm__ __volatile__( - "incq %0; sete %1" + _ASM_INC "%0; sete %1" :"+m" (l->a.counter), "=qm" (c) : : "memory"); return c != 0; @@ -103,7 +103,7 @@ static inline int local_add_negative(long i, local_t *l) unsigned char c; __asm__ __volatile__( - "addq %2,%0; sets %1" + _ASM_ADD "%2,%0; sets %1" :"+m" (l->a.counter), "=qm" (c) :"ir" (i) : "memory"); return c; @@ -120,7 +120,7 @@ static inline long local_add_return(long i, local_t *l) { long __i = i; __asm__ __volatile__( - "xaddq %0, %1;" + _ASM_XADD "%0, %1;" :"+r" (i), "+m" (l->a.counter) : : "memory"); return i + __i; -- cgit v1.2.2 From 5638f99394d478bcba6384ac7c51e763d1a3a448 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:26 +0100 Subject: x86: unify local_{32|64}.h Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/local.h | 244 ++++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/local_32.h | 219 ---------------------------------------- include/asm-x86/local_64.h | 207 -------------------------------------- 3 files changed, 240 insertions(+), 430 deletions(-) delete mode 100644 include/asm-x86/local_32.h delete mode 100644 include/asm-x86/local_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/local.h b/include/asm-x86/local.h index c7a1b1c66c9..f5677e20860 100644 --- a/include/asm-x86/local.h +++ b/include/asm-x86/local.h @@ -1,5 +1,241 @@ -#ifdef CONFIG_X86_32 -# include "local_32.h" -#else -# include "local_64.h" +#ifndef _ARCH_LOCAL_H +#define _ARCH_LOCAL_H + +#include + +#include +#include +#include + +typedef struct +{ + atomic_long_t a; +} local_t; + +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } + +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) + +static inline void local_inc(local_t *l) +{ + __asm__ __volatile__( + _ASM_INC "%0" + :"+m" (l->a.counter)); +} + +static inline void local_dec(local_t *l) +{ + __asm__ __volatile__( + _ASM_DEC "%0" + :"+m" (l->a.counter)); +} + +static inline void local_add(long i, local_t *l) +{ + __asm__ __volatile__( + _ASM_ADD "%1,%0" + :"+m" (l->a.counter) + :"ir" (i)); +} + +static inline void local_sub(long i, local_t *l) +{ + __asm__ __volatile__( + _ASM_SUB "%1,%0" + :"+m" (l->a.counter) + :"ir" (i)); +} + +/** + * local_sub_and_test - subtract value from variable and test result + * @i: integer value to subtract + * @l: pointer to type local_t + * + * Atomically subtracts @i from @l and returns + * true if the result is zero, or false for all + * other cases. + */ +static inline int local_sub_and_test(long i, local_t *l) +{ + unsigned char c; + + __asm__ __volatile__( + _ASM_SUB "%2,%0; sete %1" + :"+m" (l->a.counter), "=qm" (c) + :"ir" (i) : "memory"); + return c; +} + +/** + * local_dec_and_test - decrement and test + * @l: pointer to type local_t + * + * Atomically decrements @l by 1 and + * returns true if the result is 0, or false for all other + * cases. + */ +static inline int local_dec_and_test(local_t *l) +{ + unsigned char c; + + __asm__ __volatile__( + _ASM_DEC "%0; sete %1" + :"+m" (l->a.counter), "=qm" (c) + : : "memory"); + return c != 0; +} + +/** + * local_inc_and_test - increment and test + * @l: pointer to type local_t + * + * Atomically increments @l by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +static inline int local_inc_and_test(local_t *l) +{ + unsigned char c; + + __asm__ __volatile__( + _ASM_INC "%0; sete %1" + :"+m" (l->a.counter), "=qm" (c) + : : "memory"); + return c != 0; +} + +/** + * local_add_negative - add and test if negative + * @i: integer value to add + * @l: pointer to type local_t + * + * Atomically adds @i to @l and returns true + * if the result is negative, or false when + * result is greater than or equal to zero. + */ +static inline int local_add_negative(long i, local_t *l) +{ + unsigned char c; + + __asm__ __volatile__( + _ASM_ADD "%2,%0; sets %1" + :"+m" (l->a.counter), "=qm" (c) + :"ir" (i) : "memory"); + return c; +} + +/** + * local_add_return - add and return + * @i: integer value to add + * @l: pointer to type local_t + * + * Atomically adds @i to @l and returns @i + @l + */ +static inline long local_add_return(long i, local_t *l) +{ + long __i; +#ifdef CONFIG_M386 + unsigned long flags; + if(unlikely(boot_cpu_data.x86 <= 3)) + goto no_xadd; #endif + /* Modern 486+ processor */ + __i = i; + __asm__ __volatile__( + _ASM_XADD "%0, %1;" + :"+r" (i), "+m" (l->a.counter) + : : "memory"); + return i + __i; + +#ifdef CONFIG_M386 +no_xadd: /* Legacy 386 processor */ + local_irq_save(flags); + __i = local_read(l); + local_set(l, i + __i); + local_irq_restore(flags); + return i + __i; +#endif +} + +static inline long local_sub_return(long i, local_t *l) +{ + return local_add_return(-i,l); +} + +#define local_inc_return(l) (local_add_return(1,l)) +#define local_dec_return(l) (local_sub_return(1,l)) + +#define local_cmpxchg(l, o, n) \ + (cmpxchg_local(&((l)->a.counter), (o), (n))) +/* Always has a lock prefix */ +#define local_xchg(l, n) (xchg(&((l)->a.counter), (n))) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to l... + * @u: ...unless l is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +#define local_add_unless(l, a, u) \ +({ \ + long c, old; \ + c = local_read(l); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = local_cmpxchg((l), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old; \ + } \ + c != (u); \ +}) +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +/* On x86_32, these are no better than the atomic variants. + * On x86-64 these are better than the atomic variants on SMP kernels + * because they dont use a lock prefix. + */ +#define __local_inc(l) local_inc(l) +#define __local_dec(l) local_dec(l) +#define __local_add(i,l) local_add((i),(l)) +#define __local_sub(i,l) local_sub((i),(l)) + +/* Use these for per-cpu local_t variables: on some archs they are + * much more efficient than these naive implementations. Note they take + * a variable, not an address. + * + * X86_64: This could be done better if we moved the per cpu data directly + * after GS. + */ + +/* Need to disable preemption for the cpu local counters otherwise we could + still access a variable of a previous CPU in a non atomic way. */ +#define cpu_local_wrap_v(l) \ + ({ local_t res__; \ + preempt_disable(); \ + res__ = (l); \ + preempt_enable(); \ + res__; }) +#define cpu_local_wrap(l) \ + ({ preempt_disable(); \ + l; \ + preempt_enable(); }) \ + +#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l))) +#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i))) +#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l))) +#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l))) +#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l))) +#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l))) + +#define __cpu_local_inc(l) cpu_local_inc(l) +#define __cpu_local_dec(l) cpu_local_dec(l) +#define __cpu_local_add(i, l) cpu_local_add((i), (l)) +#define __cpu_local_sub(i, l) cpu_local_sub((i), (l)) + +#endif /* _ARCH_LOCAL_H */ diff --git a/include/asm-x86/local_32.h b/include/asm-x86/local_32.h deleted file mode 100644 index c219fe56b3d..00000000000 --- a/include/asm-x86/local_32.h +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef _ARCH_I386_LOCAL_H -#define _ARCH_I386_LOCAL_H - -static inline void local_inc(local_t *l) -{ - __asm__ __volatile__( - _ASM_INC "%0" - :"+m" (l->a.counter)); -} - -static inline void local_dec(local_t *l) -{ - __asm__ __volatile__( - _ASM_DEC "%0" - :"+m" (l->a.counter)); -} - -static inline void local_add(long i, local_t *l) -{ - __asm__ __volatile__( - _ASM_ADD "%1,%0" - :"+m" (l->a.counter) - :"ir" (i)); -} - -static inline void local_sub(long i, local_t *l) -{ - __asm__ __volatile__( - _ASM_SUB "%1,%0" - :"+m" (l->a.counter) - :"ir" (i)); -} - -/** - * local_sub_and_test - subtract value from variable and test result - * @i: integer value to subtract - * @l: pointer of type local_t - * - * Atomically subtracts @i from @l and returns - * true if the result is zero, or false for all - * other cases. - */ -static inline int local_sub_and_test(long i, local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_SUB "%2,%0; sete %1" - :"+m" (l->a.counter), "=qm" (c) - :"ir" (i) : "memory"); - return c; -} - -/** - * local_dec_and_test - decrement and test - * @l: pointer of type local_t - * - * Atomically decrements @l by 1 and - * returns true if the result is 0, or false for all other - * cases. - */ -static inline int local_dec_and_test(local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_DEC "%0; sete %1" - :"+m" (l->a.counter), "=qm" (c) - : : "memory"); - return c != 0; -} - -/** - * local_inc_and_test - increment and test - * @l: pointer of type local_t - * - * Atomically increments @l by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ -static inline int local_inc_and_test(local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_INC "%0; sete %1" - :"+m" (l->a.counter), "=qm" (c) - : : "memory"); - return c != 0; -} - -/** - * local_add_negative - add and test if negative - * @l: pointer of type local_t - * @i: integer value to add - * - * Atomically adds @i to @l and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. - */ -static inline int local_add_negative(long i, local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_ADD "%2,%0; sets %1" - :"+m" (l->a.counter), "=qm" (c) - :"ir" (i) : "memory"); - return c; -} - -/** - * local_add_return - add and return - * @l: pointer of type local_t - * @i: integer value to add - * - * Atomically adds @i to @l and returns @i + @l - */ -static inline long local_add_return(long i, local_t *l) -{ - long __i; -#ifdef CONFIG_M386 - unsigned long flags; - if(unlikely(boot_cpu_data.x86 <= 3)) - goto no_xadd; -#endif - /* Modern 486+ processor */ - __i = i; - __asm__ __volatile__( - _ASM_XADD "%0, %1;" - :"+r" (i), "+m" (l->a.counter) - : : "memory"); - return i + __i; - -#ifdef CONFIG_M386 -no_xadd: /* Legacy 386 processor */ - local_irq_save(flags); - __i = local_read(l); - local_set(l, i + __i); - local_irq_restore(flags); - return i + __i; -#endif -} - -static inline long local_sub_return(long i, local_t *l) -{ - return local_add_return(-i,l); -} - -#define local_inc_return(l) (local_add_return(1,l)) -#define local_dec_return(l) (local_sub_return(1,l)) - -#define local_cmpxchg(l, o, n) \ - (cmpxchg_local(&((l)->a.counter), (o), (n))) -/* Always has a lock prefix */ -#define local_xchg(l, n) (xchg(&((l)->a.counter), (n))) - -/** - * local_add_unless - add unless the number is a given value - * @l: pointer of type local_t - * @a: the amount to add to l... - * @u: ...unless l is equal to u. - * - * Atomically adds @a to @l, so long as it was not @u. - * Returns non-zero if @l was not @u, and zero otherwise. - */ -#define local_add_unless(l, a, u) \ -({ \ - long c, old; \ - c = local_read(l); \ - for (;;) { \ - if (unlikely(c == (u))) \ - break; \ - old = local_cmpxchg((l), c, c + (a)); \ - if (likely(old == c)) \ - break; \ - c = old; \ - } \ - c != (u); \ -}) -#define local_inc_not_zero(l) local_add_unless((l), 1, 0) - -/* On x86, these are no better than the atomic variants. */ -#define __local_inc(l) local_inc(l) -#define __local_dec(l) local_dec(l) -#define __local_add(i,l) local_add((i),(l)) -#define __local_sub(i,l) local_sub((i),(l)) - -/* Use these for per-cpu local_t variables: on some archs they are - * much more efficient than these naive implementations. Note they take - * a variable, not an address. - */ - -/* Need to disable preemption for the cpu local counters otherwise we could - still access a variable of a previous CPU in a non atomic way. */ -#define cpu_local_wrap_v(l) \ - ({ local_t res__; \ - preempt_disable(); \ - res__ = (l); \ - preempt_enable(); \ - res__; }) -#define cpu_local_wrap(l) \ - ({ preempt_disable(); \ - l; \ - preempt_enable(); }) \ - -#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l))) -#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i))) -#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l))) -#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l))) -#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l))) -#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l))) - -#define __cpu_local_inc(l) cpu_local_inc(l) -#define __cpu_local_dec(l) cpu_local_dec(l) -#define __cpu_local_add(i, l) cpu_local_add((i), (l)) -#define __cpu_local_sub(i, l) cpu_local_sub((i), (l)) - -#endif /* _ARCH_I386_LOCAL_H */ diff --git a/include/asm-x86/local_64.h b/include/asm-x86/local_64.h deleted file mode 100644 index d685cd7e014..00000000000 --- a/include/asm-x86/local_64.h +++ /dev/null @@ -1,207 +0,0 @@ -#ifndef _ARCH_X8664_LOCAL_H -#define _ARCH_X8664_LOCAL_H - -static inline void local_inc(local_t *l) -{ - __asm__ __volatile__( - _ASM_INC "%0" - :"+m" (l->a.counter)); -} - -static inline void local_dec(local_t *l) -{ - __asm__ __volatile__( - _ASM_DEC "%0" - :"+m" (l->a.counter)); -} - -static inline void local_add(long i, local_t *l) -{ - __asm__ __volatile__( - _ASM_ADD "%1,%0" - :"+m" (l->a.counter) - :"ir" (i)); -} - -static inline void local_sub(long i, local_t *l) -{ - __asm__ __volatile__( - _ASM_SUB "%1,%0" - :"+m" (l->a.counter) - :"ir" (i)); -} - -/** - * local_sub_and_test - subtract value from variable and test result - * @i: integer value to subtract - * @l: pointer to type local_t - * - * Atomically subtracts @i from @l and returns - * true if the result is zero, or false for all - * other cases. - */ -static inline int local_sub_and_test(long i, local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_SUB "%2,%0; sete %1" - :"+m" (l->a.counter), "=qm" (c) - :"ir" (i) : "memory"); - return c; -} - -/** - * local_dec_and_test - decrement and test - * @l: pointer to type local_t - * - * Atomically decrements @l by 1 and - * returns true if the result is 0, or false for all other - * cases. - */ -static inline int local_dec_and_test(local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_DEC "%0; sete %1" - :"+m" (l->a.counter), "=qm" (c) - : : "memory"); - return c != 0; -} - -/** - * local_inc_and_test - increment and test - * @l: pointer to type local_t - * - * Atomically increments @l by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ -static inline int local_inc_and_test(local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_INC "%0; sete %1" - :"+m" (l->a.counter), "=qm" (c) - : : "memory"); - return c != 0; -} - -/** - * local_add_negative - add and test if negative - * @i: integer value to add - * @l: pointer to type local_t - * - * Atomically adds @i to @l and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. - */ -static inline int local_add_negative(long i, local_t *l) -{ - unsigned char c; - - __asm__ __volatile__( - _ASM_ADD "%2,%0; sets %1" - :"+m" (l->a.counter), "=qm" (c) - :"ir" (i) : "memory"); - return c; -} - -/** - * local_add_return - add and return - * @i: integer value to add - * @l: pointer to type local_t - * - * Atomically adds @i to @l and returns @i + @l - */ -static inline long local_add_return(long i, local_t *l) -{ - long __i = i; - __asm__ __volatile__( - _ASM_XADD "%0, %1;" - :"+r" (i), "+m" (l->a.counter) - : : "memory"); - return i + __i; -} - -static inline long local_sub_return(long i, local_t *l) -{ - return local_add_return(-i,l); -} - -#define local_inc_return(l) (local_add_return(1,l)) -#define local_dec_return(l) (local_sub_return(1,l)) - -#define local_cmpxchg(l, o, n) \ - (cmpxchg_local(&((l)->a.counter), (o), (n))) -/* Always has a lock prefix */ -#define local_xchg(l, n) (xchg(&((l)->a.counter), (n))) - -/** - * atomic_up_add_unless - add unless the number is a given value - * @l: pointer of type local_t - * @a: the amount to add to l... - * @u: ...unless l is equal to u. - * - * Atomically adds @a to @l, so long as it was not @u. - * Returns non-zero if @l was not @u, and zero otherwise. - */ -#define local_add_unless(l, a, u) \ -({ \ - long c, old; \ - c = local_read(l); \ - for (;;) { \ - if (unlikely(c == (u))) \ - break; \ - old = local_cmpxchg((l), c, c + (a)); \ - if (likely(old == c)) \ - break; \ - c = old; \ - } \ - c != (u); \ -}) -#define local_inc_not_zero(l) local_add_unless((l), 1, 0) - -/* On x86-64 these are better than the atomic variants on SMP kernels - because they dont use a lock prefix. */ -#define __local_inc(l) local_inc(l) -#define __local_dec(l) local_dec(l) -#define __local_add(i,l) local_add((i),(l)) -#define __local_sub(i,l) local_sub((i),(l)) - -/* Use these for per-cpu local_t variables: on some archs they are - * much more efficient than these naive implementations. Note they take - * a variable, not an address. - * - * This could be done better if we moved the per cpu data directly - * after GS. - */ - -/* Need to disable preemption for the cpu local counters otherwise we could - still access a variable of a previous CPU in a non atomic way. */ -#define cpu_local_wrap_v(l) \ - ({ local_t res__; \ - preempt_disable(); \ - res__ = (l); \ - preempt_enable(); \ - res__; }) -#define cpu_local_wrap(l) \ - ({ preempt_disable(); \ - l; \ - preempt_enable(); }) \ - -#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l))) -#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i))) -#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l))) -#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l))) -#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l))) -#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l))) - -#define __cpu_local_inc(l) cpu_local_inc(l) -#define __cpu_local_dec(l) cpu_local_dec(l) -#define __cpu_local_add(i, l) cpu_local_add((i), (l)) -#define __cpu_local_sub(i, l) cpu_local_sub((i), (l)) - -#endif /* _ARCH_X8664_LOCAL_H */ -- cgit v1.2.2 From 01c57fb6a3eefc34da17be1399453c0800bcff68 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:26 +0100 Subject: x86: local.h fix checkpatch warnings Mostly space after comma, one space after if. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/local.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/local.h b/include/asm-x86/local.h index f5677e20860..f852c62b331 100644 --- a/include/asm-x86/local.h +++ b/include/asm-x86/local.h @@ -7,15 +7,14 @@ #include #include -typedef struct -{ +typedef struct { atomic_long_t a; } local_t; #define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } #define local_read(l) atomic_long_read(&(l)->a) -#define local_set(l,i) atomic_long_set(&(l)->a, (i)) +#define local_set(l, i) atomic_long_set(&(l)->a, (i)) static inline void local_inc(local_t *l) { @@ -137,7 +136,7 @@ static inline long local_add_return(long i, local_t *l) long __i; #ifdef CONFIG_M386 unsigned long flags; - if(unlikely(boot_cpu_data.x86 <= 3)) + if (unlikely(boot_cpu_data.x86 <= 3)) goto no_xadd; #endif /* Modern 486+ processor */ @@ -160,11 +159,11 @@ no_xadd: /* Legacy 386 processor */ static inline long local_sub_return(long i, local_t *l) { - return local_add_return(-i,l); + return local_add_return(-i, l); } -#define local_inc_return(l) (local_add_return(1,l)) -#define local_dec_return(l) (local_sub_return(1,l)) +#define local_inc_return(l) (local_add_return(1, l)) +#define local_dec_return(l) (local_sub_return(1, l)) #define local_cmpxchg(l, o, n) \ (cmpxchg_local(&((l)->a.counter), (o), (n))) @@ -202,8 +201,8 @@ static inline long local_sub_return(long i, local_t *l) */ #define __local_inc(l) local_inc(l) #define __local_dec(l) local_dec(l) -#define __local_add(i,l) local_add((i),(l)) -#define __local_sub(i,l) local_sub((i),(l)) +#define __local_add(i, l) local_add((i), (l)) +#define __local_sub(i, l) local_sub((i), (l)) /* Use these for per-cpu local_t variables: on some archs they are * much more efficient than these naive implementations. Note they take -- cgit v1.2.2 From 3c233d1334ffc8de63a4b6a6a86c40961aed335e Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:26 +0100 Subject: x86: unify kexec_{32|64}.h One section collecting all constant defines. Ifdef the asm blocks for X86_32/64. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Reviewed-by: Vivek Goyal --- include/asm-x86/kexec.h | 169 ++++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/kexec_32.h | 99 -------------------------- include/asm-x86/kexec_64.h | 94 ------------------------- 3 files changed, 167 insertions(+), 195 deletions(-) delete mode 100644 include/asm-x86/kexec_32.h delete mode 100644 include/asm-x86/kexec_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/kexec.h b/include/asm-x86/kexec.h index 718ddbfb951..c90d3c77afc 100644 --- a/include/asm-x86/kexec.h +++ b/include/asm-x86/kexec.h @@ -1,5 +1,170 @@ +#ifndef _KEXEC_H +#define _KEXEC_H + #ifdef CONFIG_X86_32 -# include "kexec_32.h" +# define PA_CONTROL_PAGE 0 +# define VA_CONTROL_PAGE 1 +# define PA_PGD 2 +# define VA_PGD 3 +# define PA_PTE_0 4 +# define VA_PTE_0 5 +# define PA_PTE_1 6 +# define VA_PTE_1 7 +# ifdef CONFIG_X86_PAE +# define PA_PMD_0 8 +# define VA_PMD_0 9 +# define PA_PMD_1 10 +# define VA_PMD_1 11 +# define PAGES_NR 12 +# else +# define PAGES_NR 8 +# endif #else -# include "kexec_64.h" +# define PA_CONTROL_PAGE 0 +# define VA_CONTROL_PAGE 1 +# define PA_PGD 2 +# define VA_PGD 3 +# define PA_PUD_0 4 +# define VA_PUD_0 5 +# define PA_PMD_0 6 +# define VA_PMD_0 7 +# define PA_PTE_0 8 +# define VA_PTE_0 9 +# define PA_PUD_1 10 +# define VA_PUD_1 11 +# define PA_PMD_1 12 +# define VA_PMD_1 13 +# define PA_PTE_1 14 +# define VA_PTE_1 15 +# define PA_TABLE_PAGE 16 +# define PAGES_NR 17 #endif + +#ifndef __ASSEMBLY__ + +#include + +#include +#include + +/* + * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. + * I.e. Maximum page that is mapped directly into kernel memory, + * and kmap is not required. + * + * So far x86_64 is limited to 40 physical address bits. + */ +#ifdef CONFIG_X86_32 +/* Maximum physical address we can use pages from */ +# define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) +/* Maximum address we can reach in physical address mode */ +# define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) +/* Maximum address we can use for the control code buffer */ +# define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE + +# define KEXEC_CONTROL_CODE_SIZE 4096 + +/* The native architecture */ +# define KEXEC_ARCH KEXEC_ARCH_386 + +/* We can also handle crash dumps from 64 bit kernel. */ +# define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64) +#else +/* Maximum physical address we can use pages from */ +# define KEXEC_SOURCE_MEMORY_LIMIT (0xFFFFFFFFFFUL) +/* Maximum address we can reach in physical address mode */ +# define KEXEC_DESTINATION_MEMORY_LIMIT (0xFFFFFFFFFFUL) +/* Maximum address we can use for the control pages */ +# define KEXEC_CONTROL_MEMORY_LIMIT (0xFFFFFFFFFFUL) + +/* Allocate one page for the pdp and the second for the code */ +# define KEXEC_CONTROL_CODE_SIZE (4096UL + 4096UL) + +/* The native architecture */ +# define KEXEC_ARCH KEXEC_ARCH_X86_64 +#endif + +/* + * CPU does not save ss and sp on stack if execution is already + * running in kernel mode at the time of NMI occurrence. This code + * fixes it. + */ +static inline void crash_fixup_ss_esp(struct pt_regs *newregs, + struct pt_regs *oldregs) +{ +#ifdef CONFIG_X86_32 + newregs->sp = (unsigned long)&(oldregs->sp); + __asm__ __volatile__( + "xorl %%eax, %%eax\n\t" + "movw %%ss, %%ax\n\t" + :"=a"(newregs->ss)); +#endif +} + +/* + * This function is responsible for capturing register states if coming + * via panic otherwise just fix up the ss and sp if coming via kernel + * mode exception. + */ +static inline void crash_setup_regs(struct pt_regs *newregs, + struct pt_regs *oldregs) +{ + if (oldregs) { + memcpy(newregs, oldregs, sizeof(*newregs)); + crash_fixup_ss_esp(newregs, oldregs); + } else { +#ifdef CONFIG_X86_32 + __asm__ __volatile__("movl %%ebx,%0" : "=m"(newregs->bx)); + __asm__ __volatile__("movl %%ecx,%0" : "=m"(newregs->cx)); + __asm__ __volatile__("movl %%edx,%0" : "=m"(newregs->dx)); + __asm__ __volatile__("movl %%esi,%0" : "=m"(newregs->si)); + __asm__ __volatile__("movl %%edi,%0" : "=m"(newregs->di)); + __asm__ __volatile__("movl %%ebp,%0" : "=m"(newregs->bp)); + __asm__ __volatile__("movl %%eax,%0" : "=m"(newregs->ax)); + __asm__ __volatile__("movl %%esp,%0" : "=m"(newregs->sp)); + __asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss)); + __asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs)); + __asm__ __volatile__("movl %%ds, %%eax;" :"=a"(newregs->ds)); + __asm__ __volatile__("movl %%es, %%eax;" :"=a"(newregs->es)); + __asm__ __volatile__("pushfl; popl %0" :"=m"(newregs->flags)); +#else + __asm__ __volatile__("movq %%rbx,%0" : "=m"(newregs->bx)); + __asm__ __volatile__("movq %%rcx,%0" : "=m"(newregs->cx)); + __asm__ __volatile__("movq %%rdx,%0" : "=m"(newregs->dx)); + __asm__ __volatile__("movq %%rsi,%0" : "=m"(newregs->si)); + __asm__ __volatile__("movq %%rdi,%0" : "=m"(newregs->di)); + __asm__ __volatile__("movq %%rbp,%0" : "=m"(newregs->bp)); + __asm__ __volatile__("movq %%rax,%0" : "=m"(newregs->ax)); + __asm__ __volatile__("movq %%rsp,%0" : "=m"(newregs->sp)); + __asm__ __volatile__("movq %%r8,%0" : "=m"(newregs->r8)); + __asm__ __volatile__("movq %%r9,%0" : "=m"(newregs->r9)); + __asm__ __volatile__("movq %%r10,%0" : "=m"(newregs->r10)); + __asm__ __volatile__("movq %%r11,%0" : "=m"(newregs->r11)); + __asm__ __volatile__("movq %%r12,%0" : "=m"(newregs->r12)); + __asm__ __volatile__("movq %%r13,%0" : "=m"(newregs->r13)); + __asm__ __volatile__("movq %%r14,%0" : "=m"(newregs->r14)); + __asm__ __volatile__("movq %%r15,%0" : "=m"(newregs->r15)); + __asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss)); + __asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs)); + __asm__ __volatile__("pushfq; popq %0" :"=m"(newregs->flags)); +#endif + newregs->ip = (unsigned long)current_text_addr(); + } +} + +#ifdef CONFIG_X86_32 +asmlinkage NORET_TYPE void +relocate_kernel(unsigned long indirection_page, + unsigned long control_page, + unsigned long start_address, + unsigned int has_pae) ATTRIB_NORET; +#else +NORET_TYPE void +relocate_kernel(unsigned long indirection_page, + unsigned long page_list, + unsigned long start_address) ATTRIB_NORET; +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _KEXEC_H */ diff --git a/include/asm-x86/kexec_32.h b/include/asm-x86/kexec_32.h deleted file mode 100644 index ff39d2f8802..00000000000 --- a/include/asm-x86/kexec_32.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef _I386_KEXEC_H -#define _I386_KEXEC_H - -#define PA_CONTROL_PAGE 0 -#define VA_CONTROL_PAGE 1 -#define PA_PGD 2 -#define VA_PGD 3 -#define PA_PTE_0 4 -#define VA_PTE_0 5 -#define PA_PTE_1 6 -#define VA_PTE_1 7 -#ifdef CONFIG_X86_PAE -#define PA_PMD_0 8 -#define VA_PMD_0 9 -#define PA_PMD_1 10 -#define VA_PMD_1 11 -#define PAGES_NR 12 -#else -#define PAGES_NR 8 -#endif - -#ifndef __ASSEMBLY__ - -#include -#include - -/* - * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. - * I.e. Maximum page that is mapped directly into kernel memory, - * and kmap is not required. - */ - -/* Maximum physical address we can use pages from */ -#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) -/* Maximum address we can reach in physical address mode */ -#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) -/* Maximum address we can use for the control code buffer */ -#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE - -#define KEXEC_CONTROL_CODE_SIZE 4096 - -/* The native architecture */ -#define KEXEC_ARCH KEXEC_ARCH_386 - -/* We can also handle crash dumps from 64 bit kernel. */ -#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64) - -/* CPU does not save ss and sp on stack if execution is already - * running in kernel mode at the time of NMI occurrence. This code - * fixes it. - */ -static inline void crash_fixup_ss_esp(struct pt_regs *newregs, - struct pt_regs *oldregs) -{ - memcpy(newregs, oldregs, sizeof(*newregs)); - newregs->sp = (unsigned long)&(oldregs->sp); - __asm__ __volatile__( - "xorl %%eax, %%eax\n\t" - "movw %%ss, %%ax\n\t" - :"=a"(newregs->ss)); -} - -/* - * This function is responsible for capturing register states if coming - * via panic otherwise just fix up the ss and sp if coming via kernel - * mode exception. - */ -static inline void crash_setup_regs(struct pt_regs *newregs, - struct pt_regs *oldregs) -{ - if (oldregs) - crash_fixup_ss_esp(newregs, oldregs); - else { - __asm__ __volatile__("movl %%ebx,%0" : "=m"(newregs->bx)); - __asm__ __volatile__("movl %%ecx,%0" : "=m"(newregs->cx)); - __asm__ __volatile__("movl %%edx,%0" : "=m"(newregs->dx)); - __asm__ __volatile__("movl %%esi,%0" : "=m"(newregs->si)); - __asm__ __volatile__("movl %%edi,%0" : "=m"(newregs->di)); - __asm__ __volatile__("movl %%ebp,%0" : "=m"(newregs->bp)); - __asm__ __volatile__("movl %%eax,%0" : "=m"(newregs->ax)); - __asm__ __volatile__("movl %%esp,%0" : "=m"(newregs->sp)); - __asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss)); - __asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs)); - __asm__ __volatile__("movl %%ds, %%eax;" :"=a"(newregs->ds)); - __asm__ __volatile__("movl %%es, %%eax;" :"=a"(newregs->es)); - __asm__ __volatile__("pushfl; popl %0" :"=m"(newregs->flags)); - - newregs->ip = (unsigned long)current_text_addr(); - } -} -asmlinkage NORET_TYPE void -relocate_kernel(unsigned long indirection_page, - unsigned long control_page, - unsigned long start_address, - unsigned int has_pae) ATTRIB_NORET; - -#endif /* __ASSEMBLY__ */ - -#endif /* _I386_KEXEC_H */ diff --git a/include/asm-x86/kexec_64.h b/include/asm-x86/kexec_64.h deleted file mode 100644 index b5f989b15c0..00000000000 --- a/include/asm-x86/kexec_64.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _X86_64_KEXEC_H -#define _X86_64_KEXEC_H - -#define PA_CONTROL_PAGE 0 -#define VA_CONTROL_PAGE 1 -#define PA_PGD 2 -#define VA_PGD 3 -#define PA_PUD_0 4 -#define VA_PUD_0 5 -#define PA_PMD_0 6 -#define VA_PMD_0 7 -#define PA_PTE_0 8 -#define VA_PTE_0 9 -#define PA_PUD_1 10 -#define VA_PUD_1 11 -#define PA_PMD_1 12 -#define VA_PMD_1 13 -#define PA_PTE_1 14 -#define VA_PTE_1 15 -#define PA_TABLE_PAGE 16 -#define PAGES_NR 17 - -#ifndef __ASSEMBLY__ - -#include - -#include -#include - -/* - * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. - * I.e. Maximum page that is mapped directly into kernel memory, - * and kmap is not required. - * - * So far x86_64 is limited to 40 physical address bits. - */ - -/* Maximum physical address we can use pages from */ -#define KEXEC_SOURCE_MEMORY_LIMIT (0xFFFFFFFFFFUL) -/* Maximum address we can reach in physical address mode */ -#define KEXEC_DESTINATION_MEMORY_LIMIT (0xFFFFFFFFFFUL) -/* Maximum address we can use for the control pages */ -#define KEXEC_CONTROL_MEMORY_LIMIT (0xFFFFFFFFFFUL) - -/* Allocate one page for the pdp and the second for the code */ -#define KEXEC_CONTROL_CODE_SIZE (4096UL + 4096UL) - -/* The native architecture */ -#define KEXEC_ARCH KEXEC_ARCH_X86_64 - -/* - * Saving the registers of the cpu on which panic occured in - * crash_kexec to save a valid sp. The registers of other cpus - * will be saved in machine_crash_shutdown while shooting down them. - */ - -static inline void crash_setup_regs(struct pt_regs *newregs, - struct pt_regs *oldregs) -{ - if (oldregs) - memcpy(newregs, oldregs, sizeof(*newregs)); - else { - __asm__ __volatile__("movq %%rbx,%0" : "=m"(newregs->bx)); - __asm__ __volatile__("movq %%rcx,%0" : "=m"(newregs->cx)); - __asm__ __volatile__("movq %%rdx,%0" : "=m"(newregs->dx)); - __asm__ __volatile__("movq %%rsi,%0" : "=m"(newregs->si)); - __asm__ __volatile__("movq %%rdi,%0" : "=m"(newregs->di)); - __asm__ __volatile__("movq %%rbp,%0" : "=m"(newregs->bp)); - __asm__ __volatile__("movq %%rax,%0" : "=m"(newregs->ax)); - __asm__ __volatile__("movq %%rsp,%0" : "=m"(newregs->sp)); - __asm__ __volatile__("movq %%r8,%0" : "=m"(newregs->r8)); - __asm__ __volatile__("movq %%r9,%0" : "=m"(newregs->r9)); - __asm__ __volatile__("movq %%r10,%0" : "=m"(newregs->r10)); - __asm__ __volatile__("movq %%r11,%0" : "=m"(newregs->r11)); - __asm__ __volatile__("movq %%r12,%0" : "=m"(newregs->r12)); - __asm__ __volatile__("movq %%r13,%0" : "=m"(newregs->r13)); - __asm__ __volatile__("movq %%r14,%0" : "=m"(newregs->r14)); - __asm__ __volatile__("movq %%r15,%0" : "=m"(newregs->r15)); - __asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss)); - __asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs)); - __asm__ __volatile__("pushfq; popq %0" :"=m"(newregs->flags)); - - newregs->ip = (unsigned long)current_text_addr(); - } -} - -NORET_TYPE void -relocate_kernel(unsigned long indirection_page, - unsigned long page_list, - unsigned long start_address) ATTRIB_NORET; - -#endif /* __ASSEMBLY__ */ - -#endif /* _X86_64_KEXEC_H */ -- cgit v1.2.2 From 73018a66e70fa631935192e5ed6ef8fa2d20b22d Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:26 +0100 Subject: x86: move tsc definitions to were they belong This patch wipes out the definitions of tsc_disable from processor_32.h and move it to tsc.h, were it belongs Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_32.h | 5 ----- include/asm-x86/tsc.h | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index a5560a3b57e..76cada930d2 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -22,9 +22,6 @@ #include #include -/* flag for disabling the tsc */ -extern int tsc_disable; - static inline int desc_empty(const void *ptr) { const u32 *desc = ptr; @@ -206,8 +203,6 @@ extern int bootloader_type; #define HAVE_ARCH_PICK_MMAP_LAYOUT -extern void disable_TSC(void); - /* * Size of io_bitmap. */ diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index 9b7d264897f..40130372413 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -16,6 +16,10 @@ typedef unsigned long long cycles_t; extern unsigned int cpu_khz; extern unsigned int tsc_khz; +/* flag for disabling the tsc */ +extern int tsc_disable; + +extern void disable_TSC(void); static inline cycles_t get_cycles(void) { -- cgit v1.2.2 From 053de044411111da00272d1b4e174e7dd743f499 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:27 +0100 Subject: x86: get rid of _MASK flags There's no need for the *_MASK flags (TF_MASK, IF_MASK, etc), found in processor.h (both _32 and _64). They have a one-to-one mapping with the EFLAGS value. This patch removes the definitions, and use the already existent X86_EFLAGS_ version when applicable. [ roland@redhat.com: KVM build fixes. ] Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/kprobes.h | 2 +- include/asm-x86/processor.h | 2 ++ include/asm-x86/processor_32.h | 1 - include/asm-x86/processor_64.h | 11 ----------- 4 files changed, 3 insertions(+), 13 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h index 6e6371a856e..143476a3cb5 100644 --- a/include/asm-x86/kprobes.h +++ b/include/asm-x86/kprobes.h @@ -88,7 +88,7 @@ struct kprobe_ctlblk { */ static inline void restore_interrupts(struct pt_regs *regs) { - if (regs->flags & IF_MASK) + if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); } diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index dea81b70895..e8dd394c9f4 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -1,6 +1,8 @@ #ifndef __ASM_X86_PROCESSOR_H #define __ASM_X86_PROCESSOR_H +#include + static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 76cada930d2..b9dbe4668e7 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -19,7 +19,6 @@ #include #include #include -#include #include static inline int desc_empty(const void *ptr) diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index a0a9e551509..c49716a7664 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -18,19 +18,8 @@ #include #include #include -#include #include -#define TF_MASK 0x00000100 -#define IF_MASK 0x00000200 -#define IOPL_MASK 0x00003000 -#define NT_MASK 0x00004000 -#define VM_MASK 0x00020000 -#define AC_MASK 0x00040000 -#define VIF_MASK 0x00080000 /* virtual interrupt flag */ -#define VIP_MASK 0x00100000 /* virtual interrupt pending */ -#define ID_MASK 0x00200000 - static inline int desc_empty(const void *ptr) { const u32 *desc = ptr; -- cgit v1.2.2 From 746ff60f2627626fca0d8ddbf6b1f04d505782f4 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:27 +0100 Subject: x86: move desc_empty to where they belong This patch moves the (duplicated) desc_empty implementation to desc.h, where the descriptor things belong. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 6 ++++++ include/asm-x86/processor_32.h | 6 ------ include/asm-x86/processor_64.h | 6 ------ 3 files changed, 6 insertions(+), 12 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index e9356a85202..e17581ad882 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -71,6 +71,12 @@ static inline void pack_gate(gate_desc *gate, unsigned char type, #endif +static inline int desc_empty(const void *ptr) +{ + const u32 *desc = ptr; + return !(desc[0] | desc[1]); +} + #ifdef CONFIG_PARAVIRT #include #else diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index b9dbe4668e7..cadeffb54a7 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -21,12 +21,6 @@ #include #include -static inline int desc_empty(const void *ptr) -{ - const u32 *desc = ptr; - return !(desc[0] | desc[1]); -} - /* * Default implementation of macro that returns current * instruction pointer ("program counter"). diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index c49716a7664..acecef80a51 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -20,12 +20,6 @@ #include #include -static inline int desc_empty(const void *ptr) -{ - const u32 *desc = ptr; - return !(desc[0] | desc[1]); -} - /* * Default implementation of macro that returns current * instruction pointer ("program counter"). -- cgit v1.2.2 From c72dcf83ff8585c95739abffa3be7c87ca63d66b Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:27 +0100 Subject: x86: move load_cr3 to a common place. There are currently two definitions of load_cr3, that essentially do the same thing. This patch moves them all to processor.h. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mmu_context_64.h | 5 ----- include/asm-x86/processor.h | 7 +++++++ include/asm-x86/processor_32.h | 1 - 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h index 98bfe43dd80..7e2aa23fccb 100644 --- a/include/asm-x86/mmu_context_64.h +++ b/include/asm-x86/mmu_context_64.h @@ -23,11 +23,6 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) #endif } -static inline void load_cr3(pgd_t *pgd) -{ - asm volatile("movq %0,%%cr3" :: "r" (__pa(pgd)) : "memory"); -} - static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index e8dd394c9f4..36ee9881b74 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -3,6 +3,9 @@ #include +#include +#include + static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { @@ -15,6 +18,10 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, : "0" (*eax), "2" (*ecx)); } +static inline void load_cr3(pgd_t *pgdir) +{ + write_cr3(__pa(pgdir)); +} #ifdef CONFIG_X86_32 # include "processor_32.h" diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index cadeffb54a7..b586902acd8 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -120,7 +120,6 @@ extern void detect_ht(struct cpuinfo_x86 *c); static inline void detect_ht(struct cpuinfo_x86 *c) {} #endif -#define load_cr3(pgdir) write_cr3(__pa(pgdir)) /* * Save the cr4 feature set we're using (ie -- cgit v1.2.2 From 1b46cbe0ccaad25786526601bc54426f2e2abb20 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:27 +0100 Subject: x86: unify paravirt pieces of processor.h This patch unifies the paravirt pieces of processor.h The functionality present in 32 bit, but not (yet) in 64-bit, like load_sp0 is _not_ done here, and let to a different patch. With this unification, we get paravirt for free in x86_64 processor.h Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 90 +++++++++++++++++++++++++++++++++++++++++- include/asm-x86/processor_32.h | 87 ---------------------------------------- include/asm-x86/processor_64.h | 36 ----------------- 3 files changed, 89 insertions(+), 124 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 36ee9881b74..8d0af7bf090 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -29,9 +29,97 @@ static inline void load_cr3(pgd_t *pgdir) # include "processor_64.h" #endif +static inline unsigned long native_get_debugreg(int regno) +{ + unsigned long val = 0; /* Damn you, gcc! */ + + switch (regno) { + case 0: + asm("mov %%db0, %0" :"=r" (val)); break; + case 1: + asm("mov %%db1, %0" :"=r" (val)); break; + case 2: + asm("mov %%db2, %0" :"=r" (val)); break; + case 3: + asm("mov %%db3, %0" :"=r" (val)); break; + case 6: + asm("mov %%db6, %0" :"=r" (val)); break; + case 7: + asm("mov %%db7, %0" :"=r" (val)); break; + default: + BUG(); + } + return val; +} + +static inline void native_set_debugreg(int regno, unsigned long value) +{ + switch (regno) { + case 0: + asm("mov %0,%%db0" : /* no output */ :"r" (value)); + break; + case 1: + asm("mov %0,%%db1" : /* no output */ :"r" (value)); + break; + case 2: + asm("mov %0,%%db2" : /* no output */ :"r" (value)); + break; + case 3: + asm("mov %0,%%db3" : /* no output */ :"r" (value)); + break; + case 6: + asm("mov %0,%%db6" : /* no output */ :"r" (value)); + break; + case 7: + asm("mov %0,%%db7" : /* no output */ :"r" (value)); + break; + default: + BUG(); + } +} + + #ifndef CONFIG_PARAVIRT #define __cpuid native_cpuid -#endif +#define paravirt_enabled() 0 + +/* + * These special macros can be used to get or set a debugging register + */ +#define get_debugreg(var, register) \ + (var) = native_get_debugreg(register) +#define set_debugreg(value, register) \ + native_set_debugreg(register, value) + +#endif /* CONFIG_PARAVIRT */ + +/* + * Save the cr4 feature set we're using (ie + * Pentium 4MB enable and PPro Global page + * enable), so that any CPU's that boot up + * after us can get the correct flags. + */ +extern unsigned long mmu_cr4_features; + +static inline void set_in_cr4(unsigned long mask) +{ + unsigned cr4; + mmu_cr4_features |= mask; + cr4 = read_cr4(); + cr4 |= mask; + write_cr4(cr4); +} + +static inline void clear_in_cr4(unsigned long mask) +{ + unsigned cr4; + mmu_cr4_features &= ~mask; + cr4 = read_cr4(); + cr4 &= ~mask; + write_cr4(cr4); +} + + /* * Generic CPUID function diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index b586902acd8..e7fc023cd81 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -120,33 +120,6 @@ extern void detect_ht(struct cpuinfo_x86 *c); static inline void detect_ht(struct cpuinfo_x86 *c) {} #endif - -/* - * Save the cr4 feature set we're using (ie - * Pentium 4MB enable and PPro Global page - * enable), so that any CPU's that boot up - * after us can get the correct flags. - */ -extern unsigned long mmu_cr4_features; - -static inline void set_in_cr4 (unsigned long mask) -{ - unsigned cr4; - mmu_cr4_features |= mask; - cr4 = read_cr4(); - cr4 |= mask; - write_cr4(cr4); -} - -static inline void clear_in_cr4 (unsigned long mask) -{ - unsigned cr4; - mmu_cr4_features &= ~mask; - cr4 = read_cr4(); - cr4 &= ~mask; - write_cr4(cr4); -} - /* Stop speculative execution */ static inline void sync_core(void) { @@ -482,57 +455,6 @@ static inline void native_load_sp0(struct tss_struct *tss, struct thread_struct wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); } } - - -static inline unsigned long native_get_debugreg(int regno) -{ - unsigned long val = 0; /* Damn you, gcc! */ - - switch (regno) { - case 0: - asm("movl %%db0, %0" :"=r" (val)); break; - case 1: - asm("movl %%db1, %0" :"=r" (val)); break; - case 2: - asm("movl %%db2, %0" :"=r" (val)); break; - case 3: - asm("movl %%db3, %0" :"=r" (val)); break; - case 6: - asm("movl %%db6, %0" :"=r" (val)); break; - case 7: - asm("movl %%db7, %0" :"=r" (val)); break; - default: - BUG(); - } - return val; -} - -static inline void native_set_debugreg(int regno, unsigned long value) -{ - switch (regno) { - case 0: - asm("movl %0,%%db0" : /* no output */ :"r" (value)); - break; - case 1: - asm("movl %0,%%db1" : /* no output */ :"r" (value)); - break; - case 2: - asm("movl %0,%%db2" : /* no output */ :"r" (value)); - break; - case 3: - asm("movl %0,%%db3" : /* no output */ :"r" (value)); - break; - case 6: - asm("movl %0,%%db6" : /* no output */ :"r" (value)); - break; - case 7: - asm("movl %0,%%db7" : /* no output */ :"r" (value)); - break; - default: - BUG(); - } -} - /* * Set IOPL bits in EFLAGS from given mask */ @@ -552,21 +474,12 @@ static inline void native_set_iopl_mask(unsigned mask) #ifdef CONFIG_PARAVIRT #include #else -#define paravirt_enabled() 0 static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread) { native_load_sp0(tss, thread); } -/* - * These special macros can be used to get or set a debugging register - */ -#define get_debugreg(var, register) \ - (var) = native_get_debugreg(register) -#define set_debugreg(value, register) \ - native_set_debugreg(register, value) - #define set_iopl_mask native_set_iopl_mask #endif /* CONFIG_PARAVIRT */ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index acecef80a51..6abe1ba30fe 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -88,34 +88,6 @@ extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); extern unsigned short num_cache_leaves; -/* - * Save the cr4 feature set we're using (ie - * Pentium 4MB enable and PPro Global page - * enable), so that any CPU's that boot up - * after us can get the correct flags. - */ -extern unsigned long mmu_cr4_features; - -static inline void set_in_cr4 (unsigned long mask) -{ - mmu_cr4_features |= mask; - __asm__("movq %%cr4,%%rax\n\t" - "orq %0,%%rax\n\t" - "movq %%rax,%%cr4\n" - : : "irg" (mask) - :"ax"); -} - -static inline void clear_in_cr4 (unsigned long mask) -{ - mmu_cr4_features &= ~mask; - __asm__("movq %%cr4,%%rax\n\t" - "andq %0,%%rax\n\t" - "movq %%rax,%%cr4\n" - : : "irg" (~mask) - :"ax"); -} - /* * User space process size. 47bits minus one guard page. @@ -254,14 +226,6 @@ struct thread_struct { set_fs(USER_DS); \ } while(0) -#define get_debugreg(var, register) \ - __asm__("movq %%db" #register ", %0" \ - :"=r" (var)) -#define set_debugreg(value, register) \ - __asm__("movq %0,%%db" #register \ - : /* no output */ \ - :"r" (value)) - struct task_struct; struct mm_struct; -- cgit v1.2.2 From 62d7d7ed11760a0fea40e4fc6f0553e721d00443 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:27 +0100 Subject: x86: move the definition of set_iopl_mask to common header This patch moves the definition of set_iopl_mask to processor.h, instead of letting it at processor_32.h. For x86_64, nothing is done, as we don't really need such a function. However, having it on both arches saves us from putting an ifdef in the pv_cpu_ops struct. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 19 +++++++++++++++++++ include/asm-x86/processor_32.h | 17 ----------------- 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 8d0af7bf090..8b779476688 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -78,6 +78,24 @@ static inline void native_set_debugreg(int regno, unsigned long value) } } +/* + * Set IOPL bits in EFLAGS from given mask + */ +static inline void native_set_iopl_mask(unsigned mask) +{ +#ifdef CONFIG_X86_32 + unsigned int reg; + __asm__ __volatile__ ("pushfl;" + "popl %0;" + "andl %1, %0;" + "orl %2, %0;" + "pushl %0;" + "popfl" + : "=&r" (reg) + : "i" (~X86_EFLAGS_IOPL), "r" (mask)); +#endif +} + #ifndef CONFIG_PARAVIRT #define __cpuid native_cpuid @@ -91,6 +109,7 @@ static inline void native_set_debugreg(int regno, unsigned long value) #define set_debugreg(value, register) \ native_set_debugreg(register, value) +#define set_iopl_mask native_set_iopl_mask #endif /* CONFIG_PARAVIRT */ /* diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index e7fc023cd81..516a38ad2a7 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -455,21 +455,6 @@ static inline void native_load_sp0(struct tss_struct *tss, struct thread_struct wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); } } -/* - * Set IOPL bits in EFLAGS from given mask - */ -static inline void native_set_iopl_mask(unsigned mask) -{ - unsigned int reg; - __asm__ __volatile__ ("pushfl;" - "popl %0;" - "andl %1, %0;" - "orl %2, %0;" - "pushl %0;" - "popfl" - : "=&r" (reg) - : "i" (~X86_EFLAGS_IOPL), "r" (mask)); -} #ifdef CONFIG_PARAVIRT #include @@ -479,8 +464,6 @@ static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread { native_load_sp0(tss, thread); } - -#define set_iopl_mask native_set_iopl_mask #endif /* CONFIG_PARAVIRT */ /* generic versions from gas */ -- cgit v1.2.2 From 683e0253dbd12554b2ee969b15e68105252bff57 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:27 +0100 Subject: x86: unify common parts of processor.h This patch moves the pieces of processor_32.h and processor_64 that are equal to processor.h. Only what's exactly the same is moved around, the rest not being touched. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 120 +++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 111 -------------------------------------- include/asm-x86/processor_64.h | 116 --------------------------------------- 3 files changed, 120 insertions(+), 227 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 8b779476688..52e3637ef59 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -3,6 +3,10 @@ #include +/* Forward declaration, a strange C thing */ +struct task_struct; +struct mm_struct; + #include #include @@ -29,6 +33,11 @@ static inline void load_cr3(pgd_t *pgdir) # include "processor_64.h" #endif +extern void print_cpu_info(struct cpuinfo_x86 *); +extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); +extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); +extern unsigned short num_cache_leaves; + static inline unsigned long native_get_debugreg(int regno) { unsigned long val = 0; /* Damn you, gcc! */ @@ -138,7 +147,53 @@ static inline void clear_in_cr4(unsigned long mask) write_cr4(cr4); } +struct microcode_header { + unsigned int hdrver; + unsigned int rev; + unsigned int date; + unsigned int sig; + unsigned int cksum; + unsigned int ldrver; + unsigned int pf; + unsigned int datasize; + unsigned int totalsize; + unsigned int reserved[3]; +}; + +struct microcode { + struct microcode_header hdr; + unsigned int bits[0]; +}; + +typedef struct microcode microcode_t; +typedef struct microcode_header microcode_header_t; + +/* microcode format is extended from prescott processors */ +struct extended_signature { + unsigned int sig; + unsigned int pf; + unsigned int cksum; +}; + +struct extended_sigtable { + unsigned int count; + unsigned int cksum; + unsigned int reserved[3]; + struct extended_signature sigs[0]; +}; + +/* + * create a kernel thread without removing it from tasklists + */ +extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + +/* Prepare to copy thread state - unlazy all lazy status */ +extern void prepare_to_copy(struct task_struct *tsk); +unsigned long get_wchan(struct task_struct *p); /* * Generic CPUID function @@ -196,4 +251,69 @@ static inline unsigned int cpuid_edx(unsigned int op) return edx; } +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ +static inline void rep_nop(void) +{ + __asm__ __volatile__("rep;nop": : :"memory"); +} + +/* Stop speculative execution */ +static inline void sync_core(void) +{ + int tmp; + asm volatile("cpuid" : "=a" (tmp) : "0" (1) + : "ebx", "ecx", "edx", "memory"); +} + +#define cpu_relax() rep_nop() + +static inline void __monitor(const void *eax, unsigned long ecx, + unsigned long edx) +{ + /* "monitor %eax,%ecx,%edx;" */ + asm volatile( + ".byte 0x0f,0x01,0xc8;" + : :"a" (eax), "c" (ecx), "d"(edx)); +} + +static inline void __mwait(unsigned long eax, unsigned long ecx) +{ + /* "mwait %eax,%ecx;" */ + asm volatile( + ".byte 0x0f,0x01,0xc9;" + : :"a" (eax), "c" (ecx)); +} + +static inline void __sti_mwait(unsigned long eax, unsigned long ecx) +{ + /* "mwait %eax,%ecx;" */ + asm volatile( + "sti; .byte 0x0f,0x01,0xc9;" + : :"a" (eax), "c" (ecx)); +} + +extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); + +extern int force_mwait; + +extern void select_idle_routine(const struct cpuinfo_x86 *c); + +extern unsigned long boot_option_idle_override; + +/* Boot loader type from the setup header */ +extern int bootloader_type; +#define cache_line_size() (boot_cpu_data.x86_cache_alignment) + +#define HAVE_ARCH_PICK_MMAP_LAYOUT 1 +#define ARCH_HAS_PREFETCHW +#define ARCH_HAS_SPINLOCK_PREFETCH + +#define spin_lock_prefetch(x) prefetchw(x) +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) + +#define KSTK_EIP(task) (task_pt_regs(task)->ip) + #endif diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 516a38ad2a7..9e119d3789b 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -109,10 +109,6 @@ void __init cpu_detect(struct cpuinfo_x86 *c); extern void identify_boot_cpu(void); extern void identify_secondary_cpu(struct cpuinfo_x86 *); -extern void print_cpu_info(struct cpuinfo_x86 *); -extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); -extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); -extern unsigned short num_cache_leaves; #ifdef CONFIG_X86_HT extern void detect_ht(struct cpuinfo_x86 *c); @@ -120,32 +116,6 @@ extern void detect_ht(struct cpuinfo_x86 *c); static inline void detect_ht(struct cpuinfo_x86 *c) {} #endif -/* Stop speculative execution */ -static inline void sync_core(void) -{ - int tmp; - asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory"); -} - -static inline void __monitor(const void *eax, unsigned long ecx, - unsigned long edx) -{ - /* "monitor %eax,%ecx,%edx;" */ - asm volatile( - ".byte 0x0f,0x01,0xc8;" - : :"a" (eax), "c" (ecx), "d"(edx)); -} - -static inline void __mwait(unsigned long eax, unsigned long ecx) -{ - /* "mwait %eax,%ecx;" */ - asm volatile( - ".byte 0x0f,0x01,0xc9;" - : :"a" (eax), "c" (ecx)); -} - -extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); - /* from system description table in BIOS. Mostly for MCA use, but others may find it useful. */ extern unsigned int machine_id; @@ -153,20 +123,11 @@ extern unsigned int machine_submodel_id; extern unsigned int BIOS_revision; extern unsigned int mca_pentium_flag; -/* Boot loader type from the setup header */ -extern int bootloader_type; - /* * User space process size: 3GB (default). */ #define TASK_SIZE (PAGE_OFFSET) -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) - -#define HAVE_ARCH_PICK_MMAP_LAYOUT /* * Size of io_bitmap. @@ -356,25 +317,9 @@ struct thread_struct { regs->sp = new_esp; \ } while (0) -/* Forward declaration, a strange C thing */ -struct task_struct; -struct mm_struct; - -/* Free all resources held by a thread. */ -extern void release_thread(struct task_struct *); - -/* Prepare to copy thread state - unlazy all lazy status */ -extern void prepare_to_copy(struct task_struct *tsk); - -/* - * create a kernel thread without removing it from tasklists - */ -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); extern unsigned long thread_saved_pc(struct task_struct *tsk); -unsigned long get_wchan(struct task_struct *p); - #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) #define KSTK_TOP(info) \ ({ \ @@ -399,53 +344,8 @@ unsigned long get_wchan(struct task_struct *p); __regs__ - 1; \ }) -#define KSTK_EIP(task) (task_pt_regs(task)->ip) #define KSTK_ESP(task) (task_pt_regs(task)->sp) - -struct microcode_header { - unsigned int hdrver; - unsigned int rev; - unsigned int date; - unsigned int sig; - unsigned int cksum; - unsigned int ldrver; - unsigned int pf; - unsigned int datasize; - unsigned int totalsize; - unsigned int reserved[3]; -}; - -struct microcode { - struct microcode_header hdr; - unsigned int bits[0]; -}; - -typedef struct microcode microcode_t; -typedef struct microcode_header microcode_header_t; - -/* microcode format is extended from prescott processors */ -struct extended_signature { - unsigned int sig; - unsigned int pf; - unsigned int cksum; -}; - -struct extended_sigtable { - unsigned int count; - unsigned int cksum; - unsigned int reserved[3]; - struct extended_signature sigs[0]; -}; - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -#define cpu_relax() rep_nop() - static inline void native_load_sp0(struct tss_struct *tss, struct thread_struct *thread) { tss->x86_tss.sp0 = thread->sp0; @@ -555,7 +455,6 @@ static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread because they are microcoded there and very slow. However we don't do prefetches for pre XP Athlons currently That should be fixed. */ -#define ARCH_HAS_PREFETCH static inline void prefetch(const void *x) { alternative_input(ASM_NOP4, @@ -565,8 +464,6 @@ static inline void prefetch(const void *x) } #define ARCH_HAS_PREFETCH -#define ARCH_HAS_PREFETCHW -#define ARCH_HAS_SPINLOCK_PREFETCH /* 3dnow! prefetch to get an exclusive cache line. Useful for spinlocks to avoid one state transition in the cache coherency protocol. */ @@ -577,13 +474,7 @@ static inline void prefetchw(const void *x) X86_FEATURE_3DNOW, "r" (x)); } -#define spin_lock_prefetch(x) prefetchw(x) - -extern void select_idle_routine(const struct cpuinfo_x86 *c); -#define cache_line_size() (boot_cpu_data.x86_cache_alignment) - -extern unsigned long boot_option_idle_override; extern void enable_sep_cpu(void); extern int sysenter_setup(void); @@ -595,6 +486,4 @@ extern void switch_to_new_gdt(void); extern void cpu_init(void); extern void init_gdt(int cpu); -extern int force_mwait; - #endif /* __ASM_I386_PROCESSOR_H */ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 6abe1ba30fe..5f5c7fc6379 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -83,11 +83,6 @@ DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); extern char ignore_irq13; extern void identify_cpu(struct cpuinfo_x86 *); -extern void print_cpu_info(struct cpuinfo_x86 *); -extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); -extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); -extern unsigned short num_cache_leaves; - /* * User space process size. 47bits minus one guard page. @@ -102,8 +97,6 @@ extern unsigned short num_cache_leaves; #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64) #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) -#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE/3) - /* * Size of io_bitmap. */ @@ -226,68 +219,16 @@ struct thread_struct { set_fs(USER_DS); \ } while(0) -struct task_struct; -struct mm_struct; - -/* Free all resources held by a thread. */ -extern void release_thread(struct task_struct *); - -/* Prepare to copy thread state - unlazy all lazy status */ -extern void prepare_to_copy(struct task_struct *tsk); - -/* - * create a kernel thread without removing it from tasklists - */ -extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - /* * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork. */ #define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8)) -extern unsigned long get_wchan(struct task_struct *p); #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->ip) #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ -struct microcode_header { - unsigned int hdrver; - unsigned int rev; - unsigned int date; - unsigned int sig; - unsigned int cksum; - unsigned int ldrver; - unsigned int pf; - unsigned int datasize; - unsigned int totalsize; - unsigned int reserved[3]; -}; - -struct microcode { - struct microcode_header hdr; - unsigned int bits[0]; -}; - -typedef struct microcode microcode_t; -typedef struct microcode_header microcode_header_t; - -/* microcode format is extended from prescott processors */ -struct extended_signature { - unsigned int sig; - unsigned int pf; - unsigned int cksum; -}; - -struct extended_sigtable { - unsigned int count; - unsigned int cksum; - unsigned int reserved[3]; - struct extended_signature sigs[0]; -}; - - #if defined(CONFIG_MPSC) || defined(CONFIG_MCORE2) #define ASM_NOP1 P6_NOP1 #define ASM_NOP2 P6_NOP2 @@ -331,20 +272,6 @@ struct extended_sigtable { #define ASM_NOP_MAX 8 -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -/* Stop speculative execution */ -static inline void sync_core(void) -{ - int tmp; - asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory"); -} - -#define ARCH_HAS_PREFETCHW 1 static inline void prefetchw(void *x) { alternative_input("prefetcht0 (%1)", @@ -353,42 +280,6 @@ static inline void prefetchw(void *x) "r" (x)); } -#define ARCH_HAS_SPINLOCK_PREFETCH 1 - -#define spin_lock_prefetch(x) prefetchw(x) - -#define cpu_relax() rep_nop() - -static inline void __monitor(const void *eax, unsigned long ecx, - unsigned long edx) -{ - /* "monitor %eax,%ecx,%edx;" */ - asm volatile( - ".byte 0x0f,0x01,0xc8;" - : :"a" (eax), "c" (ecx), "d"(edx)); -} - -static inline void __mwait(unsigned long eax, unsigned long ecx) -{ - /* "mwait %eax,%ecx;" */ - asm volatile( - ".byte 0x0f,0x01,0xc9;" - : :"a" (eax), "c" (ecx)); -} - -static inline void __sti_mwait(unsigned long eax, unsigned long ecx) -{ - /* "mwait %eax,%ecx;" */ - asm volatile( - "sti; .byte 0x0f,0x01,0xc9;" - : :"a" (eax), "c" (ecx)); -} - -extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); - -extern int force_mwait; - -extern void select_idle_routine(const struct cpuinfo_x86 *c); #define stack_current() \ ({ \ @@ -397,12 +288,5 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c); ti->task; \ }) -#define cache_line_size() (boot_cpu_data.x86_cache_alignment) - -extern unsigned long boot_option_idle_override; -/* Boot loader type from the setup header */ -extern int bootloader_type; - -#define HAVE_ARCH_PICK_MMAP_LAYOUT 1 #endif /* __ASM_X86_64_PROCESSOR_H */ -- cgit v1.2.2 From 0ccb8acc51693a2aef0f38024943808046d81251 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:27 +0100 Subject: x86: unify current_text_addr current_text_addr() has a different implementation in x86_64 and i386, but it is not fundamentally different. I stick to the i386 implementation, that seem to be a common base, and move it to processor.h Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 11 +++++++++++ include/asm-x86/processor_32.h | 6 ------ include/asm-x86/processor_64.h | 6 ------ 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 52e3637ef59..3deb5ba55f5 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -10,6 +10,17 @@ struct mm_struct; #include #include +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +static inline void *current_text_addr(void) +{ + void *pc; + asm volatile("mov $1f,%0\n1:":"=r" (pc)); + return pc; +} + static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 9e119d3789b..6cd2149dcba 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -21,12 +21,6 @@ #include #include -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) - /* * CPU type and hardware bug flags. Kept separately for each CPU. * Members of this structure are referenced in head.S, so think twice diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 5f5c7fc6379..1984a4a38b7 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -20,12 +20,6 @@ #include #include -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ void *pc; asm volatile("leaq 1f(%%rip),%0\n1:":"=r"(pc)); pc; }) - /* * CPU type and hardware bug flags. Kept separately for each CPU. */ -- cgit v1.2.2 From ca241c75037b32e0216a68e39ad2801d04fa1f87 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:31 +0100 Subject: x86: unify tss_struct Although slighly different, the tss_struct is very similar in x86_64 and i386. The really different part, which matchs the hardware vision of it, is now called x86_hw_tss, and each of the architectures provides yours. It's then used as a field in the outter tss_struct. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/lguest.h | 2 +- include/asm-x86/processor.h | 77 ++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 62 ---------------------------------- include/asm-x86/processor_64.h | 35 +------------------ 4 files changed, 79 insertions(+), 97 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h index 3585a1628b5..1c8367a692f 100644 --- a/include/asm-x86/lguest.h +++ b/include/asm-x86/lguest.h @@ -51,7 +51,7 @@ struct lguest_ro_state /* Fields which are used when guest is running. */ struct desc_ptr guest_idt_desc; struct desc_ptr guest_gdt_desc; - struct i386_hw_tss guest_tss; + struct x86_hw_tss guest_tss; struct desc_struct guest_idt[IDT_ENTRIES]; struct desc_struct guest_gdt[GDT_ENTRIES]; }; diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 3deb5ba55f5..cede9ad3dc6 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -8,6 +8,7 @@ struct task_struct; struct mm_struct; #include +#include #include /* @@ -38,6 +39,82 @@ static inline void load_cr3(pgd_t *pgdir) write_cr3(__pa(pgdir)); } +#ifdef CONFIG_X86_32 +/* This is the TSS defined by the hardware. */ +struct x86_hw_tss { + unsigned short back_link, __blh; + unsigned long sp0; + unsigned short ss0, __ss0h; + unsigned long sp1; + unsigned short ss1, __ss1h; /* ss1 caches MSR_IA32_SYSENTER_CS */ + unsigned long sp2; + unsigned short ss2, __ss2h; + unsigned long __cr3; + unsigned long ip; + unsigned long flags; + unsigned long ax, cx, dx, bx; + unsigned long sp, bp, si, di; + unsigned short es, __esh; + unsigned short cs, __csh; + unsigned short ss, __ssh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; + unsigned short ldt, __ldth; + unsigned short trace, io_bitmap_base; +} __attribute__((packed)); +#else +struct x86_hw_tss { + u32 reserved1; + u64 sp0; + u64 sp1; + u64 sp2; + u64 reserved2; + u64 ist[7]; + u32 reserved3; + u32 reserved4; + u16 reserved5; + u16 io_bitmap_base; +} __attribute__((packed)) ____cacheline_aligned; +#endif + +/* + * Size of io_bitmap. + */ +#define IO_BITMAP_BITS 65536 +#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) +#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) +#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap) +#define INVALID_IO_BITMAP_OFFSET 0x8000 +#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000 + +struct tss_struct { + struct x86_hw_tss x86_tss; + + /* + * The extra 1 is there because the CPU will access an + * additional byte beyond the end of the IO permission + * bitmap. The extra byte must be all 1 bits, and must + * be within the limit. + */ + unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; + /* + * Cache the current maximum and the last task that used the bitmap: + */ + unsigned long io_bitmap_max; + struct thread_struct *io_bitmap_owner; + /* + * pads the TSS to be cacheline-aligned (size is 0x100) + */ + unsigned long __cacheline_filler[35]; + /* + * .. and then another 0x100 bytes for emergency kernel stack + */ + unsigned long stack[64]; +} __attribute__((packed)); + +DECLARE_PER_CPU(struct tss_struct, init_tss); + #ifdef CONFIG_X86_32 # include "processor_32.h" #else diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 6cd2149dcba..57b345bc3c7 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -81,7 +81,6 @@ struct cpuinfo_x86 { extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 new_cpu_data; extern struct tss_struct doublefault_tss; -DECLARE_PER_CPU(struct tss_struct, init_tss); #ifdef CONFIG_SMP DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); @@ -123,16 +122,6 @@ extern unsigned int mca_pentium_flag; #define TASK_SIZE (PAGE_OFFSET) -/* - * Size of io_bitmap. - */ -#define IO_BITMAP_BITS 65536 -#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) -#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) -#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) -#define INVALID_IO_BITMAP_OFFSET 0x8000 -#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000 - struct i387_fsave_struct { long cwd; long swd; @@ -185,57 +174,6 @@ typedef struct { unsigned long seg; } mm_segment_t; -struct thread_struct; - -/* This is the TSS defined by the hardware. */ -struct i386_hw_tss { - unsigned short back_link,__blh; - unsigned long sp0; - unsigned short ss0,__ss0h; - unsigned long sp1; - unsigned short ss1,__ss1h; /* ss1 is used to cache MSR_IA32_SYSENTER_CS */ - unsigned long sp2; - unsigned short ss2,__ss2h; - unsigned long __cr3; - unsigned long ip; - unsigned long flags; - unsigned long ax, cx, dx, bx; - unsigned long sp, bp, si, di; - unsigned short es, __esh; - unsigned short cs, __csh; - unsigned short ss, __ssh; - unsigned short ds, __dsh; - unsigned short fs, __fsh; - unsigned short gs, __gsh; - unsigned short ldt, __ldth; - unsigned short trace, io_bitmap_base; -} __attribute__((packed)); - -struct tss_struct { - struct i386_hw_tss x86_tss; - - /* - * The extra 1 is there because the CPU will access an - * additional byte beyond the end of the IO permission - * bitmap. The extra byte must be all 1 bits, and must - * be within the limit. - */ - unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; - /* - * Cache the current maximum and the last task that used the bitmap: - */ - unsigned long io_bitmap_max; - struct thread_struct *io_bitmap_owner; - /* - * pads the TSS to be cacheline-aligned (size is 0x100) - */ - unsigned long __cacheline_filler[35]; - /* - * .. and then another 0x100 bytes for emergency kernel stack - */ - unsigned long stack[64]; -} __attribute__((packed)); - #define ARCH_MIN_TASKALIGN 16 struct thread_struct { diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 1984a4a38b7..8d342c23ad1 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -91,14 +91,6 @@ extern void identify_cpu(struct cpuinfo_x86 *); #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64) #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) -/* - * Size of io_bitmap. - */ -#define IO_BITMAP_BITS 65536 -#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) -#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) -#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) -#define INVALID_IO_BITMAP_OFFSET 0x8000 struct i387_fxsave_struct { u16 cwd; @@ -118,32 +110,7 @@ union i387_union { struct i387_fxsave_struct fxsave; }; -struct tss_struct { - u32 reserved1; - u64 sp0; - u64 sp1; - u64 sp2; - u64 reserved2; - u64 ist[7]; - u32 reserved3; - u32 reserved4; - u16 reserved5; - u16 io_bitmap_base; - /* - * The extra 1 is there because the CPU will access an - * additional byte beyond the end of the IO permission - * bitmap. The extra byte must be all 1 bits, and must - * be within the limit. Thus we have: - * - * 128 bytes, the bitmap itself, for ports 0..0x3ff - * 8 bytes, for an extra "long" of ~0UL - */ - unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; -} __attribute__((packed)) ____cacheline_aligned; - - extern struct cpuinfo_x86 boot_cpu_data; -DECLARE_PER_CPU(struct tss_struct,init_tss); /* Save the original ist values for checking stack pointers during debugging */ struct orig_ist { unsigned long ist[7]; @@ -195,7 +162,7 @@ struct thread_struct { } #define INIT_TSS { \ - .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ + .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } #define INIT_MMAP \ -- cgit v1.2.2 From 7818a1e0294debee02d5135e17b89f28b8871887 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:31 +0100 Subject: x86: provide 64-bit with a load_sp0 function. Paravirt guests need to inform the underlying hypervisor whenever the sp0 tss field changes. i386 already has such a function, and we use it for x86_64 too. There's an unnecessary (for 64-bit) msr handling part in the original version, and it is placed around an ifdef. Making no more sense in processor_32.h, it is moved to the common header Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 22 +++++++++++++++++++++- include/asm-x86/processor_32.h | 20 -------------------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index cede9ad3dc6..b1ea5215636 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -193,8 +193,22 @@ static inline void native_set_iopl_mask(unsigned mask) #endif } +static inline void native_load_sp0(struct tss_struct *tss, + struct thread_struct *thread) +{ + tss->x86_tss.sp0 = thread->sp0; +#ifdef CONFIG_X86_32 + /* Only happens when SEP is enabled, no need to test "SEP"arately */ + if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { + tss->x86_tss.ss1 = thread->sysenter_cs; + wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); + } +#endif +} -#ifndef CONFIG_PARAVIRT +#ifdef CONFIG_PARAVIRT +#include +#else #define __cpuid native_cpuid #define paravirt_enabled() 0 @@ -206,6 +220,12 @@ static inline void native_set_iopl_mask(unsigned mask) #define set_debugreg(value, register) \ native_set_debugreg(register, value) +static inline void load_sp0(struct tss_struct *tss, + struct thread_struct *thread) +{ + native_load_sp0(tss, thread); +} + #define set_iopl_mask native_set_iopl_mask #endif /* CONFIG_PARAVIRT */ diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 57b345bc3c7..53037d1a6ae 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -278,26 +278,6 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); #define KSTK_ESP(task) (task_pt_regs(task)->sp) -static inline void native_load_sp0(struct tss_struct *tss, struct thread_struct *thread) -{ - tss->x86_tss.sp0 = thread->sp0; - /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { - tss->x86_tss.ss1 = thread->sysenter_cs; - wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); - } -} - -#ifdef CONFIG_PARAVIRT -#include -#else - -static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread) -{ - native_load_sp0(tss, thread); -} -#endif /* CONFIG_PARAVIRT */ - /* generic versions from gas */ #define GENERIC_NOP1 ".byte 0x90\n" #define GENERIC_NOP2 ".byte 0x89,0xf6\n" -- cgit v1.2.2 From cb38d377337cadd73fe4c582f77c5273685aeb71 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:31 +0100 Subject: x86: unify thread struct. The thread_struct is not fundamentally different between architectures, and this patch puts it in the common header. What's really unique for each of them is enclosed in ifdefs. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 44 ++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 37 ----------------------------------- include/asm-x86/processor_64.h | 32 ------------------------------ 3 files changed, 44 insertions(+), 69 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index b1ea5215636..0e82ad5a22a 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -126,6 +126,50 @@ extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); extern unsigned short num_cache_leaves; +struct thread_struct { +/* cached TLS descriptors. */ + struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; + unsigned long sp0; + unsigned long sp; +#ifdef CONFIG_X86_32 + unsigned long sysenter_cs; +#else + unsigned long usersp; /* Copy from PDA */ + unsigned short es, ds, fsindex, gsindex; +#endif + unsigned long ip; + unsigned long fs; + unsigned long gs; +/* Hardware debugging registers */ + unsigned long debugreg0; + unsigned long debugreg1; + unsigned long debugreg2; + unsigned long debugreg3; + unsigned long debugreg6; + unsigned long debugreg7; +/* fault info */ + unsigned long cr2, trap_no, error_code; +/* floating point info */ + union i387_union i387 __attribute__((aligned(16)));; +#ifdef CONFIG_X86_32 +/* virtual 86 mode info */ + struct vm86_struct __user *vm86_info; + unsigned long screen_bitmap; + unsigned long v86flags, v86mask, saved_sp0; + unsigned int saved_fs, saved_gs; +#endif +/* IO permissions */ + unsigned long *io_bitmap_ptr; + unsigned long iopl; +/* max allowed port in the bitmap, in bytes: */ + unsigned io_bitmap_max; +/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ + unsigned long debugctlmsr; +/* Debug Store - if not 0 points to a DS Save Area configuration; + * goes into MSR_IA32_DS_AREA */ + unsigned long ds_area_msr; +}; + static inline unsigned long native_get_debugreg(int regno) { unsigned long val = 0; /* Damn you, gcc! */ diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 53037d1a6ae..8cb05cec3cb 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -176,43 +176,6 @@ typedef struct { #define ARCH_MIN_TASKALIGN 16 -struct thread_struct { -/* cached TLS descriptors. */ - struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; - unsigned long sp0; - unsigned long sysenter_cs; - unsigned long ip; - unsigned long sp; - unsigned long fs; - unsigned long gs; -/* Hardware debugging registers */ - unsigned long debugreg0; - unsigned long debugreg1; - unsigned long debugreg2; - unsigned long debugreg3; - unsigned long debugreg6; - unsigned long debugreg7; -/* fault info */ - unsigned long cr2, trap_no, error_code; -/* floating point info */ - union i387_union i387; -/* virtual 86 mode info */ - struct vm86_struct __user * vm86_info; - unsigned long screen_bitmap; - unsigned long v86flags, v86mask, saved_sp0; - unsigned int saved_fs, saved_gs; -/* IO permissions */ - unsigned long *io_bitmap_ptr; - unsigned long iopl; -/* max allowed port in the bitmap, in bytes: */ - unsigned long io_bitmap_max; -/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ - unsigned long debugctlmsr; -/* Debug Store - if not 0 points to a DS Save Area configuration; - * goes into MSR_IA32_DS_AREA */ - unsigned long ds_area_msr; -}; - #define INIT_THREAD { \ .sp0 = sizeof(init_stack) + (long)&init_stack, \ .vm86_info = NULL, \ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 8d342c23ad1..4b4ec3d7991 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -125,38 +125,6 @@ DECLARE_PER_CPU(struct orig_ist, orig_ist); #define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif -struct thread_struct { - unsigned long sp0; - unsigned long sp; - unsigned long usersp; /* Copy from PDA */ - unsigned long fs; - unsigned long gs; - unsigned short es, ds, fsindex, gsindex; -/* Hardware debugging registers */ - unsigned long debugreg0; - unsigned long debugreg1; - unsigned long debugreg2; - unsigned long debugreg3; - unsigned long debugreg6; - unsigned long debugreg7; -/* fault info */ - unsigned long cr2, trap_no, error_code; -/* floating point info */ - union i387_union i387 __attribute__((aligned(16))); -/* IO permissions. the bitmap could be moved into the GDT, that would make - switch faster for a limited number of ioperm using tasks. -AK */ - int ioperm; - unsigned long *io_bitmap_ptr; - unsigned io_bitmap_max; -/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ - unsigned long debugctlmsr; -/* Debug Store - if not 0 points to a DS Save Area configuration; - * goes into MSR_IA32_DS_AREA */ - unsigned long ds_area_msr; -/* cached TLS descriptors. */ - struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; -} __attribute__((aligned(16))); - #define INIT_THREAD { \ .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } -- cgit v1.2.2 From dbcb4660246c240a159b4037067fdedb563a63cb Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:31 +0100 Subject: x86: unify TASK_ALIGN definitions This patch moves the TASK_ALIGN constraints to common header. The base of it is the same for x86_64 and i386. The only difference is the presence of vSMP in x86_64. As it's not a worry in i386, we can safely use the same code for both. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 8 ++++++++ include/asm-x86/processor_32.h | 1 - include/asm-x86/processor_64.h | 8 -------- 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 0e82ad5a22a..8b56c23f043 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -22,6 +22,14 @@ static inline void *current_text_addr(void) return pc; } +#ifdef CONFIG_X86_VSMP +#define ARCH_MIN_TASKALIGN (1 << INTERNODE_CACHE_SHIFT) +#define ARCH_MIN_MMSTRUCT_ALIGN (1 << INTERNODE_CACHE_SHIFT) +#else +#define ARCH_MIN_TASKALIGN 16 +#define ARCH_MIN_MMSTRUCT_ALIGN 0 +#endif + static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 8cb05cec3cb..8380243a19d 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -174,7 +174,6 @@ typedef struct { unsigned long seg; } mm_segment_t; -#define ARCH_MIN_TASKALIGN 16 #define INIT_THREAD { \ .sp0 = sizeof(init_stack) + (long)&init_stack, \ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 4b4ec3d7991..7fe5c1461c8 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -117,14 +117,6 @@ struct orig_ist { }; DECLARE_PER_CPU(struct orig_ist, orig_ist); -#ifdef CONFIG_X86_VSMP -#define ARCH_MIN_TASKALIGN (1 << INTERNODE_CACHE_SHIFT) -#define ARCH_MIN_MMSTRUCT_ALIGN (1 << INTERNODE_CACHE_SHIFT) -#else -#define ARCH_MIN_TASKALIGN 16 -#define ARCH_MIN_MMSTRUCT_ALIGN 0 -#endif - #define INIT_THREAD { \ .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } -- cgit v1.2.2 From 26996dd22b3cbc9dbe18cf908d2f844a116b6ec1 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:31 +0100 Subject: x86: change bitwise operations to get a void parameter. This patch changes the bitwise operations in bitops.h to get a void pointers as a parameter. Before this patch, a lot of warnings can be seen. They're gone after it. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/bitops.h | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index c6dd7e259b4..1a23ce1a569 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h @@ -43,7 +43,7 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static inline void set_bit(int nr, volatile unsigned long *addr) +static inline void set_bit(int nr, volatile void *addr) { asm volatile(LOCK_PREFIX "bts %1,%0" : ADDR @@ -59,7 +59,7 @@ static inline void set_bit(int nr, volatile unsigned long *addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static inline void __set_bit(int nr, volatile unsigned long *addr) +static inline void __set_bit(int nr, volatile void *addr) { asm volatile("bts %1,%0" : ADDR @@ -77,7 +77,7 @@ static inline void __set_bit(int nr, volatile unsigned long *addr) * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -static inline void clear_bit(int nr, volatile unsigned long *addr) +static inline void clear_bit(int nr, volatile void *addr) { asm volatile(LOCK_PREFIX "btr %1,%0" : ADDR @@ -92,13 +92,13 @@ static inline void clear_bit(int nr, volatile unsigned long *addr) * clear_bit() is atomic and implies release semantics before the memory * operation. It can be used for an unlock. */ -static inline void clear_bit_unlock(unsigned nr, volatile unsigned long *addr) +static inline void clear_bit_unlock(unsigned nr, volatile void *addr) { barrier(); clear_bit(nr, addr); } -static inline void __clear_bit(int nr, volatile unsigned long *addr) +static inline void __clear_bit(int nr, volatile void *addr) { asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); } @@ -115,7 +115,7 @@ static inline void __clear_bit(int nr, volatile unsigned long *addr) * No memory barrier is required here, because x86 cannot reorder stores past * older loads. Same principle as spin_unlock. */ -static inline void __clear_bit_unlock(unsigned nr, volatile unsigned long *addr) +static inline void __clear_bit_unlock(unsigned nr, volatile void *addr) { barrier(); __clear_bit(nr, addr); @@ -133,7 +133,7 @@ static inline void __clear_bit_unlock(unsigned nr, volatile unsigned long *addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static inline void __change_bit(int nr, volatile unsigned long *addr) +static inline void __change_bit(int nr, volatile void *addr) { asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); } @@ -147,7 +147,7 @@ static inline void __change_bit(int nr, volatile unsigned long *addr) * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static inline void change_bit(int nr, volatile unsigned long *addr) +static inline void change_bit(int nr, volatile void *addr) { asm volatile(LOCK_PREFIX "btc %1,%0" : ADDR : "Ir" (nr)); @@ -161,7 +161,7 @@ static inline void change_bit(int nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_set_bit(int nr, volatile unsigned long *addr) +static inline int test_and_set_bit(int nr, volatile void *addr) { int oldbit; @@ -180,7 +180,7 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr) * * This is the same as test_and_set_bit on x86. */ -static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) +static inline int test_and_set_bit_lock(int nr, volatile void *addr) { return test_and_set_bit(nr, addr); } @@ -194,7 +194,7 @@ static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) +static inline int __test_and_set_bit(int nr, volatile void *addr) { int oldbit; @@ -213,7 +213,7 @@ static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) +static inline int test_and_clear_bit(int nr, volatile void *addr) { int oldbit; @@ -234,7 +234,7 @@ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) +static inline int __test_and_clear_bit(int nr, volatile void *addr) { int oldbit; @@ -246,7 +246,7 @@ static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) } /* WARNING: non atomic and it can be reordered! */ -static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) +static inline int __test_and_change_bit(int nr, volatile void *addr) { int oldbit; @@ -266,7 +266,7 @@ static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_change_bit(int nr, volatile unsigned long *addr) +static inline int test_and_change_bit(int nr, volatile void *addr) { int oldbit; @@ -278,19 +278,20 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) return oldbit; } -static inline int constant_test_bit(int nr, const volatile unsigned long *addr) +static inline int constant_test_bit(int nr, const volatile void *addr) { - return ((1UL << (nr % BITS_PER_LONG)) & (addr[nr / BITS_PER_LONG])) != 0; + return ((1UL << (nr % BITS_PER_LONG)) & + (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; } -static inline int variable_test_bit(int nr, volatile const unsigned long *addr) +static inline int variable_test_bit(int nr, volatile const void *addr) { int oldbit; asm volatile("bt %2,%1\n\t" "sbb %0,%0" : "=r" (oldbit) - : "m" (*addr), "Ir" (nr)); + : "m" (*(unsigned long *)addr), "Ir" (nr)); return oldbit; } -- cgit v1.2.2 From 5300db887e251276eaab2801af297acf4b53b9eb Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:33 +0100 Subject: x86: unify x86_cpuinfo struct. x86_cpuinfo is one more to the family of "not fundamentally different" structs. It's unified in processor.h, with very specific fields enclosed around ifdefs. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 82 ++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 67 ---------------------------------- include/asm-x86/processor_64.h | 57 ----------------------------- 3 files changed, 82 insertions(+), 124 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 8b56c23f043..2b896b0aa3f 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -10,6 +10,9 @@ struct mm_struct; #include #include #include +#include +#include +#include /* * Default implementation of macro that returns current @@ -30,6 +33,85 @@ static inline void *current_text_addr(void) #define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif +/* + * CPU type and hardware bug flags. Kept separately for each CPU. + * Members of this structure are referenced in head.S, so think twice + * before touching them. [mj] + */ + +struct cpuinfo_x86 { + __u8 x86; /* CPU family */ + __u8 x86_vendor; /* CPU vendor */ + __u8 x86_model; + __u8 x86_mask; +#ifdef CONFIG_X86_32 + char wp_works_ok; /* It doesn't on 386's */ + char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */ + char hard_math; + char rfu; + char fdiv_bug; + char f00f_bug; + char coma_bug; + char pad0; +#else + /* number of 4K pages in DTLB/ITLB combined(in pages)*/ + int x86_tlbsize; + __u8 x86_virt_bits, x86_phys_bits; + /* cpuid returned core id bits */ + __u8 x86_coreid_bits; + /* Max extended CPUID function supported */ + __u32 extended_cpuid_level; +#endif + int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ + __u32 x86_capability[NCAPINTS]; + char x86_vendor_id[16]; + char x86_model_id[64]; + int x86_cache_size; /* in KB - valid for CPUS which support this + call */ + int x86_cache_alignment; /* In bytes */ + int x86_power; + unsigned long loops_per_jiffy; +#ifdef CONFIG_SMP + cpumask_t llc_shared_map; /* cpus sharing the last level cache */ +#endif + unsigned char x86_max_cores; /* cpuid returned max cores value */ + unsigned char apicid; + unsigned short x86_clflush_size; +#ifdef CONFIG_SMP + unsigned char booted_cores; /* number of cores as seen by OS */ + __u8 phys_proc_id; /* Physical processor id. */ + __u8 cpu_core_id; /* Core id */ + __u8 cpu_index; /* index into per_cpu list */ +#endif +} __attribute__((__aligned__(SMP_CACHE_BYTES))); + +#define X86_VENDOR_INTEL 0 +#define X86_VENDOR_CYRIX 1 +#define X86_VENDOR_AMD 2 +#define X86_VENDOR_UMC 3 +#define X86_VENDOR_NEXGEN 4 +#define X86_VENDOR_CENTAUR 5 +#define X86_VENDOR_TRANSMETA 7 +#define X86_VENDOR_NSC 8 +#define X86_VENDOR_NUM 9 +#define X86_VENDOR_UNKNOWN 0xff + +extern struct cpuinfo_x86 boot_cpu_data; + +#ifdef CONFIG_SMP +DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); +#define cpu_data(cpu) per_cpu(cpu_info, cpu) +#define current_cpu_data cpu_data(smp_processor_id()) +#else +#define cpu_data(cpu) boot_cpu_data +#define current_cpu_data boot_cpu_data +#endif + +extern void print_cpu_info(struct cpuinfo_x86 *); +extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); +extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); +extern unsigned short num_cache_leaves; + static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 8380243a19d..f0f7ca48444 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -14,83 +14,16 @@ #include #include #include -#include #include -#include -#include #include #include -/* - * CPU type and hardware bug flags. Kept separately for each CPU. - * Members of this structure are referenced in head.S, so think twice - * before touching them. [mj] - */ - -struct cpuinfo_x86 { - __u8 x86; /* CPU family */ - __u8 x86_vendor; /* CPU vendor */ - __u8 x86_model; - __u8 x86_mask; - char wp_works_ok; /* It doesn't on 386's */ - char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */ - char hard_math; - char rfu; - int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ - unsigned long x86_capability[NCAPINTS]; - char x86_vendor_id[16]; - char x86_model_id[64]; - int x86_cache_size; /* in KB - valid for CPUS which support this - call */ - int x86_cache_alignment; /* In bytes */ - char fdiv_bug; - char f00f_bug; - char coma_bug; - char pad0; - int x86_power; - unsigned long loops_per_jiffy; -#ifdef CONFIG_SMP - cpumask_t llc_shared_map; /* cpus sharing the last level cache */ -#endif - unsigned char x86_max_cores; /* cpuid returned max cores value */ - unsigned char apicid; - unsigned short x86_clflush_size; -#ifdef CONFIG_SMP - unsigned char booted_cores; /* number of cores as seen by OS */ - __u8 phys_proc_id; /* Physical processor id. */ - __u8 cpu_core_id; /* Core id */ - __u8 cpu_index; /* index into per_cpu list */ -#endif -} __attribute__((__aligned__(SMP_CACHE_BYTES))); - -#define X86_VENDOR_INTEL 0 -#define X86_VENDOR_CYRIX 1 -#define X86_VENDOR_AMD 2 -#define X86_VENDOR_UMC 3 -#define X86_VENDOR_NEXGEN 4 -#define X86_VENDOR_CENTAUR 5 -#define X86_VENDOR_TRANSMETA 7 -#define X86_VENDOR_NSC 8 -#define X86_VENDOR_NUM 9 -#define X86_VENDOR_UNKNOWN 0xff - /* * capabilities of CPUs */ - -extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 new_cpu_data; extern struct tss_struct doublefault_tss; -#ifdef CONFIG_SMP -DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); -#define cpu_data(cpu) per_cpu(cpu_info, cpu) -#define current_cpu_data cpu_data(smp_processor_id()) -#else -#define cpu_data(cpu) boot_cpu_data -#define current_cpu_data boot_cpu_data -#endif - /* * the following now lives in the per cpu area: * extern int cpu_llc_id[NR_CPUS]; diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 7fe5c1461c8..5045abe91e3 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -15,65 +15,9 @@ #include #include #include -#include #include -#include #include -/* - * CPU type and hardware bug flags. Kept separately for each CPU. - */ - -struct cpuinfo_x86 { - __u8 x86; /* CPU family */ - __u8 x86_vendor; /* CPU vendor */ - __u8 x86_model; - __u8 x86_mask; - int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ - __u32 x86_capability[NCAPINTS]; - char x86_vendor_id[16]; - char x86_model_id[64]; - int x86_cache_size; /* in KB */ - int x86_clflush_size; - int x86_cache_alignment; - int x86_tlbsize; /* number of 4K pages in DTLB/ITLB combined(in pages)*/ - __u8 x86_virt_bits, x86_phys_bits; - __u8 x86_max_cores; /* cpuid returned max cores value */ - __u8 x86_coreid_bits; /* cpuid returned core id bits */ - __u32 x86_power; - __u32 extended_cpuid_level; /* Max extended CPUID function supported */ - unsigned long loops_per_jiffy; -#ifdef CONFIG_SMP - cpumask_t llc_shared_map; /* cpus sharing the last level cache */ -#endif - __u8 apicid; -#ifdef CONFIG_SMP - __u8 booted_cores; /* number of cores as seen by OS */ - __u8 phys_proc_id; /* Physical Processor id. */ - __u8 cpu_core_id; /* Core id. */ - __u8 cpu_index; /* index into per_cpu list */ -#endif -} ____cacheline_aligned; - -#define X86_VENDOR_INTEL 0 -#define X86_VENDOR_CYRIX 1 -#define X86_VENDOR_AMD 2 -#define X86_VENDOR_UMC 3 -#define X86_VENDOR_NEXGEN 4 -#define X86_VENDOR_CENTAUR 5 -#define X86_VENDOR_TRANSMETA 7 -#define X86_VENDOR_NUM 8 -#define X86_VENDOR_UNKNOWN 0xff - -#ifdef CONFIG_SMP -DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); -#define cpu_data(cpu) per_cpu(cpu_info, cpu) -#define current_cpu_data cpu_data(smp_processor_id()) -#else -#define cpu_data(cpu) boot_cpu_data -#define current_cpu_data boot_cpu_data -#endif - extern char ignore_irq13; extern void identify_cpu(struct cpuinfo_x86 *); @@ -110,7 +54,6 @@ union i387_union { struct i387_fxsave_struct fxsave; }; -extern struct cpuinfo_x86 boot_cpu_data; /* Save the original ist values for checking stack pointers during debugging */ struct orig_ist { unsigned long ist[7]; -- cgit v1.2.2 From 2c1c468a382e64afccacdfe03fa4c0615cd4264f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:37 +0100 Subject: x86: remove legacy stuff from processor_64.h This patch removes definitions and macros that are not used anymore from processor_64.h Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_64.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 5045abe91e3..bfc4ce6e2f0 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -18,8 +18,6 @@ #include #include -extern char ignore_irq13; - extern void identify_cpu(struct cpuinfo_x86 *); /* @@ -68,9 +66,6 @@ DECLARE_PER_CPU(struct orig_ist, orig_ist); .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } -#define INIT_MMAP \ -{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } - #define start_thread(regs,new_rip,new_rsp) do { \ asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \ load_gs_index(0); \ @@ -144,13 +139,4 @@ static inline void prefetchw(void *x) "r" (x)); } - -#define stack_current() \ -({ \ - struct thread_info *ti; \ - asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ - ti->task; \ -}) - - #endif /* __ASM_X86_64_PROCESSOR_H */ -- cgit v1.2.2 From fc87e9061a5635fe1b367dad95498846dd5eda31 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:38 +0100 Subject: x86: unify mm_segment_t definition This patch moves the mm_segment_t structure definition to processor.h This makes mmsegment.h file useless, and it is deleted. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mmsegment.h | 8 -------- include/asm-x86/processor.h | 5 +++++ include/asm-x86/processor_32.h | 5 ----- include/asm-x86/processor_64.h | 1 - include/asm-x86/thread_info_64.h | 2 +- 5 files changed, 6 insertions(+), 15 deletions(-) delete mode 100644 include/asm-x86/mmsegment.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/mmsegment.h b/include/asm-x86/mmsegment.h deleted file mode 100644 index d3f80c99633..00000000000 --- a/include/asm-x86/mmsegment.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _ASM_MMSEGMENT_H -#define _ASM_MMSEGMENT_H 1 - -typedef struct { - unsigned long seg; -} mm_segment_t; - -#endif diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 2b896b0aa3f..87466b6d3b9 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -424,6 +424,11 @@ struct extended_sigtable { struct extended_signature sigs[0]; }; +typedef struct { + unsigned long seg; +} mm_segment_t; + + /* * create a kernel thread without removing it from tasklists */ diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index f0f7ca48444..fa921aa1a93 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -103,11 +103,6 @@ union i387_union { struct i387_soft_struct soft; }; -typedef struct { - unsigned long seg; -} mm_segment_t; - - #define INIT_THREAD { \ .sp0 = sizeof(init_stack) + (long)&init_stack, \ .vm86_info = NULL, \ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index bfc4ce6e2f0..1a258749b7c 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h index c2911a99cc3..9b531ea015a 100644 --- a/include/asm-x86/thread_info_64.h +++ b/include/asm-x86/thread_info_64.h @@ -21,7 +21,7 @@ #ifndef __ASSEMBLY__ struct task_struct; struct exec_domain; -#include +#include struct thread_info { struct task_struct *task; /* main task structure */ -- cgit v1.2.2 From 1a53905adddf6cc6d795bd7e988c60a19773f72e Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:39 +0100 Subject: x86: move definitions to processor.h This patch moves definitions that are present in only one of the files (between processor_32.h and processor_64.h), to processor.h. They're mostly structures and function definitions. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 41 +++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 35 ----------------------------------- include/asm-x86/processor_64.h | 6 ------ 3 files changed, 41 insertions(+), 41 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 87466b6d3b9..c6b749a018a 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -96,7 +96,12 @@ struct cpuinfo_x86 { #define X86_VENDOR_NUM 9 #define X86_VENDOR_UNKNOWN 0xff +/* + * capabilities of CPUs + */ extern struct cpuinfo_x86 boot_cpu_data; +extern struct cpuinfo_x86 new_cpu_data; +extern struct tss_struct doublefault_tss; #ifdef CONFIG_SMP DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); @@ -107,11 +112,22 @@ DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); #define current_cpu_data boot_cpu_data #endif +void 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 void init_scattered_cpuid_features(struct cpuinfo_x86 *c); extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); extern unsigned short num_cache_leaves; +#if defined(CONFIG_X86_HT) || defined(CONFIG_X86_64) +extern void detect_ht(struct cpuinfo_x86 *c); +#else +static inline void detect_ht(struct cpuinfo_x86 *c) {} +#endif + static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { @@ -205,6 +221,11 @@ struct tss_struct { DECLARE_PER_CPU(struct tss_struct, init_tss); +/* Save the original ist values for checking stack pointers during debugging */ +struct orig_ist { + unsigned long ist[7]; +}; + #ifdef CONFIG_X86_32 # include "processor_32.h" #else @@ -547,8 +568,28 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c); extern unsigned long boot_option_idle_override; +extern void enable_sep_cpu(void); +extern int sysenter_setup(void); + +/* Defined in head.S */ +extern struct desc_ptr early_gdt_descr; + +extern void cpu_set_gdt(int); +extern void switch_to_new_gdt(void); +extern void cpu_init(void); +extern void init_gdt(int cpu); + +/* from system description table in BIOS. Mostly for MCA use, but + * others may find it useful. */ +extern unsigned int machine_id; +extern unsigned int machine_submodel_id; +extern unsigned int BIOS_revision; +extern unsigned int mca_pentium_flag; + /* Boot loader type from the setup header */ extern int bootloader_type; + +extern char ignore_fpu_irq; #define cache_line_size() (boot_cpu_data.x86_cache_alignment) #define HAVE_ARCH_PICK_MMAP_LAYOUT 1 diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index fa921aa1a93..84a4c5e47d5 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -18,36 +18,12 @@ #include #include -/* - * capabilities of CPUs - */ -extern struct cpuinfo_x86 new_cpu_data; -extern struct tss_struct doublefault_tss; /* * the following now lives in the per cpu area: * extern int cpu_llc_id[NR_CPUS]; */ DECLARE_PER_CPU(u8, cpu_llc_id); -extern char ignore_fpu_irq; - -void __init cpu_detect(struct cpuinfo_x86 *c); - -extern void identify_boot_cpu(void); -extern void identify_secondary_cpu(struct cpuinfo_x86 *); - -#ifdef CONFIG_X86_HT -extern void detect_ht(struct cpuinfo_x86 *c); -#else -static inline void detect_ht(struct cpuinfo_x86 *c) {} -#endif - -/* from system description table in BIOS. Mostly for MCA use, but -others may find it useful. */ -extern unsigned int machine_id; -extern unsigned int machine_submodel_id; -extern unsigned int BIOS_revision; -extern unsigned int mca_pentium_flag; /* * User space process size: 3GB (default). @@ -277,15 +253,4 @@ static inline void prefetchw(const void *x) "r" (x)); } -extern void enable_sep_cpu(void); -extern int sysenter_setup(void); - -/* Defined in head.S */ -extern struct desc_ptr early_gdt_descr; - -extern void cpu_set_gdt(int); -extern void switch_to_new_gdt(void); -extern void cpu_init(void); -extern void init_gdt(int cpu); - #endif /* __ASM_I386_PROCESSOR_H */ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 1a258749b7c..45e382989b3 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -17,8 +17,6 @@ #include #include -extern void identify_cpu(struct cpuinfo_x86 *); - /* * User space process size. 47bits minus one guard page. */ @@ -51,10 +49,6 @@ union i387_union { struct i387_fxsave_struct fxsave; }; -/* Save the original ist values for checking stack pointers during debugging */ -struct orig_ist { - unsigned long ist[7]; -}; DECLARE_PER_CPU(struct orig_ist, orig_ist); #define INIT_THREAD { \ -- cgit v1.2.2 From ae2e15eb3b6c2a011bee615470bf52d2beb99a4b Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:40 +0100 Subject: x86: unify prefetch operations This patch moves the prefetch[w]? functions to processor.h Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 30 ++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 25 ------------------------- include/asm-x86/processor_64.h | 8 -------- 3 files changed, 30 insertions(+), 33 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index c6b749a018a..bfac9739f57 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -596,6 +596,36 @@ extern char ignore_fpu_irq; #define ARCH_HAS_PREFETCHW #define ARCH_HAS_SPINLOCK_PREFETCH +#ifdef CONFIG_X86_32 +#define BASE_PREFETCH ASM_NOP4 +#define ARCH_HAS_PREFETCH +#else +#define BASE_PREFETCH "prefetcht0 (%1)" +#endif + +/* Prefetch instructions for Pentium III and AMD Athlon */ +/* It's not worth to care about 3dnow! prefetches for the K6 + because they are microcoded there and very slow. + However we don't do prefetches for pre XP Athlons currently + That should be fixed. */ +static inline void prefetch(const void *x) +{ + alternative_input(BASE_PREFETCH, + "prefetchnta (%1)", + X86_FEATURE_XMM, + "r" (x)); +} + +/* 3dnow! prefetch to get an exclusive cache line. Useful for + spinlocks to avoid one state transition in the cache coherency protocol. */ +static inline void prefetchw(const void *x) +{ + alternative_input(BASE_PREFETCH, + "prefetchw (%1)", + X86_FEATURE_3DNOW, + "r" (x)); +} + #define spin_lock_prefetch(x) prefetchw(x) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 84a4c5e47d5..61a9cae2364 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -228,29 +228,4 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); #define ASM_NOP_MAX 8 -/* Prefetch instructions for Pentium III and AMD Athlon */ -/* It's not worth to care about 3dnow! prefetches for the K6 - because they are microcoded there and very slow. - However we don't do prefetches for pre XP Athlons currently - That should be fixed. */ -static inline void prefetch(const void *x) -{ - alternative_input(ASM_NOP4, - "prefetchnta (%1)", - X86_FEATURE_XMM, - "r" (x)); -} - -#define ARCH_HAS_PREFETCH - -/* 3dnow! prefetch to get an exclusive cache line. Useful for - spinlocks to avoid one state transition in the cache coherency protocol. */ -static inline void prefetchw(const void *x) -{ - alternative_input(ASM_NOP4, - "prefetchw (%1)", - X86_FEATURE_3DNOW, - "r" (x)); -} - #endif /* __ASM_I386_PROCESSOR_H */ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 45e382989b3..08b965124b9 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -124,12 +124,4 @@ DECLARE_PER_CPU(struct orig_ist, orig_ist); #define ASM_NOP_MAX 8 -static inline void prefetchw(void *x) -{ - alternative_input("prefetcht0 (%1)", - "prefetchw (%1)", - X86_FEATURE_3DNOW, - "r" (x)); -} - #endif /* __ASM_X86_64_PROCESSOR_H */ -- cgit v1.2.2 From ea5e3593a493298c69b8c4a958628feace930478 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:40 +0100 Subject: x86: unify asm nops There's only one difference between the NOPs used in asm code for i386 and x86_64: i386 has a lot more variants. The code is moved to processor.h, and adjusted accordingly. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 85 ++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 85 ------------------------------------------ include/asm-x86/processor_64.h | 44 ---------------------- 3 files changed, 85 insertions(+), 129 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index bfac9739f57..a8f1702ec3b 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -592,6 +592,91 @@ extern int bootloader_type; extern char ignore_fpu_irq; #define cache_line_size() (boot_cpu_data.x86_cache_alignment) +/* generic versions from gas */ +#define GENERIC_NOP1 ".byte 0x90\n" +#define GENERIC_NOP2 ".byte 0x89,0xf6\n" +#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" +#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" +#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 +#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 + +/* Opteron nops */ +#define K8_NOP1 GENERIC_NOP1 +#define K8_NOP2 ".byte 0x66,0x90\n" +#define K8_NOP3 ".byte 0x66,0x66,0x90\n" +#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" +#define K8_NOP5 K8_NOP3 K8_NOP2 +#define K8_NOP6 K8_NOP3 K8_NOP3 +#define K8_NOP7 K8_NOP4 K8_NOP3 +#define K8_NOP8 K8_NOP4 K8_NOP4 + +/* K7 nops */ +/* uses eax dependencies (arbitary choice) */ +#define K7_NOP1 GENERIC_NOP1 +#define K7_NOP2 ".byte 0x8b,0xc0\n" +#define K7_NOP3 ".byte 0x8d,0x04,0x20\n" +#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" +#define K7_NOP5 K7_NOP4 ASM_NOP1 +#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" +#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" +#define K7_NOP8 K7_NOP7 ASM_NOP1 + +/* P6 nops */ +/* uses eax dependencies (Intel-recommended choice) */ +#define P6_NOP1 GENERIC_NOP1 +#define P6_NOP2 ".byte 0x66,0x90\n" +#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" +#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" +#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" +#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" +#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" +#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" + +#ifdef CONFIG_MK7 +#define ASM_NOP1 K7_NOP1 +#define ASM_NOP2 K7_NOP2 +#define ASM_NOP3 K7_NOP3 +#define ASM_NOP4 K7_NOP4 +#define ASM_NOP5 K7_NOP5 +#define ASM_NOP6 K7_NOP6 +#define ASM_NOP7 K7_NOP7 +#define ASM_NOP8 K7_NOP8 +#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \ + defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \ + defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4) || \ + defined(CONFIG_MPSC) +#define ASM_NOP1 P6_NOP1 +#define ASM_NOP2 P6_NOP2 +#define ASM_NOP3 P6_NOP3 +#define ASM_NOP4 P6_NOP4 +#define ASM_NOP5 P6_NOP5 +#define ASM_NOP6 P6_NOP6 +#define ASM_NOP7 P6_NOP7 +#define ASM_NOP8 P6_NOP8 +#elif defined(CONFIG_MK8) || defined(CONFIG_X86_64) +#define ASM_NOP1 K8_NOP1 +#define ASM_NOP2 K8_NOP2 +#define ASM_NOP3 K8_NOP3 +#define ASM_NOP4 K8_NOP4 +#define ASM_NOP5 K8_NOP5 +#define ASM_NOP6 K8_NOP6 +#define ASM_NOP7 K8_NOP7 +#define ASM_NOP8 K8_NOP8 +#else +#define ASM_NOP1 GENERIC_NOP1 +#define ASM_NOP2 GENERIC_NOP2 +#define ASM_NOP3 GENERIC_NOP3 +#define ASM_NOP4 GENERIC_NOP4 +#define ASM_NOP5 GENERIC_NOP5 +#define ASM_NOP6 GENERIC_NOP6 +#define ASM_NOP7 GENERIC_NOP7 +#define ASM_NOP8 GENERIC_NOP8 +#endif + +#define ASM_NOP_MAX 8 + #define HAVE_ARCH_PICK_MMAP_LAYOUT 1 #define ARCH_HAS_PREFETCHW #define ARCH_HAS_SPINLOCK_PREFETCH diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 61a9cae2364..82fafabbfe7 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -18,7 +18,6 @@ #include #include - /* * the following now lives in the per cpu area: * extern int cpu_llc_id[NR_CPUS]; @@ -144,88 +143,4 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); #define KSTK_ESP(task) (task_pt_regs(task)->sp) -/* generic versions from gas */ -#define GENERIC_NOP1 ".byte 0x90\n" -#define GENERIC_NOP2 ".byte 0x89,0xf6\n" -#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" -#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" -#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 -#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 - -/* Opteron nops */ -#define K8_NOP1 GENERIC_NOP1 -#define K8_NOP2 ".byte 0x66,0x90\n" -#define K8_NOP3 ".byte 0x66,0x66,0x90\n" -#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" -#define K8_NOP5 K8_NOP3 K8_NOP2 -#define K8_NOP6 K8_NOP3 K8_NOP3 -#define K8_NOP7 K8_NOP4 K8_NOP3 -#define K8_NOP8 K8_NOP4 K8_NOP4 - -/* K7 nops */ -/* uses eax dependencies (arbitary choice) */ -#define K7_NOP1 GENERIC_NOP1 -#define K7_NOP2 ".byte 0x8b,0xc0\n" -#define K7_NOP3 ".byte 0x8d,0x04,0x20\n" -#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" -#define K7_NOP5 K7_NOP4 ASM_NOP1 -#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" -#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" -#define K7_NOP8 K7_NOP7 ASM_NOP1 - -/* P6 nops */ -/* uses eax dependencies (Intel-recommended choice) */ -#define P6_NOP1 GENERIC_NOP1 -#define P6_NOP2 ".byte 0x66,0x90\n" -#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" -#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" -#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" -#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" -#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" -#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" - -#ifdef CONFIG_MK8 -#define ASM_NOP1 K8_NOP1 -#define ASM_NOP2 K8_NOP2 -#define ASM_NOP3 K8_NOP3 -#define ASM_NOP4 K8_NOP4 -#define ASM_NOP5 K8_NOP5 -#define ASM_NOP6 K8_NOP6 -#define ASM_NOP7 K8_NOP7 -#define ASM_NOP8 K8_NOP8 -#elif defined(CONFIG_MK7) -#define ASM_NOP1 K7_NOP1 -#define ASM_NOP2 K7_NOP2 -#define ASM_NOP3 K7_NOP3 -#define ASM_NOP4 K7_NOP4 -#define ASM_NOP5 K7_NOP5 -#define ASM_NOP6 K7_NOP6 -#define ASM_NOP7 K7_NOP7 -#define ASM_NOP8 K7_NOP8 -#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \ - defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \ - defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4) -#define ASM_NOP1 P6_NOP1 -#define ASM_NOP2 P6_NOP2 -#define ASM_NOP3 P6_NOP3 -#define ASM_NOP4 P6_NOP4 -#define ASM_NOP5 P6_NOP5 -#define ASM_NOP6 P6_NOP6 -#define ASM_NOP7 P6_NOP7 -#define ASM_NOP8 P6_NOP8 -#else -#define ASM_NOP1 GENERIC_NOP1 -#define ASM_NOP2 GENERIC_NOP2 -#define ASM_NOP3 GENERIC_NOP3 -#define ASM_NOP4 GENERIC_NOP4 -#define ASM_NOP5 GENERIC_NOP5 -#define ASM_NOP6 GENERIC_NOP6 -#define ASM_NOP7 GENERIC_NOP7 -#define ASM_NOP8 GENERIC_NOP8 -#endif - -#define ASM_NOP_MAX 8 - #endif /* __ASM_I386_PROCESSOR_H */ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 08b965124b9..86fc2dcc868 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -80,48 +80,4 @@ DECLARE_PER_CPU(struct orig_ist, orig_ist); #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ - -#if defined(CONFIG_MPSC) || defined(CONFIG_MCORE2) -#define ASM_NOP1 P6_NOP1 -#define ASM_NOP2 P6_NOP2 -#define ASM_NOP3 P6_NOP3 -#define ASM_NOP4 P6_NOP4 -#define ASM_NOP5 P6_NOP5 -#define ASM_NOP6 P6_NOP6 -#define ASM_NOP7 P6_NOP7 -#define ASM_NOP8 P6_NOP8 -#else -#define ASM_NOP1 K8_NOP1 -#define ASM_NOP2 K8_NOP2 -#define ASM_NOP3 K8_NOP3 -#define ASM_NOP4 K8_NOP4 -#define ASM_NOP5 K8_NOP5 -#define ASM_NOP6 K8_NOP6 -#define ASM_NOP7 K8_NOP7 -#define ASM_NOP8 K8_NOP8 -#endif - -/* Opteron nops */ -#define K8_NOP1 ".byte 0x90\n" -#define K8_NOP2 ".byte 0x66,0x90\n" -#define K8_NOP3 ".byte 0x66,0x66,0x90\n" -#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" -#define K8_NOP5 K8_NOP3 K8_NOP2 -#define K8_NOP6 K8_NOP3 K8_NOP3 -#define K8_NOP7 K8_NOP4 K8_NOP3 -#define K8_NOP8 K8_NOP4 K8_NOP4 - -/* P6 nops */ -/* uses eax dependencies (Intel-recommended choice) */ -#define P6_NOP1 ".byte 0x90\n" -#define P6_NOP2 ".byte 0x66,0x90\n" -#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" -#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" -#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" -#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" -#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" -#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" - -#define ASM_NOP_MAX 8 - #endif /* __ASM_X86_64_PROCESSOR_H */ -- cgit v1.2.2 From 46265df040533f57c191bb2b019d6b25c3bf1f34 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:41 +0100 Subject: x86: move i387 definitions to processor.h This patch moves i387 definitions from processor_32.h and processor_64.h to processor.h. They are different. Very different. And there's appearently nothing we can do about it, so they're enclosed inside ifdefs. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 66 ++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 49 ------------------------------- include/asm-x86/processor_64.h | 17 ----------- 3 files changed, 66 insertions(+), 66 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index a8f1702ec3b..80c50020ef6 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -227,8 +227,74 @@ struct orig_ist { }; #ifdef CONFIG_X86_32 +struct i387_fsave_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + long status; /* software status information */ +}; + +struct i387_fxsave_struct { + unsigned short cwd; + unsigned short swd; + unsigned short twd; + unsigned short fop; + long fip; + long fcs; + long foo; + long fos; + long mxcsr; + long mxcsr_mask; + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + long padding[56]; +} __attribute__((aligned(16))); + +struct i387_soft_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + unsigned char ftop, changed, lookahead, no_update, rm, alimit; + struct info *info; + unsigned long entry_eip; +}; + +union i387_union { + struct i387_fsave_struct fsave; + struct i387_fxsave_struct fxsave; + struct i387_soft_struct soft; +}; + # include "processor_32.h" #else +struct i387_fxsave_struct { + u16 cwd; + u16 swd; + u16 twd; + u16 fop; + u64 rip; + u64 rdp; + u32 mxcsr; + u32 mxcsr_mask; + u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */ + u32 padding[24]; +} __attribute__((aligned(16))); + +union i387_union { + struct i387_fxsave_struct fxsave; +}; + # include "processor_64.h" #endif diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 82fafabbfe7..0d6a430b2bc 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -29,55 +29,6 @@ DECLARE_PER_CPU(u8, cpu_llc_id); */ #define TASK_SIZE (PAGE_OFFSET) - -struct i387_fsave_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ - long status; /* software status information */ -}; - -struct i387_fxsave_struct { - unsigned short cwd; - unsigned short swd; - unsigned short twd; - unsigned short fop; - long fip; - long fcs; - long foo; - long fos; - long mxcsr; - long mxcsr_mask; - long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ - long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ - long padding[56]; -} __attribute__ ((aligned (16))); - -struct i387_soft_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ - unsigned char ftop, changed, lookahead, no_update, rm, alimit; - struct info *info; - unsigned long entry_eip; -}; - -union i387_union { - struct i387_fsave_struct fsave; - struct i387_fxsave_struct fxsave; - struct i387_soft_struct soft; -}; - #define INIT_THREAD { \ .sp0 = sizeof(init_stack) + (long)&init_stack, \ .vm86_info = NULL, \ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 86fc2dcc868..04ce823ea7e 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -31,23 +31,6 @@ #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) -struct i387_fxsave_struct { - u16 cwd; - u16 swd; - u16 twd; - u16 fop; - u64 rip; - u64 rdp; - u32 mxcsr; - u32 mxcsr_mask; - u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ - u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */ - u32 padding[24]; -} __attribute__ ((aligned (16))); - -union i387_union { - struct i387_fxsave_struct fxsave; -}; DECLARE_PER_CPU(struct orig_ist, orig_ist); -- cgit v1.2.2 From 85f2adf16955460c98131360f3d76aeb51aba073 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:31:42 +0100 Subject: x86: use helper in fault_64.c Use the fixup_exception() helper in fault_64.c Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/uaccess_64.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index f4ce8768ad4..31d79470271 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -65,6 +65,8 @@ struct exception_table_entry unsigned long insn, fixup; }; +extern int fixup_exception(struct pt_regs *regs); + #define ARCH_HAS_SEARCH_EXTABLE /* -- cgit v1.2.2 From 0ddc9cc8fdfe3df7a90557e66069e3da2c584725 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 18 Dec 2007 03:58:10 -0800 Subject: x86: unify module_{32|64}.h This adds one case to the MODULE_PROC_FAMILY block testing for X86_64. There are no new things defined on X86_64 than there were before. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/module.h | 81 +++++++++++++++++++++++++++++++++++++++++++-- include/asm-x86/module_32.h | 75 ----------------------------------------- include/asm-x86/module_64.h | 10 ------ 3 files changed, 79 insertions(+), 87 deletions(-) delete mode 100644 include/asm-x86/module_32.h delete mode 100644 include/asm-x86/module_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/module.h b/include/asm-x86/module.h index 2b2f18d8a53..bfedb247871 100644 --- a/include/asm-x86/module.h +++ b/include/asm-x86/module.h @@ -1,5 +1,82 @@ +#ifndef _ASM_MODULE_H +#define _ASM_MODULE_H + +/* x86_32/64 are simple */ +struct mod_arch_specific {}; + #ifdef CONFIG_X86_32 -# include "module_32.h" +# define Elf_Shdr Elf32_Shdr +# define Elf_Sym Elf32_Sym +# define Elf_Ehdr Elf32_Ehdr #else -# include "module_64.h" +# define Elf_Shdr Elf64_Shdr +# define Elf_Sym Elf64_Sym +# define Elf_Ehdr Elf64_Ehdr #endif + +#ifdef CONFIG_X86_64 +/* X86_64 does not define MODULE_PROC_FAMILY */ +#elif defined CONFIG_M386 +#define MODULE_PROC_FAMILY "386 " +#elif defined CONFIG_M486 +#define MODULE_PROC_FAMILY "486 " +#elif defined CONFIG_M586 +#define MODULE_PROC_FAMILY "586 " +#elif defined CONFIG_M586TSC +#define MODULE_PROC_FAMILY "586TSC " +#elif defined CONFIG_M586MMX +#define MODULE_PROC_FAMILY "586MMX " +#elif defined CONFIG_MCORE2 +#define MODULE_PROC_FAMILY "CORE2 " +#elif defined CONFIG_M686 +#define MODULE_PROC_FAMILY "686 " +#elif defined CONFIG_MPENTIUMII +#define MODULE_PROC_FAMILY "PENTIUMII " +#elif defined CONFIG_MPENTIUMIII +#define MODULE_PROC_FAMILY "PENTIUMIII " +#elif defined CONFIG_MPENTIUMM +#define MODULE_PROC_FAMILY "PENTIUMM " +#elif defined CONFIG_MPENTIUM4 +#define MODULE_PROC_FAMILY "PENTIUM4 " +#elif defined CONFIG_MK6 +#define MODULE_PROC_FAMILY "K6 " +#elif defined CONFIG_MK7 +#define MODULE_PROC_FAMILY "K7 " +#elif defined CONFIG_MK8 +#define MODULE_PROC_FAMILY "K8 " +#elif defined CONFIG_X86_ELAN +#define MODULE_PROC_FAMILY "ELAN " +#elif defined CONFIG_MCRUSOE +#define MODULE_PROC_FAMILY "CRUSOE " +#elif defined CONFIG_MEFFICEON +#define MODULE_PROC_FAMILY "EFFICEON " +#elif defined CONFIG_MWINCHIPC6 +#define MODULE_PROC_FAMILY "WINCHIPC6 " +#elif defined CONFIG_MWINCHIP2 +#define MODULE_PROC_FAMILY "WINCHIP2 " +#elif defined CONFIG_MWINCHIP3D +#define MODULE_PROC_FAMILY "WINCHIP3D " +#elif defined CONFIG_MCYRIXIII +#define MODULE_PROC_FAMILY "CYRIXIII " +#elif defined CONFIG_MVIAC3_2 +#define MODULE_PROC_FAMILY "VIAC3-2 " +#elif defined CONFIG_MVIAC7 +#define MODULE_PROC_FAMILY "VIAC7 " +#elif defined CONFIG_MGEODEGX1 +#define MODULE_PROC_FAMILY "GEODEGX1 " +#elif defined CONFIG_MGEODE_LX +#define MODULE_PROC_FAMILY "GEODE " +#else +#error unknown processor family +#endif + +#ifdef CONFIG_X86_32 +# ifdef CONFIG_4KSTACKS +# define MODULE_STACKSIZE "4KSTACKS " +# else +# define MODULE_STACKSIZE "" +# endif +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE +#endif + +#endif /* _ASM_MODULE_H */ diff --git a/include/asm-x86/module_32.h b/include/asm-x86/module_32.h deleted file mode 100644 index 7e5fda6c397..00000000000 --- a/include/asm-x86/module_32.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _ASM_I386_MODULE_H -#define _ASM_I386_MODULE_H - -/* x86 is simple */ -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#ifdef CONFIG_M386 -#define MODULE_PROC_FAMILY "386 " -#elif defined CONFIG_M486 -#define MODULE_PROC_FAMILY "486 " -#elif defined CONFIG_M586 -#define MODULE_PROC_FAMILY "586 " -#elif defined CONFIG_M586TSC -#define MODULE_PROC_FAMILY "586TSC " -#elif defined CONFIG_M586MMX -#define MODULE_PROC_FAMILY "586MMX " -#elif defined CONFIG_MCORE2 -#define MODULE_PROC_FAMILY "CORE2 " -#elif defined CONFIG_M686 -#define MODULE_PROC_FAMILY "686 " -#elif defined CONFIG_MPENTIUMII -#define MODULE_PROC_FAMILY "PENTIUMII " -#elif defined CONFIG_MPENTIUMIII -#define MODULE_PROC_FAMILY "PENTIUMIII " -#elif defined CONFIG_MPENTIUMM -#define MODULE_PROC_FAMILY "PENTIUMM " -#elif defined CONFIG_MPENTIUM4 -#define MODULE_PROC_FAMILY "PENTIUM4 " -#elif defined CONFIG_MK6 -#define MODULE_PROC_FAMILY "K6 " -#elif defined CONFIG_MK7 -#define MODULE_PROC_FAMILY "K7 " -#elif defined CONFIG_MK8 -#define MODULE_PROC_FAMILY "K8 " -#elif defined CONFIG_X86_ELAN -#define MODULE_PROC_FAMILY "ELAN " -#elif defined CONFIG_MCRUSOE -#define MODULE_PROC_FAMILY "CRUSOE " -#elif defined CONFIG_MEFFICEON -#define MODULE_PROC_FAMILY "EFFICEON " -#elif defined CONFIG_MWINCHIPC6 -#define MODULE_PROC_FAMILY "WINCHIPC6 " -#elif defined CONFIG_MWINCHIP2 -#define MODULE_PROC_FAMILY "WINCHIP2 " -#elif defined CONFIG_MWINCHIP3D -#define MODULE_PROC_FAMILY "WINCHIP3D " -#elif defined CONFIG_MCYRIXIII -#define MODULE_PROC_FAMILY "CYRIXIII " -#elif defined CONFIG_MVIAC3_2 -#define MODULE_PROC_FAMILY "VIAC3-2 " -#elif defined CONFIG_MVIAC7 -#define MODULE_PROC_FAMILY "VIAC7 " -#elif defined CONFIG_MGEODEGX1 -#define MODULE_PROC_FAMILY "GEODEGX1 " -#elif defined CONFIG_MGEODE_LX -#define MODULE_PROC_FAMILY "GEODE " -#else -#error unknown processor family -#endif - -#ifdef CONFIG_4KSTACKS -#define MODULE_STACKSIZE "4KSTACKS " -#else -#define MODULE_STACKSIZE "" -#endif - -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE - -#endif /* _ASM_I386_MODULE_H */ diff --git a/include/asm-x86/module_64.h b/include/asm-x86/module_64.h deleted file mode 100644 index 67f8f69fa7b..00000000000 --- a/include/asm-x86/module_64.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _ASM_X8664_MODULE_H -#define _ASM_X8664_MODULE_H - -struct mod_arch_specific {}; - -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr - -#endif -- cgit v1.2.2 From 863aec860259f287797f886c3f373389cdafc8e3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:48 +0100 Subject: x86: x86-64 wired cpu_has macros This adds hard-wired definitions for the remaining cpu_has_* macros that correspond to flags required-features.h demands are set for 64-bit. Using these can efficiently avoid some #ifdef's when merging 32-bit and 64-bit code together. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 87dd900154d..75e2f78a7fd 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -192,9 +192,21 @@ #undef cpu_has_centaur_mcr #define cpu_has_centaur_mcr 0 +#undef cpu_has_pse +#define cpu_has_pse 1 + #undef cpu_has_pge #define cpu_has_pge 1 +#undef cpu_has_xmm +#define cpu_has_xmm 1 + +#undef cpu_has_xmm2 +#define cpu_has_xmm2 1 + +#undef cpu_has_fxsr +#define cpu_has_fxsr 1 + #endif /* CONFIG_X86_64 */ #endif /* _ASM_X86_CPUFEATURE_H */ -- cgit v1.2.2 From 99f8ecdf4506010feda26ffe4ac0d23962947106 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:48 +0100 Subject: x86: x86 i387 unify structs The i387_fxsave_struct formats really have the same layout on 32 and 64, with only some slightly different use of a few fields. The i387_fsave_struct and i387_soft_struct formats are never used by 64-bit kernels, but it doesn't hurt to have the unused types in the union and cuts down on the amount of #ifdef hair required throughout the i387 code. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 92 +++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 50 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 80c50020ef6..ea222cfe7b0 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -226,64 +226,37 @@ struct orig_ist { unsigned long ist[7]; }; -#ifdef CONFIG_X86_32 -struct i387_fsave_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ - long status; /* software status information */ -}; - -struct i387_fxsave_struct { - unsigned short cwd; - unsigned short swd; - unsigned short twd; - unsigned short fop; - long fip; - long fcs; - long foo; - long fos; - long mxcsr; - long mxcsr_mask; - long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ - long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ - long padding[56]; -} __attribute__((aligned(16))); +#define MXCSR_DEFAULT 0x1f80 -struct i387_soft_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ - unsigned char ftop, changed, lookahead, no_update, rm, alimit; - struct info *info; - unsigned long entry_eip; -}; - -union i387_union { - struct i387_fsave_struct fsave; - struct i387_fxsave_struct fxsave; - struct i387_soft_struct soft; +struct i387_fsave_struct { + u32 cwd; + u32 swd; + u32 twd; + u32 fip; + u32 fcs; + u32 foo; + u32 fos; + u32 st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + u32 status; /* software status information */ }; -# include "processor_32.h" -#else struct i387_fxsave_struct { u16 cwd; u16 swd; u16 twd; u16 fop; - u64 rip; - u64 rdp; + union { + struct { + u64 rip; + u64 rdp; + }; + struct { + u32 fip; + u32 fcs; + u32 foo; + u32 fos; + }; + }; u32 mxcsr; u32 mxcsr_mask; u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ @@ -291,10 +264,29 @@ struct i387_fxsave_struct { u32 padding[24]; } __attribute__((aligned(16))); +struct i387_soft_struct { + u32 cwd; + u32 swd; + u32 twd; + u32 fip; + u32 fcs; + u32 foo; + u32 fos; + u32 st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + u8 ftop, changed, lookahead, no_update, rm, alimit; + struct info *info; + u32 entry_eip; +}; + union i387_union { + struct i387_fsave_struct fsave; struct i387_fxsave_struct fxsave; + struct i387_soft_struct soft; }; +#ifdef CONFIG_X86_32 +# include "processor_32.h" +#else # include "processor_64.h" #endif -- cgit v1.2.2 From cc927a25bd704448b18b095c658cbfdd79dab865 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:49 +0100 Subject: x86: x86 i387 header cleanup This moves some code into asm-x86/i387_64.h in preparation for unifying this code between 32 and 64. The 32-bit versions of some things are copied in some existing names changed to match 32-bit names and share code. For 64, save_i387 is moved into an inline from i387_64.c; this matches restore_i387, which is already an inline, and makes sense since there is exactly one caller (in signal_64.c). The save_i387 function could use more cosmetic cleanup, but it is just moved verbatim in this patch. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/i387_64.h | 315 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 233 insertions(+), 82 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h index 12edb9f2d75..4cea7373ac7 100644 --- a/include/asm-x86/i387_64.h +++ b/include/asm-x86/i387_64.h @@ -7,33 +7,23 @@ * x86-64 work by Andi Kleen 2002 */ -#ifndef __ASM_X86_64_I387_H -#define __ASM_X86_64_I387_H +#ifndef _ASM_X86_I387_H +#define _ASM_X86_I387_H #include +#include #include #include #include -#include #include extern void fpu_init(void); extern unsigned int mxcsr_feature_mask; extern void mxcsr_feature_mask_init(void); extern void init_fpu(struct task_struct *child); -extern int save_i387(struct _fpstate __user *buf); extern asmlinkage void math_state_restore(void); -/* - * FPU lazy state save handling... - */ - -#define unlazy_fpu(tsk) do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) \ - save_init_fpu(tsk); \ - else \ - tsk->fpu_counter = 0; \ -} while (0) +#ifdef CONFIG_X86_64 /* Ignore delayed exceptions from user space */ static inline void tolerant_fwait(void) @@ -46,52 +36,8 @@ static inline void tolerant_fwait(void) " .previous\n"); } -#define clear_fpu(tsk) do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) { \ - tolerant_fwait(); \ - task_thread_info(tsk)->status &= ~TS_USEDFPU; \ - stts(); \ - } \ -} while (0) - -/* - * ptrace request handers... - */ -extern int get_fpregs(struct user_i387_struct __user *buf, - struct task_struct *tsk); -extern int set_fpregs(struct task_struct *tsk, - struct user_i387_struct __user *buf); - -/* - * i387 state interaction - */ -#define get_fpu_mxcsr(t) ((t)->thread.i387.fxsave.mxcsr) -#define get_fpu_cwd(t) ((t)->thread.i387.fxsave.cwd) -#define get_fpu_fxsr_twd(t) ((t)->thread.i387.fxsave.twd) -#define get_fpu_swd(t) ((t)->thread.i387.fxsave.swd) -#define set_fpu_cwd(t,val) ((t)->thread.i387.fxsave.cwd = (val)) -#define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val)) -#define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val)) - -#define X87_FSW_ES (1 << 7) /* Exception Summary */ - -/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception - is pending. Clear the x87 state here by setting it to fixed - values. The kernel data segment can be sometimes 0 and sometimes - new user value. Both should be ok. - Use the PDA as safe address because it should be already in L1. */ -static inline void clear_fpu_state(struct i387_fxsave_struct *fx) +static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) { - if (unlikely(fx->swd & X87_FSW_ES)) - asm volatile("fnclex"); - alternative_input(ASM_NOP8 ASM_NOP2, - " emms\n" /* clear stack tags */ - " fildl %%gs:0", /* load to clear state */ - X86_FEATURE_FXSAVE_LEAK); -} - -static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) -{ int err; asm volatile("1: rex64/fxrstor (%[fx])\n\t" @@ -105,7 +51,7 @@ static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) " .quad 1b,3b\n" ".previous" : [err] "=r" (err) -#if 0 /* See comment in __fxsave_clear() below. */ +#if 0 /* See comment in __save_init_fpu() below. */ : [fx] "r" (fx), "m" (*fx), "0" (0)); #else : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0)); @@ -113,10 +59,27 @@ static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) if (unlikely(err)) init_fpu(current); return err; -} +} -static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) -{ +#define X87_FSW_ES (1 << 7) /* Exception Summary */ + +/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. The kernel data segment can be sometimes 0 and sometimes + new user value. Both should be ok. + Use the PDA as safe address because it should be already in L1. */ +static inline void clear_fpu_state(struct i387_fxsave_struct *fx) +{ + if (unlikely(fx->swd & X87_FSW_ES)) + asm volatile("fnclex"); + alternative_input(ASM_NOP8 ASM_NOP2, + " emms\n" /* clear stack tags */ + " fildl %%gs:0", /* load to clear state */ + X86_FEATURE_FXSAVE_LEAK); +} + +static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) +{ int err; asm volatile("1: rex64/fxsave (%[fx])\n\t" @@ -139,9 +102,9 @@ static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) err = -EFAULT; /* No need to clear here because the caller clears USED_MATH */ return err; -} +} -static inline void __fxsave_clear(struct task_struct *tsk) +static inline void __save_init_fpu(struct task_struct *tsk) { /* Using "rex64; fxsave %0" is broken because, if the memory operand uses any extended registers for addressing, a second REX prefix @@ -169,18 +132,142 @@ static inline void __fxsave_clear(struct task_struct *tsk) thread.i387.fxsave))); #endif clear_fpu_state(&tsk->thread.i387.fxsave); + task_thread_info(tsk)->status &= ~TS_USEDFPU; +} + +/* + * Signal frame handlers. + */ + +static inline int save_i387(struct _fpstate __user *buf) +{ + struct task_struct *tsk = current; + int err = 0; + + BUILD_BUG_ON(sizeof(struct user_i387_struct) != + sizeof(tsk->thread.i387.fxsave)); + + if ((unsigned long)buf % 16) + printk("save_i387: bad fpstate %p\n", buf); + + if (!used_math()) + return 0; + clear_used_math(); /* trigger finit */ + if (task_thread_info(tsk)->status & TS_USEDFPU) { + err = save_i387_checking((struct i387_fxsave_struct __user *)buf); + if (err) return err; + task_thread_info(tsk)->status &= ~TS_USEDFPU; + stts(); + } else { + if (__copy_to_user(buf, &tsk->thread.i387.fxsave, + sizeof(struct i387_fxsave_struct))) + return -1; + } + return 1; +} + +/* + * This restores directly out of user space. Exceptions are handled. + */ +static inline int restore_i387(struct _fpstate __user *buf) +{ + set_used_math(); + if (!(task_thread_info(current)->status & TS_USEDFPU)) { + clts(); + task_thread_info(current)->status |= TS_USEDFPU; + } + return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); +} + +#else /* CONFIG_X86_32 */ + +static inline void tolerant_fwait(void) +{ + asm volatile("fnclex ; fwait"); +} + +static inline void restore_fpu(struct task_struct *tsk) +{ + /* + * The "nop" is needed to make the instructions the same + * length. + */ + alternative_input( + "nop ; frstor %1", + "fxrstor %1", + X86_FEATURE_FXSR, + "m" ((tsk)->thread.i387.fxsave)); +} + +/* We need a safe address that is cheap to find and that is already + in L1 during context switch. The best choices are unfortunately + different for UP and SMP */ +#ifdef CONFIG_SMP +#define safe_address (__per_cpu_offset[0]) +#else +#define safe_address (kstat_cpu(0).cpustat.user) +#endif + +/* + * These must be called with preempt disabled + */ +static inline void __save_init_fpu(struct task_struct *tsk) +{ + /* Use more nops than strictly needed in case the compiler + varies code */ + alternative_input( + "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, + "fxsave %[fx]\n" + "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", + X86_FEATURE_FXSR, + [fx] "m" (tsk->thread.i387.fxsave), + [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. safe_address is a random variable that should be in L1 */ + alternative_input( + GENERIC_NOP8 GENERIC_NOP2, + "emms\n\t" /* clear stack tags */ + "fildl %[addr]", /* set F?P to defined value */ + X86_FEATURE_FXSAVE_LEAK, + [addr] "m" (safe_address)); + task_thread_info(tsk)->status &= ~TS_USEDFPU; +} + +/* + * Signal frame handlers... + */ +extern int save_i387(struct _fpstate __user *buf); +extern int restore_i387(struct _fpstate __user *buf); + +#endif /* CONFIG_X86_64 */ + +static inline void __unlazy_fpu(struct task_struct *tsk) +{ + if (task_thread_info(tsk)->status & TS_USEDFPU) { + __save_init_fpu(tsk); + stts(); + } else + tsk->fpu_counter = 0; +} + +static inline void __clear_fpu(struct task_struct *tsk) +{ + if (task_thread_info(tsk)->status & TS_USEDFPU) { + tolerant_fwait(); + task_thread_info(tsk)->status &= ~TS_USEDFPU; + stts(); + } } static inline void kernel_fpu_begin(void) { struct thread_info *me = current_thread_info(); preempt_disable(); - if (me->status & TS_USEDFPU) { - __fxsave_clear(me->task); - me->status &= ~TS_USEDFPU; - return; - } - clts(); + if (me->status & TS_USEDFPU) + __save_init_fpu(me->task); + else + clts(); } static inline void kernel_fpu_end(void) @@ -189,24 +276,88 @@ static inline void kernel_fpu_end(void) preempt_enable(); } +#ifdef CONFIG_X86_64 + static inline void save_init_fpu(struct task_struct *tsk) { - __fxsave_clear(tsk); - task_thread_info(tsk)->status &= ~TS_USEDFPU; + __save_init_fpu(tsk); stts(); } -/* - * This restores directly out of user space. Exceptions are handled. +#define unlazy_fpu __unlazy_fpu +#define clear_fpu __clear_fpu + +#else /* CONFIG_X86_32 */ + +/* + * These disable preemption on their own and are safe */ -static inline int restore_i387(struct _fpstate __user *buf) +static inline void save_init_fpu(struct task_struct *tsk) { - set_used_math(); - if (!(task_thread_info(current)->status & TS_USEDFPU)) { - clts(); - task_thread_info(current)->status |= TS_USEDFPU; + preempt_disable(); + __save_init_fpu(tsk); + stts(); + preempt_enable(); +} + +static inline void unlazy_fpu(struct task_struct *tsk) +{ + preempt_disable(); + __unlazy_fpu(tsk); + preempt_enable(); +} + +static inline void clear_fpu(struct task_struct *tsk) +{ + preempt_disable(); + __clear_fpu(tsk); + preempt_enable(); +} + +#endif /* CONFIG_X86_64 */ + +/* + * ptrace request handlers... + */ +extern int get_fpregs(struct user_i387_struct __user *buf, + struct task_struct *tsk); +extern int set_fpregs(struct task_struct *tsk, + struct user_i387_struct __user *buf); + +struct user_fxsr_struct; +extern int get_fpxregs(struct user_fxsr_struct __user *buf, + struct task_struct *tsk); +extern int set_fpxregs(struct task_struct *tsk, + struct user_fxsr_struct __user *buf); + +/* + * i387 state interaction + */ +static inline unsigned short get_fpu_cwd(struct task_struct *tsk) +{ + if (cpu_has_fxsr) { + return tsk->thread.i387.fxsave.cwd; + } else { + return (unsigned short)tsk->thread.i387.fsave.cwd; + } +} + +static inline unsigned short get_fpu_swd(struct task_struct *tsk) +{ + if (cpu_has_fxsr) { + return tsk->thread.i387.fxsave.swd; + } else { + return (unsigned short)tsk->thread.i387.fsave.swd; + } +} + +static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) +{ + if (cpu_has_xmm) { + return tsk->thread.i387.fxsave.mxcsr; + } else { + return MXCSR_DEFAULT; } - return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); } -#endif /* __ASM_X86_64_I387_H */ +#endif /* _ASM_X86_I387_H */ -- cgit v1.2.2 From 4421011120b2304e5c248ae4165a2704588aedf1 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:50 +0100 Subject: x86: x86 i387 user_regset This revamps the i387 code to be shared across 32-bit, 64-bit, and 32-on-64. It does so by consolidating the code in one place based on the user_regset accessor interfaces. This switches 32-bit to using the i387_64.h header and 64-bit to using the i387.c that was previously i387_32.c, but that's what took the least cleanup in each file. Here i387.h is stubbed to always include i387_64.h rather than renaming the file, to keep this diff smaller and easier to read. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/fpu32.h | 10 ---------- include/asm-x86/i387.h | 6 +----- include/asm-x86/i387_64.h | 11 +++++++++++ 3 files changed, 12 insertions(+), 15 deletions(-) delete mode 100644 include/asm-x86/fpu32.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/fpu32.h b/include/asm-x86/fpu32.h deleted file mode 100644 index 4153db5c0c3..00000000000 --- a/include/asm-x86/fpu32.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _FPU32_H -#define _FPU32_H 1 - -struct _fpstate_ia32; - -int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave); -int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, - struct pt_regs *regs, int fsave); - -#endif diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index a8bbed34966..b2bc0050ce9 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h @@ -1,5 +1 @@ -#ifdef CONFIG_X86_32 -# include "i387_32.h" -#else -# include "i387_64.h" -#endif +#include "i387_64.h" diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h index 4cea7373ac7..de435b9114d 100644 --- a/include/asm-x86/i387_64.h +++ b/include/asm-x86/i387_64.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,16 @@ extern void mxcsr_feature_mask_init(void); extern void init_fpu(struct task_struct *child); extern asmlinkage void math_state_restore(void); +extern user_regset_active_fn fpregs_active, xfpregs_active; +extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; +extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set; + +#ifdef CONFIG_IA32_EMULATION +struct _fpstate_ia32; +extern int save_i387_ia32(struct _fpstate_ia32 __user *buf); +extern int restore_i387_ia32(struct _fpstate_ia32 __user *buf); +#endif + #ifdef CONFIG_X86_64 /* Ignore delayed exceptions from user space */ -- cgit v1.2.2 From 1eeaed7679eab3666d2d8c964d060c2169b3813b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:51 +0100 Subject: x86: x86 i387 cleanup This removes all the old code that is no longer used after the i387 unification and cleanup. The i387_64.h is renamed to i387.h with no changes, but since it replaces the nonempty one-line stub i387.h it looks like a big diff and not a rename. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/i387.h | 375 +++++++++++++++++++++++++++++++++++++++++++++- include/asm-x86/i387_32.h | 149 ------------------ include/asm-x86/i387_64.h | 374 --------------------------------------------- 3 files changed, 374 insertions(+), 524 deletions(-) delete mode 100644 include/asm-x86/i387_32.h delete mode 100644 include/asm-x86/i387_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index b2bc0050ce9..de435b9114d 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h @@ -1 +1,374 @@ -#include "i387_64.h" +/* + * Copyright (C) 1994 Linus Torvalds + * + * Pentium III FXSR, SSE support + * General FPU state handling cleanups + * Gareth Hughes , May 2000 + * x86-64 work by Andi Kleen 2002 + */ + +#ifndef _ASM_X86_I387_H +#define _ASM_X86_I387_H + +#include +#include +#include +#include +#include +#include +#include + +extern void fpu_init(void); +extern unsigned int mxcsr_feature_mask; +extern void mxcsr_feature_mask_init(void); +extern void init_fpu(struct task_struct *child); +extern asmlinkage void math_state_restore(void); + +extern user_regset_active_fn fpregs_active, xfpregs_active; +extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; +extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set; + +#ifdef CONFIG_IA32_EMULATION +struct _fpstate_ia32; +extern int save_i387_ia32(struct _fpstate_ia32 __user *buf); +extern int restore_i387_ia32(struct _fpstate_ia32 __user *buf); +#endif + +#ifdef CONFIG_X86_64 + +/* Ignore delayed exceptions from user space */ +static inline void tolerant_fwait(void) +{ + asm volatile("1: fwait\n" + "2:\n" + " .section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 1b,2b\n" + " .previous\n"); +} + +static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) +{ + int err; + + asm volatile("1: rex64/fxrstor (%[fx])\n\t" + "2:\n" + ".section .fixup,\"ax\"\n" + "3: movl $-1,%[err]\n" + " jmp 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 1b,3b\n" + ".previous" + : [err] "=r" (err) +#if 0 /* See comment in __save_init_fpu() below. */ + : [fx] "r" (fx), "m" (*fx), "0" (0)); +#else + : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0)); +#endif + if (unlikely(err)) + init_fpu(current); + return err; +} + +#define X87_FSW_ES (1 << 7) /* Exception Summary */ + +/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. The kernel data segment can be sometimes 0 and sometimes + new user value. Both should be ok. + Use the PDA as safe address because it should be already in L1. */ +static inline void clear_fpu_state(struct i387_fxsave_struct *fx) +{ + if (unlikely(fx->swd & X87_FSW_ES)) + asm volatile("fnclex"); + alternative_input(ASM_NOP8 ASM_NOP2, + " emms\n" /* clear stack tags */ + " fildl %%gs:0", /* load to clear state */ + X86_FEATURE_FXSAVE_LEAK); +} + +static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) +{ + int err; + + asm volatile("1: rex64/fxsave (%[fx])\n\t" + "2:\n" + ".section .fixup,\"ax\"\n" + "3: movl $-1,%[err]\n" + " jmp 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 1b,3b\n" + ".previous" + : [err] "=r" (err), "=m" (*fx) +#if 0 /* See comment in __fxsave_clear() below. */ + : [fx] "r" (fx), "0" (0)); +#else + : [fx] "cdaSDb" (fx), "0" (0)); +#endif + if (unlikely(err) && __clear_user(fx, sizeof(struct i387_fxsave_struct))) + err = -EFAULT; + /* No need to clear here because the caller clears USED_MATH */ + return err; +} + +static inline void __save_init_fpu(struct task_struct *tsk) +{ + /* Using "rex64; fxsave %0" is broken because, if the memory operand + uses any extended registers for addressing, a second REX prefix + will be generated (to the assembler, rex64 followed by semicolon + is a separate instruction), and hence the 64-bitness is lost. */ +#if 0 + /* Using "fxsaveq %0" would be the ideal choice, but is only supported + starting with gas 2.16. */ + __asm__ __volatile__("fxsaveq %0" + : "=m" (tsk->thread.i387.fxsave)); +#elif 0 + /* Using, as a workaround, the properly prefixed form below isn't + accepted by any binutils version so far released, complaining that + the same type of prefix is used twice if an extended register is + needed for addressing (fix submitted to mainline 2005-11-21). */ + __asm__ __volatile__("rex64/fxsave %0" + : "=m" (tsk->thread.i387.fxsave)); +#else + /* This, however, we can work around by forcing the compiler to select + an addressing mode that doesn't require extended registers. */ + __asm__ __volatile__("rex64/fxsave %P2(%1)" + : "=m" (tsk->thread.i387.fxsave) + : "cdaSDb" (tsk), + "i" (offsetof(__typeof__(*tsk), + thread.i387.fxsave))); +#endif + clear_fpu_state(&tsk->thread.i387.fxsave); + task_thread_info(tsk)->status &= ~TS_USEDFPU; +} + +/* + * Signal frame handlers. + */ + +static inline int save_i387(struct _fpstate __user *buf) +{ + struct task_struct *tsk = current; + int err = 0; + + BUILD_BUG_ON(sizeof(struct user_i387_struct) != + sizeof(tsk->thread.i387.fxsave)); + + if ((unsigned long)buf % 16) + printk("save_i387: bad fpstate %p\n", buf); + + if (!used_math()) + return 0; + clear_used_math(); /* trigger finit */ + if (task_thread_info(tsk)->status & TS_USEDFPU) { + err = save_i387_checking((struct i387_fxsave_struct __user *)buf); + if (err) return err; + task_thread_info(tsk)->status &= ~TS_USEDFPU; + stts(); + } else { + if (__copy_to_user(buf, &tsk->thread.i387.fxsave, + sizeof(struct i387_fxsave_struct))) + return -1; + } + return 1; +} + +/* + * This restores directly out of user space. Exceptions are handled. + */ +static inline int restore_i387(struct _fpstate __user *buf) +{ + set_used_math(); + if (!(task_thread_info(current)->status & TS_USEDFPU)) { + clts(); + task_thread_info(current)->status |= TS_USEDFPU; + } + return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); +} + +#else /* CONFIG_X86_32 */ + +static inline void tolerant_fwait(void) +{ + asm volatile("fnclex ; fwait"); +} + +static inline void restore_fpu(struct task_struct *tsk) +{ + /* + * The "nop" is needed to make the instructions the same + * length. + */ + alternative_input( + "nop ; frstor %1", + "fxrstor %1", + X86_FEATURE_FXSR, + "m" ((tsk)->thread.i387.fxsave)); +} + +/* We need a safe address that is cheap to find and that is already + in L1 during context switch. The best choices are unfortunately + different for UP and SMP */ +#ifdef CONFIG_SMP +#define safe_address (__per_cpu_offset[0]) +#else +#define safe_address (kstat_cpu(0).cpustat.user) +#endif + +/* + * These must be called with preempt disabled + */ +static inline void __save_init_fpu(struct task_struct *tsk) +{ + /* Use more nops than strictly needed in case the compiler + varies code */ + alternative_input( + "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, + "fxsave %[fx]\n" + "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", + X86_FEATURE_FXSR, + [fx] "m" (tsk->thread.i387.fxsave), + [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. safe_address is a random variable that should be in L1 */ + alternative_input( + GENERIC_NOP8 GENERIC_NOP2, + "emms\n\t" /* clear stack tags */ + "fildl %[addr]", /* set F?P to defined value */ + X86_FEATURE_FXSAVE_LEAK, + [addr] "m" (safe_address)); + task_thread_info(tsk)->status &= ~TS_USEDFPU; +} + +/* + * Signal frame handlers... + */ +extern int save_i387(struct _fpstate __user *buf); +extern int restore_i387(struct _fpstate __user *buf); + +#endif /* CONFIG_X86_64 */ + +static inline void __unlazy_fpu(struct task_struct *tsk) +{ + if (task_thread_info(tsk)->status & TS_USEDFPU) { + __save_init_fpu(tsk); + stts(); + } else + tsk->fpu_counter = 0; +} + +static inline void __clear_fpu(struct task_struct *tsk) +{ + if (task_thread_info(tsk)->status & TS_USEDFPU) { + tolerant_fwait(); + task_thread_info(tsk)->status &= ~TS_USEDFPU; + stts(); + } +} + +static inline void kernel_fpu_begin(void) +{ + struct thread_info *me = current_thread_info(); + preempt_disable(); + if (me->status & TS_USEDFPU) + __save_init_fpu(me->task); + else + clts(); +} + +static inline void kernel_fpu_end(void) +{ + stts(); + preempt_enable(); +} + +#ifdef CONFIG_X86_64 + +static inline void save_init_fpu(struct task_struct *tsk) +{ + __save_init_fpu(tsk); + stts(); +} + +#define unlazy_fpu __unlazy_fpu +#define clear_fpu __clear_fpu + +#else /* CONFIG_X86_32 */ + +/* + * These disable preemption on their own and are safe + */ +static inline void save_init_fpu(struct task_struct *tsk) +{ + preempt_disable(); + __save_init_fpu(tsk); + stts(); + preempt_enable(); +} + +static inline void unlazy_fpu(struct task_struct *tsk) +{ + preempt_disable(); + __unlazy_fpu(tsk); + preempt_enable(); +} + +static inline void clear_fpu(struct task_struct *tsk) +{ + preempt_disable(); + __clear_fpu(tsk); + preempt_enable(); +} + +#endif /* CONFIG_X86_64 */ + +/* + * ptrace request handlers... + */ +extern int get_fpregs(struct user_i387_struct __user *buf, + struct task_struct *tsk); +extern int set_fpregs(struct task_struct *tsk, + struct user_i387_struct __user *buf); + +struct user_fxsr_struct; +extern int get_fpxregs(struct user_fxsr_struct __user *buf, + struct task_struct *tsk); +extern int set_fpxregs(struct task_struct *tsk, + struct user_fxsr_struct __user *buf); + +/* + * i387 state interaction + */ +static inline unsigned short get_fpu_cwd(struct task_struct *tsk) +{ + if (cpu_has_fxsr) { + return tsk->thread.i387.fxsave.cwd; + } else { + return (unsigned short)tsk->thread.i387.fsave.cwd; + } +} + +static inline unsigned short get_fpu_swd(struct task_struct *tsk) +{ + if (cpu_has_fxsr) { + return tsk->thread.i387.fxsave.swd; + } else { + return (unsigned short)tsk->thread.i387.fsave.swd; + } +} + +static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) +{ + if (cpu_has_xmm) { + return tsk->thread.i387.fxsave.mxcsr; + } else { + return MXCSR_DEFAULT; + } +} + +#endif /* _ASM_X86_I387_H */ diff --git a/include/asm-x86/i387_32.h b/include/asm-x86/i387_32.h deleted file mode 100644 index 9ac2502cdd3..00000000000 --- a/include/asm-x86/i387_32.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 1994 Linus Torvalds - * - * Pentium III FXSR, SSE support - * General FPU state handling cleanups - * Gareth Hughes , May 2000 - */ - -#ifndef __ASM_I386_I387_H -#define __ASM_I386_I387_H - -#include -#include -#include -#include -#include -#include - -extern void mxcsr_feature_mask_init(void); -extern void init_fpu(struct task_struct *); - -/* - * FPU lazy state save handling... - */ - -/* - * The "nop" is needed to make the instructions the same - * length. - */ -#define restore_fpu(tsk) \ - alternative_input( \ - "nop ; frstor %1", \ - "fxrstor %1", \ - X86_FEATURE_FXSR, \ - "m" ((tsk)->thread.i387.fxsave)) - -extern void kernel_fpu_begin(void); -#define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) - -/* We need a safe address that is cheap to find and that is already - in L1 during context switch. The best choices are unfortunately - different for UP and SMP */ -#ifdef CONFIG_SMP -#define safe_address (__per_cpu_offset[0]) -#else -#define safe_address (kstat_cpu(0).cpustat.user) -#endif - -/* - * These must be called with preempt disabled - */ -static inline void __save_init_fpu( struct task_struct *tsk ) -{ - /* Use more nops than strictly needed in case the compiler - varies code */ - alternative_input( - "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, - "fxsave %[fx]\n" - "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", - X86_FEATURE_FXSR, - [fx] "m" (tsk->thread.i387.fxsave), - [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); - /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception - is pending. Clear the x87 state here by setting it to fixed - values. safe_address is a random variable that should be in L1 */ - alternative_input( - GENERIC_NOP8 GENERIC_NOP2, - "emms\n\t" /* clear stack tags */ - "fildl %[addr]", /* set F?P to defined value */ - X86_FEATURE_FXSAVE_LEAK, - [addr] "m" (safe_address)); - task_thread_info(tsk)->status &= ~TS_USEDFPU; -} - -#define __unlazy_fpu( tsk ) do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) { \ - __save_init_fpu(tsk); \ - stts(); \ - } else \ - tsk->fpu_counter = 0; \ -} while (0) - -#define __clear_fpu( tsk ) \ -do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) { \ - asm volatile("fnclex ; fwait"); \ - task_thread_info(tsk)->status &= ~TS_USEDFPU; \ - stts(); \ - } \ -} while (0) - - -/* - * These disable preemption on their own and are safe - */ -static inline void save_init_fpu( struct task_struct *tsk ) -{ - preempt_disable(); - __save_init_fpu(tsk); - stts(); - preempt_enable(); -} - -#define unlazy_fpu( tsk ) do { \ - preempt_disable(); \ - __unlazy_fpu(tsk); \ - preempt_enable(); \ -} while (0) - -#define clear_fpu( tsk ) do { \ - preempt_disable(); \ - __clear_fpu( tsk ); \ - preempt_enable(); \ -} while (0) - -/* - * FPU state interaction... - */ -extern unsigned short get_fpu_cwd( struct task_struct *tsk ); -extern unsigned short get_fpu_swd( struct task_struct *tsk ); -extern unsigned short get_fpu_mxcsr( struct task_struct *tsk ); -extern asmlinkage void math_state_restore(void); - -/* - * Signal frame handlers... - */ -extern int save_i387( struct _fpstate __user *buf ); -extern int restore_i387( struct _fpstate __user *buf ); - -/* - * ptrace request handers... - */ -extern int get_fpregs( struct user_i387_struct __user *buf, - struct task_struct *tsk ); -extern int set_fpregs( struct task_struct *tsk, - struct user_i387_struct __user *buf ); - -extern int get_fpxregs( struct user_fxsr_struct __user *buf, - struct task_struct *tsk ); -extern int set_fpxregs( struct task_struct *tsk, - struct user_fxsr_struct __user *buf ); - -/* - * FPU state for core dumps... - */ -extern int dump_fpu( struct pt_regs *regs, - struct user_i387_struct *fpu ); - -#endif /* __ASM_I386_I387_H */ diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h deleted file mode 100644 index de435b9114d..00000000000 --- a/include/asm-x86/i387_64.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (C) 1994 Linus Torvalds - * - * Pentium III FXSR, SSE support - * General FPU state handling cleanups - * Gareth Hughes , May 2000 - * x86-64 work by Andi Kleen 2002 - */ - -#ifndef _ASM_X86_I387_H -#define _ASM_X86_I387_H - -#include -#include -#include -#include -#include -#include -#include - -extern void fpu_init(void); -extern unsigned int mxcsr_feature_mask; -extern void mxcsr_feature_mask_init(void); -extern void init_fpu(struct task_struct *child); -extern asmlinkage void math_state_restore(void); - -extern user_regset_active_fn fpregs_active, xfpregs_active; -extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; -extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set; - -#ifdef CONFIG_IA32_EMULATION -struct _fpstate_ia32; -extern int save_i387_ia32(struct _fpstate_ia32 __user *buf); -extern int restore_i387_ia32(struct _fpstate_ia32 __user *buf); -#endif - -#ifdef CONFIG_X86_64 - -/* Ignore delayed exceptions from user space */ -static inline void tolerant_fwait(void) -{ - asm volatile("1: fwait\n" - "2:\n" - " .section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 1b,2b\n" - " .previous\n"); -} - -static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) -{ - int err; - - asm volatile("1: rex64/fxrstor (%[fx])\n\t" - "2:\n" - ".section .fixup,\"ax\"\n" - "3: movl $-1,%[err]\n" - " jmp 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 1b,3b\n" - ".previous" - : [err] "=r" (err) -#if 0 /* See comment in __save_init_fpu() below. */ - : [fx] "r" (fx), "m" (*fx), "0" (0)); -#else - : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0)); -#endif - if (unlikely(err)) - init_fpu(current); - return err; -} - -#define X87_FSW_ES (1 << 7) /* Exception Summary */ - -/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception - is pending. Clear the x87 state here by setting it to fixed - values. The kernel data segment can be sometimes 0 and sometimes - new user value. Both should be ok. - Use the PDA as safe address because it should be already in L1. */ -static inline void clear_fpu_state(struct i387_fxsave_struct *fx) -{ - if (unlikely(fx->swd & X87_FSW_ES)) - asm volatile("fnclex"); - alternative_input(ASM_NOP8 ASM_NOP2, - " emms\n" /* clear stack tags */ - " fildl %%gs:0", /* load to clear state */ - X86_FEATURE_FXSAVE_LEAK); -} - -static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) -{ - int err; - - asm volatile("1: rex64/fxsave (%[fx])\n\t" - "2:\n" - ".section .fixup,\"ax\"\n" - "3: movl $-1,%[err]\n" - " jmp 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 1b,3b\n" - ".previous" - : [err] "=r" (err), "=m" (*fx) -#if 0 /* See comment in __fxsave_clear() below. */ - : [fx] "r" (fx), "0" (0)); -#else - : [fx] "cdaSDb" (fx), "0" (0)); -#endif - if (unlikely(err) && __clear_user(fx, sizeof(struct i387_fxsave_struct))) - err = -EFAULT; - /* No need to clear here because the caller clears USED_MATH */ - return err; -} - -static inline void __save_init_fpu(struct task_struct *tsk) -{ - /* Using "rex64; fxsave %0" is broken because, if the memory operand - uses any extended registers for addressing, a second REX prefix - will be generated (to the assembler, rex64 followed by semicolon - is a separate instruction), and hence the 64-bitness is lost. */ -#if 0 - /* Using "fxsaveq %0" would be the ideal choice, but is only supported - starting with gas 2.16. */ - __asm__ __volatile__("fxsaveq %0" - : "=m" (tsk->thread.i387.fxsave)); -#elif 0 - /* Using, as a workaround, the properly prefixed form below isn't - accepted by any binutils version so far released, complaining that - the same type of prefix is used twice if an extended register is - needed for addressing (fix submitted to mainline 2005-11-21). */ - __asm__ __volatile__("rex64/fxsave %0" - : "=m" (tsk->thread.i387.fxsave)); -#else - /* This, however, we can work around by forcing the compiler to select - an addressing mode that doesn't require extended registers. */ - __asm__ __volatile__("rex64/fxsave %P2(%1)" - : "=m" (tsk->thread.i387.fxsave) - : "cdaSDb" (tsk), - "i" (offsetof(__typeof__(*tsk), - thread.i387.fxsave))); -#endif - clear_fpu_state(&tsk->thread.i387.fxsave); - task_thread_info(tsk)->status &= ~TS_USEDFPU; -} - -/* - * Signal frame handlers. - */ - -static inline int save_i387(struct _fpstate __user *buf) -{ - struct task_struct *tsk = current; - int err = 0; - - BUILD_BUG_ON(sizeof(struct user_i387_struct) != - sizeof(tsk->thread.i387.fxsave)); - - if ((unsigned long)buf % 16) - printk("save_i387: bad fpstate %p\n", buf); - - if (!used_math()) - return 0; - clear_used_math(); /* trigger finit */ - if (task_thread_info(tsk)->status & TS_USEDFPU) { - err = save_i387_checking((struct i387_fxsave_struct __user *)buf); - if (err) return err; - task_thread_info(tsk)->status &= ~TS_USEDFPU; - stts(); - } else { - if (__copy_to_user(buf, &tsk->thread.i387.fxsave, - sizeof(struct i387_fxsave_struct))) - return -1; - } - return 1; -} - -/* - * This restores directly out of user space. Exceptions are handled. - */ -static inline int restore_i387(struct _fpstate __user *buf) -{ - set_used_math(); - if (!(task_thread_info(current)->status & TS_USEDFPU)) { - clts(); - task_thread_info(current)->status |= TS_USEDFPU; - } - return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); -} - -#else /* CONFIG_X86_32 */ - -static inline void tolerant_fwait(void) -{ - asm volatile("fnclex ; fwait"); -} - -static inline void restore_fpu(struct task_struct *tsk) -{ - /* - * The "nop" is needed to make the instructions the same - * length. - */ - alternative_input( - "nop ; frstor %1", - "fxrstor %1", - X86_FEATURE_FXSR, - "m" ((tsk)->thread.i387.fxsave)); -} - -/* We need a safe address that is cheap to find and that is already - in L1 during context switch. The best choices are unfortunately - different for UP and SMP */ -#ifdef CONFIG_SMP -#define safe_address (__per_cpu_offset[0]) -#else -#define safe_address (kstat_cpu(0).cpustat.user) -#endif - -/* - * These must be called with preempt disabled - */ -static inline void __save_init_fpu(struct task_struct *tsk) -{ - /* Use more nops than strictly needed in case the compiler - varies code */ - alternative_input( - "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, - "fxsave %[fx]\n" - "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", - X86_FEATURE_FXSR, - [fx] "m" (tsk->thread.i387.fxsave), - [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); - /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception - is pending. Clear the x87 state here by setting it to fixed - values. safe_address is a random variable that should be in L1 */ - alternative_input( - GENERIC_NOP8 GENERIC_NOP2, - "emms\n\t" /* clear stack tags */ - "fildl %[addr]", /* set F?P to defined value */ - X86_FEATURE_FXSAVE_LEAK, - [addr] "m" (safe_address)); - task_thread_info(tsk)->status &= ~TS_USEDFPU; -} - -/* - * Signal frame handlers... - */ -extern int save_i387(struct _fpstate __user *buf); -extern int restore_i387(struct _fpstate __user *buf); - -#endif /* CONFIG_X86_64 */ - -static inline void __unlazy_fpu(struct task_struct *tsk) -{ - if (task_thread_info(tsk)->status & TS_USEDFPU) { - __save_init_fpu(tsk); - stts(); - } else - tsk->fpu_counter = 0; -} - -static inline void __clear_fpu(struct task_struct *tsk) -{ - if (task_thread_info(tsk)->status & TS_USEDFPU) { - tolerant_fwait(); - task_thread_info(tsk)->status &= ~TS_USEDFPU; - stts(); - } -} - -static inline void kernel_fpu_begin(void) -{ - struct thread_info *me = current_thread_info(); - preempt_disable(); - if (me->status & TS_USEDFPU) - __save_init_fpu(me->task); - else - clts(); -} - -static inline void kernel_fpu_end(void) -{ - stts(); - preempt_enable(); -} - -#ifdef CONFIG_X86_64 - -static inline void save_init_fpu(struct task_struct *tsk) -{ - __save_init_fpu(tsk); - stts(); -} - -#define unlazy_fpu __unlazy_fpu -#define clear_fpu __clear_fpu - -#else /* CONFIG_X86_32 */ - -/* - * These disable preemption on their own and are safe - */ -static inline void save_init_fpu(struct task_struct *tsk) -{ - preempt_disable(); - __save_init_fpu(tsk); - stts(); - preempt_enable(); -} - -static inline void unlazy_fpu(struct task_struct *tsk) -{ - preempt_disable(); - __unlazy_fpu(tsk); - preempt_enable(); -} - -static inline void clear_fpu(struct task_struct *tsk) -{ - preempt_disable(); - __clear_fpu(tsk); - preempt_enable(); -} - -#endif /* CONFIG_X86_64 */ - -/* - * ptrace request handlers... - */ -extern int get_fpregs(struct user_i387_struct __user *buf, - struct task_struct *tsk); -extern int set_fpregs(struct task_struct *tsk, - struct user_i387_struct __user *buf); - -struct user_fxsr_struct; -extern int get_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *tsk); -extern int set_fpxregs(struct task_struct *tsk, - struct user_fxsr_struct __user *buf); - -/* - * i387 state interaction - */ -static inline unsigned short get_fpu_cwd(struct task_struct *tsk) -{ - if (cpu_has_fxsr) { - return tsk->thread.i387.fxsave.cwd; - } else { - return (unsigned short)tsk->thread.i387.fsave.cwd; - } -} - -static inline unsigned short get_fpu_swd(struct task_struct *tsk) -{ - if (cpu_has_fxsr) { - return tsk->thread.i387.fxsave.swd; - } else { - return (unsigned short)tsk->thread.i387.fsave.swd; - } -} - -static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) -{ - if (cpu_has_xmm) { - return tsk->thread.i387.fxsave.mxcsr; - } else { - return MXCSR_DEFAULT; - } -} - -#endif /* _ASM_X86_I387_H */ -- cgit v1.2.2 From 1bd5718ce58fb49ac158653380fa200f4759daad Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:51 +0100 Subject: x86: x86 TLS desc_struct cleanup This cleans up the TLS code to use struct desc_struct and to separate the encoding and installation magic from the interface wrappers. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/desc.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index e17581ad882..5b6a05d3a77 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -7,7 +7,8 @@ #include #include -static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) +static inline void fill_ldt(struct desc_struct *desc, + const struct user_desc *info) { desc->limit0 = info->limit & 0x0ffff; desc->base0 = info->base_addr & 0x0000ffff; @@ -275,10 +276,16 @@ static inline void load_LDT(mm_context_t *pc) preempt_enable(); } -static inline unsigned long get_desc_base(struct desc_struct *desc) +static inline unsigned long get_desc_base(const struct desc_struct *desc) { return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); } + +static inline unsigned long get_desc_limit(const struct desc_struct *desc) +{ + return desc->limit0 | (desc->limit << 16); +} + static inline void _set_gate(int gate, unsigned type, void *addr, unsigned dpl, unsigned ist, unsigned seg) { -- cgit v1.2.2 From 975511be74d1b82bf041aaed2861a242abfe3886 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:54 +0100 Subject: x86: x86 CORE_DUMP_USE_REGSET This switches x86 to the user_regset-based code for ELF core dumps. The core dumps come out exactly the same as before. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/elf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index 5e5705bf082..123e2d599c6 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -201,6 +201,7 @@ extern int vdso_enabled; #endif /* !CONFIG_X86_32 */ +#define CORE_DUMP_USE_REGSET #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 -- cgit v1.2.2 From 60b3b9af35aad66345e395be911e46fb8443f0c5 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:55 +0100 Subject: x86: x86 user_regset cleanup This removes a bunch of dead code that is no longer needed now that the user_regset interfaces are being used for all these jobs. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/elf.h | 68 ---------------------------------------------- include/asm-x86/i387.h | 14 ---------- include/asm-x86/math_emu.h | 5 ---- 3 files changed, 87 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index 123e2d599c6..d6bf7421d7b 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -104,28 +104,6 @@ typedef struct user_fxsr_struct elf_fpxregset_t; _r->ax = 0; \ } while (0) -/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is - now struct_user_regs, they are different) */ - -#define ELF_CORE_COPY_REGS(pr_reg, regs) \ - pr_reg[0] = regs->bx; \ - pr_reg[1] = regs->cx; \ - pr_reg[2] = regs->dx; \ - pr_reg[3] = regs->si; \ - pr_reg[4] = regs->di; \ - pr_reg[5] = regs->bp; \ - pr_reg[6] = regs->ax; \ - pr_reg[7] = regs->ds & 0xffff; \ - pr_reg[8] = regs->es & 0xffff; \ - pr_reg[9] = regs->fs & 0xffff; \ - savesegment(gs,pr_reg[10]); \ - pr_reg[11] = regs->orig_ax; \ - pr_reg[12] = regs->ip; \ - pr_reg[13] = regs->cs & 0xffff; \ - pr_reg[14] = regs->flags; \ - pr_reg[15] = regs->sp; \ - pr_reg[16] = regs->ss & 0xffff; - #define ELF_PLATFORM (utsname()->machine) #define set_personality_64bit() do { } while (0) extern unsigned int vdso_enabled; @@ -159,41 +137,6 @@ extern unsigned int vdso_enabled; clear_thread_flag(TIF_IA32); \ } while (0) -/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is - now struct_user_regs, they are different). Assumes current is the process - getting dumped. */ - -#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ - unsigned v; \ - (pr_reg)[0] = (regs)->r15; \ - (pr_reg)[1] = (regs)->r14; \ - (pr_reg)[2] = (regs)->r13; \ - (pr_reg)[3] = (regs)->r12; \ - (pr_reg)[4] = (regs)->bp; \ - (pr_reg)[5] = (regs)->bx; \ - (pr_reg)[6] = (regs)->r11; \ - (pr_reg)[7] = (regs)->r10; \ - (pr_reg)[8] = (regs)->r9; \ - (pr_reg)[9] = (regs)->r8; \ - (pr_reg)[10] = (regs)->ax; \ - (pr_reg)[11] = (regs)->cx; \ - (pr_reg)[12] = (regs)->dx; \ - (pr_reg)[13] = (regs)->si; \ - (pr_reg)[14] = (regs)->di; \ - (pr_reg)[15] = (regs)->orig_ax; \ - (pr_reg)[16] = (regs)->ip; \ - (pr_reg)[17] = (regs)->cs; \ - (pr_reg)[18] = (regs)->flags; \ - (pr_reg)[19] = (regs)->sp; \ - (pr_reg)[20] = (regs)->ss; \ - (pr_reg)[21] = current->thread.fs; \ - (pr_reg)[22] = current->thread.gs; \ - asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \ - asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \ - asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \ - asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v; \ -} while(0); - /* I'm not sure if we can use '-' here */ #define ELF_PLATFORM ("x86_64") extern void set_personality_64bit(void); @@ -236,18 +179,7 @@ extern int vdso_enabled; struct task_struct; -extern int dump_task_regs (struct task_struct *, elf_gregset_t *); -extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); - -#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) -#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) - #ifdef CONFIG_X86_32 -extern int dump_task_extended_fpu (struct task_struct *, - struct user_fxsr_struct *); -#define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) \ - dump_task_extended_fpu(tsk, elf_xfpregs) -#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index de435b9114d..ba8105ca822 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h @@ -327,20 +327,6 @@ static inline void clear_fpu(struct task_struct *tsk) #endif /* CONFIG_X86_64 */ -/* - * ptrace request handlers... - */ -extern int get_fpregs(struct user_i387_struct __user *buf, - struct task_struct *tsk); -extern int set_fpregs(struct task_struct *tsk, - struct user_i387_struct __user *buf); - -struct user_fxsr_struct; -extern int get_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *tsk); -extern int set_fpxregs(struct task_struct *tsk, - struct user_fxsr_struct __user *buf); - /* * i387 state interaction */ diff --git a/include/asm-x86/math_emu.h b/include/asm-x86/math_emu.h index a4b0aa3320e..9bf4ae93ab1 100644 --- a/include/asm-x86/math_emu.h +++ b/include/asm-x86/math_emu.h @@ -1,11 +1,6 @@ #ifndef _I386_MATH_EMU_H #define _I386_MATH_EMU_H -#include - -int restore_i387_soft(void *s387, struct _fpstate __user *buf); -int save_i387_soft(void *s387, struct _fpstate __user *buf); - /* This structure matches the layout of the data saved to the stack following a device-not-present interrupt, part of it saved automatically by the 80386/80486. -- cgit v1.2.2 From a97f52e67890fda6b373c1c1895ff1c1c69b36c8 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:55 +0100 Subject: x86: compat_binfmt_elf This switches x86-64's 32-bit ELF support to use the shared fs/compat_binfmt_elf.c code instead of our own ia32_binfmt.c. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/elf.h | 88 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 24 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index d6bf7421d7b..dab4744f958 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -73,6 +73,9 @@ typedef struct user_fxsr_struct elf_fpxregset_t; #endif #ifdef __KERNEL__ +#include + +extern unsigned int vdso_enabled; /* * This is used to ensure we don't load something for the wrong architecture. @@ -84,7 +87,6 @@ typedef struct user_fxsr_struct elf_fpxregset_t; #include #include /* for savesegment */ #include -#include #define elf_check_arch(x) elf_check_arch_ia32(x) @@ -106,7 +108,6 @@ typedef struct user_fxsr_struct elf_fpxregset_t; #define ELF_PLATFORM (utsname()->machine) #define set_personality_64bit() do { } while (0) -extern unsigned int vdso_enabled; #else /* CONFIG_X86_32 */ @@ -118,29 +119,57 @@ extern unsigned int vdso_enabled; #define elf_check_arch(x) \ ((x)->e_machine == EM_X86_64) +#define compat_elf_check_arch(x) elf_check_arch_ia32(x) + +static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp) +{ + asm volatile("movl %0,%%fs" :: "r" (0)); + asm volatile("movl %0,%%es; movl %0,%%ds" : : "r" (__USER32_DS)); + load_gs_index(0); + regs->ip = ip; + regs->sp = sp; + regs->flags = X86_EFLAGS_IF; + regs->cs = __USER32_CS; + regs->ss = __USER32_DS; +} + +static inline void elf_common_init(struct thread_struct *t, + struct pt_regs *regs, const u16 ds) +{ + regs->ax = regs->bx = regs->cx = regs->dx = 0; + regs->si = regs->di = regs->bp = 0; + regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0; + regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0; + t->fs = t->gs = 0; + t->fsindex = t->gsindex = 0; + t->ds = t->es = ds; +} + #define ELF_PLAT_INIT(_r, load_addr) do { \ - struct task_struct *cur = current; \ - (_r)->bx = 0; (_r)->cx = 0; (_r)->dx = 0; \ - (_r)->si = 0; (_r)->di = 0; (_r)->bp = 0; \ - (_r)->ax = 0; \ - (_r)->r8 = 0; \ - (_r)->r9 = 0; \ - (_r)->r10 = 0; \ - (_r)->r11 = 0; \ - (_r)->r12 = 0; \ - (_r)->r13 = 0; \ - (_r)->r14 = 0; \ - (_r)->r15 = 0; \ - cur->thread.fs = 0; cur->thread.gs = 0; \ - cur->thread.fsindex = 0; cur->thread.gsindex = 0; \ - cur->thread.ds = 0; cur->thread.es = 0; \ + elf_common_init(¤t->thread, _r, 0); \ clear_thread_flag(TIF_IA32); \ } while (0) +#define COMPAT_ELF_PLAT_INIT(regs, load_addr) \ + elf_common_init(¤t->thread, regs, __USER_DS) +#define compat_start_thread(regs, ip, sp) do { \ + start_ia32_thread(regs, ip, sp); \ + set_fs(USER_DS); \ + } while (0) +#define COMPAT_SET_PERSONALITY(ex, ibcs2) do { \ + if (test_thread_flag(TIF_IA32)) \ + clear_thread_flag(TIF_ABI_PENDING); \ + else \ + set_thread_flag(TIF_ABI_PENDING); \ + current->personality |= force_personality32; \ + } while (0) +#define COMPAT_ELF_PLATFORM ("i686") + /* I'm not sure if we can use '-' here */ #define ELF_PLATFORM ("x86_64") extern void set_personality_64bit(void); -extern int vdso_enabled; +extern unsigned int sysctl_vsyscall32; +extern int force_personality32; #endif /* !CONFIG_X86_32 */ @@ -179,17 +208,19 @@ extern int vdso_enabled; struct task_struct; +#define ARCH_DLINFO_IA32(vdso_enabled) \ +do if (vdso_enabled) { \ + NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ +} while (0) + #ifdef CONFIG_X86_32 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) -/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ +#define ARCH_DLINFO ARCH_DLINFO_IA32(vdso_enabled) -#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) +/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ #else /* CONFIG_X86_32 */ @@ -203,6 +234,12 @@ do if (vdso_enabled) { \ NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\ } while (0) +#define AT_SYSINFO 32 + +#define COMPAT_ARCH_DLINFO ARCH_DLINFO_IA32(sysctl_vsyscall32) + +#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) + #endif /* !CONFIG_X86_32 */ #define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) @@ -216,6 +253,9 @@ struct linux_binprm; extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); +extern int syscall32_setup_pages(struct linux_binprm *, int exstack); +#define compat_arch_setup_additional_pages syscall32_setup_pages + extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk -- cgit v1.2.2 From 7ba65c7e17a292fe1e6e48fd38d1b1ecb626b586 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:57 +0100 Subject: x86: remove __init modifier from header declaration This patch removes the __init modifier from an extern function declaration in acpi.h. Besides not being strictly needed, it requires the inclusion of linux/init.h, which is usually not even included directly, increasing header mess by a lot. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/acpi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/acpi.h b/include/asm-x86/acpi.h index c477e574175..2feb0c494be 100644 --- a/include/asm-x86/acpi.h +++ b/include/asm-x86/acpi.h @@ -158,7 +158,7 @@ extern int acpi_scan_nodes(unsigned long start, unsigned long end); #ifdef CONFIG_X86_64 # define NR_NODE_MEMBLKS (MAX_NUMNODES*2) #endif -extern void __init acpi_fake_nodes(const struct bootnode *fake_nodes, +extern void acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes); #else static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, -- cgit v1.2.2 From 2f66dcc933f012cd487c5ebf5d400e50b1d5c488 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:57 +0100 Subject: x86: finish processor.h integration What's left in processor_32.h and processor_64.h cannot be cleanly integrated. However, it's just a couple of definitions. They are moved to processor.h around ifdefs, and the original files are deleted. Note that there's much less headers included in the final version. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 140 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index ea222cfe7b0..e6fa06fee72 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -7,12 +7,24 @@ struct task_struct; struct mm_struct; +#include +#include +#include #include -#include +#include +#include +#include +#include #include +#include #include +#include +#include +#include #include #include +#include +#include /* * Default implementation of macro that returns current @@ -285,9 +297,13 @@ union i387_union { }; #ifdef CONFIG_X86_32 -# include "processor_32.h" +/* + * the following now lives in the per cpu area: + * extern int cpu_llc_id[NR_CPUS]; + */ +DECLARE_PER_CPU(u8, cpu_llc_id); #else -# include "processor_64.h" +DECLARE_PER_CPU(struct orig_ist, orig_ist); #endif extern void print_cpu_info(struct cpuinfo_x86 *); @@ -770,6 +786,124 @@ static inline void prefetchw(const void *x) } #define spin_lock_prefetch(x) prefetchw(x) +#ifdef CONFIG_X86_32 +/* + * User space process size: 3GB (default). + */ +#define TASK_SIZE (PAGE_OFFSET) + +#define INIT_THREAD { \ + .sp0 = sizeof(init_stack) + (long)&init_stack, \ + .vm86_info = NULL, \ + .sysenter_cs = __KERNEL_CS, \ + .io_bitmap_ptr = NULL, \ + .fs = __KERNEL_PERCPU, \ +} + +/* + * Note that the .io_bitmap member must be extra-big. This is because + * the CPU will access an additional byte beyond the end of the IO + * permission bitmap. The extra byte must be all 1 bits, and must + * be within the limit. + */ +#define INIT_TSS { \ + .x86_tss = { \ + .sp0 = sizeof(init_stack) + (long)&init_stack, \ + .ss0 = __KERNEL_DS, \ + .ss1 = __KERNEL_CS, \ + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ + }, \ + .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, \ +} + +#define start_thread(regs, new_eip, new_esp) do { \ + __asm__("movl %0,%%gs": :"r" (0)); \ + regs->fs = 0; \ + set_fs(USER_DS); \ + regs->ds = __USER_DS; \ + regs->es = __USER_DS; \ + regs->ss = __USER_DS; \ + regs->cs = __USER_CS; \ + regs->ip = new_eip; \ + regs->sp = new_esp; \ +} while (0) + + +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +#define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) +#define KSTK_TOP(info) \ +({ \ + unsigned long *__ptr = (unsigned long *)(info); \ + (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \ +}) + +/* + * The below -8 is to reserve 8 bytes on top of the ring0 stack. + * This is necessary to guarantee that the entire "struct pt_regs" + * is accessable even if the CPU haven't stored the SS/ESP registers + * on the stack (interrupt gate does not save these registers + * when switching to the same priv ring). + * Therefore beware: accessing the ss/esp fields of the + * "struct pt_regs" is possible, but they may contain the + * completely wrong values. + */ +#define task_pt_regs(task) \ +({ \ + struct pt_regs *__regs__; \ + __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \ + __regs__ - 1; \ +}) + +#define KSTK_ESP(task) (task_pt_regs(task)->sp) + +#else +/* + * User space process size. 47bits minus one guard page. + */ +#define TASK_SIZE64 (0x800000000000UL - 4096) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \ + 0xc0000000 : 0xFFFFe000) + +#define TASK_SIZE (test_thread_flag(TIF_IA32) ? \ + IA32_PAGE_OFFSET : TASK_SIZE64) +#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? \ + IA32_PAGE_OFFSET : TASK_SIZE64) + +#define INIT_THREAD { \ + .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ +} + +#define INIT_TSS { \ + .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ +} + +#define start_thread(regs, new_rip, new_rsp) do { \ + asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \ + load_gs_index(0); \ + (regs)->ip = (new_rip); \ + (regs)->sp = (new_rsp); \ + write_pda(oldrsp, (new_rsp)); \ + (regs)->cs = __USER_CS; \ + (regs)->ss = __USER_DS; \ + (regs)->flags = 0x200; \ + set_fs(USER_DS); \ +} while (0) + +/* + * Return saved PC of a blocked thread. + * What is this good for? it will be always the scheduler or ret_from_fork. + */ +#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8)) + +#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) +#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ +#endif /* CONFIG_X86_64 */ + /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -- cgit v1.2.2 From aca46ba29298810b329518b96f97ace985027b59 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:31:58 +0100 Subject: x86: remove unused include/asm-x86/processor_32/64.h remove unused include/asm-x86/processor_32/64.h. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor_32.h | 97 ------------------------------------------ include/asm-x86/processor_64.h | 66 ---------------------------- 2 files changed, 163 deletions(-) delete mode 100644 include/asm-x86/processor_32.h delete mode 100644 include/asm-x86/processor_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h deleted file mode 100644 index 0d6a430b2bc..00000000000 --- a/include/asm-x86/processor_32.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 1994 Linus Torvalds - */ - -#ifndef __ASM_I386_PROCESSOR_H -#define __ASM_I386_PROCESSOR_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * the following now lives in the per cpu area: - * extern int cpu_llc_id[NR_CPUS]; - */ -DECLARE_PER_CPU(u8, cpu_llc_id); - -/* - * User space process size: 3GB (default). - */ -#define TASK_SIZE (PAGE_OFFSET) - -#define INIT_THREAD { \ - .sp0 = sizeof(init_stack) + (long)&init_stack, \ - .vm86_info = NULL, \ - .sysenter_cs = __KERNEL_CS, \ - .io_bitmap_ptr = NULL, \ - .fs = __KERNEL_PERCPU, \ -} - -/* - * Note that the .io_bitmap member must be extra-big. This is because - * the CPU will access an additional byte beyond the end of the IO - * permission bitmap. The extra byte must be all 1 bits, and must - * be within the limit. - */ -#define INIT_TSS { \ - .x86_tss = { \ - .sp0 = sizeof(init_stack) + (long)&init_stack, \ - .ss0 = __KERNEL_DS, \ - .ss1 = __KERNEL_CS, \ - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ - }, \ - .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ -} - -#define start_thread(regs, new_eip, new_esp) do { \ - __asm__("movl %0,%%gs": :"r" (0)); \ - regs->fs = 0; \ - set_fs(USER_DS); \ - regs->ds = __USER_DS; \ - regs->es = __USER_DS; \ - regs->ss = __USER_DS; \ - regs->cs = __USER_CS; \ - regs->ip = new_eip; \ - regs->sp = new_esp; \ -} while (0) - - -extern unsigned long thread_saved_pc(struct task_struct *tsk); - -#define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) -#define KSTK_TOP(info) \ -({ \ - unsigned long *__ptr = (unsigned long *)(info); \ - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \ -}) - -/* - * The below -8 is to reserve 8 bytes on top of the ring0 stack. - * This is necessary to guarantee that the entire "struct pt_regs" - * is accessable even if the CPU haven't stored the SS/ESP registers - * on the stack (interrupt gate does not save these registers - * when switching to the same priv ring). - * Therefore beware: accessing the ss/esp fields of the - * "struct pt_regs" is possible, but they may contain the - * completely wrong values. - */ -#define task_pt_regs(task) \ -({ \ - struct pt_regs *__regs__; \ - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \ - __regs__ - 1; \ -}) - -#define KSTK_ESP(task) (task_pt_regs(task)->sp) - -#endif /* __ASM_I386_PROCESSOR_H */ diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h deleted file mode 100644 index 04ce823ea7e..00000000000 --- a/include/asm-x86/processor_64.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 1994 Linus Torvalds - */ - -#ifndef __ASM_X86_64_PROCESSOR_H -#define __ASM_X86_64_PROCESSOR_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * User space process size. 47bits minus one guard page. - */ -#define TASK_SIZE64 (0x800000000000UL - 4096) - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) - -#define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64) -#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) - - - -DECLARE_PER_CPU(struct orig_ist, orig_ist); - -#define INIT_THREAD { \ - .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ -} - -#define INIT_TSS { \ - .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ -} - -#define start_thread(regs,new_rip,new_rsp) do { \ - asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \ - load_gs_index(0); \ - (regs)->ip = (new_rip); \ - (regs)->sp = (new_rsp); \ - write_pda(oldrsp, (new_rsp)); \ - (regs)->cs = __USER_CS; \ - (regs)->ss = __USER_DS; \ - (regs)->flags = 0x200; \ - set_fs(USER_DS); \ -} while(0) - -/* - * Return saved PC of a blocked thread. - * What is this good for? it will be always the scheduler or ret_from_fork. - */ -#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8)) - -#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) -#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ - -#endif /* __ASM_X86_64_PROCESSOR_H */ -- cgit v1.2.2 From bca25bafbb390eeec376ac994954b99489d198ec Mon Sep 17 00:00:00 2001 From: Parag Warudkar Date: Wed, 30 Jan 2008 13:31:59 +0100 Subject: x86: fix dmi_alloc() to not advance alloc index in case of dmi_alloc() for CONFIG_X86_64 is defined to allocate from a static array and it maintains a allocation index which is advanced each time allocation is attempted - it gets incremented even if an allocation fails thereby depriving any future request that may be small enough to be satisfied from the array. Fix this by first testing if allocation is going to be possible and incrementing alloc index only then. Signed-off-by: Parag Warudkar Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/dmi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/dmi.h b/include/asm-x86/dmi.h index 8e2b0e6aa8e..5008c365e6e 100644 --- a/include/asm-x86/dmi.h +++ b/include/asm-x86/dmi.h @@ -22,8 +22,9 @@ extern char dmi_alloc_data[DMI_MAX_DATA]; static inline void *dmi_alloc(unsigned len) { int idx = dmi_alloc_index; - if ((dmi_alloc_index += len) > DMI_MAX_DATA) + if ((dmi_alloc_index + len) > DMI_MAX_DATA) return NULL; + dmi_alloc_index += len; return dmi_alloc_data + idx; } -- cgit v1.2.2 From bde6f5f59c2b2b48a7a849c129d5b48838fe77ee Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Wed, 30 Jan 2008 13:32:01 +0100 Subject: x86: voluntary leave_mm before entering ACPI C3 Aviod TLB flush IPIs during C3 states by voluntary leave_mm() before entering C3. The performance impact of TLB flush on C3 should not be significant with respect to C3 wakeup latency. Also, CPUs tend to flush TLB in hardware while in C3 anyways. On a 8 logical CPU system, running make -j2, the number of tlbflush IPIs goes down from 40 per second to ~ 0. Total number of interrupts during the run of this workload was ~1200 per second, which makes it ~3% savings in wakeups. There was no measurable performance or power impact however. [ akpm@linux-foundation.org: symbol export fixes. ] Signed-off-by: Venkatesh Pallipadi Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/acpi.h | 3 +++ include/asm-x86/mmu.h | 8 ++++++++ include/asm-x86/mmu_context_32.h | 2 -- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/acpi.h b/include/asm-x86/acpi.h index 2feb0c494be..98a9ca26653 100644 --- a/include/asm-x86/acpi.h +++ b/include/asm-x86/acpi.h @@ -27,6 +27,7 @@ #include #include +#include #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long @@ -167,4 +168,6 @@ static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, } #endif +#define acpi_unlazy_tlb(x) leave_mm(x) + #endif /*__X86_ASM_ACPI_H*/ diff --git a/include/asm-x86/mmu.h b/include/asm-x86/mmu.h index 3f922c8e1c8..efa962c3889 100644 --- a/include/asm-x86/mmu.h +++ b/include/asm-x86/mmu.h @@ -20,4 +20,12 @@ typedef struct { void *vdso; } mm_context_t; +#ifdef CONFIG_SMP +void leave_mm(int cpu); +#else +static inline void leave_mm(int cpu) +{ +} +#endif + #endif /* _ASM_X86_MMU_H */ diff --git a/include/asm-x86/mmu_context_32.h b/include/asm-x86/mmu_context_32.h index 7eb0b0b1fb3..8198d1cca1f 100644 --- a/include/asm-x86/mmu_context_32.h +++ b/include/asm-x86/mmu_context_32.h @@ -32,8 +32,6 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) #endif } -void leave_mm(unsigned long cpu); - static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) -- cgit v1.2.2 From e6ae5d9540727b0e2e5e2fbeb683c84671ed0a31 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:32:03 +0100 Subject: x86, ptrace: support 32bit-cross-64bit BTS recording Support BTS recording of 32bit and 64bit tasks from 32bit or 64bit tasks. Signed-off-by: Markus Metzger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ds.h | 10 +++++----- include/asm-x86/ptrace-abi.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ds.h b/include/asm-x86/ds.h index b84040abee6..7881368142f 100644 --- a/include/asm-x86/ds.h +++ b/include/asm-x86/ds.h @@ -39,16 +39,16 @@ enum bts_qualifier { }; struct bts_struct { - enum bts_qualifier qualifier; + u64 qualifier; union { /* BTS_BRANCH */ struct { - long from_ip; - long to_ip; + u64 from_ip; + u64 to_ip; } lbr; /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */ - unsigned long jiffies; + u64 jiffies; } variant; }; @@ -64,7 +64,7 @@ extern int ds_get_bts_index(void *); extern int ds_set_overflow(void *, int); extern int ds_get_overflow(void *); extern int ds_clear(void *); -extern int ds_read_bts(void *, size_t, struct bts_struct *); +extern int ds_read_bts(void *, int, struct bts_struct *); extern int ds_write_bts(void *, const struct bts_struct *); extern unsigned long ds_debugctl_mask(void); extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *c); diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index cf2fe4633ee..32fe137822b 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -85,9 +85,9 @@ */ struct ptrace_bts_config { /* requested or actual size of BTS buffer in bytes */ - unsigned long size; + unsigned int size; /* bitmask of below flags */ - unsigned long flags; + unsigned int flags; }; #define PTRACE_BTS_O_TRACE 0x1 /* branch trace */ -- cgit v1.2.2 From cba4b65d359268c40679ca75ac92c0b93cecf6de Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:32:03 +0100 Subject: x86, ptrace: add buffer size checks Pass the buffer size for (most) ptrace commands that pass user-allocated buffers and check that size before accessing the buffer. Unfortunately, PTRACE_BTS_GET already uses all 4 parameters. Commands that access user buffers return the number of bytes or records read or written. Signed-off-by: Markus Metzger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace-abi.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 32fe137822b..bcf67044754 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -99,13 +99,15 @@ struct ptrace_bts_config { #define PTRACE_BTS_CONFIG 40 /* Configure branch trace recording. - DATA is ignored, ADDR points to a struct ptrace_bts_config. + ADDR points to a struct ptrace_bts_config. + DATA gives the size of that buffer. A new buffer is allocated, iff the size changes. + Returns the number of bytes read. */ #define PTRACE_BTS_STATUS 41 -/* Return the current configuration. - DATA is ignored, ADDR points to a struct ptrace_bts_config - that will contain the result. +/* Return the current configuration in a struct ptrace_bts_config + pointed to by ADDR; DATA gives the size of that buffer. + Returns the number of bytes written. */ #define PTRACE_BTS_SIZE 42 /* Return the number of available BTS records. @@ -123,8 +125,8 @@ struct ptrace_bts_config { */ #define PTRACE_BTS_DRAIN 45 /* Read all available BTS records and clear the buffer. - DATA is ignored. ADDR points to an array of struct bts_struct of - suitable size. + ADDR points to an array of struct bts_struct. + DATA gives the size of that buffer. BTS records are read from oldest to newest. Returns number of BTS records drained. */ -- cgit v1.2.2 From c6334593c61c71ab2e666c015eef13995736f49a Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:32:04 +0100 Subject: x86, ptrace: overflow signal API Establish the user API for sending a user-defined signal to the traced task on a BTS buffer overflow. This should complete the user API for the BTS ptrace extension. The patches so far implement wrap-around overflow handling as is needed for debugging. The remaining open is another overflow handling mechanism that sends a signal to the traced task on a buffer overflow. This will take some more time from my side. Since, from a user perspective, this occurs behind the scenes, the patch set should already be useful. More features may/will be added on top of it (overflow signal, pageable back-up buffers, kernel tracing, core file support, profiling, ...). Signed-off-by: Markus Metzger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace-abi.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index bcf67044754..b3b9e023afc 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -88,11 +88,13 @@ struct ptrace_bts_config { unsigned int size; /* bitmask of below flags */ unsigned int flags; + /* buffer overflow signal */ + unsigned int signal; }; #define PTRACE_BTS_O_TRACE 0x1 /* branch trace */ #define PTRACE_BTS_O_SCHED 0x2 /* scheduling events w/ jiffies */ -#define PTRACE_BTS_O_SIGNAL 0x4 /* send SIG? on buffer overflow +#define PTRACE_BTS_O_SIGNAL 0x4 /* send SIG on buffer overflow instead of wrapping around */ #define PTRACE_BTS_O_CUT_SIZE 0x8 /* cut requested size to max available instead of failing */ -- cgit v1.2.2 From a4746364da0c7caa155cc945a5c10312e7925b46 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:05 +0100 Subject: x86: adjust PVOP_CALL/VCALL macros for 64-bit This patch adjust the PVOP_VCALL and PVOP_CALL macros to work with x86_64. It has a different calling convention, and we use auxiliary macros to account for both calling conventions as cleanly as possible Comments are adjusted accordingly. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 87 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 22 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 24406703007..bef93277266 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -320,7 +320,7 @@ int paravirt_disable_iospace(void); * runtime. * * Normally, a call to a pv_op function is a simple indirect call: - * (paravirt_ops.operations)(args...). + * (pv_op_struct.operations)(args...). * * Unfortunately, this is a relatively slow operation for modern CPUs, * because it cannot necessarily determine what the destination @@ -330,11 +330,17 @@ int paravirt_disable_iospace(void); * calls are essentially free, because the call and return addresses * are completely predictable.) * - * These macros rely on the standard gcc "regparm(3)" calling + * For i386, these macros rely on the standard gcc "regparm(3)" calling * convention, in which the first three arguments are placed in %eax, * %edx, %ecx (in that order), and the remaining arguments are placed * on the stack. All caller-save registers (eax,edx,ecx) are expected * to be modified (either clobbered or used for return values). + * X86_64, on the other hand, already specifies a register-based calling + * conventions, returning at %rax, with parameteres going on %rdi, %rsi, + * %rdx, and %rcx. Note that for this reason, x86_64 does not need any + * special handling for dealing with 4 arguments, unlike i386. + * However, x86_64 also have to clobber all caller saved registers, which + * unfortunately, are quite a bit (r8 - r11) * * The call instruction itself is marked by placing its start address * and size into the .parainstructions section, so that @@ -357,10 +363,12 @@ int paravirt_disable_iospace(void); * the return type. The macro then uses sizeof() on that type to * determine whether its a 32 or 64 bit value, and places the return * in the right register(s) (just %eax for 32-bit, and %edx:%eax for - * 64-bit). + * 64-bit). For x86_64 machines, it just returns at %rax regardless of + * the return value size. * * 64-bit arguments are passed as a pair of adjacent 32-bit arguments - * in low,high order. + * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments + * in low,high order * * Small structures are passed and returned in registers. The macro * calling convention can't directly deal with this, so the wrapper @@ -370,46 +378,67 @@ int paravirt_disable_iospace(void); * means that all uses must be wrapped in inline functions. This also * makes sure the incoming and outgoing types are always correct. */ +#ifdef CONFIG_X86_32 +#define PVOP_VCALL_ARGS unsigned long __eax, __edx, __ecx +#define PVOP_CALL_ARGS PVOP_VCALL_ARGS +#define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \ + "=c" (__ecx) +#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS +#define EXTRA_CLOBBERS +#define VEXTRA_CLOBBERS +#else +#define PVOP_VCALL_ARGS unsigned long __edi, __esi, __edx, __ecx +#define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax +#define PVOP_VCALL_CLOBBERS "=D" (__edi), \ + "=S" (__esi), "=d" (__edx), \ + "=c" (__ecx) + +#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax) + +#define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11" +#define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11" +#endif + #define __PVOP_CALL(rettype, op, pre, post, ...) \ ({ \ rettype __ret; \ - unsigned long __eax, __edx, __ecx; \ + PVOP_CALL_ARGS; \ + /* This is 32-bit specific, but is okay in 64-bit */ \ + /* since this condition will never hold */ \ if (sizeof(rettype) > sizeof(unsigned long)) { \ asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : "=a" (__eax), "=d" (__edx), \ - "=c" (__ecx) \ + : PVOP_CALL_CLOBBERS \ : paravirt_type(op), \ paravirt_clobber(CLBR_ANY), \ ##__VA_ARGS__ \ - : "memory", "cc"); \ + : "memory", "cc" EXTRA_CLOBBERS); \ __ret = (rettype)((((u64)__edx) << 32) | __eax); \ } else { \ asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : "=a" (__eax), "=d" (__edx), \ - "=c" (__ecx) \ + : PVOP_CALL_CLOBBERS \ : paravirt_type(op), \ paravirt_clobber(CLBR_ANY), \ ##__VA_ARGS__ \ - : "memory", "cc"); \ + : "memory", "cc" EXTRA_CLOBBERS); \ __ret = (rettype)__eax; \ } \ __ret; \ }) #define __PVOP_VCALL(op, pre, post, ...) \ ({ \ - unsigned long __eax, __edx, __ecx; \ + PVOP_VCALL_ARGS; \ asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : "=a" (__eax), "=d" (__edx), "=c" (__ecx) \ + : PVOP_VCALL_CLOBBERS \ : paravirt_type(op), \ paravirt_clobber(CLBR_ANY), \ ##__VA_ARGS__ \ - : "memory", "cc"); \ + : "memory", "cc" VEXTRA_CLOBBERS); \ }) #define PVOP_CALL0(rettype, op) \ @@ -418,22 +447,26 @@ int paravirt_disable_iospace(void); __PVOP_VCALL(op, "", "") #define PVOP_CALL1(rettype, op, arg1) \ - __PVOP_CALL(rettype, op, "", "", "0" ((u32)(arg1))) + __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1))) #define PVOP_VCALL1(op, arg1) \ - __PVOP_VCALL(op, "", "", "0" ((u32)(arg1))) + __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1))) #define PVOP_CALL2(rettype, op, arg1, arg2) \ - __PVOP_CALL(rettype, op, "", "", "0" ((u32)(arg1)), "1" ((u32)(arg2))) + __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)), \ + "1" ((unsigned long)(arg2))) #define PVOP_VCALL2(op, arg1, arg2) \ - __PVOP_VCALL(op, "", "", "0" ((u32)(arg1)), "1" ((u32)(arg2))) + __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)), \ + "1" ((unsigned long)(arg2))) #define PVOP_CALL3(rettype, op, arg1, arg2, arg3) \ - __PVOP_CALL(rettype, op, "", "", "0" ((u32)(arg1)), \ - "1"((u32)(arg2)), "2"((u32)(arg3))) + __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)), \ + "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3))) #define PVOP_VCALL3(op, arg1, arg2, arg3) \ - __PVOP_VCALL(op, "", "", "0" ((u32)(arg1)), "1"((u32)(arg2)), \ - "2"((u32)(arg3))) + __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)), \ + "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3))) +/* This is the only difference in x86_64. We can make it much simpler */ +#ifdef CONFIG_X86_32 #define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ __PVOP_CALL(rettype, op, \ "push %[_arg4];", "lea 4(%%esp),%%esp;", \ @@ -444,6 +477,16 @@ int paravirt_disable_iospace(void); "push %[_arg4];", "lea 4(%%esp),%%esp;", \ "0" ((u32)(arg1)), "1" ((u32)(arg2)), \ "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4))) +#else +#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ + __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)), \ + "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)), \ + "3"((unsigned long)(arg4))) +#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ + __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)), \ + "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)), \ + "3"((unsigned long)(arg4))) +#endif static inline int paravirt_enabled(void) { -- cgit v1.2.2 From f72a9ef979c5a828c64deb88ebba743f7d899907 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:05 +0100 Subject: x86: cleanup write_tsc write_tsc() does not need to be enclosed in any paravirt closure, as it uses wrmsr(). So we rip off the duplicate in msr.h and the definition from paravirt.h Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 2 -- include/asm-x86/paravirt.h | 2 -- 2 files changed, 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 088652a62d5..bca8c395013 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -157,8 +157,6 @@ static inline int wrmsr_safe(unsigned msr, unsigned low, unsigned high) #define rdtscll(val) \ ((val) = native_read_tsc()) -#define write_tsc(val1,val2) wrmsr(0x10, val1, val2) - #define rdpmc(counter,low,high) \ do { \ u64 _l = native_read_pmc(counter); \ diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index bef93277266..66290f58e93 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -657,8 +657,6 @@ static inline unsigned long long paravirt_sched_clock(void) } #define calculate_cpu_khz() (pv_time_ops.get_cpu_khz()) -#define write_tsc(val1,val2) wrmsr(0x10, val1, val2) - static inline unsigned long long paravirt_read_pmc(int counter) { return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter); -- cgit v1.2.2 From e5aaac443635c7c6f842f0bf8169f71f3236d574 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:05 +0100 Subject: x86: provide paravirtualized hook for rdtscp This patch adds a field in pv_cpu_ops for a paravirtualized hook for rdtscp, needed for x86_64. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 66290f58e93..8f7984319c3 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -120,6 +120,7 @@ struct pv_cpu_ops { u64 (*read_tsc)(void); u64 (*read_pmc)(int counter); + unsigned long long (*read_tscp)(unsigned int *aux); /* These two are jmp to, not actually called. */ void (*irq_enable_syscall_ret)(void); @@ -668,6 +669,27 @@ static inline unsigned long long paravirt_read_pmc(int counter) high = _l >> 32; \ } while(0) +static inline unsigned long long paravirt_rdtscp(unsigned int *aux) +{ + return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); +} + +#define rdtscp(low, high, aux) \ +do { \ + int __aux; \ + unsigned long __val = paravirt_rdtscp(&__aux); \ + (low) = (u32)__val; \ + (high) = (u32)(__val >> 32); \ + (aux) = __aux; \ +} while (0) + +#define rdtscpll(val, aux) \ +do { \ + unsigned long __aux; \ + val = paravirt_rdtscp(&__aux); \ + (aux) = __aux; \ +} while (0) + static inline void load_TR_desc(void) { PVOP_VCALL0(pv_cpu_ops.load_tr_desc); -- cgit v1.2.2 From 658be9d395630d30a501c850bde90ac791a678c9 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:06 +0100 Subject: x86: change assembly definition of paravirt_patch_site To account for differences in x86_64, we change the macros that create raw instances of the paravirt_patch_site struct. We need to align 64-pointers to 64-bit boundaries, so we add an alignment directive. Also, we need to make room for a word-sized pointer, instead of a fixed 32-bit one Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 8f7984319c3..56389954d10 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -5,6 +5,7 @@ #ifdef CONFIG_PARAVIRT #include +#include /* Bitmask of what can be clobbered: usually at least eax. */ #define CLBR_NONE 0x0 @@ -281,7 +282,8 @@ extern struct pv_mmu_ops pv_mmu_ops; #define _paravirt_alt(insn_string, type, clobber) \ "771:\n\t" insn_string "\n" "772:\n" \ ".pushsection .parainstructions,\"a\"\n" \ - " .long 771b\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR " 771b\n" \ " .byte " type "\n" \ " .byte 772b-771b\n" \ " .short " clobber "\n" \ @@ -1159,17 +1161,25 @@ static inline unsigned long __raw_local_irq_save(void) #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) -#define PARA_SITE(ptype, clobbers, ops) \ +#define _PVSITE(ptype, clobbers, ops, word, algn) \ 771:; \ ops; \ 772:; \ .pushsection .parainstructions,"a"; \ - .long 771b; \ + .align algn; \ + word 771b; \ .byte ptype; \ .byte 772b-771b; \ .short clobbers; \ .popsection + +#ifdef CONFIG_X86_64 +#define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) +#else +#define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) +#endif + #define INTERRUPT_RETURN \ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ jmp *%cs:pv_cpu_ops+PV_CPU_iret) -- cgit v1.2.2 From 6057fc827b3a9f2fe5db18b882ebf96500500b64 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:06 +0100 Subject: x86: adjust assembly macros on 64-bit as well. This patch adjust the paravirt macros used in assembly code to accomodate for x86_64 as well. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 56389954d10..854c19364da 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1159,8 +1159,6 @@ static inline unsigned long __raw_local_irq_save(void) #else /* __ASSEMBLY__ */ -#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) - #define _PVSITE(ptype, clobbers, ops, word, algn) \ 771:; \ ops; \ @@ -1175,8 +1173,14 @@ static inline unsigned long __raw_local_irq_save(void) #ifdef CONFIG_X86_64 +#define PV_SAVE_REGS pushq %rax; pushq %rdi; pushq %rcx; pushq %rdx +#define PV_RESTORE_REGS popq %rdx; popq %rcx; popq %rdi; popq %rax +#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8) #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) #else +#define PV_SAVE_REGS pushl %eax; pushl %edi; pushl %ecx; pushl %edx +#define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax +#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) #endif @@ -1186,25 +1190,27 @@ static inline unsigned long __raw_local_irq_save(void) #define DISABLE_INTERRUPTS(clobbers) \ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ - pushl %eax; pushl %ecx; pushl %edx; \ + PV_SAVE_REGS; \ call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \ - popl %edx; popl %ecx; popl %eax) \ + PV_RESTORE_REGS;) \ #define ENABLE_INTERRUPTS(clobbers) \ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ - pushl %eax; pushl %ecx; pushl %edx; \ + PV_SAVE_REGS; \ call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \ - popl %edx; popl %ecx; popl %eax) + PV_RESTORE_REGS;) #define ENABLE_INTERRUPTS_SYSCALL_RET \ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\ CLBR_NONE, \ jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret) +#ifdef CONFIG_X86_32 #define GET_CR0_INTO_EAX \ push %ecx; push %edx; \ call *pv_cpu_ops+PV_CPU_read_cr0; \ pop %edx; pop %ecx +#endif #endif /* __ASSEMBLY__ */ #endif /* CONFIG_PARAVIRT */ -- cgit v1.2.2 From 2e47d3e6c35bb5b78fea2b2584c7eeaf782f138d Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:07 +0100 Subject: x86: change irq functions to accomodate 64-bit This patch changes the irq handling function definitions in paravirt.h (like raw_local_irq_disable) to accomodate for x86_64. The differences are in the calling convention. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 854c19364da..0735a90f531 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1085,52 +1085,68 @@ struct paravirt_patch_site { extern struct paravirt_patch_site __parainstructions[], __parainstructions_end[]; +#ifdef CONFIG_X86_32 +#define PV_SAVE_REGS "pushl %%ecx; pushl %%edx;" +#define PV_RESTORE_REGS "popl %%edx; popl %%ecx" +#define PV_FLAGS_ARG "0" +#define PV_EXTRA_CLOBBERS +#define PV_VEXTRA_CLOBBERS +#else +/* We save some registers, but all of them, that's too much. We clobber all + * caller saved registers but the argument parameter */ +#define PV_SAVE_REGS "pushq %%rdi;" +#define PV_RESTORE_REGS "popq %%rdi;" +#define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx" +#define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx" +#define PV_FLAGS_ARG "D" +#endif + static inline unsigned long __raw_local_save_flags(void) { unsigned long f; - asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + asm volatile(paravirt_alt(PV_SAVE_REGS PARAVIRT_CALL - "popl %%edx; popl %%ecx") + PV_RESTORE_REGS) : "=a"(f) : paravirt_type(pv_irq_ops.save_fl), paravirt_clobber(CLBR_EAX) - : "memory", "cc"); + : "memory", "cc" PV_VEXTRA_CLOBBERS); return f; } static inline void raw_local_irq_restore(unsigned long f) { - asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + asm volatile(paravirt_alt(PV_SAVE_REGS PARAVIRT_CALL - "popl %%edx; popl %%ecx") + PV_RESTORE_REGS) : "=a"(f) - : "0"(f), + : PV_FLAGS_ARG(f), paravirt_type(pv_irq_ops.restore_fl), paravirt_clobber(CLBR_EAX) - : "memory", "cc"); + : "memory", "cc" PV_EXTRA_CLOBBERS); } static inline void raw_local_irq_disable(void) { - asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + asm volatile(paravirt_alt(PV_SAVE_REGS PARAVIRT_CALL - "popl %%edx; popl %%ecx") + PV_RESTORE_REGS) : : paravirt_type(pv_irq_ops.irq_disable), paravirt_clobber(CLBR_EAX) - : "memory", "eax", "cc"); + : "memory", "eax", "cc" PV_EXTRA_CLOBBERS); } static inline void raw_local_irq_enable(void) { - asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" + asm volatile(paravirt_alt(PV_SAVE_REGS PARAVIRT_CALL - "popl %%edx; popl %%ecx") + PV_RESTORE_REGS) : : paravirt_type(pv_irq_ops.irq_enable), paravirt_clobber(CLBR_EAX) - : "memory", "eax", "cc"); + : "memory", "eax", "cc" PV_EXTRA_CLOBBERS); } static inline unsigned long __raw_local_irq_save(void) @@ -1205,6 +1221,7 @@ static inline unsigned long __raw_local_irq_save(void) CLBR_NONE, \ jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret) + #ifdef CONFIG_X86_32 #define GET_CR0_INTO_EAX \ push %ecx; push %edx; \ -- cgit v1.2.2 From 4a8c4c4e10d1bc2c3bd80caabb6a76a66849f7e8 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:07 +0100 Subject: x86: add macro for privileged 64-bit operation i386 has a macro GET_CR0_INTO_EAX, used in early trap handling code. x86_64 has similar needs, only it needs to put cr2 into rcx. We provide a macro for such task, in the same way Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 0735a90f531..7d1c126e224 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1227,6 +1227,12 @@ static inline unsigned long __raw_local_irq_save(void) push %ecx; push %edx; \ call *pv_cpu_ops+PV_CPU_read_cr0; \ pop %edx; pop %ecx +#else +#define GET_CR2_INTO_RCX \ + call *pv_mmu_ops+PV_MMU_read_cr2; \ + movq %rax, %rcx; \ + xorq %rax, %rax; + #endif #endif /* __ASSEMBLY__ */ -- cgit v1.2.2 From e801f864ec7e5b149bd05337800e419f408523bb Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:08 +0100 Subject: x86: adds paravirt hook for swapgs This patch adds paravirt hook for swapgs operation, which is a privileged operation in x86_64. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 9 +++++++++ include/asm-x86/processor.h | 8 ++++++++ 2 files changed, 17 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 7d1c126e224..e8fbf742d42 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -127,6 +127,8 @@ struct pv_cpu_ops { void (*irq_enable_syscall_ret)(void); void (*iret)(void); + void (*swapgs)(void); + struct pv_lazy_ops lazy_mode; }; @@ -1228,6 +1230,13 @@ static inline unsigned long __raw_local_irq_save(void) call *pv_cpu_ops+PV_CPU_read_cr0; \ pop %edx; pop %ecx #else +#define SWAPGS \ + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ + PV_SAVE_REGS; \ + call *pv_cpu_ops+PV_CPU_swapgs; \ + PV_RESTORE_REGS \ + ) + #define GET_CR2_INTO_RCX \ call *pv_mmu_ops+PV_MMU_read_cr2; \ movq %rax, %rcx; \ diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index e6fa06fee72..72740c6f110 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -435,6 +435,13 @@ static inline void native_load_sp0(struct tss_struct *tss, #endif } +static inline void native_swapgs(void) +{ +#ifdef CONFIG_X86_64 + asm volatile("swapgs" ::: "memory"); +#endif +} + #ifdef CONFIG_PARAVIRT #include #else @@ -456,6 +463,7 @@ static inline void load_sp0(struct tss_struct *tss, } #define set_iopl_mask native_set_iopl_mask +#define SWAPGS swapgs #endif /* CONFIG_PARAVIRT */ /* -- cgit v1.2.2 From 1954448fb0c03dd5e301d7bef2dda71cd9b2fcf2 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:09 +0100 Subject: x86: cleanup CLI_STRING, STI_STRING and friends Since the advent of ticket locking, CLI_STRING, STI_STRING, and friends are not used anymore. They can now be safely deleted. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/spinlock.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h index 97d52b506af..2076d5d62d8 100644 --- a/include/asm-x86/spinlock.h +++ b/include/asm-x86/spinlock.h @@ -19,15 +19,6 @@ * (the type definitions are in asm/spinlock_types.h) */ -#ifdef CONFIG_PARAVIRT -#include -#else -#define CLI_STRING "cli" -#define STI_STRING "sti" -#define CLI_STI_CLOBBERS -#define CLI_STI_INPUT_ARGS -#endif /* CONFIG_PARAVIRT */ - #ifdef CONFIG_X86_32 typedef char _slock_t; # define LOCK_INS_DEC "decb" -- cgit v1.2.2 From 21438f7c138f0b893a32df3cc77434e39a2145f8 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:09 +0100 Subject: x86: add CLBR_ defines for 64-bit x86_64 needs a potentially larger clobber list than i386, due to its calling convention. So we add more CLBR_ defines for it. Note that CLBR_ANY is different for each of the architectures, since it comprises the notion of "All call clobbers in this architecture" Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index e8fbf742d42..5935c273af1 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -8,11 +8,24 @@ #include /* Bitmask of what can be clobbered: usually at least eax. */ -#define CLBR_NONE 0x0 -#define CLBR_EAX 0x1 -#define CLBR_ECX 0x2 -#define CLBR_EDX 0x4 -#define CLBR_ANY 0x7 +#define CLBR_NONE 0 +#define CLBR_EAX (1 << 0) +#define CLBR_ECX (1 << 1) +#define CLBR_EDX (1 << 2) + +#ifdef CONFIG_X86_64 +#define CLBR_RSI (1 << 3) +#define CLBR_RDI (1 << 4) +#define CLBR_R8 (1 << 5) +#define CLBR_R9 (1 << 6) +#define CLBR_R10 (1 << 7) +#define CLBR_R11 (1 << 8) +#define CLBR_ANY ((1 << 9) - 1) +#include +#else +/* CLBR_ANY should match all regs platform has. For i386, that's just it */ +#define CLBR_ANY ((1 << 3) - 1) +#endif /* X86_64 */ #ifndef __ASSEMBLY__ #include -- cgit v1.2.2 From 2f485ef568372af4680c4e2f8490efb9f2523b05 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:32:10 +0100 Subject: x86: move patching code to arch-specific file. The core patching code for paravirt is sufficiently different among i386 and x86_64, and we move them to specific files. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 5935c273af1..b35ed95166e 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -308,6 +308,11 @@ extern struct pv_mmu_ops pv_mmu_ops; #define paravirt_alt(insn_string) \ _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") +/* Simple instruction patching code. */ +#define DEF_NATIVE(ops, name, code) \ + extern const char start_##ops##_##name[], end_##ops##_##name[]; \ + asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") + unsigned paravirt_patch_nop(void); unsigned paravirt_patch_ignore(unsigned len); unsigned paravirt_patch_call(void *insnbuf, @@ -322,6 +327,9 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, unsigned paravirt_patch_insns(void *insnbuf, unsigned len, const char *start, const char *end); +unsigned native_patch(u8 type, u16 clobbers, void *ibuf, + unsigned long addr, unsigned len); + int paravirt_disable_iospace(void); /* -- cgit v1.2.2 From 27efeb67714608b28c0b213cceb6080749435c6b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:36 +0100 Subject: x86: make ptrace.h safe to include from assembler code Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace-abi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index b3b9e023afc..08a12b790a7 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -80,6 +80,7 @@ #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ +#ifndef __ASSEMBLY__ /* configuration/status structure used in PTRACE_BTS_CONFIG and PTRACE_BTS_STATUS commands. */ @@ -91,6 +92,7 @@ struct ptrace_bts_config { /* buffer overflow signal */ unsigned int signal; }; +#endif #define PTRACE_BTS_O_TRACE 0x1 /* branch trace */ #define PTRACE_BTS_O_SCHED 0x2 /* scheduling events w/ jiffies */ -- cgit v1.2.2 From de4218634e3df6d73a3e6cdfdf3a17fa3bc7e013 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:37 +0100 Subject: x86: implement support to synchronize RDTSC through MFENCE on AMD CPUs According to AMD RDTSC can be synchronized through MFENCE. Implement the necessary CPUID bit for that. Cc: andreas.herrmann3@amd.com Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 75e2f78a7fd..7d53eea8b94 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -79,6 +79,7 @@ /* 14 free */ #define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ +#define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ -- cgit v1.2.2 From 707fa8ed923b1b6a3d7af0d386b0b3abad28ed19 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:37 +0100 Subject: x86: Implement support to synchronize RDTSC with LFENCE on Intel CPUs According to Intel RDTSC can be always synchronized with LFENCE on all current CPUs. Implement the necessary CPUID bit for that. It is unclear yet if that is true for all future CPUs too, but if there's another way the kernel can be always updated. Cc: asit.k.mallick@intel.com Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 7d53eea8b94..c1a7e07859c 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -80,6 +80,7 @@ #define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */ +#define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ -- cgit v1.2.2 From bd61643ef6139ba44142f2ba6e79e03267e6b54a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:38 +0100 Subject: x86: move nop declarations into separate include file Moving things out of processor.h is always a good thing. Also needed to avoid include loop in later patch. Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/nops.h | 90 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor.h | 86 +------------------------------------------ 2 files changed, 91 insertions(+), 85 deletions(-) create mode 100644 include/asm-x86/nops.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/nops.h b/include/asm-x86/nops.h new file mode 100644 index 00000000000..fec025c7f58 --- /dev/null +++ b/include/asm-x86/nops.h @@ -0,0 +1,90 @@ +#ifndef _ASM_NOPS_H +#define _ASM_NOPS_H 1 + +/* Define nops for use with alternative() */ + +/* generic versions from gas */ +#define GENERIC_NOP1 ".byte 0x90\n" +#define GENERIC_NOP2 ".byte 0x89,0xf6\n" +#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" +#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" +#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 +#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 + +/* Opteron 64bit nops */ +#define K8_NOP1 GENERIC_NOP1 +#define K8_NOP2 ".byte 0x66,0x90\n" +#define K8_NOP3 ".byte 0x66,0x66,0x90\n" +#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" +#define K8_NOP5 K8_NOP3 K8_NOP2 +#define K8_NOP6 K8_NOP3 K8_NOP3 +#define K8_NOP7 K8_NOP4 K8_NOP3 +#define K8_NOP8 K8_NOP4 K8_NOP4 + +/* K7 nops */ +/* uses eax dependencies (arbitary choice) */ +#define K7_NOP1 GENERIC_NOP1 +#define K7_NOP2 ".byte 0x8b,0xc0\n" +#define K7_NOP3 ".byte 0x8d,0x04,0x20\n" +#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" +#define K7_NOP5 K7_NOP4 ASM_NOP1 +#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" +#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" +#define K7_NOP8 K7_NOP7 ASM_NOP1 + +/* P6 nops */ +/* uses eax dependencies (Intel-recommended choice) */ +#define P6_NOP1 GENERIC_NOP1 +#define P6_NOP2 ".byte 0x66,0x90\n" +#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" +#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" +#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" +#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" +#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" +#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" + +#if defined(CONFIG_MK8) +#define ASM_NOP1 K8_NOP1 +#define ASM_NOP2 K8_NOP2 +#define ASM_NOP3 K8_NOP3 +#define ASM_NOP4 K8_NOP4 +#define ASM_NOP5 K8_NOP5 +#define ASM_NOP6 K8_NOP6 +#define ASM_NOP7 K8_NOP7 +#define ASM_NOP8 K8_NOP8 +#elif defined(CONFIG_MK7) +#define ASM_NOP1 K7_NOP1 +#define ASM_NOP2 K7_NOP2 +#define ASM_NOP3 K7_NOP3 +#define ASM_NOP4 K7_NOP4 +#define ASM_NOP5 K7_NOP5 +#define ASM_NOP6 K7_NOP6 +#define ASM_NOP7 K7_NOP7 +#define ASM_NOP8 K7_NOP8 +#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \ + defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \ + defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4) +#define ASM_NOP1 P6_NOP1 +#define ASM_NOP2 P6_NOP2 +#define ASM_NOP3 P6_NOP3 +#define ASM_NOP4 P6_NOP4 +#define ASM_NOP5 P6_NOP5 +#define ASM_NOP6 P6_NOP6 +#define ASM_NOP7 P6_NOP7 +#define ASM_NOP8 P6_NOP8 +#else +#define ASM_NOP1 GENERIC_NOP1 +#define ASM_NOP2 GENERIC_NOP2 +#define ASM_NOP3 GENERIC_NOP3 +#define ASM_NOP4 GENERIC_NOP4 +#define ASM_NOP5 GENERIC_NOP5 +#define ASM_NOP6 GENERIC_NOP6 +#define ASM_NOP7 GENERIC_NOP7 +#define ASM_NOP8 GENERIC_NOP8 +#endif + +#define ASM_NOP_MAX 8 + +#endif diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 72740c6f110..41c002440de 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -20,6 +20,7 @@ struct mm_struct; #include #include #include +#include #include #include #include @@ -674,91 +675,6 @@ extern int bootloader_type; extern char ignore_fpu_irq; #define cache_line_size() (boot_cpu_data.x86_cache_alignment) -/* generic versions from gas */ -#define GENERIC_NOP1 ".byte 0x90\n" -#define GENERIC_NOP2 ".byte 0x89,0xf6\n" -#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" -#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" -#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 -#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 - -/* Opteron nops */ -#define K8_NOP1 GENERIC_NOP1 -#define K8_NOP2 ".byte 0x66,0x90\n" -#define K8_NOP3 ".byte 0x66,0x66,0x90\n" -#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" -#define K8_NOP5 K8_NOP3 K8_NOP2 -#define K8_NOP6 K8_NOP3 K8_NOP3 -#define K8_NOP7 K8_NOP4 K8_NOP3 -#define K8_NOP8 K8_NOP4 K8_NOP4 - -/* K7 nops */ -/* uses eax dependencies (arbitary choice) */ -#define K7_NOP1 GENERIC_NOP1 -#define K7_NOP2 ".byte 0x8b,0xc0\n" -#define K7_NOP3 ".byte 0x8d,0x04,0x20\n" -#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" -#define K7_NOP5 K7_NOP4 ASM_NOP1 -#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" -#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" -#define K7_NOP8 K7_NOP7 ASM_NOP1 - -/* P6 nops */ -/* uses eax dependencies (Intel-recommended choice) */ -#define P6_NOP1 GENERIC_NOP1 -#define P6_NOP2 ".byte 0x66,0x90\n" -#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" -#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n" -#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n" -#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n" -#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n" -#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n" - -#ifdef CONFIG_MK7 -#define ASM_NOP1 K7_NOP1 -#define ASM_NOP2 K7_NOP2 -#define ASM_NOP3 K7_NOP3 -#define ASM_NOP4 K7_NOP4 -#define ASM_NOP5 K7_NOP5 -#define ASM_NOP6 K7_NOP6 -#define ASM_NOP7 K7_NOP7 -#define ASM_NOP8 K7_NOP8 -#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \ - defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \ - defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4) || \ - defined(CONFIG_MPSC) -#define ASM_NOP1 P6_NOP1 -#define ASM_NOP2 P6_NOP2 -#define ASM_NOP3 P6_NOP3 -#define ASM_NOP4 P6_NOP4 -#define ASM_NOP5 P6_NOP5 -#define ASM_NOP6 P6_NOP6 -#define ASM_NOP7 P6_NOP7 -#define ASM_NOP8 P6_NOP8 -#elif defined(CONFIG_MK8) || defined(CONFIG_X86_64) -#define ASM_NOP1 K8_NOP1 -#define ASM_NOP2 K8_NOP2 -#define ASM_NOP3 K8_NOP3 -#define ASM_NOP4 K8_NOP4 -#define ASM_NOP5 K8_NOP5 -#define ASM_NOP6 K8_NOP6 -#define ASM_NOP7 K8_NOP7 -#define ASM_NOP8 K8_NOP8 -#else -#define ASM_NOP1 GENERIC_NOP1 -#define ASM_NOP2 GENERIC_NOP2 -#define ASM_NOP3 GENERIC_NOP3 -#define ASM_NOP4 GENERIC_NOP4 -#define ASM_NOP5 GENERIC_NOP5 -#define ASM_NOP6 GENERIC_NOP6 -#define ASM_NOP7 GENERIC_NOP7 -#define ASM_NOP8 GENERIC_NOP8 -#endif - -#define ASM_NOP_MAX 8 - #define HAVE_ARCH_PICK_MMAP_LAYOUT 1 #define ARCH_HAS_PREFETCHW #define ARCH_HAS_SPINLOCK_PREFETCH -- cgit v1.2.2 From fde1b3fa947c2512e3715962ebb1d3a6a9b9bb7d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:38 +0100 Subject: x86: introduce rdtsc_barrier() rdtsc_barrier() is a new barrier primitive that stops RDTSC speculation to avoid races with timer interrupts on other CPUs. It expands either to LFENCE (for Intel CPUs) or MFENCE (for AMD CPUs) which stops RDTSC on all currently known microarchitectures that implement SSE. On CPUs without SSE there is generally no RDTSC speculation. [ mingo@elte.hu: renamed it to rdtsc_barrier() and made it x86-only ] Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 6c7d1fda499..39474f2957a 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -395,5 +396,17 @@ void default_idle(void); #define set_mb(var, value) do { var = value; barrier(); } while (0) #endif +/* + * Stop RDTSC speculation. This is needed when you need to use RDTSC + * (or get_cycles or vread that possibly accesses the TSC) in a defined + * code region. + * + * (Could use an alternative three way for this if there was one.) + */ +static inline void rdtsc_barrier(void) +{ + alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); + alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); +} #endif -- cgit v1.2.2 From cdc7957d1954908a39a6964e9c6f643916e76c4b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:39 +0100 Subject: x86: move native_read_tsc() offline move native_read_tsc() offline. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index bca8c395013..decfec4ab17 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -91,13 +91,7 @@ static inline int native_write_msr_safe(unsigned int msr, return err; } -static inline unsigned long long native_read_tsc(void) -{ - DECLARE_ARGS(val, low, high); - - asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); - return EAX_EDX_VAL(val, low, high); -} +extern unsigned long long native_read_tsc(void); static inline unsigned long long native_read_pmc(int counter) { -- cgit v1.2.2 From e4026440130b84101f2da7f5a0c7a3b046173d3c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:39 +0100 Subject: x86: map vsyscalls early enough map vsyscalls early enough. This is important if a __vsyscall_fn function is used by other kernel code too. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/vsyscall.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/vsyscall.h b/include/asm-x86/vsyscall.h index f01c49f5d10..17b3700949b 100644 --- a/include/asm-x86/vsyscall.h +++ b/include/asm-x86/vsyscall.h @@ -36,6 +36,8 @@ extern volatile unsigned long __jiffies; extern int vgetcpu_mode; extern struct timezone sys_tz; +extern void map_vsyscall(void); + #endif /* __KERNEL__ */ #endif /* _ASM_X86_64_VSYSCALL_H_ */ -- cgit v1.2.2 From 6d63de8dbcda98511206897562ecfcdacf18f523 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:39 +0100 Subject: x86: remove get_cycles_sync rdtsc is now speculation-safe, so no need for the sync variants of the APIs. [ mingo@elte.hu: removed the nsec_barrier() complication. ] Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/tsc.h | 60 +++++++-------------------------------------------- 1 file changed, 8 insertions(+), 52 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index 40130372413..f51a50da35a 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -36,62 +36,18 @@ static inline cycles_t get_cycles(void) return ret; } -/* Like get_cycles, but make sure the CPU is synchronized. */ -static __always_inline cycles_t __get_cycles_sync(void) +static inline cycles_t vget_cycles(void) { - unsigned long long ret; - unsigned eax, edx; - /* - * Use RDTSCP if possible; it is guaranteed to be synchronous - * and doesn't cause a VMEXIT on Hypervisors + * We only do VDSOs on TSC capable CPUs, so this shouldnt + * access boot_cpu_data (which is not VDSO-safe): */ - alternative_io(ASM_NOP3, ".byte 0x0f,0x01,0xf9", X86_FEATURE_RDTSCP, - ASM_OUTPUT2("=a" (eax), "=d" (edx)), - "a" (0U), "d" (0U) : "ecx", "memory"); - ret = (((unsigned long long)edx) << 32) | ((unsigned long long)eax); - if (ret) - return ret; - - /* - * Don't do an additional sync on CPUs where we know - * RDTSC is already synchronous: - */ - alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC, - "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); - - return 0; -} - -static __always_inline cycles_t get_cycles_sync(void) -{ - unsigned long long ret; - ret = __get_cycles_sync(); - if (!ret) - rdtscll(ret); - return ret; -} - -#ifdef CONFIG_PARAVIRT -/* - * For paravirt guests, some functionalities are executed through function - * pointers in the various pvops structures. - * These function pointers exist inside the kernel and can not - * be accessed by user space. To avoid this, we make a copy of the - * get_cycles_sync (called in kernel) but force the use of native_read_tsc. - * Ideally, the guest should set up it's own clock and vread - */ -static __always_inline long long vget_cycles_sync(void) -{ - unsigned long long ret; - ret = __get_cycles_sync(); - if (!ret) - ret = native_read_tsc(); - return ret; -} -#else -# define vget_cycles_sync() get_cycles_sync() +#ifndef CONFIG_X86_TSC + if (!cpu_has_tsc) + return 0; #endif + return (cycles_t) native_read_tsc(); +} extern void tsc_init(void); extern void mark_tsc_unstable(char *reason); -- cgit v1.2.2 From 92767af0e3904b4d35ed547fb514ff6cb227e678 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:40 +0100 Subject: x86: fix sched_clock() [ andi@firstfloor.org: build fix ] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr.h | 11 +++++++++++ include/asm-x86/tsc.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index decfec4ab17..204a8a30fec 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -93,6 +93,17 @@ static inline int native_write_msr_safe(unsigned int msr, extern unsigned long long native_read_tsc(void); +static __always_inline unsigned long long __native_read_tsc(void) +{ + DECLARE_ARGS(val, low, high); + + rdtsc_barrier(); + asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); + rdtsc_barrier(); + + return EAX_EDX_VAL(val, low, high); +} + static inline unsigned long long native_read_pmc(int counter) { DECLARE_ARGS(val, low, high); diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index f51a50da35a..071e0ce5b66 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -46,7 +46,7 @@ static inline cycles_t vget_cycles(void) if (!cpu_has_tsc) return 0; #endif - return (cycles_t) native_read_tsc(); + return (cycles_t) __native_read_tsc(); } extern void tsc_init(void); -- cgit v1.2.2 From 68071a96655c883b316da9ef497f6dec8953529f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:32:40 +0100 Subject: x86: remove the now unused X86_FEATURE_SYNC_RDTSC we need to know whether RDTSC is synchronous or not. Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index c1a7e07859c..93c143fb8a5 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -77,7 +77,7 @@ #define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ #define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ /* 14 free */ -#define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ +/* 15 free */ #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */ #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ -- cgit v1.2.2 From 83a5101bf2fa7dcf09ffd436078a021d32c97f85 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:41 +0100 Subject: x86: page.h: unify constants # HG changeset patch # User Jeremy Fitzhardinge # Date 1199317360 28800 # Node ID ba0ec40a50a7aef1a3153cea124c35e261f5a2df # Parent c45c263179cb78284b6b869c574457df088027d1 x86: page.h: unify constants There are many constants which are shared by 32 and 64-bit. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 125 ++++++++++++++++++++++++++++++++++++++++++---- include/asm-x86/page_32.h | 46 ----------------- include/asm-x86/page_64.h | 74 ++------------------------- 3 files changed, 119 insertions(+), 126 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index a757eb26141..e0fa4a032ea 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -1,13 +1,116 @@ -#ifdef __KERNEL__ -# ifdef CONFIG_X86_32 -# include "page_32.h" -# else -# include "page_64.h" -# endif +#ifndef _ASM_X86_PAGE_H +#define _ASM_X86_PAGE_H + +#include + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#define PHYSICAL_PAGE_MASK (PAGE_MASK & __PHYSICAL_MASK) + +#define LARGE_PAGE_SIZE (_AC(1,UL) << PMD_SHIFT) +#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) + +#define HPAGE_SHIFT PMD_SHIFT +#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) +#define HPAGE_MASK (~(HPAGE_SIZE - 1)) +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +#define __PHYSICAL_MASK ((_AC(1,UL) << __PHYSICAL_MASK_SHIFT) - 1) +#define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1) + + +#ifdef CONFIG_X86_64 +#define THREAD_ORDER 1 +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) +#define CURRENT_MASK (~(THREAD_SIZE-1)) + +#define EXCEPTION_STACK_ORDER 0 +#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) + +#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) +#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) + +#define IRQSTACK_ORDER 2 +#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) + +#define STACKFAULT_STACK 1 +#define DOUBLEFAULT_STACK 2 +#define NMI_STACK 3 +#define DEBUG_STACK 4 +#define MCE_STACK 5 +#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ + +#define __PAGE_OFFSET _AC(0xffff810000000000, UL) + +#define __PHYSICAL_START CONFIG_PHYSICAL_START +#define __KERNEL_ALIGN 0x200000 + +/* + * Make sure kernel is aligned to 2MB address. Catching it at compile + * time is better. Change your config file and compile the kernel + * for a 2MB aligned address (CONFIG_PHYSICAL_START) + */ +#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 +#error "CONFIG_PHYSICAL_START must be a multiple of 2MB" +#endif + +#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) +#define __START_KERNEL_map _AC(0xffffffff80000000, UL) + +/* See Documentation/x86_64/mm.txt for a description of the memory map. */ +#define __PHYSICAL_MASK_SHIFT 46 +#define __VIRTUAL_MASK_SHIFT 48 + +#define KERNEL_TEXT_SIZE (40*1024*1024) +#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) + +#endif /* CONFIG_X86_64 */ + +#ifdef CONFIG_X86_32 + +/* + * This handles the memory map. + * + * A __PAGE_OFFSET of 0xC0000000 means that the kernel has + * a virtual address space of one gigabyte, which limits the + * amount of physical memory you can use to about 950MB. + * + * If you want more physical memory than this then see the CONFIG_HIGHMEM4G + * and CONFIG_HIGHMEM64G options in the kernel configuration. + */ +#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) + +#ifdef CONFIG_X86_PAE +#define __PHYSICAL_MASK_SHIFT 36 +#define __VIRTUAL_MASK_SHIFT 32 +#else /* !CONFIG_X86_PAE */ +#define __PHYSICAL_MASK_SHIFT 32 +#define __VIRTUAL_MASK_SHIFT 32 +#endif /* CONFIG_X86_PAE */ + +#ifdef CONFIG_HUGETLB_PAGE +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA +#endif + +#endif /* CONFIG_X86_32 */ + +#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) + +#define VM_DATA_DEFAULT_FLAGS \ + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + + +#ifdef CONFIG_X86_32 +# include "page_32.h" #else -# ifdef __i386__ -# include "page_32.h" -# else -# include "page_64.h" -# endif +# include "page_64.h" #endif + +#endif /* _ASM_X86_PAGE_H */ diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index c620c934e55..69e520059b2 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -1,14 +1,6 @@ #ifndef _I386_PAGE_H #define _I386_PAGE_H -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) -#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT) - #ifdef __KERNEL__ #ifndef __ASSEMBLY__ @@ -111,7 +103,6 @@ static inline pte_t native_make_pte(unsigned long long val) #define __pmd(x) native_make_pmd(x) #endif -#define HPAGE_SHIFT 21 #include #else /* !CONFIG_X86_PAE */ typedef struct { unsigned long pte_low; } pte_t; @@ -139,19 +130,11 @@ static inline pte_t native_make_pte(unsigned long val) return (pte_t) { .pte_low = val }; } -#define HPAGE_SHIFT 22 #include #endif /* CONFIG_X86_PAE */ #define PTE_MASK PAGE_MASK -#ifdef CONFIG_HUGETLB_PAGE -#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) -#define HPAGE_MASK (~(HPAGE_SIZE - 1)) -#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) -#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA -#endif - #define pgprot_val(x) ((x).pgprot) #define __pgprot(x) ((pgprot_t) { (x) } ) @@ -164,22 +147,6 @@ static inline pte_t native_make_pte(unsigned long val) #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - -/* - * This handles the memory map.. We could make this a config - * option, but too many people screw it up, and too few need - * it. - * - * A __PAGE_OFFSET of 0xC0000000 means that the kernel has - * a virtual address space of one gigabyte, which limits the - * amount of physical memory you can use to about 950MB. - * - * If you want more physical memory than this then see the CONFIG_HIGHMEM4G - * and CONFIG_HIGHMEM64G options in the kernel configuration. - */ - #ifndef __ASSEMBLY__ struct vm_area_struct; @@ -196,14 +163,6 @@ extern int page_is_ram(unsigned long pagenr); #endif /* __ASSEMBLY__ */ -#ifdef __ASSEMBLY__ -#define __PAGE_OFFSET CONFIG_PAGE_OFFSET -#else -#define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET) -#endif - - -#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) #define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) @@ -219,11 +178,6 @@ extern int page_is_ram(unsigned long pagenr); #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #include #include diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index 068b5e4cea4..69ef7cf9dad 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -1,42 +1,6 @@ #ifndef _X86_64_PAGE_H #define _X86_64_PAGE_H -#include - -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) -#define PHYSICAL_PAGE_MASK (~(PAGE_SIZE-1) & __PHYSICAL_MASK) - -#define THREAD_ORDER 1 -#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) -#define CURRENT_MASK (~(THREAD_SIZE-1)) - -#define EXCEPTION_STACK_ORDER 0 -#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) - -#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) -#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) - -#define IRQSTACK_ORDER 2 -#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) - -#define STACKFAULT_STACK 1 -#define DOUBLEFAULT_STACK 2 -#define NMI_STACK 3 -#define DEBUG_STACK 4 -#define MCE_STACK 5 -#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ - -#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) -#define LARGE_PAGE_SIZE (_AC(1,UL) << PMD_SHIFT) - -#define HPAGE_SHIFT PMD_SHIFT -#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) -#define HPAGE_MASK (~(HPAGE_SIZE - 1)) -#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) - #ifdef __KERNEL__ #ifndef __ASSEMBLY__ @@ -90,35 +54,6 @@ extern unsigned long phys_base; #endif /* !__ASSEMBLY__ */ -#define __PHYSICAL_START CONFIG_PHYSICAL_START -#define __KERNEL_ALIGN 0x200000 - -/* - * Make sure kernel is aligned to 2MB address. Catching it at compile - * time is better. Change your config file and compile the kernel - * for a 2MB aligned address (CONFIG_PHYSICAL_START) - */ -#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 -#error "CONFIG_PHYSICAL_START must be a multiple of 2MB" -#endif - -#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) -#define __START_KERNEL_map _AC(0xffffffff80000000, UL) -#define __PAGE_OFFSET _AC(0xffff810000000000, UL) - -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - -/* See Documentation/x86_64/mm.txt for a description of the memory map. */ -#define __PHYSICAL_MASK_SHIFT 46 -#define __PHYSICAL_MASK ((_AC(1,UL) << __PHYSICAL_MASK_SHIFT) - 1) -#define __VIRTUAL_MASK_SHIFT 48 -#define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1) - -#define KERNEL_TEXT_SIZE (40*1024*1024) -#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) -#define PAGE_OFFSET __PAGE_OFFSET - #ifndef __ASSEMBLY__ #include @@ -138,10 +73,6 @@ extern unsigned long __phys_addr(unsigned long); #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) -#define VM_DATA_DEFAULT_FLAGS \ - (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - #define __HAVE_ARCH_GATE_AREA 1 #define vmemmap ((struct page *)VMEMMAP_START) @@ -150,4 +81,9 @@ extern unsigned long __phys_addr(unsigned long); #endif /* __KERNEL__ */ +#ifdef CONFIG_FLATMEM +#define pfn_valid(pfn) ((pfn) < end_pfn) +#endif + + #endif /* _X86_64_PAGE_H */ -- cgit v1.2.2 From 345b904c3f7c24fbfadfee7cddd5896d13b176d9 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:42 +0100 Subject: x86: page.h: unify page copying and clearing # HG changeset patch # User Jeremy Fitzhardinge # Date 1199317362 28800 # Node ID 4d9a413a0f4c1d98dbea704f0366457b5117045d # Parent ba0ec40a50a7aef1a3153cea124c35e261f5a2df x86: page.h: unify page copying and clearing Move, and to some extent unify, the various page copying and clearing functions. The only unification here is that both architectures use the same function for copying/clearing user and kernel pages. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/page_32.h | 53 --------------------------------------------- include/asm-x86/page_64.h | 20 ----------------- 3 files changed, 55 insertions(+), 73 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index e0fa4a032ea..2ebb6977e00 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -70,6 +70,11 @@ #define KERNEL_TEXT_SIZE (40*1024*1024) #define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) +#ifndef __ASSEMBLY__ +void clear_page(void *page); +void copy_page(void *to, void *from); +#endif /* !__ASSEMBLY__ */ + #endif /* CONFIG_X86_64 */ #ifdef CONFIG_X86_32 @@ -98,6 +103,34 @@ #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #endif +#ifndef __ASSEMBLY__ +#ifdef CONFIG_X86_USE_3DNOW +#include + +static inline void clear_page(void *page) +{ + mmx_clear_page(page); +} + +static inline void copy_page(void *to, void *from) +{ + mmx_copy_page(to, from); +} +#else /* !CONFIG_X86_USE_3DNOW */ +#include + +static inline void clear_page(void *page) +{ + memset(page, 0, PAGE_SIZE); +} + +static inline void copy_page(void *to, void *from) +{ + memcpy(to, from, PAGE_SIZE); +} +#endif /* CONFIG_X86_3DNOW */ +#endif /* !__ASSEMBLY__ */ + #endif /* CONFIG_X86_32 */ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) @@ -107,6 +140,28 @@ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#ifndef __ASSEMBLY__ +struct page; + +static void inline clear_user_page(void *page, unsigned long vaddr, + struct page *pg) +{ + clear_page(page); +} + +static void inline copy_user_page(void *to, void *from, unsigned long vaddr, + struct page *topage) +{ + copy_page(to, from); +} + +#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ + alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) +#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE + +#endif /* __ASSEMBLY__ */ + + #ifdef CONFIG_X86_32 # include "page_32.h" #else diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index 69e520059b2..b4750ef4492 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -4,59 +4,6 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ -#include - -#ifdef CONFIG_X86_USE_3DNOW - -#include - -static inline void clear_page(void *page) -{ - mmx_clear_page(page); -} - -static inline void copy_page(void *to, void *from) -{ - mmx_copy_page(to, from); -} - -#else - -/* - * On older X86 processors it's not a win to use MMX here it seems. - * Maybe the K6-III ? - */ - -static inline void clear_page(void *page) -{ - memset(page, 0, PAGE_SIZE); -} - -static inline void copy_page(void *to, void *from) -{ - memcpy(to, from, PAGE_SIZE); -} - -#endif - -struct page; - -static void inline clear_user_page(void *page, unsigned long vaddr, - struct page *pg) -{ - clear_page(page); -} - -static void inline copy_user_page(void *to, void *from, unsigned long vaddr, - struct page *topage) -{ - copy_page(to, from); -} - -#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ - alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) -#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE - /* * These are used to make use of C type-checking.. */ diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index 69ef7cf9dad..f5e0543b8af 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -7,26 +7,6 @@ extern unsigned long end_pfn; extern unsigned long end_pfn_map; -void clear_page(void *page); -void copy_page(void *to, void *from); - -struct page; - -static void inline clear_user_page(void *page, unsigned long vaddr, - struct page *pg) -{ - clear_page(page); -} - -static void inline copy_user_page(void *to, void *from, unsigned long vaddr, - struct page *topage) -{ - copy_page(to, from); -} - -#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ - alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) -#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE /* * These are used to make use of C type-checking.. */ -- cgit v1.2.2 From 3da1bcc2659de27094592e5a037d0b1d59351e03 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:42 +0100 Subject: x86: page.h: move and unify types for pagetable entry, #1 based on: Subject: x86: page.h: move and unify types for pagetable entry From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 2ebb6977e00..911d7e0b3cd 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -9,6 +9,7 @@ #define PAGE_MASK (~(PAGE_SIZE-1)) #define PHYSICAL_PAGE_MASK (PAGE_MASK & __PHYSICAL_MASK) +#define PTE_MASK PHYSICAL_PAGE_MASK #define LARGE_PAGE_SIZE (_AC(1,UL) << PMD_SHIFT) #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) @@ -24,8 +25,13 @@ #define __PHYSICAL_MASK ((_AC(1,UL) << __PHYSICAL_MASK_SHIFT) - 1) #define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1) +#ifndef __ASSEMBLY__ +#include +#endif #ifdef CONFIG_X86_64 +#define PAGETABLE_LEVELS 4 + #define THREAD_ORDER 1 #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) #define CURRENT_MASK (~(THREAD_SIZE-1)) -- cgit v1.2.2 From 7a2389b457a03f226b441b5c53f9808d4eefdcea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:42 +0100 Subject: x86: page.h: move and unify types for pagetable entry, #2 based on: Subject: x86: page.h: move and unify types for pagetable entry From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 5c252d9fee1..3f280105d7b 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -79,12 +79,12 @@ static inline void set_pte(pte_t *dst, pte_t val) static inline void set_pmd(pmd_t *dst, pmd_t val) { - pmd_val(*dst) = pmd_val(val); + *dst = val; } static inline void set_pud(pud_t *dst, pud_t val) { - pud_val(*dst) = pud_val(val); + *dst = val; } static inline void pud_clear (pud_t *pud) @@ -94,7 +94,7 @@ static inline void pud_clear (pud_t *pud) static inline void set_pgd(pgd_t *dst, pgd_t val) { - pgd_val(*dst) = pgd_val(val); + *dst = val; } static inline void pgd_clear (pgd_t * pgd) -- cgit v1.2.2 From ba2b6c525eec459e1c6397f0f3eaeeafad153eab Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:42 +0100 Subject: x86: page.h: move and unify types for pagetable entry, #3 based on: Subject: x86: page.h: move and unify types for pagetable entry From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 13 +++++++++++++ include/asm-x86/page_64.h | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 911d7e0b3cd..a522fbada97 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -79,6 +79,19 @@ #ifndef __ASSEMBLY__ void clear_page(void *page); void copy_page(void *to, void *from); + +/* + * These are used to make use of C type-checking.. + */ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; +typedef unsigned long phys_addr_t; + +typedef struct { pteval_t pte; } pte_t; + #endif /* !__ASSEMBLY__ */ #endif /* CONFIG_X86_64 */ diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index f5e0543b8af..f5e82c695d2 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -10,7 +10,6 @@ extern unsigned long end_pfn_map; /* * These are used to make use of C type-checking.. */ -typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pud; } pud_t; typedef struct { unsigned long pgd; } pgd_t; -- cgit v1.2.2 From d6e3cf63e927310f65e21132f1d1c50e3aa4c2b0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:43 +0100 Subject: x86: page.h: move and unify types for pagetable entry, #4 Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index a522fbada97..530439e0d34 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -92,6 +92,9 @@ typedef unsigned long phys_addr_t; typedef struct { pteval_t pte; } pte_t; +#define native_pte_val(x) ((x).pte) +#define native_make_pte(x) ((pte_t) { (x) } ) + #endif /* !__ASSEMBLY__ */ #endif /* CONFIG_X86_64 */ -- cgit v1.2.2 From 38f0f12793a490ac633dbba2418172b7abfa077e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:43 +0100 Subject: x86: page.h: move and unify types for pagetable entry, #5 based on: Subject: x86: page.h: move and unify types for pagetable entry From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/page_64.h | 21 -------------- 2 files changed, 72 insertions(+), 21 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 530439e0d34..014f087d7c2 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -181,6 +181,78 @@ static void inline 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 +#ifdef CONFIG_X86_64 +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 }; +} + +static inline pgdval_t native_pgd_val(pgd_t pgd) +{ + return pgd.pgd; +} + +#if PAGETABLE_LEVELS >= 3 +#if PAGETABLE_LEVELS == 4 +typedef struct { pudval_t pud; } pud_t; + +static inline pud_t native_make_pud(pmdval_t val) +{ + return (pud_t) { val }; +} + +static inline pudval_t native_pud_val(pud_t pud) +{ + return pud.pud; +} +#else /* PAGETABLE_LEVELS == 3 */ +#include +#endif /* PAGETABLE_LEVELS == 4 */ + +typedef struct { pmdval_t pmd; } pmd_t; + +static inline pmd_t native_make_pmd(pmdval_t val) +{ + return (pmd_t) { val }; +} + +static inline pmdval_t native_pmd_val(pmd_t pmd) +{ + return pmd.pmd; +} +#else /* PAGETABLE_LEVELS == 2 */ +#include +#endif /* PAGETABLE_LEVELS >= 3 */ + +#define pgprot_val(x) ((x).pgprot) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#ifdef CONFIG_PARAVIRT +#include +#else /* !CONFIG_PARAVIRT */ + +#define pgd_val(x) native_pgd_val(x) +#define __pgd(x) native_make_pgd(x) + +#ifndef __PAGETABLE_PUD_FOLDED +#define pud_val(x) native_pud_val(x) +#define __pud(x) native_make_pud(x) +#endif + +#ifndef __PAGETABLE_PMD_FOLDED +#define pmd_val(x) native_pmd_val(x) +#define __pmd(x) native_make_pmd(x) +#endif + +#define pte_val(x) native_pte_val(x) +#define __pte(x) native_make_pte(x) + +#endif /* CONFIG_PARAVIRT */ + +#endif /* CONFIG_X86_64 */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index f5e82c695d2..f8a07bf54c3 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -7,30 +7,9 @@ extern unsigned long end_pfn; extern unsigned long end_pfn_map; -/* - * These are used to make use of C type-checking.. - */ -typedef struct { unsigned long pmd; } pmd_t; -typedef struct { unsigned long pud; } pud_t; -typedef struct { unsigned long pgd; } pgd_t; -#define PTE_MASK PHYSICAL_PAGE_MASK - -typedef struct { unsigned long pgprot; } pgprot_t; extern unsigned long phys_base; -#define pte_val(x) ((x).pte) -#define pmd_val(x) ((x).pmd) -#define pud_val(x) ((x).pud) -#define pgd_val(x) ((x).pgd) -#define pgprot_val(x) ((x).pgprot) - -#define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pud(x) ((pud_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) -#define __pgprot(x) ((pgprot_t) { (x) } ) - #endif /* !__ASSEMBLY__ */ #ifndef __ASSEMBLY__ -- cgit v1.2.2 From 881d90d0daaeac018b0d5beb739dd825ccee0143 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:43 +0100 Subject: x86: page.h: move and unify types for pagetable entry # HG changeset patch # User Jeremy Fitzhardinge # Date 1199319654 28800 # Node ID 3bd7db6e85e66e7f3362874802df26a82fcb2d92 # Parent f7e7db3facd9406545103164f9be8f9ba1a2b549 x86: page.h: move and unify types for pagetable entry definitions This patch: 1. Defines arch-specific types for the contents of a pagetable entry. That is, 32-bit entries for 32-bit non-PAE, and 64-bit entries for 32-bit PAE and 64-bit. However, even though the latter two are the same size, they're defined with different types in order to retain compatibility with printk format strings, etc. 2. Defines arch-specific pte_t. This is different because 32-bit PAE defines it in two halves, whereas 32-bit PAE and 64-bit define it as a single entry. All the other pagetable levels can be defined in a common way. This also defines arch-specific pte_val/make_pte functions. 3. Define PAGETABLE_LEVELS for each architecture variation, for later use. 4. Define common pagetable entry accessors in a paravirt-compatible way. (64-bit does not yet use paravirt-ops in any way). 5. Convert a few instances of using a *_val() as an lvalue where it is no longer a macro. There are still places in the 64-bit code which use pte_val() as an lvalue. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 50 ++++++++++++++++++++++++++-- include/asm-x86/page_32.h | 83 ----------------------------------------------- 2 files changed, 48 insertions(+), 85 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 014f087d7c2..00353eb5666 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -116,9 +116,57 @@ typedef struct { pteval_t pte; } pte_t; #ifdef CONFIG_X86_PAE #define __PHYSICAL_MASK_SHIFT 36 #define __VIRTUAL_MASK_SHIFT 32 +#define PAGETABLE_LEVELS 3 + +#ifndef __ASSEMBLY__ +typedef u64 pteval_t; +typedef u64 pmdval_t; +typedef u64 pudval_t; +typedef u64 pgdval_t; +typedef u64 pgprotval_t; +typedef u64 phys_addr_t; + +typedef struct { unsigned long pte_low, pte_high; } pte_t; + +static inline unsigned long long native_pte_val(pte_t pte) +{ + return pte.pte_low | ((unsigned long long)pte.pte_high << 32); +} + +static inline pte_t native_make_pte(unsigned long long val) +{ + return (pte_t) { .pte_low = val, .pte_high = (val >> 32) } ; +} + +#endif /* __ASSEMBLY__ + */ #else /* !CONFIG_X86_PAE */ #define __PHYSICAL_MASK_SHIFT 32 #define __VIRTUAL_MASK_SHIFT 32 +#define PAGETABLE_LEVELS 2 + +#ifndef __ASSEMBLY__ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; +typedef unsigned long phys_addr_t; + +typedef struct { pteval_t pte_low; } pte_t; +typedef pte_t boot_pte_t; + +static inline unsigned long native_pte_val(pte_t pte) +{ + return pte.pte_low; +} + +static inline pte_t native_make_pte(unsigned long val) +{ + return (pte_t) { .pte_low = val }; +} + +#endif /* __ASSEMBLY__ */ #endif /* CONFIG_X86_PAE */ #ifdef CONFIG_HUGETLB_PAGE @@ -181,7 +229,6 @@ static void inline 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 -#ifdef CONFIG_X86_64 typedef struct { pgdval_t pgd; } pgd_t; typedef struct { pgprotval_t pgprot; } pgprot_t; @@ -252,7 +299,6 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) #endif /* CONFIG_PARAVIRT */ -#endif /* CONFIG_X86_64 */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index b4750ef4492..2d60661ab34 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -9,89 +9,6 @@ */ extern int nx_enabled; -#ifdef CONFIG_X86_PAE -typedef struct { unsigned long pte_low, pte_high; } pte_t; -typedef struct { unsigned long long pmd; } pmd_t; -typedef struct { unsigned long long pgd; } pgd_t; -typedef struct { unsigned long long pgprot; } pgprot_t; - -static inline unsigned long long native_pgd_val(pgd_t pgd) -{ - return pgd.pgd; -} - -static inline unsigned long long native_pmd_val(pmd_t pmd) -{ - return pmd.pmd; -} - -static inline unsigned long long native_pte_val(pte_t pte) -{ - return pte.pte_low | ((unsigned long long)pte.pte_high << 32); -} - -static inline pgd_t native_make_pgd(unsigned long long val) -{ - return (pgd_t) { val }; -} - -static inline pmd_t native_make_pmd(unsigned long long val) -{ - return (pmd_t) { val }; -} - -static inline pte_t native_make_pte(unsigned long long val) -{ - return (pte_t) { .pte_low = val, .pte_high = (val >> 32) } ; -} - -#ifndef CONFIG_PARAVIRT -#define pmd_val(x) native_pmd_val(x) -#define __pmd(x) native_make_pmd(x) -#endif - -#include -#else /* !CONFIG_X86_PAE */ -typedef struct { unsigned long pte_low; } pte_t; -typedef struct { unsigned long pgd; } pgd_t; -typedef struct { unsigned long pgprot; } pgprot_t; -#define boot_pte_t pte_t /* or would you rather have a typedef */ - -static inline unsigned long native_pgd_val(pgd_t pgd) -{ - return pgd.pgd; -} - -static inline unsigned long native_pte_val(pte_t pte) -{ - return pte.pte_low; -} - -static inline pgd_t native_make_pgd(unsigned long val) -{ - return (pgd_t) { val }; -} - -static inline pte_t native_make_pte(unsigned long val) -{ - return (pte_t) { .pte_low = val }; -} - -#include -#endif /* CONFIG_X86_PAE */ - -#define PTE_MASK PAGE_MASK - -#define pgprot_val(x) ((x).pgprot) -#define __pgprot(x) ((pgprot_t) { (x) } ) - -#ifndef CONFIG_PARAVIRT -#define pgd_val(x) native_pgd_val(x) -#define __pgd(x) native_make_pgd(x) -#define pte_val(x) native_pte_val(x) -#define __pte(x) native_make_pte(x) -#endif - #endif /* !__ASSEMBLY__ */ #ifndef __ASSEMBLY__ -- cgit v1.2.2 From 6724a1d2fc6b40d55f232b8dacc12a915878bdc7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:43 +0100 Subject: x86: page.h: move and unify types for pagetable entry, #6 based on: Subject: x86: page.h: move and unify types for pagetable entry From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 00353eb5666..ef393c3df90 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -22,7 +22,7 @@ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define __PHYSICAL_MASK ((_AC(1,UL) << __PHYSICAL_MASK_SHIFT) - 1) +#define __PHYSICAL_MASK _AT(phys_addr_t, (_AC(1,ULL) << __PHYSICAL_MASK_SHIFT) - 1) #define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1) #ifndef __ASSEMBLY__ -- cgit v1.2.2 From 98fd5aee348f0420afd1c636790d50aaaec6ceec Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:43 +0100 Subject: x86: page.h: move pa and va related things # HG changeset patch # User Jeremy Fitzhardinge # Date 1199319656 28800 # Node ID d617b72a0cc9d14bde2087d065c36d4ed3265761 # Parent 3bd7db6e85e66e7f3362874802df26a82fcb2d92 x86: page.h: move pa and va related things Move and unify the virtual<->physical address space conversion functions. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 24 ++++++++++++++++++++++++ include/asm-x86/page_32.h | 13 +------------ include/asm-x86/page_64.h | 13 ------------- 3 files changed, 25 insertions(+), 25 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index ef393c3df90..9830eeb5717 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -80,6 +80,9 @@ void clear_page(void *page); void copy_page(void *to, void *from); +extern unsigned long __phys_addr(unsigned long); +#define __phys_reloc_hide(x) (x) + /* * These are used to make use of C type-checking.. */ @@ -174,6 +177,13 @@ static inline pte_t native_make_pte(unsigned long val) #endif #ifndef __ASSEMBLY__ +#define __phys_addr(x) ((x)-PAGE_OFFSET) +#define __phys_reloc_hide(x) RELOC_HIDE((x), 0) + +#ifdef CONFIG_FLATMEM +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#endif /* CONFIG_FLATMEM */ + #ifdef CONFIG_X86_USE_3DNOW #include @@ -299,6 +309,20 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) #endif /* CONFIG_PARAVIRT */ +#define __pa(x) __phys_addr((unsigned long)(x)) +/* __pa_symbol should be used for C visible symbols. + This seems to be the official gcc blessed way to do such arithmetic. */ +#define __pa_symbol(x) __pa(__phys_reloc_hide((unsigned long)(x))) + +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) + +#define __boot_va(x) __va(x) +#define __boot_pa(x) __pa(x) + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + #endif /* __ASSEMBLY__ */ diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index 2d60661ab34..a27424a2ee0 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -29,18 +29,7 @@ extern int page_is_ram(unsigned long pagenr); #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) #define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -/* __pa_symbol should be used for C visible symbols. - This seems to be the official gcc blessed way to do such arithmetic. */ -#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0)) -#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) -#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) -#ifdef CONFIG_FLATMEM -#define pfn_valid(pfn) ((pfn) < max_mapnr) -#endif /* CONFIG_FLATMEM */ -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) - -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + #include #include diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index f8a07bf54c3..7094684270a 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -16,21 +16,8 @@ extern unsigned long phys_base; #include -extern unsigned long __phys_addr(unsigned long); - #endif /* __ASSEMBLY__ */ -#define __pa(x) __phys_addr((unsigned long)(x)) -#define __pa_symbol(x) __phys_addr((unsigned long)(x)) - -#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) -#define __boot_va(x) __va(x) -#define __boot_pa(x) __pa(x) - -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) - #define __HAVE_ARCH_GATE_AREA 1 #define vmemmap ((struct page *)VMEMMAP_START) -- cgit v1.2.2 From e62f4473f32a882a537b32cb7202da8d5d7c4f1f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:44 +0100 Subject: x86: page.h: move remaining bits and pieces # HG changeset patch # User Jeremy Fitzhardinge # Date 1199319657 28800 # Node ID bba9287641ff90e836d090d80b5c0a846aab7162 # Parent d617b72a0cc9d14bde2087d065c36d4ed3265761 x86: page.h: move remaining bits and pieces Move the remaining odds and ends into page.h. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 23 +++++++++++++++++++++++ include/asm-x86/page_32.h | 17 ----------------- include/asm-x86/page_64.h | 13 ------------- 3 files changed, 23 insertions(+), 30 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 9830eeb5717..f65a2ae6e32 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -80,6 +80,10 @@ void clear_page(void *page); void copy_page(void *to, void *from); +extern unsigned long end_pfn; +extern unsigned long end_pfn_map; +extern unsigned long phys_base; + extern unsigned long __phys_addr(unsigned long); #define __phys_reloc_hide(x) (x) @@ -98,6 +102,8 @@ typedef struct { pteval_t pte; } pte_t; #define native_pte_val(x) ((x).pte) #define native_make_pte(x) ((pte_t) { (x) } ) +#define vmemmap ((struct page *)VMEMMAP_START) + #endif /* !__ASSEMBLY__ */ #endif /* CONFIG_X86_64 */ @@ -184,6 +190,19 @@ static inline pte_t native_make_pte(unsigned long val) #define pfn_valid(pfn) ((pfn) < max_mapnr) #endif /* CONFIG_FLATMEM */ +extern int nx_enabled; + +/* + * This much address space is reserved for vmalloc() and iomap() + * as well as fixmap mappings. + */ +extern unsigned int __VMALLOC_RESERVE; +extern int sysctl_legacy_va_layout; +extern int page_is_ram(unsigned long pagenr); + +#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) +#define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) + #ifdef CONFIG_X86_USE_3DNOW #include @@ -325,6 +344,10 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) #endif /* __ASSEMBLY__ */ +#include +#include + +#define __HAVE_ARCH_GATE_AREA 1 #ifdef CONFIG_X86_32 # include "page_32.h" diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index a27424a2ee0..c27b41fd025 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -7,7 +7,6 @@ /* * These are used to make use of C type-checking.. */ -extern int nx_enabled; #endif /* !__ASSEMBLY__ */ @@ -15,26 +14,10 @@ extern int nx_enabled; struct vm_area_struct; -/* - * This much address space is reserved for vmalloc() and iomap() - * as well as fixmap mappings. - */ -extern unsigned int __VMALLOC_RESERVE; - -extern int sysctl_legacy_va_layout; - -extern int page_is_ram(unsigned long pagenr); - #endif /* __ASSEMBLY__ */ -#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) -#define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) - -#include -#include -#define __HAVE_ARCH_GATE_AREA 1 #endif /* __KERNEL__ */ #endif /* _I386_PAGE_H */ diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index 7094684270a..94d4803aab2 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -4,26 +4,13 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ -extern unsigned long end_pfn; -extern unsigned long end_pfn_map; - - -extern unsigned long phys_base; - #endif /* !__ASSEMBLY__ */ #ifndef __ASSEMBLY__ -#include #endif /* __ASSEMBLY__ */ -#define __HAVE_ARCH_GATE_AREA 1 -#define vmemmap ((struct page *)VMEMMAP_START) - -#include -#include - #endif /* __KERNEL__ */ #ifdef CONFIG_FLATMEM -- cgit v1.2.2 From 11b7c7dc945b8802c459baa3304c1b501d2bf872 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:44 +0100 Subject: x86: page.h: move things back to their own files # HG changeset patch # User Jeremy Fitzhardinge # Date 1199321648 28800 # Node ID 22f6a5902285b58bfc1fbbd9e183498c9017bd78 # Parent bba9287641ff90e836d090d80b5c0a846aab7162 x86: page.h: move things back to their own files Oops, asm/page.h has turned into an #ifdef hellhole. Move 32/64-specific things back to their own headers to make it somewhat comprehensible... Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/Kbuild | 3 +- include/asm-x86/page.h | 212 ++-------------------------------------------- include/asm-x86/page_32.h | 121 +++++++++++++++++++++++--- include/asm-x86/page_64.h | 74 ++++++++++++++-- 4 files changed, 187 insertions(+), 223 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild index 22e3a284c1e..e6189b22914 100644 --- a/include/asm-x86/Kbuild +++ b/include/asm-x86/Kbuild @@ -15,8 +15,7 @@ unifdef-y += ist.h unifdef-y += mce.h unifdef-y += msr.h unifdef-y += mtrr.h -unifdef-y += page_32.h -unifdef-y += page_64.h +unifdef-y += page.h unifdef-y += posix_types_32.h unifdef-y += posix_types_64.h unifdef-y += ptrace.h diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index f65a2ae6e32..3a00d0d9dfd 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -8,6 +8,8 @@ #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) +#ifdef __KERNEL__ + #define PHYSICAL_PAGE_MASK (PAGE_MASK & __PHYSICAL_MASK) #define PTE_MASK PHYSICAL_PAGE_MASK @@ -30,208 +32,11 @@ #endif #ifdef CONFIG_X86_64 -#define PAGETABLE_LEVELS 4 - -#define THREAD_ORDER 1 -#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) -#define CURRENT_MASK (~(THREAD_SIZE-1)) - -#define EXCEPTION_STACK_ORDER 0 -#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) - -#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) -#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) - -#define IRQSTACK_ORDER 2 -#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) - -#define STACKFAULT_STACK 1 -#define DOUBLEFAULT_STACK 2 -#define NMI_STACK 3 -#define DEBUG_STACK 4 -#define MCE_STACK 5 -#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ - -#define __PAGE_OFFSET _AC(0xffff810000000000, UL) - -#define __PHYSICAL_START CONFIG_PHYSICAL_START -#define __KERNEL_ALIGN 0x200000 - -/* - * Make sure kernel is aligned to 2MB address. Catching it at compile - * time is better. Change your config file and compile the kernel - * for a 2MB aligned address (CONFIG_PHYSICAL_START) - */ -#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 -#error "CONFIG_PHYSICAL_START must be a multiple of 2MB" -#endif - -#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) -#define __START_KERNEL_map _AC(0xffffffff80000000, UL) - -/* See Documentation/x86_64/mm.txt for a description of the memory map. */ -#define __PHYSICAL_MASK_SHIFT 46 -#define __VIRTUAL_MASK_SHIFT 48 - -#define KERNEL_TEXT_SIZE (40*1024*1024) -#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) - -#ifndef __ASSEMBLY__ -void clear_page(void *page); -void copy_page(void *to, void *from); - -extern unsigned long end_pfn; -extern unsigned long end_pfn_map; -extern unsigned long phys_base; - -extern unsigned long __phys_addr(unsigned long); -#define __phys_reloc_hide(x) (x) - -/* - * These are used to make use of C type-checking.. - */ -typedef unsigned long pteval_t; -typedef unsigned long pmdval_t; -typedef unsigned long pudval_t; -typedef unsigned long pgdval_t; -typedef unsigned long pgprotval_t; -typedef unsigned long phys_addr_t; - -typedef struct { pteval_t pte; } pte_t; - -#define native_pte_val(x) ((x).pte) -#define native_make_pte(x) ((pte_t) { (x) } ) - -#define vmemmap ((struct page *)VMEMMAP_START) - -#endif /* !__ASSEMBLY__ */ - +#include +#else +#include #endif /* CONFIG_X86_64 */ -#ifdef CONFIG_X86_32 - -/* - * This handles the memory map. - * - * A __PAGE_OFFSET of 0xC0000000 means that the kernel has - * a virtual address space of one gigabyte, which limits the - * amount of physical memory you can use to about 950MB. - * - * If you want more physical memory than this then see the CONFIG_HIGHMEM4G - * and CONFIG_HIGHMEM64G options in the kernel configuration. - */ -#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) - -#ifdef CONFIG_X86_PAE -#define __PHYSICAL_MASK_SHIFT 36 -#define __VIRTUAL_MASK_SHIFT 32 -#define PAGETABLE_LEVELS 3 - -#ifndef __ASSEMBLY__ -typedef u64 pteval_t; -typedef u64 pmdval_t; -typedef u64 pudval_t; -typedef u64 pgdval_t; -typedef u64 pgprotval_t; -typedef u64 phys_addr_t; - -typedef struct { unsigned long pte_low, pte_high; } pte_t; - -static inline unsigned long long native_pte_val(pte_t pte) -{ - return pte.pte_low | ((unsigned long long)pte.pte_high << 32); -} - -static inline pte_t native_make_pte(unsigned long long val) -{ - return (pte_t) { .pte_low = val, .pte_high = (val >> 32) } ; -} - -#endif /* __ASSEMBLY__ - */ -#else /* !CONFIG_X86_PAE */ -#define __PHYSICAL_MASK_SHIFT 32 -#define __VIRTUAL_MASK_SHIFT 32 -#define PAGETABLE_LEVELS 2 - -#ifndef __ASSEMBLY__ -typedef unsigned long pteval_t; -typedef unsigned long pmdval_t; -typedef unsigned long pudval_t; -typedef unsigned long pgdval_t; -typedef unsigned long pgprotval_t; -typedef unsigned long phys_addr_t; - -typedef struct { pteval_t pte_low; } pte_t; -typedef pte_t boot_pte_t; - -static inline unsigned long native_pte_val(pte_t pte) -{ - return pte.pte_low; -} - -static inline pte_t native_make_pte(unsigned long val) -{ - return (pte_t) { .pte_low = val }; -} - -#endif /* __ASSEMBLY__ */ -#endif /* CONFIG_X86_PAE */ - -#ifdef CONFIG_HUGETLB_PAGE -#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA -#endif - -#ifndef __ASSEMBLY__ -#define __phys_addr(x) ((x)-PAGE_OFFSET) -#define __phys_reloc_hide(x) RELOC_HIDE((x), 0) - -#ifdef CONFIG_FLATMEM -#define pfn_valid(pfn) ((pfn) < max_mapnr) -#endif /* CONFIG_FLATMEM */ - -extern int nx_enabled; - -/* - * This much address space is reserved for vmalloc() and iomap() - * as well as fixmap mappings. - */ -extern unsigned int __VMALLOC_RESERVE; -extern int sysctl_legacy_va_layout; -extern int page_is_ram(unsigned long pagenr); - -#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) -#define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) - -#ifdef CONFIG_X86_USE_3DNOW -#include - -static inline void clear_page(void *page) -{ - mmx_clear_page(page); -} - -static inline void copy_page(void *to, void *from) -{ - mmx_copy_page(to, from); -} -#else /* !CONFIG_X86_USE_3DNOW */ -#include - -static inline void clear_page(void *page) -{ - memset(page, 0, PAGE_SIZE); -} - -static inline void copy_page(void *to, void *from) -{ - memcpy(to, from, PAGE_SIZE); -} -#endif /* CONFIG_X86_3DNOW */ -#endif /* !__ASSEMBLY__ */ - -#endif /* CONFIG_X86_32 */ - #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) #define VM_DATA_DEFAULT_FLAGS \ @@ -349,10 +154,5 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) #define __HAVE_ARCH_GATE_AREA 1 -#ifdef CONFIG_X86_32 -# include "page_32.h" -#else -# include "page_64.h" -#endif - +#endif /* __KERNEL__ */ #endif /* _ASM_X86_PAGE_H */ diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index c27b41fd025..e424bef4395 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -1,23 +1,124 @@ -#ifndef _I386_PAGE_H -#define _I386_PAGE_H +#ifndef _ASM_X86_PAGE_32_H +#define _ASM_X86_PAGE_32_H + +/* + * This handles the memory map. + * + * A __PAGE_OFFSET of 0xC0000000 means that the kernel has + * a virtual address space of one gigabyte, which limits the + * amount of physical memory you can use to about 950MB. + * + * If you want more physical memory than this then see the CONFIG_HIGHMEM4G + * and CONFIG_HIGHMEM64G options in the kernel configuration. + */ +#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) + +#ifdef CONFIG_X86_PAE +#define __PHYSICAL_MASK_SHIFT 36 +#define __VIRTUAL_MASK_SHIFT 32 +#define PAGETABLE_LEVELS 3 -#ifdef __KERNEL__ #ifndef __ASSEMBLY__ +typedef u64 pteval_t; +typedef u64 pmdval_t; +typedef u64 pudval_t; +typedef u64 pgdval_t; +typedef u64 pgprotval_t; +typedef u64 phys_addr_t; -/* - * These are used to make use of C type-checking.. +typedef struct { unsigned long pte_low, pte_high; } pte_t; + +static inline unsigned long long native_pte_val(pte_t pte) +{ + return pte.pte_low | ((unsigned long long)pte.pte_high << 32); +} + +static inline pte_t native_make_pte(unsigned long long val) +{ + return (pte_t) { .pte_low = val, .pte_high = (val >> 32) } ; +} + +#endif /* __ASSEMBLY__ */ +#else /* !CONFIG_X86_PAE */ +#define __PHYSICAL_MASK_SHIFT 32 +#define __VIRTUAL_MASK_SHIFT 32 +#define PAGETABLE_LEVELS 2 + +#ifndef __ASSEMBLY__ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; +typedef unsigned long phys_addr_t; -#endif /* !__ASSEMBLY__ */ +typedef struct { pteval_t pte_low; } pte_t; +typedef pte_t boot_pte_t; + +static inline unsigned long native_pte_val(pte_t pte) +{ + return pte.pte_low; +} + +static inline pte_t native_make_pte(unsigned long val) +{ + return (pte_t) { .pte_low = val }; +} + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_X86_PAE */ + +#ifdef CONFIG_HUGETLB_PAGE +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA +#endif #ifndef __ASSEMBLY__ +#define __phys_addr(x) ((x)-PAGE_OFFSET) +#define __phys_reloc_hide(x) RELOC_HIDE((x), 0) + +#ifdef CONFIG_FLATMEM +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#endif /* CONFIG_FLATMEM */ + +extern int nx_enabled; + +/* + * This much address space is reserved for vmalloc() and iomap() + * as well as fixmap mappings. + */ +extern unsigned int __VMALLOC_RESERVE; +extern int sysctl_legacy_va_layout; +extern int page_is_ram(unsigned long pagenr); + +#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) +#define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) -struct vm_area_struct; +#ifdef CONFIG_X86_USE_3DNOW +#include -#endif /* __ASSEMBLY__ */ +static inline void clear_page(void *page) +{ + mmx_clear_page(page); +} +static inline void copy_page(void *to, void *from) +{ + mmx_copy_page(to, from); +} +#else /* !CONFIG_X86_USE_3DNOW */ +#include +static inline void clear_page(void *page) +{ + memset(page, 0, PAGE_SIZE); +} -#endif /* __KERNEL__ */ +static inline void copy_page(void *to, void *from) +{ + memcpy(to, from, PAGE_SIZE); +} +#endif /* CONFIG_X86_3DNOW */ +#endif /* !__ASSEMBLY__ */ -#endif /* _I386_PAGE_H */ +#endif /* _ASM_X86_PAGE_32_H */ diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index 94d4803aab2..ebf977a809a 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -1,17 +1,81 @@ #ifndef _X86_64_PAGE_H #define _X86_64_PAGE_H -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ +#define PAGETABLE_LEVELS 4 + +#define THREAD_ORDER 1 +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) +#define CURRENT_MASK (~(THREAD_SIZE-1)) + +#define EXCEPTION_STACK_ORDER 0 +#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) + +#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) +#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) + +#define IRQSTACK_ORDER 2 +#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) + +#define STACKFAULT_STACK 1 +#define DOUBLEFAULT_STACK 2 +#define NMI_STACK 3 +#define DEBUG_STACK 4 +#define MCE_STACK 5 +#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ + +#define __PAGE_OFFSET _AC(0xffff810000000000, UL) + +#define __PHYSICAL_START CONFIG_PHYSICAL_START +#define __KERNEL_ALIGN 0x200000 -#endif /* !__ASSEMBLY__ */ +/* + * Make sure kernel is aligned to 2MB address. Catching it at compile + * time is better. Change your config file and compile the kernel + * for a 2MB aligned address (CONFIG_PHYSICAL_START) + */ +#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 +#error "CONFIG_PHYSICAL_START must be a multiple of 2MB" +#endif + +#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) +#define __START_KERNEL_map _AC(0xffffffff80000000, UL) + +/* See Documentation/x86_64/mm.txt for a description of the memory map. */ +#define __PHYSICAL_MASK_SHIFT 46 +#define __VIRTUAL_MASK_SHIFT 48 + +#define KERNEL_TEXT_SIZE (40*1024*1024) +#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) #ifndef __ASSEMBLY__ +void clear_page(void *page); +void copy_page(void *to, void *from); + +extern unsigned long end_pfn; +extern unsigned long end_pfn_map; +extern unsigned long phys_base; + +extern unsigned long __phys_addr(unsigned long); +#define __phys_reloc_hide(x) (x) + +/* + * These are used to make use of C type-checking.. + */ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; +typedef unsigned long phys_addr_t; + +typedef struct { pteval_t pte; } pte_t; +#define native_pte_val(x) ((x).pte) +#define native_make_pte(x) ((pte_t) { (x) } ) -#endif /* __ASSEMBLY__ */ +#define vmemmap ((struct page *)VMEMMAP_START) -#endif /* __KERNEL__ */ +#endif /* !__ASSEMBLY__ */ #ifdef CONFIG_FLATMEM #define pfn_valid(pfn) ((pfn) < end_pfn) -- cgit v1.2.2 From 0c2bd5a5e3b9469c6ab2b96c403980f192db0bf7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:49 +0100 Subject: x86: clean up include/asm-x86/calling.h clean up include/asm-x86/calling.h. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/calling.h | 194 ++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 94 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/calling.h b/include/asm-x86/calling.h index 6f4f63af96e..f13e62e2cb3 100644 --- a/include/asm-x86/calling.h +++ b/include/asm-x86/calling.h @@ -1,162 +1,168 @@ -/* +/* * Some macros to handle stack frames in assembly. - */ + */ +#define R15 0 +#define R14 8 +#define R13 16 +#define R12 24 +#define RBP 32 +#define RBX 40 -#define R15 0 -#define R14 8 -#define R13 16 -#define R12 24 -#define RBP 32 -#define RBX 40 /* arguments: interrupts/non tracing syscalls only save upto here*/ -#define R11 48 -#define R10 56 -#define R9 64 -#define R8 72 -#define RAX 80 -#define RCX 88 -#define RDX 96 -#define RSI 104 -#define RDI 112 -#define ORIG_RAX 120 /* + error_code */ -/* end of arguments */ +#define R11 48 +#define R10 56 +#define R9 64 +#define R8 72 +#define RAX 80 +#define RCX 88 +#define RDX 96 +#define RSI 104 +#define RDI 112 +#define ORIG_RAX 120 /* + error_code */ +/* end of arguments */ + /* cpu exception frame or undefined in case of fast syscall. */ -#define RIP 128 -#define CS 136 -#define EFLAGS 144 -#define RSP 152 -#define SS 160 -#define ARGOFFSET R11 -#define SWFRAME ORIG_RAX +#define RIP 128 +#define CS 136 +#define EFLAGS 144 +#define RSP 152 +#define SS 160 + +#define ARGOFFSET R11 +#define SWFRAME ORIG_RAX - .macro SAVE_ARGS addskip=0,norcx=0,nor891011=0 - subq $9*8+\addskip,%rsp + .macro SAVE_ARGS addskip=0, norcx=0, nor891011=0 + subq $9*8+\addskip, %rsp CFI_ADJUST_CFA_OFFSET 9*8+\addskip - movq %rdi,8*8(%rsp) - CFI_REL_OFFSET rdi,8*8 - movq %rsi,7*8(%rsp) - CFI_REL_OFFSET rsi,7*8 - movq %rdx,6*8(%rsp) - CFI_REL_OFFSET rdx,6*8 + movq %rdi, 8*8(%rsp) + CFI_REL_OFFSET rdi, 8*8 + movq %rsi, 7*8(%rsp) + CFI_REL_OFFSET rsi, 7*8 + movq %rdx, 6*8(%rsp) + CFI_REL_OFFSET rdx, 6*8 .if \norcx .else - movq %rcx,5*8(%rsp) - CFI_REL_OFFSET rcx,5*8 + movq %rcx, 5*8(%rsp) + CFI_REL_OFFSET rcx, 5*8 .endif - movq %rax,4*8(%rsp) - CFI_REL_OFFSET rax,4*8 + movq %rax, 4*8(%rsp) + CFI_REL_OFFSET rax, 4*8 .if \nor891011 .else - movq %r8,3*8(%rsp) - CFI_REL_OFFSET r8,3*8 - movq %r9,2*8(%rsp) - CFI_REL_OFFSET r9,2*8 - movq %r10,1*8(%rsp) - CFI_REL_OFFSET r10,1*8 - movq %r11,(%rsp) - CFI_REL_OFFSET r11,0*8 + movq %r8, 3*8(%rsp) + CFI_REL_OFFSET r8, 3*8 + movq %r9, 2*8(%rsp) + CFI_REL_OFFSET r9, 2*8 + movq %r10, 1*8(%rsp) + CFI_REL_OFFSET r10, 1*8 + movq %r11, (%rsp) + CFI_REL_OFFSET r11, 0*8 .endif .endm -#define ARG_SKIP 9*8 - .macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0 +#define ARG_SKIP 9*8 + + .macro RESTORE_ARGS skiprax=0, addskip=0, skiprcx=0, skipr11=0, \ + skipr8910=0, skiprdx=0 .if \skipr11 .else - movq (%rsp),%r11 + movq (%rsp), %r11 CFI_RESTORE r11 .endif .if \skipr8910 .else - movq 1*8(%rsp),%r10 + movq 1*8(%rsp), %r10 CFI_RESTORE r10 - movq 2*8(%rsp),%r9 + movq 2*8(%rsp), %r9 CFI_RESTORE r9 - movq 3*8(%rsp),%r8 + movq 3*8(%rsp), %r8 CFI_RESTORE r8 .endif .if \skiprax .else - movq 4*8(%rsp),%rax + movq 4*8(%rsp), %rax CFI_RESTORE rax .endif .if \skiprcx .else - movq 5*8(%rsp),%rcx + movq 5*8(%rsp), %rcx CFI_RESTORE rcx .endif .if \skiprdx .else - movq 6*8(%rsp),%rdx + movq 6*8(%rsp), %rdx CFI_RESTORE rdx .endif - movq 7*8(%rsp),%rsi + movq 7*8(%rsp), %rsi CFI_RESTORE rsi - movq 8*8(%rsp),%rdi + movq 8*8(%rsp), %rdi CFI_RESTORE rdi .if ARG_SKIP+\addskip > 0 - addq $ARG_SKIP+\addskip,%rsp + addq $ARG_SKIP+\addskip, %rsp CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip) .endif - .endm + .endm .macro LOAD_ARGS offset - movq \offset(%rsp),%r11 - movq \offset+8(%rsp),%r10 - movq \offset+16(%rsp),%r9 - movq \offset+24(%rsp),%r8 - movq \offset+40(%rsp),%rcx - movq \offset+48(%rsp),%rdx - movq \offset+56(%rsp),%rsi - movq \offset+64(%rsp),%rdi - movq \offset+72(%rsp),%rax + movq \offset(%rsp), %r11 + movq \offset+8(%rsp), %r10 + movq \offset+16(%rsp), %r9 + movq \offset+24(%rsp), %r8 + movq \offset+40(%rsp), %rcx + movq \offset+48(%rsp), %rdx + movq \offset+56(%rsp), %rsi + movq \offset+64(%rsp), %rdi + movq \offset+72(%rsp), %rax .endm - -#define REST_SKIP 6*8 + +#define REST_SKIP 6*8 + .macro SAVE_REST - subq $REST_SKIP,%rsp + subq $REST_SKIP, %rsp CFI_ADJUST_CFA_OFFSET REST_SKIP - movq %rbx,5*8(%rsp) - CFI_REL_OFFSET rbx,5*8 - movq %rbp,4*8(%rsp) - CFI_REL_OFFSET rbp,4*8 - movq %r12,3*8(%rsp) - CFI_REL_OFFSET r12,3*8 - movq %r13,2*8(%rsp) - CFI_REL_OFFSET r13,2*8 - movq %r14,1*8(%rsp) - CFI_REL_OFFSET r14,1*8 - movq %r15,(%rsp) - CFI_REL_OFFSET r15,0*8 - .endm + movq %rbx, 5*8(%rsp) + CFI_REL_OFFSET rbx, 5*8 + movq %rbp, 4*8(%rsp) + CFI_REL_OFFSET rbp, 4*8 + movq %r12, 3*8(%rsp) + CFI_REL_OFFSET r12, 3*8 + movq %r13, 2*8(%rsp) + CFI_REL_OFFSET r13, 2*8 + movq %r14, 1*8(%rsp) + CFI_REL_OFFSET r14, 1*8 + movq %r15, (%rsp) + CFI_REL_OFFSET r15, 0*8 + .endm .macro RESTORE_REST - movq (%rsp),%r15 + movq (%rsp), %r15 CFI_RESTORE r15 - movq 1*8(%rsp),%r14 + movq 1*8(%rsp), %r14 CFI_RESTORE r14 - movq 2*8(%rsp),%r13 + movq 2*8(%rsp), %r13 CFI_RESTORE r13 - movq 3*8(%rsp),%r12 + movq 3*8(%rsp), %r12 CFI_RESTORE r12 - movq 4*8(%rsp),%rbp + movq 4*8(%rsp), %rbp CFI_RESTORE rbp - movq 5*8(%rsp),%rbx + movq 5*8(%rsp), %rbx CFI_RESTORE rbx - addq $REST_SKIP,%rsp + addq $REST_SKIP, %rsp CFI_ADJUST_CFA_OFFSET -(REST_SKIP) .endm - + .macro SAVE_ALL SAVE_ARGS SAVE_REST .endm - + .macro RESTORE_ALL addskip=0 RESTORE_REST - RESTORE_ARGS 0,\addskip + RESTORE_ARGS 0, \addskip .endm .macro icebp .byte 0xf1 .endm + -- cgit v1.2.2 From 4d022e35fd7e07c522c7863fee6f07e53cf3fc14 Mon Sep 17 00:00:00 2001 From: Miguel Boton Date: Wed, 30 Jan 2008 13:32:51 +0100 Subject: x86: reboot_{32|64}.c unification reboot_{32|64}.c unification patch. This patch unifies the code from the reboot_32.c and reboot_64.c files. It has been tested in computers with X86_32 and X86_64 kernels and it looks like all reboot modes work fine (EFI restart system hasn't been tested yet). Probably I made some mistakes (like I usually do) so I hope we can identify and fix them soon. Signed-off-by: Miguel Boton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/emergency-restart.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/emergency-restart.h b/include/asm-x86/emergency-restart.h index 54189084462..8e6aef19f8f 100644 --- a/include/asm-x86/emergency-restart.h +++ b/include/asm-x86/emergency-restart.h @@ -4,6 +4,9 @@ enum reboot_type { BOOT_TRIPLE = 't', BOOT_KBD = 'k', +#ifdef CONFIG_X86_32 + BOOT_BIOS = 'b', +#endif BOOT_ACPI = 'a', BOOT_EFI = 'e' }; -- cgit v1.2.2 From b32ef636a59aad12f9f9b5dc34c93222842c58ba Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:32:51 +0100 Subject: percpu: use a kconfig variable to signal arch specific percpu setup The use of the __GENERIC_PERCPU is a bit problematic since arches may want to run their own percpu setup while using the generic percpu definitions. Replace it through a kconfig variable. Cc: Rusty Russell Cc: Andi Kleen Signed-off-by: Christoph Lameter Signed-off-by: Mike Travis Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/percpu_32.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/percpu_32.h b/include/asm-x86/percpu_32.h index a7ebd436f3c..3949586bf94 100644 --- a/include/asm-x86/percpu_32.h +++ b/include/asm-x86/percpu_32.h @@ -41,8 +41,6 @@ * PER_CPU(cpu_gdt_descr, %ebx) */ #ifdef CONFIG_SMP -/* Same as generic implementation except for optimized local access. */ -#define __GENERIC_PER_CPU /* This is used for other cpus to find our section. */ extern unsigned long __per_cpu_offset[]; -- cgit v1.2.2 From 5280e004fc22314122c84978c0b6a741cf96dc0f Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:32:52 +0100 Subject: percpu: move arch XX_PER_CPU_XX definitions into linux/percpu.h - Special consideration for IA64: Add the ability to specify arch specific per cpu flags - remove .data.percpu attribute from DEFINE_PER_CPU for non-smp case. The arch definitions are all the same. So move them into linux/percpu.h. We cannot move DECLARE_PER_CPU since some include files just include asm/percpu.h to avoid include recursion problems. Cc: Rusty Russell Cc: Andi Kleen Signed-off-by: Christoph Lameter Signed-off-by: Mike Travis Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/percpu_32.h | 12 ------------ include/asm-x86/percpu_64.h | 17 ----------------- 2 files changed, 29 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/percpu_32.h b/include/asm-x86/percpu_32.h index 3949586bf94..77bd0045f33 100644 --- a/include/asm-x86/percpu_32.h +++ b/include/asm-x86/percpu_32.h @@ -47,16 +47,7 @@ extern unsigned long __per_cpu_offset[]; #define per_cpu_offset(x) (__per_cpu_offset[x]) -/* Separate out the type, so (int[3], foo) works. */ #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name -#define DEFINE_PER_CPU(type, name) \ - __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name - -#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - __attribute__((__section__(".data.percpu.shared_aligned"))) \ - __typeof__(type) per_cpu__##name \ - ____cacheline_aligned_in_smp - /* We can use this directly for local CPU (faster). */ DECLARE_PER_CPU(unsigned long, this_cpu_off); @@ -81,9 +72,6 @@ do { \ (src), (size)); \ } while (0) -#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) -#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) - /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ #define __percpu_seg "%%fs:" #else /* !SMP */ diff --git a/include/asm-x86/percpu_64.h b/include/asm-x86/percpu_64.h index 5abd4827010..24fe7075248 100644 --- a/include/asm-x86/percpu_64.h +++ b/include/asm-x86/percpu_64.h @@ -16,15 +16,6 @@ #define per_cpu_offset(x) (__per_cpu_offset(x)) -/* Separate out the type, so (int[3], foo) works. */ -#define DEFINE_PER_CPU(type, name) \ - __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name - -#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - __attribute__((__section__(".data.percpu.shared_aligned"))) \ - __typeof__(type) per_cpu__##name \ - ____cacheline_internodealigned_in_smp - /* var is in discarded region: offset to particular copy we want */ #define per_cpu(var, cpu) (*({ \ extern int simple_identifier_##var(void); \ @@ -49,11 +40,6 @@ extern void setup_per_cpu_areas(void); #else /* ! SMP */ -#define DEFINE_PER_CPU(type, name) \ - __typeof__(type) per_cpu__##name -#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - DEFINE_PER_CPU(type, name) - #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var)) #define __get_cpu_var(var) per_cpu__##var #define __raw_get_cpu_var(var) per_cpu__##var @@ -62,7 +48,4 @@ extern void setup_per_cpu_areas(void); #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name -#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) -#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) - #endif /* _ASM_X8664_PERCPU_H_ */ -- cgit v1.2.2 From 0af8a5ccc51ee2269712c90ab09c91b0150f4224 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:32:52 +0100 Subject: x86_32: use generic percpu.h x86_32 only provides a special way to obtain the local per cpu area offset via x86_read_percpu. Otherwise it can fully use the generic handling. Cc: ak@suse.de Signed-off-by: Christoph Lameter Signed-off-by: Mike Travis Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/percpu_32.h | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/percpu_32.h b/include/asm-x86/percpu_32.h index 77bd0045f33..e62ce2fe2c9 100644 --- a/include/asm-x86/percpu_32.h +++ b/include/asm-x86/percpu_32.h @@ -42,26 +42,7 @@ */ #ifdef CONFIG_SMP -/* This is used for other cpus to find our section. */ -extern unsigned long __per_cpu_offset[]; - -#define per_cpu_offset(x) (__per_cpu_offset[x]) - -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name -/* We can use this directly for local CPU (faster). */ -DECLARE_PER_CPU(unsigned long, this_cpu_off); - -/* var is in discarded region: offset to particular copy we want */ -#define per_cpu(var, cpu) (*({ \ - extern int simple_indentifier_##var(void); \ - RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) - -#define __raw_get_cpu_var(var) (*({ \ - extern int simple_indentifier_##var(void); \ - RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \ -})) - -#define __get_cpu_var(var) __raw_get_cpu_var(var) +#define __my_cpu_offset x86_read_percpu(this_cpu_off) /* A macro to avoid #include hell... */ #define percpu_modcopy(pcpudst, src, size) \ @@ -74,11 +55,18 @@ do { \ /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ #define __percpu_seg "%%fs:" + #else /* !SMP */ -#include + #define __percpu_seg "" + #endif /* SMP */ +#include + +/* We can use this directly for local CPU (faster). */ +DECLARE_PER_CPU(unsigned long, this_cpu_off); + /* For arch-specific code, we can use direct single-insn ops (they * don't give an lvalue though). */ extern void __bad_percpu_size(void); -- cgit v1.2.2 From 072a1e6953d2caffbad7d217ae51cdc61125960f Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:32:52 +0100 Subject: x86: use generic percpu on 64-bit x86_64 provides an optimized way to determine the local per cpu area offset through the pda and determines the base by accessing a remote pda. Cc: Rusty Russell Cc: Andi Kleen Signed-off-by: Christoph Lameter Signed-off-by: Mike Travis Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/percpu_64.h | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/percpu_64.h b/include/asm-x86/percpu_64.h index 24fe7075248..e7f3f6d2175 100644 --- a/include/asm-x86/percpu_64.h +++ b/include/asm-x86/percpu_64.h @@ -12,21 +12,10 @@ #include #define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset) -#define __my_cpu_offset() read_pda(data_offset) +#define __my_cpu_offset read_pda(data_offset) #define per_cpu_offset(x) (__per_cpu_offset(x)) -/* var is in discarded region: offset to particular copy we want */ -#define per_cpu(var, cpu) (*({ \ - extern int simple_identifier_##var(void); \ - RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)); })) -#define __get_cpu_var(var) (*({ \ - extern int simple_identifier_##var(void); \ - RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); })) -#define __raw_get_cpu_var(var) (*({ \ - extern int simple_identifier_##var(void); \ - RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); })) - /* A macro to avoid #include hell... */ #define percpu_modcopy(pcpudst, src, size) \ do { \ @@ -36,16 +25,8 @@ do { \ (src), (size)); \ } while (0) -extern void setup_per_cpu_areas(void); - -#else /* ! SMP */ - -#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var)) -#define __get_cpu_var(var) per_cpu__##var -#define __raw_get_cpu_var(var) per_cpu__##var - #endif /* SMP */ -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name +#include #endif /* _ASM_X8664_PERCPU_H_ */ -- cgit v1.2.2 From 3334052a321aca0ffecb54244d666311f98f5487 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:32:53 +0100 Subject: x86: unify percpu.h Form a single percpu.h from percpu_32.h and percpu_64.h. Both are now pretty small so this is simply adding them together. Cc: Rusty Russell Signed-off-by: Christoph Lameter Signed-off-by: Mike Travis Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/percpu.h | 145 ++++++++++++++++++++++++++++++++++++++++++-- include/asm-x86/percpu_32.h | 128 -------------------------------------- include/asm-x86/percpu_64.h | 32 ---------- 3 files changed, 141 insertions(+), 164 deletions(-) delete mode 100644 include/asm-x86/percpu_32.h delete mode 100644 include/asm-x86/percpu_64.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/percpu.h b/include/asm-x86/percpu.h index a1aaad274cc..0dec00f27eb 100644 --- a/include/asm-x86/percpu.h +++ b/include/asm-x86/percpu.h @@ -1,5 +1,142 @@ -#ifdef CONFIG_X86_32 -# include "percpu_32.h" -#else -# include "percpu_64.h" +#ifndef _ASM_X86_PERCPU_H_ +#define _ASM_X86_PERCPU_H_ + +#ifdef CONFIG_X86_64 +#include + +/* Same as asm-generic/percpu.h, except that we store the per cpu offset + in the PDA. Longer term the PDA and every per cpu variable + should be just put into a single section and referenced directly + from %gs */ + +#ifdef CONFIG_SMP +#include + +#define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset) +#define __my_cpu_offset read_pda(data_offset) + +#define per_cpu_offset(x) (__per_cpu_offset(x)) + #endif +#include + +DECLARE_PER_CPU(struct x8664_pda, pda); + +#else /* CONFIG_X86_64 */ + +#ifdef __ASSEMBLY__ + +/* + * PER_CPU finds an address of a per-cpu variable. + * + * Args: + * var - variable name + * reg - 32bit register + * + * The resulting address is stored in the "reg" argument. + * + * Example: + * PER_CPU(cpu_gdt_descr, %ebx) + */ +#ifdef CONFIG_SMP +#define PER_CPU(var, reg) \ + movl %fs:per_cpu__##this_cpu_off, reg; \ + lea per_cpu__##var(reg), reg +#define PER_CPU_VAR(var) %fs:per_cpu__##var +#else /* ! SMP */ +#define PER_CPU(var, reg) \ + movl $per_cpu__##var, reg +#define PER_CPU_VAR(var) per_cpu__##var +#endif /* SMP */ + +#else /* ...!ASSEMBLY */ + +/* + * PER_CPU finds an address of a per-cpu variable. + * + * Args: + * var - variable name + * cpu - 32bit register containing the current CPU number + * + * The resulting address is stored in the "cpu" argument. + * + * Example: + * PER_CPU(cpu_gdt_descr, %ebx) + */ +#ifdef CONFIG_SMP + +#define __my_cpu_offset x86_read_percpu(this_cpu_off) + +/* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ +#define __percpu_seg "%%fs:" + +#else /* !SMP */ + +#define __percpu_seg "" + +#endif /* SMP */ + +#include + +/* We can use this directly for local CPU (faster). */ +DECLARE_PER_CPU(unsigned long, this_cpu_off); + +/* For arch-specific code, we can use direct single-insn ops (they + * don't give an lvalue though). */ +extern void __bad_percpu_size(void); + +#define percpu_to_op(op,var,val) \ + do { \ + typedef typeof(var) T__; \ + if (0) { T__ tmp__; tmp__ = (val); } \ + switch (sizeof(var)) { \ + case 1: \ + asm(op "b %1,"__percpu_seg"%0" \ + : "+m" (var) \ + :"ri" ((T__)val)); \ + break; \ + case 2: \ + asm(op "w %1,"__percpu_seg"%0" \ + : "+m" (var) \ + :"ri" ((T__)val)); \ + break; \ + case 4: \ + asm(op "l %1,"__percpu_seg"%0" \ + : "+m" (var) \ + :"ri" ((T__)val)); \ + break; \ + default: __bad_percpu_size(); \ + } \ + } while (0) + +#define percpu_from_op(op,var) \ + ({ \ + typeof(var) ret__; \ + switch (sizeof(var)) { \ + case 1: \ + asm(op "b "__percpu_seg"%1,%0" \ + : "=r" (ret__) \ + : "m" (var)); \ + break; \ + case 2: \ + asm(op "w "__percpu_seg"%1,%0" \ + : "=r" (ret__) \ + : "m" (var)); \ + break; \ + case 4: \ + asm(op "l "__percpu_seg"%1,%0" \ + : "=r" (ret__) \ + : "m" (var)); \ + break; \ + default: __bad_percpu_size(); \ + } \ + ret__; }) + +#define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var) +#define x86_write_percpu(var,val) percpu_to_op("mov", per_cpu__##var, val) +#define x86_add_percpu(var,val) percpu_to_op("add", per_cpu__##var, val) +#define x86_sub_percpu(var,val) percpu_to_op("sub", per_cpu__##var, val) +#define x86_or_percpu(var,val) percpu_to_op("or", per_cpu__##var, val) +#endif /* !__ASSEMBLY__ */ +#endif /* !CONFIG_X86_64 */ +#endif /* _ASM_X86_PERCPU_H_ */ diff --git a/include/asm-x86/percpu_32.h b/include/asm-x86/percpu_32.h deleted file mode 100644 index e62ce2fe2c9..00000000000 --- a/include/asm-x86/percpu_32.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef __ARCH_I386_PERCPU__ -#define __ARCH_I386_PERCPU__ - -#ifdef __ASSEMBLY__ - -/* - * PER_CPU finds an address of a per-cpu variable. - * - * Args: - * var - variable name - * reg - 32bit register - * - * The resulting address is stored in the "reg" argument. - * - * Example: - * PER_CPU(cpu_gdt_descr, %ebx) - */ -#ifdef CONFIG_SMP -#define PER_CPU(var, reg) \ - movl %fs:per_cpu__##this_cpu_off, reg; \ - lea per_cpu__##var(reg), reg -#define PER_CPU_VAR(var) %fs:per_cpu__##var -#else /* ! SMP */ -#define PER_CPU(var, reg) \ - movl $per_cpu__##var, reg -#define PER_CPU_VAR(var) per_cpu__##var -#endif /* SMP */ - -#else /* ...!ASSEMBLY */ - -/* - * PER_CPU finds an address of a per-cpu variable. - * - * Args: - * var - variable name - * cpu - 32bit register containing the current CPU number - * - * The resulting address is stored in the "cpu" argument. - * - * Example: - * PER_CPU(cpu_gdt_descr, %ebx) - */ -#ifdef CONFIG_SMP - -#define __my_cpu_offset x86_read_percpu(this_cpu_off) - -/* A macro to avoid #include hell... */ -#define percpu_modcopy(pcpudst, src, size) \ -do { \ - unsigned int __i; \ - for_each_possible_cpu(__i) \ - memcpy((pcpudst)+__per_cpu_offset[__i], \ - (src), (size)); \ -} while (0) - -/* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ -#define __percpu_seg "%%fs:" - -#else /* !SMP */ - -#define __percpu_seg "" - -#endif /* SMP */ - -#include - -/* We can use this directly for local CPU (faster). */ -DECLARE_PER_CPU(unsigned long, this_cpu_off); - -/* For arch-specific code, we can use direct single-insn ops (they - * don't give an lvalue though). */ -extern void __bad_percpu_size(void); - -#define percpu_to_op(op,var,val) \ - do { \ - typedef typeof(var) T__; \ - if (0) { T__ tmp__; tmp__ = (val); } \ - switch (sizeof(var)) { \ - case 1: \ - asm(op "b %1,"__percpu_seg"%0" \ - : "+m" (var) \ - :"ri" ((T__)val)); \ - break; \ - case 2: \ - asm(op "w %1,"__percpu_seg"%0" \ - : "+m" (var) \ - :"ri" ((T__)val)); \ - break; \ - case 4: \ - asm(op "l %1,"__percpu_seg"%0" \ - : "+m" (var) \ - :"ri" ((T__)val)); \ - break; \ - default: __bad_percpu_size(); \ - } \ - } while (0) - -#define percpu_from_op(op,var) \ - ({ \ - typeof(var) ret__; \ - switch (sizeof(var)) { \ - case 1: \ - asm(op "b "__percpu_seg"%1,%0" \ - : "=r" (ret__) \ - : "m" (var)); \ - break; \ - case 2: \ - asm(op "w "__percpu_seg"%1,%0" \ - : "=r" (ret__) \ - : "m" (var)); \ - break; \ - case 4: \ - asm(op "l "__percpu_seg"%1,%0" \ - : "=r" (ret__) \ - : "m" (var)); \ - break; \ - default: __bad_percpu_size(); \ - } \ - ret__; }) - -#define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var) -#define x86_write_percpu(var,val) percpu_to_op("mov", per_cpu__##var, val) -#define x86_add_percpu(var,val) percpu_to_op("add", per_cpu__##var, val) -#define x86_sub_percpu(var,val) percpu_to_op("sub", per_cpu__##var, val) -#define x86_or_percpu(var,val) percpu_to_op("or", per_cpu__##var, val) -#endif /* !__ASSEMBLY__ */ - -#endif /* __ARCH_I386_PERCPU__ */ diff --git a/include/asm-x86/percpu_64.h b/include/asm-x86/percpu_64.h deleted file mode 100644 index e7f3f6d2175..00000000000 --- a/include/asm-x86/percpu_64.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _ASM_X8664_PERCPU_H_ -#define _ASM_X8664_PERCPU_H_ -#include - -/* Same as asm-generic/percpu.h, except that we store the per cpu offset - in the PDA. Longer term the PDA and every per cpu variable - should be just put into a single section and referenced directly - from %gs */ - -#ifdef CONFIG_SMP - -#include - -#define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset) -#define __my_cpu_offset read_pda(data_offset) - -#define per_cpu_offset(x) (__per_cpu_offset(x)) - -/* A macro to avoid #include hell... */ -#define percpu_modcopy(pcpudst, src, size) \ -do { \ - unsigned int __i; \ - for_each_possible_cpu(__i) \ - memcpy((pcpudst)+__per_cpu_offset(__i), \ - (src), (size)); \ -} while (0) - -#endif /* SMP */ - -#include - -#endif /* _ASM_X8664_PERCPU_H_ */ -- cgit v1.2.2 From 58f6f6ea1d5031f998b5e7d640d7bc45ed86d0c8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:54 +0100 Subject: x86: migration helpers for KVM migration helpers for KVM. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/processor.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 41c002440de..cc549bf819a 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -3,6 +3,10 @@ #include +/* migration helpers, for KVM - will be removed in 2.6.25: */ +#include +#define Xgt_desc_struct desc_ptr + /* Forward declaration, a strange C thing */ struct task_struct; struct mm_struct; -- cgit v1.2.2 From 87e8407f9ad2a2df901c4b690ab0a2bf0fb168c5 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 30 Jan 2008 13:32:54 +0100 Subject: x86, ptrace: add bts_struct size to status command Return the size of bts_struct in the PTRACE_BTS_STATUS command. Change types to u32. Signed-off-by: Markus Metzger Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/ptrace-abi.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 08a12b790a7..81a8ee4c55f 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -81,16 +81,21 @@ #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ #ifndef __ASSEMBLY__ + +#include + /* configuration/status structure used in PTRACE_BTS_CONFIG and PTRACE_BTS_STATUS commands. */ struct ptrace_bts_config { /* requested or actual size of BTS buffer in bytes */ - unsigned int size; + u32 size; /* bitmask of below flags */ - unsigned int flags; + u32 flags; /* buffer overflow signal */ - unsigned int signal; + u32 signal; + /* actual size of bts_struct in bytes */ + u32 bts_size; }; #endif -- cgit v1.2.2 From 82bc03fc158e28c90d7ed9919410776039cb4e14 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:54 +0100 Subject: x86: add PWT to NOCACHE flags add PWT bit to NOCACHE flags. No real difference to CPUs, but needed later for PAT. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_32.h | 2 +- include/asm-x86/pgtable_64.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index a8be1ee15a9..16da5d5cce4 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -156,7 +156,7 @@ void paging_init(void); extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) #define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) -#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD) +#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 3f280105d7b..9c9cddf5138 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -189,13 +189,13 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define __PAGE_KERNEL_EXEC \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) #define __PAGE_KERNEL_NOCACHE \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_PWT | _PAGE_ACCESSED | _PAGE_NX) #define __PAGE_KERNEL_RO \ (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) #define __PAGE_KERNEL_VSYSCALL \ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define __PAGE_KERNEL_VSYSCALL_NOCACHE \ - (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD) + (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD | _PAGE_PWT) #define __PAGE_KERNEL_LARGE \ (__PAGE_KERNEL | _PAGE_PSE) #define __PAGE_KERNEL_LARGE_EXEC \ -- cgit v1.2.2 From 6c3866558213ff706d8331053386915371ad63ec Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:55 +0100 Subject: x86: move all asm/pgtable constants into one place 32 and 64-bit use the same flags for pagetable entries, so make them all common. [ mingo@elte.hu: fixes ] Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 119 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/pgtable_32.h | 110 --------------------------------------- include/asm-x86/pgtable_64.h | 91 --------------------------------- 3 files changed, 119 insertions(+), 201 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 1039140652a..5b858f0285a 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -1,5 +1,124 @@ +#ifndef _ASM_X86_PGTABLE_H +#define _ASM_X86_PGTABLE_H + +#define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE+1) +#define FIRST_USER_ADDRESS 0 + +#define _PAGE_BIT_PRESENT 0 +#define _PAGE_BIT_RW 1 +#define _PAGE_BIT_USER 2 +#define _PAGE_BIT_PWT 3 +#define _PAGE_BIT_PCD 4 +#define _PAGE_BIT_ACCESSED 5 +#define _PAGE_BIT_DIRTY 6 +#define _PAGE_BIT_FILE 6 +#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ +#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ +#define _PAGE_BIT_UNUSED1 9 /* available for programmer */ +#define _PAGE_BIT_UNUSED2 10 +#define _PAGE_BIT_UNUSED3 11 +#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ + +#define _PAGE_PRESENT (_AC(1, UL)<<_PAGE_BIT_PRESENT) +#define _PAGE_RW (_AC(1, UL)<<_PAGE_BIT_RW) +#define _PAGE_USER (_AC(1, UL)<<_PAGE_BIT_USER) +#define _PAGE_PWT (_AC(1, UL)<<_PAGE_BIT_PWT) +#define _PAGE_PCD (_AC(1, UL)<<_PAGE_BIT_PCD) +#define _PAGE_ACCESSED (_AC(1, UL)<<_PAGE_BIT_ACCESSED) +#define _PAGE_DIRTY (_AC(1, UL)<<_PAGE_BIT_DIRTY) +#define _PAGE_PSE (_AC(1, UL)<<_PAGE_BIT_PSE) /* 2MB page */ +#define _PAGE_GLOBAL (_AC(1, UL)<<_PAGE_BIT_GLOBAL) /* Global TLB entry */ +#define _PAGE_UNUSED1 (_AC(1, UL)<<_PAGE_BIT_UNUSED1) +#define _PAGE_UNUSED2 (_AC(1, UL)<<_PAGE_BIT_UNUSED2) +#define _PAGE_UNUSED3 (_AC(1, UL)<<_PAGE_BIT_UNUSED3) + +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +#define _PAGE_NX (_AC(1, ULL) << _PAGE_BIT_NX) +#else +#define _PAGE_NX 0 +#endif + +/* If _PAGE_PRESENT is clear, we use these: */ +#define _PAGE_FILE _PAGE_DIRTY /* nonlinear file mapping, saved PTE; unset:swap */ +#define _PAGE_PROTNONE _PAGE_PSE /* if the user mapped it with PROT_NONE; + pte_present gives true */ + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) + +#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY PAGE_COPY_NOEXEC +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) + +#ifdef CONFIG_X86_32 +#define _PAGE_KERNEL_EXEC \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define _PAGE_KERNEL (_PAGE_KERNEL_EXEC | _PAGE_NX) + +#ifndef __ASSEMBLY__ +extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; +#endif /* __ASSEMBLY__ */ +#else +#define __PAGE_KERNEL_EXEC \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX) +#endif + +#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) +#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) +#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) +#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) +#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) +#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) + +#ifdef CONFIG_X86_32 +# define MAKE_GLOBAL(x) __pgprot((x)) +#else +# define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL) +#endif + +#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) +#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX) +#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) +#define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_LARGE_EXEC MAKE_GLOBAL(__PAGE_KERNEL_LARGE_EXEC) +#define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL) +#define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE) + +/* xwr */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY_EXEC +#define __P101 PAGE_READONLY_EXEC +#define __P110 PAGE_COPY_EXEC +#define __P111 PAGE_COPY_EXEC + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY_EXEC +#define __S101 PAGE_READONLY_EXEC +#define __S110 PAGE_SHARED_EXEC +#define __S111 PAGE_SHARED_EXEC + #ifdef CONFIG_X86_32 # include "pgtable_32.h" #else # include "pgtable_64.h" #endif + +#endif /* _ASM_X86_PGTABLE_H */ diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 16da5d5cce4..3b40cb6dea1 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -58,9 +58,6 @@ void paging_init(void); #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) -#define FIRST_USER_ADDRESS 0 - #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) @@ -84,113 +81,6 @@ void paging_init(void); # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) #endif -/* - * _PAGE_PSE set in the page directory entry just means that - * the page directory entry points directly to a 4MB-aligned block of - * memory. - */ -#define _PAGE_BIT_PRESENT 0 -#define _PAGE_BIT_RW 1 -#define _PAGE_BIT_USER 2 -#define _PAGE_BIT_PWT 3 -#define _PAGE_BIT_PCD 4 -#define _PAGE_BIT_ACCESSED 5 -#define _PAGE_BIT_DIRTY 6 -#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page, Pentium+, if present.. */ -#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ -#define _PAGE_BIT_UNUSED1 9 /* available for programmer */ -#define _PAGE_BIT_UNUSED2 10 -#define _PAGE_BIT_UNUSED3 11 -#define _PAGE_BIT_NX 63 - -#define _PAGE_PRESENT 0x001 -#define _PAGE_RW 0x002 -#define _PAGE_USER 0x004 -#define _PAGE_PWT 0x008 -#define _PAGE_PCD 0x010 -#define _PAGE_ACCESSED 0x020 -#define _PAGE_DIRTY 0x040 -#define _PAGE_PSE 0x080 /* 4 MB (or 2MB) page, Pentium+, if present.. */ -#define _PAGE_GLOBAL 0x100 /* Global TLB entry PPro+ */ -#define _PAGE_UNUSED1 0x200 /* available for programmer */ -#define _PAGE_UNUSED2 0x400 -#define _PAGE_UNUSED3 0x800 - -/* If _PAGE_PRESENT is clear, we use these: */ -#define _PAGE_FILE 0x040 /* nonlinear file mapping, saved PTE; unset:swap */ -#define _PAGE_PROTNONE 0x080 /* if the user mapped it with PROT_NONE; - pte_present gives true */ -#ifdef CONFIG_X86_PAE -#define _PAGE_NX (1ULL<<_PAGE_BIT_NX) -#else -#define _PAGE_NX 0 -#endif - -#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) -#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) -#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) - -#define PAGE_NONE \ - __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) -#define PAGE_SHARED \ - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) - -#define PAGE_SHARED_EXEC \ - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY_NOEXEC \ - __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) -#define PAGE_COPY_EXEC \ - __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY \ - PAGE_COPY_NOEXEC -#define PAGE_READONLY \ - __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) -#define PAGE_READONLY_EXEC \ - __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) - -#define _PAGE_KERNEL \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) -#define _PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) - -extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; -#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) -#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) -#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) -#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) -#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) - -#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) -#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) -#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) -#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) -#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) -#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) - -/* - * The i386 can't do page protection for execute, and considers that - * the same are read. Also, write permissions imply read permissions. - * This is the closest we can get.. - */ -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY_EXEC -#define __P101 PAGE_READONLY_EXEC -#define __P110 PAGE_COPY_EXEC -#define __P111 PAGE_COPY_EXEC - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY_EXEC -#define __S101 PAGE_READONLY_EXEC -#define __S110 PAGE_SHARED_EXEC -#define __S111 PAGE_SHARED_EXEC - /* * Define this if things work differently on an i386 and an i486: * it will (on an i486) warn about kernel memory accesses that are diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 9c9cddf5138..93eb4df2ec1 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -131,8 +131,6 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -#define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE+1) -#define FIRST_USER_ADDRESS 0 #define MAXMEM _AC(0x3fffffffffff, UL) #define VMALLOC_START _AC(0xffffc20000000000, UL) @@ -142,95 +140,6 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define MODULES_END _AC(0xfffffffffff00000, UL) #define MODULES_LEN (MODULES_END - MODULES_VADDR) -#define _PAGE_BIT_PRESENT 0 -#define _PAGE_BIT_RW 1 -#define _PAGE_BIT_USER 2 -#define _PAGE_BIT_PWT 3 -#define _PAGE_BIT_PCD 4 -#define _PAGE_BIT_ACCESSED 5 -#define _PAGE_BIT_DIRTY 6 -#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ -#define _PAGE_BIT_FILE 6 -#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ -#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ - -#define _PAGE_PRESENT (_AC(1, UL)<<_PAGE_BIT_PRESENT) -#define _PAGE_RW (_AC(1, UL)<<_PAGE_BIT_RW) -#define _PAGE_USER (_AC(1, UL)<<_PAGE_BIT_USER) -#define _PAGE_PWT (_AC(1, UL)<<_PAGE_BIT_PWT) -#define _PAGE_PCD (_AC(1, UL)<<_PAGE_BIT_PCD) -#define _PAGE_ACCESSED (_AC(1, UL)<<_PAGE_BIT_ACCESSED) -#define _PAGE_DIRTY (_AC(1, UL)<<_PAGE_BIT_DIRTY) -/* 2MB page */ -#define _PAGE_PSE (_AC(1, UL)<<_PAGE_BIT_PSE) -/* nonlinear file mapping, saved PTE; unset:swap */ -#define _PAGE_FILE (_AC(1, UL)<<_PAGE_BIT_FILE) -/* Global TLB entry */ -#define _PAGE_GLOBAL (_AC(1, UL)<<_PAGE_BIT_GLOBAL) - -#define _PAGE_PROTNONE 0x080 /* If not present */ -#define _PAGE_NX (_AC(1, UL)<<_PAGE_BIT_NX) - -#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) -#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) - -#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) - -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) -#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) -#define PAGE_COPY PAGE_COPY_NOEXEC -#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) -#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define __PAGE_KERNEL \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) -#define __PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) -#define __PAGE_KERNEL_NOCACHE \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_PWT | _PAGE_ACCESSED | _PAGE_NX) -#define __PAGE_KERNEL_RO \ - (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) -#define __PAGE_KERNEL_VSYSCALL \ - (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define __PAGE_KERNEL_VSYSCALL_NOCACHE \ - (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD | _PAGE_PWT) -#define __PAGE_KERNEL_LARGE \ - (__PAGE_KERNEL | _PAGE_PSE) -#define __PAGE_KERNEL_LARGE_EXEC \ - (__PAGE_KERNEL_EXEC | _PAGE_PSE) - -#define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL) - -#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) -#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC) -#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) -#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL) -#define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL) -#define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE) -#define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE) - -/* xwr */ -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY_EXEC -#define __P101 PAGE_READONLY_EXEC -#define __P110 PAGE_COPY_EXEC -#define __P111 PAGE_COPY_EXEC - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY_EXEC -#define __S101 PAGE_READONLY_EXEC -#define __S110 PAGE_SHARED_EXEC -#define __S111 PAGE_SHARED_EXEC - #ifndef __ASSEMBLY__ static inline unsigned long pgd_bad(pgd_t pgd) -- cgit v1.2.2 From 61f38226def55d972cfd0e789971e952525ff8e5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:55 +0100 Subject: x86/pgtable: fix constant sign extension problem based on: Subject: x86/pgtable: fix constant sign extension problem From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 5b858f0285a..73e2b47c055 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -19,18 +19,18 @@ #define _PAGE_BIT_UNUSED3 11 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ -#define _PAGE_PRESENT (_AC(1, UL)<<_PAGE_BIT_PRESENT) -#define _PAGE_RW (_AC(1, UL)<<_PAGE_BIT_RW) -#define _PAGE_USER (_AC(1, UL)<<_PAGE_BIT_USER) -#define _PAGE_PWT (_AC(1, UL)<<_PAGE_BIT_PWT) -#define _PAGE_PCD (_AC(1, UL)<<_PAGE_BIT_PCD) -#define _PAGE_ACCESSED (_AC(1, UL)<<_PAGE_BIT_ACCESSED) -#define _PAGE_DIRTY (_AC(1, UL)<<_PAGE_BIT_DIRTY) -#define _PAGE_PSE (_AC(1, UL)<<_PAGE_BIT_PSE) /* 2MB page */ -#define _PAGE_GLOBAL (_AC(1, UL)<<_PAGE_BIT_GLOBAL) /* Global TLB entry */ -#define _PAGE_UNUSED1 (_AC(1, UL)<<_PAGE_BIT_UNUSED1) -#define _PAGE_UNUSED2 (_AC(1, UL)<<_PAGE_BIT_UNUSED2) -#define _PAGE_UNUSED3 (_AC(1, UL)<<_PAGE_BIT_UNUSED3) +#define _PAGE_PRESENT (_AC(1, L)<<_PAGE_BIT_PRESENT) +#define _PAGE_RW (_AC(1, L)<<_PAGE_BIT_RW) +#define _PAGE_USER (_AC(1, L)<<_PAGE_BIT_USER) +#define _PAGE_PWT (_AC(1, L)<<_PAGE_BIT_PWT) +#define _PAGE_PCD (_AC(1, L)<<_PAGE_BIT_PCD) +#define _PAGE_ACCESSED (_AC(1, L)<<_PAGE_BIT_ACCESSED) +#define _PAGE_DIRTY (_AC(1, L)<<_PAGE_BIT_DIRTY) +#define _PAGE_PSE (_AC(1, L)<<_PAGE_BIT_PSE) /* 2MB page */ +#define _PAGE_GLOBAL (_AC(1, L)<<_PAGE_BIT_GLOBAL) /* Global TLB entry */ +#define _PAGE_UNUSED1 (_AC(1, L)<<_PAGE_BIT_UNUSED1) +#define _PAGE_UNUSED2 (_AC(1, L)<<_PAGE_BIT_UNUSED2) +#define _PAGE_UNUSED3 (_AC(1, L)<<_PAGE_BIT_UNUSED3) #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) #define _PAGE_NX (_AC(1, ULL) << _PAGE_BIT_NX) -- cgit v1.2.2 From dcbae6b377d78190954055ef2d8909ae83ff57de Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:55 +0100 Subject: x86/pgtable: unify pagetable accessors, #1 based on: Subject: x86/pgtable: unify pagetable accessors From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 93eb4df2ec1..3a058808848 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -179,21 +179,27 @@ static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) * Undefined behaviour if not.. */ #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) + static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } -static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; } -static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; } -static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; } -static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } -static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_PSE)); return pte; } -static inline pte_t pte_clrhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_PSE)); return pte; } +static inline int pmd_large(pmd_t pte) { + return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == + (_PAGE_PSE|_PAGE_PRESENT); +} + +static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_DIRTY); } +static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } +static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); } +static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } +static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } +static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } +static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } +static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } +static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } struct vm_area_struct; -- cgit v1.2.2 From 92ac166f3a776afc51766395076ffcfde112740a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:55 +0100 Subject: x86/pgtable: unify pagetable accessors, #2 change the pte_dirty/* inlines to the unified format. Non-NOP! based on: Subject: x86/pgtable: unify pagetable accessors From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_32.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 3b40cb6dea1..57d4aab5594 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -105,15 +105,15 @@ extern unsigned long pg0[]; * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; } -static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; } -static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; } -static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } /* * The following only works if pte_present() is not true. */ -static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; } static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; } -- cgit v1.2.2 From 1444d2da4468f30daff47cacfd98acbd7baf43a7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:56 +0100 Subject: x86/pgtable: unify pagetable accessors, #3 change the pte_mk inlines to the unified format. Non-NOP! based on: Subject: x86/pgtable: unify pagetable accessors From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_32.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 57d4aab5594..c1e855fdf60 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -115,13 +115,13 @@ static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } */ static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; } -static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; } -static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } -static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; } +static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_DIRTY); } +static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } +static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); } +static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } +static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } +static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } +static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } #ifdef CONFIG_X86_PAE # include -- cgit v1.2.2 From 7d00a1ae54779db1bec03fa575cf53d99cb6cc48 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:56 +0100 Subject: x86/pgtable: unify pagetable accessors, #4 add new ops to 32-bit. based on: Subject: x86/pgtable: unify pagetable accessors From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_32.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index c1e855fdf60..b3e92124fc3 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -123,6 +123,14 @@ static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_A static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } +static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } +static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } + +static inline int pmd_large(pmd_t pte) { + return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == + (_PAGE_PSE|_PAGE_PRESENT); +} + #ifdef CONFIG_X86_PAE # include #else -- cgit v1.2.2 From e8a4852453c5af27d2a9c606e76809afa3dedb64 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:56 +0100 Subject: x86/pgtable: unify pagetable accessors, #5 reorder. NOP. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_32.h | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index b3e92124fc3..1c43c302609 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -108,28 +108,23 @@ extern unsigned long pg0[]; static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } -/* - * The following only works if pte_present() is not true. - */ -static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +static inline int pmd_large(pmd_t pte) { + return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == + (_PAGE_PSE|_PAGE_PRESENT); +} static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_DIRTY); } static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); } +static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } - static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } -static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } - -static inline int pmd_large(pmd_t pte) { - return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == - (_PAGE_PSE|_PAGE_PRESENT); -} #ifdef CONFIG_X86_PAE # include -- cgit v1.2.2 From 4614139c6a74fe02c85f702ba9c0e57f8e38647e Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:56 +0100 Subject: x86/pgtable: unify pagetable accessors, #6 Unify functions to test and set bits in pagetable entries. NOP: only moves existing code around, without any change to it. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 28 ++++++++++++++++++++++++++++ include/asm-x86/pgtable_32.h | 28 ---------------------------- include/asm-x86/pgtable_64.h | 32 -------------------------------- 3 files changed, 28 insertions(+), 60 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 73e2b47c055..4c03ff2246f 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -115,6 +115,34 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define __S110 PAGE_SHARED_EXEC #define __S111 PAGE_SHARED_EXEC +#ifndef __ASSEMBLY__ +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } + +static inline int pmd_large(pmd_t pte) { + return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == + (_PAGE_PSE|_PAGE_PRESENT); +} + +static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_DIRTY); } +static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } +static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); } +static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } +static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } +static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } +static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } +static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } +static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } + +#endif /* __ASSEMBLY__ */ + #ifdef CONFIG_X86_32 # include "pgtable_32.h" #else diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 1c43c302609..0aaefdda515 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -101,31 +101,6 @@ extern unsigned long pg0[]; #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } -static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } - -static inline int pmd_large(pmd_t pte) { - return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == - (_PAGE_PSE|_PAGE_PRESENT); -} - -static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_DIRTY); } -static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } -static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); } -static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } -static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } -static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } -static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } -static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } -static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } - #ifdef CONFIG_X86_PAE # include #else @@ -276,9 +251,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) return pte; } -#define pmd_large(pmd) \ -((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT)) - /* * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] * diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 3a058808848..84f47f9d789 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -173,34 +173,6 @@ static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) pte_val(pte) &= __supported_pte_mask; return pte; } - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) - -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } -static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } - -static inline int pmd_large(pmd_t pte) { - return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == - (_PAGE_PSE|_PAGE_PRESENT); -} - -static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_DIRTY); } -static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } -static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); } -static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } -static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } -static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } -static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } -static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } -static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } - struct vm_area_struct; static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) @@ -220,10 +192,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, */ #define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) -static inline int pmd_large(pmd_t pte) { - return (pmd_val(pte) & __LARGE_PTE) == __LARGE_PTE; -} - /* * Conversion functions: convert a page and protection to a page entry, -- cgit v1.2.2 From c3bcfb57e1e64b9b2f8b2d90564826637e21c5ea Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:57 +0100 Subject: x86: mask NX from pte_pfn In 32-bit PAE, mask NX from pte_pfn, since it isn't part of the PFN. This code is due for unification anyway, but this fixes a latent bug. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable-3level.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 948a3341411..9816346f7df 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -155,7 +155,7 @@ static inline int pte_none(pte_t pte) static inline unsigned long pte_pfn(pte_t pte) { - return pte_val(pte) >> PAGE_SHIFT; + return (pte_val(pte) & ~_PAGE_NX) >> PAGE_SHIFT; } extern unsigned long long __supported_pte_mask; -- cgit v1.2.2 From 6fdc05d4794056e0b98901646c4b68c60a01d5eb Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:57 +0100 Subject: x86: unify pgtable accessors which use Make users of supported_pte_mask common. This has the side-effect of introducing the variable for 32-bit non-PAE, but I think its a pretty small cost to simplify the code. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable-2level.h | 2 -- include/asm-x86/pgtable-3level.h | 14 -------------- include/asm-x86/pgtable.h | 14 ++++++++++++++ include/asm-x86/pgtable_64.h | 18 ------------------ 4 files changed, 14 insertions(+), 34 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h index 84b03cf56a7..d3171c0cb15 100644 --- a/include/asm-x86/pgtable-2level.h +++ b/include/asm-x86/pgtable-2level.h @@ -53,8 +53,6 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp) #define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_none(x) (!(x).pte_low) #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) -#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) -#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) /* * All present pages are kernel-executable: diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 9816346f7df..61a7d0029f6 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -158,20 +158,6 @@ static inline unsigned long pte_pfn(pte_t pte) return (pte_val(pte) & ~_PAGE_NX) >> PAGE_SHIFT; } -extern unsigned long long __supported_pte_mask; - -static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) -{ - return __pte((((unsigned long long)page_nr << PAGE_SHIFT) | - pgprot_val(pgprot)) & __supported_pte_mask); -} - -static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) -{ - return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | - pgprot_val(pgprot)) & __supported_pte_mask); -} - /* * Bits 0, 6 and 7 are taken in the low part of the pte, * put the 32 bits of offset into the high part. diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 4c03ff2246f..b29a122fc1f 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -141,6 +141,20 @@ static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_R static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } +extern pteval_t __supported_pte_mask; + +static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) +{ + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) | + pgprot_val(pgprot)) & __supported_pte_mask); +} + +static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) +{ + return __pmd((((phys_addr_t)page_nr << PAGE_SHIFT) | + pgprot_val(pgprot)) & __supported_pte_mask); +} + #endif /* __ASSEMBLY__ */ #ifdef CONFIG_X86_32 diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 84f47f9d789..57e4ebe0f7f 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -17,7 +17,6 @@ extern pud_t level3_kernel_pgt[512]; extern pud_t level3_ident_pgt[512]; extern pmd_t level2_kernel_pgt[512]; extern pgd_t init_level4_pgt[]; -extern unsigned long __supported_pte_mask; #define swapper_pg_dir init_level4_pgt @@ -165,14 +164,6 @@ static inline unsigned long pmd_bad(pmd_t pmd) #define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_pfn(x) ((pte_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) -static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) -{ - pte_t pte; - pte_val(pte) = (page_nr << PAGE_SHIFT); - pte_val(pte) |= pgprot_val(pgprot); - pte_val(pte) &= __supported_pte_mask; - return pte; -} struct vm_area_struct; static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) @@ -239,15 +230,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, /* page, protection -> pte */ #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -/* Change flags of a PTE */ -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - pte_val(pte) &= _PAGE_CHG_MASK; - pte_val(pte) |= pgprot_val(newprot); - pte_val(pte) &= __supported_pte_mask; - return pte; -} - #define pte_index(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset_kernel(dir, address) ((pte_t *) pmd_page_vaddr(*(dir)) + \ -- cgit v1.2.2 From 38472311679d8784c2934d071ddda23d9b3fe264 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:57 +0100 Subject: x86: unify pgtable accessors which use, #2 based on: Subject: x86: unify pgtable accessors which use supported_pte_mask From: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 15 +++++++++++++++ include/asm-x86/pgtable_32.h | 16 ---------------- 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index b29a122fc1f..6452286e71a 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -155,6 +155,21 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) pgprot_val(pgprot)) & __supported_pte_mask); } +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pteval_t val = pte_val(pte); + + /* + * Chop off the NX bit (if present), and add the NX portion of + * the newprot (if present): + */ + val &= _PAGE_CHG_MASK & ~_PAGE_NX; + val |= pgprot_val(newprot) & __supported_pte_mask; + + return __pte(val); +} + + #endif /* __ASSEMBLY__ */ #ifdef CONFIG_X86_32 diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 0aaefdda515..109dad5e16e 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -235,22 +235,6 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - pte.pte_low &= _PAGE_CHG_MASK; - pte.pte_low |= pgprot_val(newprot); -#ifdef CONFIG_X86_PAE - /* - * Chop off the NX bit (if present), and add the NX portion of - * the newprot (if present): - */ - pte.pte_high &= ~(1 << (_PAGE_BIT_NX - 32)); - pte.pte_high |= (pgprot_val(newprot) >> 32) & \ - (__supported_pte_mask >> 32); -#endif - return pte; -} - /* * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] * -- cgit v1.2.2 From b7fff536d0ad45c4810f9b99845c707ceadc3afc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:32:57 +0100 Subject: x86: fix pte_modify() bug fix sign extension bug in PTE_MASK / _PTE_CHG_MASK. this resolves the following bootup crash on PAE systems: [ 94.710726] init[1]: segfault at 00000004 ip 49471cbb sp bff0c6c0 error 4 [ 94.717764] init[1]: segfault at 00000004 ip 49471cbb sp bff0c6c0 error 4 [ 94.724772] init[1]: segfault at 00000004 ip 49471cbb sp bff0c6c0 error 4 [ 94.731777] init[1]: segfault at 00000004 ip 49471cbb sp bff0c6c0 error 4 Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 3a00d0d9dfd..91920565a57 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -11,7 +11,7 @@ #ifdef __KERNEL__ #define PHYSICAL_PAGE_MASK (PAGE_MASK & __PHYSICAL_MASK) -#define PTE_MASK PHYSICAL_PAGE_MASK +#define PTE_MASK (_AT(long, PHYSICAL_PAGE_MASK)) #define LARGE_PAGE_SIZE (_AC(1,UL) << PMD_SHIFT) #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) -- cgit v1.2.2 From c8e5393ab38564d2f45b560a2f95bc8f9ff6f823 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:57 +0100 Subject: x86: page.h: make pte_t a union to always include Make sure pte_t, whatever its definition, has a pte element with type pteval_t. This allows common code to access it without needing to be specifically parameterised on what pagetable mode we're compiling for. For 32-bit, this means that pte_t becomes a union with "pte" and "{ pte_low, pte_high }" (PAE) or just "pte_low" (non-PAE). Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 10 ++++++++++ include/asm-x86/page_32.h | 30 +++++++----------------------- include/asm-x86/page_64.h | 3 --- include/asm-x86/paravirt.h | 2 +- include/asm-x86/pgtable-2level.h | 4 ++-- include/asm-x86/pgtable-3level.h | 4 ++-- include/asm-x86/pgtable_64.h | 6 +++--- include/asm-x86/processor.h | 1 - 8 files changed, 25 insertions(+), 35 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 91920565a57..a6495eb5c60 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -108,6 +108,16 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) #include #endif /* PAGETABLE_LEVELS >= 3 */ +static inline pte_t native_make_pte(pteval_t val) +{ + return (pte_t) { .pte = val }; +} + +static inline pteval_t native_pte_val(pte_t pte) +{ + return pte.pte; +} + #define pgprot_val(x) ((x).pgprot) #define __pgprot(x) ((pgprot_t) { (x) } ) diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index e424bef4395..11c4b39cada 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -26,18 +26,12 @@ typedef u64 pgdval_t; typedef u64 pgprotval_t; typedef u64 phys_addr_t; -typedef struct { unsigned long pte_low, pte_high; } pte_t; - -static inline unsigned long long native_pte_val(pte_t pte) -{ - return pte.pte_low | ((unsigned long long)pte.pte_high << 32); -} - -static inline pte_t native_make_pte(unsigned long long val) -{ - return (pte_t) { .pte_low = val, .pte_high = (val >> 32) } ; -} - +typedef union { + struct { + unsigned long pte_low, pte_high; + }; + pteval_t pte; +} pte_t; #endif /* __ASSEMBLY__ */ #else /* !CONFIG_X86_PAE */ @@ -53,19 +47,9 @@ typedef unsigned long pgdval_t; typedef unsigned long pgprotval_t; typedef unsigned long phys_addr_t; -typedef struct { pteval_t pte_low; } pte_t; +typedef union { pteval_t pte, pte_low; } pte_t; typedef pte_t boot_pte_t; -static inline unsigned long native_pte_val(pte_t pte) -{ - return pte.pte_low; -} - -static inline pte_t native_make_pte(unsigned long val) -{ - return (pte_t) { .pte_low = val }; -} - #endif /* __ASSEMBLY__ */ #endif /* CONFIG_X86_PAE */ diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index ebf977a809a..c1ac42d8707 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -70,9 +70,6 @@ typedef unsigned long phys_addr_t; typedef struct { pteval_t pte; } pte_t; -#define native_pte_val(x) ((x).pte) -#define native_make_pte(x) ((pte_t) { (x) } ) - #define vmemmap ((struct page *)VMEMMAP_START) #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index b35ed95166e..24385decbd4 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -922,7 +922,7 @@ static inline pte_t __pte(unsigned long long val) unsigned long long ret = PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pte, val, val >> 32); - return (pte_t) { ret, ret >> 32 }; + return (pte_t) { .pte = ret }; } static inline pmd_t __pmd(unsigned long long val) diff --git a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h index d3171c0cb15..f949bb08308 100644 --- a/include/asm-x86/pgtable-2level.h +++ b/include/asm-x86/pgtable-2level.h @@ -72,13 +72,13 @@ static inline int pte_exec_kernel(pte_t pte) ((((pte).pte_low >> 1) & 0x1f ) + (((pte).pte_low >> 8) << 5 )) #define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x1f) << 1) + (((off) >> 5) << 8) + _PAGE_FILE }) + ((pte_t) { .pte_low = (((off) & 0x1f) << 1) + (((off) >> 5) << 8) + _PAGE_FILE }) /* Encode and de-code a swap entry */ #define __swp_type(x) (((x).val >> 1) & 0x1f) #define __swp_offset(x) ((x).val >> 8) #define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) #endif /* _I386_PGTABLE_2LEVEL_H */ diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 61a7d0029f6..3da96f792dd 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -163,7 +163,7 @@ static inline unsigned long pte_pfn(pte_t pte) * put the 32 bits of offset into the high part. */ #define pte_to_pgoff(pte) ((pte).pte_high) -#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) }) +#define pgoff_to_pte(off) ((pte_t) { { .pte_low = _PAGE_FILE, .pte_high = (off) } }) #define PTE_FILE_MAX_BITS 32 /* Encode and de-code a swap entry */ @@ -171,7 +171,7 @@ static inline unsigned long pte_pfn(pte_t pte) #define __swp_offset(x) ((x).val >> 5) #define __swp_entry(type, offset) ((swp_entry_t){(type) | (offset) << 5}) #define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high }) -#define __swp_entry_to_pte(x) ((pte_t){ 0, (x).val }) +#define __swp_entry_to_pte(x) ((pte_t){ { .pte_high = (x).val } }) #define __pmd_free_tlb(tlb, x) do { } while (0) diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 57e4ebe0f7f..77038d8e9bf 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -72,7 +72,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; static inline void set_pte(pte_t *dst, pte_t val) { - pte_val(*dst) = pte_val(val); + *dst = val; } #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) @@ -222,7 +222,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, #define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) #define pte_to_pgoff(pte) ((pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT) -#define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE }) +#define pgoff_to_pte(off) ((pte_t) { .pte = ((off) << PAGE_SHIFT) | _PAGE_FILE }) #define PTE_FILE_MAX_BITS __PHYSICAL_MASK_SHIFT /* PTE - Level 1 access. */ @@ -264,7 +264,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, #define __swp_offset(x) ((x).val >> 8) #define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) extern spinlock_t pgd_lock; extern struct list_head pgd_list; diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index cc549bf819a..e701ac5487e 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -14,7 +14,6 @@ struct mm_struct; #include #include #include -#include #include #include #include -- cgit v1.2.2 From 195466dc4b9b8a4cc89d37ea1211746f3afbc941 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:58 +0100 Subject: x86: pgtable: unify pte accessors Make various pte accessors common. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable-2level.h | 1 - include/asm-x86/pgtable-3level.h | 1 - include/asm-x86/pgtable.h | 110 ++++++++++++++++++++++++++++++++++++++- include/asm-x86/pgtable_32.h | 101 ----------------------------------- include/asm-x86/pgtable_64.h | 43 ++------------- 5 files changed, 113 insertions(+), 143 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h index f949bb08308..65cdc8f9e3b 100644 --- a/include/asm-x86/pgtable-2level.h +++ b/include/asm-x86/pgtable-2level.h @@ -33,7 +33,6 @@ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) #define set_pte_present(mm,addr,ptep,pteval) set_pte_at(mm,addr,ptep,pteval) -#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *xp) diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 3da96f792dd..a123e687112 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -101,7 +101,6 @@ static inline void native_pmd_clear(pmd_t *pmd) #define set_pte_atomic(ptep, pte) native_set_pte_atomic(ptep, pte) #define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd) #define set_pud(pudp, pud) native_set_pud(pudp, pud) -#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) #define pmd_clear(pmd) native_pmd_clear(pmd) #endif diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 6452286e71a..62fa856c249 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -116,6 +116,7 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define __S111 PAGE_SHARED_EXEC #ifndef __ASSEMBLY__ + /* * The following only work if pte_present() is true. * Undefined behaviour if not.. @@ -169,7 +170,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) return __pte(val); } - #endif /* __ASSEMBLY__ */ #ifdef CONFIG_X86_32 @@ -178,4 +178,112 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) # include "pgtable_64.h" #endif +#ifndef __ASSEMBLY__ + +#ifndef CONFIG_PARAVIRT +/* + * Rules for using pte_update - it must be called after any PTE update which + * has not been done using the set_pte / clear_pte interfaces. It is used by + * shadow mode hypervisors to resynchronize the shadow page tables. Kernel PTE + * updates should either be sets, clears, or set_pte_atomic for P->P + * transitions, which means this hook should only be called for user PTEs. + * This hook implies a P->P protection or access change has taken place, which + * requires a subsequent TLB flush. The notification can optionally be delayed + * until the TLB flush event by using the pte_update_defer form of the + * interface, but care must be taken to assure that the flush happens while + * still holding the same page table lock so that the shadow and primary pages + * do not become out of sync on SMP. + */ +#define pte_update(mm, addr, ptep) do { } while (0) +#define pte_update_defer(mm, addr, ptep) do { } while (0) +#endif + +/* local pte updates need not use xchg for locking */ +static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) +{ + pte_t res = *ptep; + + /* Pure native function needs no input for mm, addr */ + native_pte_clear(NULL, 0, ptep); + return res; +} + +/* + * We only update the dirty/accessed state if we set + * the dirty bit by hand in the kernel, since the hardware + * will do the accessed bit for us, and we don't want to + * race with other CPU's that might be updating the dirty + * bit at the same time. + */ +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +#define ptep_set_access_flags(vma, address, ptep, entry, dirty) \ +({ \ + int __changed = !pte_same(*(ptep), entry); \ + if (__changed && dirty) { \ + *ptep = entry; \ + pte_update_defer((vma)->vm_mm, (address), (ptep)); \ + flush_tlb_page(vma, address); \ + } \ + __changed; \ +}) + +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +#define ptep_test_and_clear_young(vma, addr, ptep) ({ \ + int __ret = 0; \ + if (pte_young(*(ptep))) \ + __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, \ + &(ptep)->pte); \ + if (__ret) \ + pte_update((vma)->vm_mm, addr, ptep); \ + __ret; \ +}) + +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH +#define ptep_clear_flush_young(vma, address, ptep) \ +({ \ + int __young; \ + __young = ptep_test_and_clear_young((vma), (address), (ptep)); \ + if (__young) \ + flush_tlb_page(vma, address); \ + __young; \ +}) + +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + pte_t pte = native_ptep_get_and_clear(ptep); + pte_update(mm, addr, ptep); + return pte; +} + +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL +static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) +{ + pte_t pte; + if (full) { + /* + * Full address destruction in progress; paravirt does not + * care about updates and native needs no locking + */ + pte = native_local_ptep_get_and_clear(ptep); + } else { + pte = ptep_get_and_clear(mm, addr, ptep); + } + return pte; +} + +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + clear_bit(_PAGE_BIT_RW, &ptep->pte); + pte_update(mm, addr, ptep); +} + +#ifndef CONFIG_PARAVIRT +#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) +#endif /* !CONFIG_PARAVIRT */ + +#include +#endif /* __ASSEMBLY__ */ + #endif /* _ASM_X86_PGTABLE_H */ diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 109dad5e16e..d4d238c1029 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -107,105 +107,6 @@ extern unsigned long pg0[]; # include #endif -#ifndef CONFIG_PARAVIRT -/* - * Rules for using pte_update - it must be called after any PTE update which - * has not been done using the set_pte / clear_pte interfaces. It is used by - * shadow mode hypervisors to resynchronize the shadow page tables. Kernel PTE - * updates should either be sets, clears, or set_pte_atomic for P->P - * transitions, which means this hook should only be called for user PTEs. - * This hook implies a P->P protection or access change has taken place, which - * requires a subsequent TLB flush. The notification can optionally be delayed - * until the TLB flush event by using the pte_update_defer form of the - * interface, but care must be taken to assure that the flush happens while - * still holding the same page table lock so that the shadow and primary pages - * do not become out of sync on SMP. - */ -#define pte_update(mm, addr, ptep) do { } while (0) -#define pte_update_defer(mm, addr, ptep) do { } while (0) -#endif - -/* local pte updates need not use xchg for locking */ -static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) -{ - pte_t res = *ptep; - - /* Pure native function needs no input for mm, addr */ - native_pte_clear(NULL, 0, ptep); - return res; -} - -/* - * We only update the dirty/accessed state if we set - * the dirty bit by hand in the kernel, since the hardware - * will do the accessed bit for us, and we don't want to - * race with other CPU's that might be updating the dirty - * bit at the same time. - */ -#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS -#define ptep_set_access_flags(vma, address, ptep, entry, dirty) \ -({ \ - int __changed = !pte_same(*(ptep), entry); \ - if (__changed && dirty) { \ - (ptep)->pte_low = (entry).pte_low; \ - pte_update_defer((vma)->vm_mm, (address), (ptep)); \ - flush_tlb_page(vma, address); \ - } \ - __changed; \ -}) - -#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG -#define ptep_test_and_clear_young(vma, addr, ptep) ({ \ - int __ret = 0; \ - if (pte_young(*(ptep))) \ - __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, \ - &(ptep)->pte_low); \ - if (__ret) \ - pte_update((vma)->vm_mm, addr, ptep); \ - __ret; \ -}) - -#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH -#define ptep_clear_flush_young(vma, address, ptep) \ -({ \ - int __young; \ - __young = ptep_test_and_clear_young((vma), (address), (ptep)); \ - if (__young) \ - flush_tlb_page(vma, address); \ - __young; \ -}) - -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR -static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - pte_t pte = native_ptep_get_and_clear(ptep); - pte_update(mm, addr, ptep); - return pte; -} - -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL -static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) -{ - pte_t pte; - if (full) { - /* - * Full address destruction in progress; paravirt does not - * care about updates and native needs no locking - */ - pte = native_local_ptep_get_and_clear(ptep); - } else { - pte = ptep_get_and_clear(mm, addr, ptep); - } - return pte; -} - -#define __HAVE_ARCH_PTEP_SET_WRPROTECT -static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - clear_bit(_PAGE_BIT_RW, &ptep->pte_low); - pte_update(mm, addr, ptep); -} - /* * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); * @@ -359,6 +260,4 @@ static inline void paravirt_pagetable_setup_done(pgd_t *base) #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) -#include - #endif /* _I386_PGTABLE_H */ diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 77038d8e9bf..987f51f684a 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -101,18 +101,18 @@ static inline void pgd_clear (pgd_t * pgd) set_pgd(pgd, __pgd(0)); } -#define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte, 0)) +#define native_ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte, 0)) struct mm_struct; -static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) +static inline pte_t native_ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) { pte_t pte; if (full) { pte = *ptep; *ptep = __pte(0); } else { - pte = ptep_get_and_clear(mm, addr, ptep); + pte = native_ptep_get_and_clear(ptep); } return pte; } @@ -158,26 +158,12 @@ static inline unsigned long pmd_bad(pmd_t pmd) #define pte_none(x) (!pte_val(x)) #define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) -#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) +#define native_pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) /* FIXME: is this right? */ #define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_pfn(x) ((pte_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) -struct vm_area_struct; - -static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) -{ - if (!pte_young(*ptep)) - return 0; - return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte); -} - -static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - clear_bit(_PAGE_BIT_RW, &ptep->pte); -} - /* * Macro to mark a page protection value as "uncacheable". */ @@ -243,22 +229,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, #define update_mmu_cache(vma,address,pte) do { } while (0) -/* We only update the dirty/accessed state if we set - * the dirty bit by hand in the kernel, since the hardware - * will do the accessed bit for us, and we don't want to - * race with other CPU's that might be updating the dirty - * bit at the same time. */ -#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS -#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ -({ \ - int __changed = !pte_same(*(__ptep), __entry); \ - if (__changed && __dirty) { \ - set_pte(__ptep, __entry); \ - flush_tlb_page(__vma, __address); \ - } \ - __changed; \ -}) - /* Encode and de-code a swap entry */ #define __swp_type(x) (((x).val >> 1) & 0x3f) #define __swp_offset(x) ((x).val >> 8) @@ -290,12 +260,7 @@ pte_t *lookup_address(unsigned long addr); #define kc_offset_to_vaddr(o) \ (((o) & (1UL << (__VIRTUAL_MASK_SHIFT-1))) ? ((o) | (~__VIRTUAL_MASK)) : (o)) -#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL -#define __HAVE_ARCH_PTEP_SET_WRPROTECT #define __HAVE_ARCH_PTE_SAME -#include #endif /* !__ASSEMBLY__ */ #endif /* _X86_64_PGTABLE_H */ -- cgit v1.2.2 From d8d89827fc0c9c2ea6ac4c22e14e30586a856f58 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:58 +0100 Subject: x86: fix warning &ptep->pte isn't always an unsigned long *, so cast it to avoid a warning. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 62fa856c249..820db41dbe4 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -275,7 +275,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define __HAVE_ARCH_PTEP_SET_WRPROTECT static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - clear_bit(_PAGE_BIT_RW, &ptep->pte); + clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte); pte_update(mm, addr, ptep); } -- cgit v1.2.2 From 8405b122ad0dd75354b3bfed4de9a96514fd40cb Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:58 +0100 Subject: x86: unify zero_page definition Move ZERO_PAGE/empty_zero_page to common place. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 8 ++++++++ include/asm-x86/pgtable_32.h | 6 ------ include/asm-x86/pgtable_64.h | 7 ------- 3 files changed, 8 insertions(+), 13 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 820db41dbe4..eb14a70a472 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -117,6 +117,14 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #ifndef __ASSEMBLY__ +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) + + /* * The following only work if pte_present() is true. * Undefined behaviour if not.. diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index d4d238c1029..eb8cccfa6a4 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -25,12 +25,6 @@ struct mm_struct; struct vm_area_struct; -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) -extern unsigned long empty_zero_page[1024]; extern pgd_t swapper_pg_dir[1024]; extern struct kmem_cache *pmd_cache; extern spinlock_t pgd_lock; diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 987f51f684a..435e17187eb 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -23,13 +23,6 @@ extern pgd_t init_level4_pgt[]; extern void paging_init(void); extern void clear_kernel_mapping(unsigned long addr, unsigned long size); -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) - #endif /* !__ASSEMBLY__ */ /* -- cgit v1.2.2 From 4891645e764d2e181b834509a689fcd12e890c10 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:58 +0100 Subject: x86: unify paravirt pagetable accessors Put all the defines for mapping pagetable operations to their native versions (for the non-paravirt case) into one place. Make the corresponding changes to paravirt.h. The tricky part here is that when a pagetable entry can't be updated atomically (ie, 32-bit PAE), we need special handlers for pte_clear, set_pte_atomic and set_pte_present. However, the other two modes don't need special handling for these, and can use a common set_pte(_at) path. [ mingo@elte.hu: fixes ] Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 21 +++++++++++++ include/asm-x86/pgtable-2level.h | 30 ++++++++++--------- include/asm-x86/pgtable-3level.h | 15 ---------- include/asm-x86/pgtable.h | 63 ++++++++++++++++++++++++++++++--------- include/asm-x86/pgtable_64.h | 64 ++++++++++++++++++++++------------------ 5 files changed, 121 insertions(+), 72 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 24385decbd4..4aa06b929e4 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1039,6 +1039,27 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) { PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd); } + +static inline void pmd_clear(pmd_t *pmdp) +{ + set_pmd(pmdp, __pmd(0)); +} + +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + set_pte_at(mm, addr, ptep, __pte(0)); +} + +static inline void set_pte_atomic(pte_t *ptep, pte_t pte) +{ + set_pte(ptep, pte); +} + +static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + set_pte(ptep, pte); +} #endif /* CONFIG_X86_PAE */ /* Lazy mode for batching updates / context switch */ diff --git a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h index 65cdc8f9e3b..ce486bdbbbb 100644 --- a/include/asm-x86/pgtable-2level.h +++ b/include/asm-x86/pgtable-2level.h @@ -15,29 +15,31 @@ static inline void native_set_pte(pte_t *ptep , pte_t pte) { *ptep = pte; } -static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep , pte_t pte) -{ - native_set_pte(ptep, pte); -} + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) { *pmdp = pmd; } -#ifndef CONFIG_PARAVIRT -#define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval) -#define set_pte_at(mm,addr,ptep,pteval) native_set_pte_at(mm, addr, ptep, pteval) -#define set_pmd(pmdptr, pmdval) native_set_pmd(pmdptr, pmdval) -#endif -#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) -#define set_pte_present(mm,addr,ptep,pteval) set_pte_at(mm,addr,ptep,pteval) +static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) +{ + native_set_pte(ptep, pte); +} + +static inline void native_set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + native_set_pte(ptep, pte); +} -#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +static inline void native_pmd_clear(pmd_t *pmdp) +{ + native_set_pmd(pmdp, __pmd(0)); +} static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *xp) { - *xp = __pte(0); + *xp = native_make_pte(0); } #ifdef CONFIG_SMP diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index a123e687112..5af7a44ed90 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -39,11 +39,6 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) smp_wmb(); ptep->pte_low = pte.pte_low; } -static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep , pte_t pte) -{ - native_set_pte(ptep, pte); -} /* * Since this is only called on user PTEs, and the page fault handler @@ -94,16 +89,6 @@ static inline void native_pmd_clear(pmd_t *pmd) *(tmp + 1) = 0; } -#ifndef CONFIG_PARAVIRT -#define set_pte(ptep, pte) native_set_pte(ptep, pte) -#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) -#define set_pte_present(mm, addr, ptep, pte) native_set_pte_present(mm, addr, ptep, pte) -#define set_pte_atomic(ptep, pte) native_set_pte_atomic(ptep, pte) -#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd) -#define set_pud(pudp, pud) native_set_pud(pudp, pud) -#define pmd_clear(pmd) native_pmd_clear(pmd) -#endif - /* * Pentium-II erratum A13: in PAE mode we explicitly have to flush * the TLB via cr3 if the top-level pgd is changed... diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index eb14a70a472..a1eeacdf9d8 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -178,6 +178,39 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) return __pte(val); } +#ifdef CONFIG_PARAVIRT +#include +#else /* !CONFIG_PARAVIRT */ +#define set_pte(ptep, pte) native_set_pte(ptep, pte) +#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) + +#define set_pte_present(mm, addr, ptep, pte) \ + native_set_pte_present(mm, addr, ptep, pte) +#define set_pte_atomic(ptep, pte) \ + native_set_pte_atomic(ptep, pte) + +#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd) + +#ifndef __PAGETABLE_PUD_FOLDED +#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd) +#define pgd_clear(pgd) native_pgd_clear(pgd) +#endif + +#ifndef set_pud +# define set_pud(pudp, pud) native_set_pud(pudp, pud) +#endif + +#ifndef __PAGETABLE_PMD_FOLDED +#define pud_clear(pud) native_pud_clear(pud) +#endif + +#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) +#define pmd_clear(pmd) native_pmd_clear(pmd) + +#define pte_update(mm, addr, ptep) do { } while (0) +#define pte_update_defer(mm, addr, ptep) do { } while (0) +#endif /* CONFIG_PARAVIRT */ + #endif /* __ASSEMBLY__ */ #ifdef CONFIG_X86_32 @@ -188,6 +221,22 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #ifndef __ASSEMBLY__ +/* local pte updates need not use xchg for locking */ +static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) +{ + pte_t res = *ptep; + + /* Pure native function needs no input for mm, addr */ + native_pte_clear(NULL, 0, ptep); + return res; +} + +static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep , pte_t pte) +{ + native_set_pte(ptep, pte); +} + #ifndef CONFIG_PARAVIRT /* * Rules for using pte_update - it must be called after any PTE update which @@ -206,16 +255,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pte_update_defer(mm, addr, ptep) do { } while (0) #endif -/* local pte updates need not use xchg for locking */ -static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) -{ - pte_t res = *ptep; - - /* Pure native function needs no input for mm, addr */ - native_pte_clear(NULL, 0, ptep); - return res; -} - /* * We only update the dirty/accessed state if we set * the dirty bit by hand in the kernel, since the hardware @@ -287,10 +326,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_update(mm, addr, ptep); } -#ifndef CONFIG_PARAVIRT -#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) -#endif /* !CONFIG_PARAVIRT */ - #include #endif /* __ASSEMBLY__ */ diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 435e17187eb..29fdeb8111b 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -63,51 +63,59 @@ extern void clear_kernel_mapping(unsigned long addr, unsigned long size); #define pgd_none(x) (!pgd_val(x)) #define pud_none(x) (!pud_val(x)) -static inline void set_pte(pte_t *dst, pte_t val) +struct mm_struct; + +static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) { - *dst = val; -} -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + *ptep = native_make_pte(0); +} -static inline void set_pmd(pmd_t *dst, pmd_t val) +static inline void native_set_pte(pte_t *ptep, pte_t pte) { - *dst = val; -} + *ptep = pte; +} -static inline void set_pud(pud_t *dst, pud_t val) +static inline pte_t native_ptep_get_and_clear(pte_t *xp) { - *dst = val; +#ifdef CONFIG_SMP + return native_make_pte(xchg(&xp->pte, 0)); +#else + /* native_local_ptep_get_and_clear, but duplicated because of cyclic dependency */ + pte_t ret = *xp; + native_pte_clear(NULL, 0, xp); + return ret; +#endif } -static inline void pud_clear (pud_t *pud) +static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) { - set_pud(pud, __pud(0)); + *pmdp = pmd; } -static inline void set_pgd(pgd_t *dst, pgd_t val) +static inline void native_pmd_clear(pmd_t *pmd) { - *dst = val; -} + native_set_pmd(pmd, native_make_pmd(0)); +} -static inline void pgd_clear (pgd_t * pgd) +static inline void native_set_pud(pud_t *pudp, pud_t pud) { - set_pgd(pgd, __pgd(0)); + *pudp = pud; } -#define native_ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte, 0)) +static inline void native_pud_clear(pud_t *pud) +{ + native_set_pud(pud, native_make_pud(0)); +} -struct mm_struct; +static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd) +{ + *pgdp = pgd; +} -static inline pte_t native_ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) +static inline void native_pgd_clear(pgd_t * pgd) { - pte_t pte; - if (full) { - pte = *ptep; - *ptep = __pte(0); - } else { - pte = native_ptep_get_and_clear(ptep); - } - return pte; + native_set_pgd(pgd, native_make_pgd(0)); } #define pte_same(a, b) ((a).pte == (b).pte) @@ -151,7 +159,6 @@ static inline unsigned long pmd_bad(pmd_t pmd) #define pte_none(x) (!pte_val(x)) #define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) -#define native_pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) /* FIXME: is this right? */ #define pte_page(x) pfn_to_page(pte_pfn(x)) @@ -196,7 +203,6 @@ static inline unsigned long pmd_bad(pmd_t pmd) pmd_index(address)) #define pmd_none(x) (!pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot))) #define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) -- cgit v1.2.2 From f29192320f22f1617d50a9c790862603eeef64e6 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:32:59 +0100 Subject: x86/pgtable: explain constant sign extension problem When the _PAGE_FOO constants are defined as (1ul << _PAGE_BIT_FOO), they become unsigned longs. In 32-bit PAE mode, these end up being implicitly cast to 64-bit types when used to manipulate a pte, and because they're unsigned the top 32-bits are 0, destroying the upper bits of the pte. When _PAGE_FOO constants are given a signed integer type, the cast to 64-bits will sign-extend so that the upper bits are all ones, preserving the upper pte bits in manipulations. Explain this in a prominent place. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index a1eeacdf9d8..75a656e6b3f 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -19,6 +19,11 @@ #define _PAGE_BIT_UNUSED3 11 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ +/* + * Note: we use _AC(1, L) instead of _AC(1, UL) so that we get a + * sign-extended value on 32-bit with all 1's in the upper word, + * which preserves the upper pte values on 64-bit ptes: + */ #define _PAGE_PRESENT (_AC(1, L)<<_PAGE_BIT_PRESENT) #define _PAGE_RW (_AC(1, L)<<_PAGE_BIT_RW) #define _PAGE_USER (_AC(1, L)<<_PAGE_BIT_USER) -- cgit v1.2.2 From 3a556b26a2718e48aa2b6ce06ea4875ddcd0778e Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 30 Jan 2008 13:33:00 +0100 Subject: x86: big ticket locks This implements ticket lock support for more than 255 CPUs on x86. The code gets switched according to the configured NR_CPUS. Signed-off-by: Nick Piggin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/spinlock.h | 124 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 27 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h index 2076d5d62d8..23804c1890f 100644 --- a/include/asm-x86/spinlock.h +++ b/include/asm-x86/spinlock.h @@ -35,10 +35,35 @@ typedef int _slock_t; # define LOCK_PTR_REG "D" #endif -#if (NR_CPUS > 256) -#error spinlock supports a maximum of 256 CPUs +#if defined(CONFIG_X86_32) && \ + (defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)) +/* + * On PPro SMP or if we are using OOSTORE, we use a locked operation to unlock + * (PPro errata 66, 92) + */ +# define UNLOCK_LOCK_PREFIX LOCK_PREFIX +#else +# define UNLOCK_LOCK_PREFIX #endif +/* + * Ticket locks are conceptually two parts, one indicating the current head of + * the queue, and the other indicating the current tail. The lock is acquired + * by atomically noting the tail and incrementing it by one (thus adding + * ourself to the queue and noting our position), then waiting until the head + * becomes equal to the the initial value of the tail. + * + * We use an xadd covering *both* parts of the lock, to increment the tail and + * also load the position of the head, which takes care of memory ordering + * issues and should be optimal for the uncontended case. Note the tail must be + * in the high part, because a wide xadd increment of the low part would carry + * up and contaminate the high part. + * + * With fewer than 2^8 possible CPUs, we can use x86's partial registers to + * save some instructions and make the code more elegant. There really isn't + * much between them in performance though, especially as locks are out of line. + */ +#if (NR_CPUS < 256) static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { int tmp = *(volatile signed int *)(&(lock)->slock); @@ -57,21 +82,6 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) { short inc = 0x0100; - /* - * Ticket locks are conceptually two bytes, one indicating the current - * head of the queue, and the other indicating the current tail. The - * lock is acquired by atomically noting the tail and incrementing it - * by one (thus adding ourself to the queue and noting our position), - * then waiting until the head becomes equal to the the initial value - * of the tail. - * - * This uses a 16-bit xadd to increment the tail and also load the - * position of the head, which takes care of memory ordering issues - * and should be optimal for the uncontended case. Note the tail must - * be in the high byte, otherwise the 16-bit wide increment of the low - * byte would carry up and contaminate the high byte. - */ - __asm__ __volatile__ ( LOCK_PREFIX "xaddw %w0, %1\n" "1:\t" @@ -111,25 +121,85 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) return tmp; } -#if defined(CONFIG_X86_32) && \ - (defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)) -/* - * On PPro SMP or if we are using OOSTORE, we use a locked operation to unlock - * (PPro errata 66, 92) - */ -# define UNLOCK_LOCK_PREFIX LOCK_PREFIX +static inline void __raw_spin_unlock(raw_spinlock_t *lock) +{ + __asm__ __volatile__( + UNLOCK_LOCK_PREFIX "incb %0" + :"+m" (lock->slock) + : + :"memory", "cc"); +} #else -# define UNLOCK_LOCK_PREFIX -#endif +static inline int __raw_spin_is_locked(raw_spinlock_t *lock) +{ + int tmp = *(volatile signed int *)(&(lock)->slock); + + return (((tmp >> 16) & 0xffff) != (tmp & 0xffff)); +} + +static inline int __raw_spin_is_contended(raw_spinlock_t *lock) +{ + int tmp = *(volatile signed int *)(&(lock)->slock); + + return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1; +} + +static inline void __raw_spin_lock(raw_spinlock_t *lock) +{ + int inc = 0x00010000; + int tmp; + + __asm__ __volatile__ ( + "lock ; xaddl %0, %1\n" + "movzwl %w0, %2\n\t" + "shrl $16, %0\n\t" + "1:\t" + "cmpl %0, %2\n\t" + "je 2f\n\t" + "rep ; nop\n\t" + "movzwl %1, %2\n\t" + /* don't need lfence here, because loads are in-order */ + "jmp 1b\n" + "2:" + :"+Q" (inc), "+m" (lock->slock), "=r" (tmp) + : + :"memory", "cc"); +} + +#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) + +static inline int __raw_spin_trylock(raw_spinlock_t *lock) +{ + int tmp; + int new; + + asm volatile( + "movl %2,%0\n\t" + "movl %0,%1\n\t" + "roll $16, %0\n\t" + "cmpl %0,%1\n\t" + "jne 1f\n\t" + "addl $0x00010000, %1\n\t" + "lock ; cmpxchgl %1,%2\n\t" + "1:" + "sete %b1\n\t" + "movzbl %b1,%0\n\t" + :"=&a" (tmp), "=r" (new), "+m" (lock->slock) + : + : "memory", "cc"); + + return tmp; +} static inline void __raw_spin_unlock(raw_spinlock_t *lock) { __asm__ __volatile__( - UNLOCK_LOCK_PREFIX "incb %0" + UNLOCK_LOCK_PREFIX "incw %0" :"+m" (lock->slock) : :"memory", "cc"); } +#endif static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) { -- cgit v1.2.2 From d50efc6c40620b2e11648cac64ebf4a824e40382 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:00 +0100 Subject: x86: fix UML and -regparm=3 introduce the "asmregparm" calling convention: for functions implemented in assembly with a fixed regparm input parameters calling convention. mark the semaphore and rwsem slowpath functions with that. Signed-off-by: Ingo Molnar Signed-off-by: Miklos Szeredi Signed-off-by: Thomas Gleixner --- include/asm-x86/linkage.h | 5 +++++ include/asm-x86/rwsem.h | 12 ++++++++---- include/asm-x86/semaphore_32.h | 8 ++++---- 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/linkage.h b/include/asm-x86/linkage.h index 5a4c9590542..31739c7d66a 100644 --- a/include/asm-x86/linkage.h +++ b/include/asm-x86/linkage.h @@ -9,6 +9,11 @@ #ifdef CONFIG_X86_32 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) #define prevent_tail_call(ret) __asm__ ("" : "=r" (ret) : "0" (ret)) +/* + * For 32-bit UML - mark functions implemented in assembly that use + * regparm input parameters: + */ +#define asmregparm __attribute__((regparm(3))) #endif #ifdef CONFIG_X86_ALIGNMENT_16 diff --git a/include/asm-x86/rwsem.h b/include/asm-x86/rwsem.h index a7e7e14cb43..520a379f4b8 100644 --- a/include/asm-x86/rwsem.h +++ b/include/asm-x86/rwsem.h @@ -44,10 +44,14 @@ struct rwsem_waiter; -extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem)); -extern struct rw_semaphore *FASTCALL(rwsem_down_write_failed(struct rw_semaphore *sem)); -extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *)); -extern struct rw_semaphore *FASTCALL(rwsem_downgrade_wake(struct rw_semaphore *sem)); +extern asmregparm struct rw_semaphore * + rwsem_down_read_failed(struct rw_semaphore *sem); +extern asmregparm struct rw_semaphore * + rwsem_down_write_failed(struct rw_semaphore *sem); +extern asmregparm struct rw_semaphore * + rwsem_wake(struct rw_semaphore *); +extern asmregparm struct rw_semaphore * + rwsem_downgrade_wake(struct rw_semaphore *sem); /* * the semaphore definition diff --git a/include/asm-x86/semaphore_32.h b/include/asm-x86/semaphore_32.h index cc826e85323..ac96d3804d0 100644 --- a/include/asm-x86/semaphore_32.h +++ b/include/asm-x86/semaphore_32.h @@ -83,10 +83,10 @@ static inline void init_MUTEX_LOCKED (struct semaphore *sem) sema_init(sem, 0); } -void __down_failed(void /* special register calling convention */); -int __down_failed_interruptible(void /* params in registers */); -int __down_failed_trylock(void /* params in registers */); -void __up_wakeup(void /* special register calling convention */); +extern asmregparm void __down_failed(atomic_t *count_ptr); +extern asmregparm int __down_failed_interruptible(atomic_t *count_ptr); +extern asmregparm int __down_failed_trylock(atomic_t *count_ptr); +extern asmregparm void __up_wakeup(atomic_t *count_ptr); /* * This is ugly, but we want the default case to fall through. -- cgit v1.2.2 From 1379a5ce3ffc549a7ff3daffc49c5e1c372717a3 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:33:00 +0100 Subject: x86: move get_segment_eip() to step.c get_segment_eip has similarities to convert_rip_to_linear(), and is used in a similar context. Move get_segment_eip to step.c to allow easier consolidation. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 61946fe8c08..cc4456667d8 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -184,6 +184,8 @@ convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs); #ifdef __KERNEL__ +unsigned long get_segment_eip(struct pt_regs *regs, unsigned long *eip_limit); + /* * These are defined as per linux/ptrace.h, which see. */ -- cgit v1.2.2 From 2a6648e65a2939b80c44262975176a15bac3a75e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:33:01 +0100 Subject: x86: : boot GDT entries are 32/64-independent The boot GDT entries are common between 32- and 64-bit mode, so move them to common code instead of having two identical copies. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/segment.h | 24 ++++++++---------------- include/asm-x86/segment_32.h | 1 - 2 files changed, 8 insertions(+), 17 deletions(-) delete mode 100644 include/asm-x86/segment_32.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h index c7509df7914..1ff05a9f551 100644 --- a/include/asm-x86/segment.h +++ b/include/asm-x86/segment.h @@ -1,6 +1,14 @@ #ifndef _ASM_X86_SEGMENT_H_ #define _ASM_X86_SEGMENT_H_ +/* Simple and small GDT entries for booting only */ + +#define GDT_ENTRY_BOOT_CS 2 +#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) + +#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) +#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) + #ifdef CONFIG_X86_32 /* * The layout of the per-CPU GDT under Linux: @@ -86,14 +94,6 @@ */ #define GDT_ENTRIES 32 -/* Simple and small GDT entries for booting only */ - -#define GDT_ENTRY_BOOT_CS 2 -#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) - -#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) -#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) - /* The PnP BIOS entries in the GDT */ #define GDT_ENTRY_PNPBIOS_CS32 (GDT_ENTRY_PNPBIOS_BASE + 0) #define GDT_ENTRY_PNPBIOS_CS16 (GDT_ENTRY_PNPBIOS_BASE + 1) @@ -136,14 +136,6 @@ #else #include -/* Simple and small GDT entries for booting only */ - -#define GDT_ENTRY_BOOT_CS 2 -#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) - -#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) -#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) - #define __KERNEL_CS 0x10 #define __KERNEL_DS 0x18 diff --git a/include/asm-x86/segment_32.h b/include/asm-x86/segment_32.h deleted file mode 100644 index 8b137891791..00000000000 --- a/include/asm-x86/segment_32.h +++ /dev/null @@ -1 +0,0 @@ - -- cgit v1.2.2 From 88089519f302f1296b4739be45699f06f728ec31 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Jan 2008 13:33:02 +0100 Subject: x86 setup: initialize LDTR and TR to make life easier to Intel VT Intel VT doesn't like to engage when the protected-mode state isn't fully initialized. Make life easier for it by initializing LDTR (to null) and TR (to a dummy hunk of low memory which will never actually be touched.) Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/segment.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h index 1ff05a9f551..57c8d372383 100644 --- a/include/asm-x86/segment.h +++ b/include/asm-x86/segment.h @@ -9,6 +9,9 @@ #define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) #define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) +#define GDT_ENTRY_BOOT_TSS (GDT_ENTRY_BOOT_CS + 2) +#define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8) + #ifdef CONFIG_X86_32 /* * The layout of the per-CPU GDT under Linux: -- cgit v1.2.2 From 8866cd9dc9d0bbadcf361a14e0cdfecb66473087 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:33:06 +0100 Subject: x86: early_idt_handler improvements, 64-bit It's not too pretty, but I found this made the "PANIC: early exception" messages become much more reliably useful: 1. print the vector number, 2. print the %cs value, 3. handle error-code-pushing vs non-pushing vectors. Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/segment.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h index 57c8d372383..23f0535fec6 100644 --- a/include/asm-x86/segment.h +++ b/include/asm-x86/segment.h @@ -195,4 +195,10 @@ #define GDT_ENTRY_TLS_ENTRIES 3 #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ +extern const char early_idt_handlers[IDT_ENTRIES][10]; +#endif +#endif + #endif -- cgit v1.2.2 From 076f9776f5d8d131b36955db8641aba3893c2c1b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:06 +0100 Subject: x86: make early printk selectable on 64-bit as well Enable CONFIG_EMBEDDED to select CONFIG_EARLY_PRINTK on 64-bit as well. saves ~2K: text data bss dec hex filename 7290283 3672091 1907848 12870222 c4624e vmlinux.before 7288373 3671795 1907848 12868016 c459b0 vmlinux.after Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/kdebug.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index a5e5e3b7eb2..e9f42d1ac38 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -22,7 +22,6 @@ enum die_val { DIE_PAGE_FAULT, }; -extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); extern void printk_address(unsigned long address); extern void die(const char *,struct pt_regs *,long); extern int __must_check __die(const char *, struct pt_regs *, long); -- cgit v1.2.2 From bc850d6b374fffd08336996f4b4d3bbd6bf427f6 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 30 Jan 2008 13:33:07 +0100 Subject: x86: add the capability to print fuzzy backtraces For enhancing the 32 bit EBP based backtracer, I need the capability for the backtracer to tell it's customer that an entry is either reliable or unreliable, and the backtrace printing code then needs to print the unreliable ones slightly different. This patch adds the basic capability, the next patch will add a user of this capability. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/kdebug.h | 5 +++-- include/asm-x86/stacktrace.h | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index e9f42d1ac38..dd442a1632c 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -22,12 +22,13 @@ enum die_val { DIE_PAGE_FAULT, }; -extern void printk_address(unsigned long address); +extern void printk_address(unsigned long address, int reliable); extern void die(const char *,struct pt_regs *,long); extern int __must_check __die(const char *, struct pt_regs *, long); extern void show_registers(struct pt_regs *regs); extern void __show_registers(struct pt_regs *, int all); -extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long *); +extern void show_trace(struct task_struct *t, struct pt_regs *regs, + unsigned long *sp, unsigned long bp); extern void __show_regs(struct pt_regs *regs); extern void show_regs(struct pt_regs *regs); extern void dump_pagetable(unsigned long); diff --git a/include/asm-x86/stacktrace.h b/include/asm-x86/stacktrace.h index 70dd5bae323..30f82526a8e 100644 --- a/include/asm-x86/stacktrace.h +++ b/include/asm-x86/stacktrace.h @@ -9,12 +9,13 @@ struct stacktrace_ops { void (*warning)(void *data, char *msg); /* msg must contain %s for the symbol */ void (*warning_symbol)(void *data, char *msg, unsigned long symbol); - void (*address)(void *data, unsigned long address); + void (*address)(void *data, unsigned long address, int reliable); /* On negative return stop dumping */ int (*stack)(void *data, char *name); }; -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, +void dump_trace(struct task_struct *tsk, struct pt_regs *regs, + unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data); #endif -- cgit v1.2.2 From 306c142f99caef5a30a0d61a39a956c069941b63 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:08 +0100 Subject: x86: pat: e820 cleanup NOP change. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/e820.h | 3 +++ include/asm-x86/e820_64.h | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 3e214f39fad..f96f1853bc4 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -22,6 +22,9 @@ struct e820map { }; #endif /* __ASSEMBLY__ */ +#define ISA_START_ADDRESS 0xa0000 +#define ISA_END_ADDRESS 0x100000 + #ifdef __KERNEL__ #ifdef CONFIG_X86_32 # include "e820_32.h" diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h index 1c7ba880417..8cba49da479 100644 --- a/include/asm-x86/e820_64.h +++ b/include/asm-x86/e820_64.h @@ -26,6 +26,10 @@ extern void e820_reserve_resources(struct resource *code_resource, 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); @@ -38,6 +42,7 @@ extern struct e820map e820; extern unsigned ebda_addr, ebda_size; extern unsigned long nodemap_addr, nodemap_size; + #endif/*!__ASSEMBLY__*/ #endif/*__E820_HEADER*/ -- cgit v1.2.2 From aaf230424204864e2833dcc1da23e2cb0b9f39cd Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 30 Jan 2008 13:33:09 +0100 Subject: x86: disable the GART early, 64-bit For K8 system: 4G RAM with memory hole remapping enabled, or more than 4G RAM installed. when try to use kexec second kernel, and the first doesn't include gart_shutdown. the second kernel could have different aper position than the first kernel. and second kernel could use that hole as RAM that is still used by GART set by the first kernel. esp. when try to kexec 2.6.24 with sparse mem enable from previous kernel (from RHEL 5 or SLES 10). the new kernel will use aper by GART (set by first kernel) for vmemmap. and after new kernel setting one new GART. the position will be real RAM. the _mapcount set is lost. Bad page state in process 'swapper' page:ffffe2000e600020 flags:0x0000000000000000 mapping:0000000000000000 mapcount:1 count:0 Trying to fix it up, but a reboot is needed Backtrace: Pid: 0, comm: swapper Not tainted 2.6.24-rc7-smp-gcdf71a10-dirty #13 Call Trace: [] bad_page+0x63/0x8d [] __free_pages_ok+0x7c/0x2a5 [] free_all_bootmem_core+0xd0/0x198 [] numa_free_all_bootmem+0x3b/0x76 [] mem_init+0x3b/0x152 [] start_kernel+0x236/0x2c2 [] _sinittext+0x11a/0x121 and [ffffe2000e600000-ffffe2000e7fffff] PMD ->ffff81001c200000 on node 0 phys addr is : 0x1c200000 RHEL 5.1 kernel -53 said: PCI-DMA: aperture base @ 1c000000 size 65536 KB new kernel said: Mapping aperture over 65536 KB of RAM @ 3c000000 So could try to disable that GART if possible. According to Ingo > hm, i'm wondering, instead of modifying the GART, why dont we simply > _detect_ whatever GART settings we have inherited, and propagate that > into our e820 maps? I.e. if there's inconsistency, then punch that out > from the memory maps and just dont use that memory. > > that way it would not matter whether the GART settings came from a [old > or crashing] Linux kernel that has not called gart_iommu_shutdown(), or > whether it's a BIOS that has set up an aperture hole inconsistent with > the memory map it passed. (or the memory map we _think_ i tried to pass > us) > > it would also be more robust to only read and do a memory map quirk > based on that, than actively trying to change the GART so early in the > bootup. Later on we have to re-enable the GART _anyway_ and have to > punch a hole for it. > > and as a bonus, we would have shored up our defenses against crappy > BIOSes as well. add e820 modification for gart inconsistent setting. gart_fix_e820=off could be used to disable e820 fix. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/e820_64.h | 1 + include/asm-x86/gart.h | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h index 8cba49da479..ff36f434f00 100644 --- a/include/asm-x86/e820_64.h +++ b/include/asm-x86/e820_64.h @@ -39,6 +39,7 @@ extern void e820_register_active_regions(int nid, extern void finish_e820_parsing(void); extern struct e820map e820; +extern void update_e820(void); extern unsigned ebda_addr, ebda_size; extern unsigned long nodemap_addr, nodemap_size; diff --git a/include/asm-x86/gart.h b/include/asm-x86/gart.h index f704c50519b..90958ed993f 100644 --- a/include/asm-x86/gart.h +++ b/include/asm-x86/gart.h @@ -9,6 +9,7 @@ extern int iommu_detected; extern void gart_iommu_init(void); extern void gart_iommu_shutdown(void); extern void __init gart_parse_options(char *); +extern void early_gart_iommu_check(void); extern void gart_iommu_hole_init(void); extern int fallback_aper_order; extern int fallback_aper_force; @@ -20,6 +21,10 @@ extern int fix_aperture; #define gart_iommu_aperture 0 #define gart_iommu_aperture_allowed 0 +static inline void early_gart_iommu_check(void) +{ +} + static inline void gart_iommu_shutdown(void) { } -- cgit v1.2.2 From ef97001f3d869d7cc1956e0cc0d89e514e3f7db0 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:10 +0100 Subject: x86: change size of APICIDs from u8 to u16 Change the size of APICIDs from u8 to u16. This partially supports the new x2apic mode that will be present on future processor chips. (Chips actually support 32-bit APICIDs, but that change is more intrusive. Supporting 16-bit is sufficient for now). Signed-off-by: Jack Steiner I've included just the partial change from u8 to u16 apicids. The remaining x2apic changes will be in a separate patch. In addition, the fake_node_to_pxm_map[] and fake_apicid_to_node[] tables have been moved from local data to the __initdata section reducing stack pressure when MAX_NUMNODES and MAX_LOCAL_APIC are increased in size. Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 14 +++++++------- include/asm-x86/smp_64.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index e701ac5487e..81ecfed83e4 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -90,14 +90,14 @@ struct cpuinfo_x86 { #ifdef CONFIG_SMP cpumask_t llc_shared_map; /* cpus sharing the last level cache */ #endif - unsigned char x86_max_cores; /* cpuid returned max cores value */ - unsigned char apicid; - unsigned short x86_clflush_size; + u16 x86_max_cores; /* cpuid returned max cores value */ + u16 apicid; + u16 x86_clflush_size; #ifdef CONFIG_SMP - unsigned char booted_cores; /* number of cores as seen by OS */ - __u8 phys_proc_id; /* Physical processor id. */ - __u8 cpu_core_id; /* Core id */ - __u8 cpu_index; /* index into per_cpu list */ + u16 booted_cores; /* number of cores as seen by OS */ + u16 phys_proc_id; /* Physical processor id. */ + u16 cpu_core_id; /* Core id */ + u16 cpu_index; /* index into per_cpu list */ #endif } __attribute__((__aligned__(SMP_CACHE_BYTES))); diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h index 2feddda91e1..b1d5381aa76 100644 --- a/include/asm-x86/smp_64.h +++ b/include/asm-x86/smp_64.h @@ -26,14 +26,14 @@ extern void unlock_ipi_call_lock(void); extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, int wait); -extern u8 __initdata x86_cpu_to_apicid_init[]; +extern u16 __initdata x86_cpu_to_apicid_init[]; extern void *x86_cpu_to_apicid_ptr; -extern u8 bios_cpu_apicid[]; +extern u16 bios_cpu_apicid[]; DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); DECLARE_PER_CPU(cpumask_t, cpu_core_map); -DECLARE_PER_CPU(u8, cpu_llc_id); -DECLARE_PER_CPU(u8, x86_cpu_to_apicid); +DECLARE_PER_CPU(u16, cpu_llc_id); +DECLARE_PER_CPU(u16, x86_cpu_to_apicid); static inline int cpu_present_to_apicid(int mps_cpu) { -- cgit v1.2.2 From 3cc87e3f4042a099fb649c5df33d3ccfae36173f Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:11 +0100 Subject: x86: change size of node ids from u8 to u16 Change the size of node ids from 8 bits to 16 bits to accomodate more than 256 nodes. Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/numa_64.h | 4 ++-- include/asm-x86/topology.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index 4449889bb0c..941889471b5 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h @@ -20,7 +20,7 @@ extern void numa_set_node(int cpu, int node); extern void srat_reserve_add_area(int nodeid); extern int hotadd_percent; -extern unsigned char apicid_to_node[MAX_LOCAL_APIC]; +extern u16 apicid_to_node[MAX_LOCAL_APIC]; extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); extern unsigned long numa_free_all_bootmem(void); @@ -40,6 +40,6 @@ static inline void clear_node_cpumask(int cpu) #define clear_node_cpumask(cpu) do {} while (0) #endif -#define NUMA_NO_NODE 0xff +#define NUMA_NO_NODE 0xffff #endif diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 9c251604ecc..f8706b2a3d8 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -30,7 +30,7 @@ #include /* Mappings between logical cpu number and node number */ -extern int cpu_to_node_map[]; +extern u16 cpu_to_node_map[]; extern cpumask_t node_to_cpumask_map[]; /* Returns the number of the node containing CPU 'cpu' */ -- cgit v1.2.2 From 30964d54e94229f567a7312a0e6666f9deb6a488 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:11 +0100 Subject: x86: change NR_CPUS arrays in topology Change the following static arrays sized by NR_CPUS to per_cpu data variables: i386_cpu cpu_devices[NR_CPUS]; (And change the struct name to x86_cpu.) Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpu.h b/include/asm-x86/cpu.h index b1bc7b1b64b..85ece5f10e9 100644 --- a/include/asm-x86/cpu.h +++ b/include/asm-x86/cpu.h @@ -7,7 +7,7 @@ #include #include -struct i386_cpu { +struct x86_cpu { struct cpu cpu; }; extern int arch_register_cpu(int num); -- cgit v1.2.2 From 3b41908902df1dba141cd7de1a727bb03718a654 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:11 +0100 Subject: x86: cleanup x86_cpu_to_apicid references Clean up references to x86_cpu_to_apicid. Removes extraneous comments and standardizes on "x86_*_early_ptr" for the early kernel init references. Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/smp_32.h | 2 +- include/asm-x86/smp_64.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h index c69e960429c..56152e31228 100644 --- a/include/asm-x86/smp_32.h +++ b/include/asm-x86/smp_32.h @@ -30,7 +30,7 @@ extern void (*mtrr_hook) (void); extern void zap_low_mappings (void); extern u8 __initdata x86_cpu_to_apicid_init[]; -extern void *x86_cpu_to_apicid_ptr; +extern void *x86_cpu_to_apicid_early_ptr; DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); DECLARE_PER_CPU(cpumask_t, cpu_core_map); diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h index b1d5381aa76..6fa332db29c 100644 --- a/include/asm-x86/smp_64.h +++ b/include/asm-x86/smp_64.h @@ -27,7 +27,7 @@ extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, int wait); extern u16 __initdata x86_cpu_to_apicid_init[]; -extern void *x86_cpu_to_apicid_ptr; +extern void *x86_cpu_to_apicid_early_ptr; extern u16 bios_cpu_apicid[]; DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); -- cgit v1.2.2 From df3825c56dd70a4d7796041388f3cfe51c1db832 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:11 +0100 Subject: x86: change NR_CPUS arrays in numa_64 Change the following static arrays sized by NR_CPUS to per_cpu data variables: char cpu_to_node_map[NR_CPUS]; Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/numa_64.h | 2 -- include/asm-x86/topology.h | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index 941889471b5..c797cd523d2 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h @@ -40,6 +40,4 @@ static inline void clear_node_cpumask(int cpu) #define clear_node_cpumask(cpu) do {} while (0) #endif -#define NUMA_NO_NODE 0xffff - #endif diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index f8706b2a3d8..e612ed8d2bc 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -30,13 +30,24 @@ #include /* Mappings between logical cpu number and node number */ -extern u16 cpu_to_node_map[]; +DECLARE_PER_CPU(u16, x86_cpu_to_node_map); +extern u16 __initdata x86_cpu_to_node_map_init[]; +extern void *x86_cpu_to_node_map_early_ptr; extern cpumask_t node_to_cpumask_map[]; +#define NUMA_NO_NODE ((u16)(~0)) + /* Returns the number of the node containing CPU 'cpu' */ static inline int cpu_to_node(int cpu) { - return cpu_to_node_map[cpu]; + u16 *cpu_to_node_map = (u16 *)x86_cpu_to_node_map_early_ptr; + + if (cpu_to_node_map) + return cpu_to_node_map[cpu]; + else if (per_cpu_offset(cpu)) + return per_cpu(x86_cpu_to_node_map, cpu); + else + return NUMA_NO_NODE; } /* -- cgit v1.2.2 From e8c10ef9dde3ab7b7d7db6804859d9daf38f01c4 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:12 +0100 Subject: x86: change bios_cpu_apicid to percpu data variable Change static bios_cpu_apicid array to a per_cpu data variable. This includes using a static array used during initialization similar to the way x86_cpu_to_apicid[] is handled. There is one early use of bios_cpu_apicid in apic_is_clustered_box(). The other reference in cpu_present_to_apicid() is called after smp_set_apicids() has setup the percpu version of bios_cpu_apicid. [ mingo@elte.hu: build fix ] Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/smp_64.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h index 6fa332db29c..e0a75519ad2 100644 --- a/include/asm-x86/smp_64.h +++ b/include/asm-x86/smp_64.h @@ -27,18 +27,20 @@ extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, int wait); extern u16 __initdata x86_cpu_to_apicid_init[]; +extern u16 __initdata x86_bios_cpu_apicid_init[]; extern void *x86_cpu_to_apicid_early_ptr; -extern u16 bios_cpu_apicid[]; +extern void *x86_bios_cpu_apicid_early_ptr; DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); DECLARE_PER_CPU(cpumask_t, cpu_core_map); DECLARE_PER_CPU(u16, cpu_llc_id); DECLARE_PER_CPU(u16, x86_cpu_to_apicid); +DECLARE_PER_CPU(u16, x86_bios_cpu_apicid); static inline int cpu_present_to_apicid(int mps_cpu) { - if (mps_cpu < NR_CPUS) - return (int)bios_cpu_apicid[mps_cpu]; + if (cpu_present(mps_cpu)) + return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); else return BAD_APICID; } -- cgit v1.2.2 From 37cd9cf3dafed82f7cf905785883300f6ff7c818 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:33:12 +0100 Subject: x86: common x86_32|64 naming Rename convert_rip_to_linear to convert_ip_to_linear for shared X86_32|64 use. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index cc4456667d8..35c10371490 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -177,7 +177,7 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where); struct task_struct; extern unsigned long -convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs); +convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); #endif /* __KERNEL__ */ #endif /* !__i386__ */ -- cgit v1.2.2 From f2857ce92023409df1544737d5b3499b4630a183 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:33:12 +0100 Subject: x86: remove last user of get_segment_eip is_prefetch was the last user of get_segment_eip and only on X86_32. This function returned the faulting instruction's address and set the upper segment limit. Instead, use the convert_ip_to_linear helper and rely on probe_kernel_address to do the segment checks which was already done everywhere the segment limit was being checked on X86_32. Remove get_segment_eip as well. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 35c10371490..ee4b595e1cc 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -70,6 +70,10 @@ struct pt_regs { #include struct task_struct; + +extern unsigned long +convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); + extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); /* @@ -184,8 +188,6 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); #ifdef __KERNEL__ -unsigned long get_segment_eip(struct pt_regs *regs, unsigned long *eip_limit); - /* * These are defined as per linux/ptrace.h, which see. */ -- cgit v1.2.2 From 466eed22d127a1f16e1251cdc54a9f8f944140c0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Jan 2008 13:33:14 +0100 Subject: x86: isolate PIC/PIT in/out calls Rather than remove and/or mangle inb_p/outb_p we want to remove the use of them from inappropriate places. For the PIC/PIT this may eventually depend on 32/64bitism or similar so start by adding inb/outb_pit and inb/outb_pic so that we can make them use any scheme we settle on without disturbing the existing, correct (for ISA), port 0x80 usage. (eg we can make inb_pit use udelay without messing up inb_p). Floppy already does this for the fdc. That really only leaves the CMOS as a core logic item to tackle, and bits of parallel port handling in the chipset layers. Signed-off-by: Alan Cox Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/i8253.h | 3 +++ include/asm-x86/i8259.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/i8253.h b/include/asm-x86/i8253.h index 747548ec5d1..b51c0487fc4 100644 --- a/include/asm-x86/i8253.h +++ b/include/asm-x86/i8253.h @@ -12,4 +12,7 @@ extern struct clock_event_device *global_clock_event; extern void setup_pit_timer(void); +#define inb_pit inb_p +#define outb_pit outb_p + #endif /* __ASM_I8253_H__ */ diff --git a/include/asm-x86/i8259.h b/include/asm-x86/i8259.h index cabcc6cf392..67c319e0efc 100644 --- a/include/asm-x86/i8259.h +++ b/include/asm-x86/i8259.h @@ -29,4 +29,7 @@ extern void enable_8259A_irq(unsigned int irq); extern void disable_8259A_irq(unsigned int irq); extern unsigned int startup_8259A_irq(unsigned int irq); +#define inb_pic inb_p +#define outb_pic outb_p + #endif /* __ASM_I8259_H__ */ -- cgit v1.2.2 From 693e3c560317577a29c625d89f6745d5c7cfd918 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Wed, 30 Jan 2008 13:33:14 +0100 Subject: x86: reduce memory and intra-node effects Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/topology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index e612ed8d2bc..a89b46eb252 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -40,7 +40,7 @@ extern cpumask_t node_to_cpumask_map[]; /* Returns the number of the node containing CPU 'cpu' */ static inline int cpu_to_node(int cpu) { - u16 *cpu_to_node_map = (u16 *)x86_cpu_to_node_map_early_ptr; + u16 *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; if (cpu_to_node_map) return cpu_to_node_map[cpu]; -- cgit v1.2.2 From 118c890961a2ca456947d72ebe0ce43de07907f0 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 30 Jan 2008 13:33:14 +0100 Subject: arch/x86/mm/numa_64.c: section fix WARNING: vmlinux.o(__ksymtab+0x670): Section mismatch: reference to .init.data:x86_cpu_to_node_map_init (between '__ksymtab_x86_cpu_to_node_map_init' and '__ksymtab_node_data') Cc: Matthew Dobson Cc: Mike Travis Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/topology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index a89b46eb252..2da1464ecbe 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -31,7 +31,7 @@ /* Mappings between logical cpu number and node number */ DECLARE_PER_CPU(u16, x86_cpu_to_node_map); -extern u16 __initdata x86_cpu_to_node_map_init[]; +extern u16 x86_cpu_to_node_map_init[]; extern void *x86_cpu_to_node_map_early_ptr; extern cpumask_t node_to_cpumask_map[]; -- cgit v1.2.2 From 2f98b2faac1b5fec327edbde945cdf7f7a53f351 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:14 +0100 Subject: add native_pud_val and _pmd_val for 2 and 3 Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index a6495eb5c60..eba88d94009 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -91,6 +91,11 @@ static inline pudval_t native_pud_val(pud_t pud) } #else /* PAGETABLE_LEVELS == 3 */ #include + +static inline pudval_t native_pud_val(pud_t pud) +{ + return native_pgd_val(pud.pgd); +} #endif /* PAGETABLE_LEVELS == 4 */ typedef struct { pmdval_t pmd; } pmd_t; @@ -106,6 +111,11 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) } #else /* PAGETABLE_LEVELS == 2 */ #include + +static inline pmdval_t native_pmd_val(pmd_t pmd) +{ + return native_pgd_val(pmd.pud.pgd); +} #endif /* PAGETABLE_LEVELS >= 3 */ static inline pte_t native_make_pte(pteval_t val) -- cgit v1.2.2 From 5b8dd1e95b5f2b7b80cfc7e6bb709603aef8bbc1 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86/paravirt: rearrange common mmu_ops Rearrange the various pagetable mmu_ops to remove duplication. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 4aa06b929e4..c38cf1ac4e4 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -230,28 +230,32 @@ struct pv_mmu_ops { void (*pte_update_defer)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); + pteval_t (*pte_val)(pte_t); + pte_t (*make_pte)(pteval_t pte); + + pgdval_t (*pgd_val)(pgd_t); + pgd_t (*make_pgd)(pgdval_t pgd); + +#if PAGETABLE_LEVELS >= 3 #ifdef CONFIG_X86_PAE void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); - void (*set_pud)(pud_t *pudp, pud_t pudval); void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); void (*pmd_clear)(pmd_t *pmdp); - unsigned long long (*pte_val)(pte_t); - unsigned long long (*pmd_val)(pmd_t); - unsigned long long (*pgd_val)(pgd_t); +#endif /* CONFIG_X86_PAE */ + + void (*set_pud)(pud_t *pudp, pud_t pudval); - pte_t (*make_pte)(unsigned long long pte); - pmd_t (*make_pmd)(unsigned long long pmd); - pgd_t (*make_pgd)(unsigned long long pgd); -#else - unsigned long (*pte_val)(pte_t); - unsigned long (*pgd_val)(pgd_t); + pmdval_t (*pmd_val)(pmd_t); + pmd_t (*make_pmd)(pmdval_t pmd); - pte_t (*make_pte)(unsigned long pte); - pgd_t (*make_pgd)(unsigned long pgd); -#endif +#if PAGETABLE_LEVELS == 4 + pudval_t (*pud_val)(pud_t); + pud_t (*make_pud)(pudval_t pud); +#endif /* PAGETABLE_LEVELS == 4 */ +#endif /* PAGETABLE_LEVELS >= 3 */ #ifdef CONFIG_HIGHPTE void *(*kmap_atomic_pte)(struct page *page, enum km_type type); -- cgit v1.2.2 From 773221f46f82dc2f277dacc331d9d2ef2c690cb6 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86/paravirt: common implementation for pte value ops Remove duplicate __pte/pte_val functions. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 48 ++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 21 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index c38cf1ac4e4..b7342efab83 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -920,15 +920,37 @@ static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr, PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep); } -#ifdef CONFIG_X86_PAE -static inline pte_t __pte(unsigned long long val) +static inline pte_t __pte(pteval_t val) { - unsigned long long ret = PVOP_CALL2(unsigned long long, - pv_mmu_ops.make_pte, - val, val >> 32); + pteval_t ret; + + if (sizeof(pteval_t) > sizeof(long)) + ret = PVOP_CALL2(pteval_t, + pv_mmu_ops.make_pte, + val, (u64)val >> 32); + else + ret = PVOP_CALL1(pteval_t, + pv_mmu_ops.make_pte, + val); + return (pte_t) { .pte = ret }; } +static inline pteval_t pte_val(pte_t pte) +{ + pteval_t ret; + + if (sizeof(pteval_t) > sizeof(long)) + ret = PVOP_CALL2(pteval_t, pv_mmu_ops.pte_val, + pte.pte, (u64)pte.pte >> 32); + else + ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_val, + pte.pte); + + return ret; +} + +#ifdef CONFIG_X86_PAE static inline pmd_t __pmd(unsigned long long val) { return (pmd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pmd, @@ -941,12 +963,6 @@ static inline pgd_t __pgd(unsigned long long val) val, val >> 32) }; } -static inline unsigned long long pte_val(pte_t x) -{ - return PVOP_CALL2(unsigned long long, pv_mmu_ops.pte_val, - x.pte_low, x.pte_high); -} - static inline unsigned long long pmd_val(pmd_t x) { return PVOP_CALL2(unsigned long long, pv_mmu_ops.pmd_val, @@ -1008,21 +1024,11 @@ static inline void pmd_clear(pmd_t *pmdp) #else /* !CONFIG_X86_PAE */ -static inline pte_t __pte(unsigned long val) -{ - return (pte_t) { PVOP_CALL1(unsigned long, pv_mmu_ops.make_pte, val) }; -} - static inline pgd_t __pgd(unsigned long val) { return (pgd_t) { PVOP_CALL1(unsigned long, pv_mmu_ops.make_pgd, val) }; } -static inline unsigned long pte_val(pte_t x) -{ - return PVOP_CALL1(unsigned long, pv_mmu_ops.pte_val, x.pte_low); -} - static inline unsigned long pgd_val(pgd_t x) { return PVOP_CALL1(unsigned long, pv_mmu_ops.pgd_val, x.pgd); -- cgit v1.2.2 From ef38503e034f82ad16a75a9dfea40ed7adaf00a8 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86/paravirt: common implementation for pgd value ops Remove duplicate __pgd/pgd_val functions. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 50 ++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index b7342efab83..eac25b5323a 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -950,16 +950,38 @@ static inline pteval_t pte_val(pte_t pte) return ret; } -#ifdef CONFIG_X86_PAE -static inline pmd_t __pmd(unsigned long long val) +static inline pgd_t __pgd(pgdval_t val) { - return (pmd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pmd, - val, val >> 32) }; + pgdval_t ret; + + if (sizeof(pgdval_t) > sizeof(long)) + ret = PVOP_CALL2(pgdval_t, pv_mmu_ops.make_pgd, + val, (u64)val >> 32); + else + ret = PVOP_CALL1(pgdval_t, pv_mmu_ops.make_pgd, + val); + + return (pgd_t) { ret }; +} + +static inline pgdval_t pgd_val(pgd_t pgd) +{ + pgdval_t ret; + + if (sizeof(pgdval_t) > sizeof(long)) + ret = PVOP_CALL2(pgdval_t, pv_mmu_ops.pgd_val, + pgd.pgd, (u64)pgd.pgd >> 32); + else + ret = PVOP_CALL1(pgdval_t, pv_mmu_ops.pgd_val, + pgd.pgd); + + return ret; } -static inline pgd_t __pgd(unsigned long long val) +#ifdef CONFIG_X86_PAE +static inline pmd_t __pmd(unsigned long long val) { - return (pgd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pgd, + return (pmd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pmd, val, val >> 32) }; } @@ -969,12 +991,6 @@ static inline unsigned long long pmd_val(pmd_t x) x.pmd, x.pmd >> 32); } -static inline unsigned long long pgd_val(pgd_t x) -{ - return PVOP_CALL2(unsigned long long, pv_mmu_ops.pgd_val, - x.pgd, x.pgd >> 32); -} - static inline void set_pte(pte_t *ptep, pte_t pteval) { PVOP_VCALL3(pv_mmu_ops.set_pte, ptep, pteval.pte_low, pteval.pte_high); @@ -1024,16 +1040,6 @@ static inline void pmd_clear(pmd_t *pmdp) #else /* !CONFIG_X86_PAE */ -static inline pgd_t __pgd(unsigned long val) -{ - return (pgd_t) { PVOP_CALL1(unsigned long, pv_mmu_ops.make_pgd, val) }; -} - -static inline unsigned long pgd_val(pgd_t x) -{ - return PVOP_CALL1(unsigned long, pv_mmu_ops.pgd_val, x.pgd); -} - static inline void set_pte(pte_t *ptep, pte_t pteval) { PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, pteval.pte_low); -- cgit v1.2.2 From a632da2fc9c1e4e8021c5665fc34201fea485dcf Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86/paravirt: common implementation for pmd value ops Remove duplicate __pmd/pmd_val functions. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index eac25b5323a..3593211e345 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -978,18 +978,37 @@ static inline pgdval_t pgd_val(pgd_t pgd) return ret; } -#ifdef CONFIG_X86_PAE -static inline pmd_t __pmd(unsigned long long val) +#if PAGETABLE_LEVELS >= 3 +static inline pmd_t __pmd(pmdval_t val) { - return (pmd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pmd, - val, val >> 32) }; + pmdval_t ret; + + if (sizeof(pmdval_t) > sizeof(long)) + ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd, + val, (u64)val >> 32); + else + ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd, + val); + + return (pmd_t) { ret }; } -static inline unsigned long long pmd_val(pmd_t x) +static inline pmdval_t pmd_val(pmd_t pmd) { - return PVOP_CALL2(unsigned long long, pv_mmu_ops.pmd_val, - x.pmd, x.pmd >> 32); + pmdval_t ret; + + if (sizeof(pmdval_t) > sizeof(long)) + ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val, + pmd.pmd, (u64)pmd.pmd >> 32); + else + ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val, + pmd.pmd); + + return ret; } +#endif /* PAGETABLE_LEVELS >= 3 */ + +#ifdef CONFIG_X86_PAE static inline void set_pte(pte_t *ptep, pte_t pteval) { -- cgit v1.2.2 From 4eed80cd7a1668df6ddd884f9474beccc81ef3f7 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86/paravirt: make set_pte operations common Remove duplicate set_pte* operations. PAE still needs to have special variants of some of these because it can't atomically update a 64-bit pte, so there's still some duplication. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 116 +++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 56 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 3593211e345..ba1b9433414 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -978,6 +978,66 @@ static inline pgdval_t pgd_val(pgd_t pgd) return ret; } +static inline void set_pte(pte_t *ptep, pte_t pte) +{ + if (sizeof(pteval_t) > sizeof(long)) + PVOP_VCALL3(pv_mmu_ops.set_pte, ptep, + pte.pte, (u64)pte.pte >> 32); + else + PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, + pte.pte); +} + +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + if (sizeof(pteval_t) > sizeof(long)) + /* 5 arg words */ + pv_mmu_ops.set_pte_at(mm, addr, ptep, pte); + else + PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); +} + +#ifdef CONFIG_X86_PAE +/* Special-case pte-setting operations for PAE, which can't update a + 64-bit pte atomically */ +static inline void set_pte_atomic(pte_t *ptep, pte_t pte) +{ + PVOP_VCALL3(pv_mmu_ops.set_pte_atomic, ptep, + pte.pte, pte.pte >> 32); +} + +static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + /* 5 arg words */ + pv_mmu_ops.set_pte_present(mm, addr, ptep, pte); +} + +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + PVOP_VCALL3(pv_mmu_ops.pte_clear, mm, addr, ptep); +} +#else /* !CONFIG_X86_PAE */ +static inline void set_pte_atomic(pte_t *ptep, pte_t pte) +{ + set_pte(ptep, pte); +} + +static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + set_pte(ptep, pte); +} + +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + set_pte_at(mm, addr, ptep, __pte(0)); +} +#endif /* CONFIG_X86_PAE */ + #if PAGETABLE_LEVELS >= 3 static inline pmd_t __pmd(pmdval_t val) { @@ -1010,31 +1070,6 @@ static inline pmdval_t pmd_val(pmd_t pmd) #ifdef CONFIG_X86_PAE -static inline void set_pte(pte_t *ptep, pte_t pteval) -{ - PVOP_VCALL3(pv_mmu_ops.set_pte, ptep, pteval.pte_low, pteval.pte_high); -} - -static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pteval) -{ - /* 5 arg words */ - pv_mmu_ops.set_pte_at(mm, addr, ptep, pteval); -} - -static inline void set_pte_atomic(pte_t *ptep, pte_t pteval) -{ - PVOP_VCALL3(pv_mmu_ops.set_pte_atomic, ptep, - pteval.pte_low, pteval.pte_high); -} - -static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte) -{ - /* 5 arg words */ - pv_mmu_ops.set_pte_present(mm, addr, ptep, pte); -} - static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) { PVOP_VCALL3(pv_mmu_ops.set_pmd, pmdp, @@ -1047,11 +1082,6 @@ static inline void set_pud(pud_t *pudp, pud_t pudval) pudval.pgd.pgd, pudval.pgd.pgd >> 32); } -static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - PVOP_VCALL3(pv_mmu_ops.pte_clear, mm, addr, ptep); -} - static inline void pmd_clear(pmd_t *pmdp) { PVOP_VCALL1(pv_mmu_ops.pmd_clear, pmdp); @@ -1059,17 +1089,6 @@ static inline void pmd_clear(pmd_t *pmdp) #else /* !CONFIG_X86_PAE */ -static inline void set_pte(pte_t *ptep, pte_t pteval) -{ - PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, pteval.pte_low); -} - -static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pteval) -{ - PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pteval.pte_low); -} - static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) { PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd); @@ -1080,21 +1099,6 @@ static inline void pmd_clear(pmd_t *pmdp) set_pmd(pmdp, __pmd(0)); } -static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - set_pte_at(mm, addr, ptep, __pte(0)); -} - -static inline void set_pte_atomic(pte_t *ptep, pte_t pte) -{ - set_pte(ptep, pte); -} - -static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte) -{ - set_pte(ptep, pte); -} #endif /* CONFIG_X86_PAE */ /* Lazy mode for batching updates / context switch */ -- cgit v1.2.2 From 60b3f626dee9f0b1b656918e40e211822c18200d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86/paravirt: make set_pmd operation common Remove duplicate set_pmd()s. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index ba1b9433414..d9957ece49b 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -998,6 +998,16 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); } +static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) +{ + pmdval_t val = native_pmd_val(pmd); + + if (sizeof(pmdval_t) > sizeof(long)) + PVOP_VCALL3(pv_mmu_ops.set_pmd, pmdp, val, (u64)val >> 32); + else + PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, val); +} + #ifdef CONFIG_X86_PAE /* Special-case pte-setting operations for PAE, which can't update a 64-bit pte atomically */ @@ -1019,6 +1029,11 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, { PVOP_VCALL3(pv_mmu_ops.pte_clear, mm, addr, ptep); } + +static inline void pmd_clear(pmd_t *pmdp) +{ + PVOP_VCALL1(pv_mmu_ops.pmd_clear, pmdp); +} #else /* !CONFIG_X86_PAE */ static inline void set_pte_atomic(pte_t *ptep, pte_t pte) { @@ -1036,6 +1051,11 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, { set_pte_at(mm, addr, ptep, __pte(0)); } + +static inline void pmd_clear(pmd_t *pmdp) +{ + set_pmd(pmdp, __pmd(0)); +} #endif /* CONFIG_X86_PAE */ #if PAGETABLE_LEVELS >= 3 @@ -1070,35 +1090,12 @@ static inline pmdval_t pmd_val(pmd_t pmd) #ifdef CONFIG_X86_PAE -static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) -{ - PVOP_VCALL3(pv_mmu_ops.set_pmd, pmdp, - pmdval.pmd, pmdval.pmd >> 32); -} - static inline void set_pud(pud_t *pudp, pud_t pudval) { PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, pudval.pgd.pgd, pudval.pgd.pgd >> 32); } -static inline void pmd_clear(pmd_t *pmdp) -{ - PVOP_VCALL1(pv_mmu_ops.pmd_clear, pmdp); -} - -#else /* !CONFIG_X86_PAE */ - -static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) -{ - PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd); -} - -static inline void pmd_clear(pmd_t *pmdp) -{ - set_pmd(pmdp, __pmd(0)); -} - #endif /* CONFIG_X86_PAE */ /* Lazy mode for batching updates / context switch */ -- cgit v1.2.2 From 28c6075c72a312986f6d7802005251bdb91ca80c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86/paravirt: make set_pud operation common Remove duplicate set_pud()s. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index d9957ece49b..c56b17a5eba 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1086,17 +1086,19 @@ static inline pmdval_t pmd_val(pmd_t pmd) return ret; } -#endif /* PAGETABLE_LEVELS >= 3 */ - -#ifdef CONFIG_X86_PAE -static inline void set_pud(pud_t *pudp, pud_t pudval) +static inline void set_pud(pud_t *pudp, pud_t pud) { - PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, - pudval.pgd.pgd, pudval.pgd.pgd >> 32); -} + pudval_t val = native_pud_val(pud); -#endif /* CONFIG_X86_PAE */ + if (sizeof(pudval_t) > sizeof(long)) + PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, + val, (u64)val >> 32); + else + PVOP_VCALL2(pv_mmu_ops.set_pud, pudp, + val); +} +#endif /* PAGETABLE_LEVELS >= 3 */ /* Lazy mode for batching updates / context switch */ enum paravirt_lazy_mode { -- cgit v1.2.2 From e34cda04d4ec0114185459eb101a2245563bbeba Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 30 Jan 2008 13:33:15 +0100 Subject: x86: 64-bit, remove redundant cpu_has_ definitions PSE, PGE, XMM, XMM2, and FXSR are defined as required features, and will be optimized to a constant at compile time. Remove their redundant definitions. Signed-off-by: Kyle McMartin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 93c143fb8a5..29727bf0e17 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -194,21 +194,6 @@ #undef cpu_has_centaur_mcr #define cpu_has_centaur_mcr 0 -#undef cpu_has_pse -#define cpu_has_pse 1 - -#undef cpu_has_pge -#define cpu_has_pge 1 - -#undef cpu_has_xmm -#define cpu_has_xmm 1 - -#undef cpu_has_xmm2 -#define cpu_has_xmm2 1 - -#undef cpu_has_fxsr -#define cpu_has_fxsr 1 - #endif /* CONFIG_X86_64 */ #endif /* _ASM_X86_CPUFEATURE_H */ -- cgit v1.2.2 From 770181d99098bc141031fe0a4b1d6221258c1182 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 30 Jan 2008 13:33:16 +0100 Subject: x86_32: remove the useless NR_syscalls macro This is against current x86.git. The size of the system call table for 32-bit x86 kernels is obtained by compile-time calculation of the sys_call_table array, not from the value, which the NR_syscalls macro expands to. This trivial patch removes the fossil macro. Manually tested by grepping the x86 files for the "NR_syscalls" string. No relevant use cases found. Build-tested using allyesconfig, allnoconfig and a couple of randconfig instances. All builds successfully finished. Runtime test performed using a stripped-down Debian-ish config. The system booted successfully. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/unistd_32.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/unistd_32.h b/include/asm-x86/unistd_32.h index 9b15545eb9b..8d8f9b5adbb 100644 --- a/include/asm-x86/unistd_32.h +++ b/include/asm-x86/unistd_32.h @@ -333,8 +333,6 @@ #ifdef __KERNEL__ -#define NR_syscalls 325 - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT -- cgit v1.2.2 From 064954761254ef17fae2b84fb5a034d48a769143 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Wed, 30 Jan 2008 13:33:16 +0100 Subject: x86: kdump failure kdump needs ELF_CORE_COPY_REGS in crash_save_cpu(). This lack of the macro causes the following BUG. SysRq : Trigger a crashdump ------------[ cut here ]------------ kernel BUG at include/linux/elfcore.h:105! invalid opcode: 0000 [1] PREEMPT SMP Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/elf.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index dab4744f958..d9c94e70728 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -106,6 +106,31 @@ extern unsigned int vdso_enabled; _r->ax = 0; \ } while (0) +/* + * regs is struct pt_regs, pr_reg is elf_gregset_t (which is + * now struct_user_regs, they are different) + */ + +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = regs->bx; \ + pr_reg[1] = regs->cx; \ + pr_reg[2] = regs->dx; \ + pr_reg[3] = regs->si; \ + pr_reg[4] = regs->di; \ + pr_reg[5] = regs->bp; \ + pr_reg[6] = regs->ax; \ + pr_reg[7] = regs->ds & 0xffff; \ + pr_reg[8] = regs->es & 0xffff; \ + pr_reg[9] = regs->fs & 0xffff; \ + savesegment(gs, pr_reg[10]); \ + pr_reg[11] = regs->orig_ax; \ + pr_reg[12] = regs->ip; \ + pr_reg[13] = regs->cs & 0xffff; \ + pr_reg[14] = regs->flags; \ + pr_reg[15] = regs->sp; \ + pr_reg[16] = regs->ss & 0xffff; \ +} while (0); + #define ELF_PLATFORM (utsname()->machine) #define set_personality_64bit() do { } while (0) @@ -165,6 +190,43 @@ static inline void elf_common_init(struct thread_struct *t, } while (0) #define COMPAT_ELF_PLATFORM ("i686") +/* + * regs is struct pt_regs, pr_reg is elf_gregset_t (which is + * now struct_user_regs, they are different). Assumes current is the process + * getting dumped. + */ + +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + unsigned v; \ + (pr_reg)[0] = (regs)->r15; \ + (pr_reg)[1] = (regs)->r14; \ + (pr_reg)[2] = (regs)->r13; \ + (pr_reg)[3] = (regs)->r12; \ + (pr_reg)[4] = (regs)->bp; \ + (pr_reg)[5] = (regs)->bx; \ + (pr_reg)[6] = (regs)->r11; \ + (pr_reg)[7] = (regs)->r10; \ + (pr_reg)[8] = (regs)->r9; \ + (pr_reg)[9] = (regs)->r8; \ + (pr_reg)[10] = (regs)->ax; \ + (pr_reg)[11] = (regs)->cx; \ + (pr_reg)[12] = (regs)->dx; \ + (pr_reg)[13] = (regs)->si; \ + (pr_reg)[14] = (regs)->di; \ + (pr_reg)[15] = (regs)->orig_ax; \ + (pr_reg)[16] = (regs)->ip; \ + (pr_reg)[17] = (regs)->cs; \ + (pr_reg)[18] = (regs)->flags; \ + (pr_reg)[19] = (regs)->sp; \ + (pr_reg)[20] = (regs)->ss; \ + (pr_reg)[21] = current->thread.fs; \ + (pr_reg)[22] = current->thread.gs; \ + asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \ + asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \ + asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \ + asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v; \ +} while (0); + /* I'm not sure if we can use '-' here */ #define ELF_PLATFORM ("x86_64") extern void set_personality_64bit(void); -- cgit v1.2.2 From 90d43d728d22a5e20c63c8db1cfb497210768f19 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:33:16 +0100 Subject: x86: unify pt_regs accessors ptrace.h Unify the definiton of: v8086_mode user_mode user_mode_vm stack_pointer instruction_pointer frame_pointer in ptrace.h to make it clear where the differences are between 32 and 64 bit. Changes macros to static inlines as well. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 84 +++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 30 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index ee4b595e1cc..0ad9a2b7f8c 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -76,30 +76,6 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); -/* - * user_mode_vm(regs) determines whether a register set came from user mode. - * This is true if V8086 mode was enabled OR if the register set was from - * protected mode with RPL-3 CS value. This tricky test checks that with - * one comparison. Many places in the kernel can bypass this full check - * if they have already ruled out V8086 mode, so user_mode(regs) can be used. - */ -static inline int user_mode(struct pt_regs *regs) -{ - return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; -} -static inline int user_mode_vm(struct pt_regs *regs) -{ - return ((regs->cs & SEGMENT_RPL_MASK) | - (regs->flags & VM_MASK)) >= USER_RPL; -} -static inline int v8086_mode(struct pt_regs *regs) -{ - return (regs->flags & VM_MASK); -} - -#define instruction_pointer(regs) ((regs)->ip) -#define frame_pointer(regs) ((regs)->bp) -#define stack_pointer(regs) ((unsigned long)(regs)) #define regs_return_value(regs) ((regs)->ax) extern unsigned long profile_pc(struct pt_regs *regs); @@ -167,12 +143,6 @@ struct pt_regs { /* top of stack page */ }; -#define user_mode(regs) (!!((regs)->cs & 3)) -#define user_mode_vm(regs) user_mode(regs) -#define v8086_mode(regs) 0 /* No V86 mode support in long mode */ -#define instruction_pointer(regs) ((regs)->ip) -#define frame_pointer(regs) ((regs)->bp) -#define stack_pointer(regs) ((regs)->sp) #define regs_return_value(regs) ((regs)->ax) extern unsigned long profile_pc(struct pt_regs *regs); @@ -188,6 +158,60 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); #ifdef __KERNEL__ +/* + * user_mode_vm(regs) determines whether a register set came from user mode. + * This is true if V8086 mode was enabled OR if the register set was from + * protected mode with RPL-3 CS value. This tricky test checks that with + * one comparison. Many places in the kernel can bypass this full check + * if they have already ruled out V8086 mode, so user_mode(regs) can be used. + */ +static inline int user_mode(struct pt_regs *regs) +{ +#ifdef CONFIG_X86_32 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; +#else + return !!(regs->cs & 3); +#endif +} + +static inline int user_mode_vm(struct pt_regs *regs) +{ +#ifdef CONFIG_X86_32 + return ((regs->cs & SEGMENT_RPL_MASK) | + (regs->flags & VM_MASK)) >= USER_RPL; +#else + return user_mode(regs); +#endif +} + +static inline int v8086_mode(struct pt_regs *regs) +{ +#ifdef CONFIG_X86_32 + return (regs->flags & VM_MASK); +#else + return 0; /* No V86 mode support in long mode */ +#endif +} + +static inline unsigned long stack_pointer(struct pt_regs *regs) +{ +#ifdef CONFIG_X86_32 + return (unsigned long)regs; +#else + return regs->sp; +#endif +} + +static inline unsigned long instruction_pointer(struct pt_regs *regs) +{ + return regs->ip; +} + +static inline unsigned long frame_pointer(struct pt_regs *regs) +{ + return regs->bp; +} + /* * These are defined as per linux/ptrace.h, which see. */ -- cgit v1.2.2 From dbe3533b7f687402651e893d5b3a7b66f22d6487 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:33:16 +0100 Subject: x86: clean up ptrace.h Leave definition of pt_regs in its own section, move all kernel code to section afterwards, unify prototype definitions, has some conditional prototypes to make it clear what was only defined in 32 and 64 bit. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 0ad9a2b7f8c..79d5b8fcd7b 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -7,17 +7,6 @@ #ifndef __ASSEMBLY__ -#ifdef __KERNEL__ - -/* the DS BTS struct is used for ptrace as well */ -#include - -struct task_struct; -extern void ptrace_bts_take_timestamp(struct task_struct *, enum bts_qualifier); - -#endif /* __KERNEL__ */ - - #ifdef __i386__ /* this struct defines the way the registers are stored on the stack during a system call. */ @@ -69,16 +58,6 @@ struct pt_regs { #include #include -struct task_struct; - -extern unsigned long -convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); - -extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); - -#define regs_return_value(regs) ((regs)->ax) - -extern unsigned long profile_pc(struct pt_regs *regs); #endif /* __KERNEL__ */ #else /* __i386__ */ @@ -143,20 +122,30 @@ struct pt_regs { /* top of stack page */ }; -#define regs_return_value(regs) ((regs)->ax) +#endif /* __KERNEL__ */ +#endif /* !__i386__ */ -extern unsigned long profile_pc(struct pt_regs *regs); -void signal_fault(struct pt_regs *regs, void __user *frame, char *where); +#ifdef __KERNEL__ + +/* the DS BTS struct is used for ptrace as well */ +#include struct task_struct; +extern void ptrace_bts_take_timestamp(struct task_struct *, enum bts_qualifier); + +extern unsigned long profile_pc(struct pt_regs *regs); + extern unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); -#endif /* __KERNEL__ */ -#endif /* !__i386__ */ +#ifdef CONFIG_X86_32 +extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); +#else +void signal_fault(struct pt_regs *regs, void __user *frame, char *where); +#endif -#ifdef __KERNEL__ +#define regs_return_value(regs) ((regs)->ax) /* * user_mode_vm(regs) determines whether a register set came from user mode. -- cgit v1.2.2 From f6e8e28410c017adb273983057023a17a8791ad3 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 30 Jan 2008 13:33:16 +0100 Subject: x86: rename stack_pointer to kernel_trap_sp Choose a less generic name for such a special case. Add a comment explaining the odd use in X86_32. Change the one user of stack_pointer. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/ptrace.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 79d5b8fcd7b..d9e04b46a44 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -182,7 +182,13 @@ static inline int v8086_mode(struct pt_regs *regs) #endif } -static inline unsigned long stack_pointer(struct pt_regs *regs) +/* + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode + * when it traps. So regs will be the current sp. + * + * This is valid only for kernel mode traps. + */ +static inline unsigned long kernel_trap_sp(struct pt_regs *regs) { #ifdef CONFIG_X86_32 return (unsigned long)regs; -- cgit v1.2.2 From 751752789162fde69474edfa15935d0a77c0bc17 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:17 +0100 Subject: x86: replace hard coded reservations in 64-bit early boot code with dynamic table On x86-64 there are several memory allocations before bootmem. To avoid them stomping on each other they used to be all hard coded in bad_area(). Replace this with an array that is filled as needed. This cleans up the code considerably and allows to expand its use. Cc: peterz@infradead.org Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/e820_64.h | 4 ++-- include/asm-x86/proto.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h index ff36f434f00..51e4170f9ca 100644 --- a/include/asm-x86/e820_64.h +++ b/include/asm-x86/e820_64.h @@ -41,8 +41,8 @@ extern void finish_e820_parsing(void); extern struct e820map e820; extern void update_e820(void); -extern unsigned ebda_addr, ebda_size; -extern unsigned long nodemap_addr, nodemap_size; +extern void reserve_early(unsigned long start, unsigned long end); +extern void early_res_to_bootmem(void); #endif/*!__ASSEMBLY__*/ diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 3c6fb89f112..68563c0709a 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -22,8 +22,6 @@ extern void syscall32_cpu_init(void); extern void check_efer(void); -extern unsigned long table_start, table_end; - extern int reboot_force; long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); -- cgit v1.2.2 From 99fc8d424bc5d803fe92cad56c068fe64e73747a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 30 Jan 2008 13:33:18 +0100 Subject: x86, 32-bit: trim memory not covered by wb mtrrs On some machines, buggy BIOSes don't properly setup WB MTRRs to cover all available RAM, meaning the last few megs (or even gigs) of memory will be marked uncached. Since Linux tends to allocate from high memory addresses first, this causes the machine to be unusably slow as soon as the kernel starts really using memory (i.e. right around init time). This patch works around the problem by scanning the MTRRs at boot and figuring out whether the current end_pfn value (setup by early e820 code) goes beyond the highest WB MTRR range, and if so, trimming it to match. A fairly obnoxious KERN_WARNING is printed too, letting the user know that not all of their memory is available due to a likely BIOS bug. Something similar could be done on i386 if needed, but the boot ordering would be slightly different, since the MTRR code on i386 depends on the boot_cpu_data structure being setup. This patch fixes a bug in the last patch that caused the code to run on non-Intel machines (AMD machines apparently don't need it and it's untested on other non-Intel machines, so best keep it off). Further enhancements and fixes from: Yinghai Lu Andi Kleen Signed-off-by: Jesse Barnes Tested-by: Justin Piszcz Cc: Andi Kleen Cc: "Eric W. Biederman" Cc: Yinghai Lu Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mtrr.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mtrr.h b/include/asm-x86/mtrr.h index 262670e4207..319d065800b 100644 --- a/include/asm-x86/mtrr.h +++ b/include/asm-x86/mtrr.h @@ -97,6 +97,7 @@ extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); extern void mtrr_ap_init(void); extern void mtrr_bp_init(void); +extern int mtrr_trim_uncached_memory(unsigned long end_pfn); # else #define mtrr_save_fixed_ranges(arg) do {} while (0) #define mtrr_save_state() do {} while (0) @@ -120,7 +121,10 @@ static __inline__ int mtrr_del_page (int reg, unsigned long base, { return -ENODEV; } - +static inline int mtrr_trim_uncached_memory(unsigned long end_pfn) +{ + return 0; +} static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;} #define mtrr_ap_init() do {} while (0) -- cgit v1.2.2 From 2274c33ebdfbb848e7291849e662d36519b52bf4 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 30 Jan 2008 13:33:18 +0100 Subject: x86: msr for AMD Fam 10h mmio Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/msr-index.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/msr-index.h b/include/asm-x86/msr-index.h index 4045bbe4737..fae118a2527 100644 --- a/include/asm-x86/msr-index.h +++ b/include/asm-x86/msr-index.h @@ -95,6 +95,14 @@ #define MSR_AMD64_IBSDCPHYSAD 0xc0011039 #define MSR_AMD64_IBSCTL 0xc001103a +/* Fam 10h MSRs */ +#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 +#define FAM10H_MMIO_CONF_ENABLE (1<<0) +#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf +#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 +#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff +#define FAM10H_MMIO_CONF_BASE_SHIFT 20 + /* K8 MSRs */ #define MSR_K8_TOP_MEM1 0xc001001a #define MSR_K8_TOP_MEM2 0xc001001d -- cgit v1.2.2 From b03878307a78ba0248f6f8d24279c846f1a26f6e Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:33:19 +0100 Subject: x86: provide a native_init_IRQ function on 64-bit x86_64 lacks a native_init_IRQ() function, so we turn the arch's init_IRQ() function into a native construct Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/hw_irq_64.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/hw_irq_64.h b/include/asm-x86/hw_irq_64.h index a346159b6ac..312a58d6dac 100644 --- a/include/asm-x86/hw_irq_64.h +++ b/include/asm-x86/hw_irq_64.h @@ -141,6 +141,7 @@ extern void print_IO_APIC(void); extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); extern void send_IPI(int dest, int vector); extern void setup_ioapic_dest(void); +extern void native_init_IRQ(void); extern unsigned long io_apic_irqs; -- cgit v1.2.2 From 046627130591993fd04acef9aebccf70fdad3702 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:33:19 +0100 Subject: x86: put generic mm_hooks include into PARAVIRT With PARAVIRT, we actually have arch_{dup,exit}_mmap functions, so we can't include the generic header Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mmu_context_64.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h index 7e2aa23fccb..ad6dc821ef9 100644 --- a/include/asm-x86/mmu_context_64.h +++ b/include/asm-x86/mmu_context_64.h @@ -7,7 +7,9 @@ #include #include #include +#ifndef CONFIG_PARAVIRT #include +#endif /* * possibly do the LDT unload here? -- cgit v1.2.2 From 4c9890c246121d070deb8cf5cf53e80caffc4dde Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:33:19 +0100 Subject: x86: puts read and write cr8 into pv_cpu_ops This patch adds room for read and write_cr8 functions back in pv_cpu_ops struct Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index c56b17a5eba..73547acbbbf 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -101,6 +101,11 @@ struct pv_cpu_ops { unsigned long (*read_cr4)(void); void (*write_cr4)(unsigned long); +#ifdef CONFIG_X86_64 + unsigned long (*read_cr8)(void); + void (*write_cr8)(unsigned long); +#endif + /* Segment descriptor handling */ void (*load_tr_desc)(void); void (*load_gdt)(const struct desc_ptr *); @@ -614,6 +619,16 @@ static inline void write_cr4(unsigned long x) PVOP_VCALL1(pv_cpu_ops.write_cr4, x); } +static inline unsigned long read_cr8(void) +{ + return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr8); +} + +static inline void write_cr8(unsigned long x) +{ + PVOP_VCALL1(pv_cpu_ops.write_cr8, x); +} + static inline void raw_safe_halt(void) { PVOP_VCALL0(pv_irq_ops.safe_halt); -- cgit v1.2.2 From 94ea03cdda520f0c0dc80cbb4674ab9a33749ee2 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:33:19 +0100 Subject: x86: provide read and write cr8 paravirt hooks Since the cr8 manipulation functions ended up staying in the tree, they can't be defined just when PARAVIRT is off: In this patch, those functions are defined for the PARAVIRT case too. [ mingo@elte.hu: fixes ] Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 2 ++ include/asm-x86/system.h | 30 ++++++++++++++++-------------- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 73547acbbbf..a55f95e921e 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -619,6 +619,7 @@ static inline void write_cr4(unsigned long x) PVOP_VCALL1(pv_cpu_ops.write_cr4, x); } +#ifdef CONFIG_X86_64 static inline unsigned long read_cr8(void) { return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr8); @@ -628,6 +629,7 @@ static inline void write_cr8(unsigned long x) { PVOP_VCALL1(pv_cpu_ops.write_cr8, x); } +#endif static inline void raw_safe_halt(void) { diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 39474f2957a..ee32ef9367f 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -231,6 +231,20 @@ static inline void native_write_cr4(unsigned long val) asm volatile("mov %0,%%cr4": :"r" (val), "m" (__force_order)); } +#ifdef CONFIG_X86_64 +static inline unsigned long native_read_cr8(void) +{ + unsigned long cr8; + asm volatile("movq %%cr8,%0" : "=r" (cr8)); + return cr8; +} + +static inline void native_write_cr8(unsigned long val) +{ + asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); +} +#endif + static inline void native_wbinvd(void) { asm volatile("wbinvd": : :"memory"); @@ -248,21 +262,9 @@ static inline void native_wbinvd(void) #define read_cr4_safe() (native_read_cr4_safe()) #define write_cr4(x) (native_write_cr4(x)) #define wbinvd() (native_wbinvd()) - #ifdef CONFIG_X86_64 - -static inline unsigned long read_cr8(void) -{ - unsigned long cr8; - asm volatile("movq %%cr8,%0" : "=r" (cr8)); - return cr8; -} - -static inline void write_cr8(unsigned long val) -{ - asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); -} - +#define read_cr8() (native_read_cr8()) +#define write_cr8(x) (native_write_cr8(x)) #endif /* Clear the 'TS' bit */ -- cgit v1.2.2 From 1fe91514a3dc07ab540bc891589c46aaa47e92f6 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:33:19 +0100 Subject: x86: change function orders in paravirt.h __pmd, pmd_val and set_pud are used before they are defined (as static) We move them a little up in the file, so it doesn't happen. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 84 +++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 42 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index a55f95e921e..62cecb7778e 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1025,6 +1025,48 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, val); } +#if PAGETABLE_LEVELS >= 3 +static inline pmd_t __pmd(pmdval_t val) +{ + pmdval_t ret; + + if (sizeof(pmdval_t) > sizeof(long)) + ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd, + val, (u64)val >> 32); + else + ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd, + val); + + return (pmd_t) { ret }; +} + +static inline pmdval_t pmd_val(pmd_t pmd) +{ + pmdval_t ret; + + if (sizeof(pmdval_t) > sizeof(long)) + ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val, + pmd.pmd, (u64)pmd.pmd >> 32); + else + ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val, + pmd.pmd); + + return ret; +} + +static inline void set_pud(pud_t *pudp, pud_t pud) +{ + pudval_t val = native_pud_val(pud); + + if (sizeof(pudval_t) > sizeof(long)) + PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, + val, (u64)val >> 32); + else + PVOP_VCALL2(pv_mmu_ops.set_pud, pudp, + val); +} +#endif /* PAGETABLE_LEVELS >= 3 */ + #ifdef CONFIG_X86_PAE /* Special-case pte-setting operations for PAE, which can't update a 64-bit pte atomically */ @@ -1075,48 +1117,6 @@ static inline void pmd_clear(pmd_t *pmdp) } #endif /* CONFIG_X86_PAE */ -#if PAGETABLE_LEVELS >= 3 -static inline pmd_t __pmd(pmdval_t val) -{ - pmdval_t ret; - - if (sizeof(pmdval_t) > sizeof(long)) - ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd, - val, (u64)val >> 32); - else - ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd, - val); - - return (pmd_t) { ret }; -} - -static inline pmdval_t pmd_val(pmd_t pmd) -{ - pmdval_t ret; - - if (sizeof(pmdval_t) > sizeof(long)) - ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val, - pmd.pmd, (u64)pmd.pmd >> 32); - else - ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val, - pmd.pmd); - - return ret; -} - -static inline void set_pud(pud_t *pudp, pud_t pud) -{ - pudval_t val = native_pud_val(pud); - - if (sizeof(pudval_t) > sizeof(long)) - PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, - val, (u64)val >> 32); - else - PVOP_VCALL2(pv_mmu_ops.set_pud, pudp, - val); -} -#endif /* PAGETABLE_LEVELS >= 3 */ - /* Lazy mode for batching updates / context switch */ enum paravirt_lazy_mode { PARAVIRT_LAZY_NONE, -- cgit v1.2.2 From 9042219cd8d43b81322b826d463dd6e52acae6cf Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 30 Jan 2008 13:33:20 +0100 Subject: x86: include/asm-x86/paravirt.h: x86_64 mmu operations Add .set_pgd field to pv_mmu_ops. Implement pud_val(), __pud(), set_pgd(), pud_clear(), pgd_clear(). pud_clear() and pgd_clear() are implemented simply using set_pud() and set_pmd(). They don't have a field at pv_mmu_ops. Signed-off-by: Eduardo Habkost Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 62cecb7778e..9f9ff57b3ef 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -259,6 +259,8 @@ struct pv_mmu_ops { #if PAGETABLE_LEVELS == 4 pudval_t (*pud_val)(pud_t); pud_t (*make_pud)(pudval_t pud); + + void (*set_pgd)(pgd_t *pudp, pgd_t pgdval); #endif /* PAGETABLE_LEVELS == 4 */ #endif /* PAGETABLE_LEVELS >= 3 */ @@ -1065,6 +1067,59 @@ static inline void set_pud(pud_t *pudp, pud_t pud) PVOP_VCALL2(pv_mmu_ops.set_pud, pudp, val); } +#if PAGETABLE_LEVELS == 4 +static inline pud_t __pud(pudval_t val) +{ + pudval_t ret; + + if (sizeof(pudval_t) > sizeof(long)) + ret = PVOP_CALL2(pudval_t, pv_mmu_ops.make_pud, + val, (u64)val >> 32); + else + ret = PVOP_CALL1(pudval_t, pv_mmu_ops.make_pud, + val); + + return (pud_t) { ret }; +} + +static inline pudval_t pud_val(pud_t pud) +{ + pudval_t ret; + + if (sizeof(pudval_t) > sizeof(long)) + ret = PVOP_CALL2(pudval_t, pv_mmu_ops.pud_val, + pud.pud, (u64)pud.pud >> 32); + else + ret = PVOP_CALL1(pudval_t, pv_mmu_ops.pud_val, + pud.pud); + + return ret; +} + +static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) +{ + pgdval_t val = native_pgd_val(pgd); + + if (sizeof(pgdval_t) > sizeof(long)) + PVOP_VCALL3(pv_mmu_ops.set_pgd, pgdp, + val, (u64)val >> 32); + else + PVOP_VCALL2(pv_mmu_ops.set_pgd, pgdp, + val); +} + +static inline void pgd_clear(pgd_t *pgdp) +{ + set_pgd(pgdp, __pgd(0)); +} + +static inline void pud_clear(pud_t *pudp) +{ + set_pud(pudp, __pud(0)); +} + +#endif /* PAGETABLE_LEVELS == 4 */ + #endif /* PAGETABLE_LEVELS >= 3 */ #ifdef CONFIG_X86_PAE -- cgit v1.2.2 From 7d851c8d3db0f79b92c8b14361779ede8acd2488 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:20 +0100 Subject: x86: add framework to disable CPUID bits on the command line There are already various options to disable specific cpuid bits on the command line. They all use their own variable. Add a generic mask to make this easier in the future. Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 4 ++++ include/asm-x86/processor.h | 1 + 2 files changed, 5 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 29727bf0e17..b8f53f869e1 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -131,6 +131,10 @@ #define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability)) #define clear_cpu_cap(c, bit) clear_bit(bit, (unsigned long *)((c)->x86_capability)) +#define setup_clear_cpu_cap(bit) do { \ + clear_cpu_cap(&boot_cpu_data, bit); \ + set_bit(bit, cleared_cpu_caps); \ +} while (0) #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) #define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 81ecfed83e4..ab4d0c2a3f8 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -118,6 +118,7 @@ struct cpuinfo_x86 { extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 new_cpu_data; extern struct tss_struct doublefault_tss; +extern __u32 cleared_cpu_caps[NCAPINTS]; #ifdef CONFIG_SMP DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); -- cgit v1.2.2 From 404ee5b14b68d3cba287c2596588b83790c49f7b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:20 +0100 Subject: x86: convert TSC disabling to generic cpuid disable bitmap Fix from: Ian Campbell Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cpufeature.h | 4 ++++ include/asm-x86/tsc.h | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index b8f53f869e1..3fb7dfa7fc9 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -135,6 +135,10 @@ clear_cpu_cap(&boot_cpu_data, bit); \ set_bit(bit, cleared_cpu_caps); \ } while (0) +#define setup_force_cpu_cap(bit) do { \ + set_cpu_cap(&boot_cpu_data, bit); \ + clear_bit(bit, cleared_cpu_caps); \ +} while (0) #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) #define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index 071e0ce5b66..a6e8d35c3f8 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -16,8 +16,6 @@ typedef unsigned long long cycles_t; extern unsigned int cpu_khz; extern unsigned int tsc_khz; -/* flag for disabling the tsc */ -extern int tsc_disable; extern void disable_TSC(void); -- cgit v1.2.2 From 834beda15ecc43c110c0a6ac39ec1aa79f891716 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:21 +0100 Subject: x86: change NR_CPUS arrays in numa_64 fixup Change the following static arrays sized by NR_CPUS to per_cpu data variables: char cpu_to_node_map[NR_CPUS]; fixup: - Split cpu_to_node function into "early" and "late" versions so that x86_cpu_to_node_map_early_ptr is not EXPORT'ed and the cpu_to_node inline function is more streamlined. - This also involves setting up the percpu maps as early as possible. - Fix X86_32 NUMA build errors that previous version of this patch caused. V2->V3: - add early_cpu_to_node function to keep cpu_to_node efficient - move and rename smp_set_apicids() to setup_percpu_maps() - call setup_percpu_maps() as early as possible V1->V2: - Removed extraneous casts - Fix !NUMA builds with '#ifdef CONFIG_NUMA" Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/topology.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 2da1464ecbe..040374f030c 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -30,15 +30,29 @@ #include /* Mappings between logical cpu number and node number */ +#ifdef CONFIG_X86_32 +extern u8 cpu_to_node_map[]; + +#else DECLARE_PER_CPU(u16, x86_cpu_to_node_map); extern u16 x86_cpu_to_node_map_init[]; extern void *x86_cpu_to_node_map_early_ptr; +#endif + extern cpumask_t node_to_cpumask_map[]; #define NUMA_NO_NODE ((u16)(~0)) /* Returns the number of the node containing CPU 'cpu' */ +#ifdef CONFIG_X86_32 +#define early_cpu_to_node(cpu) cpu_to_node(cpu) static inline int cpu_to_node(int cpu) +{ + return cpu_to_node_map[cpu]; +} + +#else /* CONFIG_X86_64 */ +static inline int early_cpu_to_node(int cpu) { u16 *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; @@ -50,6 +64,15 @@ static inline int cpu_to_node(int cpu) return NUMA_NO_NODE; } +static inline int cpu_to_node(int cpu) +{ + if(per_cpu_offset(cpu)) + return per_cpu(x86_cpu_to_node_map, cpu); + else + return NUMA_NO_NODE; +} +#endif /* CONFIG_X86_64 */ + /* * Returns the number of the node containing Node 'node'. This * architecture is flat, so it is a pretty simple function! -- cgit v1.2.2 From c49a4955ea504c82f6b690491639bba5b8c1dc47 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:22 +0100 Subject: x86: add debug of invalid per_cpu map accesses Provide a means to trap usages of per_cpu map variables before they are setup. Define CONFIG_DEBUG_PER_CPU_MAPS to activate. Signed-off-by: Mike Travis Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/topology.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 040374f030c..f1e12329078 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -66,6 +66,13 @@ static inline int early_cpu_to_node(int cpu) static inline int cpu_to_node(int cpu) { +#ifdef CONFIG_DEBUG_PER_CPU_MAPS + if(x86_cpu_to_node_map_early_ptr) { + printk("KERN_NOTICE cpu_to_node(%d): usage too early!\n", + (int)cpu); + BUG(); + } +#endif if(per_cpu_offset(cpu)) return per_cpu(x86_cpu_to_node_map, cpu); else -- cgit v1.2.2 From 5f5cd8fd60c71ce47d2ce4e60e7ccbc306e91c64 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:23 +0100 Subject: x86: add debug of invalid per_cpu map accesses dont crash survivable situations. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/topology.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index f1e12329078..9a8228a177c 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -66,14 +66,15 @@ static inline int early_cpu_to_node(int cpu) static inline int cpu_to_node(int cpu) { -#ifdef CONFIG_DEBUG_PER_CPU_MAPS - if(x86_cpu_to_node_map_early_ptr) { +#ifdef CONFIG_DEBUG_PER_CPU_MAPS + if (x86_cpu_to_node_map_early_ptr) { printk("KERN_NOTICE cpu_to_node(%d): usage too early!\n", (int)cpu); - BUG(); + dump_stack(); + return ((int *)x86_cpu_to_node_map_early_ptr)[cpu]; } #endif - if(per_cpu_offset(cpu)) + if (per_cpu_offset(cpu)) return per_cpu(x86_cpu_to_node_map, cpu); else return NUMA_NO_NODE; -- cgit v1.2.2 From 75f2ce033168ff435e72bf5bb615176d9930e77f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:24 +0100 Subject: x86: get_cycles() fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/tsc.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index a6e8d35c3f8..7d3e27f7d48 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -27,10 +27,8 @@ static inline cycles_t get_cycles(void) if (!cpu_has_tsc) return 0; #endif - -#if defined(CONFIG_X86_GENERIC) || defined(CONFIG_X86_TSC) rdtscll(ret); -#endif + return ret; } -- cgit v1.2.2 From 625d6cffcac1c96faa18d629f1271d63af0e05f2 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Wed, 30 Jan 2008 13:33:25 +0100 Subject: x86: fix early cpu_to_node panic from nr_free_zone_pages call early_cpu_to_node() since per_cpu(cpu_to_node_map) might not be setup yet. I also had to export x86_cpu_to_node_map_early_ptr because of some calls from the network code to numa_node_id(): net/ipv4/netfilter/arp_tables.c: net/ipv4/netfilter/ip_tables.c: net/ipv4/netfilter/ip_tables.c: Signed-off-by: Mike Travis Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/topology.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 9a8228a177c..7b0cce2f370 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -37,6 +37,8 @@ extern u8 cpu_to_node_map[]; DECLARE_PER_CPU(u16, x86_cpu_to_node_map); extern u16 x86_cpu_to_node_map_init[]; extern void *x86_cpu_to_node_map_early_ptr; +/* Returns the number of the current Node. */ +#define numa_node_id() (early_cpu_to_node(raw_smp_processor_id())) #endif extern cpumask_t node_to_cpumask_map[]; -- cgit v1.2.2 From 4323838215184f5a2f081e0d17b8d60731b03164 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:25 +0100 Subject: x86: change size of node ids from u8 to s16 Change the size of node ids for X86_64 from u8 to s16 to accomodate more than 32k nodes and allow for NUMA_NO_NODE (-1) to be sign extended to int. Cc: David Rientjes Cc: Yinghai Lu Cc: Eric Dumazet Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mmzone_64.h | 6 +++--- include/asm-x86/numa_64.h | 2 +- include/asm-x86/topology.h | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/mmzone_64.h b/include/asm-x86/mmzone_64.h index b0c25ae111d..ebaf9663aa8 100644 --- a/include/asm-x86/mmzone_64.h +++ b/include/asm-x86/mmzone_64.h @@ -15,9 +15,9 @@ struct memnode { int shift; unsigned int mapsize; - u8 *map; - u8 embedded_map[64-16]; -} ____cacheline_aligned; /* total size = 64 bytes */ + s16 *map; + s16 embedded_map[64-8]; +} ____cacheline_aligned; /* total size = 128 bytes */ extern struct memnode memnode; #define memnode_shift memnode.shift #define memnodemap memnode.map diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index c797cd523d2..15fe07cde58 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h @@ -20,7 +20,7 @@ extern void numa_set_node(int cpu, int node); extern void srat_reserve_add_area(int nodeid); extern int hotadd_percent; -extern u16 apicid_to_node[MAX_LOCAL_APIC]; +extern s16 apicid_to_node[MAX_LOCAL_APIC]; extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); extern unsigned long numa_free_all_bootmem(void); diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 7b0cce2f370..8af05a93f09 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -31,11 +31,11 @@ /* Mappings between logical cpu number and node number */ #ifdef CONFIG_X86_32 -extern u8 cpu_to_node_map[]; +extern int cpu_to_node_map[]; #else -DECLARE_PER_CPU(u16, x86_cpu_to_node_map); -extern u16 x86_cpu_to_node_map_init[]; +DECLARE_PER_CPU(int, x86_cpu_to_node_map); +extern int x86_cpu_to_node_map_init[]; extern void *x86_cpu_to_node_map_early_ptr; /* Returns the number of the current Node. */ #define numa_node_id() (early_cpu_to_node(raw_smp_processor_id())) @@ -43,7 +43,7 @@ extern void *x86_cpu_to_node_map_early_ptr; extern cpumask_t node_to_cpumask_map[]; -#define NUMA_NO_NODE ((u16)(~0)) +#define NUMA_NO_NODE (-1) /* Returns the number of the node containing CPU 'cpu' */ #ifdef CONFIG_X86_32 @@ -56,7 +56,7 @@ static inline int cpu_to_node(int cpu) #else /* CONFIG_X86_64 */ static inline int early_cpu_to_node(int cpu) { - u16 *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; + int *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; if (cpu_to_node_map) return cpu_to_node_map[cpu]; -- cgit v1.2.2 From 1bdbdaacf774f2979ed4cb0c4a4316c9e578c897 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Wed, 30 Jan 2008 13:33:28 +0100 Subject: x86, rtc: make CONFIG_HPET_EMULATE_RTC usable from modules enabled, then interrupts don't work for the rtc-cmos driver which results in RTC_AIE*, RTC_PIE* and RTC_ALM being unusable. This affects hwclock from util-linux-ng at least on i386 since that uses RTC_PIE_ON. (For x86-64, a polling method is used for unknown reasons.) This patch series now 1. export the functions from arch/x86/kernel/hpet.c that the old char/rtc driver uses to work around that problem, 2. makes it possible to compile the old rtc driver as module, while still having CONFIG_HPET_EMULATE_RTC enabled and 3. makes use of the exported functions in (1) in the new rtc-cmos driver. This patch: This patch makes the RTC emulation functions in arch/x86/kernel/hpet.c usable for kernel modules. It - exports the functions (EXPORT_SYMBOL_GPL()), - adds an interface to register the interrupt callback function instead of using only a fixed callback function and - replaces the rtc_get_rtc_time() function which depends on CONFIG_RTC with a call to get_rtc_time() which is defined in include/asm-generic/rtc.h. The only dependency to CONFIG_RTC is the call to rtc_interrupt() which is removed by the next patch. After this, there's no (code) dependency of this functions to CONFIG_RTC=y any more. Signed-off-by: Bernhard Walle Cc: Alessandro Zummo Cc: David Brownell Cc: Andi Kleen Cc: john stultz Cc: Robert Picco Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/hpet.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h index 624f600f716..6a9b4ac59bf 100644 --- a/include/asm-x86/hpet.h +++ b/include/asm-x86/hpet.h @@ -69,6 +69,7 @@ extern void force_hpet_resume(void); #include +typedef irqreturn_t (*rtc_irq_handler)(int interrupt, void *cookie); extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask); extern int hpet_set_rtc_irq_bit(unsigned long bit_mask); extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, @@ -77,6 +78,8 @@ extern int hpet_set_periodic_freq(unsigned long freq); extern int hpet_rtc_dropped_irq(void); extern int hpet_rtc_timer_init(void); extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); +extern int hpet_register_irq_handler(rtc_irq_handler handler); +extern void hpet_unregister_irq_handler(rtc_irq_handler handler); #endif /* CONFIG_HPET_EMULATE_RTC */ -- cgit v1.2.2 From 093af8d7f0ba3c6be1485973508584ef081e9f93 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 30 Jan 2008 13:33:32 +0100 Subject: x86_32: trim memory by updating e820 when MTRRs are not covering the whole e820 table, we need to trim the RAM and need to update e820. reuse some code on 64-bit as well. here need to add early_get_cap and use it in early_cpu_detect, and move mtrr_bp_init early. The code successfully trimmed the memory map on Justin's system: from: [ 0.000000] BIOS-e820: 0000000100000000 - 000000022c000000 (usable) to: [ 0.000000] modified: 0000000100000000 - 0000000228000000 (usable) [ 0.000000] modified: 0000000228000000 - 000000022c000000 (reserved) According to Justin it makes quite a difference: | When I boot the box without any trimming it acts like a 286 or 386, | takes about 10 minutes to boot (using raptor disks). Signed-off-by: Yinghai Lu Tested-by: Justin Piszcz Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/e820_32.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h index e2faf5f3a0b..f1da7ebd190 100644 --- a/include/asm-x86/e820_32.h +++ b/include/asm-x86/e820_32.h @@ -19,12 +19,15 @@ #ifndef __ASSEMBLY__ 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 find_max_pfn(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 void e820_register_memory(void); extern void limit_regions(unsigned long long size); extern void print_memory_map(char *who); -- cgit v1.2.2 From ade761496dcd0aea1c41da21d5a6ced4897f02e7 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Wed, 30 Jan 2008 13:33:35 +0100 Subject: x86: GEODE: update GPIO API to support setting multiple GPIOs at once The existing Geode GPIO API only allows for updating one GPIO at once. There are instances where users want to update multiple GPIOs at once. With the current API, they are given two choices; either ignore the GPIO API: outl(0xc000, gpio_base + GPIO_OUTPUT_VAL); outl(0xc000, gpio_base + GPIO_OUTPUT_ENABLE); Alternatively, call each GPIO update separately: geode_gpio_set(14, GPIO_OUTPUT_VAL); geode_gpio_set(15, GPIO_OUTPUT_VAL); geode_gpio_set(14, GPIO_OUTPUT_ENABLE); geode_gpio_set(15, GPIO_OUTPUT_ENABLE); Neither are desirable. This patch changes the GPIO API to allow for setting of multiple GPIOs at once; rather than being passed an integer, we pass a bitmask and provide a translation function. The above code would now look like this: geode_gpio_set(geode_gpio(14)|geode_gpio(15), GPIO_OUTPUT_VAL); geode_gpio_set(geode_gpio(14)|geode_gpio(15), GPIO_OUTPUT_ENABLE); Since there are no upstream users of the GPIO API yet (afaik), best to change this now. This also adds a bit of sanity checking; it is no longer possible to use a GPIO above 28. Note the semantics of geode_gpio_isset() have changed: geode_gpio_isset(geode_gpio(3)|geode_gpio(4), ...) will only return true iff both GPIOs are set. Signed-off-by: Andres Salomon Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/geode.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h index 771af336734..811fe14f70b 100644 --- a/include/asm-x86/geode.h +++ b/include/asm-x86/geode.h @@ -121,9 +121,15 @@ extern int geode_get_dev_base(unsigned int dev); #define GPIO_MAP_Z 0xE8 #define GPIO_MAP_W 0xEC -extern void geode_gpio_set(unsigned int, unsigned int); -extern void geode_gpio_clear(unsigned int, unsigned int); -extern int geode_gpio_isset(unsigned int, unsigned int); +static inline u32 geode_gpio(unsigned int nr) +{ + BUG_ON(nr > 28); + return 1 << nr; +} + +extern void geode_gpio_set(u32, unsigned int); +extern void geode_gpio_clear(u32, unsigned int); +extern int geode_gpio_isset(u32, unsigned int); extern void geode_gpio_setup_event(unsigned int, int, int); extern void geode_gpio_set_irq(unsigned int, unsigned int); -- cgit v1.2.2 From a608295935d237bdbe95eefdba1e3fa40676df31 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 30 Jan 2008 13:33:35 +0100 Subject: x86: add generic GPIO support to x86 This patch adds the generic GPIO support to the x86 architecture. We do the same as for MIPS, we let the machine override the gpio callbacks and provide defaults one in mach-generic. Signed-off-by: Florian Fainelli Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/gpio.h | 6 ++++++ include/asm-x86/mach-generic/gpio.h | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 include/asm-x86/gpio.h create mode 100644 include/asm-x86/mach-generic/gpio.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/gpio.h b/include/asm-x86/gpio.h new file mode 100644 index 00000000000..ff87fca0caf --- /dev/null +++ b/include/asm-x86/gpio.h @@ -0,0 +1,6 @@ +#ifndef _ASM_I386_GPIO_H +#define _ASM_I386_GPIO_H + +#include + +#endif /* _ASM_I386_GPIO_H */ diff --git a/include/asm-x86/mach-generic/gpio.h b/include/asm-x86/mach-generic/gpio.h new file mode 100644 index 00000000000..5305dcb96df --- /dev/null +++ b/include/asm-x86/mach-generic/gpio.h @@ -0,0 +1,15 @@ +#ifndef __ASM_MACH_GENERIC_GPIO_H +#define __ASM_MACH_GENERIC_GPIO_H + +int gpio_request(unsigned gpio, const char *label); +void gpio_free(unsigned gpio); +int gpio_direction_input(unsigned gpio); +int gpio_direction_output(unsigned gpio, int value); +int gpio_get_value(unsigned gpio); +void gpio_set_value(unsigned gpio, int value); +int gpio_to_irq(unsigned gpio); +int irq_to_gpio(unsigned irq); + +#include /* cansleep wrappers */ + +#endif /* __ASM_MACH_GENERIC_GPIO_H */ -- cgit v1.2.2 From 5e3a77e9a9b7bfc1f69f51fe6d34aa649887980c Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 30 Jan 2008 13:33:36 +0100 Subject: x86: add support for the RDC R-321x SoC This patch adds support for the RDC R-321x system-on-chip, also known as R-861x-(G). It uses the generic GPIO API and has support for the on-chip hardware watchdog. Build-fix from: Randy Dunlap Signed-off-by: Florian Fainelli Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/mach-rdc321x/gpio.h | 56 +++++++++++++++++++++++++++++ include/asm-x86/mach-rdc321x/rdc321x_defs.h | 6 ++++ include/asm-x86/timex.h | 2 ++ 3 files changed, 64 insertions(+) create mode 100644 include/asm-x86/mach-rdc321x/gpio.h create mode 100644 include/asm-x86/mach-rdc321x/rdc321x_defs.h (limited to 'include/asm-x86') diff --git a/include/asm-x86/mach-rdc321x/gpio.h b/include/asm-x86/mach-rdc321x/gpio.h new file mode 100644 index 00000000000..db31b929b99 --- /dev/null +++ b/include/asm-x86/mach-rdc321x/gpio.h @@ -0,0 +1,56 @@ +#ifndef _RDC321X_GPIO_H +#define _RDC321X_GPIO_H + +extern int rdc_gpio_get_value(unsigned gpio); +extern void rdc_gpio_set_value(unsigned gpio, int value); +extern int rdc_gpio_direction_input(unsigned gpio); +extern int rdc_gpio_direction_output(unsigned gpio, int value); + + +/* Wrappers for the arch-neutral GPIO API */ + +static inline int gpio_request(unsigned gpio, const char *label) +{ + /* Not yet implemented */ + return 0; +} + +static inline void gpio_free(unsigned gpio) +{ + /* Not yet implemented */ +} + +static inline int gpio_direction_input(unsigned gpio) +{ + return rdc_gpio_direction_input(gpio); +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ + return rdc_gpio_direction_output(gpio, value); +} + +static inline int gpio_get_value(unsigned gpio) +{ + return rdc_gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + rdc_gpio_set_value(gpio, value); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return gpio; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return irq; +} + +/* For cansleep */ +#include + +#endif /* _RDC321X_GPIO_H_ */ diff --git a/include/asm-x86/mach-rdc321x/rdc321x_defs.h b/include/asm-x86/mach-rdc321x/rdc321x_defs.h new file mode 100644 index 00000000000..838ba8f64fd --- /dev/null +++ b/include/asm-x86/mach-rdc321x/rdc321x_defs.h @@ -0,0 +1,6 @@ +#define PFX "rdc321x: " + +/* General purpose configuration and data registers */ +#define RDC3210_CFGREG_ADDR 0x0CF8 +#define RDC3210_CFGREG_DATA 0x0CFC +#define RDC_MAX_GPIO 0x3A diff --git a/include/asm-x86/timex.h b/include/asm-x86/timex.h index 39a21ab030f..27cfd6c599b 100644 --- a/include/asm-x86/timex.h +++ b/include/asm-x86/timex.h @@ -7,6 +7,8 @@ #ifdef CONFIG_X86_ELAN # define PIT_TICK_RATE 1189200 /* AMD Elan has different frequency! */ +#elif defined(CONFIG_X86_RDC321X) +# define PIT_TICK_RATE 1041667 /* Underlying HZ for R8610 */ #else # define PIT_TICK_RATE 1193182 /* Underlying HZ */ #endif -- cgit v1.2.2 From 6c435456dc91ace468b4e9d72ad0e13dafa22a45 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:39 +0100 Subject: x86: add mm parameter to paravirt_alloc_pd Add mm to paravirt_alloc_pd, partly to make it consistent with paravirt_alloc_pt, and because later changes will make use of it. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/paravirt.h | 6 +++--- include/asm-x86/pgalloc_32.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 9f9ff57b3ef..d6236eb4646 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -221,7 +221,7 @@ struct pv_mmu_ops { /* Hooks for allocating/releasing pagetable pages */ void (*alloc_pt)(struct mm_struct *mm, u32 pfn); - void (*alloc_pd)(u32 pfn); + void (*alloc_pd)(struct mm_struct *mm, u32 pfn); void (*alloc_pd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count); void (*release_pt)(u32 pfn); void (*release_pd)(u32 pfn); @@ -903,9 +903,9 @@ static inline void paravirt_release_pt(unsigned pfn) PVOP_VCALL1(pv_mmu_ops.release_pt, pfn); } -static inline void paravirt_alloc_pd(unsigned pfn) +static inline void paravirt_alloc_pd(struct mm_struct *mm, unsigned pfn) { - PVOP_VCALL1(pv_mmu_ops.alloc_pd, pfn); + PVOP_VCALL2(pv_mmu_ops.alloc_pd, mm, pfn); } static inline void paravirt_alloc_pd_clone(unsigned pfn, unsigned clonepfn, diff --git a/include/asm-x86/pgalloc_32.h b/include/asm-x86/pgalloc_32.h index f2fc33ceb9f..fbc6357f5eb 100644 --- a/include/asm-x86/pgalloc_32.h +++ b/include/asm-x86/pgalloc_32.h @@ -8,8 +8,7 @@ #include #else #define paravirt_alloc_pt(mm, pfn) do { } while (0) -#define paravirt_alloc_pd(pfn) do { } while (0) -#define paravirt_alloc_pd(pfn) do { } while (0) +#define paravirt_alloc_pd(mm, pfn) do { } while (0) #define paravirt_alloc_pd_clone(pfn, clonepfn, start, count) do { } while (0) #define paravirt_release_pt(pfn) do { } while (0) #define paravirt_release_pd(pfn) do { } while (0) -- cgit v1.2.2 From a5a19c63f4e55e32dc0bc3d936d7f94793d8b380 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:33:39 +0100 Subject: x86: demacro asm-x86/pgalloc_32.h Convert macros into inline functions, for better type-checking. This patch required a little bit of fiddling with headers in order to make __(pte|pmd)_free_tlb inline rather than macros. asm-generic/tlb.h includes asm/pgalloc.h, though it doesn't directly use any pgalloc definitions. I removed this include to avoid an include cycle, but it may cause secondary compile failures by things depending on the indirect inclusion; arch/x86/mm/hugetlbpage.c was one such place; there may be others. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc_32.h | 61 +++++++++++++++++++++++++--------------- include/asm-x86/pgtable-3level.h | 2 -- 2 files changed, 39 insertions(+), 24 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgalloc_32.h b/include/asm-x86/pgalloc_32.h index fbc6357f5eb..3482c342789 100644 --- a/include/asm-x86/pgalloc_32.h +++ b/include/asm-x86/pgalloc_32.h @@ -3,6 +3,8 @@ #include #include /* for struct page */ +#include +#include #ifdef CONFIG_PARAVIRT #include @@ -14,19 +16,20 @@ #define paravirt_release_pd(pfn) do { } while (0) #endif -#define pmd_populate_kernel(mm, pmd, pte) \ -do { \ - paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \ - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \ -} while (0) +static inline void pmd_populate_kernel(struct mm_struct *mm, + pmd_t *pmd, pte_t *pte) +{ + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); +} -#define pmd_populate(mm, pmd, pte) \ -do { \ - paravirt_alloc_pt(mm, page_to_pfn(pte)); \ - set_pmd(pmd, __pmd(_PAGE_TABLE + \ - ((unsigned long long)page_to_pfn(pte) << \ - (unsigned long long) PAGE_SHIFT))); \ -} while (0) +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) +{ + unsigned long pfn = page_to_pfn(pte); + + paravirt_alloc_pt(mm, pfn); + set_pmd(pmd, __pmd(((pteval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE)); +} /* * Allocate and free page tables. @@ -48,20 +51,34 @@ static inline void pte_free(struct page *pte) } -#define __pte_free_tlb(tlb,pte) \ -do { \ - paravirt_release_pt(page_to_pfn(pte)); \ - tlb_remove_page((tlb),(pte)); \ -} while (0) +static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) +{ + paravirt_release_pt(page_to_pfn(pte)); + tlb_remove_page(tlb, pte); +} #ifdef CONFIG_X86_PAE /* * In the PAE case we free the pmds as part of the pgd. */ -#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) -#define pmd_free(x) do { } while (0) -#define __pmd_free_tlb(tlb,x) do { } while (0) -#define pud_populate(mm, pmd, pte) BUG() -#endif +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + BUG(); + return (pmd_t *)2; +} + +static inline void pmd_free(pmd_t *pmd) +{ +} + +static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) +{ +} + +static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +{ + BUG(); +} +#endif /* CONFIG_X86_PAE */ #endif /* _I386_PGALLOC_H */ diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 5af7a44ed90..62bb06575d5 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -157,6 +157,4 @@ static inline unsigned long pte_pfn(pte_t pte) #define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high }) #define __swp_entry_to_pte(x) ((pte_t){ { .pte_high = (x).val } }) -#define __pmd_free_tlb(tlb, x) do { } while (0) - #endif /* _I386_PGTABLE_3LEVEL_H */ -- cgit v1.2.2 From 6371b495991debfd1417b17c2bc4f7d7bae05739 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:40 +0100 Subject: x86: change ioremap() to default to uncached Prepare ioremap() to default to uncached. This will be the safest - but first we have to fix CPA. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/io_32.h | 15 ++++++++++++--- include/asm-x86/io_64.h | 23 +++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index 2a04bd17eac..db397884637 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h @@ -111,18 +111,27 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign * make bus memory CPU accessible via the readb/readw/readl/writeb/ * writew/writel functions and the other mmio helpers. The returned * address is not guaranteed to be usable directly as a virtual - * address. + * address. * * If the area you are trying to map is a PCI BAR you should have a * look at pci_iomap(). */ +extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size); -static inline void __iomem * ioremap(unsigned long offset, unsigned long size) +static inline void __iomem * +ioremap_cache(unsigned long offset, unsigned long size) { return __ioremap(offset, size, 0); } -extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size); +/* + * The default ioremap() behavior is non-cached: + */ +static inline void __iomem * ioremap(unsigned long offset, unsigned long size) +{ + return ioremap_nocache(offset, size); +} + extern void iounmap(volatile void __iomem *addr); /* diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h index fef0ce2ced8..7dee3c6e9c3 100644 --- a/include/asm-x86/io_64.h +++ b/include/asm-x86/io_64.h @@ -152,11 +152,6 @@ static inline void * phys_to_virt(unsigned long address) extern void __iomem *__ioremap(unsigned long offset, unsigned long size, unsigned long flags); -static inline void __iomem * ioremap (unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, 0); -} - extern void *early_ioremap(unsigned long addr, unsigned long size); extern void early_iounmap(void *addr, unsigned long size); @@ -165,8 +160,24 @@ extern void early_iounmap(void *addr, unsigned long size); * it's useful if some control registers are in such an area and write combining * or read caching is not desirable: */ -extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); +extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size); + +static inline void __iomem * +ioremap_cache(unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, 0); +} + +/* + * The default ioremap() behavior is non-cached: + */ +static inline void __iomem * ioremap(unsigned long offset, unsigned long size) +{ + return ioremap_cache(offset, size); +} + extern void iounmap(volatile void __iomem *addr); + extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); /* -- cgit v1.2.2 From 4c3c4b4513a361cc6ac5ee8677695260c4f0f25f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:42 +0100 Subject: x86: clean up pte_exec - Rename it to pte_exec() from pte_exec_kernel(). There is nothing kernel specific in there. - Move it into the common file because _PAGE_NX is 0 on !PAE and then pte_exec() will be always evaluate to true. Signed-off-by: Andi Kleen Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable-2level.h | 8 -------- include/asm-x86/pgtable-3level.h | 8 -------- include/asm-x86/pgtable.h | 1 + 3 files changed, 1 insertion(+), 16 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h index ce486bdbbbb..701404fab30 100644 --- a/include/asm-x86/pgtable-2level.h +++ b/include/asm-x86/pgtable-2level.h @@ -55,14 +55,6 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp) #define pte_none(x) (!(x).pte_low) #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) -/* - * All present pages are kernel-executable: - */ -static inline int pte_exec_kernel(pte_t pte) -{ - return 1; -} - /* * Bits 0, 6 and 7 are taken, split up the 29 bits of offset * into this range: diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 62bb06575d5..62a1ffbc878 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -19,14 +19,6 @@ #define pud_bad(pud) 0 #define pud_present(pud) 1 -/* - * All present pages with !NX bit are kernel-executable: - */ -static inline int pte_exec_kernel(pte_t pte) -{ - return !(pte_val(pte) & _PAGE_NX); -} - /* Rules for using set_pte: the pte being assigned *must* be * either not present or in a state where the hardware will * not attempt to update the pte. In places where this is diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 75a656e6b3f..2f3d90807ef 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -139,6 +139,7 @@ static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } +static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); } static inline int pmd_large(pmd_t pte) { return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == -- cgit v1.2.2 From a5a5dc31794c3271c066835ad2c90c58a3805569 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:42 +0100 Subject: x86: add pte accessors for the global bit Needed for some test code. Signed-off-by: Andi Kleen Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 2f3d90807ef..18a5f9e3283 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -139,6 +139,7 @@ static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } +static inline int pte_global(pte_t pte) { return pte_val(pte) & _PAGE_GLOBAL; } static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); } static inline int pmd_large(pmd_t pte) { @@ -155,6 +156,8 @@ static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_A static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } +static inline pte_t pte_mkglobal(pte_t pte) { return __pte(pte_val(pte) | _PAGE_GLOBAL); } +static inline pte_t pte_clrglobal(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_GLOBAL); } extern pteval_t __supported_pte_mask; -- cgit v1.2.2 From f0646e43acb18f0e00b00085dc88bc3f403e7930 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:43 +0100 Subject: x86: return the page table level in lookup_address() based on this patch from Andi Kleen: | Subject: CPA: Return the page table level in lookup_address() | From: Andi Kleen | | Needed for the next change. | | And change all the callers. and ported it to x86.git. Signed-off-by: Andi Kleen Acked-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_32.h | 2 +- include/asm-x86/pgtable_64.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index eb8cccfa6a4..9381bd37b9b 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -182,7 +182,7 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) * NOTE: the return type is pte_t but if the pmd is PSE then we return it * as a pte too. */ -extern pte_t *lookup_address(unsigned long address); +extern pte_t *lookup_address(unsigned long address, int *level); /* * Make a given kernel text page executable/non-executable. diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 29fdeb8111b..139da50cd51 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -240,7 +240,7 @@ extern struct list_head pgd_list; extern int kern_addr_valid(unsigned long addr); -pte_t *lookup_address(unsigned long addr); +pte_t *lookup_address(unsigned long addr, int *level); #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) -- cgit v1.2.2 From 0947b2f31ca1ea1211d3cde2dbd8fcec579ef395 Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:33:44 +0100 Subject: i386 boot: replace boot_ioremap with enhanced bt_ioremap - enhance bt_ioremap This patch makes it possible for bt_ioremap() to be used before paging_init(), via providing an early implementation of set_fixmap() that can be used before paging_init(). This way boot_ioremap() can be replaced by bt_ioremap(). Signed-off-by: Huang Ying Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/io_32.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index db397884637..f7b733d9ace 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h @@ -139,6 +139,9 @@ extern void iounmap(volatile void __iomem *addr); * mappings, before the real ioremap() is functional. * A boot-time mapping is currently limited to at most 16 pages. */ +extern void bt_ioremap_init(void); +extern void bt_ioremap_clear(void); +extern void bt_ioremap_reset(void); extern void *bt_ioremap(unsigned long offset, unsigned long size); extern void bt_iounmap(void *addr, unsigned long size); extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); -- cgit v1.2.2 From 4716e79c9946044a53a65418cfba04836f6a5c36 Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:33:44 +0100 Subject: x86: replace boot_ioremap() with enhanced bt_ioremap() - remove boot_ioremap() This patch replaces boot_ioremap invokation with bt_ioremap and removes the boot_ioremap implementation. Signed-off-by: Huang Ying Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/efi.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h index 6d54502755a..10fcf20bdc7 100644 --- a/include/asm-x86/efi.h +++ b/include/asm-x86/efi.h @@ -32,13 +32,9 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); efi_call_virt(f, a1, a2, a3, a4, a5) #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ efi_call_virt(f, a1, a2, a3, a4, a5, a6) -/* - * We require an early boot_ioremap mapping mechanism initially - */ -extern void *boot_ioremap(unsigned long, unsigned long); -#define efi_early_ioremap(addr, size) boot_ioremap(addr, size) -#define efi_early_iounmap(vaddr, size) +#define efi_early_ioremap(addr, size) bt_ioremap(addr, size) +#define efi_early_iounmap(vaddr, size) bt_iounmap(vaddr, size) #define efi_ioremap(addr, size) ioremap(addr, size) -- cgit v1.2.2 From beacfaac3f23b30814aafee37a055257c7062ef3 Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:33:44 +0100 Subject: x86 32-bit boot: rename bt_ioremap() to early_ioremap() This patch renames bt_ioremap to early_ioremap, which is used in x86_64. This makes it easier to merge i386 and x86_64 usage. [ mingo@elte.hu: fix ] Signed-off-by: Huang Ying Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/dmi.h | 7 ++----- include/asm-x86/efi.h | 8 -------- include/asm-x86/io_32.h | 16 ++++++++-------- 3 files changed, 10 insertions(+), 21 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/dmi.h b/include/asm-x86/dmi.h index 5008c365e6e..1241e6ad193 100644 --- a/include/asm-x86/dmi.h +++ b/include/asm-x86/dmi.h @@ -5,9 +5,6 @@ #ifdef CONFIG_X86_32 -/* Use early IO mappings for DMI because it's initialized early */ -#define dmi_ioremap bt_ioremap -#define dmi_iounmap bt_iounmap #define dmi_alloc alloc_bootmem #else /* CONFIG_X86_32 */ @@ -28,9 +25,9 @@ static inline void *dmi_alloc(unsigned len) return dmi_alloc_data + idx; } +#endif + #define dmi_ioremap early_ioremap #define dmi_iounmap early_iounmap #endif - -#endif diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h index 10fcf20bdc7..8380131ca54 100644 --- a/include/asm-x86/efi.h +++ b/include/asm-x86/efi.h @@ -33,9 +33,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ efi_call_virt(f, a1, a2, a3, a4, a5, a6) -#define efi_early_ioremap(addr, size) bt_ioremap(addr, size) -#define efi_early_iounmap(vaddr, size) bt_iounmap(vaddr, size) - #define efi_ioremap(addr, size) ioremap(addr, size) #define end_pfn_map max_low_pfn @@ -91,13 +88,8 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) -#define efi_early_ioremap(addr, size) early_ioremap(addr, size) -#define efi_early_iounmap(vaddr, size) early_iounmap(vaddr, size) - extern void *efi_ioremap(unsigned long offset, unsigned long size); -extern int efi_time; - #endif /* CONFIG_X86_32 */ extern void efi_reserve_bootmem(void); diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index f7b733d9ace..059a1fee4de 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h @@ -135,20 +135,20 @@ static inline void __iomem * ioremap(unsigned long offset, unsigned long size) extern void iounmap(volatile void __iomem *addr); /* - * bt_ioremap() and bt_iounmap() are for temporary early boot-time + * early_ioremap() and early_iounmap() are for temporary early boot-time * mappings, before the real ioremap() is functional. * A boot-time mapping is currently limited to at most 16 pages. */ -extern void bt_ioremap_init(void); -extern void bt_ioremap_clear(void); -extern void bt_ioremap_reset(void); -extern void *bt_ioremap(unsigned long offset, unsigned long size); -extern void bt_iounmap(void *addr, unsigned long size); +extern void early_ioremap_init(void); +extern void early_ioremap_clear(void); +extern void early_ioremap_reset(void); +extern void *early_ioremap(unsigned long offset, unsigned long size); +extern void early_iounmap(void *addr, unsigned long size); extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); /* Use early IO mappings for DMI because it's initialized early */ -#define dmi_ioremap bt_ioremap -#define dmi_iounmap bt_iounmap +#define dmi_ioremap early_ioremap +#define dmi_iounmap early_iounmap #define dmi_alloc alloc_bootmem /* -- cgit v1.2.2 From 1b42f51630c7eebce6fb780b480731eb81afd325 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:45 +0100 Subject: x86: enhance early_ioremap() - allow nesting of up to 4 levels Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/fixmap_32.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h index 249e753ac80..0e990218a09 100644 --- a/include/asm-x86/fixmap_32.h +++ b/include/asm-x86/fixmap_32.h @@ -65,7 +65,7 @@ enum fixed_addresses { #endif #ifdef CONFIG_X86_VISWS_APIC FIX_CO_CPU, /* Cobalt timer */ - FIX_CO_APIC, /* Cobalt APIC Redirection Table */ + FIX_CO_APIC, /* Cobalt APIC Redirection Table */ FIX_LI_PCIA, /* Lithium PCI Bridge A */ FIX_LI_PCIB, /* Lithium PCI Bridge B */ #endif @@ -74,7 +74,7 @@ enum fixed_addresses { #endif #ifdef CONFIG_X86_CYCLONE_TIMER FIX_CYCLONE_TIMER, /*cyclone timer register*/ -#endif +#endif #ifdef CONFIG_HIGHMEM FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, @@ -91,9 +91,10 @@ enum fixed_addresses { #endif __end_of_permanent_fixed_addresses, /* temporary boot-time mappings, used before ioremap() is functional */ -#define NR_FIX_BTMAPS 16 +#define NR_FIX_BTMAPS 16 +#define FIX_BTMAPS_NESTING 4 FIX_BTMAP_END = __end_of_permanent_fixed_addresses, - FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1, + FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, FIX_WP_TEST, __end_of_fixed_addresses }; -- cgit v1.2.2 From a8efa1cd51d6f6407df5f42d8f1a7e9fc7178d1a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:45 +0100 Subject: x86: increase the number of boot-mappings increase max early_ioremap() remapping size from 64K to 256K. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/fixmap_32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h index 0e990218a09..46bedb7b542 100644 --- a/include/asm-x86/fixmap_32.h +++ b/include/asm-x86/fixmap_32.h @@ -91,7 +91,7 @@ enum fixed_addresses { #endif __end_of_permanent_fixed_addresses, /* temporary boot-time mappings, used before ioremap() is functional */ -#define NR_FIX_BTMAPS 16 +#define NR_FIX_BTMAPS 64 #define FIX_BTMAPS_NESTING 4 FIX_BTMAP_END = __end_of_permanent_fixed_addresses, FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, -- cgit v1.2.2 From d701fda8601fe267fbd3648f108f0e751305101b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:48 +0100 Subject: x86: fix early_ioremap()/btmap fix a long-standing weakness of the early-ioremap allocator: it uses a single pgd entry for the boot mappings, and was not properly protecting itself against crossing a 2MB (4MB) boundary. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/fixmap_32.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h index 46bedb7b542..fde140fd6d9 100644 --- a/include/asm-x86/fixmap_32.h +++ b/include/asm-x86/fixmap_32.h @@ -90,10 +90,18 @@ enum fixed_addresses { FIX_PARAVIRT_BOOTMAP, #endif __end_of_permanent_fixed_addresses, - /* temporary boot-time mappings, used before ioremap() is functional */ + /* + * 256 temporary boot-time mappings, used by early_ioremap(), + * before ioremap() is functional. + * + * We round it up to the next 512 pages boundary so that we + * can have a single pgd entry and a single pte table: + */ #define NR_FIX_BTMAPS 64 #define FIX_BTMAPS_NESTING 4 - FIX_BTMAP_END = __end_of_permanent_fixed_addresses, + FIX_BTMAP_END = + __end_of_permanent_fixed_addresses + 512 - + (__end_of_permanent_fixed_addresses & 511), FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, FIX_WP_TEST, __end_of_fixed_addresses -- cgit v1.2.2 From c93c82bbea20bef627dbe8e34a4bc8e526217104 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:50 +0100 Subject: x86: shrink __PAGE_KERNEL/__PAGE_KERNEL_EXEC on non PAE kernels No need to make it 64bit there. Signed-off-by: Andi Kleen Acked-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 18a5f9e3283..0c3ecca0f79 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -69,7 +69,7 @@ #define _PAGE_KERNEL (_PAGE_KERNEL_EXEC | _PAGE_NX) #ifndef __ASSEMBLY__ -extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; +extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #endif /* __ASSEMBLY__ */ #else #define __PAGE_KERNEL_EXEC \ -- cgit v1.2.2 From c6ca18eb759c43ae20d953ef90c3de4557f9342a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:51 +0100 Subject: x86: add pte_pgprot to 32-bit 64bit already had it. Needed for later patches. Signed-off-by: Andi Kleen Acked-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 2 ++ include/asm-x86/pgtable_64.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 0c3ecca0f79..b4ee5939afe 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -187,6 +187,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) return __pte(val); } +#define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX)) + #ifdef CONFIG_PARAVIRT #include #else /* !CONFIG_PARAVIRT */ diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 139da50cd51..df1fcbd12e4 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -120,8 +120,6 @@ static inline void native_pgd_clear(pgd_t * pgd) #define pte_same(a, b) ((a).pte == (b).pte) -#define pte_pgprot(a) (__pgprot((a).pte & ~PHYSICAL_PAGE_MASK)) - #endif /* !__ASSEMBLY__ */ #define PMD_SIZE (_AC(1,UL) << PMD_SHIFT) -- cgit v1.2.2 From aaa0e89023656c078c67cbd0460fc2ccbf3323c6 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:51 +0100 Subject: x86: don't drop NX bit in pte modifier functions on 32-bit The pte_* modifier functions that cleared bits dropped the NX bit on 32bit PAE because they only worked in int, but NX is in bit 63. Fix that by adding appropiate casts so that the arithmetic happens as long long on PAE kernels. I decided to just use 64bit arithmetic instead of open coding like pte_modify() because gcc should generate good enough code for that now. Signed-off-by: Andi Kleen Acked-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index b4ee5939afe..2f93723a3e1 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -147,17 +147,17 @@ static inline int pmd_large(pmd_t pte) { (_PAGE_PSE|_PAGE_PRESENT); } -static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_DIRTY); } -static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } -static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); } -static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_NX); } +static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); } +static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); } +static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW); } +static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX); } static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } -static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_PSE); } +static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_PSE); } static inline pte_t pte_mkglobal(pte_t pte) { return __pte(pte_val(pte) | _PAGE_GLOBAL); } -static inline pte_t pte_clrglobal(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_GLOBAL); } +static inline pte_t pte_clrglobal(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); } extern pteval_t __supported_pte_mask; -- cgit v1.2.2 From 1e8e23bc469a11fc190a6bace857075d83dc2555 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:53 +0100 Subject: x86: introduce canon_pgprot() Introduce canon_pgprot() Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 2f93723a3e1..2726ddc457f 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -189,6 +189,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX)) +#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) + #ifdef CONFIG_PARAVIRT #include #else /* !CONFIG_PARAVIRT */ -- cgit v1.2.2 From 934d15854d04e8ca2495d8f5698164df990d5d66 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 30 Jan 2008 13:33:53 +0100 Subject: x86: remove set_kernel_exec() The SMP trampoline always runs in real mode, so making it executable in the page tables doesn't make much sense because it executes before page tables are set up. That was the only user of set_kernel_exec(). Remove set_kernel_exec(). Signed-off-by: Andi Kleen Acked-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_32.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 9381bd37b9b..72eb06c2bac 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -184,18 +184,6 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) */ extern pte_t *lookup_address(unsigned long address, int *level); -/* - * Make a given kernel text page executable/non-executable. - * Returns the previous executability setting of that page (which - * is used to restore the previous state). Used by the SMP bootup code. - * NOTE: this is an __init function for security reasons. - */ -#ifdef CONFIG_X86_PAE - extern int set_kernel_exec(unsigned long vaddr, int enable); -#else - static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;} -#endif - #if defined(CONFIG_HIGHPTE) #define pte_offset_map(dir, address) \ ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) -- cgit v1.2.2 From a2172e2586f6662af996e47f417bb718c37cf8d2 Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:33:55 +0100 Subject: x86: fix some bugs about EFI runtime code mapping This patch fixes some bugs of making EFI runtime code executable. - Use change_page_attr in i386 too. Because the runtime code may be mapped not through ioremap. - If there is no _PAGE_NX in __supported_pte_mask, the change_page_attr is not called. - Make efi_ioremap map pages as PAGE_KERNEL_EXEC_NOCACHE, because EFI runtime code may be mapped through efi_ioremap. Signed-off-by: Huang Ying Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/efi.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h index 8380131ca54..9e08ae84795 100644 --- a/include/asm-x86/efi.h +++ b/include/asm-x86/efi.h @@ -95,6 +95,5 @@ extern void *efi_ioremap(unsigned long offset, unsigned long size); extern void efi_reserve_bootmem(void); extern void efi_call_phys_prelog(void); extern void efi_call_phys_epilog(void); -extern void runtime_code_page_mkexec(void); #endif -- cgit v1.2.2 From 12d6f21eacc21d84a809829543f2fe45c7e37319 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:33:58 +0100 Subject: x86: do not PSE on CONFIG_DEBUG_PAGEALLOC=y get more testing of the c_p_a() code done by not turning off PSE on DEBUG_PAGEALLOC. this simplifies the early pagetable setup code, and tests the largepage-splitup code quite heavily. In the end, all the largepages will be split up pretty quickly, so there's no difference to how DEBUG_PAGEALLOC worked before. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cacheflush.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index 9411a2d3f19..fccb563e230 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -29,11 +29,6 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot); int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot); void clflush_cache_range(void *addr, int size); -#ifdef CONFIG_DEBUG_PAGEALLOC -/* internal debugging function */ -void kernel_map_pages(struct page *page, int numpages, int enable); -#endif - #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void); #endif -- cgit v1.2.2 From b65e6390fb99ca93877ffc1c84e93c857f32dafc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:01 +0100 Subject: x86: introduce native_set_pte_atomic() on 64-bit too Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index df1fcbd12e4..223b0032bab 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -76,6 +76,11 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) *ptep = pte; } +static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) +{ + native_set_pte(ptep, pte); +} + static inline pte_t native_ptep_get_and_clear(pte_t *xp) { #ifdef CONFIG_SMP -- cgit v1.2.2 From e4b71dcf54fa90fc30fb901bbce7e38a46467af7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:04 +0100 Subject: x86: clean up arch/x86/mm/pageattr.c do some leftover cleanups in the now unified arch/x86/mm/pageattr.c file. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 223b0032bab..faa6a96c2a5 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -25,6 +25,8 @@ extern void clear_kernel_mapping(unsigned long addr, unsigned long size); #endif /* !__ASSEMBLY__ */ +#define SHARED_KERNEL_PMD 1 + /* * PGDIR_SHIFT determines what a top-level page table entry can map */ -- cgit v1.2.2 From 0a663088cd6ff9e89f285ae7689e6eee46cfb54c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:34:04 +0100 Subject: x86: clean up lookup_address() declarations Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 8 ++++++++ include/asm-x86/pgtable_32.h | 8 -------- include/asm-x86/pgtable_64.h | 2 -- 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 2726ddc457f..4409dabe31c 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -234,6 +234,14 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #ifndef __ASSEMBLY__ +/* + * Helper function that returns the kernel pagetable entry controlling + * the virtual address 'address'. NULL means no pagetable entry present. + * NOTE: the return type is pte_t but if the pmd is PSE then we return it + * as a pte too. + */ +extern pte_t *lookup_address(unsigned long address, int *level); + /* local pte updates need not use xchg for locking */ static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) { diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 72eb06c2bac..ca7b150ca8b 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -176,14 +176,6 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) #define pmd_page_vaddr(pmd) \ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) -/* - * Helper function that returns the kernel pagetable entry controlling - * the virtual address 'address'. NULL means no pagetable entry present. - * NOTE: the return type is pte_t but if the pmd is PSE then we return it - * as a pte too. - */ -extern pte_t *lookup_address(unsigned long address, int *level); - #if defined(CONFIG_HIGHPTE) #define pte_offset_map(dir, address) \ ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index faa6a96c2a5..ce1dbab75e3 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -245,8 +245,6 @@ extern struct list_head pgd_list; extern int kern_addr_valid(unsigned long addr); -pte_t *lookup_address(unsigned long addr, int *level); - #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) -- cgit v1.2.2 From 30551bb3ce9257a2352b3cb4e45010d415cc0ad5 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:34:04 +0100 Subject: x86: add PG_LEVEL enum this way PG_LEVEL_1GB will be an easy change. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 4409dabe31c..7aa34c8eb22 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -234,6 +234,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #ifndef __ASSEMBLY__ +enum { + PG_LEVEL_NONE, + PG_LEVEL_4K, + PG_LEVEL_2M, +}; + /* * Helper function that returns the kernel pagetable entry controlling * the virtual address 'address'. NULL means no pagetable entry present. -- cgit v1.2.2 From d2e626f45cc450c00f5f98a89b8b4c4ac3c9bf5f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:04 +0100 Subject: x86: add PAGE_KERNEL_EXEC_NOCACHE add PAGE_KERNEL_EXEC_NOCACHE. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 7aa34c8eb22..ee40a88882f 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -79,6 +79,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) #define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) +#define __PAGE_KERNEL_EXEC_NOCACHE (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT) #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) #define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) @@ -96,6 +97,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC) #define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX) #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) +#define PAGE_KERNEL_EXEC_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE) #define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE) #define PAGE_KERNEL_LARGE_EXEC MAKE_GLOBAL(__PAGE_KERNEL_LARGE_EXEC) #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL) -- cgit v1.2.2 From f87519e8f4f1de9b39a40e56479a7ad2443169dd Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:34:05 +0100 Subject: x86: introduce max_pfn_mapped 64bit uses end_pfn_map and 32bit uses max_low_pfn. There are several files which have #ifdef'ed defines which map either to end_pfn_map or max_low_pfn. Replace this by a universal define and clean up all the other instances. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/efi.h | 2 -- include/asm-x86/page.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h index 9e08ae84795..9c68a1f098d 100644 --- a/include/asm-x86/efi.h +++ b/include/asm-x86/efi.h @@ -35,8 +35,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); #define efi_ioremap(addr, size) ioremap(addr, size) -#define end_pfn_map max_low_pfn - #else /* !CONFIG_X86_32 */ #define MAX_EFI_IO_PAGES 100 diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index eba88d94009..e2c79d8dcdc 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -33,8 +33,10 @@ #ifdef CONFIG_X86_64 #include +#define max_pfn_mapped end_pfn_map #else #include +#define max_pfn_mapped max_low_pfn #endif /* CONFIG_X86_64 */ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) -- cgit v1.2.2 From 75cbade8ea3127a84e3da7c2c15808e54f0df7e8 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 30 Jan 2008 13:34:06 +0100 Subject: x86: a new API for drivers/etc to control cache and other page attributes Right now, if drivers or other code want to change, say, a cache attribute of a page, the only API they have is change_page_attr(). c-p-a is a really bad API for this, because it forces the caller to know *ALL* the attributes he wants for the page, not just the 1 thing he wants to change. So code that wants to set a page uncachable, needs to be aware of the NX status as well etc etc etc. This patch introduces a set of new APIs for this, set_pages_ and set_memory_, that offer a logical change to the user, and leave all attributes not implied by the requested logical change alone. Signed-off-by: Arjan van de Ven Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/cacheflush.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index fccb563e230..7b928d55c19 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -27,6 +27,21 @@ void global_flush_tlb(void); int change_page_attr(struct page *page, int numpages, pgprot_t prot); int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot); + +int set_pages_uc(struct page *page, int numpages); +int set_pages_wb(struct page *page, int numpages); +int set_pages_x(struct page *page, int numpages); +int set_pages_nx(struct page *page, int numpages); +int set_pages_ro(struct page *page, int numpages); +int set_pages_rw(struct page *page, int numpages); + +int set_memory_uc(unsigned long addr, int numpages); +int set_memory_wb(unsigned long addr, int numpages); +int set_memory_x(unsigned long addr, int numpages); +int set_memory_nx(unsigned long addr, int numpages); +int set_memory_ro(unsigned long addr, int numpages); +int set_memory_rw(unsigned long addr, int numpages); + void clflush_cache_range(void *addr, int size); #ifdef CONFIG_DEBUG_RODATA -- cgit v1.2.2 From 6d238cc4dc8a36a3915c26202fe49f58a0683fb9 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 30 Jan 2008 13:34:06 +0100 Subject: x86: convert CPA users to the new set_page_ API This patch converts various users of change_page_attr() to the new, more intent driven set_page_*/set_memory_* API set. Signed-off-by: Arjan van de Ven Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/agp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/agp.h b/include/asm-x86/agp.h index 62df2a9e713..f6df7256183 100644 --- a/include/asm-x86/agp.h +++ b/include/asm-x86/agp.h @@ -16,8 +16,8 @@ * Caller's responsibility to call global_flush_tlb() for performance * reasons */ -#define map_page_into_agp(page) change_page_attr(page, 1, PAGE_KERNEL_NOCACHE) -#define unmap_page_from_agp(page) change_page_attr(page, 1, PAGE_KERNEL) +#define map_page_into_agp(page) set_pages_uc(page, 1) +#define unmap_page_from_agp(page) set_pages_wb(page, 1) #define flush_agp_mappings() global_flush_tlb() /* -- cgit v1.2.2 From e1271f686a0e376aa6ee97984c16f91a787e4480 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 30 Jan 2008 13:34:06 +0100 Subject: x86: deprecate change_page_attr() for drivers With the introduction of the new API, no driver or non-archcore code needs to use c-p-a anymore, so this patch also deprecates the EXPORT_SYMBOL of CPA (it's a horrible API after all). Signed-off-by: Arjan van de Ven Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/cacheflush.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index 7b928d55c19..e79159bc098 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -25,7 +25,8 @@ memcpy(dst, src, len) void global_flush_tlb(void); -int change_page_attr(struct page *page, int numpages, pgprot_t prot); +int __deprecated_for_modules change_page_attr(struct page *page, int numpages, + pgprot_t prot); int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot); int set_pages_uc(struct page *page, int numpages); -- cgit v1.2.2 From 5f5192b9feeff6a96c97c143c3ca558fdbe2dc8e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:34:06 +0100 Subject: x86: move page_is_ram() function Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/page.h | 3 +++ include/asm-x86/page_32.h | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index e2c79d8dcdc..c8b30efeed8 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -47,6 +47,9 @@ #ifndef __ASSEMBLY__ + +extern int page_is_ram(unsigned long pagenr); + struct page; static void inline clear_user_page(void *page, unsigned long vaddr, diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index 11c4b39cada..a6fd10f230d 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -73,7 +73,6 @@ extern int nx_enabled; */ extern unsigned int __VMALLOC_RESERVE; extern int sysctl_legacy_va_layout; -extern int page_is_ram(unsigned long pagenr); #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) #define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) -- cgit v1.2.2 From 950f9d95bed1a366434d3597ea75f5b9d772d74f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:34:06 +0100 Subject: x86: fix the missing BIOS area check in page_is_ram page_is_ram has a FIXME since ages, which reminds to sanity check the BIOS area between 640k and 1M, which is sometimes falsely reported as RAM in the e820 tables. Implement the sanity check. Move the BIOS range defines from pageattr.c into e820.h to avoid duplicate defines. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/e820.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index f96f1853bc4..7004251fc66 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -25,6 +25,9 @@ struct e820map { #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 +#define BIOS_BEGIN 0x000a0000 +#define BIOS_END 0x00100000 + #ifdef __KERNEL__ #ifdef CONFIG_X86_32 # include "e820_32.h" -- cgit v1.2.2 From 5f8681529cb243b3a492e55f2da9d632ad0d5e32 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:34:06 +0100 Subject: x86: fix ioremap API Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/io_32.h | 13 +++---------- include/asm-x86/io_64.h | 13 +++---------- 2 files changed, 6 insertions(+), 20 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index 059a1fee4de..586d7aa54ce 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h @@ -100,8 +100,6 @@ static inline void * phys_to_virt(unsigned long address) */ #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) -extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); - /** * ioremap - map bus memory into CPU space * @offset: bus address of the memory @@ -116,18 +114,13 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign * If the area you are trying to map is a PCI BAR you should have a * look at pci_iomap(). */ -extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size); - -static inline void __iomem * -ioremap_cache(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, 0); -} +extern void __iomem *ioremap_nocache(unsigned long offset, unsigned long size); +extern void __iomem *ioremap_cache(unsigned long offset, unsigned long size); /* * The default ioremap() behavior is non-cached: */ -static inline void __iomem * ioremap(unsigned long offset, unsigned long size) +static inline void __iomem *ioremap(unsigned long offset, unsigned long size) { return ioremap_nocache(offset, size); } diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h index 7dee3c6e9c3..ee7a5c95596 100644 --- a/include/asm-x86/io_64.h +++ b/include/asm-x86/io_64.h @@ -150,8 +150,6 @@ static inline void * phys_to_virt(unsigned long address) #include -extern void __iomem *__ioremap(unsigned long offset, unsigned long size, unsigned long flags); - extern void *early_ioremap(unsigned long addr, unsigned long size); extern void early_iounmap(void *addr, unsigned long size); @@ -160,18 +158,13 @@ extern void early_iounmap(void *addr, unsigned long size); * it's useful if some control registers are in such an area and write combining * or read caching is not desirable: */ -extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size); - -static inline void __iomem * -ioremap_cache(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, 0); -} +extern void __iomem *ioremap_nocache(unsigned long offset, unsigned long size); +extern void __iomem *ioremap_cache(unsigned long offset, unsigned long size); /* * The default ioremap() behavior is non-cached: */ -static inline void __iomem * ioremap(unsigned long offset, unsigned long size) +static inline void __iomem *ioremap(unsigned long offset, unsigned long size) { return ioremap_cache(offset, size); } -- cgit v1.2.2 From f62d0f008e889915c93631c04d4c7d871f05bea7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:07 +0100 Subject: x86: cpa: set_memory_notpresent() Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cacheflush.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index e79159bc098..a95afaf1240 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -42,6 +42,7 @@ int set_memory_x(unsigned long addr, int numpages); int set_memory_nx(unsigned long addr, int numpages); int set_memory_ro(unsigned long addr, int numpages); int set_memory_rw(unsigned long addr, int numpages); +int set_memory_np(unsigned long addr, int numpages); void clflush_cache_range(void *addr, int size); -- cgit v1.2.2 From d1028a154c65d7fadd1b2d0276c077014d401ec7 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 30 Jan 2008 13:34:07 +0100 Subject: x86: make various pageattr.c functions static change_page_attr_add is only used in pageattr.c now, so we can make this function static. change_page_attr() isn't used anywere at all anymore; this function is a really bad API anyway so just remove the bloat entirely. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cacheflush.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index a95afaf1240..d15ff359d3e 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -27,7 +27,6 @@ void global_flush_tlb(void); int __deprecated_for_modules change_page_attr(struct page *page, int numpages, pgprot_t prot); -int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot); int set_pages_uc(struct page *page, int numpages); int set_pages_wb(struct page *page, int numpages); -- cgit v1.2.2 From d7c8f21a8cad0228c7c5ce2bb6dbd95d1ee49d13 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:34:07 +0100 Subject: x86: cpa: move flush to cpa The set_memory_* and set_pages_* family of API's currently requires the callers to do a global tlb flush after the function call; forgetting this is a very nasty deathtrap. This patch moves the global tlb flush into each of the callers Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/agp.h | 6 +----- include/asm-x86/cacheflush.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/agp.h b/include/asm-x86/agp.h index f6df7256183..0c309b9a521 100644 --- a/include/asm-x86/agp.h +++ b/include/asm-x86/agp.h @@ -12,13 +12,9 @@ * page. This avoids data corruption on some CPUs. */ -/* - * Caller's responsibility to call global_flush_tlb() for performance - * reasons - */ #define map_page_into_agp(page) set_pages_uc(page, 1) #define unmap_page_from_agp(page) set_pages_wb(page, 1) -#define flush_agp_mappings() global_flush_tlb() +#define flush_agp_mappings() do { } while (0) /* * Could use CLFLUSH here if the cpu supports it. But then it would diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index d15ff359d3e..157da0206cc 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -24,7 +24,6 @@ #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ memcpy(dst, src, len) -void global_flush_tlb(void); int __deprecated_for_modules change_page_attr(struct page *page, int numpages, pgprot_t prot); -- cgit v1.2.2 From 5398f9854f60d670e8ef1ea08c0e0310f253eeb1 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:07 +0100 Subject: x86: remove flush_agp_mappings() Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/agp.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/agp.h b/include/asm-x86/agp.h index 0c309b9a521..e4004a9f6a9 100644 --- a/include/asm-x86/agp.h +++ b/include/asm-x86/agp.h @@ -14,7 +14,6 @@ #define map_page_into_agp(page) set_pages_uc(page, 1) #define unmap_page_from_agp(page) set_pages_wb(page, 1) -#define flush_agp_mappings() do { } while (0) /* * Could use CLFLUSH here if the cpu supports it. But then it would -- cgit v1.2.2 From edeed30589f5defe63ce6aaae56f2b7c855e4520 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 30 Jan 2008 13:34:08 +0100 Subject: x86: add testcases for RODATA and NX protections/attributes Latest update; I now have 4 NX tests, but 2 fail so they're #if 0'd. I also cleaned up the NX test code quite a bit, and got rid of the ugly exception table sorting stuff. From: Arjan van de Ven This patch adds testcases for the CONFIG_DEBUG_RODATA configuration option as well as the NX CPU feature/mappings. Both testcases can move to tests/ once that patch gets merged into mainline. (I'm half considering moving the rodata test into mm/init.c but I'll wait with that until init.c is unified) As part of this I had to fix a not-quite-right alignment in the vmlinux.lds.h for the RODATA sections, which lead to 1 page less being marked read only. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/cacheflush.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index 157da0206cc..3e74aff9080 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -47,5 +47,12 @@ void clflush_cache_range(void *addr, int size); #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void); #endif +#ifdef CONFIG_DEBUG_RODATA_TEST +void rodata_test(void); +#else +static inline void rodata_test(void) +{ +} +#endif #endif -- cgit v1.2.2 From 4c61afcdb2cd4be299c1442b33adf312b695e2d7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:09 +0100 Subject: x86: fix clflush_page_range logic only present ptes must be flushed. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/asm-x86/cacheflush.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index 3e74aff9080..8dd8c5e3cc7 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -42,7 +42,7 @@ int set_memory_ro(unsigned long addr, int numpages); int set_memory_rw(unsigned long addr, int numpages); int set_memory_np(unsigned long addr, int numpages); -void clflush_cache_range(void *addr, int size); +void clflush_cache_range(void *addr, unsigned int size); #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void); -- cgit v1.2.2 From 86f03989d99cfa2e1216cdd7aa996852236909cf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:09 +0100 Subject: x86: cpa: fix the self-test Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index ee40a88882f..269e7e29ea8 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -240,6 +240,7 @@ enum { PG_LEVEL_NONE, PG_LEVEL_4K, PG_LEVEL_2M, + PG_LEVEL_1G, }; /* -- cgit v1.2.2 From 9af993a92623e022c176459fa6607a564b9a7eaf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:09 +0100 Subject: x86: make ioremap() UC by default Yes! A mere 120 c_p_a() fixing and rewriting patches later, we are now confident that we can enable UC by default for ioremap(), on x86 too. Every other architectures was doing this already. Doing so makes Linux more robust against MTRR mixups (which might go unnoticed if BIOS writers test other OSs only - where PAT might override bad MTRRs defaults). Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/io_64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h index ee7a5c95596..f64a59cc396 100644 --- a/include/asm-x86/io_64.h +++ b/include/asm-x86/io_64.h @@ -166,7 +166,7 @@ extern void __iomem *ioremap_cache(unsigned long offset, unsigned long size); */ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) { - return ioremap_cache(offset, size); + return ioremap_nocache(offset, size); } extern void iounmap(volatile void __iomem *addr); -- cgit v1.2.2 From 8550eb99821b3f78cddfd19964f30e8bc4e429e0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 30 Jan 2008 13:34:10 +0100 Subject: x86: arch/x86/mm/init_32.c cleanup Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/bugs.h | 3 ++- include/asm-x86/numa_32.h | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/bugs.h b/include/asm-x86/bugs.h index aac8317420a..3fcc30dc073 100644 --- a/include/asm-x86/bugs.h +++ b/include/asm-x86/bugs.h @@ -1,6 +1,7 @@ #ifndef _ASM_X86_BUGS_H #define _ASM_X86_BUGS_H -void check_bugs(void); +extern void check_bugs(void); +extern int ppro_with_ram_bug(void); #endif /* _ASM_X86_BUGS_H */ diff --git a/include/asm-x86/numa_32.h b/include/asm-x86/numa_32.h index 96fcb157db1..03d0f7a9bf0 100644 --- a/include/asm-x86/numa_32.h +++ b/include/asm-x86/numa_32.h @@ -1,3 +1,15 @@ +#ifndef _ASM_X86_32_NUMA_H +#define _ASM_X86_32_NUMA_H 1 -int pxm_to_nid(int pxm); +extern int pxm_to_nid(int pxm); +#ifdef CONFIG_NUMA +extern void __init remap_numa_kva(void); +extern void set_highmem_pages_init(int); +#else +static inline void remap_numa_kva(void) +{ +} +#endif + +#endif /* _ASM_X86_32_NUMA_H */ -- cgit v1.2.2 From 6194ba6ff6ccf8d5c54c857600843c67aa82c407 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:34:11 +0100 Subject: x86: don't special-case pmd allocations as much In x86 PAE mode, stop treating pmds as a special case. Previously they were always allocated and freed with the pgd. The modifies the code to be the same as 64-bit mode, where they are allocated on demand. This is a step on the way to unifying 32/64-bit pagetable allocation as much as possible. There is a complicating wart, however. When you install a new reference to a pmd in the pgd, the processor isn't guaranteed to see it unless you reload cr3. Since reloading cr3 also has the side-effect of flushing the tlb, this is an expense that we want to avoid whereever possible. This patch simply avoids reloading cr3 unless the update is to the current pagetable. Later patches will optimise this further. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Cc: Linus Torvalds Cc: H. Peter Anvin Cc: William Irwin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc_32.h | 22 ++++++++++++++++++---- include/asm-x86/pgtable-3level.h | 39 ++++++++++++++++++++++++++++----------- include/asm-x86/pgtable_32.h | 3 +-- 3 files changed, 47 insertions(+), 17 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgalloc_32.h b/include/asm-x86/pgalloc_32.h index 3482c342789..0caa37a9a25 100644 --- a/include/asm-x86/pgalloc_32.h +++ b/include/asm-x86/pgalloc_32.h @@ -63,21 +63,35 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) */ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - BUG(); - return (pmd_t *)2; + return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); } static inline void pmd_free(pmd_t *pmd) { + BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); + free_page((unsigned long)pmd); } static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { + paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); + tlb_remove_page(tlb, virt_to_page(pmd)); } -static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) { - BUG(); + paravirt_alloc_pd(mm, __pa(pmd) >> PAGE_SHIFT); + + /* Note: almost everything apart from _PAGE_PRESENT is + reserved at the pmd (PDPT) level. */ + set_pud(pudp, __pud(__pa(pmd) | _PAGE_PRESENT)); + + /* + * Pentium-II erratum A13: in PAE mode we explicitly have to flush + * the TLB via cr3 if the top-level pgd is changed... + */ + if (mm == current->active_mm) + write_cr3(read_cr3()); } #endif /* CONFIG_X86_PAE */ diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 62a1ffbc878..ed4c6f0e57e 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -15,9 +15,19 @@ #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pgd_val(e)) -#define pud_none(pud) 0 -#define pud_bad(pud) 0 -#define pud_present(pud) 1 + +static inline int pud_none(pud_t pud) +{ + return pud_val(pud) == 0; +} +static inline int pud_bad(pud_t pud) +{ + return (pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0; +} +static inline int pud_present(pud_t pud) +{ + return pud_val(pud) & _PAGE_PRESENT; +} /* Rules for using set_pte: the pte being assigned *must* be * either not present or in a state where the hardware will @@ -58,7 +68,7 @@ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) } static inline void native_set_pud(pud_t *pudp, pud_t pud) { - *pudp = pud; + set_64bit((unsigned long long *)(pudp),native_pud_val(pud)); } /* @@ -81,13 +91,20 @@ static inline void native_pmd_clear(pmd_t *pmd) *(tmp + 1) = 0; } -/* - * Pentium-II erratum A13: in PAE mode we explicitly have to flush - * the TLB via cr3 if the top-level pgd is changed... - * We do not let the generic code free and clear pgd entries due to - * this erratum. - */ -static inline void pud_clear (pud_t * pud) { } +static inline void pud_clear(pud_t *pudp) +{ + set_pud(pudp, __pud(0)); + + /* + * Pentium-II erratum A13: in PAE mode we explicitly have to flush + * the TLB via cr3 if the top-level pgd is changed... + * + * XXX I don't think we need to worry about this here, since + * when clearing the pud, the calling code needs to flush the + * tlb anyway. But do it now for safety's sake. - jsgf + */ + write_cr3(read_cr3()); +} #define pud_page(pud) \ ((struct page *) __va(pud_val(pud) & PAGE_MASK)) diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index ca7b150ca8b..7b61cb5989b 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -31,8 +31,7 @@ extern spinlock_t pgd_lock; extern struct page *pgd_list; void check_pgt_cache(void); -void pmd_ctor(struct kmem_cache *, void *); -void pgtable_cache_init(void); +static inline void pgtable_cache_init(void) {} void paging_init(void); -- cgit v1.2.2 From f212ec4b7b4d84290f12c9c0416cdea283bf5f40 Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Wed, 30 Jan 2008 13:34:11 +0100 Subject: x86: early boot debugging via FireWire (ohci1394_dma=early) This patch adds a new configuration option, which adds support for a new early_param which gets checked in arch/x86/kernel/setup_{32,64}.c:setup_arch() to decide wether OHCI-1394 FireWire controllers should be initialized and enabled for physical DMA access to allow remote debugging of early problems like issues ACPI or other subsystems which are executed very early. If the config option is not enabled, no code is changed, and if the boot paramenter is not given, no new code is executed, and independent of that, all new code is freed after boot, so the config option can be even enabled in standard, non-debug kernels. With specialized tools, it is then possible to get debugging information from machines which have no serial ports (notebooks) such as the printk buffer contents, or any data which can be referenced from global pointers, if it is stored below the 4GB limit and even memory dumps of of the physical RAM region below the 4GB limit can be taken without any cooperation from the CPU of the host, so the machine can be crashed early, it does not matter. In the extreme, even kernel debuggers can be accessed in this way. I wrote a small kgdb module and an accompanying gdb stub for FireWire which allows to gdb to talk to kgdb using remote remory reads and writes over FireWire. An version of the gdb stub fore FireWire is able to read all global data from a system which is running a a normal kernel without any kernel debugger, without any interruption or support of the system's CPU. That way, e.g. the task struct and so on can be read and even manipulated when the physical DMA access is granted. A HOWTO is included in this patch, in Documentation/debugging-via-ohci1394.txt and I've put a copy online at ftp://ftp.suse.de/private/bk/firewire/docs/debugging-via-ohci1394.txt It also has links to all the tools which are available to make use of it another copy of it is online at: ftp://ftp.suse.de/private/bk/firewire/kernel/ohci1394_dma_early-v2.diff Signed-Off-By: Bernhard Kaindl Tested-By: Thomas Renninger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/fixmap_32.h | 3 +++ include/asm-x86/fixmap_64.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'include/asm-x86') diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h index fde140fd6d9..a7404d50686 100644 --- a/include/asm-x86/fixmap_32.h +++ b/include/asm-x86/fixmap_32.h @@ -104,6 +104,9 @@ enum fixed_addresses { (__end_of_permanent_fixed_addresses & 511), FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, FIX_WP_TEST, +#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT + FIX_OHCI1394_BASE, +#endif __end_of_fixed_addresses }; diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h index 8f44782e5fe..70ddb21e645 100644 --- a/include/asm-x86/fixmap_64.h +++ b/include/asm-x86/fixmap_64.h @@ -44,6 +44,9 @@ enum fixed_addresses { FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, FIX_EFI_IO_MAP_LAST_PAGE, FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE+MAX_EFI_IO_PAGES-1, +#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT + FIX_OHCI1394_BASE, +#endif __end_of_fixed_addresses }; -- cgit v1.2.2 From fa28ba21cec24d3fa1279bcae7e5d5ff6224635a Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:34:11 +0100 Subject: x86: defer cr3 reload when doing pud_clear() PAE mode requires that we reload cr3 in order to guarantee that changes to the pgd will be noticed by the processor. This means that in principle pud_clear needs to reload cr3 every time. However, because reloading cr3 implies a tlb flush, we want to avoid it where possible. pud_clear() is only used in a couple of places: - in free_pmd_range(), when pulling down a range of process address space, and - huge_pmd_unshare() In both cases, the calling code will do a a tlb flush anyway, so there's no need to do it within pud_clear(). In free_pmd_range(), the pud_clear is immediately followed by pmd_free_tlb(); we can hook that to make the mmu_gather do an unconditional full flush to make sure cr3 gets reloaded. In huge_pmd_unshare, it is followed by flush_tlb_range, which always results in a full cr3-reload tlb flush. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Cc: Linus Torvalds Cc: H. Peter Anvin Cc: William Irwin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc_32.h | 7 +++++++ include/asm-x86/pgtable-3level.h | 21 +++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgalloc_32.h b/include/asm-x86/pgalloc_32.h index 0caa37a9a25..10c2b452e64 100644 --- a/include/asm-x86/pgalloc_32.h +++ b/include/asm-x86/pgalloc_32.h @@ -74,6 +74,13 @@ static inline void pmd_free(pmd_t *pmd) static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { + /* This is called just after the pmd has been detached from + the pgd, which requires a full tlb flush to be recognized + by the CPU. Rather than incurring multiple tlb flushes + while the address space is being pulled down, make the tlb + gathering machinery do a full flush when we're done. */ + tlb->fullmm = 1; + paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); tlb_remove_page(tlb, virt_to_page(pmd)); } diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index ed4c6f0e57e..a195c3e757b 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -96,14 +96,23 @@ static inline void pud_clear(pud_t *pudp) set_pud(pudp, __pud(0)); /* - * Pentium-II erratum A13: in PAE mode we explicitly have to flush - * the TLB via cr3 if the top-level pgd is changed... + * In principle we need to do a cr3 reload here to make sure + * the processor recognizes the changed pgd. In practice, all + * the places where pud_clear() gets called are followed by + * full tlb flushes anyway, so we can defer the cost here. * - * XXX I don't think we need to worry about this here, since - * when clearing the pud, the calling code needs to flush the - * tlb anyway. But do it now for safety's sake. - jsgf + * Specifically: + * + * mm/memory.c:free_pmd_range() - immediately after the + * pud_clear() it does a pmd_free_tlb(). We change the + * mmu_gather structure to do a full tlb flush (which has the + * effect of reloading cr3) when the pagetable free is + * complete. + * + * arch/x86/mm/hugetlbpage.c:huge_pmd_unshare() - the call to + * this is followed by a flush_tlb_range, which on x86 does a + * full tlb flush. */ - write_cr3(read_cr3()); } #define pud_page(pud) \ -- cgit v1.2.2 From e3ed910db221768f8fd6192b13373e17d61bcdf0 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 30 Jan 2008 13:34:11 +0100 Subject: x86: use the same pgd_list for PAE and 64-bit Use a standard list threaded through page->lru for maintaining the pgd list on PAE. This is the same as 64-bit, and seems saner than using a non-standard list via page->index. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable.h | 2 ++ include/asm-x86/pgtable_32.h | 2 -- include/asm-x86/pgtable_64.h | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'include/asm-x86') diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 269e7e29ea8..cd2524f0745 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -131,6 +131,8 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC; extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) +extern spinlock_t pgd_lock; +extern struct list_head pgd_list; /* * The following only work if pte_present() is true. diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 7b61cb5989b..21e70fbf1da 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -27,8 +27,6 @@ struct vm_area_struct; extern pgd_t swapper_pg_dir[1024]; extern struct kmem_cache *pmd_cache; -extern spinlock_t pgd_lock; -extern struct page *pgd_list; void check_pgt_cache(void); static inline void pgtable_cache_init(void) {} diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index ce1dbab75e3..6e615a103c2 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -240,9 +240,6 @@ static inline unsigned long pmd_bad(pmd_t pmd) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) -extern spinlock_t pgd_lock; -extern struct list_head pgd_list; - extern int kern_addr_valid(unsigned long addr); #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ -- cgit v1.2.2