Commit de5b55f6 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Greg Kroah-Hartman

KVM: x86: fix conversion of addresses to linear in 32-bit protected mode

commit 0c1d77f4 upstream.

Commit e8dd2d2d ("Silence compiler warning in arch/x86/kvm/emulate.c",
2015-09-06) broke boot of the Hurd.  The bug is that the "default:"
case actually could modify "la", but after the patch this change is
not reflected in *linear.

The bug is visible whenever a non-zero segment base causes the linear
address to wrap around the 4GB mark.

Fixes: e8dd2d2dReported-by: default avatarAurelien Jarno <aurelien@aurel32.net>
Tested-by: default avatarAurelien Jarno <aurelien@aurel32.net>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fc90441e
...@@ -650,10 +650,10 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, ...@@ -650,10 +650,10 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
u16 sel; u16 sel;
la = seg_base(ctxt, addr.seg) + addr.ea; la = seg_base(ctxt, addr.seg) + addr.ea;
*linear = la;
*max_size = 0; *max_size = 0;
switch (mode) { switch (mode) {
case X86EMUL_MODE_PROT64: case X86EMUL_MODE_PROT64:
*linear = la;
if (is_noncanonical_address(la)) if (is_noncanonical_address(la))
goto bad; goto bad;
...@@ -662,6 +662,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, ...@@ -662,6 +662,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
goto bad; goto bad;
break; break;
default: default:
*linear = la = (u32)la;
usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL, usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL,
addr.seg); addr.seg);
if (!usable) if (!usable)
...@@ -689,7 +690,6 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, ...@@ -689,7 +690,6 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
if (size > *max_size) if (size > *max_size)
goto bad; goto bad;
} }
la &= (u32)-1;
break; break;
} }
if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0)) if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment