Skip to content

Commit 590b09b

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86: Register "emergency disable" callbacks when virt is enabled
Register the "disable virtualization in an emergency" callback just before KVM enables virtualization in hardware, as there is no functional need to keep the callbacks registered while KVM happens to be loaded, but is inactive, i.e. if KVM hasn't enabled virtualization. Note, unregistering the callback every time the last VM is destroyed could have measurable latency due to the synchronize_rcu() needed to ensure all references to the callback are dropped before KVM is unloaded. But the latency should be a small fraction of the total latency of disabling virtualization across all CPUs, and userspace can set enable_virt_at_load to completely eliminate the runtime overhead. Add a pointer in kvm_x86_ops to allow vendor code to provide its callback. There is no reason to force vendor code to do the registration, and either way KVM would need a new kvm_x86_ops hook. Suggested-by: Kai Huang <[email protected]> Reviewed-by: Chao Gao <[email protected]> Reviewed-by: Kai Huang <[email protected]> Acked-by: Kai Huang <[email protected]> Tested-by: Farrah Chen <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Message-ID: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 6d55a94 commit 590b09b

File tree

6 files changed

+18
-9
lines changed

6 files changed

+18
-9
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <asm/kvm_page_track.h>
3737
#include <asm/kvm_vcpu_regs.h>
3838
#include <asm/hyperv-tlfs.h>
39+
#include <asm/reboot.h>
3940

4041
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS
4142

@@ -1631,6 +1632,8 @@ struct kvm_x86_ops {
16311632

16321633
int (*enable_virtualization_cpu)(void);
16331634
void (*disable_virtualization_cpu)(void);
1635+
cpu_emergency_virt_cb *emergency_disable_virtualization_cpu;
1636+
16341637
void (*hardware_unsetup)(void);
16351638
bool (*has_emulated_msr)(struct kvm *kvm, u32 index);
16361639
void (*vcpu_after_set_cpuid)(struct kvm_vcpu *vcpu);

arch/x86/kvm/svm/svm.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4982,6 +4982,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
49824982
.hardware_unsetup = svm_hardware_unsetup,
49834983
.enable_virtualization_cpu = svm_enable_virtualization_cpu,
49844984
.disable_virtualization_cpu = svm_disable_virtualization_cpu,
4985+
.emergency_disable_virtualization_cpu = svm_emergency_disable_virtualization_cpu,
49854986
.has_emulated_msr = svm_has_emulated_msr,
49864987

49874988
.vcpu_create = svm_vcpu_create,
@@ -5410,8 +5411,6 @@ static struct kvm_x86_init_ops svm_init_ops __initdata = {
54105411
static void __svm_exit(void)
54115412
{
54125413
kvm_x86_vendor_exit();
5413-
5414-
cpu_emergency_unregister_virt_callback(svm_emergency_disable_virtualization_cpu);
54155414
}
54165415

54175416
static int __init svm_init(void)
@@ -5427,8 +5426,6 @@ static int __init svm_init(void)
54275426
if (r)
54285427
return r;
54295428

5430-
cpu_emergency_register_virt_callback(svm_emergency_disable_virtualization_cpu);
5431-
54325429
/*
54335430
* Common KVM initialization _must_ come last, after this, /dev/kvm is
54345431
* exposed to userspace!

arch/x86/kvm/vmx/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
2525

2626
.enable_virtualization_cpu = vmx_enable_virtualization_cpu,
2727
.disable_virtualization_cpu = vmx_disable_virtualization_cpu,
28+
.emergency_disable_virtualization_cpu = vmx_emergency_disable_virtualization_cpu,
29+
2830
.has_emulated_msr = vmx_has_emulated_msr,
2931

3032
.vm_size = sizeof(struct kvm_vmx),

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ static int kvm_cpu_vmxoff(void)
755755
return -EIO;
756756
}
757757

758-
static void vmx_emergency_disable_virtualization_cpu(void)
758+
void vmx_emergency_disable_virtualization_cpu(void)
759759
{
760760
int cpu = raw_smp_processor_id();
761761
struct loaded_vmcs *v;
@@ -8584,8 +8584,6 @@ static void __vmx_exit(void)
85848584
{
85858585
allow_smaller_maxphyaddr = false;
85868586

8587-
cpu_emergency_unregister_virt_callback(vmx_emergency_disable_virtualization_cpu);
8588-
85898587
vmx_cleanup_l1d_flush();
85908588
}
85918589

@@ -8632,8 +8630,6 @@ static int __init vmx_init(void)
86328630
pi_init_cpu(cpu);
86338631
}
86348632

8635-
cpu_emergency_register_virt_callback(vmx_emergency_disable_virtualization_cpu);
8636-
86378633
vmx_check_vmcs12_offsets();
86388634

86398635
/*

arch/x86/kvm/vmx/x86_ops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void vmx_hardware_unsetup(void);
1515
int vmx_check_processor_compat(void);
1616
int vmx_enable_virtualization_cpu(void);
1717
void vmx_disable_virtualization_cpu(void);
18+
void vmx_emergency_disable_virtualization_cpu(void);
1819
int vmx_vm_init(struct kvm *kvm);
1920
void vmx_vm_destroy(struct kvm *kvm);
2021
int vmx_vcpu_precreate(struct kvm *kvm);

arch/x86/kvm/x86.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12512,6 +12512,16 @@ void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)
1251212512
}
1251312513
EXPORT_SYMBOL_GPL(kvm_vcpu_deliver_sipi_vector);
1251412514

12515+
void kvm_arch_enable_virtualization(void)
12516+
{
12517+
cpu_emergency_register_virt_callback(kvm_x86_ops.emergency_disable_virtualization_cpu);
12518+
}
12519+
12520+
void kvm_arch_disable_virtualization(void)
12521+
{
12522+
cpu_emergency_unregister_virt_callback(kvm_x86_ops.emergency_disable_virtualization_cpu);
12523+
}
12524+
1251512525
int kvm_arch_enable_virtualization_cpu(void)
1251612526
{
1251712527
struct kvm *kvm;

0 commit comments

Comments
 (0)