diff mbox series

[Impish,SRU,1/3] KVM: Add infrastructure and macro to mark VM as bugged

Message ID 20220411140157.97354-2-po-hsu.lin@canonical.com
State New
Headers show
Series Fix KVM regression on Impish | expand

Commit Message

Po-Hsu Lin April 11, 2022, 2:01 p.m. UTC
From: Sean Christopherson <sean.j.christopherson@intel.com>

BugLink: https://bugs.launchpad.net/bugs/1966499

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <3a0998645c328bf0895f1290e61821b70f048549.1625186503.git.isaku.yamahata@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(backported from commit 0b8f11737cffc1a406d1134b58687abc29d76b52)
[PHLin: missing 2fdef3a2ae CONFIG_HAVE_KVM_PM_NOTIFIER check]
[PHLin: missing fcfe1baedd char stats_id]
Signed-off-by: Po-Hsu Lin <po-hsu.lin@canonical.com>
---
 include/linux/kvm_host.h | 28 +++++++++++++++++++++++++++-
 virt/kvm/kvm_main.c      | 10 +++++-----
 2 files changed, 32 insertions(+), 6 deletions(-)

Comments

Kleber Sacilotto de Souza April 13, 2022, 10:37 a.m. UTC | #1
On 11.04.22 16:01, Po-Hsu Lin wrote:
> From: Sean Christopherson <sean.j.christopherson@intel.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1966499
> 
> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> Message-Id: <3a0998645c328bf0895f1290e61821b70f048549.1625186503.git.isaku.yamahata@intel.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> (backported from commit 0b8f11737cffc1a406d1134b58687abc29d76b52)
> [PHLin: missing 2fdef3a2ae CONFIG_HAVE_KVM_PM_NOTIFIER check]
> [PHLin: missing fcfe1baedd char stats_id]

Hi Sam,

To help with the backport review, it would be useful to have some
additional information on what changes were required because of the
missing commits. E.g. whether only context adjustments or other
changes were needed.

Thanks,

Kleber

