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: Sergey Senozhatsky <senozhatsky@chromium.org> Acked-by: Marc Zyngier <maz@kernel.org> Message-Id: <20210606021045.14159-1-senozhatsky@chromium.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
768d134d8c
commit
2fdef3a2ae
@ -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 {
|
|||||||
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);
|
|||||||
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
|
|||||||
|
|
||||||
config KVM_XFER_TO_GUEST_WORK
|
config KVM_XFER_TO_GUEST_WORK
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config HAVE_KVM_PM_NOTIFIER
|
||||||
|
bool
|
||||||
|
@ -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)
|
|||||||
|
|
||||||
#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)
|
|||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user