@@ -129,7 +129,7 @@ relocate_kernel(unsigned long indirection_page,
unsigned long page_list,
unsigned long start_address,
unsigned int preserve_context,
- unsigned int host_mem_enc_active);
+ unsigned int bare_metal);
#endif
#define ARCH_HAS_KIMAGE_ARCH
@@ -358,7 +358,7 @@ void machine_kexec(struct kimage *image)
(unsigned long)page_list,
image->start,
image->preserve_context,
- cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT));
+ !boot_cpu_has(X86_FEATURE_HYPERVISOR));
#ifdef CONFIG_KEXEC_JUMP
if (image->preserve_context)
@@ -50,7 +50,7 @@ SYM_CODE_START_NOALIGN(relocate_kernel)
* %rsi page_list
* %rdx start address
* %rcx preserve_context
- * %r8 host_mem_enc_active
+ * %r8 bare_metal
*/
/* Save the CPU context, used for jumping back */
@@ -78,7 +78,7 @@ SYM_CODE_START_NOALIGN(relocate_kernel)
pushq $0
popfq
- /* Save SME active flag */
+ /* Save the bare_metal flag */
movq %r8, %r12
/*
@@ -160,9 +160,20 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
movq %r9, %cr3
/*
- * If SME is active, there could be old encrypted cache line
+ * The kernel could leave caches in incoherent state on SME/TDX
+ * capable platforms. Just do unconditional WBINVD to avoid
+ * silent memory corruption to the new kernel for these platforms.
+ *
+ * For SME, need to flush cache here before copying the kernel.
+ * When it is active, there could be old encrypted cache line
* entries that will conflict with the now unencrypted memory
- * used by kexec. Flush the caches before copying the kernel.
+ * used by kexec.
+ *
+ * Do WBINVD for bare-metal only to cover both SME and TDX. It
+ * isn't necessary to perform a WBINVD in a guest and performing
+ * one could result in an exception (#VE or #VC) for a TDX or
+ * SEV-ES/SEV-SNP guest that can crash the guest since, at this
+ * stage, the kernel has torn down the IDT.
*/
testq %r12, %r12
jz 1f