Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: Opt out of generic hardware enabling on s390 and PPC

Allow architectures to opt out of the generic hardware enabling logic,
and opt out on both s390 and PPC, which don't need to manually enable
virtualization as it's always on (when available).

In addition to letting s390 and PPC drop a bit of dead code, this will
hopefully also allow ARM to clean up its related code, e.g. ARM has its
own per-CPU flag to track which CPUs have enable hardware due to the
need to keep hardware enabled indefinitely when pKVM is enabled.

Signed-off-by: Sean Christopherson <seanjc@google.com>
Acked-by: Anup Patel <anup@brainfault.org>
Message-Id: <20221130230934.1014142-50-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Sean Christopherson and committed by
Paolo Bonzini
441f7bfa 35774a9f

+35 -19
+1
arch/arm64/kvm/Kconfig
··· 21 21 menuconfig KVM 22 22 bool "Kernel-based Virtual Machine (KVM) support" 23 23 depends on HAVE_KVM 24 + select KVM_GENERIC_HARDWARE_ENABLING 24 25 select MMU_NOTIFIER 25 26 select PREEMPT_NOTIFIERS 26 27 select HAVE_KVM_CPU_RELAX_INTERCEPT
+1
arch/mips/kvm/Kconfig
··· 28 28 select MMU_NOTIFIER 29 29 select SRCU 30 30 select INTERVAL_TREE 31 + select KVM_GENERIC_HARDWARE_ENABLING 31 32 help 32 33 Support for hosting Guest kernels. 33 34
-1
arch/powerpc/include/asm/kvm_host.h
··· 876 876 #define __KVM_HAVE_ARCH_WQP 877 877 #define __KVM_HAVE_CREATE_DEVICE 878 878 879 - static inline void kvm_arch_hardware_disable(void) {} 880 879 static inline void kvm_arch_sync_events(struct kvm *kvm) {} 881 880 static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} 882 881 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
-5
arch/powerpc/kvm/powerpc.c
··· 435 435 } 436 436 EXPORT_SYMBOL_GPL(kvmppc_ld); 437 437 438 - int kvm_arch_hardware_enable(void) 439 - { 440 - return 0; 441 - } 442 - 443 438 int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) 444 439 { 445 440 struct kvmppc_ops *kvm_ops = NULL;
+1
arch/riscv/kvm/Kconfig
··· 20 20 config KVM 21 21 tristate "Kernel-based Virtual Machine (KVM) support (EXPERIMENTAL)" 22 22 depends on RISCV_SBI && MMU 23 + select KVM_GENERIC_HARDWARE_ENABLING 23 24 select MMU_NOTIFIER 24 25 select PREEMPT_NOTIFIERS 25 26 select KVM_MMIO
-1
arch/s390/include/asm/kvm_host.h
··· 1031 1031 extern int kvm_s390_gisc_register(struct kvm *kvm, u32 gisc); 1032 1032 extern int kvm_s390_gisc_unregister(struct kvm *kvm, u32 gisc); 1033 1033 1034 - static inline void kvm_arch_hardware_disable(void) {} 1035 1034 static inline void kvm_arch_sync_events(struct kvm *kvm) {} 1036 1035 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} 1037 1036 static inline void kvm_arch_free_memslot(struct kvm *kvm,
-6
arch/s390/kvm/kvm-s390.c
··· 256 256 debug_info_t *kvm_s390_dbf_uv; 257 257 258 258 /* Section: not file related */ 259 - int kvm_arch_hardware_enable(void) 260 - { 261 - /* every s390 is virtualization enabled ;-) */ 262 - return 0; 263 - } 264 - 265 259 /* forward declarations */ 266 260 static void kvm_gmap_notifier(struct gmap *gmap, unsigned long start, 267 261 unsigned long end);
+1
arch/x86/kvm/Kconfig
··· 49 49 select SRCU 50 50 select INTERVAL_TREE 51 51 select HAVE_KVM_PM_NOTIFIER if PM 52 + select KVM_GENERIC_HARDWARE_ENABLING 52 53 help 53 54 Support hosting fully virtualized guest machines using hardware 54 55 virtualization extensions. You will need a fairly recent
+4
include/linux/kvm_host.h
··· 1441 1441 static inline void kvm_create_vcpu_debugfs(struct kvm_vcpu *vcpu) {} 1442 1442 #endif 1443 1443 1444 + #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING 1444 1445 int kvm_arch_hardware_enable(void); 1445 1446 void kvm_arch_hardware_disable(void); 1447 + #endif 1446 1448 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu); 1447 1449 bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu); 1448 1450 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); ··· 2076 2074 } 2077 2075 } 2078 2076 2077 + #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING 2079 2078 extern bool kvm_rebooting; 2079 + #endif 2080 2080 2081 2081 extern unsigned int halt_poll_ns; 2082 2082 extern unsigned int halt_poll_ns_grow;
+3
virt/kvm/Kconfig
··· 92 92 93 93 config HAVE_KVM_PM_NOTIFIER 94 94 bool 95 + 96 + config KVM_GENERIC_HARDWARE_ENABLING 97 + bool
+24 -6
virt/kvm/kvm_main.c
··· 102 102 DEFINE_MUTEX(kvm_lock); 103 103 LIST_HEAD(vm_list); 104 104 105 - static DEFINE_PER_CPU(bool, hardware_enabled); 106 - static int kvm_usage_count; 107 - 108 105 static struct kmem_cache *kvm_vcpu_cache; 109 106 110 107 static __read_mostly struct preempt_ops kvm_preempt_ops; ··· 142 145 static void hardware_disable_all(void); 143 146 144 147 static void kvm_io_bus_destroy(struct kvm_io_bus *bus); 145 - 146 - __visible bool kvm_rebooting; 147 - EXPORT_SYMBOL_GPL(kvm_rebooting); 148 148 149 149 #define KVM_EVENT_CREATE_VM 0 150 150 #define KVM_EVENT_DESTROY_VM 1 ··· 5087 5093 &kvm_chardev_ops, 5088 5094 }; 5089 5095 5096 + #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING 5097 + __visible bool kvm_rebooting; 5098 + EXPORT_SYMBOL_GPL(kvm_rebooting); 5099 + 5100 + static DEFINE_PER_CPU(bool, hardware_enabled); 5101 + static int kvm_usage_count; 5102 + 5090 5103 static int __hardware_enable_nolock(void) 5091 5104 { 5092 5105 if (__this_cpu_read(hardware_enabled)) ··· 5255 5254 .suspend = kvm_suspend, 5256 5255 .resume = kvm_resume, 5257 5256 }; 5257 + #else /* CONFIG_KVM_GENERIC_HARDWARE_ENABLING */ 5258 + static int hardware_enable_all(void) 5259 + { 5260 + return 0; 5261 + } 5262 + 5263 + static void hardware_disable_all(void) 5264 + { 5265 + 5266 + } 5267 + #endif /* CONFIG_KVM_GENERIC_HARDWARE_ENABLING */ 5258 5268 5259 5269 static void kvm_io_bus_destroy(struct kvm_io_bus *bus) 5260 5270 { ··· 5954 5942 int r; 5955 5943 int cpu; 5956 5944 5945 + #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING 5957 5946 r = cpuhp_setup_state_nocalls(CPUHP_AP_KVM_ONLINE, "kvm/cpu:online", 5958 5947 kvm_online_cpu, kvm_offline_cpu); 5959 5948 if (r) ··· 5962 5949 5963 5950 register_reboot_notifier(&kvm_reboot_notifier); 5964 5951 register_syscore_ops(&kvm_syscore_ops); 5952 + #endif 5965 5953 5966 5954 /* A kmem cache lets us meet the alignment requirements of fx_save. */ 5967 5955 if (!vcpu_align) ··· 6030 6016 free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); 6031 6017 kmem_cache_destroy(kvm_vcpu_cache); 6032 6018 out_free_3: 6019 + #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING 6033 6020 unregister_syscore_ops(&kvm_syscore_ops); 6034 6021 unregister_reboot_notifier(&kvm_reboot_notifier); 6035 6022 cpuhp_remove_state_nocalls(CPUHP_AP_KVM_ONLINE); 6023 + #endif 6036 6024 return r; 6037 6025 } 6038 6026 EXPORT_SYMBOL_GPL(kvm_init); ··· 6056 6040 kmem_cache_destroy(kvm_vcpu_cache); 6057 6041 kvm_vfio_ops_exit(); 6058 6042 kvm_async_pf_deinit(); 6043 + #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING 6059 6044 unregister_syscore_ops(&kvm_syscore_ops); 6060 6045 unregister_reboot_notifier(&kvm_reboot_notifier); 6061 6046 cpuhp_remove_state_nocalls(CPUHP_AP_KVM_ONLINE); 6047 + #endif 6062 6048 kvm_irqfd_exit(); 6063 6049 } 6064 6050 EXPORT_SYMBOL_GPL(kvm_exit);