diff --git a/kernel.spec b/kernel.spec index 8d4aca75f..57843e0f9 100644 --- a/kernel.spec +++ b/kernel.spec @@ -705,6 +705,10 @@ Patch21013: Platform-fix-samsung-laptop-DMI-identification-for-N.patch Patch21014: block-Free-queue-resources-at-blk_release_queue.patch +# rhbz #700718 +Patch21015: x86-Save-stack-pointer-in-perf-live-regs-savings.patch +Patch21016: x86-Fetch-stack-from-regs-when-possible-in-dump_trac.patch + %endif BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -1279,6 +1283,10 @@ ApplyPatch Platform-fix-samsung-laptop-DMI-identification-for-N.patch ApplyPatch block-Free-queue-resources-at-blk_release_queue.patch +# rhbz #700718 +ApplyPatch x86-Save-stack-pointer-in-perf-live-regs-savings.patch +ApplyPatch x86-Fetch-stack-from-regs-when-possible-in-dump_trac.patch + # END OF PATCH APPLICATIONS %endif @@ -1899,7 +1907,10 @@ fi # and build. %changelog -* Wed Sep 28 2011 Josh Boyer 2.6.40.4-6 +* Thu Sep 29 2011 Josh Boyer +- Backport two upstream patches to fix rhbz 700718 + +* Wed Sep 28 2011 Josh Boyer - Backport upstream block patch to try and fix a number of oopses we're seeing with USB drive removals - Update usb-add-quirk-for-logitech-webcams.patch (rhbz 742010) diff --git a/x86-Fetch-stack-from-regs-when-possible-in-dump_trac.patch b/x86-Fetch-stack-from-regs-when-possible-in-dump_trac.patch new file mode 100644 index 000000000..bda767af8 --- /dev/null +++ b/x86-Fetch-stack-from-regs-when-possible-in-dump_trac.patch @@ -0,0 +1,86 @@ +From 47ce11a2b6519f9c7843223ea8e561eb71ea5896 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Thu, 30 Jun 2011 19:04:56 +0200 +Subject: [PATCH 2/2] x86: Fetch stack from regs when possible in dump_trace() + +When regs are passed to dump_stack(), we fetch the frame +pointer from the regs but the stack pointer is taken from +the current frame. + +Thus the frame and stack pointers may not come from the same +context. For example this can result in the unwinder to +think the context is in irq, due to the current value of +the stack, but the frame pointer coming from the regs points +to a frame from another place. It then tries to fix up +the irq link but ends up dereferencing a random frame +pointer that doesn't belong to the irq stack: + +[ 9131.706906] ------------[ cut here ]------------ +[ 9131.707003] WARNING: at arch/x86/kernel/dumpstack_64.c:129 dump_trace+0x2aa/0x330() +[ 9131.707003] Hardware name: AMD690VM-FMH +[ 9131.707003] Perf: bad frame pointer = 0000000000000005 in callchain +[ 9131.707003] Modules linked in: +[ 9131.707003] Pid: 1050, comm: perf Not tainted 3.0.0-rc3+ #181 +[ 9131.707003] Call Trace: +[ 9131.707003] [] warn_slowpath_common+0x7a/0xb0 +[ 9131.707003] [] warn_slowpath_fmt+0x41/0x50 +[ 9131.707003] [] ? bad_to_user+0x6d/0x10be +[ 9131.707003] [] dump_trace+0x2aa/0x330 +[ 9131.707003] [] ? native_sched_clock+0x13/0x50 +[ 9131.707003] [] perf_callchain_kernel+0x54/0x70 +[ 9131.707003] [] perf_prepare_sample+0x19f/0x2a0 +[ 9131.707003] [] __perf_event_overflow+0x16c/0x290 +[ 9131.707003] [] ? __perf_event_overflow+0x130/0x290 +[ 9131.707003] [] ? native_sched_clock+0x13/0x50 +[ 9131.707003] [] ? sched_clock+0x9/0x10 +[ 9131.707003] [] ? T.375+0x15/0x90 +[ 9131.707003] [] ? trace_hardirqs_on_caller+0x64/0x180 +[ 9131.707003] [] ? trace_hardirqs_off+0xd/0x10 +[ 9131.707003] [] perf_event_overflow+0x14/0x20 +[ 9131.707003] [] perf_swevent_hrtimer+0x11c/0x130 +[ 9131.707003] [] ? error_exit+0x51/0xb0 +[ 9131.707003] [] __run_hrtimer+0x83/0x1e0 +[ 9131.707003] [] ? perf_event_overflow+0x20/0x20 +[ 9131.707003] [] hrtimer_interrupt+0x106/0x250 +[ 9131.707003] [] ? trace_hardirqs_off_thunk+0x3a/0x3c +[ 9131.707003] [] smp_apic_timer_interrupt+0x53/0x90 +[ 9131.707003] [] apic_timer_interrupt+0x13/0x20 +[ 9131.707003] [] ? error_exit+0x51/0xb0 +[ 9131.707003] [] ? error_exit+0x4c/0xb0 +[ 9131.707003] ---[ end trace b2560d4876709347 ]--- + +Fix this by simply taking the stack pointer from regs->sp +when regs are provided. + +Signed-off-by: Frederic Weisbecker +Cc: Ingo Molnar +Cc: Thomas Gleixner +Cc: H. Peter Anvin +Cc: Peter Zijlstra +Cc: Arnaldo Carvalho de Melo +--- + arch/x86/kernel/dumpstack_64.c | 7 +++++-- + 1 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c +index e71c98d..788295c 100644 +--- a/arch/x86/kernel/dumpstack_64.c ++++ b/arch/x86/kernel/dumpstack_64.c +@@ -155,9 +155,12 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, + task = current; + + if (!stack) { +- stack = &dummy; +- if (task && task != current) ++ if (regs) ++ stack = (unsigned long *)regs->sp; ++ else if (task && task != current) + stack = (unsigned long *)task->thread.sp; ++ else ++ stack = &dummy; + } + + if (!bp) +-- +1.7.6 + diff --git a/x86-Save-stack-pointer-in-perf-live-regs-savings.patch b/x86-Save-stack-pointer-in-perf-live-regs-savings.patch new file mode 100644 index 000000000..3964f10e9 --- /dev/null +++ b/x86-Save-stack-pointer-in-perf-live-regs-savings.patch @@ -0,0 +1,38 @@ +From 9e46294dadedc0c04adcb8ce760bd2cd74f7332d Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Sat, 2 Jul 2011 15:00:52 +0200 +Subject: [PATCH 1/2] x86: Save stack pointer in perf live regs savings + +In order to prepare for fetching the stack pointer from the +regs when possible in dump_trace() instead of taking the +local one, save the current stack pointer in perf live regs saving. + +Signed-off-by: Frederic Weisbecker +Cc: Ingo Molnar +Cc: Thomas Gleixner +Cc: H. Peter Anvin +Cc: Peter Zijlstra +Cc: Arnaldo Carvalho de Melo +--- + arch/x86/include/asm/perf_event.h | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h +index d9d4dae..094fb30 100644 +--- a/arch/x86/include/asm/perf_event.h ++++ b/arch/x86/include/asm/perf_event.h +@@ -152,6 +152,11 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs); + (regs)->bp = caller_frame_pointer(); \ + (regs)->cs = __KERNEL_CS; \ + regs->flags = 0; \ ++ asm volatile( \ ++ _ASM_MOV "%%"_ASM_SP ", %0\n" \ ++ : "=m" ((regs)->sp) \ ++ :: "memory" \ ++ ); \ + } + + #else +-- +1.7.6 +