summaryrefslogtreecommitdiffstats
path: root/kernel/.gitignore
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-10-27 14:40:39 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2014-10-29 13:13:48 +0100
commitfd56e1546a5f734290cbedd2b81c518850736511 (patch)
tree859bbfa5437caf77f1e53a5b1a43b7ac01fba58b /kernel/.gitignore
parentKVM: emulator: fix error code for __linearize (diff)
downloadlinux-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