Skip to content

Commit

Permalink
x86: support data operand independent timing mode
Browse files Browse the repository at this point in the history
[1] specifies a long list of instructions which are intended to exhibit
timing behavior independent of the data they operate on. On certain
hardware this independence is optional, controlled by a bit in a new
MSR. Provide a command line option to control the mode Xen and its
guests are to operate in, with a build time control over the default.
Longer term we may want to allow guests to control this.

Since Arm64 supposedly also has such a control, put command line option
and Kconfig control in common files.

[1] https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html

Requested-by: Demi Marie Obenour <[email protected]>
Signed-off-by: Jan Beulich <[email protected]>
Acked-by: Roger Pau Monné <[email protected]>
Release-acked-by: Henry Wang <[email protected]>
  • Loading branch information
jbeulich committed Oct 20, 2023
1 parent 8a5ef97 commit bad1ac3
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
nodes using a device tree overlay binary (.dtbo).
- Introduce two new hypercalls to map the vCPU runstate and time areas by
physical rather than linear/virtual addresses.
- On x86, support for enforcing system-wide operation in Data Operand
Independent Timing Mode.

### Removed
- On x86, the "pku" command line option has been removed. It has never
Expand Down
11 changes: 11 additions & 0 deletions docs/misc/xen-command-line.pandoc
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,17 @@ Specify the size of the console debug trace buffer. By specifying `cpu:`
additionally a trace buffer of the specified size is allocated per cpu.
The debug trace feature is only enabled in debugging builds of Xen.

### dit (x86/Intel)
> `= <boolean>`

> Default: `CONFIG_DIT_DEFAULT`

Specify whether Xen and guests should operate in Data Independent Timing
mode (Intel calls this DOITM, Data Operand Independent Timing Mode). Note
that enabling this option cannot guarantee anything beyond what underlying
hardware guarantees (with, where available and known to Xen, respective
tweaks applied).

### dma_bits
> `= <integer>`

Expand Down
1 change: 1 addition & 0 deletions xen/arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ config X86
select HAS_ALTERNATIVE
select HAS_COMPAT
select HAS_CPUFREQ
select HAS_DIT
select HAS_EHCI
select HAS_EX_TABLE
select HAS_FAST_MULTIPLY
Expand Down
24 changes: 24 additions & 0 deletions xen/arch/x86/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,28 @@ void ctxt_switch_levelling(const struct vcpu *next)
alternative_vcall(ctxt_switch_masking, next);
}

static void setup_doitm(void)
{
uint64_t msr;

if ( !cpu_has_doitm )
return;

/*
* We don't currently enumerate DOITM to guests. As a conseqeuence, guest
* kernels will believe they're safe even when they are not.
*
* For now, set it unilaterally. This prevents otherwise-correct crypto
* code from becoming vulnerable to timing sidechannels.
*/

rdmsrl(MSR_UARCH_MISC_CTRL, msr);
msr |= UARCH_CTRL_DOITM;
if ( !opt_dit )
msr &= ~UARCH_CTRL_DOITM;
wrmsrl(MSR_UARCH_MISC_CTRL, msr);
}

bool opt_cpu_info;
boolean_param("cpuinfo", opt_cpu_info);

Expand Down Expand Up @@ -599,6 +621,8 @@ void identify_cpu(struct cpuinfo_x86 *c)

mtrr_bp_init();
}

setup_doitm();
}

/* leaf 0xb SMT level */
Expand Down
1 change: 1 addition & 0 deletions xen/arch/x86/include/asm/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ static inline bool boot_cpu_has(unsigned int feat)
#define cpu_has_tsx_ctrl boot_cpu_has(X86_FEATURE_TSX_CTRL)
#define cpu_has_taa_no boot_cpu_has(X86_FEATURE_TAA_NO)
#define cpu_has_mcu_ctrl boot_cpu_has(X86_FEATURE_MCU_CTRL)
#define cpu_has_doitm boot_cpu_has(X86_FEATURE_DOITM)
#define cpu_has_fb_clear boot_cpu_has(X86_FEATURE_FB_CLEAR)
#define cpu_has_rrsba boot_cpu_has(X86_FEATURE_RRSBA)
#define cpu_has_gds_ctrl boot_cpu_has(X86_FEATURE_GDS_CTRL)
Expand Down
18 changes: 18 additions & 0 deletions xen/common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ config HAS_COMPAT
config HAS_DEVICE_TREE
bool

config HAS_DIT # Data Independent Timing
bool

config HAS_EX_TABLE
bool

Expand Down Expand Up @@ -187,6 +190,21 @@ config SPECULATIVE_HARDEN_GUEST_ACCESS

endmenu

config DIT_DEFAULT
bool "Data Independent Timing default"
depends on HAS_DIT
help
Hardware often surfaces instructions the timing of which is dependent
on the data they process. Some of these instructions may be used in
timing sensitive environments, e.g. cryptography. When such
instructions exist, hardware may further surface a control allowing
to make the behavior of such instructions independent of the data
they act upon. Note the build time value can be overridden at runtime
using the "dit" command line option.

NB: Intel calls the feature DOITM (Data Operand Independent Timing
Mode).

config HYPFS
bool "Hypervisor file system support"
default y
Expand Down
5 changes: 5 additions & 0 deletions xen/common/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ CHECK_feature_info;

enum system_state system_state = SYS_STATE_early_boot;

#ifdef CONFIG_HAS_DIT
bool __ro_after_init opt_dit = IS_ENABLED(CONFIG_DIT_DEFAULT);
boolean_param("dit", opt_dit);
#endif

static xen_commandline_t saved_cmdline;
static const char __initconst opt_builtin_cmdline[] = CONFIG_CMDLINE;

Expand Down
2 changes: 2 additions & 0 deletions xen/include/xen/param.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
string_param(_name, _var); \
string_runtime_only_param(_name, _var)

extern bool opt_dit;

static inline void no_config_param(const char *cfg, const char *param,
const char *s, const char *e)
{
Expand Down

0 comments on commit bad1ac3

Please sign in to comment.