Some x86 2.6.22 candidate patches for review
Subsystems (3)
PATCH 2/35 x86_64: revert x86_64-mm-add-genapic_force
In reply to Andi KleenFrom: Andrew Morton <[email protected]>
This is obsoleted by new Ingo genapic patches.
---
arch/x86_64/kernel/genapic.c | 9 +-------- include/asm-x86_64/genapic.h | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-)
arch/x86_64/kernel/genapic.c +1 -8
@@ -33,7 +33,7 @@ extern struct genapic apic_flat;extern struct genapic apic_physflat;struct genapic *genapic = &apic_flat; -struct genapic *genapic_force; +/* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
@@ -46,13 +46,6 @@ void __init clustered_apic_check(void)u8 cluster_cnt[NUM_APIC_CLUSTERS ];int max_apic =0 ; -/* genapic selection can be forced because of certain quirks. -*/ -if (genapic_force) { - genapic = genapic_force; - goto print; - } -#if defined(CONFIG_ACPI )/* * Some x86_64 machines use physical APIC mode regardless of how many
include/asm-x86_64/genapic.h +1 -1
@@ -30,6 +30,6 @@ struct genapic { }; -extern struct genapic *genapic, *genapic_force, apic_flat; +extern struct genapic *genapic;#endif
PATCH 6/35 x86_64: remove clustered APIC mode
In reply to Andi KleenFrom: Ingo Molnar <[email protected]>
Remove now unused clustered APIC mode code.
---
arch/x86_64/kernel/Makefile | 3 arch/x86_64/kernel/genapic_cluster.c | 137 ----------------------------------- 2 files changed, 1 insertion(+), 139 deletions(-)
arch/x86_64/kernel/Makefile +1 -2
@@ -21,8 +21,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o tsc_sync.o obj-y += apic.o nmi.o -obj-y += io_apic.o mpparse.o \ - genapic.o genapic_cluster.o genapic_flat.o +obj-y += io_apic.o mpparse.o genapic.o genapic_flat.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += suspend.o
arch/x86_64/kernel/genapic_cluster.c deleted +0 -137
137 lines not on this page · raw message
PATCH 29/35 i386: Update __copy_to_user_inatomic linuxdoc description
In reply to Andi KleenFrom: "Aneesh Kumar K.V" <[email protected]> Explicity specify that the caller should pin the user memory otherwise the function will sleep
--- include/asm-i386/uaccess.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
include/asm-i386/uaccess.h +13 -1
@@ -397,7 +397,19 @@ unsigned long __must_check __copy_from_uunsigned long __must_check __copy_from_user_ll_nocache_nozero (void *to,const void __user *from,unsigned long n); -/* +/** +* __copy_to_user_inatomic: - Copy a block of data into user space, with less checking. +* @to: Destination address, in user space. +* @from: Source address, in kernel space. +* @n: Number of bytes to copy. +* +* Context: User context only. +* +* Copy data from kernel space to user space. Caller must check +* the specified block with access_ok() before calling this function. +* The caller should also make sure he pins the user space address +* so that the we don't result in page fault and sleep. +* * Here we special-case 1, 2 and 4-byte copy_*_user invocations. On a fault * we return the initial request size (1, 2 or 4), as copy_*_user should do. * If a store crosses a page boundary and gets a fault, the x86 will not write
PATCH 16/35 i386: Add an option for the VIA C7 which sets appropriate L1 cache
In reply to Andi KleenFrom: Simon Arlott <[email protected]>
The VIA C7 is a 686 (with TSC) that supports MMX, SSE and SSE2, it also has a cache line length of 64 according to
http://www.digit-life.com/articles2/cpu/rmma-via-c7.html. This patch sets gcc to -march=686 and select s the correct cache shift.
---
arch/i386/Kconfig.cpu | 13 ++++++++++--- arch/i386/Makefile.cpu | 1 + arch/um/defconfig | 1 + include/asm-i386/module.h | 2 ++ 4 files changed, 14 insertions(+), 3 deletions(-)
arch/i386/Kconfig.cpu +10 -3
@@ -43,6 +43,7 @@ config M386 - "Geode GX/LX" For AMD Geode GX and LX processors. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. - "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above). + - "VIA C7" for VIA C7. If you don't know what to do, choose "386".
@@ -203,6 +204,12 @@ config MVIAC3_2 of SSE and tells gcc to treat the CPU as a 686. Note, this kernel will not boot on older (pre model 9) C3s. +config MVIAC7 + bool "VIA C7" + help + Select this for a VIA C7. Selecting this uses the correct cache + shift and tells gcc to treat the CPU as a 686. + endchoice config X86_GENERIC
@@ -231,7 +238,7 @@ config X86_L1_CACHE_SHIFT default "7" if MPENTIUM4 || X86_GENERIC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX - default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 + default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 config RWSEM_GENERIC_SPINLOCK bool
@@ -297,7 +304,7 @@ config X86_ALIGNMENT_16 config X86_GOOD_APIC bool - depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 + depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 default y config X86_INTEL_USERCOPY
@@ -322,5 +329,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ default y
arch/i386/Makefile.cpu +1 -0
@@ -32,6 +32,7 @@ cflags-$(CONFIG_MWINCHIP2) += $(call cc- cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) +cflags-$(CONFIG_MVIAC7) += -march=i686 cflags-$(CONFIG_MCORE2) += -march=i686 $(call cc-option,-mtune=core2,$(call cc-option,-mtune=generic,-mtune=i686)) # AMD Elan support
arch/um/defconfig +1 -0
@@ -41,6 +41,7 @@ CONFIG_M686=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set # CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y
include/asm-i386/module.h +2 -0
@@ -54,6 +54,8 @@ struct mod_arch_specific#define MODULE_PROC_FAMILY "CYRIXIII "#elif definedCONFIG_MVIAC3_2 #define MODULE_PROC_FAMILY "VIAC3-2 " +#elif definedCONFIG_MVIAC7 +#define MODULE_PROC_FAMILY "VIAC7 "#elif definedCONFIG_MGEODEGX1 #define MODULE_PROC_FAMILY "GEODEGX1 "#elif definedCONFIG_MGEODE_LX
PATCH 27/35 i386: Support Oprofile for AMD Family 10 CPUs
In reply to Andi Kleen--- arch/i386/oprofile/nmi_int.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/i386/oprofile/nmi_int.c +4 -0
@@ -414,6 +414,10 @@ int __init op_nmi_init(struct oprofile_ouser space an consistent name. */ cpu_type ="x86-64/hammer" ;break ; +case 0x10 : + model = &op_athlon_spec; + cpu_type ="x86-64/family10" ; +break ; }break ;
PATCH 25/35 i386: Change sysenter_setup to __cpuinit & improve __INIT, __INITDATA
In reply to Andi KleenFrom: Prarit Bhargava <[email protected]> Change sysenter_setup to __cpuinit.
Change __INIT & __INITDATA to be cpu hotplug aware.
Resolve MODPOST warnings similar to:
WARNING: vmlinux - Section mismatch: reference to .init.text:sysenter_setup from
.text between 'identify_cpu' (at offset 0xc040a380) and 'detect_ht'
and
WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_int80_end from .text between 'sysenter_setup' (at offset 0xc041a269) and 'enable_sep_cpu'
WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_int80_start from .text between 'sysenter_setup' (at offset 0xc041a26e) and 'enable_sep_cpu'
WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_sysenter_end from .text between 'sysenter_setup' (at offset 0xc041a275) and 'enable_sep_cpu'
WARNING: vmlinux - Section mismatch: reference to .init.data:vsyscall_sysenter_start from .text between 'sysenter_setup' (at offset 0xc041a27a) and 'enable_sep_cpu'
--- arch/i386/kernel/sysenter.c | 2 +- include/linux/init.h | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-)
arch/i386/kernel/sysenter.c +1 -1
@@ -72,7 +72,7 @@ extern const char vsyscall_int80_start,extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;static struct page *syscall_pages[1 ]; -int __init sysenter_setup (void ) +int __cpuinit sysenter_setup (void ) {void *syscall_page = (void *)get_zeroed_page (GFP_ATOMIC ); syscall_pages[0 ] =virt_to_page (syscall_page);
include/linux/init.h +6 -1
@@ -52,9 +52,14 @@#endif /* For assembly routines */ +#ifdef CONFIG_HOTPLUG_CPU +#define __INIT .section ".text","ax" +#define __INITDATA .section ".data","aw" +#else #define __INIT .section ".init.text","ax" -#define __FINIT .previous#define __INITDATA .section ".init.data","aw" +#endif +#define __FINIT .previous#ifndef __ASSEMBLY__/*
PATCH 31/35 i386: Fix usage of -mtune when X86_GENERIC=y or CONFIG_MCORE2=y
In reply to Andi KleenFrom: Lasse Collin <[email protected]>
Hi!
I sent this simple patch to lkml about two weeks ago and also cc'ed to Linus, but seems that the patch got ignored. I decided to write to you, because you have modified the relevant file most recently.
Below is a copy of the mail that is also available at
<http://lkml.org/lkml/2007/2/28/230>.
---
Two fixes to arch/i386/Makefile.cpu:
1) When X86_GENERIC=y is set, use -mtune=i686 if $(CC) doesn't support -mtune=generic. GCC 4.1.2 and earlier don't support -mtune=generic. When building a generic kernel for a distro that runs on i586 and better, it is nice to use -march=i586 -mtune=i686 instead of plain -march=i586.
2) Use $(call tune) instead of hardcoded -mtune when CONFIG_MCORE2=y. This makes it possible to have CONFIG_MCORE2=y when using GCC 3.3, which uses -mcpu instead of -mtune. Also dropped fallback to -mtune=generic and -mtune=i686, because -march=i686 already implies -mtune=i686.
The patch is against 2.6.20, but Makefile.cpu hasn't changed recently.
--- arch/i386/Makefile.cpu | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/i386/Makefile.cpu +4 -4
@@ -4,9 +4,9 @@ #-mtune exists since gcc 3.4 HAS_MTUNE := $(call cc-option-yn, -mtune=i386) ifeq ($(HAS_MTUNE),y) -tune = $(call cc-option,-mtune=$(1),) +tune = $(call cc-option,-mtune=$(1),$(2)) else -tune = $(call cc-option,-mcpu=$(1),) +tune = $(call cc-option,-mcpu=$(1),$(2)) endif align := $(cc-option-align)
@@ -33,7 +33,7 @@ cflags-$(CONFIG_MWINCHIP3D) += $(call cc cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) cflags-$(CONFIG_MVIAC7) += -march=i686 -cflags-$(CONFIG_MCORE2) += -march=i686 $(call cc-option,-mtune=core2,$(call cc-option,-mtune=generic,-mtune=i686)) +cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) # AMD Elan support cflags-$(CONFIG_X86_ELAN) += -march=i486
@@ -43,5 +43,5 @@ cflags-$(CONFIG_MGEODEGX1) += -march=pen # add at the end to overwrite eventual tuning options from earlier # cpu entries -cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic) +cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686))
PATCH 21/35 x86_64: Some cleanup in time.c
In reply to Andi KleenMove prototypes into header files
Remove unneeded includes.
--- arch/x86_64/kernel/time.c | 5 +---- include/asm-x86_64/proto.h | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-)
arch/x86_64/kernel/time.c +1 -4
@@ -39,13 +39,10 @@#include <asm/proto.h> #include <asm/hpet.h> #include <asm/sections.h> -#include <linux/cpufreq.h> #include <linux/hpet.h> #include <asm/apic.h> #include <asm/hpet.h> - -extern void i8254_timer_resume (void ); -extern int using_apic_timer; +#include <asm/mpspec.h> static char *timename =NULL ;
include/asm-x86_64/proto.h +2 -0
@@ -122,6 +122,8 @@ extern void smp_local_timer_interrupt(volong do_arch_prctl (struct task_struct *task,int code,unsigned long addr); +void i8254_timer_resume (void ); +#define round_up (x,y) (((x) + (y) - 1) & ~((y)-1))#define round_down (x,y) ((x) & ~((y)-1))
PATCH 34/35 x86_64: fix cpu MHz reporting on constant_tsc cpus
In reply to Andi KleenFrom: Joerg Roedel <[email protected]>
This patch fixes the reporting of cpu_mhz in /proc/cpuinfo on CPUs with a constant TSC rate and a kernel with disabled cpufreq.
arch/x86_64/kernel/apic.c | 2 - arch/x86_64/kernel/time.c | 58 +++++++++++++++++++++++++++++++++++++++--- arch/x86_64/kernel/tsc.c | 12 +++++--- arch/x86_64/kernel/tsc_sync.c | 2 - include/asm-x86_64/proto.h | 1 5 files changed, 65 insertions(+), 10 deletions(-)
arch/x86_64/kernel/apic.c +1 -1
@@ -843,7 +843,7 @@ static int __init calibrate_APIC_clock(v }while ((tsc - tsc_start) <TICK_COUNT && (apic - apic_start) <TICK_COUNT ); - result = (apic_start - apic) *1000L * cpu_khz / + result = (apic_start - apic) *1000L * tsc_khz / (tsc - tsc_start); }printk ("result %d\n" , result);
arch/x86_64/kernel/time.c +55 -3
88 lines not on this page · raw message
arch/x86_64/kernel/tsc.c +7 -5
@@ -13,6 +13,8 @@ static int notsc __initdata = 0;unsigned int cpu_khz;/* TSC clocks / usec, not used here */ EXPORT_SYMBOL (cpu_khz); +unsigned int tsc_khz; +EXPORT_SYMBOL (tsc_khz);static unsigned int cyc2ns_scale__read_mostly ;
@@ -77,7 +79,7 @@ static void handle_cpufreq_delayed_get(sstatic unsigned int ref_freq =0 ;static unsigned long loops_per_jiffy_ref =0 ; -static unsigned long cpu_khz_ref =0 ; +static unsigned long tsc_khz_ref =0 ;static int time_cpufreq_notifier (struct notifier_block *nb,unsigned long val,void *data)
@@ -99,7 +101,7 @@ static int time_cpufreq_notifier(structif (!ref_freq) { ref_freq = freq->old; loops_per_jiffy_ref = *lpj; - cpu_khz_ref = cpu_khz; + tsc_khz_ref = tsc_khz; } if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
@@ -107,12 +109,12 @@ static int time_cpufreq_notifier(struct *lpj =cpufreq_scale (loops_per_jiffy_ref, ref_freq, freq->new); - cpu_khz =cpufreq_scale (cpu_khz_ref, ref_freq, freq->new); + tsc_khz =cpufreq_scale (tsc_khz_ref, ref_freq, freq->new);if (!(freq->flags &CPUFREQ_CONST_LOOPS ))mark_tsc_unstable (); } -set_cyc2ns_scale (cpu_khz_ref); +set_cyc2ns_scale (tsc_khz_ref);return 0 ; }
@@ -213,7 +215,7 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable);void __init init_tsc_clocksource (void ) {if (!notsc) { - clocksource_tsc.mult =clocksource_khz2mult (cpu_khz, + clocksource_tsc.mult =clocksource_khz2mult (tsc_khz, clocksource_tsc.shift);if (check_tsc_unstable ()) clocksource_tsc.rating =0 ;
arch/x86_64/kernel/tsc_sync.c +1 -1
@@ -50,7 +50,7 @@ static __cpuinit void check_tsc_warp(voi/* * The measurement runs for 20 msecs: */ - end = start + cpu_khz *20ULL ; + end = start + tsc_khz *20ULL ; now = start;for (i =0 ; ; i++) {
include/asm-x86_64/proto.h +1 -0
@@ -92,6 +92,7 @@ extern unsigned long table_start, table_extern int exception_trace;extern unsigned cpu_khz; +extern unsigned tsc_khz;extern void no_iommu_init (void );extern int force_iommu, no_iommu;
PATCH 33/35 x86_64: Remove duplicated code for reading control registers
In reply to Andi KleenFrom: Glauber de Oliveira Costa <[email protected]>
Quoted 4 lines · Randy.Dunlap
Quoted 2 lines · Glauber de Oliveira Costa
Tiny cleanup:
Quoted 8 lines
Quoted 5 lines
In
x86_64, the same functions for reading cr3 and writing cr{3,4} are defined intlbflush.handsystem.h, whith just a name change. The only difference is the clobbering of memory, which seems a safe, and even needed change for thewrite_cr4. This patch removes the duplicate.write_cr3()is moved tosystem.hfor consistency.missing patch.....
thanks. Attached now
Signature · 90 lines
Glauber de Oliveira Costa Red Hat Inc. "Free as in Freedom" Signed-off-by: Andi Kleen <[email protected]> --- include/asm-x86_64/system.h | 7 ++++++- include/asm-x86_64/tlbflush.h | 33 +++++---------------------------- 2 files changed, 11 insertions(+), 29 deletions(-) 2d19cf472903fa4c9e763301b7b1cc0fa53bd023 Index: linux/include/asm-x86_64/system.h =================================================================== --- linux.orig/include/asm-x86_64/system.h +++ linux/include/asm-x86_64/system.h @@ -89,6 +89,11 @@ static inline unsigned long read_cr3(voi 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; @@ -98,7 +103,7 @@ static inline unsigned long read_cr4(voi static inline void write_cr4(unsigned long val) { - asm volatile("movq %0,%%cr4" :: "r" (val)); + asm volatile("movq %0,%%cr4" :: "r" (val) : "memory"); } #define stts() write_cr0(8 | read_cr0()) Index: linux/include/asm-x86_64/tlbflush.h =================================================================== --- linux.orig/include/asm-x86_64/tlbflush.h +++ linux/include/asm-x86_64/tlbflush.h @@ -3,41 +3,18 @@ #include <linux/mm.h> #include <asm/processor.h> - -static inline unsigned long get_cr3(void) -{ - unsigned long cr3; - asm volatile("mov %%cr3,%0" : "=r" (cr3)); - return cr3; -} - -static inline void set_cr3(unsigned long cr3) -{ - asm volatile("mov %0,%%cr3" :: "r" (cr3) : "memory"); -} +#include <asm/system.h> static inline void __flush_tlb(void) { - set_cr3(get_cr3()); -} - -static inline unsigned long get_cr4(void) -{ - unsigned long cr4; - asm volatile("mov %%cr4,%0" : "=r" (cr4)); - return cr4; -} - -static inline void set_cr4(unsigned long cr4) -{ - asm volatile("mov %0,%%cr4" :: "r" (cr4) : "memory"); + write_cr3(read_cr3()); } static inline void __flush_tlb_all(void) { - unsigned long cr4 = get_cr4(); - set_cr4(cr4 & ~X86_CR4_PGE); /* clear PGE */ - set_cr4(cr4); /* write old PGE again and flush TLBs */ + unsigned long cr4 = read_cr4(); + write_cr4(cr4 & ~X86_CR4_PGE); /* clear PGE */ + write_cr4(cr4); /* write old PGE again and flush TLBs */ } #define __flush_tlb_one(addr) \
PATCH 22/35 i386: i386 make NMI use PERFCTR1 for architectural perfmon (take 2)
In reply to Andi KleenFrom: Stephane Eranian <[email protected]>
Hello,
This patch against 2.6.20-git14 makes the NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting Intel architectural perfmon, such as Intel Core 2. Although all PMU events can work on both counters, the Precise Event-Based Sampling (PEBS) requires that the event be in PERFCTR0 to work correctly (see section 18.14.4.1 in the IA32 SDM Vol 3b).
A similar patch for x86-64 is to follow.
Changelog:
- make the i386 NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting the Intel architectural perfmon (e.g. Core 2 Duo). This allows PEBS to work when the NMI watchdog is active.
--- arch/i386/kernel/nmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/i386/kernel/nmi.c +4 -4
@@ -365,7 +365,7 @@ static int __init check_nmi_watchdog(voi nmi_hz =1 ;if (wd->perfctr_msr ==MSR_P6_PERFCTR0 || - wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR0 ) { + wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR1 ) { nmi_hz =adjust_for_32bit_ctr (nmi_hz); } }
@@ -799,8 +799,8 @@ static int setup_intel_arch_watchdog(voi (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) goto fail; - perfctr_msr =MSR_ARCH_PERFMON_PERFCTR0 ; - evntsel_msr =MSR_ARCH_PERFMON_EVENTSEL0 ; + perfctr_msr =MSR_ARCH_PERFMON_PERFCTR1 ; + evntsel_msr =MSR_ARCH_PERFMON_EVENTSEL1 ;if (!__reserve_perfctr_nmi (-1 , perfctr_msr)) goto fail;
@@ -1080,7 +1080,7 @@ __kprobes int nmi_watchdog_tick(struct pwrite_watchdog_counter (wd->perfctr_msr,NULL ); }else if (wd->perfctr_msr ==MSR_P6_PERFCTR0 || - wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR0 ) { + wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR1 ) {/* P6 based Pentium M need to re-unmask * the apic vector but it doesn't hurt * other P6 variant.
PATCH 23/35 x86_64: x86_64 make NMI use PERFCTR1 for architectural perfmon (take 2)
In reply to Andi KleenFrom: Stephane Eranian <[email protected]>
Hello,
This patch against 2.6.20-git14 makes the NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting Intel architectural perfmon, such as Intel Core 2. Although all PMU events can work on both counters, the Precise Event-Based Sampling (PEBS) requires that the event be in PERFCTR0 to work correctly (see section 18.14.4.1 in the IA32 SDM Vol 3b). This versions has 3 chunks compared to previous where we had missed on check.
Changelog:
- make the x86-64 NMI watchdog use PERFSEL1/PERFCTR1 instead of PERFSEL0/PERFCTR0 on processors supporting the Intel architectural perfmon (e.g. Core 2 Duo). This allows PEBS to work when the NMI watchdog is active.
--- arch/x86_64/kernel/nmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86_64/kernel/nmi.c +4 -4
@@ -348,7 +348,7 @@ int __init check_nmi_watchdog (void)struct nmi_watchdog_ctlblk *wd = &__get_cpu_var (nmi_watchdog_ctlblk); nmi_hz =1 ; -if (wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR0 ) +if (wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR1 ) nmi_hz =adjust_for_32bit_ctr (nmi_hz); }
@@ -713,8 +713,8 @@ static int setup_intel_arch_watchdog(voi (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) goto fail; - perfctr_msr =MSR_ARCH_PERFMON_PERFCTR0 ; - evntsel_msr =MSR_ARCH_PERFMON_EVENTSEL0 ; + perfctr_msr =MSR_ARCH_PERFMON_PERFCTR1 ; + evntsel_msr =MSR_ARCH_PERFMON_EVENTSEL1 ;if (!__reserve_perfctr_nmi (-1 , perfctr_msr)) goto fail;
@@ -958,7 +958,7 @@ int __kprobes nmi_watchdog_tick(struct p/* start the cycle over again */ wrmsrl (wd->perfctr_msr, -((u64 )cpu_khz *1000 / nmi_hz)); - }else if (wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR0 ) { + }else if (wd->perfctr_msr ==MSR_ARCH_PERFMON_PERFCTR1 ) {/* * ArchPerfom/Core Duo needs to re-unmask * the apic vector
PATCH 20/35 x86: Fix i386 and x86_64 fault information pollution
In reply to Andi Kleena userspace fault or a kernelspace fault which will result in the immediate death of the process. They should not be filled in as a result of a kernelspace fault which can be fixed up.
Otherwise, if the process is handling SIGSEGV and examining the fault information, this can result in the kernel space fault trashing the previously stored fault information if it arrives between the userspace fault happening and the SIGSEGV being delivered to the process.
--
arch/i386/kernel/traps.c | 24 ++++++++++++++++++------ arch/x86_64/kernel/traps.c | 30 +++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 13 deletions(-)
arch/i386/kernel/traps.c +18 -6
@@ -476,8 +476,6 @@ static void __kprobes do_trap(int trapnr siginfo_t *info) {struct task_struct *tsk = current; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr;if (regs->eflags &VM_MASK ) {if (vm86)
@@ -489,6 +487,18 @@ static void __kprobes do_trap(int trapnr goto kernel_trap; trap_signal: { +/* +* We want error_code and trap_no set for userspace faults and +* kernelspace faults which result in die(), but not +* kernelspace faults which are fixed up. die() gives the +* process no chance to handle the signal and notice the +* kernel fault information, so that won't result in polluting +* the information about previously queued, but not yet +* delivered, faults. See also do_general_protection below. +*/ + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; +if (info)force_sig_info (signr, info, tsk);else
@@ -497,8 +507,11 @@ static void __kprobes do_trap(int trapnr } kernel_trap: { -if (!fixup_exception (regs)) +if (!fixup_exception (regs)) { + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr;die (str, regs, error_code); + }return ; }
@@ -603,9 +616,6 @@ fastcall void __kprobes do_general_prote }put_cpu (); - current->thread.error_code = error_code; - current->thread.trap_no =13 ; -if (regs->eflags &VM_MASK ) goto gp_in_vm86;
@@ -624,6 +634,8 @@ gp_in_vm86: gp_in_kernel:if (!fixup_exception (regs)) { + current->thread.error_code = error_code; + current->thread.trap_no =13 ;if (notify_die (DIE_GPF ,"general protection fault" , regs, error_code,13 ,SIGSEGV ) ==NOTIFY_STOP )return ;
arch/x86_64/kernel/traps.c +23 -7
@@ -581,10 +581,20 @@ static void __kprobes do_trap(int trapnr {struct task_struct *tsk = current; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; -if (user_mode (regs)) { +/* +* We want error_code and trap_no set for userspace +* faults and kernelspace faults which result in +* die(), but not kernelspace faults which are fixed +* up. die() gives the process no chance to handle +* the signal and notice the kernel fault information, +* so that won't result in polluting the information +* about previously queued, but not yet delivered, +* faults. See also do_general_protection below. +*/ + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; +if (exception_trace &&unhandled_signal (tsk, signr)) printk(KERN_INFO "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
@@ -605,8 +615,11 @@ static void __kprobes do_trap(int trapnr fixup =search_exception_tables (regs->rip);if (fixup) regs->rip = fixup->fixup; -else +else { + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr;die (str, regs, error_code); + }return ; } }
@@ -682,10 +695,10 @@ asmlinkage void __kprobes do_general_proconditional_sti (regs); - tsk->thread.error_code = error_code; - tsk->thread.trap_no =13 ; -if (user_mode (regs)) { + tsk->thread.error_code = error_code; + tsk->thread.trap_no =13 ; +if (exception_trace &&unhandled_signal (tsk,SIGSEGV )) printk(KERN_INFO "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
@@ -704,6 +717,9 @@ asmlinkage void __kprobes do_general_pro regs->rip = fixup->fixup;return ; } + + tsk->thread.error_code = error_code; + tsk->thread.trap_no =13 ;if (notify_die (DIE_GPF ,"general protection fault" , regs, error_code,13 ,SIGSEGV ) ==NOTIFY_STOP )return ;
PATCH 28/35 x86: Drop cc-options call for all options supported in gcc 3.2+
In reply to Andi KleenThe kernel only supports gcc 3.2+ now so it doesn't make sense anymore to explicitely check for options this compiler version already has.
This actually fixes a bug. The -mprefered-stack-boundary check never worked because gcc rightly complains
CC arch/i386/kernel/asm-offsets.s
cc1: -mpreferred-stack-boundary=2 is not between 4 and 12
We just never saw the error because of cc-options. I changed it to 4 to actually work.
Tested by compiling i386 and x86-64 defconfig with gcc 3.2.
Should speed up the build time a tiny bit and improve stack usage on i386 slightly.
--- Makefile | 2 +- arch/i386/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
Makefile +1 -1
@@ -491,7 +491,7 @@ endif include $(srctree)/arch/$(ARCH)/Makefile ifdef CONFIG_FRAME_POINTER -CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) +CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls else CFLAGS += -fomit-frame-pointer endif
arch/i386/Makefile +1 -1
@@ -34,7 +34,7 @@ CHECKFLAGS += -D__i386__ CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return # prevent gcc from keeping the stack 16 byte aligned -CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) +CFLAGS += -mpreferred-stack-boundary=4 # CPU-specific tuning. Anything which can be shared with UML should go here. include $(srctree)/arch/i386/Makefile.cpu
PATCH 17/35 i386: probe_roms() cleanup
In reply to Andi KleenFrom: Rene Herman <[email protected]>
Remove the assumption that if the first page of a legacy ROM is mapped, it'll all be mapped. This'll also stop people reading this code from wondering if they're looking at a bug...
---
arch/i386/kernel/e820.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
arch/i386/kernel/e820.c +18 -11
@@ -161,26 +161,27 @@ static struct resource standard_io_resoustatic int __init romsignature (const unsigned char *rom) { +const unsigned short *const ptr = (const unsigned short *)rom;unsigned short sig; -return probe_kernel_address ((const unsigned short *)rom, sig) ==0 && - sig ==ROMSIGNATURE ; +return probe_kernel_address (ptr, sig) ==0 && sig ==ROMSIGNATURE ; } -static int __init romchecksum (unsigned char *rom,unsigned long length) +static int __init romchecksum (const unsigned char *rom,unsigned long length) { -unsigned char sum; +unsigned char sum, c; -for (sum =0 ; length; length--) - sum += *rom++; -return sum ==0 ; +for (sum =0 ; length &&probe_kernel_address (rom++, c) ==0 ; length--) + sum += c; +return !length && !sum; }static void __init probe_roms (void ) { +const unsigned char *rom;unsigned long start, length, upper; -unsigned char *rom; -int i; +unsigned char c; +int i;/* video rom */ upper = adapter_rom_resources[0 ].start;
@@ -191,8 +192,11 @@ static void __init probe_roms(void) video_rom_resource.start = start; +if (probe_kernel_address (rom +2 , c) !=0 ) +continue ; +/* 0 < length <= 0x7f * 512, historically */ - length = rom[2 ] *512 ; + length = c *512 ;/* if checksum okay, trust length byte */ if (length &&romchecksum (rom, length))
@@ -226,8 +230,11 @@ static void __init probe_roms(void)if (!romsignature (rom))continue ; +if (probe_kernel_address (rom +2 , c) !=0 ) +continue ; +/* 0 < length <= 0x7f * 512, historically */ - length = rom[2 ] *512 ; + length = c *512 ;/* but accept any length that fits if checksum okay */ if (!length || start + length > upper || !romchecksum (rom, length))
PATCH 32/35 x86_64: Remove unused set_seg_base
In reply to Andi KleenFrom: Rusty Russell <[email protected]>
The set_seg_base function isn't used anywhere (2.6.21-rc3-git1)
--- include/asm-x86_64/desc.h | 10 ---------- 1 file changed, 10 deletions(-)
include/asm-x86_64/desc.h +0 -10
@@ -107,16 +107,6 @@ static inline void set_ldt_desc(unsigned DESC_LDT, size * 8 - 1); } -static inline void set_seg_base (unsigned cpu,int entry,void *base) -{ -struct desc_struct *d = &cpu_gdt (cpu)[entry]; -u32 addr = (u32 )(u64 )base; -BUG_ON ((u64 )base >>32 ); - d->base0 = addr &0xffff ; - d->base1 = (addr >>16 ) &0xff ; - d->base2 = (addr >>24 ) &0xff ; -} -#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
PATCH 24/35 i386: Add __init to probe_bigsmp
In reply to Andi KleenFrom: Prarit Bhargava <[email protected]>
Add __init to probe_bigsmp. All callers are __init and data being examined is __initdata.
Resolves MODPOST warning similar to:
WARNING: vmlinux - Section mismatch: reference to .init.data: from .text between 'probe_bigsmp' (at offset 0xc0401e56) and 'init_apic_ldr'
--- arch/i386/mach-generic/bigsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/i386/mach-generic/bigsmp.c +1 -1
@@ -45,7 +45,7 @@ static struct dmi_system_id __initdata b }; -static int probe_bigsmp (void ) +static int __init probe_bigsmp (void ) {if (def_to_bigsmp) dmi_bigsmp =1 ;
PATCH 26/35 x86_64: Correct max number of CPUs in Kconfig
In reply to Andi KleenPointed out by Adrian Bunk
--- arch/x86_64/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86_64/Kconfig +2 -2
@@ -415,13 +415,13 @@ config OUT_OF_LINE_PFN_TO_PAGE depends on DISCONTIGMEM config NR_CPUS - int "Maximum number of CPUs (2-256)" + int "Maximum number of CPUs (2-255)" range 2 255 depends on SMP default "8" help This allows you to specify the maximum number of CPUs which this - kernel will support. Current maximum is 256 CPUs due to + kernel will support. Current maximum is 255 CPUs due to APIC addressing limits. Less depending on the hardware. This is purely to save memory - each supported CPU requires
PATCH 30/35 i386: clean up mach_reboot_fixups
In reply to Andi KleenFrom: Jeremy Fitzhardinge <[email protected]>
The reboot_fixups stuff seems to be a bit of a mess, specifically the header is in linux/ when its a purely i386-specific piece of code. I'm not sure why it has its config option; its only currently needed for "geode-gx1/cs5530a", so perhaps whatever config option controls that hardware should enable this?
--- arch/i386/kernel/reboot.c | 6 +++++- arch/i386/kernel/reboot_fixups.c | 2 +- include/asm-i386/reboot_fixups.h | 6 ++++++ include/linux/reboot_fixups.h | 10 ---------- 4 files changed, 12 insertions(+), 12 deletions(-)
===================================================================
arch/i386/kernel/reboot.c +5 -1
@@ -17,7 +17,7 @@#include <asm/apic.h> #include <asm/desc.h> #include "mach_reboot.h" -#include <linux/reboot_fixups.h> +#include <asm/reboot_fixups.h> /* * Power off function, if any
@@ -316,6 +316,10 @@ void machine_shutdown(void)#endif } +void __attribute__((weak))mach_reboot_fixups (void ) +{ +} +void machine_emergency_restart (void ) {if (!reboot_thru_bios) {
arch/i386/kernel/reboot_fixups.c +1 -1
@@ -10,7 +10,7 @@#include <asm/delay.h> #include <linux/pci.h> -#include <linux/reboot_fixups.h> +#include <asm/reboot_fixups.h> static void cs5530a_warm_reset (struct pci_dev *dev) {
include/asm-i386/reboot_fixups.h new file +6 -0
@@ -0,0 +1,6 @@ +#ifndef _LINUX_REBOOT_FIXUPS_H +#define _LINUX_REBOOT_FIXUPS_H + +extern void mach_reboot_fixups (void ); + +#endif /* _LINUX_REBOOT_FIXUPS_H */
include/linux/reboot_fixups.h deleted +0 -10
@@ -1,10 +0,0 @@ -#ifndef _LINUX_REBOOT_FIXUPS_H -#define _LINUX_REBOOT_FIXUPS_H - -#ifdef CONFIG_X86_REBOOTFIXUPS -extern void mach_reboot_fixups (void ); -#else -#define mach_reboot_fixups () ((void)(0)) -#endif - -#endif /* _LINUX_REBOOT_FIXUPS_H */
Re: [PATCH] [16/35] i386: Add an option for the VIA C7 which sets appropriate L1 cache
In reply to Andi KleenQuoted 7 lines · Andi Kleen
From: Simon Arlott <[email protected]>
The VIA C7 is a 686 (with TSC) that supports MMX, SSE and SSE2, it also has a cache line length of 64 according to
http://www.digit-life.com/articles2/cpu/rmma-via-c7.html. This patch sets gcc to -march=686 and select s the correct cache shift.
Quoted 6 lines
Signed-off-by Simon Arlott <[email protected]>Signed-off-by Andi Kleen <[email protected]>Cc Andi Kleen <[email protected]>Cc Dave Jones <[email protected]>Cc Alan Cox <[email protected]>Signed-off-by Andrew Morton <[email protected]>
Has it been verified in the field that this CPU supports CMOV?
Jeff
PATCH 35/35 i386: Simplify smp_call_function*() by using common implementation
In reply to Andi KleenFrom: Jeremy Fitzhardinge <[email protected]>
Subject: Simplify smp_call_function*() by using common implementation
smp_call_function and smp_call_function_single are almost complete duplicates of the same logic. This patch combines them by implementing them in terms of the more general smp_call_function_mask().
--- arch/i386/kernel/smp.c | 173 +++++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 77 deletions(-)
===================================================================
arch/i386/kernel/smp.c +96 -77
@@ -546,34 +546,124 @@ static void __smp_call_function(void (*fcpu_relax (); } +/** -* smp_call_function(): Run a function on all other CPUs. +* smp_call_function_mask(): Run a function on a set of other CPUs. +* @mask: The set of cpus to run on. Must not include the current cpu. * @func: The function to run. This must be fast and non-blocking. * @info: An arbitrary pointer to pass to the function. -* @nonatomic: currently unused. * @wait: If true, wait (atomically) until function has completed on other CPUs. * * Returns 0 on success, else a negative status code. Does not return until -* remote CPUs are nearly ready to execute <<func>> or are or have executed. +* remote CPUs are nearly ready to execute <<func>> or are or have finished. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -int smp_call_function (void (*func) (void *info),void *info,int nonatomic, -int wait) +int smp_call_function_mask (cpumask_t mask, +void (*func)(void *),void *info, +int wait) { +struct call_data_struct data; +cpumask_t allbutself; +int cpus; +/* Can deadlock when called with interrupts disabled */ WARN_ON (irqs_disabled ());/* Holding any lock stops cpus from going down. */ spin_lock (&call_lock); -__smp_call_function (func, info, nonatomic, wait); + + allbutself = cpu_online_map; +cpu_clear (smp_processor_id (), allbutself); + +cpus_and (mask, mask, allbutself); + cpus =cpus_weight (mask); + +if (!cpus) { +spin_unlock (&call_lock); +return 0 ; + } + + data.func = func; + data.info = info; +atomic_set (&data.started,0 ); + data.wait = wait; +if (wait) +atomic_set (&data.finished,0 ); + + call_data = &data; +mb (); + +/* Send a message to other CPUs */ +if (cpus_equal (mask, allbutself)) +send_IPI_allbutself (CALL_FUNCTION_VECTOR ); +else +send_IPI_mask (mask,CALL_FUNCTION_VECTOR ); + +/* Wait for response */ +while (atomic_read (&data.started) != cpus) +cpu_relax (); + +if (wait) +while (atomic_read (&data.finished) != cpus) +cpu_relax ();spin_unlock (&call_lock);return 0 ; } + +/** +* smp_call_function(): Run a function on all other CPUs. +* @func: The function to run. This must be fast and non-blocking. +* @info: An arbitrary pointer to pass to the function. +* @nonatomic: currently unused. +* @wait: If true, wait (atomically) until function has completed on other CPUs. +* +* Returns 0 on success, else a negative status code. Does not return until +* remote CPUs are nearly ready to execute <<func>> or are or have executed. +* +* You must not call this function with disabled interrupts or from a +* hardware interrupt handler or from a bottom half handler. +*/ +int smp_call_function (void (*func) (void *info),void *info,int nonatomic, +int wait) +{ +return smp_call_function_mask (cpu_online_map, func, info, wait); +}EXPORT_SYMBOL (smp_call_function); +/* +* smp_call_function_single - Run a function on another CPU +* @func: The function to run. This must be fast and non-blocking. +* @info: An arbitrary pointer to pass to the function. +* @nonatomic: Currently unused. +* @wait: If true, wait until function has completed on other CPUs. +* +* Retrurns 0 on success, else a negative status code. +* +* Does not return until the remote CPU is nearly ready to execute <func> +* or is or has executed. +*/ +int smp_call_function_single (int cpu,void (*func) (void *info),void *info, +int nonatomic,int wait) +{ +/* prevent preemption and reschedule on another processor */ +int ret; +int me =get_cpu (); +if (cpu == me) { +WARN_ON (1 ); +put_cpu (); +return -EBUSY ; + } + + ret =smp_call_function_mask (cpumask_of_cpu (cpu), func, info, wait); + +put_cpu (); +return ret; +} +EXPORT_SYMBOL (smp_call_function_single); +static void stop_this_cpu (void * dummy) {local_irq_disable ();
@@ -641,77 +731,6 @@ fastcall void smp_call_function_interrup } } -/* -* this function sends a 'generic call function' IPI to one other CPU -* in the system. -* -* cpu is a standard Linux logical CPU number. -*/ -static void -__smp_call_function_single (int cpu,void (*func) (void *info),void *info, -int nonatomic,int wait) -{ -struct call_data_struct data; -int cpus =1 ; - - data.func = func; - data.info = info; -atomic_set (&data.started,0 ); - data.wait = wait; -if (wait) -atomic_set (&data.finished,0 ); - - call_data = &data; -wmb (); -/* Send a message to all other CPUs and wait for them to respond */ -send_IPI_mask (cpumask_of_cpu (cpu),CALL_FUNCTION_VECTOR ); - -/* Wait for response */ -while (atomic_read (&data.started) != cpus) -cpu_relax (); - -if (!wait) -return ; - -while (atomic_read (&data.finished) != cpus) -cpu_relax (); -} - -/* -* smp_call_function_single - Run a function on another CPU -* @func: The function to run. This must be fast and non-blocking. -* @info: An arbitrary pointer to pass to the function. -* @nonatomic: Currently unused. -* @wait: If true, wait until function has completed on other CPUs. -* -* Retrurns 0 on success, else a negative status code. -* -* Does not return until the remote CPU is nearly ready to execute <func> -* or is or has executed. -*/ - -int smp_call_function_single (int cpu,void (*func) (void *info),void *info, -int nonatomic,int wait) -{ -/* prevent preemption and reschedule on another processor */ -int me =get_cpu (); -if (cpu == me) { -WARN_ON (1 ); -put_cpu (); -return -EBUSY ; - } - -/* Can deadlock when called with interrupts disabled */ -WARN_ON (irqs_disabled ()); - -spin_lock_bh (&call_lock); -__smp_call_function_single (cpu, func, info, nonatomic, wait); -spin_unlock_bh (&call_lock); -put_cpu (); -return 0 ; -} -EXPORT_SYMBOL (smp_call_function_single); -static int convert_apicid_to_cpu (int apic_id) {int i;
PATCH 18/35 x86_64: a few missing entry.S annotations
In reply to Andi KleenFrom: "Jan Beulich" <[email protected]>
--- arch/x86_64/kernel/entry.S | 5 +++++ 1 file changed, 5 insertions(+)
arch/x86_64/kernel/entry.S +5 -0
@@ -701,6 +701,7 @@ END(spurious_interrupt) CFI_ADJUST_CFA_OFFSET 8 pushq %rax /* push real oldrax to the rdi slot */ CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rax,0 leaq \sym(%rip),%rax jmp error_entry CFI_ENDPROC
@@ -710,6 +711,7 @@ END(spurious_interrupt) XCPT_FRAME pushq %rax CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rax,0 leaq \sym(%rip),%rax jmp error_entry CFI_ENDPROC
@@ -817,6 +819,7 @@ paranoid_schedule\trace: */ KPROBE_ENTRY(error_entry) _frame RDI + CFI_REL_OFFSET rax,0 /* rdi slot contains rax, oldrax contains error code */ cld subq $14*8,%rsp
@@ -824,6 +827,7 @@ KPROBE_ENTRY(error_entry) movq %rsi,13*8(%rsp) CFI_REL_OFFSET rsi,RSI movq 14*8(%rsp),%rsi /* load rax from rdi slot */ + CFI_REGISTER rax,rsi movq %rdx,12*8(%rsp) CFI_REL_OFFSET rdx,RDX movq %rcx,11*8(%rsp)
@@ -857,6 +861,7 @@ error_swapgs: swapgs error_sti: movq %rdi,RDI(%rsp) + CFI_REL_OFFSET rdi,RDI movq %rsp,%rdi movq ORIG_RAX(%rsp),%rsi /* get error code */ movq $-1,ORIG_RAX(%rsp)
PATCH 13/35 i386: No need to use -traditional for processing asm in i386/kernel/
In reply to Andi KleenFrom: Jeremy Fitzhardinge <[email protected]>
No need to use -traditional for processing asm in i386/kernel/
--- arch/i386/kernel/Makefile | 2 -- arch/i386/kernel/entry.S | 2 +- include/asm-i386/percpu.h | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-)
arch/i386/kernel/Makefile +0 -2
@@ -43,8 +43,6 @@ obj-$(CONFIG_VMI) += vmi.o vmitime.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-y += pcspeaker.o -EXTRA_AFLAGS := -traditional - obj-$(CONFIG_SCx200) += scx200.o # vsyscall.o contains the vsyscall DSO images as __initdata.
arch/i386/kernel/entry.S +1 -1
@@ -635,7 +635,7 @@ ENTRY(name) \ SAVE_ALL; \ TRACE_IRQS_OFF \ movl %esp,%eax; \ - call smp_/**/name; \ + call smp_##name; \ jmp ret_from_intr; \ CFI_ENDPROC; \ ENDPROC(name)
include/asm-i386/percpu.h +2 -2
@@ -20,10 +20,10 @@#ifdef CONFIG_SMP #define PER_CPU (var, cpu) \ movl __per_cpu_offset(,cpu,4), cpu; \ - addl $per_cpu__/**/ var, cpu; + addl $per_cpu__##var, cpu;#else /* ! SMP */ #define PER_CPU (var, cpu) \ - movl $per_cpu__/**/ var, cpu; + movl $per_cpu__##var, cpu;#endif /* SMP */ #endif /* !__ASSEMBLY__ */
PATCH 19/35 i386: Add dwarf2 annotations to *_user and checksum functions
In reply to Andi KleenFrom: Jan Beulich <[email protected]>
--- arch/i386/lib/checksum.S | 69 ++++++++++++++++++++++++++++++++++++++++------- arch/i386/lib/getuser.S | 26 +++++++++++------ arch/i386/lib/putuser.S | 39 +++++++++++++++++--------- 3 files changed, 102 insertions(+), 32 deletions(-)
arch/i386/lib/checksum.S +60 -9
@@ -25,6 +25,8 @@ * 2 of the License, or (at your option) any later version. */ +#include <linux/linkage.h> +#include <asm/dwarf2.h> #include <asm/errno.h> /*
@@ -36,8 +38,6 @@ unsigned int csum_partial(const unsigned */ .text -.align 4 -.globl csum_partial #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
@@ -48,9 +48,14 @@ unsigned int csum_partial(const unsigned * Fortunately, it is easy to convert 2-byte alignment to 4-byte * alignment for the unrolled loop. */ -csum_partial: +ENTRY(csum_partial) + CFI_STARTPROC pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: unsigned char *buff
@@ -128,16 +133,27 @@ csum_partial: roll $8, %eax 8: popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi ret + CFI_ENDPROC +ENDPROC(csum_partial) #else /* Version for PentiumII/PPro */ -csum_partial: +ENTRY(csum_partial) + CFI_STARTPROC pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: const unsigned char *buf
@@ -245,8 +261,14 @@ csum_partial: roll $8, %eax 90: popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi ret + CFI_ENDPROC +ENDPROC(csum_partial) #endif
@@ -278,19 +300,24 @@ unsigned int csum_partial_copy_generic ( .long 9999b, 6002f ; \ .previous -.align 4 -.globl csum_partial_copy_generic - #ifndef CONFIG_X86_USE_PPRO_CHECKSUM #define ARGBASE 16 #define FP 12 -csum_partial_copy_generic: +ENTRY(csum_partial_copy_generic) + CFI_STARTPROC subl $4,%esp + CFI_ADJUST_CFA_OFFSET 4 pushl %edi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edi, 0 pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 movl ARGBASE+16(%esp),%eax # sum movl ARGBASE+12(%esp),%ecx # len movl ARGBASE+4(%esp),%esi # src
@@ -400,10 +427,19 @@ DST( movb %cl, (%edi) ) .previous popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi popl %edi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE edi popl %ecx # equivalent to addl $4,%esp + CFI_ADJUST_CFA_OFFSET -4 ret + CFI_ENDPROC +ENDPROC(csum_partial_copy_generic) #else
@@ -421,10 +457,17 @@ DST( movb %cl, (%edi) ) #define ARGBASE 12 -csum_partial_copy_generic: +ENTRY(csum_partial_copy_generic) + CFI_STARTPROC pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 pushl %edi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edi, 0 pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 movl ARGBASE+4(%esp),%esi #src movl ARGBASE+8(%esp),%edi #dst movl ARGBASE+12(%esp),%ecx #len
@@ -485,9 +528,17 @@ DST( movb %dl, (%edi) ) .previous popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi popl %edi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE edi popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx ret + CFI_ENDPROC +ENDPROC(csum_partial_copy_generic) #undef ROUND #undef ROUND1
arch/i386/lib/getuser.S +17 -9
@@ -8,6 +8,8 @@ * return an error value in addition to the "real" * return value. */ +#include <linux/linkage.h> +#include <asm/dwarf2.h> #include <asm/thread_info.h>
@@ -24,19 +26,19 @@ */ .text -.align 4 -.globl __get_user_1 -__get_user_1: +ENTRY(__get_user_1) + CFI_STARTPROC GET_THREAD_INFO(%edx) cmpl TI_addr_limit(%edx),%eax jae bad_get_user 1: movzbl (%eax),%edx xorl %eax,%eax ret + CFI_ENDPROC +ENDPROC(__get_user_1) -.align 4 -.globl __get_user_2 -__get_user_2: +ENTRY(__get_user_2) + CFI_STARTPROC addl $1,%eax jc bad_get_user GET_THREAD_INFO(%edx)
@@ -45,10 +47,11 @@ __get_user_2: 2: movzwl -1(%eax),%edx xorl %eax,%eax ret + CFI_ENDPROC +ENDPROC(__get_user_2) -.align 4 -.globl __get_user_4 -__get_user_4: +ENTRY(__get_user_4) + CFI_STARTPROC addl $3,%eax jc bad_get_user GET_THREAD_INFO(%edx)
@@ -57,11 +60,16 @@ __get_user_4: 3: movl -3(%eax),%edx xorl %eax,%eax ret + CFI_ENDPROC +ENDPROC(__get_user_4) bad_get_user: + CFI_STARTPROC xorl %edx,%edx movl $-14,%eax ret + CFI_ENDPROC +END(bad_get_user) .section __ex_table,"a" .long 1b,bad_get_user
arch/i386/lib/putuser.S +25 -14
@@ -8,6 +8,8 @@ * return an error value in addition to the "real" * return value. */ +#include <linux/linkage.h> +#include <asm/dwarf2.h> #include <asm/thread_info.h>
@@ -23,23 +25,28 @@ * as they get called from within inline assembly. */ -#define ENTER pushl %ebx ; GET_THREAD_INFO(%ebx) -#define EXIT popl %ebx ; ret +#define ENTER CFI_STARTPROC ; \ + pushl %ebx ; \ + CFI_ADJUST_CFA_OFFSET 4 ; \ + CFI_REL_OFFSET ebx, 0 ; \ + GET_THREAD_INFO(%ebx) +#define EXIT popl %ebx ; \ + CFI_ADJUST_CFA_OFFSET -4 ; \ + CFI_RESTORE ebx ; \ + ret ; \ + CFI_ENDPROC .text -.align 4 -.globl __put_user_1 -__put_user_1: +ENTRY(__put_user_1) ENTER cmpl TI_addr_limit(%ebx),%ecx jae bad_put_user 1: movb %al,(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_1) -.align 4 -.globl __put_user_2 -__put_user_2: +ENTRY(__put_user_2) ENTER movl TI_addr_limit(%ebx),%ebx subl $1,%ebx
@@ -48,10 +55,9 @@ __put_user_2: 2: movw %ax,(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_2) -.align 4 -.globl __put_user_4 -__put_user_4: +ENTRY(__put_user_4) ENTER movl TI_addr_limit(%ebx),%ebx subl $3,%ebx
@@ -60,10 +66,9 @@ __put_user_4: 3: movl %eax,(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_4) -.align 4 -.globl __put_user_8 -__put_user_8: +ENTRY(__put_user_8) ENTER movl TI_addr_limit(%ebx),%ebx subl $7,%ebx
@@ -73,10 +78,16 @@ __put_user_8: 5: movl %edx,4(%ecx) xorl %eax,%eax EXIT +ENDPROC(__put_user_8) bad_put_user: + CFI_STARTPROC simple + CFI_DEF_CFA esp, 2*4 + CFI_OFFSET eip, -1*4 + CFI_OFFSET ebx, -2*4 movl $-14,%eax EXIT +END(bad_put_user) .section __ex_table,"a" .long 1b,bad_put_user
cover Some x86 2.6.22 candidate patches for review
Here are some 2.6.22 candidate x86 patches for review. I will be posting more over a few days.
This first batch has:
- Ingo's genapic rework. Now we always use physical mode on x86-64.
- Lots of minor stuff
Please review.
-Andi
PATCH 7/35 x86: default to physical mode on hotplug CPU kernels
From: Ingo Molnar <[email protected]>
Default to physical mode on hotplug CPU kernels. Furher simplify and clean up the APIC initialization code.
---
arch/i386/kernel/acpi/boot.c | 2 +- arch/i386/kernel/mpparse.c | 2 +- arch/x86_64/kernel/genapic.c | 16 +++------------- arch/x86_64/kernel/mpparse.c | 2 +- include/asm-i386/genapic.h | 4 ++-- include/asm-i386/mach-bigsmp/mach_apic.h | 2 +- include/asm-i386/mach-default/mach_apic.h | 2 +- include/asm-i386/mach-es7000/mach_apic.h | 2 +- include/asm-i386/mach-generic/mach_apic.h | 2 +- include/asm-i386/mach-numaq/mach_apic.h | 2 +- include/asm-i386/mach-summit/mach_apic.h | 2 +- include/asm-i386/mach-visws/mach_apic.h | 2 +- include/asm-x86_64/apic.h | 2 +- 13 files changed, 16 insertions(+), 26 deletions(-)
arch/i386/kernel/acpi/boot.c +1 -1
@@ -874,7 +874,7 @@ static void __init acpi_process_madt(voi acpi_ioapic =1 ; smp_found_config =1 ; -clustered_apic_check (); +setup_apic_routing (); } }if (error == -EINVAL ) {
arch/i386/kernel/mpparse.c +1 -1
@@ -477,7 +477,7 @@ static int __init smp_read_mpc(struct mp } ++mpc_record; } -clustered_apic_check (); +setup_apic_routing ();if (!num_processors)printk (KERN_ERR "SMP mptable: no processors registered!\n" );return num_processors;
arch/x86_64/kernel/genapic.c +3 -13
@@ -35,11 +35,8 @@ struct genapic __read_mostly *genapic =/* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. */ -void __init clustered_apic_check (void ) +void __init setup_apic_routing (void ) { -unsigned int i, max_apic =0 ; -u8 id; -#ifdef CONFIG_ACPI /* * Quirk: some x86_64 machines can only use physical APIC mode
@@ -49,17 +46,10 @@ void __init clustered_apic_check(void)if (acpi_gbl_FADT.header.revision >FADT2_REVISION_ID && (acpi_gbl_FADT.flags &ACPI_FADT_APIC_PHYSICAL )) genapic = &apic_physflat; + else#endif -for (i =0 ; i <NR_CPUS ; i++) { - id = bios_cpu_apicid[i]; -if (id ==BAD_APICID ) -continue ; -if (id > max_apic) - max_apic = id; - } - -if (max_apic <8 ) +if (cpus_weight (cpu_possible_map) <=8 ) genapic = &apic_flat;else genapic = &apic_physflat;
arch/x86_64/kernel/mpparse.c +1 -1
@@ -300,7 +300,7 @@ static int __init smp_read_mpc(struct mp } } } -clustered_apic_check (); +setup_apic_routing ();if (!num_processors)printk (KERN_ERR "MPTABLE: no processors registered!\n" );return num_processors;
include/asm-i386/genapic.h +2 -2
@@ -36,7 +36,7 @@ struct genapic {void (*init_apic_ldr)(void );physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map); -void (*clustered_apic_check)(void ); +void (*setup_apic_routing)(void );int (*multi_timer_check)(int apic,int irq);int (*apicid_to_node)(int logical_apicid);int (*cpu_to_logical_apicid)(int cpu);
@@ -99,7 +99,7 @@ struct genapic { APICFUNC(check_apicid_present) \ APICFUNC(init_apic_ldr) \ APICFUNC(ioapic_phys_id_map) \ - APICFUNC(clustered_apic_check) \ + APICFUNC(setup_apic_routing) \ APICFUNC(multi_timer_check) \ APICFUNC(apicid_to_node) \ APICFUNC(cpu_to_logical_apicid) \
include/asm-i386/mach-bigsmp/mach_apic.h +1 -1
@@ -71,7 +71,7 @@ static inline void init_apic_ldr(void)apic_write_around (APIC_LDR , val); } -static inline void clustered_apic_check (void ) +static inline void setup_apic_routing (void ) {printk ("Enabling APIC mode: %s. Using %d I/O APICs\n" ,"Physflat" , nr_ioapics);
include/asm-i386/mach-default/mach_apic.h +1 -1
@@ -54,7 +54,7 @@ static inline physid_mask_t ioapic_phys_return phys_map; } -static inline void clustered_apic_check (void ) +static inline void setup_apic_routing (void ) {printk ("Enabling APIC mode: %s. Using %d I/O APICs\n" ,"Flat" , nr_ioapics);
include/asm-i386/mach-es7000/mach_apic.h +1 -1
@@ -81,7 +81,7 @@ static inline void enable_apic_mode(void }extern int apic_version [MAX_APICS ]; -static inline void clustered_apic_check (void ) +static inline void setup_apic_routing (void ) {int apic = bios_cpu_apicid[smp_processor_id ()]; printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
include/asm-i386/mach-generic/mach_apic.h +1 -1
@@ -13,7 +13,7 @@#define apic_id_registered (genapic->apic_id_registered)#define init_apic_ldr (genapic->init_apic_ldr)#define ioapic_phys_id_map (genapic->ioapic_phys_id_map) -#define clustered_apic_check (genapic->clustered_apic_check) +#define setup_apic_routing (genapic->setup_apic_routing)#define multi_timer_check (genapic->multi_timer_check)#define apicid_to_node (genapic->apicid_to_node)#define cpu_to_logical_apicid (genapic->cpu_to_logical_apicid)
include/asm-i386/mach-numaq/mach_apic.h +1 -1
@@ -34,7 +34,7 @@ static inline void init_apic_ldr(void)/* Already done in NUMA-Q firmware */ } -static inline void clustered_apic_check (void ) +static inline void setup_apic_routing (void ) {printk ("Enabling APIC mode: %s. Using %d I/O APICs\n" ,"NUMA-Q" , nr_ioapics);
include/asm-i386/mach-summit/mach_apic.h +1 -1
@@ -80,7 +80,7 @@ static inline int apic_id_registered(voireturn 1 ; } -static inline void clustered_apic_check (void ) +static inline void setup_apic_routing (void ) {printk ("Enabling APIC mode: Summit. Using %d I/O APICs\n" , nr_ioapics);
include/asm-i386/mach-visws/mach_apic.h +1 -1
@@ -47,7 +47,7 @@ static inline void summit_check(char *oe { } -static inline void clustered_apic_check (void ) +static inline void setup_apic_routing (void ) { }
include/asm-x86_64/apic.h +1 -1
@@ -83,7 +83,7 @@ extern void setup_secondary_APIC_clock (extern int APIC_init_uniprocessor (void );extern void disable_APIC_timer (void );extern void enable_APIC_timer (void ); -extern void clustered_apic_check (void ); +extern void setup_apic_routing (void );extern void setup_APIC_extened_lvt (unsigned char lvt_off,unsigned char vector,unsigned char msg_type,unsigned char mask);
PATCH 8/35 x86_64: a memcpy that tries to reduce cache pressure
In reply to Andi KleenFrom: "Bryan O'Sullivan" <[email protected]>
This copy routine is memcpy-compatible, but on some architectures will use cache-bypassing loads to avoid bringing the source data into the cache.
One case where this is useful is when a device issues a DMA to a memory region, and the CPU must copy the DMAed data elsewhere before doing any work with it. Since the source data is read-once, write-never from the CPU's perspective, caching the data at those addresses can only evict potentially useful data.
We provide an x86_64 implementation that uses SSE non-temporal loads, and a generic version that falls back to plain memcpy.
Implementors for other arches should not use cache-bypassing stores to the destination, as in most cases, the destination is accessed almost immediately after a copy finishes.
---
arch/x86_64/kernel/x8664_ksyms.c | 2 arch/x86_64/lib/Makefile | 1 arch/x86_64/lib/memcpy_uncached_read.S | 142 +++++++++++++++++++++++++++++++++ include/asm-x86_64/string.h | 2 include/linux/string.h | 3 5 files changed, 150 insertions(+)
arch/x86_64/kernel/x8664_ksyms.c +2 -0
@@ -8,6 +8,7 @@#include <asm/processor.h> #include <asm/uaccess.h> #include <asm/pgtable.h> +#include <asm/string.h> EXPORT_SYMBOL (kernel_thread);
@@ -54,6 +55,7 @@ extern void * __memcpy(void *,const voidEXPORT_SYMBOL (memset);EXPORT_SYMBOL (memcpy);EXPORT_SYMBOL (__memcpy); +EXPORT_SYMBOL (memcpy_uncached_read);EXPORT_SYMBOL (empty_zero_page);EXPORT_SYMBOL (init_level4_pgt);
arch/x86_64/lib/Makefile +1 -0
@@ -11,3 +11,4 @@ lib-y := csum-partial.o csum-copy.o csum usercopy.o getuser.o putuser.o \ thunk.o clear_page.o copy_page.o bitstr.o bitops.o lib-y += memcpy.o memmove.o memset.o copy_user.o rwlock.o copy_user_nocache.o +lib-y += memcpy_uncached_read.o
arch/x86_64/lib/memcpy_uncached_read.S new file +142 -0
142 lines not on this page · raw message
include/asm-x86_64/string.h +2 -0
@@ -39,6 +39,8 @@ extern void *__memcpy(void *to, const vo __ret =__builtin_memcpy ((dst),(src),__len); \ __ret; }) +extern void *memcpy_uncached_read (void *to,const void *from,size_t len); +#define memcpy_uncached_read memcpy_uncached_read#define __HAVE_ARCH_MEMSETvoid *memset (void *s,int c,size_t n);
include/linux/string.h +3 -0
@@ -85,6 +85,9 @@ extern void * memset(void *,int,__kernel#ifndef __HAVE_ARCH_MEMCPYextern void *memcpy (void *,const void *,__kernel_size_t );#endif +#ifndef memcpy_uncached_read +#define memcpy_uncached_read (dest, src, count) memcpy((dest), (src), (count)) +#endif #ifndef __HAVE_ARCH_MEMMOVEextern void *memmove (void *,const void *,__kernel_size_t );#endif
PATCH 12/35 x86: consolidate smp_send_stop()
In reply to Andi KleenFrom: "Jan Beulich" <[email protected]>
Synchronize i386's smp_send_stop() with x86-64's in only try-locking the call lock to prevent deadlocks when called from panic(). In both version, disable interrupts before clearing the CPU off the online map to eliminate races with IRQ handlers inspecting this map. Also in both versions, save/restore interrupts rather than disabling/ enabling them.
On x86-64, eliminate one function used here by folding it into its single caller, convert to static, and rename for consistency with i386 (lkcd may like this).
--- arch/i386/kernel/smp.c | 70 ++++++++++++++++++++++++++--------------------- arch/x86_64/kernel/smp.c | 28 ++++++------------ include/asm-x86_64/smp.h | 1 3 files changed, 49 insertions(+), 50 deletions(-)
arch/i386/kernel/smp.c +39 -31
@@ -515,35 +515,14 @@ void unlock_ipi_call_lock(void)static struct call_data_struct *call_data; -/** -* smp_call_function(): Run a function on all other CPUs. -* @func: The function to run. This must be fast and non-blocking. -* @info: An arbitrary pointer to pass to the function. -* @nonatomic: currently unused. -* @wait: If true, wait (atomically) until function has completed on other CPUs. -* -* Returns 0 on success, else a negative status code. Does not return until -* remote CPUs are nearly ready to execute <<func>> or are or have executed. -* -* You must not call this function with disabled interrupts or from a -* hardware interrupt handler or from a bottom half handler. -*/ -int smp_call_function (void (*func) (void *info),void *info,int nonatomic, -int wait) +static void __smp_call_function (void (*func) (void *info),void *info, +int nonatomic,int wait) {struct call_data_struct data; -int cpus; +int cpus =num_online_cpus () -1 ; -/* Holding any lock stops cpus from going down. */ -spin_lock (&call_lock); - cpus =num_online_cpus () -1 ; -if (!cpus) { -spin_unlock (&call_lock); -return 0 ; - } - -/* Can deadlock when called with interrupts disabled */ -WARN_ON (irqs_disabled ()); +if (!cpus) +return ; data.func = func; data.info = info;
@@ -565,6 +544,30 @@ int smp_call_function (void (*func) (voiif (wait)while (atomic_read (&data.finished) != cpus)cpu_relax (); +} + +/** +* smp_call_function(): Run a function on all other CPUs. +* @func: The function to run. This must be fast and non-blocking. +* @info: An arbitrary pointer to pass to the function. +* @nonatomic: currently unused. +* @wait: If true, wait (atomically) until function has completed on other CPUs. +* +* Returns 0 on success, else a negative status code. Does not return until +* remote CPUs are nearly ready to execute <<func>> or are or have executed. +* +* You must not call this function with disabled interrupts or from a +* hardware interrupt handler or from a bottom half handler. +*/ +int smp_call_function (void (*func) (void *info),void *info,int nonatomic, +int wait) +{ +/* Can deadlock when called with interrupts disabled */ +WARN_ON (irqs_disabled ()); + +/* Holding any lock stops cpus from going down. */ +spin_lock (&call_lock); +__smp_call_function (func, info, nonatomic, wait);spin_unlock (&call_lock);return 0 ;
@@ -573,11 +576,11 @@ EXPORT_SYMBOL(smp_call_function);static void stop_this_cpu (void * dummy) { +local_irq_disable ();/* * Remove this CPU: */ cpu_clear (smp_processor_id (), cpu_online_map); -local_irq_disable ();disable_local_APIC ();if (cpu_data[smp_processor_id ()].hlt_works_ok)for (;;)halt ();
@@ -590,11 +593,16 @@ static void stop_this_cpu (void * dummy)void smp_send_stop (void ) { -smp_call_function (stop_this_cpu,NULL ,1 ,0 ); - -local_irq_disable (); +/* Don't deadlock on the call lock in panic */ +int nolock = !spin_trylock (&call_lock); +unsigned long flags; + +local_irq_save (flags); +__smp_call_function (stop_this_cpu,NULL ,0 ,0 ); +if (!nolock) +spin_unlock (&call_lock);disable_local_APIC (); -local_irq_enable (); +local_irq_restore (flags); }/*
arch/x86_64/kernel/smp.c +10 -18
@@ -452,42 +452,34 @@ int smp_call_function (void (*func) (voi }EXPORT_SYMBOL (smp_call_function); -void smp_stop_cpu (void ) +static void stop_this_cpu (void *dummy) { -unsigned long flags; +local_irq_disable ();/* * Remove this CPU: */ cpu_clear (smp_processor_id (), cpu_online_map); -local_irq_save (flags);disable_local_APIC (); -local_irq_restore (flags); -} - -static void smp_really_stop_cpu (void *dummy) -{ -smp_stop_cpu ();for (;;)halt (); }void smp_send_stop (void ) { -int nolock =0 ; +int nolock; +unsigned long flags; +if (reboot_force)return ; +/* Don't deadlock on the call lock in panic */ -if (!spin_trylock (&call_lock)) { -/* ignore locking because we have panicked anyways */ - nolock =1 ; - } -__smp_call_function (smp_really_stop_cpu,NULL ,0 ,0 ); + nolock = !spin_trylock (&call_lock); +local_irq_save (flags); +__smp_call_function (stop_this_cpu,NULL ,0 ,0 );if (!nolock)spin_unlock (&call_lock); - -local_irq_disable ();disable_local_APIC (); -local_irq_enable (); +local_irq_restore (flags); }/*
include/asm-x86_64/smp.h +0 -1
@@ -37,7 +37,6 @@ 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); -void smp_stop_cpu (void );extern cpumask_t cpu_sibling_map[NR_CPUS ];extern cpumask_t cpu_core_map[NR_CPUS ];
PATCH 3/35 x86: revert x86_64-mm-fix-the-irqbalance-quirk-for-e7320-e7520-e7525
In reply to Andi KleenFrom: Andrew Morton <[email protected]>
Obsoleted by Ingo's genapic stuff.
---
arch/i386/kernel/acpi/earlyquirk.c | 21 ---------------- arch/i386/kernel/quirks.c | 46 ++++++++----------------------------- arch/i386/kernel/smpboot.c | 6 ---- arch/x86_64/kernel/early-quirks.c | 13 ---------- arch/x86_64/kernel/smpboot.c | 8 ------ include/asm-i386/genapic.h | 2 - include/asm-i386/irq.h | 2 - include/asm-x86_64/proto.h | 1 8 files changed, 12 insertions(+), 87 deletions(-)
arch/i386/kernel/acpi/earlyquirk.c +0 -21
@@ -10,7 +10,6 @@#include <asm/pci-direct.h> #include <asm/acpi.h> #include <asm/apic.h> -#include <asm/irq.h> #ifdef CONFIG_ACPI
@@ -45,24 +44,6 @@ static int __init check_bridge(int vendoreturn 0 ; } -static void check_intel (void ) -{ -u16 vendor, device; - - vendor =read_pci_config_16 (0 ,0 ,0 ,PCI_VENDOR_ID ); - -if (vendor !=PCI_VENDOR_ID_INTEL ) -return ; - - device =read_pci_config_16 (0 ,0 ,0 ,PCI_DEVICE_ID ); -#ifdef CONFIG_SMP -if (device ==PCI_DEVICE_ID_INTEL_E7320_MCH || - device ==PCI_DEVICE_ID_INTEL_E7520_MCH || - device ==PCI_DEVICE_ID_INTEL_E7525_MCH ) -quirk_intel_irqbalance (); -#endif -} -void __init check_acpi_pci (void ) {int num, slot, func;
@@ -74,8 +55,6 @@ void __init check_acpi_pci(void)if (!early_pci_allowed ())return ; -check_intel (); -/* Poor man's PCI discovery */ for (num =0 ; num <32 ; num++) {for (slot =0 ; slot <32 ; slot++) {
arch/i386/kernel/quirks.c +11 -35
76 lines not on this page · raw message
arch/i386/kernel/smpboot.c +0 -6
@@ -54,7 +54,6 @@#include <asm/arch_hooks.h> #include <asm/nmi.h> #include <asm/pda.h> -#include <asm/genapic.h> #include <mach_apic.h> #include <mach_wakecpu.h>
@@ -1319,11 +1318,6 @@ int __cpuinit __cpu_up(unsigned int cpu)touch_nmi_watchdog (); } -#ifdef CONFIG_X86_GENERICARCH -if (num_online_cpus () >8 && genapic == &apic_default) -panic ("Default flat APIC routing can't be used with > 8 cpus\n" ); -#endif -return 0 ; }
arch/x86_64/kernel/early-quirks.c +0 -13
@@ -71,18 +71,6 @@ static void __init ati_bugs(void) } } -static void intel_bugs (void ) -{ -u16 device =read_pci_config_16 (0 ,0 ,0 ,PCI_DEVICE_ID ); - -#ifdef CONFIG_SMP -if (device ==PCI_DEVICE_ID_INTEL_E7320_MCH || - device ==PCI_DEVICE_ID_INTEL_E7520_MCH || - device ==PCI_DEVICE_ID_INTEL_E7525_MCH ) -quirk_intel_irqbalance (); -#endif -} -struct chipset {u16 vendor;void (*f)(void );
@@ -92,7 +80,6 @@ static struct chipset early_qrk[] __init { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, - { PCI_VENDOR_ID_INTEL, intel_bugs}, {} };
arch/x86_64/kernel/smpboot.c +0 -8
@@ -60,7 +60,6 @@#include <asm/irq.h> #include <asm/hw_irq.h> #include <asm/numa.h> -#include <asm/genapic.h> /* Number of siblings per CPU package */ int smp_num_siblings =1 ;
@@ -965,13 +964,6 @@ int __cpuinit __cpu_up(unsigned int cpu)while (!cpu_isset (cpu, cpu_online_map))cpu_relax (); - -if (num_online_cpus () >8 && genapic == &apic_flat) { -printk (KERN_WARNING -"flat APIC routing can't be used with > 8 cpus\n" ); -BUG (); - } - err =0 ;return err;
include/asm-i386/genapic.h +1 -1
@@ -122,6 +122,6 @@ struct genapic {APICFUNC (phys_pkg_id) \ } -extern struct genapic *genapic, apic_default; +extern struct genapic *genapic;#endif
include/asm-i386/irq.h +0 -2
@@ -37,8 +37,6 @@ static __inline__ int irq_canonicalize(iextern int irqbalance_disable (char *str);#endif -extern void quirk_intel_irqbalance (void ); -#ifdef CONFIG_HOTPLUG_CPU extern void fixup_irqs (cpumask_t map);#endif
include/asm-x86_64/proto.h +0 -1
@@ -82,7 +82,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 quirk_intel_irqbalance (void );extern void check_efer (void );extern int unhandled_signal (struct task_struct *tsk,int sig);
PATCH 15/35 i386: pit_latch_buggy has no effect
In reply to Andi KleenFrom: takada <[email protected]>
Eliminated the arch/i386/kernel/timers in 2.6.18, use clocksoures instead. pit_latch_buggy was referred in timers/timer_tsc.c, and currently removed. Therefore nobody refer it.
Until 2.6.17, MediaGX's TSC works correctly. after 2.6.18, warned "TSC appears to be running slowly. Marking it as unstable". So marked unstable TSC when CS55x0.
---
arch/i386/kernel/cpu/cyrix.c | 2 +- arch/i386/kernel/time.c | 2 -- include/asm-i386/timer.h | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-)
arch/i386/kernel/cpu/cyrix.c +1 -1
@@ -279,7 +279,7 @@ static void __cpuinit init_cyrix(struct*/ if (vendor ==PCI_VENDOR_ID_CYRIX && (device ==PCI_DEVICE_ID_CYRIX_5510 || device ==PCI_DEVICE_ID_CYRIX_5520 )) - pit_latch_buggy = 1; + mark_tsc_unstable(); }#endif c->x86_cache_size=16 ;/* Yep 16K integrated cache thats it */
arch/i386/kernel/time.c +0 -2
@@ -70,8 +70,6 @@#include <asm/i8259.h> -int pit_latch_buggy;/* extern */ -#include "do_timer.h" unsigned int cpu_khz;/* Detected as we calibrate the TSC */
include/asm-i386/timer.h +0 -2
@@ -9,8 +9,6 @@ void setup_pit_timer(void);unsigned long long native_sched_clock (void );unsigned long native_calculate_cpu_khz (void ); -/* Modifiers for buggy PIT handling */ -extern int pit_latch_buggy;extern int timer_ack;extern int no_timer_check;extern int no_sync_cmos_clock;
PATCH 14/35 i386: mtrr range check correction
In reply to Andi KleenFrom: "Jan Beulich" <[email protected]>
Whether a region is below 1Mb is determined by its start rather than its end.
This hunk got erroneously dropped from a previous patch.
---
arch/i386/kernel/cpu/mtrr/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/i386/kernel/cpu/mtrr/generic.c +1 -1
@@ -428,7 +428,7 @@ int generic_validate_add_page(unsigned l } } -if (base + size <0x100 ) { +if (base <0x100 ) {printk (KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n" , base, size);return -EINVAL ;
PATCH 4/35 x86_64: optimize & fix APIC mode setup
In reply to Andi KleenFrom: Ingo Molnar <[email protected]>
Fix a couple of inconsistencies/problems I found while reviewing the x86_64 genapic code (when I was chasing mysterious eth0 timeouts that would only trigger if CPU_HOTPLUG is enabled):
- AMD systems defaulted to the slower flat-physical mode instead of the flat-logical mode. The only restriction on AMD systems is that they should not use clustered APIC mode.
- removed the CPU hotplug hacks, switching the default for small systems back from phys-flat to logical-flat. The switching to logical flat mode on small systems fixed sporadic ethernet driver timeouts i was getting on a dual-core Athlon64 system:
NETDEV WATCHDOG: eth0: transmit timed out
eth0: Transmit timeout, status 0c 0005 c07f media 80.
eth0: Tx queue start entry 32 dirty entry 28.
eth0: Tx descriptor 0 is 0008a04a. (queue head)
eth0: Tx descriptor 1 is 0008a04a.
eth0: Tx descriptor 2 is 0008a04a.
eth0: Tx descriptor 3 is 0008a04a.
eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
- The use of '<= 8' was a bug by itself (the valid APIC ids for logical flat mode go from 0 to 7, not 0 to 8). The new logic is to use logical flat mode on both AMD and Intel systems, and to only switch to physical mode when logical mode cannot be used. If CPU hotplug is racy wrt. APIC shutdown then CPU hotplug needs fixing, not the whole IRQ system be made inconsistent and slowed down.
- minor cleanups: simplified some code constructs
build & booted on a couple of AMD and Intel SMP systems.
---
arch/x86_64/kernel/genapic.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-)
arch/x86_64/kernel/genapic.c +15 -24
@@ -32,21 +32,20 @@ extern struct genapic apic_cluster;extern struct genapic apic_flat;extern struct genapic apic_physflat; -struct genapic *genapic = &apic_flat; - +struct genapic __read_mostly *genapic = &apic_flat;/* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. */ void __init clustered_apic_check (void ) { -long i; +int i;u8 clusters, max_cluster;u8 id;u8 cluster_cnt[NUM_APIC_CLUSTERS ];int max_apic =0 ; -#if defined(CONFIG_ACPI ) +#ifdef CONFIG_ACPI /* * Some x86_64 machines use physical APIC mode regardless of how many * procs/clusters are present (x86_64 ES7000 is an example).
@@ -68,20 +67,17 @@ void __init clustered_apic_check(void) cluster_cnt[APIC_CLUSTERID (id)]++; } -/* Don't use clustered mode on AMD platforms. */ +/* +* Don't use clustered mode on AMD platforms, default +* to flat logical mode. +*/ if (boot_cpu_data.x86_vendor ==X86_VENDOR_AMD ) { - genapic = &apic_physflat; -#ifndef CONFIG_HOTPLUG_CPU -/* In the CPU hotplug case we cannot use broadcast mode -because that opens a race when a CPU is removed. -Stay at physflat mode in this case. -It is bad to do this unconditionally though. Once -we have ACPI platform support for CPU hotplug -we should detect hotplug capablity from ACPI tables and -only do this when really needed. -AK */ -if (max_apic <=8 ) - genapic = &apic_flat; -#endif +/* +* Switch to physical flat mode if more than 8 APICs +* (In the case of 8 CPUs APIC ID goes from 0 to 7): +*/ +if (max_apic >=8 ) + genapic = &apic_physflat; goto print; }
@@ -103,14 +99,9 @@ void __init clustered_apic_check(void)* (We don't use lowest priority delivery + HW APIC IRQ steering, so * can ignore the clustered logical case and go straight to physical.) */ -if (clusters <=1 && max_cluster <=8 && cluster_cnt[0 ] == max_cluster) { -#ifdef CONFIG_HOTPLUG_CPU -/* Don't use APIC shortcuts in CPU hotplug to avoid races */ - genapic = &apic_physflat; -#else +if (clusters <=1 && max_cluster <=8 && cluster_cnt[0 ] == max_cluster) genapic = &apic_flat; -#endif - }else +else genapic = &apic_cluster; print:
PATCH 5/35 x86_64: always use physical delivery mode on > 8 CPUs
In reply to Andi KleenFrom: Ingo Molnar <[email protected]>
Remove clustered APIC mode. There's little point in the use of clustered APIC mode, broadcasting is limited to within the cluster only, and chipsets have bugs in this area as well. So default to physical APIC mode when the CPU count is large, and default to logical APIC mode when the CPU count is 8 or smaller.
(this patch only removes the use of genapic_cluster and cleans up the resulting genapic.c file - removal of all remaining traces of clustered mode will be done by another patch.)
---
arch/x86_64/kernel/genapic.c | 71 +++++++++---------------------------------- include/asm-x86_64/genapic.h | 4 +- 2 files changed, 18 insertions(+), 57 deletions(-)
arch/x86_64/kernel/genapic.c +15 -56
@@ -11,26 +11,24 @@#include <linux/threads.h> #include <linux/cpumask.h> #include <linux/string.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/ctype.h> #include <linux/init.h> -#include <linux/module.h> #include <asm/smp.h> #include <asm/ipi.h> -#if defined(CONFIG_ACPI ) +#ifdef CONFIG_ACPI #include <acpi/acpi_bus.h> #endif /* which logical CPU number maps to which CPU (physical APIC ID) */ -u8 x86_cpu_to_apicid[NR_CPUS ]__read_mostly = { [0 ...NR_CPUS -1 ] =BAD_APICID }; +u8 x86_cpu_to_apicid[NR_CPUS ]__read_mostly + = { [0 ...NR_CPUS -1 ] =BAD_APICID };EXPORT_SYMBOL (x86_cpu_to_apicid); -u8 x86_cpu_to_log_apicid[NR_CPUS ] = { [0 ...NR_CPUS -1 ] =BAD_APICID }; -extern struct genapic apic_cluster; -extern struct genapic apic_flat; -extern struct genapic apic_physflat; +u8 x86_cpu_to_log_apicid[NR_CPUS ] = { [0 ...NR_CPUS -1 ] =BAD_APICID };struct genapic __read_mostly *genapic = &apic_flat;
@@ -39,76 +37,37 @@ struct genapic __read_mostly *genapic =*/ void __init clustered_apic_check (void ) { -int i; -u8 clusters, max_cluster; +unsigned int i, max_apic =0 ;u8 id; -u8 cluster_cnt[NUM_APIC_CLUSTERS ]; -int max_apic =0 ;#ifdef CONFIG_ACPI /* -* Some x86_64 machines use physical APIC mode regardless of how many -* procs/clusters are present (x86_64 ES7000 is an example). +* Quirk: some x86_64 machines can only use physical APIC mode +* regardless of how many processors are present (x86_64 ES7000 +* is an example). */ -if (acpi_gbl_FADT.header.revision >FADT2_REVISION_ID ) -if (acpi_gbl_FADT.flags &ACPI_FADT_APIC_PHYSICAL ) { - genapic = &apic_cluster; - goto print; - } +if (acpi_gbl_FADT.header.revision >FADT2_REVISION_ID && + (acpi_gbl_FADT.flags &ACPI_FADT_APIC_PHYSICAL )) + genapic = &apic_physflat;#endif -memset (cluster_cnt,0 ,sizeof (cluster_cnt));for (i =0 ; i <NR_CPUS ; i++) { id = bios_cpu_apicid[i];if (id ==BAD_APICID )continue ;if (id > max_apic) max_apic = id; - cluster_cnt[APIC_CLUSTERID (id)]++; } -/* -* Don't use clustered mode on AMD platforms, default -* to flat logical mode. -*/ -if (boot_cpu_data.x86_vendor ==X86_VENDOR_AMD ) { -/* -* Switch to physical flat mode if more than 8 APICs -* (In the case of 8 CPUs APIC ID goes from 0 to 7): -*/ -if (max_apic >=8 ) - genapic = &apic_physflat; - goto print; - } - - clusters =0 ; - max_cluster =0 ; - -for (i =0 ; i <NUM_APIC_CLUSTERS ; i++) { -if (cluster_cnt[i] >0 ) { - ++clusters; -if (cluster_cnt[i] > max_cluster) - max_cluster = cluster_cnt[i]; - } - } - -/* -* If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode, -* else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical -* else physical mode. -* (We don't use lowest priority delivery + HW APIC IRQ steering, so -* can ignore the clustered logical case and go straight to physical.) -*/ -if (clusters <=1 && max_cluster <=8 && cluster_cnt[0 ] == max_cluster) +if (max_apic <8 ) genapic = &apic_flat;else - genapic = &apic_cluster; + genapic = &apic_physflat; -print:printk (KERN_INFO "Setting APIC routing to %s\n" , genapic->name); } -/* Same for both flat and clustered. */ +/* Same for both flat and physical. */ void send_IPI_self (int vector) {
include/asm-x86_64/genapic.h +3 -1
@@ -29,7 +29,9 @@ struct genapic { unsigned int (*phys_pkg_id)(int index_msb); }; -extern struct genapic *genapic; +extern struct genapic apic_flat; +extern struct genapic apic_physflat; +#endif
PATCH 10/35 x86: adjust inclusion of asm/fixmap.h
In reply to Andi KleenFrom: "Jan Beulich" <[email protected]>
Move inclusion of asm/fixmap.h to where it is really used rather than where it may have been used long ago (requires a few other adjustments to includes due to previous implicit dependencies).
--- arch/x86_64/kernel/genapic.c | 1 + arch/x86_64/kernel/genapic_flat.c | 1 + include/asm-i386/hpet.h | 2 -- include/asm-i386/kexec.h | 5 ----- include/asm-i386/pgalloc.h | 1 - include/asm-i386/smp.h | 7 ++----- include/asm-x86_64/ipi.h | 4 +--- include/asm-x86_64/pgalloc.h | 1 - include/asm-x86_64/pgtable.h | 1 - include/asm-x86_64/smp.h | 3 +-- 10 files changed, 6 insertions(+), 20 deletions(-)
arch/x86_64/kernel/genapic.c +1 -0
@@ -18,6 +18,7 @@#include <asm/smp.h> #include <asm/ipi.h> +#include <asm/genapic.h> #ifdef CONFIG_ACPI #include <acpi/acpi_bus.h>
arch/x86_64/kernel/genapic_flat.c +1 -0
@@ -16,6 +16,7 @@#include <linux/init.h> #include <asm/smp.h> #include <asm/ipi.h> +#include <asm/genapic.h> static cpumask_t flat_target_cpus (void ) {
include/asm-i386/hpet.h +0 -2
@@ -28,8 +28,6 @@#include <linux/timex.h> -#include <asm/fixmap.h> -/* * Documentation on HPET can be found at: * http://www.intel.com/ial/home/sp/pcmmspec.htm
include/asm-i386/kexec.h +0 -5
@@ -21,7 +21,6 @@#ifndef __ASSEMBLY__ -#include <asm/fixmap.h> #include <asm/ptrace.h> #include <asm/string.h>
@@ -29,10 +28,6 @@* 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. -* -* Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct -* calculation for the amount of memory directly mappable into the -* kernel memory space. */ /* Maximum physical address we can use pages from */
include/asm-i386/pgalloc.h +0 -1
@@ -1,7 +1,6 @@#ifndef _I386_PGALLOC_H#define _I386_PGALLOC_H -#include <asm/fixmap.h> #include <linux/threads.h> #include <linux/mm.h> /* for struct page */
include/asm-i386/smp.h +2 -5
@@ -11,16 +11,13 @@#include <asm/pda.h> #endif -#ifdef CONFIG_X86_LOCAL_APIC -#ifndef __ASSEMBLY__ -#include <asm/fixmap.h> +#if defined(CONFIG_X86_LOCAL_APIC ) && !defined(__ASSEMBLY__)#include <asm/bitops.h> #include <asm/mpspec.h> +#include <asm/apic.h> #ifdef CONFIG_X86_IO_APIC #include <asm/io_apic.h> #endif -#include <asm/apic.h> -#endif #endif #define BAD_APICID 0xFFu
include/asm-x86_64/ipi.h +1 -3
@@ -18,10 +18,8 @@* Subject to the GNU Public License, v.2 */ -#include <asm/fixmap.h> #include <asm/hw_irq.h> -#include <asm/apicdef.h> -#include <asm/genapic.h> +#include <asm/apic.h> /* * the following functions deal with sending IPIs between CPUs.
include/asm-x86_64/pgalloc.h +0 -1
@@ -1,7 +1,6 @@#ifndef _X86_64_PGALLOC_H#define _X86_64_PGALLOC_H -#include <asm/fixmap.h> #include <asm/pda.h> #include <linux/threads.h> #include <linux/mm.h>
include/asm-x86_64/pgtable.h +0 -1
@@ -6,7 +6,6 @@* the x86-64 page table tree. */ #include <asm/processor.h> -#include <asm/fixmap.h> #include <asm/bitops.h> #include <linux/threads.h> #include <asm/pda.h>
include/asm-x86_64/smp.h +1 -2
@@ -10,10 +10,9 @@#include <linux/init.h> extern int disable_apic; -#include <asm/fixmap.h> #include <asm/mpspec.h> -#include <asm/io_apic.h> #include <asm/apic.h> +#include <asm/io_apic.h> #include <asm/thread_info.h> #ifdef CONFIG_SMP
PATCH 9/35 i386: adjustments to page table dump during oops (v4)
In reply to Andi KleenFrom: "Jan Beulich" <[email protected]>
- make the page table contents printing PAE capable
- make sure the address stored in current->thread.cr2 is unmodified from what was read from CR2
- don't call oops_may_print() multiple times, when one time suffices
- print pte even in highpte case, as long as the pte page isn't in actually in high memory (which is specifically the case for all page tables covering kernel space)
(Changes to v3: Use sizeof()*2 rather than the suggested sizeof()*4 for printing width, use fixed 16-nibble width for PAE, and also apply the max_low_pfn range check to the middle level lookup on PAE.)
--- arch/i386/mm/fault.c | 55 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 20 deletions(-)
arch/i386/mm/fault.c +35 -20
@@ -20,6 +20,7 @@#include <linux/tty.h> #include <linux/vt_kern.h> /* For unblank_screen() */ #include <linux/highmem.h> +#include <linux/bootmem.h> /* for max_low_pfn */ #include <linux/module.h> #include <linux/kprobes.h> #include <linux/uaccess.h>
@@ -301,7 +302,6 @@ fastcall void __kprobes do_page_fault(ststruct mm_struct *mm;struct vm_area_struct * vma;unsigned long address; -unsigned long page;int write, si_code;/* get the address */
@@ -510,7 +510,9 @@ no_context:bust_spinlocks (1 );if (oops_may_print ()) { -#ifdef CONFIG_X86_PAE + __typeof__(pte_val(__pte(0))) page; + +#ifdef CONFIG_X86_PAE if (error_code &16 ) {pte_t *pte =lookup_address (address);
@@ -519,7 +521,7 @@ no_context:"NX-protected page - exploit attempt? " "(uid: %d)\n", current->uid); } -#endif +#endif if (address <PAGE_SIZE )printk (KERN_ALERT "BUG: unable to handle kernel NULL " "pointer dereference" );
@@ -529,25 +531,38 @@ no_context:printk (" at virtual address %08lx\n" ,address);printk (KERN_ALERT " printing eip:\n" );printk ("%08lx\n" , regs->eip); - } - page =read_cr3 (); - page = ((unsigned long *)__va (page))[address >>22 ]; -if (oops_may_print ()) + + page =read_cr3 (); + page = ((__typeof__ (page) *)__va (page))[address >>PGDIR_SHIFT ]; +#ifdef CONFIG_X86_PAE +printk (KERN_ALERT "*pdpt = %016Lx\n" , page); +if ((page >>PAGE_SHIFT ) < max_low_pfn + && page & _PAGE_PRESENT) { + page &=PAGE_MASK ; + page = ((__typeof__ (page) *)__va (page))[(address >>PMD_SHIFT ) + & (PTRS_PER_PMD -1 )]; +printk (KERN_ALERT "*pde = %016Lx\n" , page); + page &= ~_PAGE_NX; + } +#else printk (KERN_ALERT "*pde = %08lx\n" , page); -/* -* We must not directly access the pte in the highpte -* case, the page table might be allocated in highmem. -* And lets rather not kmap-atomic the pte, just in case -* it's allocated already. -*/ -#ifndef CONFIG_HIGHPTE -if ((page &1 ) &&oops_may_print ()) { - page &=PAGE_MASK ; - address &=0x003ff000 ; - page = ((unsigned long *)__va (page))[address >>PAGE_SHIFT ]; -printk (KERN_ALERT "*pte = %08lx\n" , page); - }#endif + +/* +* We must not directly access the pte in the highpte +* case if the page table is located in highmem. +* And let's rather not kmap-atomic the pte, just in case +* it's allocated already. +*/ +if ((page >>PAGE_SHIFT ) < max_low_pfn + && (page & _PAGE_PRESENT)) { + page &=PAGE_MASK ; + page = ((__typeof__ (page) *)__va (page))[(address >>PAGE_SHIFT ) + & (PTRS_PER_PTE -1 )]; +printk (KERN_ALERT "*pte = %0*Lx\n" ,sizeof (page)*2 , (u64 )page); + } + } + tsk->thread.cr2 = address; tsk->thread.trap_no =14 ; tsk->thread.error_code = error_code;
PATCH 11/35 x86_64: adjust inclusion of asm/vsyscall32.h
In reply to Andi KleenFrom: "Jan Beulich" <[email protected]>
Avoid including asm/vsyscall32.h in virtually every source file.
--- arch/x86_64/ia32/syscall32.c | 1 + include/asm-x86_64/fixmap.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-)
arch/x86_64/ia32/syscall32.c +1 -0
@@ -13,6 +13,7 @@#include <asm/proto.h> #include <asm/tlbflush.h> #include <asm/ia32_unistd.h> +#include <asm/vsyscall32.h> extern unsigned char syscall32_syscall[], syscall32_syscall_end[];extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
include/asm-x86_64/fixmap.h +0 -1
@@ -15,7 +15,6 @@#include <asm/apicdef.h> #include <asm/page.h> #include <asm/vsyscall.h> -#include <asm/vsyscall32.h> /* * Here we define all the compile-time 'special' virtual
PATCH 1/35 i386: revert i386-fix-the-verify_quirk_intel_irqbalance
In reply to Andi KleenFrom: Andrew Morton <[email protected]>
This is unneeded with Ingo's genapic rework.
---
arch/i386/kernel/quirks.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-)
arch/i386/kernel/quirks.c +4 -29
@@ -10,38 +10,13 @@#if defined(CONFIG_X86_IO_APIC ) && defined(CONFIG_SMP ) && defined(CONFIG_PCI )static void __devinit verify_quirk_intel_irqbalance (struct pci_dev *dev) { -u8 config, rev; -u32 word; - -/* BIOS may enable hardware IRQ balancing for -* E7520/E7320/E7525(revision ID 0x9 and below) -* based platforms. -* For those platforms, make sure that the genapic is set to 'flat' -*/ -pci_read_config_byte (dev,PCI_CLASS_REVISION , &rev); -if (rev >0x9 ) -return ; - -/* enable access to config space*/ -pci_read_config_byte (dev,0xf4 , &config); -pci_write_config_byte (dev,0xf4 , config|0x2 ); - -/* read xTPR register */ - raw_pci_ops->read (0 ,0 ,0x40 ,0x4c ,2 , &word); - -if (!(word & (1 <<13 ))) {#ifdef CONFIG_X86_64 -if (genapic != &apic_flat) -panic ("APIC mode must be flat on this system\n" ); +if (genapic != &apic_flat) +panic ("APIC mode must be flat on this system\n" );#elif defined(CONFIG_X86_GENERICARCH ) -if (genapic != &apic_default) -panic ("APIC mode must be default(flat) on this system. Use apic=default\n" ); +if (genapic != &apic_default) +panic ("APIC mode must be default(flat) on this system. Use apic=default\n" );#endif - } - -/* put back the original value for config space*/ -if (!(config &0x2 )) -pci_write_config_byte (dev,0xf4 , config); }void __init quirk_intel_irqbalance (void )
Re: [PATCH] [16/35] i386: Add an option for the VIA C7 which sets appropriate L1 cache
In reply to Jeff GarzikQuoted 8 lines · Jeff Garzik
Quoted 7 lines · Andi Kleen
From: Simon Arlott <[email protected]>
The VIA C7 is a 686 (with TSC) that supports MMX, SSE and SSE2, it also has a cache line length of 64 according to
http://www.digit-life.com/articles2/cpu/rmma-via-c7.html. This patch sets gcc to -march=686 and select s the correct cache shift.
Quoted 8 lines
Quoted 6 lines
Signed-off-by Simon Arlott <[email protected]>Signed-off-by Andi Kleen <[email protected]>Cc Andi Kleen <[email protected]>Cc Dave Jones <[email protected]>Cc Alan Cox <[email protected]>Signed-off-by Andrew Morton <[email protected]>Has it been verified in the field that this CPU supports CMOV?
Yes. All their CPUs for some time now have done so.
Dave
Signature · 1 line
http://www.codemonkey.org.uk
Re: [patches] [PATCH] [8/35] x86_64: a memcpy that tries to reducecache pressure
In reply to Andi Kleenarch/x86_64/lib/memcpy_uncached_read.S line 42
Quoted 1 line
arch/x86_64/lib/memcpy_uncached_read.S new file +1
-0+ testb $8, %dxl /* rdx is 3,5,6,7,9..15 */
Could you use the more conventional name %dl (or whatever is being meant) here?
arch/x86_64/lib/memcpy_uncached_read.S line 89
Quoted 2 lines
+.L42:
arch/x86_64/lib/memcpy_uncached_read.S new file +1
-0+ prefetchnta 128(%rsi)
I think I commented similarly on a previous version of the patch: This will
- result in still bringing the first 128 bytes into the cache
- prevent caching of memory beyond the buffer being dealt with
arch/x86_64/lib/memcpy_uncached_read.S line 111
Quoted 1 line
arch/x86_64/lib/memcpy_uncached_read.S new file +1
-0+ sfence
Similarly, I continue to believe this is wrong here (again I commented before that this is likely unnecessary, or if at all, it should be an lfence).
arch/x86_64/lib/memcpy_uncached_read.S line 112
Quoted 1 line
arch/x86_64/lib/memcpy_uncached_read.S new file +1
-0+ orl %edx, %edx
Operations of this type generally should use 'test', not 'or' or 'and'.
Jan
Re: [patches] [PATCH] [8/35] x86_64: a memcpy that tries to reducecache pressure
Quoted 11 lines · On Monday 30 April 2007 09:26:05 Jan Beulich wrote:
arch/x86_64/lib/memcpy_uncached_read.S line 42
Quoted 1 line
arch/x86_64/lib/memcpy_uncached_read.S new file +1
-0+ testb $8, %dxl /* rdx is 3,5,6,7,9..15 */Could you use the more conventional name %dl (or whatever is being meant) here?
arch/x86_64/lib/memcpy_uncached_read.S line 89
Quoted 2 lines
+.L42:
arch/x86_64/lib/memcpy_uncached_read.S new file +1
-0+ prefetchnta 128(%rsi)I think I commented similarly on a previous version of the patch: This will
- result in still bringing the first 128 bytes into the cache
- prevent caching of memory beyond the buffer being dealt with
Yes I remember, somehow it got lost. I agree it's a bad thing. Will drop the patch for now especially since nothing seems to really need it right now.
Thanks,
-Andi
Re: [patches] [PATCH] [8/35] x86_64: a memcpy that tries to reducecache pressure
In reply to Bryan O'SullivanQuoted 6 lines · On Monday 30 April 2007 18:14:13 Bryan O'Sullivan wrote:
Quoted 2 lines · Andi Kleen
Yes I remember, somehow it got lost. I agree it's a bad thing. Will drop the patch for now especially since nothing seems to really need it right now.
It would be used by the ipath driver if it was around.
Please address the feedback from Jan then and I can remerge it then
-Andi
Re: [patches] [PATCH] [8/35] x86_64: a memcpy that tries to reducecache pressure
In reply to Andi KleenQuoted 2 lines · Andi Kleen
Yes I remember, somehow it got lost. I agree it's a bad thing. Will drop the patch for now especially since nothing seems to really need it right now.
It would be used by the ipath driver if it was around.
<b