libarch/x86/
speculation.rs1use super::ArchCapabilitiesMsr;
6use super::cpuid::{EXTENDED_AMD_FEATURES_B, EXTENDED_FEATURES_D};
7use bitrs::layout;
8use regio::RwSafe;
9use regio::traits::ReadReg;
10use regio::x86::{Cpuid, Msr};
11
12pub const SPECULATION_CONTROL: Msr<0x0000_0048, SpeculationControlMsr, RwSafe> = Msr::new();
18
19layout!({
20 pub struct SpeculationControlMsr(u64);
22 {
23 let __ @ 63..3;
24 let ssbd @ 2;
25 let stibp @ 1;
26 let ibrs @ 0;
27 }
28});
29
30impl SpeculationControlMsr {
31 pub fn is_supported(cpuid: impl Cpuid) -> bool {
32 let intel_features = cpuid.read(EXTENDED_FEATURES_D);
38 if intel_features.ibrs_ibpb() || intel_features.stibp() || intel_features.ssbd() {
39 return true;
40 }
41
42 if !cpuid.supports(EXTENDED_AMD_FEATURES_B) {
44 return false;
45 }
46 let amd_features = cpuid.read(EXTENDED_AMD_FEATURES_B);
47 amd_features.ibrs() || amd_features.stibp() || amd_features.ssbd()
48 }
49}
50
51pub const VIRTUAL_SPECULATION_CONTROL: Msr<0xc001_011f, VirtualSpeculationControlMsr, RwSafe> =
55 Msr::new();
56
57layout!({
58 pub struct VirtualSpeculationControlMsr(u64);
60 {
61 let __ @ 63..3;
62 let ssbd @ 2;
63 let __ @ 1..0;
64 }
65});
66
67impl VirtualSpeculationControlMsr {
68 pub fn is_supported(cpuid: impl Cpuid) -> bool {
69 cpuid.supports(EXTENDED_AMD_FEATURES_B) && cpuid.read(EXTENDED_AMD_FEATURES_B).virt_ssbd()
71 }
72}
73
74pub fn has_ibrs(
80 cpuid: &impl Cpuid,
81 msr: &impl ReadReg<ArchCapabilitiesMsr>,
82 always_on_mode: bool,
83) -> bool {
84 let intel_always_on = ArchCapabilitiesMsr::is_supported(cpuid) && msr.read().ibrs_all();
86 let intel_present = cpuid.read(EXTENDED_FEATURES_D).ibrs_ibpb();
87 if intel_present && (!always_on_mode || intel_always_on) {
88 return true;
89 }
90
91 if cpuid.supports(EXTENDED_AMD_FEATURES_B) {
93 let features = cpuid.read(EXTENDED_AMD_FEATURES_B);
94 if features.ibrs() && (!always_on_mode || features.ibrs_always_on()) {
95 return true;
96 }
97 }
98
99 false
100}
101
102pub fn has_stibp(cpuid: &impl Cpuid, always_on_mode: bool) -> bool {
108 let intel_present = cpuid.read(EXTENDED_FEATURES_D).stibp();
110 if intel_present && !always_on_mode {
111 return true;
113 }
114
115 if cpuid.supports(EXTENDED_AMD_FEATURES_B) {
117 let features = cpuid.read(EXTENDED_AMD_FEATURES_B);
118 if features.stibp() && (!always_on_mode || features.stibp_always_on()) {
119 return true;
120 }
121 }
122 false
123}