lkml.org 
[lkml]   [2014]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.16.y-ckt 001/168] x86: kvm: use alternatives for VMCALL vs. VMMCALL if kernel text is read-only
    Date
    3.16.7-ckt3 -stable review patch.  If anyone has any objections, please let me know.

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

    From: Paolo Bonzini <pbonzini@redhat.com>

    commit c1118b3602c2329671ad5ec8bdf8e374323d6343 upstream.

    On x86_64, kernel text mappings are mapped read-only with CONFIG_DEBUG_RODATA.
    In that case, KVM will fail to patch VMCALL instructions to VMMCALL
    as required on AMD processors.

    The failure mode is currently a divide-by-zero exception, which obviously
    is a KVM bug that has to be fixed. However, picking the right instruction
    between VMCALL and VMMCALL will be faster and will help if you cannot upgrade
    the hypervisor.

    Reported-by: Chris Webb <chris@arachsys.com>
    Tested-by: Chris Webb <chris@arachsys.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: x86@kernel.org
    Acked-by: Borislav Petkov <bp@suse.de>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Chris J Arges <chris.j.arges@canonical.com>
    [ luis: used Chris backport to 3.16 ]
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    arch/x86/include/asm/cpufeature.h | 1 +
    arch/x86/include/asm/kvm_para.h | 10 ++++++++--
    arch/x86/kernel/cpu/amd.c | 7 +++++++
    3 files changed, 16 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
    index e265ff95d16d..51f75503541d 100644
    --- a/arch/x86/include/asm/cpufeature.h
    +++ b/arch/x86/include/asm/cpufeature.h
    @@ -203,6 +203,7 @@
    #define X86_FEATURE_DECODEASSISTS (8*32+12) /* AMD Decode Assists support */
    #define X86_FEATURE_PAUSEFILTER (8*32+13) /* AMD filtered pause intercept */
    #define X86_FEATURE_PFTHRESHOLD (8*32+14) /* AMD pause filter threshold */
    +#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */


    /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
    diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
    index c7678e43465b..e62cf897f781 100644
    --- a/arch/x86/include/asm/kvm_para.h
    +++ b/arch/x86/include/asm/kvm_para.h
    @@ -2,6 +2,7 @@
    #define _ASM_X86_KVM_PARA_H

    #include <asm/processor.h>
    +#include <asm/alternative.h>
    #include <uapi/asm/kvm_para.h>

    extern void kvmclock_init(void);
    @@ -16,10 +17,15 @@ static inline bool kvm_check_and_clear_guest_paused(void)
    }
    #endif /* CONFIG_KVM_GUEST */

    -/* This instruction is vmcall. On non-VT architectures, it will generate a
    - * trap that we will then rewrite to the appropriate instruction.
    +#ifdef CONFIG_DEBUG_RODATA
    +#define KVM_HYPERCALL \
    + ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9", X86_FEATURE_VMMCALL)
    +#else
    +/* On AMD processors, vmcall will generate a trap that we will
    + * then rewrite to the appropriate instruction.
    */
    #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
    +#endif

    /* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall
    * instruction. The hypervisor may replace it with something else but only the
    diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
    index ce8b8ff0e0ef..edefacacc2cc 100644
    --- a/arch/x86/kernel/cpu/amd.c
    +++ b/arch/x86/kernel/cpu/amd.c
    @@ -506,6 +506,13 @@ static void early_init_amd(struct cpuinfo_x86 *c)
    }
    #endif

    + /*
    + * This is only needed to tell the kernel whether to use VMCALL
    + * and VMMCALL. VMMCALL is never executed except under virt, so
    + * we can set it unconditionally.
    + */
    + set_cpu_cap(c, X86_FEATURE_VMMCALL);
    +
    /* F16h erratum 793, CVE-2013-6885 */
    if (c->x86 == 0x16 && c->x86_model <= 0xf)
    msr_set_bit(MSR_AMD64_LS_CFG, 15);
    --
    2.1.3


    \
     
     \ /
      Last update: 2014-12-15 17:01    [W:8.132 / U:1.284 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site