xref: /cloud-hypervisor/hypervisor/src/kvm/x86_64/mod.rs (revision fee769bed4c58a07b67e25a7339cfd397f701f3a)
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