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 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<SegmentRegister> for kvm_segment { 82 fn from(s: SegmentRegister) -> Self { 83 Self { 84 base: s.base, 85 limit: s.limit, 86 selector: s.selector, 87 type_: s.type_, 88 present: s.present, 89 dpl: s.dpl, 90 db: s.db, 91 s: s.s, 92 l: s.l, 93 g: s.g, 94 avl: s.avl, 95 unusable: s.unusable, 96 ..Default::default() 97 } 98 } 99 } 100 101 impl From<kvm_segment> for SegmentRegister { 102 fn from(s: kvm_segment) -> Self { 103 Self { 104 base: s.base, 105 limit: s.limit, 106 selector: s.selector, 107 type_: s.type_, 108 present: s.present, 109 dpl: s.dpl, 110 db: s.db, 111 s: s.s, 112 l: s.l, 113 g: s.g, 114 avl: s.avl, 115 unusable: s.unusable, 116 } 117 } 118 } 119 120 impl From<DescriptorTable> for kvm_dtable { 121 fn from(dt: DescriptorTable) -> Self { 122 Self { 123 base: dt.base, 124 limit: dt.limit, 125 ..Default::default() 126 } 127 } 128 } 129 130 impl From<kvm_dtable> for DescriptorTable { 131 fn from(dt: kvm_dtable) -> Self { 132 Self { 133 base: dt.base, 134 limit: dt.limit, 135 } 136 } 137 } 138 139 impl From<SpecialRegisters> for kvm_sregs { 140 fn from(s: SpecialRegisters) -> Self { 141 Self { 142 cs: s.cs.into(), 143 ds: s.ds.into(), 144 es: s.es.into(), 145 fs: s.fs.into(), 146 gs: s.gs.into(), 147 ss: s.ss.into(), 148 tr: s.tr.into(), 149 ldt: s.ldt.into(), 150 gdt: s.gdt.into(), 151 idt: s.idt.into(), 152 cr0: s.cr0, 153 cr2: s.cr2, 154 cr3: s.cr3, 155 cr4: s.cr4, 156 cr8: s.cr8, 157 efer: s.efer, 158 apic_base: s.apic_base, 159 interrupt_bitmap: s.interrupt_bitmap, 160 } 161 } 162 } 163 164 impl From<kvm_sregs> for SpecialRegisters { 165 fn from(s: kvm_sregs) -> Self { 166 Self { 167 cs: s.cs.into(), 168 ds: s.ds.into(), 169 es: s.es.into(), 170 fs: s.fs.into(), 171 gs: s.gs.into(), 172 ss: s.ss.into(), 173 tr: s.tr.into(), 174 ldt: s.ldt.into(), 175 gdt: s.gdt.into(), 176 idt: s.idt.into(), 177 cr0: s.cr0, 178 cr2: s.cr2, 179 cr3: s.cr3, 180 cr4: s.cr4, 181 cr8: s.cr8, 182 efer: s.efer, 183 apic_base: s.apic_base, 184 interrupt_bitmap: s.interrupt_bitmap, 185 } 186 } 187 } 188 189 impl From<CpuIdEntry> for kvm_cpuid_entry2 { 190 fn from(e: CpuIdEntry) -> Self { 191 let flags = if e.flags & CPUID_FLAG_VALID_INDEX != 0 { 192 KVM_CPUID_FLAG_SIGNIFCANT_INDEX 193 } else { 194 0 195 }; 196 Self { 197 function: e.function, 198 index: e.index, 199 flags, 200 eax: e.eax, 201 ebx: e.ebx, 202 ecx: e.ecx, 203 edx: e.edx, 204 ..Default::default() 205 } 206 } 207 } 208 209 impl From<kvm_cpuid_entry2> for CpuIdEntry { 210 fn from(e: kvm_cpuid_entry2) -> Self { 211 let flags = if e.flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX != 0 { 212 CPUID_FLAG_VALID_INDEX 213 } else { 214 0 215 }; 216 Self { 217 function: e.function, 218 index: e.index, 219 flags, 220 eax: e.eax, 221 ebx: e.ebx, 222 ecx: e.ecx, 223 edx: e.edx, 224 } 225 } 226 } 227 228 impl From<kvm_fpu> for FpuState { 229 fn from(s: kvm_fpu) -> Self { 230 Self { 231 fpr: s.fpr, 232 fcw: s.fcw, 233 fsw: s.fsw, 234 ftwx: s.ftwx, 235 last_opcode: s.last_opcode, 236 last_ip: s.last_ip, 237 last_dp: s.last_dp, 238 xmm: s.xmm, 239 mxcsr: s.mxcsr, 240 } 241 } 242 } 243 244 impl From<FpuState> for kvm_fpu { 245 fn from(s: FpuState) -> Self { 246 Self { 247 fpr: s.fpr, 248 fcw: s.fcw, 249 fsw: s.fsw, 250 ftwx: s.ftwx, 251 last_opcode: s.last_opcode, 252 last_ip: s.last_ip, 253 last_dp: s.last_dp, 254 xmm: s.xmm, 255 mxcsr: s.mxcsr, 256 ..Default::default() 257 } 258 } 259 } 260 261 impl From<LapicState> for kvm_lapic_state { 262 fn from(s: LapicState) -> Self { 263 Self { regs: s.regs } 264 } 265 } 266 267 impl From<kvm_lapic_state> for LapicState { 268 fn from(s: kvm_lapic_state) -> Self { 269 Self { regs: s.regs } 270 } 271 } 272 273 impl From<kvm_msr_entry> for MsrEntry { 274 fn from(e: kvm_msr_entry) -> Self { 275 Self { 276 index: e.index, 277 data: e.data, 278 } 279 } 280 } 281 282 impl From<MsrEntry> for kvm_msr_entry { 283 fn from(e: MsrEntry) -> Self { 284 Self { 285 index: e.index, 286 data: e.data, 287 ..Default::default() 288 } 289 } 290 } 291 292 impl From<kvm_xsave> for XsaveState { 293 fn from(s: kvm_xsave) -> Self { 294 Self { region: s.region } 295 } 296 } 297 298 impl From<XsaveState> for kvm_xsave { 299 fn from(s: XsaveState) -> Self { 300 Self { 301 region: s.region, 302 extra: Default::default(), 303 } 304 } 305 } 306