Messages in this thread Patch in this message | | | From | Kuppuswamy Sathyanarayanan <> | Subject | [PATCH v1 1/1] x86: Skip WBINVD instruction for VM guest | Date | Mon, 15 Nov 2021 16:50:27 -0800 |
| |
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@rjwysocki.net> Cc: linux-acpi@vger.kernel.org Reviewed-by: Dan Williams <dan.j.williams@intel.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> --- 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..d4162e94bee8 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 (!boot_cpu_has(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
| |