]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commit
KVM: emulator: fix execution close to the segment limit
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 27 Oct 2014 13:40:39 +0000 (14:40 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 29 Oct 2014 12:13:48 +0000 (13:13 +0100)
commitfd56e1546a5f734290cbedd2b81c518850736511
tree859bbfa5437caf77f1e53a5b1a43b7ac01fba58b
parent3606189fa3da6afcad0cbbc9b91e94f1f158da5a
KVM: emulator: fix execution close to the segment limit

Emulation of code that is 14 bytes to the segment limit or closer
(e.g. RIP = 0xFFFFFFF2 after reset) is broken because we try to read as
many as 15 bytes from the beginning of the instruction, and __linearize
fails when the passed (address, size) pair reaches out of the segment.

To fix this, let __linearize return the maximum accessible size (clamped
to 2^32-1) for usage in __do_insn_fetch_bytes, and avoid the limit check
by passing zero for the desired size.

For expand-down segments, __linearize is performing a redundant check.
(u32)(addr.ea + size - 1) <= lim can only happen if addr.ea is close
to 4GB; in this case, addr.ea + size - 1 will also fail the check against
the upper bound of the segment (which is provided by the D/B bit).
After eliminating the redundant check, it is simple to compute
the *max_size for expand-down segments too.

Now that the limit check is done in __do_insn_fetch_bytes, we want
to inject a general protection fault there if size < op_size (like
__linearize would have done), instead of just aborting.

This fixes booting Tiano Core from emulated flash with EPT disabled.

Cc: stable@vger.kernel.org
Fixes: 719d5a9b2487e0562f178f61e323c3dc18a8b200
Reported-by: Borislav Petkov <bp@suse.de>
Tested-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/emulate.c