Skip to content

Commit

Permalink
ACPICA: Avoid cache flush inside virtual machines
Browse files Browse the repository at this point in the history
[ Upstream commit e2efb63 ]

While running inside virtual machine, the kernel can bypass cache
flushing. Changing sleep state in a virtual machine doesn't affect the
host system sleep state and cannot lead to data loss.

Before entering sleep states, the ACPI code flushes caches to prevent
data loss using the WBINVD instruction.  This mechanism is required on
bare metal.

But, any use WBINVD inside of a guest is worthless.  Changing sleep
state in a virtual machine doesn't affect the host system sleep state
and cannot lead to data loss, so most hypervisors simply ignore it.
Despite this, the ACPI code calls WBINVD unconditionally anyway.
It's useless, but also normally harmless.

In TDX guests, though, WBINVD stops being harmless; it triggers a
virtualization exception (#VE).  If the ACPI cache-flushing WBINVD
were left in place, TDX guests would need handling to recover from
the exception.

Avoid using WBINVD whenever running under a hypervisor.  This both
removes the useless WBINVDs and saves TDX from implementing WBINVD
handling.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20220405232939.73860-30-kirill.shutemov@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
kiryl authored and gregkh committed Jun 9, 2022
1 parent 29cb802 commit cd97a48
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion arch/x86/include/asm/acenv.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,19 @@

/* Asm macros */

#define ACPI_FLUSH_CPU_CACHE() wbinvd()
/*
* ACPI_FLUSH_CPU_CACHE() flushes caches on entering sleep states.
* It is required to prevent data loss.
*
* While running inside virtual machine, the kernel can bypass cache flushing.
* Changing sleep state in a virtual machine doesn't affect the host system
* sleep state and cannot lead to data loss.
*/
#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);
Expand Down

0 comments on commit cd97a48

Please sign in to comment.