Skip to content

Commit 9974200

Browse files
ethindpjosephlr
authored andcommitted
registers: add extra flags for CR0, CR4, and XCR0
Alos, add extra checks when writing to XCR0. Signed-off-by: Ethin Probst <[email protected]> Signed-off-by: Joe Richey <[email protected]>
1 parent 134cacd commit 9974200

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

src/registers/control.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ bitflags! {
2424
///
2525
/// This flags allows lazily saving x87/MMX/SSE instructions on hardware context switches.
2626
const TASK_SWITCHED = 1 << 3;
27+
/// Indicates support of 387DX math coprocessor instructions when set
28+
const EXTENSION_TYPE = 1 << 4;
2729
/// Enables the native error reporting mechanism for x87 FPU errors.
2830
const NUMERIC_ERROR = 1 << 5;
2931
/// Controls whether supervisor-level writes to read-only pages are inhibited.
@@ -114,14 +116,20 @@ bitflags! {
114116
const PCID = 1 << 17;
115117
/// Enables extendet processor state management instructions, including XGETBV and XSAVE.
116118
const OSXSAVE = 1 << 18;
119+
/// When set, the `LOADIWKEY` instruction is available; additionally, if system firmware has activated the AES key locker instructions, register EBX of CPUID leaf 0x19, bit 0 (AESKLE) is set and the AES key locker instructions are enabled. See the [Intel Key Locker Specification](https://software.intel.com/content/www/us/en/develop/download/intel-key-locker-specification.html) for information on this feature.
120+
const KEY_LOCKER = 1 << 19;
117121
/// Prevents the execution of instructions that reside in pages accessible by user-mode
118122
/// software when the processor is in supervisor-mode.
119123
const SUPERVISOR_MODE_EXECUTION_PROTECTION = 1 << 20;
120124
/// Enables restrictions for supervisor-mode software when reading data from user-mode
121125
/// pages.
122126
const SUPERVISOR_MODE_ACCESS_PREVENTION = 1 << 21;
123-
/// Enables 4-level paging to associate each linear address with a protection key.
127+
/// Enables 4-level and 5-level paging to associate each linear address with a protection key in user mode.
124128
const PROTECTION_KEY = 1 << 22;
129+
/// When set, enables intel control-flow enforcement technology. See chapter 18 of the Intel software developer manuals, volume 1, for more information.
130+
const CONTROL_FLOW_ENFORCEMENT = 1 << 23;
131+
/// When set, allows 4-level and 5-level paging implementations to use the `IA32_PKRS` MSR to specify, for each protection key, whether supervisor-mode linear addresses with a particular protection key can be read or written.
132+
const PROTECTION_KEY_SUPERVISOR = 1 << 24;
125133
}
126134
}
127135

src/registers/xcontrol.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,18 @@ bitflags! {
1616
/// Enables 256-bit SSE
1717
/// Must be set to enable AVX
1818
const YMM = 1<<2;
19+
/// When set, MPX instructions are enabled and the bound registers BND0-BND3 can be managed by XSAVE.
20+
const BNDREG = 1 << 3;
21+
/// When set, MPX instructions can be executed and XSAVE can manage the BNDCFGU and BNDSTATUS registers.
22+
const BNDCSR = 1 << 4;
23+
/// If set, AVX-512 instructions can be executed and XSAVE can manage the K0-K7 mask registers.
24+
const OPMASK = 1 << 5;
25+
/// If set, AVX-512 instructions can be executed and XSAVE can be used to manage the upper halves of the lower ZMM registers.
26+
const ZMM_HI256 = 1 << 6;
27+
/// If set, AVX-512 instructions can be executed and XSAVE can manage the upper ZMM registers.
28+
const HI16_ZMM = 1 << 7;
1929
/// When set, PKRU state management is supported by
20-
/// ZSAVE/XRSTOR
30+
/// XSAVE/XRSTOR
2131
const MPK = 1<<9;
2232
/// When set the Lightweight Profiling extensions are enabled
2333
const LWP = 1<<62;
@@ -68,6 +78,13 @@ mod x86_64 {
6878
let old_value = Self::read_raw();
6979
let reserved = old_value & !(XCr0Flags::all().bits());
7080
let new_value = reserved | flags.bits();
81+
assert!(flags.contains(XCr0Flags::X87), "The X87 flag must be set");
82+
assert!((flags.contains(XCr0Flags::AVX) && flags.contains(XCr0Flags::OPMASK) && flags.contains(XCr0Flags::ZMM_HI256) && flags.contains(XCr0Flags::HI16_ZMM)) || !(flags.contains(XCr0Flags::AVX) && flags.contains(XCr0Flags::OPMASK) && flags.contains(XCr0Flags::ZMM_HI256) && flags.contains(XCr0Flags::HI16_ZMM)), "You must enable AVX to set or unset any of XCR0.opmask, XCR0.ZMM_Hi256, and XCR0.Hi16_ZMM");
83+
if !flags.contains(XCr0Flags::AVX) && (flags.contains(XCr0Flags::OPMASK) || flags.contains(XCr0Flags::ZMM_HI256) || flags.contains(XCr0Flags::HI16_ZMM)) {
84+
panic!("You must have AVX enabled to set XCR0.opmask, XCR0.ZMM_Hi256, or XCR0.Hi16_ZMM");
85+
}
86+
assert!((flags.contains(XCr0Flags::BNDREG) && flags.contains(XCr0Flags::BNDCSR)) || !(flags.contains(XCr0Flags::BNDREG) && flags.contains(XCr0Flags::BNDCSR)), "BNDREG and BNDCSR must be set and unset together");
87+
assert!((flags.contains(XCr0Flags::OPMASK) && flags.contains(XCr0Flags::ZMM_HI256) && flags.contains(XCr0Flags::HI16_ZMM)) || !(flags.contains(XCr0Flags::OPMASK) && flags.contains(XCr0Flags::ZMM_HI256) && flags.contains(XCr0Flags::HI16_ZMM)), "You must set or unset all of XCR0.opmask, XCR0.ZMM_Hi256, and XCR0.Hi16_ZMM");
7188

7289
Self::write_raw(new_value);
7390
}

0 commit comments

Comments
 (0)