From: Sean Christopherson <seanjc@google.com>
To: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
Andrew Cooper <Andrew.Cooper3@citrix.com>
Subject: [PATCH 01/16] x86/reboot: VMCLEAR active VMCSes before emergency reboot
Date: Thu, 1 Dec 2022 23:26:40 +0000 [thread overview]
Message-ID: <20221201232655.290720-2-seanjc@google.com> (raw)
In-Reply-To: <20221201232655.290720-1-seanjc@google.com>
VMCLEAR active VMCSes before any emergency reboot, not just if the kernel
may kexec into a new kernel after a crash. Per Intel's SDM, the VMX
architecture doesn't require the CPU to flush the VMCS cache on INIT. If
an emergency reboot doesn't RESET CPUs, cached VMCSes could theoretically
be kept and only be written back to memory after the new kernel is booted,
i.e. could effectively corrupt memory after reboot.
Opportunistically remove the setting of the global pointer to NULL to make
checkpatch happy.
Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/kexec.h | 2 --
arch/x86/include/asm/reboot.h | 2 ++
arch/x86/kernel/crash.c | 31 -------------------------------
arch/x86/kernel/reboot.c | 22 ++++++++++++++++++++++
arch/x86/kvm/vmx/vmx.c | 10 +++-------
5 files changed, 27 insertions(+), 40 deletions(-)
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index a3760ca796aa..256eee99afc8 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -208,8 +208,6 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image);
#endif
#endif
-typedef void crash_vmclear_fn(void);
-extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss;
extern void kdump_nmi_shootdown_cpus(void);
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h
index bc5b4d788c08..2551baec927d 100644
--- a/arch/x86/include/asm/reboot.h
+++ b/arch/x86/include/asm/reboot.h
@@ -25,6 +25,8 @@ void __noreturn machine_real_restart(unsigned int type);
#define MRR_BIOS 0
#define MRR_APM 1
+typedef void crash_vmclear_fn(void);
+extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss;
void cpu_emergency_disable_virtualization(void);
typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 6b8a6aae02e3..7611dd5f90a4 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -48,38 +48,12 @@ struct crash_memmap_data {
unsigned int type;
};
-/*
- * This is used to VMCLEAR all VMCSs loaded on the
- * processor. And when loading kvm_intel module, the
- * callback function pointer will be assigned.
- *
- * protected by rcu.
- */
-crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss = NULL;
-EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss);
-
-static inline void cpu_crash_vmclear_loaded_vmcss(void)
-{
- crash_vmclear_fn *do_vmclear_operation = NULL;
-
- rcu_read_lock();
- do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss);
- if (do_vmclear_operation)
- do_vmclear_operation();
- rcu_read_unlock();
-}
-
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
{
crash_save_cpu(regs, cpu);
- /*
- * VMCLEAR VMCSs loaded on all cpus if needed.
- */
- cpu_crash_vmclear_loaded_vmcss();
-
/*
* Disable Intel PT to stop its logging
*/
@@ -133,11 +107,6 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
crash_smp_send_stop();
- /*
- * VMCLEAR VMCSs loaded on this cpu if needed.
- */
- cpu_crash_vmclear_loaded_vmcss();
-
cpu_emergency_disable_virtualization();
/*
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index d03c551defcc..299b970e5f82 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -787,6 +787,26 @@ void machine_crash_shutdown(struct pt_regs *regs)
}
#endif
+/*
+ * This is used to VMCLEAR all VMCSs loaded on the
+ * processor. And when loading kvm_intel module, the
+ * callback function pointer will be assigned.
+ *
+ * protected by rcu.
+ */
+crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss;
+EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss);
+
+static inline void cpu_crash_vmclear_loaded_vmcss(void)
+{
+ crash_vmclear_fn *do_vmclear_operation = NULL;
+
+ rcu_read_lock();
+ do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss);
+ if (do_vmclear_operation)
+ do_vmclear_operation();
+ rcu_read_unlock();
+}
/* This is the CPU performing the emergency shutdown work. */
int crashing_cpu = -1;
@@ -798,6 +818,8 @@ int crashing_cpu = -1;
*/
void cpu_emergency_disable_virtualization(void)
{
+ cpu_crash_vmclear_loaded_vmcss();
+
cpu_emergency_vmxoff();
cpu_emergency_svm_disable();
}
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 39dd3082fcd8..7ea020456dd0 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -41,7 +41,7 @@
#include <asm/idtentry.h>
#include <asm/io.h>
#include <asm/irq_remapping.h>
-#include <asm/kexec.h>
+#include <asm/reboot.h>
#include <asm/perf_event.h>
#include <asm/mmu_context.h>
#include <asm/mshyperv.h>
@@ -743,7 +743,6 @@ static int vmx_set_guest_uret_msr(struct vcpu_vmx *vmx,
return ret;
}
-#ifdef CONFIG_KEXEC_CORE
static void crash_vmclear_local_loaded_vmcss(void)
{
int cpu = raw_smp_processor_id();
@@ -753,7 +752,6 @@ static void crash_vmclear_local_loaded_vmcss(void)
loaded_vmcss_on_cpu_link)
vmcs_clear(v->vmcs);
}
-#endif /* CONFIG_KEXEC_CORE */
static void __loaded_vmcs_clear(void *arg)
{
@@ -8528,10 +8526,9 @@ static void __vmx_exit(void)
{
allow_smaller_maxphyaddr = false;
-#ifdef CONFIG_KEXEC_CORE
RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL);
synchronize_rcu();
-#endif
+
vmx_cleanup_l1d_flush();
}
@@ -8580,10 +8577,9 @@ static int __init vmx_init(void)
pi_init_cpu(cpu);
}
-#ifdef CONFIG_KEXEC_CORE
rcu_assign_pointer(crash_vmclear_loaded_vmcss,
crash_vmclear_local_loaded_vmcss);
-#endif
+
vmx_check_vmcs12_offsets();
/*
--
2.39.0.rc0.267.gcb52ba06e7-goog
next prev parent reply other threads:[~2022-12-01 23:27 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-01 23:26 [PATCH 00/16] x86/reboot: KVM: Clean up "emergency" virt code Sean Christopherson
2022-12-01 23:26 ` Sean Christopherson [this message]
2022-12-01 23:26 ` [PATCH 02/16] x86/reboot: Expose VMCS crash hooks if and only if KVM_INTEL is enabled Sean Christopherson
2022-12-01 23:26 ` [PATCH 03/16] x86/reboot: Harden virtualization hooks for emergency reboot Sean Christopherson
2022-12-01 23:26 ` [PATCH 04/16] x86/reboot: Assert that IRQs are disabled when turning off virtualization Sean Christopherson
2022-12-01 23:26 ` [PATCH 05/16] x86/reboot: KVM: Handle VMXOFF in KVM's reboot callback Sean Christopherson
2022-12-01 23:26 ` [PATCH 06/16] x86/reboot: KVM: Disable SVM during reboot via virt/KVM " Sean Christopherson
2022-12-01 23:26 ` [PATCH 07/16] x86/reboot: Hoist "disable virt" helpers above "emergency reboot" path Sean Christopherson
2022-12-01 23:26 ` [PATCH 08/16] x86/reboot: Disable virtualization during reboot iff callback is registered Sean Christopherson
2022-12-01 23:26 ` [PATCH 09/16] x86/virt: KVM: Open code cpu_has_vmx() in KVM VMX Sean Christopherson
2022-12-01 23:26 ` [PATCH 10/16] x86/virt: KVM: Move VMXOFF helpers into " Sean Christopherson
2022-12-01 23:26 ` [PATCH 11/16] KVM: SVM: Make KVM_AMD depend on CPU_SUP_AMD or CPU_SUP_HYGON Sean Christopherson
2022-12-01 23:26 ` [PATCH 12/16] x86/virt: Drop unnecessary check on extended CPUID level in cpu_has_svm() Sean Christopherson
2022-12-01 23:26 ` [PATCH 13/16] x86/virt: KVM: Open code cpu_has_svm() into kvm_is_svm_supported() Sean Christopherson
2022-12-01 23:26 ` [PATCH 14/16] x86/virt: KVM: Move "disable SVM" helper into KVM SVM Sean Christopherson
2022-12-01 23:26 ` [PATCH 15/16] KVM: x86: Force kvm_rebooting=true during emergency reboot/crash Sean Christopherson
2022-12-01 23:26 ` [PATCH 16/16] KVM: SVM: Use "standard" stgi() helper when disabling SVM Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221201232655.290720-2-seanjc@google.com \
--to=seanjc@google.com \
--cc=Andrew.Cooper3@citrix.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®