lkml.org 
[lkml]   [2013]   [Jun]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 059/184] MCE: Fix vm86 handling for 32bit mce handler
    2.6.32-longterm review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Andi Kleen <andi@firstfloor.org>

    commit a129a7c84582629741e5fa6f40026efcd7a65bd4 upstream.

    When running on 32bit the mce handler could misinterpret
    vm86 mode as ring 0. This can affect whether it does recovery
    or not; it was possible to panic when recovery was actually
    possible.

    Fix this by always forcing vm86 to look like ring 3.

    [ Backport to 3.0 notes:
    Things changed there slightly:
    - move mce_get_rip() up. It fills up m->cs and m->ip values which
    are evaluated in mce_severity(). Therefore move it up right before
    the mce_severity call. This seem to be another bug in 3.0?
    - Place the backport (fix m->cs in V86 case) to where m->cs gets
    filled which is mce_get_rip() in 3.0
    ]

    Signed-off-by: Andi Kleen <ak@linux.intel.com>
    Signed-off-by: Tony Luck <tony.luck@intel.com>
    Signed-off-by: Thomas Renninger <trenn@suse.de>
    Reviewed-by: Tony Luck <tony.luck@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Willy Tarreau <w@1wt.eu>
    ---
    arch/x86/kernel/cpu/mcheck/mce.c | 9 ++++++++-
    1 file changed, 8 insertions(+), 1 deletion(-)

    diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
    index 0f16a2b..28a7e4c8 100644
    --- a/arch/x86/kernel/cpu/mcheck/mce.c
    +++ b/arch/x86/kernel/cpu/mcheck/mce.c
    @@ -431,6 +431,13 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
    if (regs && (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV))) {
    m->ip = regs->ip;
    m->cs = regs->cs;
    + /*
    + * When in VM86 mode make the cs look like ring 3
    + * always. This is a lie, but it's better than passing
    + * the additional vm86 bit around everywhere.
    + */
    + if (v8086_mode(regs))
    + m->cs |= 3;
    } else {
    m->ip = 0;
    m->cs = 0;
    @@ -968,6 +975,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
    */
    add_taint(TAINT_MACHINE_CHECK);

    + mce_get_rip(&m, regs);
    severity = mce_severity(&m, tolerant, NULL);

    /*
    @@ -1006,7 +1014,6 @@ void do_machine_check(struct pt_regs *regs, long error_code)
    if (severity == MCE_AO_SEVERITY && mce_usable_address(&m))
    mce_ring_add(m.addr >> PAGE_SHIFT);

    - mce_get_rip(&m, regs);
    mce_log(&m);

    if (severity > worst) {
    --
    1.7.12.2.21.g234cd45.dirty




    \
     
     \ /
      Last update: 2013-06-05 02:01    [W:4.127 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site