• Andi Kleen's avatar
    x86: fix panic with interrupts off (needed for MCE) · 4ef702c1
    Andi Kleen authored
    For some time each panic() called with interrupts disabled
    triggered the !irqs_disabled() WARN_ON in smp_call_function(),
    producing ugly backtraces and confusing users.
    
    This is a common situation with machine checks for example which
    tend to call panic with interrupts disabled, but will also hit
    in other situations e.g. panic during early boot.  In fact it
    means that panic cannot be called in many circumstances, which
    would be bad.
    
    This all started with the new fancy queued smp_call_function,
    which is then used by the shutdown path to shut down the other
    CPUs.
    
    On closer examination it turned out that the fancy RCU
    smp_call_function() does lots of things not suitable in a panic
    situation anyways, like allocating memory and relying on complex
    system state.
    
    I originally tried to patch this over by checking for panic
    there, but it was quite complicated and the original patch
    was also not very popular.  This also didn't fix some of the
    underlying complexity problems.
    
    The new code in post 2.6.29 tries to patch around this by
    checking for oops_in_progress, but that is not enough to make
    this fully safe and I don't think that's a real solution
    because panic has to be reliable.
    
    So instead use an own vector to reboot.  This makes the reboot
    code extremly straight forward, which is definitely a big plus
    in a panic situation where it is important to avoid relying on
    too much kernel state.  The new simple code is also safe to be
    called from interupts off region because it is very very simple.
    
    There can be situations where it is important that panic
    is reliable.  For example on a fatal machine check the panic
    is needed to get the system up again and running as quickly
    as possible.  So it's important that panic is reliable and
    all function it calls simple.
    
    This is why I came up with this simple vector scheme.
    It's very hard to beat in simplicity.  Vectors are not
    particularly precious anymore since all big systems are
    using per CPU vectors.
    
    Another possibility would have been to use an NMI similar
    to kdump, but there is still the problem that NMIs don't
    work reliably on some systems due to BIOS issues.  NMIs
    would have been able to stop CPUs running with interrupts
    off too.  In the sake of universal reliability I opted for
    using a non NMI vector for now.
    
    I put the reboot vector into the highest priority bucket of
    the APIC vectors and moved the 64bit UV_BAU message down
    instead into the next lower priority.
    
    [ Impact: bug fix, fixes an old regression ]
    Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
    Signed-off-by: default avatarHidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
    Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
    4ef702c1
irqinit.c 7.16 KB