• Paolo Bonzini's avatar
    KVM: emulator: fix execution close to the segment limit · fd56e154
    Paolo Bonzini authored
    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: 719d5a9bReported-by: default avatarBorislav Petkov <bp@suse.de>
    Tested-by: default avatarBorislav Petkov <bp@suse.de>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    fd56e154
emulate.c 130 KB