Skip to content

Commit

Permalink
Tentatively working for DDP PF. Also changed PF flags for 12/13th gen…
Browse files Browse the repository at this point in the history
…, SSBD check
  • Loading branch information
brianfu committed Aug 6, 2024
1 parent 654c570 commit ae98891
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 6 deletions.
8 changes: 8 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,14 @@ Default: True

Enable a microcode patch against Speculative Store Bypass, if available.

```yaml
Name: x86_executor_disable_ddp_prefetcher
Default: True
```

Enable a microcode patch to disable the Data-Dependent Prefetcher, if available.
Currently only supported on Intel 13th gen Raptor Lake and above.

```yaml
Name: x86_executor_enable_prefetcher
Default: False
Expand Down
3 changes: 2 additions & 1 deletion src/x86/executor/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
*.mod
*.mod.c
start_qemu.sh
update_module.sh
update_module.sh
coverage.txt
2 changes: 2 additions & 0 deletions src/x86/executor/include/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ extern long uarch_reset_rounds;
#define UARCH_RESET_ROUNDS_DEFAULT 1
extern bool enable_ssbp_patch;
#define SSBP_PATCH_DEFAULT true
extern bool disable_ddp_prefetcher;
#define DISABLE_DDP_DEFAULT true
extern bool enable_prefetchers;
#define PREFETCHER_DEFAULT false
extern char pre_run_flush;
Expand Down
2 changes: 2 additions & 0 deletions src/x86/executor/include/shortcuts.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
// Printing
#define PRINT_ERR(msg, ...) printk(KERN_ERR "[x86_executor] " msg, ##__VA_ARGS__);
#define PRINT_ERRS(src, msg, ...) printk(KERN_ERR "[x86_executor:" src "] " msg, ##__VA_ARGS__);
#define PRINT_WARN(msg, ...) printk(KERN_WARNING "[x86_executor] WARNING: " msg, ##__VA_ARGS__);
#define PRINT_WARNS(src, msg, ...) printk(KERN_WARNING "[x86_executor:" src "] WARNING: " msg, ##__VA_ARGS__);

// Error handling
#define ASSERT(condition, src) \
Expand Down
3 changes: 3 additions & 0 deletions src/x86/executor/include/special_registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@ void restore_special_registers(void);
int init_special_register_manager(void);
void free_special_register_manager(void);

// Ideally this would just be in the kernel headers already for MSR_IA32_SPEC_CTRL
#define SPEC_CTRL_DDPD_U_SHIFT 8 /* Data Dependent Prefetcher Disable bit */
#define SPEC_CTRL_DDPD_U BIT(SPEC_CTRL_DDPD_U_SHIFT) /* Data Dependent Prefetcher Disable */

#endif // _MSR_H_
19 changes: 19 additions & 0 deletions src/x86/executor/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ bool quick_and_dirty_mode = false;

long uarch_reset_rounds = UARCH_RESET_ROUNDS_DEFAULT;
bool enable_ssbp_patch = SSBP_PATCH_DEFAULT;
bool disable_ddp_prefetcher = DISABLE_DDP_DEFAULT;
bool enable_prefetchers = PREFETCHER_DEFAULT;
bool enable_mpx = MPX_DEFAULT; // unused on AMD
char pre_run_flush = PRE_RUN_FLUSH_DEFAULT;
Expand Down Expand Up @@ -141,6 +142,13 @@ static ssize_t enable_ssbp_patch_store(struct kobject *kobj, struct kobj_attribu
static struct kobj_attribute enable_ssbp_patch_attribute =
__ATTR(enable_ssbp_patch, 0666, NULL, enable_ssbp_patch_store);

/// Control disable DDP prefetcher
///
static ssize_t disable_ddp_prefetcher_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count);
static struct kobj_attribute disable_ddp_prefetcher_attribute =
__ATTR(disable_ddp_prefetcher, 0666, NULL, disable_ddp_prefetcher_store);

/// Control prefetchers
///
static ssize_t enable_prefetcher_store(struct kobject *kobj, struct kobj_attribute *attr,
Expand Down Expand Up @@ -209,6 +217,7 @@ static struct attribute *sysfs_attributes[] = {
&print_sandbox_base_attribute.attr,
&print_code_base_attribute.attr,
&enable_ssbp_patch_attribute.attr,
&disable_ddp_prefetcher_attribute.attr,
&enable_prefetcher_attribute.attr,
&enable_pre_run_flush_attribute.attr,
&measurement_mode_attribute.attr,
Expand Down Expand Up @@ -377,6 +386,15 @@ static ssize_t enable_ssbp_patch_store(struct kobject *kobj, struct kobj_attribu
return count;
}

static ssize_t disable_ddp_prefetcher_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
unsigned value = 0;
sscanf(buf, "%u", &value);
disable_ddp_prefetcher = (value == 0) ? false : true;
return count;
}

static ssize_t enable_prefetcher_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
Expand Down Expand Up @@ -508,6 +526,7 @@ static ssize_t dbg_dump_show(struct kobject *kobj, struct kobj_attribute *attr,
len += sprintf(&buf[len], "quick_and_dirty_mode: %d\n", quick_and_dirty_mode);
len += sprintf(&buf[len], "uarch_reset_rounds: %ld\n", uarch_reset_rounds);
len += sprintf(&buf[len], "enable_ssbp_patch: %d\n", enable_ssbp_patch);
len += sprintf(&buf[len], "disable_ddp_prefetcher: %d\n", disable_ddp_prefetcher);
len += sprintf(&buf[len], "enable_prefetchers: %d\n", enable_prefetchers);
len += sprintf(&buf[len], "pre_run_flush: %d\n", pre_run_flush);
len += sprintf(&buf[len], "enable_mpx: %d\n", enable_mpx);
Expand Down
57 changes: 52 additions & 5 deletions src/x86/executor/special_registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static int set_msrs_for_svm(void)

static int get_ssbp_patch_msr_ctrls(uint64_t *msr_id, uint64_t *msr_mask)
{
if (cpu_has(cpuinfo, X86_FEATURE_MSR_SPEC_CTRL)) {
if (cpu_has(cpuinfo, X86_FEATURE_MSR_SPEC_CTRL) && cpu_has(cpuinfo, X86_FEATURE_SPEC_CTRL_SSBD)) {
*msr_id = MSR_IA32_SPEC_CTRL;
*msr_mask = SPEC_CTRL_SSBD;
} else if (cpu_has(cpuinfo, X86_FEATURE_VIRT_SSBD)) {
Expand Down Expand Up @@ -106,15 +106,50 @@ static int get_ssbp_patch_msr_ctrls(uint64_t *msr_id, uint64_t *msr_mask)
return 0;
}

static int check_ddpd_u_bit(void)
{
// Structured Extended Feature Enumeration Sub-leaf (Initial EAX Value = 07H, ECX = 2)
uint32_t eax, ebx, ecx, edx;
cpuid_count(7, 2, &eax, &ebx, &ecx, &edx);

if (edx & (0b1000)) {
// Bit 03: DDPD_U. If 1, indicates bit 8 of the IA32_SPEC_CTRL MSR is supported.
// Bit 8 of this MSR disables Data Dependent Prefetcher.
return 1; // True
}
return 0; // False
}

static int get_disable_ddp_prefetcher_msr_ctrls(uint64_t *msr_id, uint64_t *msr_mask)
{
if (cpu_has(cpuinfo, X86_FEATURE_MSR_SPEC_CTRL) && check_ddpd_u_bit()) {
*msr_id = MSR_IA32_SPEC_CTRL;
*msr_mask = SPEC_CTRL_DDPD_U;
} else {
// Can leave system as-is if no patch avaliable
PRINT_WARNS("get_disable_ddp_prefetcher_msr_ctrls", "Unable to control DDP prefetcher on this CPU; no known method\n");
PRINT_WARN("13th gen Raptor Lake or above required for DDP prefetcher\n");
}
return 0;
}

static int get_prefetcher_msr_ctrls(uint64_t *msr_id, uint64_t *msr_mask)
{
if (cpuinfo->x86_vendor == X86_VENDOR_INTEL) {
*msr_id = MSR_MISC_FEATURE_CONTROL;
switch (cpuinfo->x86_model) {
case 0x97:
case 0x9a:
case 0xba:
case 0xb7:
case 0x97: // Alder Lake S
*msr_mask = 0b101111; // L2 AMP Prefetcher
break;
case 0x9a: // Alder Lake P
*msr_mask = 0b101111;
break;
case 0xba: // Raptor Lake P
*msr_mask = 0b101111;
break;
case 0xb7: // Raptor Lake S
*msr_mask = 0b101111;
break;
case 0xbf:
*msr_mask = 0b101111;
break;
Expand Down Expand Up @@ -182,6 +217,13 @@ int set_special_registers(void)
err = apply_msr_mask(msr_id, msr_mask, enable_ssbp_patch);
CHECK_ERR("set_enable_ssbp_patch");

// Data Dependent Prefetcher (DDP) disable
err = get_disable_ddp_prefetcher_msr_ctrls(&msr_id, &msr_mask);
orig_special_registers_state->spec_ctrl = rdmsr64(msr_id);
CHECK_ERR("set_disable_ddp_prefetcher");
err = apply_msr_mask(msr_id, msr_mask, disable_ddp_prefetcher);
CHECK_ERR("set_disable_ddp_prefetcher");

// Prefetcher control
#ifndef VMBUILD
err = get_prefetcher_msr_ctrls(&msr_id, &msr_mask);
Expand Down Expand Up @@ -266,6 +308,11 @@ void restore_special_registers(void)
wrmsr64(msr_id, orig_special_registers_state->spec_ctrl);
}

if (orig_special_registers_state->spec_ctrl != 0) {
get_disable_ddp_prefetcher_msr_ctrls(&msr_id, &msr_mask);
wrmsr64(msr_id, orig_special_registers_state->spec_ctrl);
}

if (orig_special_registers_state->prefetcher_ctrl != 0) {
get_prefetcher_msr_ctrls(&msr_id, &msr_mask);
wrmsr64(msr_id, orig_special_registers_state->prefetcher_ctrl);
Expand Down
2 changes: 2 additions & 0 deletions src/x86/x86_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ def try_get_cpu_vendor():

x86_executor_enable_prefetcher: bool = False
""" x86_executor_enable_prefetcher: enable all prefetchers"""
x86_executor_disable_ddp_prefetcher: bool = True
""" x86_executor_disable_ddp_prefetcher: disable DDP prefetcher (if bit==1)"""
x86_executor_enable_ssbp_patch: bool = True
""" x86_executor_enable_ssbp_patch: enable a patch against Speculative Store Bypass"""
x86_enable_hpa_gpa_collisions: bool = False
Expand Down
9 changes: 9 additions & 0 deletions src/x86/x86_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,18 @@ def is_kernel_module_installed() -> bool:


def configure_kernel_module() -> None:
# Setting IA32_SPEC_CTRL bit 2 (SSBD) also disables the DDP
if (getattr(CONF, 'x86_executor_enable_ssbp_patch')
and not getattr(CONF, 'x86_executor_disable_ddp_prefetcher')):
LOG = Logger()
LOG.warning("executor", "Enabling DDP prefetcher requires \
Speculative Store Bypass Protection to be disabled")

km_write(CONF.executor_warmups, '/sys/x86_executor/warmups')
km_write("1" if getattr(CONF, 'x86_executor_enable_ssbp_patch') else "0",
"/sys/x86_executor/enable_ssbp_patch")
km_write("1" if getattr(CONF, 'x86_executor_disable_ddp_prefetcher') else "0",
"/sys/x86_executor/disable_ddp_prefetcher")
km_write("1" if getattr(CONF, 'x86_executor_enable_prefetcher') else "0",
"/sys/x86_executor/enable_prefetcher")
km_write("1" if CONF.enable_pre_run_flush else "0", "/sys/x86_executor/enable_pre_run_flush")
Expand Down

0 comments on commit ae98891

Please sign in to comment.