1 // Copyright © 2019 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause 4 // 5 // Copyright © 2020, Microsoft Corporation 6 // 7 // Copyright 2018-2019 CrowdStrike, Inc. 8 // 9 // 10 11 use crate::arch::x86::{ 12 CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters, 13 StandardRegisters, XsaveState, CPUID_FLAG_VALID_INDEX, 14 }; 15 use crate::kvm::{Cap, Kvm, KvmError, KvmResult}; 16 use serde::{Deserialize, Serialize}; 17 18 /// 19 /// Export generically-named wrappers of kvm-bindings for Unix-based platforms 20 /// 21 pub use { 22 kvm_bindings::kvm_cpuid_entry2, kvm_bindings::kvm_dtable, kvm_bindings::kvm_fpu, 23 kvm_bindings::kvm_lapic_state, kvm_bindings::kvm_mp_state as MpState, 24 kvm_bindings::kvm_msr_entry, kvm_bindings::kvm_regs, kvm_bindings::kvm_segment, 25 kvm_bindings::kvm_sregs, kvm_bindings::kvm_vcpu_events as VcpuEvents, 26 kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave, 27 kvm_bindings::CpuId, kvm_bindings::MsrList, kvm_bindings::Msrs as MsrEntries, 28 kvm_bindings::KVM_CPUID_FLAG_SIGNIFCANT_INDEX, 29 }; 30 31 /// 32 /// Check KVM extension for Linux 33 /// 34 pub fn check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()> { 35 macro_rules! check_extension { 36 ($cap:expr) => { 37 if !kvm.check_extension($cap) { 38 return Err(KvmError::CapabilityMissing($cap)); 39 } 40 }; 41 } 42 43 // DeviceCtrl, EnableCap, and SetGuestDebug are also required, but some kernels have 44 // the features implemented without the capability flags. 45 check_extension!(Cap::AdjustClock); 46 check_extension!(Cap::ExtCpuid); 47 check_extension!(Cap::GetTscKhz); 48 check_extension!(Cap::ImmediateExit); 49 check_extension!(Cap::Ioeventfd); 50 check_extension!(Cap::Irqchip); 51 check_extension!(Cap::Irqfd); 52 check_extension!(Cap::IrqRouting); 53 check_extension!(Cap::MpState); 54 check_extension!(Cap::SetIdentityMapAddr); 55 check_extension!(Cap::SetTssAddr); 56 check_extension!(Cap::SplitIrqchip); 57 check_extension!(Cap::TscDeadlineTimer); 58 check_extension!(Cap::UserMemory); 59 check_extension!(Cap::UserNmi); 60 check_extension!(Cap::VcpuEvents); 61 check_extension!(Cap::Xcrs); 62 check_extension!(Cap::Xsave); 63 Ok(()) 64 } 65 66 #[derive(Clone, Serialize, Deserialize)] 67 pub struct VcpuKvmState { 68 pub cpuid: Vec<CpuIdEntry>, 69 pub msrs: Vec<MsrEntry>, 70 pub vcpu_events: VcpuEvents, 71 pub regs: kvm_regs, 72 pub sregs: kvm_sregs, 73 pub fpu: FpuState, 74 pub lapic_state: LapicState, 75 pub xsave: XsaveState, 76 pub xcrs: ExtendedControlRegisters, 77 pub mp_state: MpState, 78 pub tsc_khz: Option<u32>, 79 } 80 81 impl From<StandardRegisters> for kvm_regs { 82 fn from(regs: StandardRegisters) -> Self { 83 Self { 84 rax: regs.rax, 85 rbx: regs.rbx, 86 rcx: regs.rcx, 87 rdx: regs.rdx, 88 rsi: regs.rsi, 89 rdi: regs.rdi, 90 rsp: regs.rsp, 91 rbp: regs.rbp, 92 r8: regs.r8, 93 r9: regs.r9, 94 r10: regs.r10, 95 r11: regs.r11, 96 r12: regs.r12, 97 r13: regs.r13, 98 r14: regs.r14, 99 r15: regs.r15, 100 rip: regs.rip, 101 rflags: regs.rflags, 102 } 103 } 104 } 105 106 impl From<kvm_regs> for StandardRegisters { 107 fn from(regs: kvm_regs) -> Self { 108 Self { 109 rax: regs.rax, 110 rbx: regs.rbx, 111 rcx: regs.rcx, 112 rdx: regs.rdx, 113 rsi: regs.rsi, 114 rdi: regs.rdi, 115 rsp: regs.rsp, 116 rbp: regs.rbp, 117 r8: regs.r8, 118 r9: regs.r9, 119 r10: regs.r10, 120 r11: regs.r11, 121 r12: regs.r12, 122 r13: regs.r13, 123 r14: regs.r14, 124 r15: regs.r15, 125 rip: regs.rip, 126 rflags: regs.rflags, 127 } 128 } 129 } 130 131 impl From<SegmentRegister> for kvm_segment { 132 fn from(s: SegmentRegister) -> Self { 133 Self { 134 base: s.base, 135 limit: s.limit, 136 selector: s.selector, 137 type_: s.type_, 138 present: s.present, 139 dpl: s.dpl, 140 db: s.db, 141 s: s.s, 142 l: s.l, 143 g: s.g, 144 avl: s.avl, 145 unusable: s.unusable, 146 ..Default::default() 147 } 148 } 149 } 150 151 impl From<kvm_segment> for SegmentRegister { 152 fn from(s: kvm_segment) -> Self { 153 Self { 154 base: s.base, 155 limit: s.limit, 156 selector: s.selector, 157 type_: s.type_, 158 present: s.present, 159 dpl: s.dpl, 160 db: s.db, 161 s: s.s, 162 l: s.l, 163 g: s.g, 164 avl: s.avl, 165 unusable: s.unusable, 166 } 167 } 168 } 169 170 impl From<DescriptorTable> for kvm_dtable { 171 fn from(dt: DescriptorTable) -> Self { 172 Self { 173 base: dt.base, 174 limit: dt.limit, 175 ..Default::default() 176 } 177 } 178 } 179 180 impl From<kvm_dtable> for DescriptorTable { 181 fn from(dt: kvm_dtable) -> Self { 182 Self { 183 base: dt.base, 184 limit: dt.limit, 185 } 186 } 187 } 188 189 impl From<SpecialRegisters> for kvm_sregs { 190 fn from(s: SpecialRegisters) -> Self { 191 Self { 192 cs: s.cs.into(), 193 ds: s.ds.into(), 194 es: s.es.into(), 195 fs: s.fs.into(), 196 gs: s.gs.into(), 197 ss: s.ss.into(), 198 tr: s.tr.into(), 199 ldt: s.ldt.into(), 200 gdt: s.gdt.into(), 201 idt: s.idt.into(), 202 cr0: s.cr0, 203 cr2: s.cr2, 204 cr3: s.cr3, 205 cr4: s.cr4, 206 cr8: s.cr8, 207 efer: s.efer, 208 apic_base: s.apic_base, 209 interrupt_bitmap: s.interrupt_bitmap, 210 } 211 } 212 } 213 214 impl From<kvm_sregs> for SpecialRegisters { 215 fn from(s: kvm_sregs) -> Self { 216 Self { 217 cs: s.cs.into(), 218 ds: s.ds.into(), 219 es: s.es.into(), 220 fs: s.fs.into(), 221 gs: s.gs.into(), 222 ss: s.ss.into(), 223 tr: s.tr.into(), 224 ldt: s.ldt.into(), 225 gdt: s.gdt.into(), 226 idt: s.idt.into(), 227 cr0: s.cr0, 228 cr2: s.cr2, 229 cr3: s.cr3, 230 cr4: s.cr4, 231 cr8: s.cr8, 232 efer: s.efer, 233 apic_base: s.apic_base, 234 interrupt_bitmap: s.interrupt_bitmap, 235 } 236 } 237 } 238 239 impl From<CpuIdEntry> for kvm_cpuid_entry2 { 240 fn from(e: CpuIdEntry) -> Self { 241 let flags = if e.flags & CPUID_FLAG_VALID_INDEX != 0 { 242 KVM_CPUID_FLAG_SIGNIFCANT_INDEX 243 } else { 244 0 245 }; 246 Self { 247 function: e.function, 248 index: e.index, 249 flags, 250 eax: e.eax, 251 ebx: e.ebx, 252 ecx: e.ecx, 253 edx: e.edx, 254 ..Default::default() 255 } 256 } 257 } 258 259 impl From<kvm_cpuid_entry2> for CpuIdEntry { 260 fn from(e: kvm_cpuid_entry2) -> Self { 261 let flags = if e.flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX != 0 { 262 CPUID_FLAG_VALID_INDEX 263 } else { 264 0 265 }; 266 Self { 267 function: e.function, 268 index: e.index, 269 flags, 270 eax: e.eax, 271 ebx: e.ebx, 272 ecx: e.ecx, 273 edx: e.edx, 274 } 275 } 276 } 277 278 impl From<kvm_fpu> for FpuState { 279 fn from(s: kvm_fpu) -> Self { 280 Self { 281 fpr: s.fpr, 282 fcw: s.fcw, 283 fsw: s.fsw, 284 ftwx: s.ftwx, 285 last_opcode: s.last_opcode, 286 last_ip: s.last_ip, 287 last_dp: s.last_dp, 288 xmm: s.xmm, 289 mxcsr: s.mxcsr, 290 } 291 } 292 } 293 294 impl From<FpuState> for kvm_fpu { 295 fn from(s: FpuState) -> Self { 296 Self { 297 fpr: s.fpr, 298 fcw: s.fcw, 299 fsw: s.fsw, 300 ftwx: s.ftwx, 301 last_opcode: s.last_opcode, 302 last_ip: s.last_ip, 303 last_dp: s.last_dp, 304 xmm: s.xmm, 305 mxcsr: s.mxcsr, 306 ..Default::default() 307 } 308 } 309 } 310 311 impl From<LapicState> for kvm_lapic_state { 312 fn from(s: LapicState) -> Self { 313 Self { regs: s.regs } 314 } 315 } 316 317 impl From<kvm_lapic_state> for LapicState { 318 fn from(s: kvm_lapic_state) -> Self { 319 Self { regs: s.regs } 320 } 321 } 322 323 impl From<kvm_msr_entry> for MsrEntry { 324 fn from(e: kvm_msr_entry) -> Self { 325 Self { 326 index: e.index, 327 data: e.data, 328 } 329 } 330 } 331 332 impl From<MsrEntry> for kvm_msr_entry { 333 fn from(e: MsrEntry) -> Self { 334 Self { 335 index: e.index, 336 data: e.data, 337 ..Default::default() 338 } 339 } 340 } 341 342 impl From<kvm_xsave> for XsaveState { 343 fn from(s: kvm_xsave) -> Self { 344 Self { region: s.region } 345 } 346 } 347 348 impl From<XsaveState> for kvm_xsave { 349 fn from(s: XsaveState) -> Self { 350 Self { 351 region: s.region, 352 extra: Default::default(), 353 } 354 } 355 } 356