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}