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

KVM: Register syscore (suspend/resume) ops early in kvm_init()

Register the suspend/resume notifier hooks at the same time KVM registers
its reboot notifier so that all the code in kvm_init() that deals with
enabling/disabling hardware is bundled together. Opportunstically move
KVM's implementations to reside near the reboot notifier code for the
same reason.

Bunching the code together will allow architectures to opt out of KVM's
generic hardware enable/disable logic with minimal #ifdeffery.

Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20221130230934.1014142-49-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Sean Christopherson and committed by
Paolo Bonzini
35774a9f e6fb7d6e

+34 -34
+34 -34
virt/kvm/kvm_main.c
··· 5223 5223 .priority = 0, 5224 5224 }; 5225 5225 5226 + static int kvm_suspend(void) 5227 + { 5228 + /* 5229 + * Secondary CPUs and CPU hotplug are disabled across the suspend/resume 5230 + * callbacks, i.e. no need to acquire kvm_lock to ensure the usage count 5231 + * is stable. Assert that kvm_lock is not held to ensure the system 5232 + * isn't suspended while KVM is enabling hardware. Hardware enabling 5233 + * can be preempted, but the task cannot be frozen until it has dropped 5234 + * all locks (userspace tasks are frozen via a fake signal). 5235 + */ 5236 + lockdep_assert_not_held(&kvm_lock); 5237 + lockdep_assert_irqs_disabled(); 5238 + 5239 + if (kvm_usage_count) 5240 + hardware_disable_nolock(NULL); 5241 + return 0; 5242 + } 5243 + 5244 + static void kvm_resume(void) 5245 + { 5246 + lockdep_assert_not_held(&kvm_lock); 5247 + lockdep_assert_irqs_disabled(); 5248 + 5249 + if (kvm_usage_count) 5250 + WARN_ON_ONCE(__hardware_enable_nolock()); 5251 + } 5252 + 5253 + static struct syscore_ops kvm_syscore_ops = { 5254 + .suspend = kvm_suspend, 5255 + .resume = kvm_resume, 5256 + }; 5257 + 5226 5258 static void kvm_io_bus_destroy(struct kvm_io_bus *bus) 5227 5259 { 5228 5260 int i; ··· 5833 5801 } 5834 5802 } 5835 5803 5836 - static int kvm_suspend(void) 5837 - { 5838 - /* 5839 - * Secondary CPUs and CPU hotplug are disabled across the suspend/resume 5840 - * callbacks, i.e. no need to acquire kvm_lock to ensure the usage count 5841 - * is stable. Assert that kvm_lock is not held to ensure the system 5842 - * isn't suspended while KVM is enabling hardware. Hardware enabling 5843 - * can be preempted, but the task cannot be frozen until it has dropped 5844 - * all locks (userspace tasks are frozen via a fake signal). 5845 - */ 5846 - lockdep_assert_not_held(&kvm_lock); 5847 - lockdep_assert_irqs_disabled(); 5848 - 5849 - if (kvm_usage_count) 5850 - hardware_disable_nolock(NULL); 5851 - return 0; 5852 - } 5853 - 5854 - static void kvm_resume(void) 5855 - { 5856 - lockdep_assert_not_held(&kvm_lock); 5857 - lockdep_assert_irqs_disabled(); 5858 - 5859 - if (kvm_usage_count) 5860 - WARN_ON_ONCE(__hardware_enable_nolock()); 5861 - } 5862 - 5863 - static struct syscore_ops kvm_syscore_ops = { 5864 - .suspend = kvm_suspend, 5865 - .resume = kvm_resume, 5866 - }; 5867 - 5868 5804 static inline 5869 5805 struct kvm_vcpu *preempt_notifier_to_vcpu(struct preempt_notifier *pn) 5870 5806 { ··· 5948 5948 return r; 5949 5949 5950 5950 register_reboot_notifier(&kvm_reboot_notifier); 5951 + register_syscore_ops(&kvm_syscore_ops); 5951 5952 5952 5953 /* A kmem cache lets us meet the alignment requirements of fx_save. */ 5953 5954 if (!vcpu_align) ··· 5983 5982 5984 5983 kvm_chardev_ops.owner = module; 5985 5984 5986 - register_syscore_ops(&kvm_syscore_ops); 5987 - 5988 5985 kvm_preempt_ops.sched_in = kvm_sched_in; 5989 5986 kvm_preempt_ops.sched_out = kvm_sched_out; 5990 5987 ··· 6016 6017 free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); 6017 6018 kmem_cache_destroy(kvm_vcpu_cache); 6018 6019 out_free_3: 6020 + unregister_syscore_ops(&kvm_syscore_ops); 6019 6021 unregister_reboot_notifier(&kvm_reboot_notifier); 6020 6022 cpuhp_remove_state_nocalls(CPUHP_AP_KVM_ONLINE); 6021 6023 return r;