> Signed-off-by: Po-Hsu Lin <po-hsu.lin@canonical.com>
> ---
>   include/linux/kvm_host.h | 28 +++++++++++++++++++++++++++-
>   virt/kvm/kvm_main.c      | 10 +++++-----
>   2 files changed, 32 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 8583ed3f..41b652f 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -149,6 +149,7 @@ static inline bool is_error_page(struct page *page)
>   #define KVM_REQ_MMU_RELOAD        (1 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
>   #define KVM_REQ_UNBLOCK           2
>   #define KVM_REQ_UNHALT            3
> +#define KVM_REQ_VM_BUGGED         (4 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
>   #define KVM_REQUEST_ARCH_BASE     8
>   
>   #define KVM_ARCH_REQ_FLAGS(nr, flags) ({ \
> @@ -585,6 +586,7 @@ struct kvm {
>   	pid_t userspace_pid;
>   	unsigned int max_halt_poll_ns;
>   	u32 dirty_ring_size;
> +	bool vm_bugged;
>   };
>   
>   #define kvm_err(fmt, ...) \
> @@ -613,6 +615,31 @@ struct kvm {
>   #define vcpu_err(vcpu, fmt, ...)					\
>   	kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
>   
> +bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
> +static inline void kvm_vm_bugged(struct kvm *kvm)
> +{
> +	kvm->vm_bugged = true;
> +	kvm_make_all_cpus_request(kvm, KVM_REQ_VM_BUGGED);
> +}
> +
> +#define KVM_BUG(cond, kvm, fmt...)				\
> +({								\
> +	int __ret = (cond);					\
> +								\
> +	if (WARN_ONCE(__ret && !(kvm)->vm_bugged, fmt))		\
> +		kvm_vm_bugged(kvm);				\
> +	unlikely(__ret);					\
> +})
> +
> +#define KVM_BUG_ON(cond, kvm)					\
> +({								\
> +	int __ret = (cond);					\
> +								\
> +	if (WARN_ON_ONCE(__ret && !(kvm)->vm_bugged))		\
> +		kvm_vm_bugged(kvm);				\
> +	unlikely(__ret);					\
> +})
> +
>   static inline bool kvm_dirty_log_manual_protect_and_init_set(struct kvm *kvm)
>   {
>   	return !!(kvm->manual_dirty_log_protect & KVM_DIRTY_LOG_INITIALLY_SET);
> @@ -930,7 +957,6 @@ void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc);
>   bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req,
>   				 struct kvm_vcpu *except,
>   				 unsigned long *vcpu_bitmap, cpumask_var_t tmp);
> -bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
>   bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req,
>   				      struct kvm_vcpu *except);
>   bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req,
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 93b5f76..309db8d 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -3455,7 +3455,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
>   	struct kvm_fpu *fpu = NULL;
>   	struct kvm_sregs *kvm_sregs = NULL;
>   
> -	if (vcpu->kvm->mm != current->mm)
> +	if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged)
>   		return -EIO;
>   
>   	if (unlikely(_IOC_TYPE(ioctl) != KVMIO))
> @@ -3661,7 +3661,7 @@ static long kvm_vcpu_compat_ioctl(struct file *filp,
>   	void __user *argp = compat_ptr(arg);
>   	int r;
>   
> -	if (vcpu->kvm->mm != current->mm)
> +	if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged)
>   		return -EIO;
>   
>   	switch (ioctl) {
> @@ -3727,7 +3727,7 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl,
>   {
>   	struct kvm_device *dev = filp->private_data;
>   
> -	if (dev->kvm->mm != current->mm)
> +	if (dev->kvm->mm != current->mm || dev->kvm->vm_bugged)
>   		return -EIO;
>   
>   	switch (ioctl) {
> @@ -4011,7 +4011,7 @@ static long kvm_vm_ioctl(struct file *filp,
>   	void __user *argp = (void __user *)arg;
>   	int r;
>   
> -	if (kvm->mm != current->mm)
> +	if (kvm->mm != current->mm || kvm->vm_bugged)
>   		return -EIO;
>   	switch (ioctl) {
>   	case KVM_CREATE_VCPU:
> @@ -4219,7 +4219,7 @@ static long kvm_vm_compat_ioctl(struct file *filp,
>   	struct kvm *kvm = filp->private_data;
>   	int r;
>   
> -	if (kvm->mm != current->mm)
> +	if (kvm->mm != current->mm || kvm->vm_bugged)
>   		return -EIO;
>   	switch (ioctl) {
>   #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT
Po-Hsu Lin April 13, 2022, 2:49 p.m. UTC | #2
On Wed, Apr 13, 2022 at 6:37 PM Kleber Souza <kleber.souza@canonical.com> wrote:
>
> On 11.04.22 16:01, Po-Hsu Lin wrote:
> > From: Sean Christopherson <sean.j.christopherson@intel.com>
> >
> > BugLink: https://bugs.launchpad.net/bugs/1966499
> >
> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> > Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
> > Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> > Message-Id: <3a0998645c328bf0895f1290e61821b70f048549.1625186503.git.isaku.yamahata@intel.com>
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > (backported from commit 0b8f11737cffc1a406d1134b58687abc29d76b52)
> > [PHLin: missing 2fdef3a2ae CONFIG_HAVE_KVM_PM_NOTIFIER check]
> > [PHLin: missing fcfe1baedd char stats_id]
>
> Hi Sam,
>
> To help with the backport review, it would be useful to have some
> additional information on what changes were required because of the
> missing commits. E.g. whether only context adjustments or other
> changes were needed.
>
> Thanks,
>
> Kleber
>
Hi Kleber,
thanks for the feedback, will try to be more specific for future patches.
Cheers
Sam

> > Signed-off-by: Po-Hsu Lin <po-hsu.lin@canonical.com>
> > ---
> >   include/linux/kvm_host.h | 28 +++++++++++++++++++++++++++-
> >   virt/kvm/kvm_main.c      | 10 +++++-----
> >   2 files changed, 32 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > index 8583ed3f..41b652f 100644
> > --- a/include/linux/kvm_host.h
> > +++ b/include/linux/kvm_host.h
> > @@ -149,6 +149,7 @@ static inline bool is_error_page(struct page *page)
> >   #define KVM_REQ_MMU_RELOAD        (1 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
> >   #define KVM_REQ_UNBLOCK           2
> >   #define KVM_REQ_UNHALT            3
> > +#define KVM_REQ_VM_BUGGED         (4 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
> >   #define KVM_REQUEST_ARCH_BASE     8
> >
> >   #define KVM_ARCH_REQ_FLAGS(nr, flags) ({ \
> > @@ -585,6 +586,7 @@ struct kvm {
> >       pid_t userspace_pid;
> >       unsigned int max_halt_poll_ns;
> >       u32 dirty_ring_size;
> > +     bool vm_bugged;
> >   };
> >
> >   #define kvm_err(fmt, ...) \
> > @@ -613,6 +615,31 @@ struct kvm {
> >   #define vcpu_err(vcpu, fmt, ...)                                    \
> >       kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
> >
> > +bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
> > +static inline void kvm_vm_bugged(struct kvm *kvm)
> > +{
> > +     kvm->vm_bugged = true;
> > +     kvm_make_all_cpus_request(kvm, KVM_REQ_VM_BUGGED);
> > +}
> > +
> > +#define KVM_BUG(cond, kvm, fmt...)                           \
> > +({                                                           \
> > +     int __ret = (cond);                                     \
> > +                                                             \
> > +     if (WARN_ONCE(__ret && !(kvm)->vm_bugged, fmt))         \
> > +             kvm_vm_bugged(kvm);                             \
> > +     unlikely(__ret);                                        \
> > +})
> > +
> > +#define KVM_BUG_ON(cond, kvm)                                        \
> > +({                                                           \
> > +     int __ret = (cond);                                     \
> > +                                                             \
> > +     if (WARN_ON_ONCE(__ret && !(kvm)->vm_bugged))           \
> > +             kvm_vm_bugged(kvm);                             \
> > +     unlikely(__ret);                                        \
> > +})
> > +
> >   static inline bool kvm_dirty_log_manual_protect_and_init_set(struct kvm *kvm)
> >   {
> >       return !!(kvm->manual_dirty_log_protect & KVM_DIRTY_LOG_INITIALLY_SET);
> > @@ -930,7 +957,6 @@ void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc);
> >   bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req,
> >                                struct kvm_vcpu *except,
> >                                unsigned long *vcpu_bitmap, cpumask_var_t tmp);
> > -bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
> >   bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req,
> >                                     struct kvm_vcpu *except);
> >   bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req,
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 93b5f76..309db8d 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -3455,7 +3455,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
> >       struct kvm_fpu *fpu = NULL;
> >       struct kvm_sregs *kvm_sregs = NULL;
> >
> > -     if (vcpu->kvm->mm != current->mm)
> > +     if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged)
> >               return -EIO;
> >
> >       if (unlikely(_IOC_TYPE(ioctl) != KVMIO))
> > @@ -3661,7 +3661,7 @@ static long kvm_vcpu_compat_ioctl(struct file *filp,
> >       void __user *argp = compat_ptr(arg);
> >       int r;
> >
> > -     if (vcpu->kvm->mm != current->mm)
> > +     if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged)
> >               return -EIO;
> >
> >       switch (ioctl) {
> > @@ -3727,7 +3727,7 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl,
> >   {
> >       struct kvm_device *dev = filp->private_data;
> >
> > -     if (dev->kvm->mm != current->mm)
> > +     if (dev->kvm->mm != current->mm || dev->kvm->vm_bugged)
> >               return -EIO;
> >
> >       switch (ioctl) {
> > @@ -4011,7 +4011,7 @@ static long kvm_vm_ioctl(struct file *filp,
> >       void __user *argp = (void __user *)arg;
> >       int r;
> >
> > -     if (kvm->mm != current->mm)
> > +     if (kvm->mm != current->mm || kvm->vm_bugged)
> >               return -EIO;
> >       switch (ioctl) {
> >       case KVM_CREATE_VCPU:
> > @@ -4219,7 +4219,7 @@ static long kvm_vm_compat_ioctl(struct file *filp,
> >       struct kvm *kvm = filp->private_data;
> >       int r;
> >
> > -     if (kvm->mm != current->mm)
> > +     if (kvm->mm != current->mm || kvm->vm_bugged)
> >               return -EIO;
> >       switch (ioctl) {
> >   #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT
>
diff mbox series

Patch

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 8583ed3f..41b652f 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -149,6 +149,7 @@  static inline bool is_error_page(struct page *page)
 #define KVM_REQ_MMU_RELOAD        (1 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
 #define KVM_REQ_UNBLOCK           2
 #define KVM_REQ_UNHALT            3
+#define KVM_REQ_VM_BUGGED         (4 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
 #define KVM_REQUEST_ARCH_BASE     8
 
 #define KVM_ARCH_REQ_FLAGS(nr, flags) ({ \
@@ -585,6 +586,7 @@  struct kvm {
 	pid_t userspace_pid;
 	unsigned int max_halt_poll_ns;
 	u32 dirty_ring_size;
+	bool vm_bugged;
 };
 
 #define kvm_err(fmt, ...) \
@@ -613,6 +615,31 @@  struct kvm {
 #define vcpu_err(vcpu, fmt, ...)					\
 	kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
 
+bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
+static inline void kvm_vm_bugged(struct kvm *kvm)
+{
+	kvm->vm_bugged = true;
+	kvm_make_all_cpus_request(kvm, KVM_REQ_VM_BUGGED);
+}
+
+#define KVM_BUG(cond, kvm, fmt...)				\
+({								\
+	int __ret = (cond);					\
+								\
+	if (WARN_ONCE(__ret && !(kvm)->vm_bugged, fmt))		\
+		kvm_vm_bugged(kvm);				\
+	unlikely(__ret);					\
+})
+
+#define KVM_BUG_ON(cond, kvm)					\
+({								\
+	int __ret = (cond);					\
+								\
+	if (WARN_ON_ONCE(__ret && !(kvm)->vm_bugged))		\
+		kvm_vm_bugged(kvm);				\
+	unlikely(__ret);					\
+})
+
 static inline bool kvm_dirty_log_manual_protect_and_init_set(struct kvm *kvm)
 {
 	return !!(kvm->manual_dirty_log_protect & KVM_DIRTY_LOG_INITIALLY_SET);
@@ -930,7 +957,6 @@  void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc);
 bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req,
 				 struct kvm_vcpu *except,
 				 unsigned long *vcpu_bitmap, cpumask_var_t tmp);
-bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
 bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req,
 				      struct kvm_vcpu *except);
 bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req,
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 93b5f76..309db8d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3455,7 +3455,7 @@  static long kvm_vcpu_ioctl(struct file *filp,
 	struct kvm_fpu *fpu = NULL;
 	struct kvm_sregs *kvm_sregs = NULL;
 
-	if (vcpu->kvm->mm != current->mm)
+	if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged)
 		return -EIO;
 
 	if (unlikely(_IOC_TYPE(ioctl) != KVMIO))
@@ -3661,7 +3661,7 @@  static long kvm_vcpu_compat_ioctl(struct file *filp,
 	void __user *argp = compat_ptr(arg);
 	int r;
 
-	if (vcpu->kvm->mm != current->mm)
+	if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged)
 		return -EIO;
 
 	switch (ioctl) {
@@ -3727,7 +3727,7 @@  static long kvm_device_ioctl(struct file *filp, unsigned int ioctl,
 {
 	struct kvm_device *dev = filp->private_data;
 
-	if (dev->kvm->mm != current->mm)
+	if (dev->kvm->mm != current->mm || dev->kvm->vm_bugged)
 		return -EIO;
 
 	switch (ioctl) {
@@ -4011,7 +4011,7 @@  static long kvm_vm_ioctl(struct file *filp,
 	void __user *argp = (void __user *)arg;
 	int r;
 
-	if (kvm->mm != current->mm)
+	if (kvm->mm != current->mm || kvm->vm_bugged)
 		return -EIO;
 	switch (ioctl) {
 	case KVM_CREATE_VCPU:
@@ -4219,7 +4219,7 @@  static long kvm_vm_compat_ioctl(struct file *filp,
 	struct kvm *kvm = filp->private_data;
 	int r;
 
-	if (kvm->mm != current->mm)
+	if (kvm->mm != current->mm || kvm->vm_bugged)
 		return -EIO;
 	switch (ioctl) {
 #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT