hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use core::sync::atomic::{AtomicU8, Ordering};

static MITIGATION_STATE: AtomicU8 = AtomicU8::new(0);

#[derive(Copy, Clone, PartialEq)]
pub enum SpeculationMitigation {
    None,
    Ibrs,
    Ibpb,
    Stibp,
    Ssbd,
    Retpoline,
}

pub fn mitigations_active() -> bool {
    MITIGATION_STATE.load(Ordering::Acquire) != 0
}

pub fn active_mitigation() -> SpeculationMitigation {
    match MITIGATION_STATE.load(Ordering::Acquire) {
        1 => SpeculationMitigation::Ibrs,
        2 => SpeculationMitigation::Ibpb,
        3 => SpeculationMitigation::Stibp,
        4 => SpeculationMitigation::Ssbd,
        5 => SpeculationMitigation::Retpoline,
        _ => SpeculationMitigation::None,
    }
}

pub fn mitigations() {
    match crate::arch::detect_arch() {
        crate::arch::Architecture::X86_64 => {
            if let Some((eax, ebx, ecx, edx)) = crate::hardware_access::read_cpuid(7, 0) {
                static SPEC_SIG: core::sync::atomic::AtomicUsize =
                    core::sync::atomic::AtomicUsize::new(0);
                SPEC_SIG.store(
                    eax as usize ^ ebx as usize ^ ecx as usize,
                    core::sync::atomic::Ordering::Release,
                );
                if edx & (1 << 26) != 0 {
                    MITIGATION_STATE.store(1, Ordering::Release);
                    return;
                }
                if edx & (1 << 31) != 0 {
                    MITIGATION_STATE.store(4, Ordering::Release);
                    return;
                }
            }
            MITIGATION_STATE.store(5, Ordering::Release);
        }
        crate::arch::Architecture::AArch64 => {
            MITIGATION_STATE.store(1, Ordering::Release);
        }
        _ => {}
    }
}