From 41aefdcc98fdba47459eab67630293d67e855fc3 Mon Sep 17 00:00:00 2001 From: Max Asbock Date: Wed, 25 Jun 2008 14:45:28 -0700 Subject: [PATCH 1/4] x86: shift bits the right way in native_read_tscp native_read_tscp shifts the bits in the high order value in the wrong direction, the attached patch fixes that. Signed-off-by: Max Asbock Acked-by: Glauber Costa Signed-off-by: Ingo Molnar --- include/asm-x86/msr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 3707650a169b..2b5f2c91db25 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -18,7 +18,7 @@ static inline unsigned long long native_read_tscp(unsigned int *aux) unsigned long low, high; asm volatile(".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (*aux)); - return low | ((u64)high >> 32); + return low | ((u64)high << 32); } /* From 0b1faeef5f9243bb5fc5713a34bbf1ceab0de562 Mon Sep 17 00:00:00 2001 From: Daniel J Blueman Date: Sun, 15 Jun 2008 12:32:15 +0100 Subject: [PATCH 2/4] x86: section/warning fixes WARNING: arch/x86/mm/built-in.o(.text+0x3a1): Section mismatch in reference from the function set_pte_phys() to the function .init.text:spp_getpage() The function set_pte_phys() references the function __init spp_getpage(). This is often because set_pte_phys lacks a __init annotation or the annotation of spp_getpage is wrong. arch/x86/mm/init_64.c: In function 'early_memtest': arch/x86/mm/init_64.c:520: warning: passing argument 2 of 'find_e820_area_size' from incompatible pointer type Signed-off-by: Daniel J Blueman Cc: "Linus Torvalds" Signed-off-by: Ingo Molnar --- arch/x86/mm/init_64.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 156e6d7b0e32..f6d20be7a8f4 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -135,7 +135,7 @@ static __init void *spp_getpage(void) return ptr; } -static void +static __init void set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) { pgd_t *pgd; @@ -214,7 +214,7 @@ void __init cleanup_highmap(void) } /* NOTE: this is meant to be run only at boot */ -void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) +void __init __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) { unsigned long address = __fix_to_virt(idx); @@ -506,7 +506,7 @@ early_param("memtest", parse_memtest); static void __init early_memtest(unsigned long start, unsigned long end) { - u64 t_start, t_size; + unsigned long t_start, t_size; unsigned pattern; if (!memtest_pattern) @@ -525,7 +525,7 @@ static void __init early_memtest(unsigned long start, unsigned long end) if (t_start + t_size > end) t_size = end - t_start; - printk(KERN_CONT "\n %016llx - %016llx pattern %d", + printk(KERN_CONT "\n %016lx - %016lx pattern %d", t_start, t_start + t_size, pattern); memtest(t_start, t_size, pattern); From fcb43042ef55d2f46b0efa5d7746967cef38f056 Mon Sep 17 00:00:00 2001 From: "Zhang, Yanmin" Date: Tue, 24 Jun 2008 16:06:23 +0800 Subject: [PATCH 3/4] x86: fix cpu hotplug crash Vegard Nossum reported crashes during cpu hotplug tests: http://marc.info/?l=linux-kernel&m=121413950227884&w=4 In function _cpu_up, the panic happens when calling __raw_notifier_call_chain at the second time. Kernel doesn't panic when calling it at the first time. If just say because of nr_cpu_ids, that's not right. By checking the source code, I found that function do_boot_cpu is the culprit. Consider below call chain: _cpu_up=>__cpu_up=>smp_ops.cpu_up=>native_cpu_up=>do_boot_cpu. So do_boot_cpu is called in the end. In do_boot_cpu, if boot_error==true, cpu_clear(cpu, cpu_possible_map) is executed. So later on, when _cpu_up calls __raw_notifier_call_chain at the second time to report CPU_UP_CANCELED, because this cpu is already cleared from cpu_possible_map, get_cpu_sysdev returns NULL. Many resources are related to cpu_possible_map, so it's better not to change it. Below patch against 2.6.26-rc7 fixes it by removing the bit clearing in cpu_possible_map. Signed-off-by: Zhang Yanmin Tested-by: Vegard Nossum Acked-by: Rusty Russell Signed-off-by: Ingo Molnar --- arch/x86/kernel/smpboot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 56078d61c793..3e1cecedde42 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -996,7 +996,6 @@ do_rest: #endif cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */ cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ - cpu_clear(cpu, cpu_possible_map); cpu_clear(cpu, cpu_present_map); per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID; } From 11dbc963a8f6128595d0f6ecf138dc369e144997 Mon Sep 17 00:00:00 2001 From: TAKADA Yoshihito Date: Mon, 30 Jun 2008 13:44:45 +0900 Subject: [PATCH 4/4] ptrace GET/SET FPXREGS broken When I update kernel 2.6.25 from 2.6.24, gdb does not work. On 2.6.25, ptrace(PTRACE_GETFPXREGS, ...) returns ENODEV. But 2.6.24 kernel's ptrace() returns EIO. It is issue of compatibility. I attached test program as pt.c and patch for fix it. #include #include #include #include #include #include #include struct user_fxsr_struct { unsigned short cwd; unsigned short swd; unsigned short twd; unsigned short fop; long fip; long fcs; long foo; long fos; long mxcsr; long reserved; 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]; }; int main(void) { pid_t pid; pid = fork(); switch(pid){ case -1:/* error */ break; case 0:/* child */ child(); break; default: parent(pid); break; } return 0; } int child(void) { ptrace(PTRACE_TRACEME); kill(getpid(), SIGSTOP); sleep(10); return 0; } int parent(pid_t pid) { int ret; struct user_fxsr_struct fpxregs; ret = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpxregs); if(ret < 0){ printf("%d: %s.\n", errno, strerror(errno)); } kill(pid, SIGCONT); wait(pid); return 0; } /* in the kerel, at kernel/i387.c get_fpxregs() */ Signed-off-by: Ingo Molnar --- arch/x86/kernel/i387.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index eb9ddd8efb82..95e80e5033c3 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -162,7 +162,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, int ret; if (!cpu_has_fxsr) - return -ENODEV; + return -EIO; ret = init_fpu(target); if (ret) @@ -179,7 +179,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, int ret; if (!cpu_has_fxsr) - return -ENODEV; + return -EIO; ret = init_fpu(target); if (ret)