ACPI mandates that CPU caches be flushed before entering any sleep state. This ensures that the CPU and its caches can be powered down without losing data. ACPI-based VMs have maintained this sleep-state-entry behavior. However, cache flushing for VM sleep state entry is useless. Unlike on bare metal, guest sleep states are not correlated with potential data loss of any kind; the host is responsible for data preservation. In fact, some KVM configurations simply skip the cache flushing instruction (see need_emulate_wbinvd()). Further, on TDX systems, the WBINVD instruction causes an unconditional #VE exception. If this cache flushing remained, it would need extra code in the form of a #VE handler. All use of ACPI_FLUSH_CPU_CACHE() appears to be in sleep-state-related code. This means that the ACPI use of WBINVD is at *best* superfluous. Disable ACPI CPU cache flushing on all X86_FEATURE_HYPERVISOR systems, which includes TDX. Cc: Rafael J. Wysocki <rjw@xxxxxxxxxxxxx> Cc: linux-acpi@xxxxxxxxxxxxxxx Reviewed-by: Dan Williams <dan.j.williams@xxxxxxxxx> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@xxxxxxxxxxxxxxx> --- Changes since v1: * Used cpu_feature_enabled() instead of boot_cpu_has(). arch/x86/include/asm/acenv.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/acenv.h b/arch/x86/include/asm/acenv.h index 9aff97f0de7f..dba05c74bd7e 100644 --- a/arch/x86/include/asm/acenv.h +++ b/arch/x86/include/asm/acenv.h @@ -10,10 +10,15 @@ #define _ASM_X86_ACENV_H #include <asm/special_insns.h> +#include <asm/cpu.h> /* Asm macros */ -#define ACPI_FLUSH_CPU_CACHE() wbinvd() +#define ACPI_FLUSH_CPU_CACHE() \ +do { \ + if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) \ + wbinvd(); \ +} while (0) int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock); -- 2.25.1