Skip to content
Permalink
Browse files
x86/tdx: Skip WBINVD instruction for TDX guest
Drivers/code-paths that use wbinvd instruction are already disabled
for TDX guest platforms. Following are the list of drivers that use
wbinvd instruction and are enabled for TDX guests.

drivers/acpi/sleep.c
drivers/acpi/acpica/hwsleep.c

Since cache is always coherent in TDX guests, making wbinvd as noop
should not cause any issues. This behavior is the same as KVM guest.

So skip its usage for TDX the guests. Also, hwsleep shouldn't happen
for TDX guest because the TDX BIOS won't enable it, but it's better
to disable it anyways

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
  • Loading branch information
Kuppuswamy Sathyanarayanan committed May 13, 2021
1 parent cfbf8e1 commit 96c781481b4771fb0fb4cc62072a6b1b50a0cea2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
@@ -9,6 +9,7 @@
*****************************************************************************/

#include <acpi/acpi.h>
#include <linux/protected_guest.h>
#include "accommon.h"

#define _COMPONENT ACPI_HARDWARE
@@ -108,9 +109,14 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
pm1a_control |= sleep_enable_reg_info->access_bit_mask;
pm1b_control |= sleep_enable_reg_info->access_bit_mask;

/* Flush caches, as per ACPI specification */

ACPI_FLUSH_CPU_CACHE();
/*
* WBINVD instruction is not supported in TDX
* guest. Since ACPI_FLUSH_CPU_CACHE() uses
* WBINVD, skip cache flushes for TDX guests.
*/
if (!protected_guest_has(GUEST_TYPE_TDX))
/* Flush caches, as per ACPI specification */
ACPI_FLUSH_CPU_CACHE();

status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control);
if (status == AE_CTRL_TERMINATE) {
@@ -18,6 +18,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/syscore_ops.h>
#include <linux/protected_guest.h>
#include <asm/io.h>
#include <trace/events/power.h>

@@ -71,7 +72,14 @@ static int acpi_sleep_prepare(u32 acpi_state)
acpi_set_waking_vector(acpi_wakeup_address);

}
ACPI_FLUSH_CPU_CACHE();

/*
* WBINVD instruction is not supported in TDX
* guest. Since ACPI_FLUSH_CPU_CACHE() uses
* WBINVD, skip cache flushes for TDX guests.
*/
if (!protected_guest_has(GUEST_TYPE_TDX))
ACPI_FLUSH_CPU_CACHE();
#endif
printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
acpi_state);
@@ -566,7 +574,13 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
u32 acpi_state = acpi_target_sleep_state;
int error;

ACPI_FLUSH_CPU_CACHE();
/*
* WBINVD instruction is not supported in TDX
* guest. Since ACPI_FLUSH_CPU_CACHE() uses
* WBINVD, skip cache flushes for TDX guests.
*/
if (!protected_guest_has(GUEST_TYPE_TDX))
ACPI_FLUSH_CPU_CACHE();

trace_suspend_resume(TPS("acpi_suspend"), acpi_state, true);
switch (acpi_state) {
@@ -899,7 +913,13 @@ static int acpi_hibernation_enter(void)
{
acpi_status status = AE_OK;

ACPI_FLUSH_CPU_CACHE();
/*
* WBINVD instruction is not supported in TDX
* guest. Since ACPI_FLUSH_CPU_CACHE() uses
* WBINVD, skip cache flushes for TDX guests.
*/
if (!protected_guest_has(GUEST_TYPE_TDX))
ACPI_FLUSH_CPU_CACHE();

/* This shouldn't return. If it returns, we have a problem */
status = acpi_enter_sleep_state(ACPI_STATE_S4);

0 comments on commit 96c7814

Please sign in to comment.