diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-10-27 14:40:39 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-10-29 13:13:48 +0100 |
commit | fd56e1546a5f734290cbedd2b81c518850736511 (patch) | |
tree | 859bbfa5437caf77f1e53a5b1a43b7ac01fba58b /kernel/.gitignore | |
parent | KVM: emulator: fix error code for __linearize (diff) | |
download | linux-fd56e1546a5f734290cbedd2b81c518850736511.tar.xz linux-fd56e1546a5f734290cbedd2b81c518850736511.zip |
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>
Diffstat (limited to 'kernel/.gitignore')
0 files changed, 0 insertions, 0 deletions