[v3,17/18] KVM: x86: Force kvm_rebooting=true during emergency reboot/crash

Message ID 20230512235026.808058-18-seanjc@google.com
State New
Headers
Series x86/reboot: KVM: Clean up "emergency" virt code |

Commit Message

Sean Christopherson May 12, 2023, 11:50 p.m. UTC
  Set kvm_rebooting when virtualization is disabled in an emergency so that
KVM eats faults on virtualization instructions even if kvm_reboot() isn't
reached.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/svm/svm.c | 2 ++
 arch/x86/kvm/vmx/vmx.c | 2 ++
 2 files changed, 4 insertions(+)
  

Comments

Kai Huang May 22, 2023, 11:25 p.m. UTC | #1
On Fri, 2023-05-12 at 16:50 -0700, Sean Christopherson wrote:
> Set kvm_rebooting when virtualization is disabled in an emergency so that
> KVM eats faults on virtualization instructions even if kvm_reboot() isn't
> reached.
> 
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
>  arch/x86/kvm/svm/svm.c | 2 ++
>  arch/x86/kvm/vmx/vmx.c | 2 ++
>  2 files changed, 4 insertions(+)
> 
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 2cc195d95d32..d00da133b14f 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -611,6 +611,8 @@ static inline void kvm_cpu_svm_disable(void)
>  
>  static void svm_emergency_disable(void)
>  {
> +	kvm_rebooting = true;
> +
>  	kvm_cpu_svm_disable();
>  }
>  
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 008914396180..1dec932aff21 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -771,6 +771,8 @@ static void vmx_emergency_disable(void)
>  	int cpu = raw_smp_processor_id();
>  	struct loaded_vmcs *v;
>  
> +	kvm_rebooting = true;

Do we need a memory barrier here?

> +
>  	list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu),
>  			    loaded_vmcss_on_cpu_link)
>  		vmcs_clear(v->vmcs);
> -- 
> 2.40.1.606.ga4b1b128d6-goog
>
  
Kai Huang May 23, 2023, 2:02 a.m. UTC | #2
On Tue, 2023-05-23 at 11:25 +1200, Kai Huang wrote:
> On Fri, 2023-05-12 at 16:50 -0700, Sean Christopherson wrote:
> > Set kvm_rebooting when virtualization is disabled in an emergency so that
> > KVM eats faults on virtualization instructions even if kvm_reboot() isn't
> > reached.
> > 
> > Signed-off-by: Sean Christopherson <seanjc@google.com>
> > ---
> >  arch/x86/kvm/svm/svm.c | 2 ++
> >  arch/x86/kvm/vmx/vmx.c | 2 ++
> >  2 files changed, 4 insertions(+)
> > 
> > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> > index 2cc195d95d32..d00da133b14f 100644
> > --- a/arch/x86/kvm/svm/svm.c
> > +++ b/arch/x86/kvm/svm/svm.c
> > @@ -611,6 +611,8 @@ static inline void kvm_cpu_svm_disable(void)
> >  
> >  static void svm_emergency_disable(void)
> >  {
> > +	kvm_rebooting = true;
> > +
> >  	kvm_cpu_svm_disable();
> >  }
> >  
> > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> > index 008914396180..1dec932aff21 100644
> > --- a/arch/x86/kvm/vmx/vmx.c
> > +++ b/arch/x86/kvm/vmx/vmx.c
> > @@ -771,6 +771,8 @@ static void vmx_emergency_disable(void)
> >  	int cpu = raw_smp_processor_id();
> >  	struct loaded_vmcs *v;
> >  
> > +	kvm_rebooting = true;
> 
> Do we need a memory barrier here?
> 

Hmm.. Please ignore this.  I was confused between cache coherency vs memory
ordering.  Not enough coffee.

Reviewed-by: Kai Huang <kai.huang@intel.com>
  

Patch

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 2cc195d95d32..d00da133b14f 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -611,6 +611,8 @@  static inline void kvm_cpu_svm_disable(void)
 
 static void svm_emergency_disable(void)
 {
+	kvm_rebooting = true;
+
 	kvm_cpu_svm_disable();
 }
 
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 008914396180..1dec932aff21 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -771,6 +771,8 @@  static void vmx_emergency_disable(void)
 	int cpu = raw_smp_processor_id();
 	struct loaded_vmcs *v;
 
+	kvm_rebooting = true;
+
 	list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu),
 			    loaded_vmcss_on_cpu_link)
 		vmcs_clear(v->vmcs);