Skip to main content

ax_cpu/arch/x86_64/
msr.rs

1// Copyright 2025 The Axvisor Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Typed hardware model-specific register identifiers.
16
17/// Architectural and vendor MSR identifiers used by CPU and VM control owners.
18#[repr(u32)]
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub enum Msr {
21    /// IA32_FEATURE_CONTROL (Intel SDM / AMD APM register identifier).
22    Ia32FeatureControl   = 0x3a,
23    /// IA32_SYSENTER_CS (Intel SDM / AMD APM register identifier).
24    Ia32SysenterCs       = 0x174,
25    /// IA32_SYSENTER_ESP (Intel SDM / AMD APM register identifier).
26    Ia32SysenterEsp      = 0x175,
27    /// IA32_SYSENTER_EIP (Intel SDM / AMD APM register identifier).
28    Ia32SysenterEip      = 0x176,
29    /// IA32_PAT (Intel SDM / AMD APM register identifier).
30    Ia32Pat              = 0x277,
31    /// IA32_VMX_BASIC (Intel SDM / AMD APM register identifier).
32    Ia32VmxBasic         = 0x480,
33    /// IA32_VMX_PINBASED_CTLS (Intel SDM / AMD APM register identifier).
34    Ia32VmxPinbasedCtls  = 0x481,
35    /// IA32_VMX_PROCBASED_CTLS (Intel SDM / AMD APM register identifier).
36    Ia32VmxProcbasedCtls = 0x482,
37    /// IA32_VMX_EXIT_CTLS (Intel SDM / AMD APM register identifier).
38    Ia32VmxExitCtls      = 0x483,
39    /// IA32_VMX_ENTRY_CTLS (Intel SDM / AMD APM register identifier).
40    Ia32VmxEntryCtls     = 0x484,
41    /// IA32_VMX_MISC (Intel SDM / AMD APM register identifier).
42    Ia32VmxMisc          = 0x485,
43    /// IA32_VMX_CR0_FIXED0 (Intel SDM / AMD APM register identifier).
44    Ia32VmxCr0Fixed0     = 0x486,
45    /// IA32_VMX_CR0_FIXED1 (Intel SDM / AMD APM register identifier).
46    Ia32VmxCr0Fixed1     = 0x487,
47    /// IA32_VMX_CR4_FIXED0 (Intel SDM / AMD APM register identifier).
48    Ia32VmxCr4Fixed0     = 0x488,
49    /// IA32_VMX_CR4_FIXED1 (Intel SDM / AMD APM register identifier).
50    Ia32VmxCr4Fixed1     = 0x489,
51    /// IA32_VMX_PROCBASED_CTLS2 (Intel SDM / AMD APM register identifier).
52    Ia32VmxProcbasedCtls2 = 0x48b,
53    /// IA32_VMX_EPT_VPID_CAP (Intel SDM / AMD APM register identifier).
54    Ia32VmxEptVpidCap    = 0x48c,
55    /// IA32_VMX_TRUE_PINBASED_CTLS (Intel SDM / AMD APM register identifier).
56    Ia32VmxTruePinbasedCtls = 0x48d,
57    /// IA32_VMX_TRUE_PROCBASED_CTLS (Intel SDM / AMD APM register identifier).
58    Ia32VmxTrueProcbasedCtls = 0x48e,
59    /// IA32_VMX_TRUE_EXIT_CTLS (Intel SDM / AMD APM register identifier).
60    Ia32VmxTrueExitCtls  = 0x48f,
61    /// IA32_VMX_TRUE_ENTRY_CTLS (Intel SDM / AMD APM register identifier).
62    Ia32VmxTrueEntryCtls = 0x490,
63    /// IA32_XSS (Intel SDM / AMD APM register identifier).
64    Ia32Xss              = 0xda0,
65    /// IA32_EFER (Intel SDM / AMD APM register identifier).
66    Ia32Efer             = 0xc000_0080,
67    /// IA32_STAR (Intel SDM / AMD APM register identifier).
68    Ia32Star             = 0xc000_0081,
69    /// IA32_LSTAR (Intel SDM / AMD APM register identifier).
70    Ia32Lstar            = 0xc000_0082,
71    /// IA32_CSTAR (Intel SDM / AMD APM register identifier).
72    Ia32Cstar            = 0xc000_0083,
73    /// IA32_FMASK (Intel SDM / AMD APM register identifier).
74    Ia32Fmask            = 0xc000_0084,
75    /// IA32_FS_BASE (Intel SDM / AMD APM register identifier).
76    Ia32FsBase           = 0xc000_0100,
77    /// IA32_GS_BASE (Intel SDM / AMD APM register identifier).
78    Ia32GsBase           = 0xc000_0101,
79    /// IA32_KERNEL_GSBASE (Intel SDM / AMD APM register identifier).
80    Ia32KernelGsbase     = 0xc000_0102,
81    /// VM_CR (Intel SDM / AMD APM register identifier).
82    VmCr                 = 0xc001_0114,
83    /// IGNNE (Intel SDM / AMD APM register identifier).
84    Ignne                = 0xc001_0115,
85    /// VM_HSAVE_PA (Intel SDM / AMD APM register identifier).
86    VmHsavePa            = 0xc001_0117,
87    /// PERF_EVT_SEL0 (Intel SDM / AMD APM register identifier).
88    PerfEvtSel0          = 0xc001_0200,
89    /// PERF_EVT_SEL1 (Intel SDM / AMD APM register identifier).
90    PerfEvtSel1          = 0xc001_0202,
91    /// PERF_EVT_SEL2 (Intel SDM / AMD APM register identifier).
92    PerfEvtSel2          = 0xc001_0204,
93    /// PERF_EVT_SEL3 (Intel SDM / AMD APM register identifier).
94    PerfEvtSel3          = 0xc001_0206,
95    /// PERF_EVT_SEL4 (Intel SDM / AMD APM register identifier).
96    PerfEvtSel4          = 0xc001_0208,
97    /// PERF_EVT_SEL5 (Intel SDM / AMD APM register identifier).
98    PerfEvtSel5          = 0xc001_020a,
99}
100
101impl Msr {
102    /// Reads the complete register value.
103    ///
104    /// # Safety
105    /// Execute at ring 0 on a CPU implementing this register with access
106    /// permitted by any higher virtualization layer.
107    pub unsafe fn read(self) -> u64 {
108        // SAFETY: the caller establishes the register's privileged availability.
109        unsafe { x86::msr::rdmsr(self as u32) }
110    }
111
112    /// Writes a validated register value.
113    ///
114    /// # Safety
115    /// The caller must own this register's machine-state transition, establish
116    /// its availability and reserved-bit rules, and retain referenced memory
117    /// and execution state for as long as the hardware can use the value.
118    pub unsafe fn write(self, value: u64) {
119        // SAFETY: the caller owns the register and the complete state lifetime.
120        unsafe { x86::msr::wrmsr(self as u32, value) };
121    }
122}