vmm/cpu_config/x86_64/static_cpu_templates/
c3.rs

1// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::cpu_config::templates::{CustomCpuTemplate, RegisterValueFilter};
5use crate::cpu_config::x86_64::cpuid::KvmCpuidFlags;
6use crate::cpu_config::x86_64::custom_cpu_template::{
7    CpuidLeafModifier, CpuidRegister, CpuidRegisterModifier,
8};
9
10/// C3 CPU template.
11///
12/// Mask CPUID to make exposed CPU features as close as possbile to AWS C3 instance.
13///
14/// CPUID dump taken in c3.large on 2023-06-15:
15/// =====
16/// $ cpuid -1 -r
17/// Disclaimer: cpuid may not support decoding of all cpuid registers.
18/// CPU:
19///   0x00000000 0x00: eax=0x0000000d ebx=0x756e6547 ecx=0x6c65746e edx=0x49656e69
20///   0x00000001 0x00: eax=0x000306e4 ebx=0x01020800 ecx=0xffba2203 edx=0x178bfbff
21///   0x00000002 0x00: eax=0x76036301 ebx=0x00f0b2ff ecx=0x00000000 edx=0x00ca0000
22///   0x00000003 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
23///   0x00000004 0x00: eax=0x00004121 ebx=0x01c0003f ecx=0x0000003f edx=0x00000000
24///   0x00000004 0x01: eax=0x00004122 ebx=0x01c0003f ecx=0x0000003f edx=0x00000000
25///   0x00000004 0x02: eax=0x00004143 ebx=0x01c0003f ecx=0x000001ff edx=0x00000000
26///   0x00000004 0x03: eax=0x00004163 ebx=0x04c0003f ecx=0x00004fff edx=0x00000006
27///   0x00000005 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
28///   0x00000006 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
29///   0x00000007 0x00: eax=0x00000000 ebx=0x00000281 ecx=0x00000000 edx=0x00000000
30///   0x00000008 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
31///   0x00000009 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
32///   0x0000000a 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
33///   0x0000000b 0x00: eax=0x00000001 ebx=0x00000002 ecx=0x00000100 edx=0x00000000
34///   0x0000000b 0x01: eax=0x00000005 ebx=0x00000001 ecx=0x00000201 edx=0x00000000
35///   0x0000000c 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
36///   0x0000000d 0x00: eax=0x00000007 ebx=0x00000340 ecx=0x00000340 edx=0x00000000
37///   0x0000000d 0x01: eax=0x00000001 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
38///   0x0000000d 0x02: eax=0x00000100 ebx=0x00000240 ecx=0x00000000 edx=0x00000000
39///   0x40000000 0x00: eax=0x40000005 ebx=0x566e6558 ecx=0x65584d4d edx=0x4d4d566e
40///   0x40000001 0x00: eax=0x0004000b ebx=0x00000000 ecx=0x00000000 edx=0x00000000
41///   0x40000002 0x00: eax=0x00000001 ebx=0x40000000 ecx=0x00000000 edx=0x00000000
42///   0x40000003 0x00: eax=0x00000006 ebx=0x00000002 ecx=0x002a9f50 edx=0x00000001
43///   0x40000003 0x02: eax=0x1387329d ebx=0x00f6b809 ecx=0xb74bc70a edx=0xffffffff
44///   0x40000004 0x00: eax=0x0000001c ebx=0x00000000 ecx=0x00002b86 edx=0x00000000
45///   0x40000005 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
46///   0x80000000 0x00: eax=0x80000008 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
47///   0x80000001 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000001 edx=0x28100800
48///   0x80000002 0x00: eax=0x20202020 ebx=0x6e492020 ecx=0x286c6574 edx=0x58202952
49///   0x80000003 0x00: eax=0x286e6f65 ebx=0x43202952 ecx=0x45205550 edx=0x36322d35
50///   0x80000004 0x00: eax=0x76203038 ebx=0x20402032 ecx=0x30382e32 edx=0x007a4847
51///   0x80000005 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
52///   0x80000006 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x01006040 edx=0x00000000
53///   0x80000007 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
54///   0x80000008 0x00: eax=0x0000302e ebx=0x00000000 ecx=0x00000000 edx=0x00000000
55///   0x80860000 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
56///   0xc0000000 0x00: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
57/// =====
58///
59/// References:
60/// - Intel SDM: <https://cdrdv2.intel.com/v1/dl/getContent/671200>
61#[allow(clippy::unusual_byte_groupings)]
62pub fn c3() -> CustomCpuTemplate {
63    CustomCpuTemplate {
64        cpuid_modifiers: vec![
65            CpuidLeafModifier {
66                leaf: 0x1,
67                subleaf: 0x0,
68                flags: KvmCpuidFlags(0),
69                modifiers: vec![
70                    // EAX: Version Information
71                    // - Bits 03-00: Stepping ID.
72                    // - Bits 07-04: Model.
73                    // - Bits 11-08: Family.
74                    // - Bits 13-12: Processor Type.
75                    // - Bits 19-16: Extended Model ID.
76                    // - Bits 27-20: Extended Family ID.
77                    CpuidRegisterModifier {
78                        register: CpuidRegister::Eax,
79                        bitmap: RegisterValueFilter {
80                            filter: 0b0000_11111111_1111_00_11_1111_1111_1111,
81                            value: 0b0000_00000000_0011_00_00_0110_1110_0100,
82                        },
83                    },
84                    // ECX: Feature Information
85                    // - Bit 02: DTES64
86                    // - Bit 03: MONITOR
87                    // - Bit 04: DS-CPL
88                    // - Bit 05: VMX
89                    // - Bit 08: TM2
90                    // - Bit 10: CNXT-ID
91                    // - Bit 11: SDBG
92                    // - Bit 12: FMA
93                    // - Bit 14: xTPR Update Control
94                    // - Bit 15: PDCM
95                    // - Bit 22: MOVBE
96                    CpuidRegisterModifier {
97                        register: CpuidRegister::Ecx,
98                        bitmap: RegisterValueFilter {
99                            filter: 0b0000_0000_0100_0000_1101_1101_0011_1100,
100                            value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
101                        },
102                    },
103                    // EDX: Feature Information
104                    // - Bit 07: MCE
105                    // - Bit 12: MTRR
106                    // - Bit 18: PSN
107                    // - Bit 21: DS
108                    // - Bit 22: ACPI
109                    // - Bit 27: SS
110                    // - Bit 29: TM
111                    // - Bit 31: PBE
112                    CpuidRegisterModifier {
113                        register: CpuidRegister::Edx,
114                        bitmap: RegisterValueFilter {
115                            filter: 0b1010_1000_0110_0100_0001_0000_1000_0000,
116                            value: 0b0000_0000_0000_0000_0001_0000_1000_0000,
117                        },
118                    },
119                ],
120            },
121            CpuidLeafModifier {
122                leaf: 0x7,
123                subleaf: 0x0,
124                flags: KvmCpuidFlags(1),
125                modifiers: vec![
126                    // EBX:
127                    // - Bit 02: SGX
128                    // - Bit 03: BMI1
129                    // - Bit 04: HLE
130                    // - Bit 05: AVX2
131                    // - Bit 08: BMI2
132                    // - Bit 10: INVPCID
133                    // - Bit 11: RTM
134                    // - Bit 12: RDT-M
135                    // - Bit 14: MPX
136                    // - Bit 15: RDT-A
137                    // - Bit 16: AVX512F
138                    // - Bit 17: AVX512DQ
139                    // - Bit 18: RDSEED
140                    // - Bit 19: ADX
141                    // - Bit 21: AVX512_IFMA
142                    // - Bit 23: CLFLUSHOPT
143                    // - Bit 24: CLWB
144                    // - Bit 25: Intel Processor Trace
145                    // - Bit 26: AVX512PF
146                    // - Bit 27: AVX512ER
147                    // - Bit 28: AVX512CD
148                    // - Bit 29: SHA
149                    // - Bit 30: AVX512BW
150                    // - Bit 31: AVX512VL
151                    CpuidRegisterModifier {
152                        register: CpuidRegister::Ebx,
153                        bitmap: RegisterValueFilter {
154                            filter: 0b1111_1111_1010_1111_1101_1101_0011_1100,
155                            value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
156                        },
157                    },
158                    // ECX:
159                    // - Bit 01: AVX512_VBMI
160                    // - Bit 02: UMIP
161                    // - Bit 03: PKU
162                    // - Bit 04: OSPKE
163                    // - Bit 11: AVX512_VNNI
164                    // - Bit 14: AVX512_VPOPCNTDQ
165                    // - Bit 16: LA57
166                    // - Bit 22: RDPID
167                    // - Bit 30: SGX_LC
168                    CpuidRegisterModifier {
169                        register: CpuidRegister::Ecx,
170                        bitmap: RegisterValueFilter {
171                            filter: 0b0100_0000_0100_0001_0100_1000_0001_1110,
172                            value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
173                        },
174                    },
175                    // EDX:
176                    // - Bit 02: AVX512_4VNNIW
177                    // - Bit 03: AVX512_4FMAPS
178                    CpuidRegisterModifier {
179                        register: CpuidRegister::Edx,
180                        bitmap: RegisterValueFilter {
181                            filter: 0b0000_0000_0000_0000_0000_0000_0000_1100,
182                            value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
183                        },
184                    },
185                ],
186            },
187            CpuidLeafModifier {
188                leaf: 0xd,
189                subleaf: 0x0,
190                flags: KvmCpuidFlags(1),
191                modifiers: vec![
192                    // EAX:
193                    // - Bits 04-03: MPX state
194                    // - Bits 07-05: AVX-512 state
195                    // - Bit 09: PKRU state
196                    CpuidRegisterModifier {
197                        register: CpuidRegister::Eax,
198                        bitmap: RegisterValueFilter {
199                            filter: 0b0000_0000_0000_0000_0000_00_1_0_111_11_000,
200                            value: 0b0000_0000_0000_0000_0000_00_0_0_000_00_000,
201                        },
202                    },
203                ],
204            },
205            CpuidLeafModifier {
206                leaf: 0xd,
207                subleaf: 0x1,
208                flags: KvmCpuidFlags(1),
209                modifiers: vec![
210                    // EAX:
211                    // - Bit 01: Supports XSAVEC and the compacted form of XRSTOR
212                    // - Bit 02: Supports XGETBV
213                    // - Bit 03: Supports XSAVES/XRSTORS and IA32_XSS
214                    CpuidRegisterModifier {
215                        register: CpuidRegister::Eax,
216                        bitmap: RegisterValueFilter {
217                            filter: 0b0000_0000_0000_0000_0000_0000_0000_1110,
218                            value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
219                        },
220                    },
221                ],
222            },
223            CpuidLeafModifier {
224                leaf: 0x80000001,
225                subleaf: 0x0,
226                flags: KvmCpuidFlags(0),
227                modifiers: vec![
228                    // ECX:
229                    // - Bit 05: LZCNT
230                    // - Bit 08: PREFETCHW
231                    CpuidRegisterModifier {
232                        register: CpuidRegister::Ecx,
233                        bitmap: RegisterValueFilter {
234                            filter: 0b0000_0000_0000_0000_0000_0001_0010_0000,
235                            value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
236                        },
237                    },
238                    // EDX:
239                    // - Bit 26: 1-GByte pages
240                    CpuidRegisterModifier {
241                        register: CpuidRegister::Edx,
242                        bitmap: RegisterValueFilter {
243                            filter: 0b0000_0100_0000_0000_0000_0000_0000_0000,
244                            value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
245                        },
246                    },
247                ],
248            },
249        ],
250        msr_modifiers: vec![],
251        ..Default::default()
252    }
253}