xref: /cloud-hypervisor/hypervisor/src/arch/x86/emulator/mod.rs (revision a3d957ba4d5fc55cdc86d6687e482056baa94c20)
1 //
2 // Copyright © 2020 Intel Corporation
3 //
4 // SPDX-License-Identifier: Apache-2.0
5 //
6 
7 extern crate iced_x86;
8 
9 use crate::arch::emulator::{EmulationError, EmulationResult, PlatformEmulator, PlatformError};
10 use crate::arch::x86::emulator::instructions::*;
11 use crate::arch::x86::Exception;
12 use crate::x86_64::{SegmentRegister, SpecialRegisters, StandardRegisters};
13 use iced_x86::*;
14 
15 #[macro_use]
16 mod instructions;
17 
18 /// CpuStateManager manages an x86 CPU state.
19 ///
20 /// Instruction emulation handlers get a mutable reference to
21 /// a `CpuStateManager` implementation, representing the current state of the
22 /// CPU they have to emulate an instruction stream against. Usually those
23 /// handlers will modify the CPU state by modifying `CpuState` and it is up to
24 /// the handler caller to commit those changes back by invoking a
25 /// `PlatformEmulator` implementation `set_state()` method.
26 ///
27 pub trait CpuStateManager: Clone {
28     /// Reads a CPU register.
29     ///
30     /// # Arguments
31     ///
32     /// * `reg` - A general purpose, control or debug register.
33     fn read_reg(&self, reg: Register) -> Result<u64, PlatformError>;
34 
35     /// Write to a CPU register.
36     ///
37     /// # Arguments
38     ///
39     /// * `reg` - A general purpose, control or debug register.
40     /// * `val` - The value to load.
41     fn write_reg(&mut self, reg: Register, val: u64) -> Result<(), PlatformError>;
42 
43     /// Reads a segment register.
44     ///
45     /// # Arguments
46     ///
47     /// * `reg` - A segment register.
48     fn read_segment(&self, reg: Register) -> Result<SegmentRegister, PlatformError>;
49 
50     /// Write to a segment register.
51     ///
52     /// # Arguments
53     ///
54     /// * `reg` - A segment register.
55     /// * `segment_reg` - The segment register value to load.
56     fn write_segment(
57         &mut self,
58         reg: Register,
59         segment_reg: SegmentRegister,
60     ) -> Result<(), PlatformError>;
61 
62     /// Get the CPU instruction pointer.
63     fn ip(&self) -> u64;
64 
65     /// Set the CPU instruction pointer.
66     ///
67     /// # Arguments
68     ///
69     /// * `ip` - The CPU instruction pointer.
70     fn set_ip(&mut self, ip: u64);
71 
72     /// Get the CPU Extended Feature Enable Register.
73     fn efer(&self) -> u64;
74 
75     /// Set the CPU Extended Feature Enable Register.
76     ///
77     /// # Arguments
78     ///
79     /// * `efer` - The CPU EFER value.
80     fn set_efer(&mut self, efer: u64);
81 
82     /// Get the CPU flags.
83     fn flags(&self) -> u64;
84 
85     /// Set the CPU flags.
86     ///
87     /// # Arguments
88     ///
89     /// * `flags` - The CPU flags
90     fn set_flags(&mut self, flags: u64);
91 }
92 
93 const REGISTER_MASK_64: u64 = 0xffff_ffff_ffff_ffffu64;
94 const REGISTER_MASK_32: u64 = 0xffff_ffffu64;
95 const REGISTER_MASK_16: u64 = 0xffffu64;
96 const REGISTER_MASK_8: u64 = 0xffu64;
97 
98 macro_rules! set_reg {
99     ($reg:expr, $mask:expr, $value:expr) => {
100         $reg = ($reg & $mask) | $value
101     };
102 }
103 
104 #[derive(Clone, Default, Debug)]
105 /// A minimal, emulated CPU state.
106 ///
107 /// Hypervisors needing x86 emulation can choose to either use their own
108 /// CPU state structures and implement the CpuStateManager interface for it,
109 /// or use `EmulatorCpuState`. The latter implies creating a new state
110 /// `EmulatorCpuState` instance for each platform `cpu_state()` call, which
111 /// might be less efficient.
112 pub struct EmulatorCpuState {
113     pub regs: StandardRegisters,
114     pub sregs: SpecialRegisters,
115 }
116 
117 impl CpuStateManager for EmulatorCpuState {
118     fn read_reg(&self, reg: Register) -> Result<u64, PlatformError> {
119         let mut reg_value: u64 = match reg {
120             Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => {
121                 self.regs.rax
122             }
123             Register::RBX | Register::EBX | Register::BX | Register::BL | Register::BH => {
124                 self.regs.rbx
125             }
126             Register::RCX | Register::ECX | Register::CX | Register::CL | Register::CH => {
127                 self.regs.rcx
128             }
129             Register::RDX | Register::EDX | Register::DX | Register::DL | Register::DH => {
130                 self.regs.rdx
131             }
132             Register::RSP | Register::ESP | Register::SP => self.regs.rsp,
133             Register::RBP | Register::EBP | Register::BP => self.regs.rbp,
134             Register::RSI | Register::ESI | Register::SI | Register::SIL => self.regs.rsi,
135             Register::RDI | Register::EDI | Register::DI | Register::DIL => self.regs.rdi,
136             Register::R8 | Register::R8D | Register::R8W | Register::R8L => self.regs.r8,
137             Register::R9 | Register::R9D | Register::R9W | Register::R9L => self.regs.r9,
138             Register::R10 | Register::R10D | Register::R10W | Register::R10L => self.regs.r10,
139             Register::R11 | Register::R11D | Register::R11W | Register::R11L => self.regs.r11,
140             Register::R12 | Register::R12D | Register::R12W | Register::R12L => self.regs.r12,
141             Register::R13 | Register::R13D | Register::R13W | Register::R13L => self.regs.r13,
142             Register::R14 | Register::R14D | Register::R14W | Register::R14L => self.regs.r14,
143             Register::R15 | Register::R15D | Register::R15W | Register::R15L => self.regs.r15,
144             Register::CR0 => self.sregs.cr0,
145             Register::CR2 => self.sregs.cr2,
146             Register::CR3 => self.sregs.cr3,
147             Register::CR4 => self.sregs.cr4,
148             Register::CR8 => self.sregs.cr8,
149 
150             r => {
151                 return Err(PlatformError::InvalidRegister(anyhow!(
152                     "read_reg invalid GPR {:?}",
153                     r
154                 )))
155             }
156         };
157 
158         reg_value = if reg.is_gpr64() || reg.is_cr() {
159             reg_value
160         } else if reg.is_gpr32() {
161             reg_value & REGISTER_MASK_32
162         } else if reg.is_gpr16() {
163             reg_value & REGISTER_MASK_16
164         } else if reg.is_gpr8() {
165             if reg == Register::AH
166                 || reg == Register::BH
167                 || reg == Register::CH
168                 || reg == Register::DH
169             {
170                 (reg_value >> 8) & REGISTER_MASK_8
171             } else {
172                 reg_value & REGISTER_MASK_8
173             }
174         } else {
175             return Err(PlatformError::InvalidRegister(anyhow!(
176                 "read_reg invalid GPR {:?}",
177                 reg
178             )));
179         };
180 
181         debug!("Register read: {:#x} from {:?}", reg_value, reg);
182 
183         Ok(reg_value)
184     }
185 
186     fn write_reg(&mut self, reg: Register, val: u64) -> Result<(), PlatformError> {
187         debug!("Register write: {:#x} to {:?}", val, reg);
188 
189         // SDM Vol 1 - 3.4.1.1
190         //
191         // 8-bit and 16-bit operands generate an 8-bit or 16-bit result.
192         // The upper 56 bits or 48 bits (respectively) of the destination
193         // general-purpose register are not modified by the operation.
194         let (reg_value, mask): (u64, u64) = if reg.is_gpr64() || reg.is_cr() {
195             (val, !REGISTER_MASK_64)
196         } else if reg.is_gpr32() {
197             (val & REGISTER_MASK_32, !REGISTER_MASK_64)
198         } else if reg.is_gpr16() {
199             (val & REGISTER_MASK_16, !REGISTER_MASK_16)
200         } else if reg.is_gpr8() {
201             if reg == Register::AH
202                 || reg == Register::BH
203                 || reg == Register::CH
204                 || reg == Register::DH
205             {
206                 ((val & REGISTER_MASK_8) << 8, !(REGISTER_MASK_8 << 8))
207             } else {
208                 (val & REGISTER_MASK_8, !REGISTER_MASK_8)
209             }
210         } else {
211             return Err(PlatformError::InvalidRegister(anyhow!(
212                 "write_reg invalid register {:?}",
213                 reg
214             )));
215         };
216 
217         match reg {
218             Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => {
219                 set_reg!(self.regs.rax, mask, reg_value);
220             }
221             Register::RBX | Register::EBX | Register::BX | Register::BL | Register::BH => {
222                 set_reg!(self.regs.rbx, mask, reg_value);
223             }
224             Register::RCX | Register::ECX | Register::CX | Register::CL | Register::CH => {
225                 set_reg!(self.regs.rcx, mask, reg_value);
226             }
227             Register::RDX | Register::EDX | Register::DX | Register::DL | Register::DH => {
228                 set_reg!(self.regs.rdx, mask, reg_value);
229             }
230             Register::RSP | Register::ESP | Register::SP => {
231                 set_reg!(self.regs.rsp, mask, reg_value)
232             }
233             Register::RBP | Register::EBP | Register::BP => {
234                 set_reg!(self.regs.rbp, mask, reg_value)
235             }
236             Register::RSI | Register::ESI | Register::SI | Register::SIL => {
237                 set_reg!(self.regs.rsi, mask, reg_value)
238             }
239             Register::RDI | Register::EDI | Register::DI | Register::DIL => {
240                 set_reg!(self.regs.rdi, mask, reg_value)
241             }
242             Register::R8 | Register::R8D | Register::R8W | Register::R8L => {
243                 set_reg!(self.regs.r8, mask, reg_value)
244             }
245             Register::R9 | Register::R9D | Register::R9W | Register::R9L => {
246                 set_reg!(self.regs.r9, mask, reg_value)
247             }
248             Register::R10 | Register::R10D | Register::R10W | Register::R10L => {
249                 set_reg!(self.regs.r10, mask, reg_value)
250             }
251             Register::R11 | Register::R11D | Register::R11W | Register::R11L => {
252                 set_reg!(self.regs.r11, mask, reg_value)
253             }
254             Register::R12 | Register::R12D | Register::R12W | Register::R12L => {
255                 set_reg!(self.regs.r12, mask, reg_value)
256             }
257             Register::R13 | Register::R13D | Register::R13W | Register::R13L => {
258                 set_reg!(self.regs.r13, mask, reg_value)
259             }
260             Register::R14 | Register::R14D | Register::R14W | Register::R14L => {
261                 set_reg!(self.regs.r14, mask, reg_value)
262             }
263             Register::R15 | Register::R15D | Register::R15W | Register::R15L => {
264                 set_reg!(self.regs.r15, mask, reg_value)
265             }
266             Register::CR0 => set_reg!(self.sregs.cr0, mask, reg_value),
267             Register::CR2 => set_reg!(self.sregs.cr2, mask, reg_value),
268             Register::CR3 => set_reg!(self.sregs.cr3, mask, reg_value),
269             Register::CR4 => set_reg!(self.sregs.cr4, mask, reg_value),
270             Register::CR8 => set_reg!(self.sregs.cr8, mask, reg_value),
271             _ => {
272                 return Err(PlatformError::InvalidRegister(anyhow!(
273                     "write_reg invalid register {:?}",
274                     reg
275                 )))
276             }
277         }
278 
279         Ok(())
280     }
281 
282     fn read_segment(&self, reg: Register) -> Result<SegmentRegister, PlatformError> {
283         if !reg.is_segment_register() {
284             return Err(PlatformError::InvalidRegister(anyhow!(
285                 "read_segment {:?} is not a segment register",
286                 reg
287             )));
288         }
289 
290         match reg {
291             Register::CS => Ok(self.sregs.cs),
292             Register::DS => Ok(self.sregs.ds),
293             Register::ES => Ok(self.sregs.es),
294             Register::FS => Ok(self.sregs.fs),
295             Register::GS => Ok(self.sregs.gs),
296             Register::SS => Ok(self.sregs.ss),
297             r => Err(PlatformError::InvalidRegister(anyhow!(
298                 "read_segment invalid register {:?}",
299                 r
300             ))),
301         }
302     }
303 
304     fn write_segment(
305         &mut self,
306         reg: Register,
307         segment_register: SegmentRegister,
308     ) -> Result<(), PlatformError> {
309         if !reg.is_segment_register() {
310             return Err(PlatformError::InvalidRegister(anyhow!("{:?}", reg)));
311         }
312 
313         match reg {
314             Register::CS => self.sregs.cs = segment_register,
315             Register::DS => self.sregs.ds = segment_register,
316             Register::ES => self.sregs.es = segment_register,
317             Register::FS => self.sregs.fs = segment_register,
318             Register::GS => self.sregs.gs = segment_register,
319             Register::SS => self.sregs.ss = segment_register,
320             r => return Err(PlatformError::InvalidRegister(anyhow!("{:?}", r))),
321         }
322 
323         Ok(())
324     }
325 
326     fn ip(&self) -> u64 {
327         self.regs.rip
328     }
329 
330     fn set_ip(&mut self, ip: u64) {
331         self.regs.rip = ip;
332     }
333 
334     fn efer(&self) -> u64 {
335         self.sregs.efer
336     }
337 
338     fn set_efer(&mut self, efer: u64) {
339         self.sregs.efer = efer
340     }
341 
342     fn flags(&self) -> u64 {
343         self.regs.rflags
344     }
345 
346     fn set_flags(&mut self, flags: u64) {
347         self.regs.rflags = flags;
348     }
349 }
350 
351 pub struct Emulator<'a, T: CpuStateManager> {
352     platform: &'a mut dyn PlatformEmulator<CpuState = T>,
353     insn_map: InstructionMap<T>,
354 }
355 
356 impl<'a, T: CpuStateManager> Emulator<'a, T> {
357     pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<T> {
358         let mut insn_map = InstructionMap::<T>::new();
359 
360         // MOV
361         insn_add!(insn_map, mov, Mov_r8_imm8);
362         insn_add!(insn_map, mov, Mov_r8_rm8);
363         insn_add!(insn_map, mov, Mov_r16_imm16);
364         insn_add!(insn_map, mov, Mov_r16_rm16);
365         insn_add!(insn_map, mov, Mov_r32_imm32);
366         insn_add!(insn_map, mov, Mov_r32_rm32);
367         insn_add!(insn_map, mov, Mov_r64_imm64);
368         insn_add!(insn_map, mov, Mov_r64_rm64);
369         insn_add!(insn_map, mov, Mov_rm8_imm8);
370         insn_add!(insn_map, mov, Mov_rm8_r8);
371         insn_add!(insn_map, mov, Mov_rm16_imm16);
372         insn_add!(insn_map, mov, Mov_rm16_r16);
373         insn_add!(insn_map, mov, Mov_rm32_imm32);
374         insn_add!(insn_map, mov, Mov_rm32_r32);
375         insn_add!(insn_map, mov, Mov_rm64_imm32);
376         insn_add!(insn_map, mov, Mov_rm64_r64);
377 
378         Emulator { platform, insn_map }
379     }
380 
381     fn emulate_insn_stream(
382         &mut self,
383         cpu_id: usize,
384         insn_stream: &[u8],
385         num_insn: Option<usize>,
386     ) -> EmulationResult<T, Exception> {
387         let mut state = self
388             .platform
389             .cpu_state(cpu_id)
390             .map_err(EmulationError::PlatformEmulationError)?;
391         let mut decoder = Decoder::new(64, insn_stream, DecoderOptions::NONE);
392         decoder.set_ip(state.ip());
393 
394         for (index, insn) in &mut decoder.iter().enumerate() {
395             self.insn_map
396                 .instructions
397                 .get(&insn.code())
398                 .ok_or_else(|| {
399                     EmulationError::UnsupportedInstruction(anyhow!("{:?}", insn.mnemonic()))
400                 })?
401                 .emulate(&insn, &mut state, self.platform)?;
402 
403             if let Some(num_insn) = num_insn {
404                 if index + 1 >= num_insn {
405                     // Exit the decoding loop, do not decode the next instruction.
406                     break;
407                 }
408             }
409         }
410 
411         state.set_ip(decoder.ip());
412         Ok(state)
413     }
414 
415     /// Emulate all instructions from the instructions stream.
416     pub fn emulate(&mut self, cpu_id: usize, insn_stream: &[u8]) -> EmulationResult<T, Exception> {
417         self.emulate_insn_stream(cpu_id, insn_stream, None)
418     }
419 
420     /// Only emulate the first instruction from the stream.
421     ///
422     /// This is useful for cases where we get readahead instruction stream
423     /// but implicitly must only emulate the first instruction, and then return
424     /// to the guest.
425     pub fn emulate_first_insn(
426         &mut self,
427         cpu_id: usize,
428         insn_stream: &[u8],
429     ) -> EmulationResult<T, Exception> {
430         self.emulate_insn_stream(cpu_id, insn_stream, Some(1))
431     }
432 }
433 
434 #[cfg(test)]
435 mod mock_vmm {
436     #![allow(unused_mut)]
437 
438     extern crate env_logger;
439 
440     use super::*;
441     use crate::arch::emulator::{EmulationError, PlatformEmulator};
442     use crate::arch::x86::emulator::{Emulator, EmulatorCpuState as CpuState};
443     use crate::arch::x86::gdt::{gdt_entry, segment_from_gdt};
444     use crate::arch::x86::Exception;
445     use std::collections::HashMap;
446     use std::sync::{Arc, Mutex};
447 
448     #[derive(Debug, Clone)]
449     pub struct MockVMM {
450         memory: Vec<u8>,
451         state: Arc<Mutex<CpuState>>,
452     }
453 
454     unsafe impl Sync for MockVMM {}
455 
456     pub type MockResult = Result<(), EmulationError<Exception>>;
457 
458     impl MockVMM {
459         pub fn new(ip: u64, regs: HashMap<Register, u64>, memory: Option<(u64, &[u8])>) -> MockVMM {
460             let _ = env_logger::try_init();
461             let cs_reg = segment_from_gdt(gdt_entry(0xc09b, 0, 0xffffffff), 1);
462             let ds_reg = segment_from_gdt(gdt_entry(0xc093, 0, 0xffffffff), 2);
463             let mut initial_state = CpuState::default();
464             initial_state.set_ip(ip);
465             initial_state.write_segment(Register::CS, cs_reg).unwrap();
466             initial_state.write_segment(Register::DS, ds_reg).unwrap();
467             for (reg, value) in regs {
468                 initial_state.write_reg(reg, value).unwrap();
469             }
470 
471             let mut vmm = MockVMM {
472                 memory: vec![0; 4096],
473                 state: Arc::new(Mutex::new(initial_state)),
474             };
475 
476             if let Some(mem) = memory {
477                 vmm.write_memory(mem.0, &mem.1).unwrap();
478             }
479 
480             vmm
481         }
482 
483         pub fn emulate_insn(&mut self, cpu_id: usize, insn: &[u8], num_insn: Option<usize>) {
484             let ip = self.cpu_state(cpu_id).unwrap().ip();
485             let mut emulator = Emulator::new(self);
486 
487             let new_state = emulator
488                 .emulate_insn_stream(cpu_id, &insn, num_insn)
489                 .unwrap();
490             if num_insn.is_none() {
491                 assert_eq!(ip + insn.len() as u64, new_state.ip());
492             }
493 
494             self.set_cpu_state(cpu_id, new_state).unwrap();
495         }
496 
497         pub fn emulate_first_insn(&mut self, cpu_id: usize, insn: &[u8]) {
498             self.emulate_insn(cpu_id, insn, None)
499         }
500     }
501 
502     impl PlatformEmulator for MockVMM {
503         type CpuState = CpuState;
504 
505         fn read_memory(&self, gva: u64, data: &mut [u8]) -> Result<(), PlatformError> {
506             debug!(
507                 "Memory read {} bytes from [{:#x} -> {:#x}]",
508                 data.len(),
509                 gva,
510                 gva
511             );
512             data.copy_from_slice(&self.memory[gva as usize..gva as usize + data.len()]);
513             Ok(())
514         }
515 
516         fn write_memory(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError> {
517             debug!(
518                 "Memory write {} bytes at [{:#x} -> {:#x}]",
519                 data.len(),
520                 gva,
521                 gva
522             );
523             self.memory[gva as usize..gva as usize + data.len()].copy_from_slice(data);
524 
525             Ok(())
526         }
527 
528         fn cpu_state(&self, _cpu_id: usize) -> Result<CpuState, PlatformError> {
529             Ok(self.state.lock().unwrap().clone())
530         }
531 
532         fn set_cpu_state(
533             &self,
534             _cpu_id: usize,
535             state: Self::CpuState,
536         ) -> Result<(), PlatformError> {
537             *self.state.lock().unwrap() = state;
538             Ok(())
539         }
540 
541         fn gva_to_gpa(&self, gva: u64) -> Result<u64, PlatformError> {
542             Ok(gva)
543         }
544     }
545 }
546