1 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // 3 // Portions Copyright 2017 The Chromium OS Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE-BSD-3-Clause file. 6 // 7 // Copyright © 2019 Intel Corporation 8 // 9 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause 10 // 11 // Copyright © 2020, Microsoft Corporation 12 // 13 14 pub mod emulator; 15 pub mod gdt; 16 #[allow(non_upper_case_globals)] 17 #[allow(non_camel_case_types)] 18 #[allow(non_snake_case)] 19 #[allow(non_upper_case_globals)] 20 pub mod msr_index; 21 22 // MTRR constants 23 pub const MTRR_ENABLE: u64 = 0x800; // IA32_MTRR_DEF_TYPE MSR: E (MTRRs enabled) flag, bit 11 24 pub const MTRR_MEM_TYPE_WB: u64 = 0x6; 25 26 // IOAPIC pins 27 pub const NUM_IOAPIC_PINS: usize = 24; 28 29 // X86 Exceptions 30 #[allow(dead_code, clippy::upper_case_acronyms)] 31 #[derive(Clone, Debug)] 32 pub enum Exception { 33 DE = 0, // Divide Error 34 DB = 1, // Debug Exception 35 BP = 3, // Breakpoint 36 OF = 4, // Overflow 37 BR = 5, // BOUND Range Exceeded 38 UD = 6, // Invalid/Undefined Opcode 39 NM = 7, // No Math Coprocessor 40 DF = 8, // Double Fault 41 TS = 10, // Invalid TSS 42 NP = 11, // Segment Not Present 43 SS = 12, // Stack Segment Fault 44 GP = 13, // General Protection 45 PF = 14, // Page Fault 46 MF = 16, // Math Fault 47 AC = 17, // Alignment Check 48 MC = 18, // Machine Check 49 XM = 19, // SIMD Floating-Point Exception 50 VE = 20, // Virtualization Exception 51 CP = 21, // Control Protection Exception 52 } 53 54 pub mod regs; 55 56 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] 57 #[cfg_attr(feature = "with-serde", derive(Deserialize, Serialize))] 58 pub struct SegmentRegister { 59 pub base: u64, 60 pub limit: u32, 61 pub selector: u16, 62 pub type_: u8, 63 pub present: u8, 64 pub dpl: u8, 65 pub db: u8, 66 pub s: u8, 67 pub l: u8, 68 pub g: u8, 69 pub avl: u8, 70 pub unusable: u8, 71 } 72 73 impl SegmentRegister { 74 pub fn segment_type(&self) -> u8 { 75 self.type_ 76 } 77 pub fn set_segment_type(&mut self, val: u8) { 78 self.type_ = val; 79 } 80 81 pub fn dpl(&self) -> u8 { 82 self.dpl 83 } 84 85 pub fn set_dpl(&mut self, val: u8) { 86 self.dpl = val; 87 } 88 89 pub fn present(&self) -> u8 { 90 self.present 91 } 92 93 pub fn set_present(&mut self, val: u8) { 94 self.present = val; 95 } 96 97 pub fn long(&self) -> u8 { 98 self.l 99 } 100 101 pub fn set_long(&mut self, val: u8) { 102 self.l = val; 103 } 104 105 pub fn avl(&self) -> u8 { 106 self.avl 107 } 108 109 pub fn set_avl(&mut self, val: u8) { 110 self.avl = val; 111 } 112 113 pub fn desc_type(&self) -> u8 { 114 self.s 115 } 116 117 pub fn set_desc_type(&mut self, val: u8) { 118 self.s = val; 119 } 120 121 pub fn granularity(&self) -> u8 { 122 self.g 123 } 124 125 pub fn set_granularity(&mut self, val: u8) { 126 self.g = val; 127 } 128 129 pub fn db(&self) -> u8 { 130 self.db 131 } 132 133 pub fn set_db(&mut self, val: u8) { 134 self.db = val; 135 } 136 } 137 138 // Code segment 139 pub const CODE_SEGMENT_TYPE: u8 = 0x8; 140 141 // Read/Write or Read/Exec segment 142 pub const RWRX_SEGMENT_TYPE: u8 = 0x2; 143 144 // Expand down segment 145 pub const EXPAND_DOWN_SEGMENT_TYPE: u8 = 0x4; 146 147 pub fn segment_type_code(t: u8) -> bool { 148 t & CODE_SEGMENT_TYPE != 0 149 } 150 151 pub fn segment_type_ro(t: u8) -> bool { 152 t & !RWRX_SEGMENT_TYPE == 0 153 } 154 155 pub fn segment_type_expand_down(t: u8) -> bool { 156 !segment_type_code(t) && (t & EXPAND_DOWN_SEGMENT_TYPE != 0) 157 } 158 #[macro_export] 159 macro_rules! msr { 160 ($msr:expr) => { 161 MsrEntry { 162 index: $msr, 163 data: 0x0, 164 } 165 }; 166 } 167 #[macro_export] 168 macro_rules! msr_data { 169 ($msr:expr, $data:expr) => { 170 MsrEntry { 171 index: $msr, 172 data: $data, 173 } 174 }; 175 } 176 177 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] 178 #[cfg_attr(feature = "with-serde", derive(Deserialize, Serialize))] 179 pub struct StandardRegisters { 180 pub rax: u64, 181 pub rbx: u64, 182 pub rcx: u64, 183 pub rdx: u64, 184 pub rsi: u64, 185 pub rdi: u64, 186 pub rsp: u64, 187 pub rbp: u64, 188 pub r8: u64, 189 pub r9: u64, 190 pub r10: u64, 191 pub r11: u64, 192 pub r12: u64, 193 pub r13: u64, 194 pub r14: u64, 195 pub r15: u64, 196 pub rip: u64, 197 pub rflags: u64, 198 } 199 200 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] 201 #[cfg_attr(feature = "with-serde", derive(Deserialize, Serialize))] 202 pub struct DescriptorTable { 203 pub base: u64, 204 pub limit: u16, 205 } 206 207 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] 208 #[cfg_attr(feature = "with-serde", derive(Deserialize, Serialize))] 209 pub struct SpecialRegisters { 210 pub cs: SegmentRegister, 211 pub ds: SegmentRegister, 212 pub es: SegmentRegister, 213 pub fs: SegmentRegister, 214 pub gs: SegmentRegister, 215 pub ss: SegmentRegister, 216 pub tr: SegmentRegister, 217 pub ldt: SegmentRegister, 218 pub gdt: DescriptorTable, 219 pub idt: DescriptorTable, 220 pub cr0: u64, 221 pub cr2: u64, 222 pub cr3: u64, 223 pub cr4: u64, 224 pub cr8: u64, 225 pub efer: u64, 226 pub apic_base: u64, 227 pub interrupt_bitmap: [u64; 4usize], 228 } 229 230 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)] 231 pub struct CpuIdEntry { 232 pub function: u32, 233 pub index: u32, 234 pub flags: u32, 235 pub eax: u32, 236 pub ebx: u32, 237 pub ecx: u32, 238 pub edx: u32, 239 } 240 241 pub const CPUID_FLAG_VALID_INDEX: u32 = 1; 242 243 #[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)] 244 pub struct FpuState { 245 pub fpr: [[u8; 16usize]; 8usize], 246 pub fcw: u16, 247 pub fsw: u16, 248 pub ftwx: u8, 249 pub last_opcode: u16, 250 pub last_ip: u64, 251 pub last_dp: u64, 252 pub xmm: [[u8; 16usize]; 16usize], 253 pub mxcsr: u32, 254 } 255 256 #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] 257 pub enum LapicState { 258 #[cfg(feature = "kvm")] 259 Kvm(kvm_bindings::kvm_lapic_state), 260 #[cfg(feature = "mshv")] 261 Mshv(mshv_bindings::LapicState), 262 } 263 264 #[cfg(any(feature = "kvm", feature = "mshv"))] 265 impl LapicState { 266 pub fn get_klapic_reg(&self, reg_offset: usize) -> u32 { 267 use byteorder::{LittleEndian, ReadBytesExt}; 268 use std::io::Cursor; 269 use std::mem; 270 271 let sliceu8 = match self { 272 #[cfg(feature = "kvm")] 273 LapicState::Kvm(s) => unsafe { 274 // This array is only accessed as parts of a u32 word, so interpret it as a u8 array. 275 // Cursors are only readable on arrays of u8, not i8(c_char). 276 mem::transmute::<&[i8], &[u8]>(&s.regs[reg_offset..]) 277 }, 278 #[cfg(feature = "mshv")] 279 LapicState::Mshv(s) => unsafe { 280 // This array is only accessed as parts of a u32 word, so interpret it as a u8 array. 281 // Cursors are only readable on arrays of u8, not i8(c_char). 282 mem::transmute::<&[i8], &[u8]>(&s.regs[reg_offset..]) 283 }, 284 }; 285 286 let mut reader = Cursor::new(sliceu8); 287 // Following call can't fail if the offsets defined above are correct. 288 reader 289 .read_u32::<LittleEndian>() 290 .expect("Failed to read klapic register") 291 } 292 293 pub fn set_klapic_reg(&mut self, reg_offset: usize, value: u32) { 294 use byteorder::{LittleEndian, WriteBytesExt}; 295 use std::io::Cursor; 296 use std::mem; 297 298 let sliceu8 = match self { 299 #[cfg(feature = "kvm")] 300 LapicState::Kvm(s) => unsafe { 301 // This array is only accessed as parts of a u32 word, so interpret it as a u8 array. 302 // Cursors are only readable on arrays of u8, not i8(c_char). 303 mem::transmute::<&mut [i8], &mut [u8]>(&mut s.regs[reg_offset..]) 304 }, 305 #[cfg(feature = "mshv")] 306 LapicState::Mshv(s) => unsafe { 307 // This array is only accessed as parts of a u32 word, so interpret it as a u8 array. 308 // Cursors are only readable on arrays of u8, not i8(c_char). 309 mem::transmute::<&mut [i8], &mut [u8]>(&mut s.regs[reg_offset..]) 310 }, 311 }; 312 313 let mut writer = Cursor::new(sliceu8); 314 // Following call can't fail if the offsets defined above are correct. 315 writer 316 .write_u32::<LittleEndian>(value) 317 .expect("Failed to write klapic register") 318 } 319 } 320 321 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)] 322 pub struct MsrEntry { 323 pub index: u32, 324 pub data: u64, 325 } 326