lkml.org 
[lkml]   [2018]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 083/101] kvm/x86: fix icebp instruction handling
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Linus Torvalds <torvalds@linux-foundation.org>

    commit 32d43cd391bacb5f0814c2624399a5dad3501d09 upstream.

    The undocumented 'icebp' instruction (aka 'int1') works pretty much like
    'int3' in the absense of in-circuit probing equipment (except,
    obviously, that it raises #DB instead of raising #BP), and is used by
    some validation test-suites as such.

    But Andy Lutomirski noticed that his test suite acted differently in kvm
    than on bare hardware.

    The reason is that kvm used an inexact test for the icebp instruction:
    it just assumed that an all-zero VM exit qualification value meant that
    the VM exit was due to icebp.

    That is not unlike the guess that do_debug() does for the actual
    exception handling case, but it's purely a heuristic, not an absolute
    rule. do_debug() does it because it wants to ascribe _some_ reasons to
    the #DB that happened, and an empty %dr6 value means that 'icebp' is the
    most likely casue and we have no better information.

    But kvm can just do it right, because unlike the do_debug() case, kvm
    actually sees the real reason for the #DB in the VM-exit interruption
    information field.

    So instead of relying on an inexact heuristic, just use the actual VM
    exit information that says "it was 'icebp'".

    Right now the 'icebp' instruction isn't technically documented by Intel,
    but that will hopefully change. The special "privileged software
    exception" information _is_ actually mentioned in the Intel SDM, even
    though the cause of it isn't enumerated.

    Reported-by: Andy Lutomirski <luto@kernel.org>
    Tested-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/include/asm/vmx.h | 1 +
    arch/x86/kvm/vmx.c | 9 ++++++++-
    2 files changed, 9 insertions(+), 1 deletion(-)

    --- a/arch/x86/include/asm/vmx.h
    +++ b/arch/x86/include/asm/vmx.h
    @@ -352,6 +352,7 @@ enum vmcs_field {
    #define INTR_TYPE_NMI_INTR (2 << 8) /* NMI */
    #define INTR_TYPE_HARD_EXCEPTION (3 << 8) /* processor exception */
    #define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */
    +#define INTR_TYPE_PRIV_SW_EXCEPTION (5 << 8) /* ICE breakpoint - undocumented */
    #define INTR_TYPE_SOFT_EXCEPTION (6 << 8) /* software exception */

    /* GUEST_INTERRUPTIBILITY_INFO flags. */
    --- a/arch/x86/kvm/vmx.c
    +++ b/arch/x86/kvm/vmx.c
    @@ -1071,6 +1071,13 @@ static inline bool is_machine_check(u32
    (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK);
    }

    +/* Undocumented: icebp/int1 */
    +static inline bool is_icebp(u32 intr_info)
    +{
    + return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
    + == (INTR_TYPE_PRIV_SW_EXCEPTION | INTR_INFO_VALID_MASK);
    +}
    +
    static inline bool cpu_has_vmx_msr_bitmap(void)
    {
    return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
    @@ -6169,7 +6176,7 @@ static int handle_exception(struct kvm_v
    (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
    vcpu->arch.dr6 &= ~15;
    vcpu->arch.dr6 |= dr6 | DR6_RTM;
    - if (!(dr6 & ~DR6_RESERVED)) /* icebp */
    + if (is_icebp(intr_info))
    skip_emulated_instruction(vcpu);

    kvm_queue_exception(vcpu, DB_VECTOR);

    \
     
     \ /
      Last update: 2018-03-27 19:24    [W:5.005 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site