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 serde::{Deserialize, Serialize};
12 ///
13 /// Export generically-named wrappers of kvm-bindings for Unix-based platforms
14 ///
15 pub use {
16 kvm_bindings::kvm_cpuid_entry2, kvm_bindings::kvm_dtable, kvm_bindings::kvm_fpu,
17 kvm_bindings::kvm_lapic_state, kvm_bindings::kvm_mp_state as MpState,
18 kvm_bindings::kvm_msr_entry, kvm_bindings::kvm_regs, kvm_bindings::kvm_segment,
19 kvm_bindings::kvm_sregs, kvm_bindings::kvm_vcpu_events as VcpuEvents,
20 kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave,
21 kvm_bindings::CpuId, kvm_bindings::MsrList, kvm_bindings::Msrs as MsrEntries,
22 kvm_bindings::KVM_CPUID_FLAG_SIGNIFCANT_INDEX,
23 };
24
25 use crate::arch::x86::{
26 CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters,
27 XsaveState, CPUID_FLAG_VALID_INDEX,
28 };
29 use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
30
31 ///
32 /// Check KVM extension for Linux
33 ///
check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()>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 {
from(s: SegmentRegister) -> Self82 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 {
from(s: kvm_segment) -> Self102 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 {
from(dt: DescriptorTable) -> Self121 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 {
from(dt: kvm_dtable) -> Self131 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 {
from(s: SpecialRegisters) -> Self140 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 {
from(s: kvm_sregs) -> Self165 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 {
from(e: CpuIdEntry) -> Self190 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 {
from(e: kvm_cpuid_entry2) -> Self210 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 {
from(s: kvm_fpu) -> Self229 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 {
from(s: FpuState) -> Self245 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 {
from(s: LapicState) -> Self262 fn from(s: LapicState) -> Self {
263 Self { regs: s.regs }
264 }
265 }
266
267 impl From<kvm_lapic_state> for LapicState {
from(s: kvm_lapic_state) -> Self268 fn from(s: kvm_lapic_state) -> Self {
269 Self { regs: s.regs }
270 }
271 }
272
273 impl From<kvm_msr_entry> for MsrEntry {
from(e: kvm_msr_entry) -> Self274 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 {
from(e: MsrEntry) -> Self283 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 {
from(s: kvm_xsave) -> Self293 fn from(s: kvm_xsave) -> Self {
294 Self { region: s.region }
295 }
296 }
297
298 impl From<XsaveState> for kvm_xsave {
from(s: XsaveState) -> Self299 fn from(s: XsaveState) -> Self {
300 Self {
301 region: s.region,
302 extra: Default::default(),
303 }
304 }
305 }
306