From dd40c05e07f8dd6365812c708cedf108da93e639 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Feb 12 2014 15:21:24 +0000 Subject: Fix backtrace in amd_e400_idle (rhbz 1031296) --- diff --git a/kernel.spec b/kernel.spec index 1040c7d..5dcdebf 100644 --- a/kernel.spec +++ b/kernel.spec @@ -753,6 +753,9 @@ Patch25187: xhci-fix-resume-issues-on-renesas-chips-in-samsung-laptops.patch #CVE-2014-1874 rhbz 1062356 1062507 Patch25188: SELinux-Fix-kernel-BUG-on-empty-security-contexts.patch +#rhbz 1031296 +Patch25189: tick-Clear-broadcast-pending-bit-when-switching-to-oneshot.patch + # END OF PATCH DEFINITIONS %endif @@ -1462,6 +1465,9 @@ ApplyPatch xhci-fix-resume-issues-on-renesas-chips-in-samsung-laptops.patch #CVE-2014-1874 rhbz 1062356 1062507 ApplyPatch SELinux-Fix-kernel-BUG-on-empty-security-contexts.patch +#rhbz 1031296 +ApplyPatch tick-Clear-broadcast-pending-bit-when-switching-to-oneshot.patch + # END OF PATCH APPLICATIONS %endif @@ -2274,6 +2280,7 @@ fi # || || %changelog * Wed Feb 12 2014 Josh Boyer +- Fix backtrace in amd_e400_idle (rhbz 1031296) - CVE-2014-1874 SELinux: local denial of service (rhbz 1062356 1062507) * Wed Feb 12 2014 Justin M. Forbes - 3.13.2-200 diff --git a/tick-Clear-broadcast-pending-bit-when-switching-to-oneshot.patch b/tick-Clear-broadcast-pending-bit-when-switching-to-oneshot.patch new file mode 100644 index 0000000..a0d58cf --- /dev/null +++ b/tick-Clear-broadcast-pending-bit-when-switching-to-oneshot.patch @@ -0,0 +1,88 @@ +On Mon, 10 Feb 2014, Thomas Gleixner wrote: +> On Mon, 10 Feb 2014, poma wrote: +> +> > [ 83.558551] [] amd_e400_idle+0x87/0x130 +> +> So this seems to happen only on AMD machines which use that e400 idle +> mode. I have no idea at the moment whats wrong there. I'll find one of +> those machines and try to reproduce. + +Found it. Patch below. + +Thanks, + + tglx +---- +Subject: tick: Clear broadcast pending bit when switching to oneshot +From: Thomas Gleixner +Date: Tue, 11 Feb 2014 14:35:40 +0100 + +AMD systems which use the C1E workaround in the amd_e400_idle routine +trigger the WARN_ON_ONCE in the broadcast code when onlining a CPU. + +The reason is that the idle routine of those AMD systems switches the +cpu into forced broadcast mode early on before the newly brought up +CPU can switch over to high resolution / NOHZ mode. The timer related +CPU1 bringup looks like this: + + clockevent_register_device(local_apic); + tick_setup(local_apic); + ... + idle() + tick_broadcast_on_off(FORCE); + tick_broadcast_oneshot_control(ENTER) + cpumask_set(cpu, broadcast_oneshot_mask); + halt(); + +Now the broadcast interrupt on CPU0 sets CPU1 in the +broadcast_pending_mask and wakes CPU1. So CPU1 continues: + + local_apic_timer_interrupt() + tick_handle_periodic(); + softirq() + tick_init_highres(); + cpumask_clr(cpu, broadcast_oneshot_mask); + + tick_broadcast_oneshot_control(ENTER) + WARN_ON(cpumask_test(cpu, broadcast_pending_mask); + +So while we remove CPU1 from the broadcast_oneshot_mask when we switch +over to highres mode, we do not clear the pending bit, which then +triggers the warning when we go back to idle. + +The reason why this is only visible on C1E affected AMD systems is +that the other machines enter the deep sleep states via +acpi_idle/intel_idle and exit the broadcast mode before executing the +remote triggered local_apic_timer_interrupt. So the pending bit is +already cleared when the switch over to highres mode is clearing the +oneshot mask. + +The solution is simple: Clear the pending bit together with the mask +bit when we switch over to highres mode. + +Reported-by: poma +Cc: stable@vger.kernel.org # 3.10+ +Signed-off-by: Thomas Gleixner +--- + kernel/time/tick-broadcast.c | 1 + + 1 file changed, 1 insertion(+) + +Index: linux-2.6/kernel/time/tick-broadcast.c +=================================================================== +--- linux-2.6.orig/kernel/time/tick-broadcast.c ++++ linux-2.6/kernel/time/tick-broadcast.c +@@ -756,6 +756,7 @@ out: + static void tick_broadcast_clear_oneshot(int cpu) + { + cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask); ++ cpumask_clear_cpu(cpu, tick_broadcast_pending_mask); + } + + static void tick_broadcast_init_next_event(struct cpumask *mask, + + +-- +To unsubscribe from this list: send the line "unsubscribe linux-kernel" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html +Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file