Commit 2fdef3a2 authored by Sergey Senozhatsky's avatar Sergey Senozhatsky Committed by Paolo Bonzini

kvm: add PM-notifier

Add KVM PM-notifier so that architectures can have arch-specific
VM suspend/resume routines. Such architectures need to select
CONFIG_HAVE_KVM_PM_NOTIFIER and implement kvm_arch_pm_notifier().
Signed-off-by: default avatarSergey Senozhatsky <senozhatsky@chromium.org>
Acked-by: default avatarMarc Zyngier <maz@kernel.org>
Message-Id: <20210606021045.14159-1-senozhatsky@chromium.org>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 768d134d
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/rcuwait.h> #include <linux/rcuwait.h>
#include <linux/refcount.h> #include <linux/refcount.h>
#include <linux/nospec.h> #include <linux/nospec.h>
#include <linux/notifier.h>
#include <asm/signal.h> #include <asm/signal.h>
#include <linux/kvm.h> #include <linux/kvm.h>
...@@ -594,6 +595,10 @@ struct kvm { ...@@ -594,6 +595,10 @@ struct kvm {
pid_t userspace_pid; pid_t userspace_pid;
unsigned int max_halt_poll_ns; unsigned int max_halt_poll_ns;
u32 dirty_ring_size; u32 dirty_ring_size;
#ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
struct notifier_block pm_notifier;
#endif
}; };
#define kvm_err(fmt, ...) \ #define kvm_err(fmt, ...) \
...@@ -1007,6 +1012,10 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu); ...@@ -1007,6 +1012,10 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu);
#ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
int kvm_arch_pm_notifier(struct kvm *kvm, unsigned long state);
#endif
#ifdef __KVM_HAVE_ARCH_VCPU_DEBUGFS #ifdef __KVM_HAVE_ARCH_VCPU_DEBUGFS
void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry); void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry);
#endif #endif
......
...@@ -63,3 +63,6 @@ config HAVE_KVM_NO_POLL ...@@ -63,3 +63,6 @@ config HAVE_KVM_NO_POLL
config KVM_XFER_TO_GUEST_WORK config KVM_XFER_TO_GUEST_WORK
bool bool
config HAVE_KVM_PM_NOTIFIER
bool
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/lockdep.h> #include <linux/lockdep.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/suspend.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/ioctl.h> #include <asm/ioctl.h>
...@@ -780,6 +781,38 @@ static int kvm_init_mmu_notifier(struct kvm *kvm) ...@@ -780,6 +781,38 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
#endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
#ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
static int kvm_pm_notifier_call(struct notifier_block *bl,
unsigned long state,
void *unused)
{
struct kvm *kvm = container_of(bl, struct kvm, pm_notifier);
return kvm_arch_pm_notifier(kvm, state);
}
static void kvm_init_pm_notifier(struct kvm *kvm)
{
kvm->pm_notifier.notifier_call = kvm_pm_notifier_call;
/* Suspend KVM before we suspend ftrace, RCU, etc. */
kvm->pm_notifier.priority = INT_MAX;
register_pm_notifier(&kvm->pm_notifier);
}
static void kvm_destroy_pm_notifier(struct kvm *kvm)
{
unregister_pm_notifier(&kvm->pm_notifier);
}
#else /* !CONFIG_HAVE_KVM_PM_NOTIFIER */
static void kvm_init_pm_notifier(struct kvm *kvm)
{
}
static void kvm_destroy_pm_notifier(struct kvm *kvm)
{
}
#endif /* CONFIG_HAVE_KVM_PM_NOTIFIER */
static struct kvm_memslots *kvm_alloc_memslots(void) static struct kvm_memslots *kvm_alloc_memslots(void)
{ {
int i; int i;
...@@ -964,6 +997,7 @@ static struct kvm *kvm_create_vm(unsigned long type) ...@@ -964,6 +997,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
mutex_unlock(&kvm_lock); mutex_unlock(&kvm_lock);
preempt_notifier_inc(); preempt_notifier_inc();
kvm_init_pm_notifier(kvm);
return kvm; return kvm;
...@@ -1011,6 +1045,7 @@ static void kvm_destroy_vm(struct kvm *kvm) ...@@ -1011,6 +1045,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
int i; int i;
struct mm_struct *mm = kvm->mm; struct mm_struct *mm = kvm->mm;
kvm_destroy_pm_notifier(kvm);
kvm_uevent_notify_change(KVM_EVENT_DESTROY_VM, kvm); kvm_uevent_notify_change(KVM_EVENT_DESTROY_VM, kvm);
kvm_destroy_vm_debugfs(kvm); kvm_destroy_vm_debugfs(kvm);
kvm_arch_sync_events(kvm); kvm_arch_sync_events(kvm);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment