lkml.org 
[lkml]   [2023]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v4 03/19] x86/reboot: KVM: Handle VMXOFF in KVM's reboot callback
    From
    Use KVM VMX's reboot/crash callback to do VMXOFF in an emergency instead
    of manually and blindly doing VMXOFF. There's no need to attempt VMXOFF
    if a hypervisor, i.e. KVM, isn't loaded/active, i.e. if the CPU can't
    possibly be post-VMXON.

    Signed-off-by: Sean Christopherson <seanjc@google.com>
    ---
    arch/x86/include/asm/virtext.h | 10 ----------
    arch/x86/kernel/reboot.c | 29 +++++++++--------------------
    arch/x86/kvm/vmx/vmx.c | 8 +++++---
    3 files changed, 14 insertions(+), 33 deletions(-)

    diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h
    index 3b12e6b99412..5bc29fab15da 100644
    --- a/arch/x86/include/asm/virtext.h
    +++ b/arch/x86/include/asm/virtext.h
    @@ -70,16 +70,6 @@ static inline void __cpu_emergency_vmxoff(void)
    cpu_vmxoff();
    }

    -/** Disable VMX if it is supported and enabled on the current CPU
    - */
    -static inline void cpu_emergency_vmxoff(void)
    -{
    - if (cpu_has_vmx())
    - __cpu_emergency_vmxoff();
    -}
    -
    -
    -

    /*
    * SVM functions:
    diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
    index 62ccedeb5e2b..d2d0f2672a64 100644
    --- a/arch/x86/kernel/reboot.c
    +++ b/arch/x86/kernel/reboot.c
    @@ -787,13 +787,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
    }
    #endif

    -/*
    - * This is used to VMCLEAR all VMCSs loaded on the
    - * processor. And when loading kvm_intel module, the
    - * callback function pointer will be assigned.
    - *
    - * protected by rcu.
    - */
    +/* RCU-protected callback to disable virtualization prior to reboot. */
    static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback;

    void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback)
    @@ -815,17 +809,6 @@ void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback)
    }
    EXPORT_SYMBOL_GPL(cpu_emergency_unregister_virt_callback);

    -static inline void cpu_crash_vmclear_loaded_vmcss(void)
    -{
    - cpu_emergency_virt_cb *callback;
    -
    - rcu_read_lock();
    - callback = rcu_dereference(cpu_emergency_virt_callback);
    - if (callback)
    - callback();
    - rcu_read_unlock();
    -}
    -
    /* This is the CPU performing the emergency shutdown work. */
    int crashing_cpu = -1;

    @@ -836,9 +819,15 @@ int crashing_cpu = -1;
    */
    void cpu_emergency_disable_virtualization(void)
    {
    - cpu_crash_vmclear_loaded_vmcss();
    + cpu_emergency_virt_cb *callback;

    - cpu_emergency_vmxoff();
    + rcu_read_lock();
    + callback = rcu_dereference(cpu_emergency_virt_callback);
    + if (callback)
    + callback();
    + rcu_read_unlock();
    +
    + /* KVM_AMD doesn't yet utilize the common callback. */
    cpu_emergency_svm_disable();
    }

    diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
    index 019cefc65142..682c20b33a96 100644
    --- a/arch/x86/kvm/vmx/vmx.c
    +++ b/arch/x86/kvm/vmx/vmx.c
    @@ -744,7 +744,7 @@ static int vmx_set_guest_uret_msr(struct vcpu_vmx *vmx,
    return ret;
    }

    -static void crash_vmclear_local_loaded_vmcss(void)
    +static void vmx_emergency_disable(void)
    {
    int cpu = raw_smp_processor_id();
    struct loaded_vmcs *v;
    @@ -752,6 +752,8 @@ static void crash_vmclear_local_loaded_vmcss(void)
    list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu),
    loaded_vmcss_on_cpu_link)
    vmcs_clear(v->vmcs);
    +
    + __cpu_emergency_vmxoff();
    }

    static void __loaded_vmcs_clear(void *arg)
    @@ -8590,7 +8592,7 @@ static void __vmx_exit(void)
    {
    allow_smaller_maxphyaddr = false;

    - cpu_emergency_unregister_virt_callback(crash_vmclear_local_loaded_vmcss);
    + cpu_emergency_unregister_virt_callback(vmx_emergency_disable);

    vmx_cleanup_l1d_flush();
    }
    @@ -8640,7 +8642,7 @@ static int __init vmx_init(void)
    pi_init_cpu(cpu);
    }

    - cpu_emergency_register_virt_callback(crash_vmclear_local_loaded_vmcss);
    + cpu_emergency_register_virt_callback(vmx_emergency_disable);

    vmx_check_vmcs12_offsets();

    --
    2.41.0.487.g6d72f3e995-goog
    \
     
     \ /
      Last update: 2023-07-21 22:20    [W:2.712 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site