1#![deny(missing_docs,
17 missing_debug_implementations, missing_copy_implementations,
18 trivial_casts, trivial_numeric_casts,
19 unstable_features,
20 unused_import_braces, unused_qualifications)]
21
22#![cfg_attr(feature = "dev", allow(unstable_features))]
23#![cfg_attr(feature = "dev", feature(plugin))]
24#![cfg_attr(feature = "dev", plugin(clippy))]
25
26extern crate errno;
27extern crate libc;
28#[macro_use]
29extern crate log;
30extern crate memmap;
31
32#[cfg(target_arch = "x86_64")]
33#[allow(missing_docs, missing_debug_implementations)]
34mod x86_64;
35
36#[cfg(target_arch = "x86_64")]
37pub use self::x86_64::*;
38
39use errno::{Errno, errno};
40use libc::{E2BIG, ENOMEM, c_int};
41use std::fmt;
42use std::fs::{File, OpenOptions};
43use std::io::{self, Error, ErrorKind};
44use std::mem;
45use std::ops::DerefMut;
46use std::os::unix::io::{AsRawFd, FromRawFd};
47
48use memmap::{Mmap, Protection};
49
50const API_VERSION: i32 = 12;
51
52extern {
53 fn kvm_get_api_version(fd: c_int) -> c_int;
54 fn kvm_create_vm(fd: c_int, flags: c_int) -> c_int;
55 fn kvm_check_extension(fd: c_int, extension: c_int) -> c_int;
56 fn kvm_get_vcpu_mmap_size(fd: c_int) -> c_int;
57 fn kvm_get_supported_cpuid(fd: c_int, cpuid: *mut Cpuid2) -> c_int;
58 fn kvm_create_vcpu(fd: c_int, vcpu_id: c_int) -> c_int;
59 fn kvm_set_user_memory_region(fd: c_int,
60 region: *const UserspaceMemoryRegion)
61 -> c_int;
62 fn kvm_run(fd: c_int) -> c_int;
63 fn kvm_get_regs(fd: c_int, regs: *mut Regs) -> c_int;
64 fn kvm_set_regs(fd: c_int, regs: *const Regs) -> c_int;
65 fn kvm_get_sregs(fd: c_int, sregs: *mut Sregs) -> c_int;
66 fn kvm_set_sregs(fd: c_int, sregs: *const Sregs) -> c_int;
67 fn kvm_set_cpuid2(fd: c_int, cpuid: *const Cpuid2) -> c_int;
68}
69
70#[derive(Debug)]
75pub struct System {
76 fd: File,
77}
78
79#[derive(Debug)]
83pub struct VirtualMachine<'a> {
84 fd: File,
85 sys: &'a System,
86 mem_slots: Vec<&'a mut [u8]>,
87 num_vcpus: u32,
88 check_extension: bool,
89}
90
91pub type Result<T> = io::Result<T>;
93
94#[allow(missing_docs)]
96#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
97#[repr(i32)]
98pub enum Capability {
99 Irqchip,
100 Hlt,
101 MmuShadowCacheControl,
102 UserMemory,
103 SetTssAddr,
104 Vapic = 6,
105 ExtCpuid,
106 ClockSource,
107 NrVcpus,
108 NrMemSlots,
109 Pit,
110 NopIoDelay,
111 PvMmu,
112 MpState,
113 CoalescedMmio,
114 SyncMmu,
115 IoMmu = 18,
116 DestroyMemoryRegionWorks = 21,
117 UserNmi,
118 MaxVcpus = 66,
119 CheckExtensionVm = 105,
120}
121
122#[allow(missing_docs)]
124#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
125#[repr(u32)]
126pub enum Exit {
127 Unknown,
128 Exception,
129 Io,
130 Hypercall,
131 Debug,
132 Hlt,
133 Mmio,
134 IrqWindowOpen,
135 Shutdown,
136 FailEntry,
137 Intr,
138 SetTpr,
139 TprAccess,
140 S390Sieic,
141 S390Reset,
142 Dcr,
143 Nmi,
144 InternalError,
145 Osi,
146 PaprHcall,
147 S390Ucontrol,
148 Watchdog,
149 S390Tsch,
150 Epr,
151 SystemEvent,
152}
153
154#[repr(C)]
155#[derive(Clone, Copy, Debug, Default)]
156struct UserspaceMemoryRegion {
157 pub slot: u32,
158 pub flags: u32,
159 pub guest_phys_addr: u64,
160 pub memory_size: u64,
161 pub userspace_addr: u64,
162}
163
164pub struct Vcpu<'a> {
166 fd: File,
167 vm: &'a VirtualMachine<'a>,
168 mmap: Mmap,
169}
170
171impl<'a> fmt::Debug for Vcpu<'a> {
172 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
173 fmt.debug_struct("Vcpu")
174 .field("fd", &self.fd)
175 .field("vm", &self.vm)
176 .finish()
177 }
178}
179
180
181#[allow(missing_docs)]
183#[repr(C)]
184#[derive(Copy)]
185pub struct Run {
186 request_interrupt_window: u8,
187 padding1: [u8; 7usize],
188 pub exit_reason: Exit,
189 pub ready_for_interrupt_injection: u8,
190 pub if_flag: u8,
191 pub flags: u16,
192 pub cr8: u64,
193 pub apic_base: u64,
194 _bindgen_data_1_: [u64; 32usize],
195 pub kvm_valid_regs: u64,
196 pub kvm_dirty_regs: u64,
197 pub s: Union_Unnamed26,
198}
199
200#[allow(missing_docs)]
201impl Run {
202 pub fn hw(&self) -> *const Struct_Unnamed9 {
203 unsafe {
204 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
205 ::std::mem::transmute(raw.offset(0))
206 }
207 }
208 pub fn hw_mut(&mut self) -> *mut Struct_Unnamed9 {
209 unsafe {
210 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
211 ::std::mem::transmute(raw.offset(0))
212 }
213 }
214 pub fn fail_entry(&self) -> *const Struct_Unnamed10 {
215 unsafe {
216 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
217 ::std::mem::transmute(raw.offset(0))
218 }
219 }
220 pub fn fail_entry_mut(&mut self) -> *mut Struct_Unnamed10 {
221 unsafe {
222 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
223 ::std::mem::transmute(raw.offset(0))
224 }
225 }
226 pub fn ex(&self) -> *const Struct_Unnamed11 {
227 unsafe {
228 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
229 ::std::mem::transmute(raw.offset(0))
230 }
231 }
232 pub fn ex_mut(&mut self) -> *mut Struct_Unnamed11 {
233 unsafe {
234 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
235 ::std::mem::transmute(raw.offset(0))
236 }
237 }
238 pub fn io(&self) -> *const ExitIo {
239 unsafe {
240 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
241 ::std::mem::transmute(raw.offset(0))
242 }
243 }
244 pub fn io_mut(&mut self) -> *mut ExitIo {
245 unsafe {
246 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
247 ::std::mem::transmute(raw.offset(0))
248 }
249 }
250 pub fn debug(&self) -> *const Struct_Unnamed13 {
251 unsafe {
252 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
253 ::std::mem::transmute(raw.offset(0))
254 }
255 }
256 pub fn debug_mut(&mut self) -> *mut Struct_Unnamed13 {
257 unsafe {
258 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
259 ::std::mem::transmute(raw.offset(0))
260 }
261 }
262 pub fn mmio(&self) -> *const Struct_Unnamed14 {
263 unsafe {
264 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
265 ::std::mem::transmute(raw.offset(0))
266 }
267 }
268 pub fn mmio_mut(&mut self) -> *mut Struct_Unnamed14 {
269 unsafe {
270 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
271 ::std::mem::transmute(raw.offset(0))
272 }
273 }
274 pub fn hypercall(&self) -> *const Struct_Unnamed15 {
275 unsafe {
276 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
277 ::std::mem::transmute(raw.offset(0))
278 }
279 }
280 pub fn hypercall_mut(&mut self) -> *mut Struct_Unnamed15 {
281 unsafe {
282 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
283 ::std::mem::transmute(raw.offset(0))
284 }
285 }
286 pub fn tpr_access(&self) -> *const Struct_Unnamed16 {
287 unsafe {
288 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
289 ::std::mem::transmute(raw.offset(0))
290 }
291 }
292 pub fn tpr_access_mut(&mut self) -> *mut Struct_Unnamed16 {
293 unsafe {
294 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
295 ::std::mem::transmute(raw.offset(0))
296 }
297 }
298 pub fn s390_sieic(&self) -> *const Struct_Unnamed17 {
299 unsafe {
300 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
301 ::std::mem::transmute(raw.offset(0))
302 }
303 }
304 pub fn s390_sieic_mut(&mut self) -> *mut Struct_Unnamed17 {
305 unsafe {
306 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
307 ::std::mem::transmute(raw.offset(0))
308 }
309 }
310 pub fn s390_reset_flags(&self) -> *const u64 {
311 unsafe {
312 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
313 ::std::mem::transmute(raw.offset(0))
314 }
315 }
316 pub fn s390_reset_flags_mut(&mut self) -> *mut u64 {
317 unsafe {
318 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
319 ::std::mem::transmute(raw.offset(0))
320 }
321 }
322 pub fn s390_ucontrol(&self) -> *const Struct_Unnamed18 {
323 unsafe {
324 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
325 ::std::mem::transmute(raw.offset(0))
326 }
327 }
328 pub fn s390_ucontrol_mut(&mut self) -> *mut Struct_Unnamed18 {
329 unsafe {
330 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
331 ::std::mem::transmute(raw.offset(0))
332 }
333 }
334 pub fn dcr(&self) -> *const Struct_Unnamed19 {
335 unsafe {
336 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
337 ::std::mem::transmute(raw.offset(0))
338 }
339 }
340 pub fn dcr_mut(&mut self) -> *mut Struct_Unnamed19 {
341 unsafe {
342 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
343 ::std::mem::transmute(raw.offset(0))
344 }
345 }
346 pub fn internal(&self) -> *const Struct_Unnamed20 {
347 unsafe {
348 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
349 ::std::mem::transmute(raw.offset(0))
350 }
351 }
352 pub fn internal_mut(&mut self) -> *mut Struct_Unnamed20 {
353 unsafe {
354 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
355 ::std::mem::transmute(raw.offset(0))
356 }
357 }
358 pub fn osi(&self) -> *const Struct_Unnamed21 {
359 unsafe {
360 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
361 ::std::mem::transmute(raw.offset(0))
362 }
363 }
364 pub fn osi_mut(&mut self) -> *mut Struct_Unnamed21 {
365 unsafe {
366 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
367 ::std::mem::transmute(raw.offset(0))
368 }
369 }
370 pub fn papr_hcall(&self) -> *const Struct_Unnamed22 {
371 unsafe {
372 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
373 ::std::mem::transmute(raw.offset(0))
374 }
375 }
376 pub fn papr_hcall_mut(&mut self) -> *mut Struct_Unnamed22 {
377 unsafe {
378 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
379 ::std::mem::transmute(raw.offset(0))
380 }
381 }
382 pub fn s390_tsch(&self) -> *const Struct_Unnamed23 {
383 unsafe {
384 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
385 ::std::mem::transmute(raw.offset(0))
386 }
387 }
388 pub fn s390_tsch_mut(&mut self) -> *mut Struct_Unnamed23 {
389 unsafe {
390 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
391 ::std::mem::transmute(raw.offset(0))
392 }
393 }
394 pub fn epr(&self) -> *const Struct_Unnamed24 {
395 unsafe {
396 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
397 ::std::mem::transmute(raw.offset(0))
398 }
399 }
400 pub fn epr_mut(&mut self) -> *mut Struct_Unnamed24 {
401 unsafe {
402 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
403 ::std::mem::transmute(raw.offset(0))
404 }
405 }
406 pub fn system_event(&self) -> *const Struct_Unnamed25 {
407 unsafe {
408 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
409 ::std::mem::transmute(raw.offset(0))
410 }
411 }
412 pub fn system_event_mut(&mut self) -> *mut Struct_Unnamed25 {
413 unsafe {
414 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
415 ::std::mem::transmute(raw.offset(0))
416 }
417 }
418}
419impl ::std::clone::Clone for Run {
420 fn clone(&self) -> Self {
421 *self
422 }
423}
424impl ::std::default::Default for Run {
425 fn default() -> Self {
426 unsafe { ::std::mem::zeroed() }
427 }
428}
429
430impl fmt::Debug for Run {
431 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
432 let mut s = fmt.debug_struct("Run");
433 s.field("request_interrupt_window", &self.request_interrupt_window)
434 .field("exit_reason", &self.exit_reason)
435 .field("ready_for_interrupt_injection",
436 &self.ready_for_interrupt_injection)
437 .field("if_flag", &self.if_flag)
438 .field("flags", &self.flags)
439 .field("cr8", &self.cr8);
440 unsafe {
441 match self.exit_reason {
442 Exit::Unknown => s.field("hw", &*self.hw()),
443 Exit::FailEntry => s.field("fail_entry", &*self.fail_entry()),
444 Exit::Exception => s.field("ex", &*self.ex()),
445 Exit::Io => s.field("io", &*self.io()),
446 Exit::Debug => s.field("debug", &*self.debug()),
447 Exit::Mmio => s.field("mmio", &*self.mmio()),
448 Exit::Hypercall => s.field("hypercall", &*self.hypercall()),
449 Exit::TprAccess => s.field("tpr_access", &*self.tpr_access()),
450 Exit::S390Sieic => s.field("s390_sieic", &*self.s390_sieic()),
451 Exit::S390Reset =>
452 s.field("s390_reset_flags", &*self.s390_reset_flags()),
453 Exit::S390Ucontrol =>
454 s.field("s390_ucontrol", &*self.s390_ucontrol()),
455 Exit::Dcr => s.field("dcr", &*self.dcr()),
456 Exit::Osi => s.field("osi", &*self.osi()),
457 Exit::PaprHcall => s.field("papr_hcall", &*self.papr_hcall()),
458 Exit::S390Tsch => s.field("s390_tsch", &*self.s390_tsch()),
459 Exit::Epr => s.field("epr", &*self.epr()),
460 Exit::SystemEvent =>
461 s.field("system_event", &*self.system_event()),
462 _ => &mut s,
463 }
464 }
465 .finish()
466 }
467}
468#[allow(missing_docs)]
469#[repr(C)]
470#[derive(Copy, Debug)]
471pub struct Struct_Unnamed9 {
472 pub hardware_exit_reason: u64,
473}
474impl ::std::clone::Clone for Struct_Unnamed9 {
475 fn clone(&self) -> Self {
476 *self
477 }
478}
479impl ::std::default::Default for Struct_Unnamed9 {
480 fn default() -> Self {
481 unsafe { ::std::mem::zeroed() }
482 }
483}
484#[allow(missing_docs)]
485#[repr(C)]
486#[derive(Copy, Debug)]
487pub struct Struct_Unnamed10 {
488 pub hardware_entry_failure_reason: u64,
489}
490impl ::std::clone::Clone for Struct_Unnamed10 {
491 fn clone(&self) -> Self {
492 *self
493 }
494}
495impl ::std::default::Default for Struct_Unnamed10 {
496 fn default() -> Self {
497 unsafe { ::std::mem::zeroed() }
498 }
499}
500#[allow(missing_docs)]
501#[repr(C)]
502#[derive(Copy, Debug)]
503pub struct Struct_Unnamed11 {
504 pub exception: u32,
505 pub error_code: u32,
506}
507impl ::std::clone::Clone for Struct_Unnamed11 {
508 fn clone(&self) -> Self {
509 *self
510 }
511}
512impl ::std::default::Default for Struct_Unnamed11 {
513 fn default() -> Self {
514 unsafe { ::std::mem::zeroed() }
515 }
516}
517
518#[allow(missing_docs)]
519#[repr(u8)]
520#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
521pub enum IoDirection {
522 In,
523 Out,
524}
525
526#[allow(missing_docs)]
527#[repr(C)]
528#[derive(Copy, Debug)]
529pub struct ExitIo {
530 pub direction: IoDirection,
531 pub size: u8,
532 pub port: u16,
533 pub count: u32,
534 pub data_offset: u64,
535}
536impl ::std::clone::Clone for ExitIo {
537 fn clone(&self) -> Self {
538 *self
539 }
540}
541impl ::std::default::Default for ExitIo {
542 fn default() -> Self {
543 unsafe { ::std::mem::zeroed() }
544 }
545}
546#[allow(missing_docs)]
547#[repr(C)]
548#[derive(Copy, Debug)]
549pub struct Struct_Unnamed13 {
550 pub arch: DebugExitArch,
551}
552impl ::std::clone::Clone for Struct_Unnamed13 {
553 fn clone(&self) -> Self {
554 *self
555 }
556}
557impl ::std::default::Default for Struct_Unnamed13 {
558 fn default() -> Self {
559 unsafe { ::std::mem::zeroed() }
560 }
561}
562#[allow(missing_docs)]
563#[repr(C)]
564#[derive(Copy, Debug)]
565pub struct Struct_Unnamed14 {
566 pub phys_addr: u64,
567 pub data: [u8; 8usize],
568 pub len: u32,
569 pub is_write: u8,
570}
571impl ::std::clone::Clone for Struct_Unnamed14 {
572 fn clone(&self) -> Self {
573 *self
574 }
575}
576impl ::std::default::Default for Struct_Unnamed14 {
577 fn default() -> Self {
578 unsafe { ::std::mem::zeroed() }
579 }
580}
581#[allow(missing_docs)]
582#[repr(C)]
583#[derive(Copy, Debug)]
584pub struct Struct_Unnamed15 {
585 pub nr: u64,
586 pub args: [u64; 6usize],
587 pub ret: u64,
588 pub longmode: u32,
589 pub pad: u32,
590}
591impl ::std::clone::Clone for Struct_Unnamed15 {
592 fn clone(&self) -> Self {
593 *self
594 }
595}
596impl ::std::default::Default for Struct_Unnamed15 {
597 fn default() -> Self {
598 unsafe { ::std::mem::zeroed() }
599 }
600}
601#[allow(missing_docs)]
602#[repr(C)]
603#[derive(Copy, Debug)]
604pub struct Struct_Unnamed16 {
605 pub rip: u64,
606 pub is_write: u32,
607 pub pad: u32,
608}
609impl ::std::clone::Clone for Struct_Unnamed16 {
610 fn clone(&self) -> Self {
611 *self
612 }
613}
614impl ::std::default::Default for Struct_Unnamed16 {
615 fn default() -> Self {
616 unsafe { ::std::mem::zeroed() }
617 }
618}
619#[allow(missing_docs)]
620#[repr(C)]
621#[derive(Copy, Debug)]
622pub struct Struct_Unnamed17 {
623 pub icptcode: u8,
624 pub ipa: u16,
625 pub ipb: u32,
626}
627impl ::std::clone::Clone for Struct_Unnamed17 {
628 fn clone(&self) -> Self {
629 *self
630 }
631}
632impl ::std::default::Default for Struct_Unnamed17 {
633 fn default() -> Self {
634 unsafe { ::std::mem::zeroed() }
635 }
636}
637#[allow(missing_docs)]
638#[repr(C)]
639#[derive(Copy, Debug)]
640pub struct Struct_Unnamed18 {
641 pub trans_exc_code: u64,
642 pub pgm_code: u32,
643}
644impl ::std::clone::Clone for Struct_Unnamed18 {
645 fn clone(&self) -> Self {
646 *self
647 }
648}
649impl ::std::default::Default for Struct_Unnamed18 {
650 fn default() -> Self {
651 unsafe { ::std::mem::zeroed() }
652 }
653}
654#[allow(missing_docs)]
655#[repr(C)]
656#[derive(Copy, Debug)]
657pub struct Struct_Unnamed19 {
658 pub dcrn: u32,
659 pub data: u32,
660 pub is_write: u8,
661}
662impl ::std::clone::Clone for Struct_Unnamed19 {
663 fn clone(&self) -> Self {
664 *self
665 }
666}
667impl ::std::default::Default for Struct_Unnamed19 {
668 fn default() -> Self {
669 unsafe { ::std::mem::zeroed() }
670 }
671}
672#[allow(missing_docs)]
673#[repr(C)]
674#[derive(Copy, Debug)]
675pub struct Struct_Unnamed20 {
676 pub suberror: u32,
677 pub ndata: u32,
678 pub data: [u64; 16usize],
679}
680impl ::std::clone::Clone for Struct_Unnamed20 {
681 fn clone(&self) -> Self {
682 *self
683 }
684}
685impl ::std::default::Default for Struct_Unnamed20 {
686 fn default() -> Self {
687 unsafe { ::std::mem::zeroed() }
688 }
689}
690#[allow(missing_docs)]
691#[repr(C)]
692#[derive(Copy, Debug)]
693pub struct Struct_Unnamed21 {
694 pub gprs: [u64; 32usize],
695}
696impl ::std::clone::Clone for Struct_Unnamed21 {
697 fn clone(&self) -> Self {
698 *self
699 }
700}
701impl ::std::default::Default for Struct_Unnamed21 {
702 fn default() -> Self {
703 unsafe { ::std::mem::zeroed() }
704 }
705}
706#[allow(missing_docs)]
707#[repr(C)]
708#[derive(Copy, Debug)]
709pub struct Struct_Unnamed22 {
710 pub nr: u64,
711 pub ret: u64,
712 pub args: [u64; 9usize],
713}
714impl ::std::clone::Clone for Struct_Unnamed22 {
715 fn clone(&self) -> Self {
716 *self
717 }
718}
719impl ::std::default::Default for Struct_Unnamed22 {
720 fn default() -> Self {
721 unsafe { ::std::mem::zeroed() }
722 }
723}
724#[allow(missing_docs)]
725#[repr(C)]
726#[derive(Copy, Debug)]
727pub struct Struct_Unnamed23 {
728 pub subchannel_id: u16,
729 pub subchannel_nr: u16,
730 pub io_int_parm: u32,
731 pub io_int_word: u32,
732 pub ipb: u32,
733 pub dequeued: u8,
734}
735impl ::std::clone::Clone for Struct_Unnamed23 {
736 fn clone(&self) -> Self {
737 *self
738 }
739}
740impl ::std::default::Default for Struct_Unnamed23 {
741 fn default() -> Self {
742 unsafe { ::std::mem::zeroed() }
743 }
744}
745#[allow(missing_docs)]
746#[repr(C)]
747#[derive(Copy, Debug)]
748pub struct Struct_Unnamed24 {
749 pub epr: u32,
750}
751impl ::std::clone::Clone for Struct_Unnamed24 {
752 fn clone(&self) -> Self {
753 *self
754 }
755}
756impl ::std::default::Default for Struct_Unnamed24 {
757 fn default() -> Self {
758 unsafe { ::std::mem::zeroed() }
759 }
760}
761#[allow(missing_docs)]
762#[repr(C)]
763#[derive(Copy, Debug)]
764pub struct Struct_Unnamed25 {
765 pub _type: u32,
766 pub flags: u64,
767}
768impl ::std::clone::Clone for Struct_Unnamed25 {
769 fn clone(&self) -> Self {
770 *self
771 }
772}
773impl ::std::default::Default for Struct_Unnamed25 {
774 fn default() -> Self {
775 unsafe { ::std::mem::zeroed() }
776 }
777}
778#[allow(missing_docs, missing_debug_implementations)]
779#[repr(C)]
780#[derive(Copy)]
781pub struct Union_Unnamed26 {
782 pub _bindgen_data_: [u8; 1024usize],
783}
784#[allow(missing_docs)]
785impl Union_Unnamed26 {
786 pub fn regs(&self) -> *const SyncRegs {
787 unsafe {
788 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
789 ::std::mem::transmute(raw.offset(0))
790 }
791 }
792 pub fn regs_mut(&mut self) -> *mut SyncRegs {
793 unsafe {
794 let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
795 ::std::mem::transmute(raw.offset(0))
796 }
797 }
798}
799impl ::std::clone::Clone for Union_Unnamed26 {
800 fn clone(&self) -> Self {
801 *self
802 }
803}
804impl ::std::default::Default for Union_Unnamed26 {
805 fn default() -> Self {
806 unsafe { ::std::mem::zeroed() }
807 }
808}
809
810impl System {
811 pub fn initialize() -> Result<Self> {
813 let f = try!(OpenOptions::new()
814 .read(true)
815 .write(true)
816 .open("/dev/kvm"));
817 let vers = unsafe { kvm_get_api_version(f.as_raw_fd()) };
818 if vers == API_VERSION {
819 Ok(System { fd: f })
820 } else {
821 Err(Error::new(ErrorKind::NotFound, "Unexpected API Version"))
822 }
823 }
824
825 pub fn check_capability(&self, cap: Capability) -> i32 {
831 unsafe { kvm_check_extension(self.fd.as_raw_fd(), cap as c_int) }
832 }
833
834 pub fn recommended_vcpus(&self) -> u32 {
836 let r = self.check_capability(Capability::NrVcpus);
837 if r != 0 {
838 r as u32
839 } else {
840 4
843 }
844 }
845
846 pub fn max_vcpus(&self) -> u32 {
848 let r = self.check_capability(Capability::MaxVcpus);
849 if r != 0 {
850 r as u32
851 } else {
852 self.recommended_vcpus()
853 }
854 }
855
856 fn get_vcpu_mmap_size(&self) -> usize {
857 let ret = unsafe { kvm_get_vcpu_mmap_size(self.fd.as_raw_fd()) };
858 assert!(ret > 0 && ret as usize >= mem::size_of::<Run>());
859 ret as usize
860 }
861}
862
863#[cfg(target_arch = "x86_64")]
864const CPUID_ENTRIES: u32 = 64;
865
866#[cfg(target_arch = "x86_64")]
867impl System {
868 pub fn get_supported_cpuid(&self) -> Result<CpuidHandle> {
870 let mut nent = CPUID_ENTRIES;
871 loop {
872 let mut c = CpuidHandle::new(nent);
873 let err = unsafe {
874 kvm_get_supported_cpuid(self.fd.as_raw_fd(), c.deref_mut())
875 };
876 if err != 0 {
877 if errno() == Errno(E2BIG) {
878 nent *= 2;
879 continue;
880 } else if errno() == Errno(ENOMEM) {
881 nent = c.nent;
882 continue;
883 } else {
884 return Err(Error::last_os_error());
885 }
886 } else {
887 return Ok(c);
888 }
889 }
890 }
891}
892
893pub const MEM_LOG_DIRTY_PAGES: u32 = 1;
895pub const MEM_READONLY: u32 = 1 << 1;
897
898impl<'a> VirtualMachine<'a> {
899 pub fn create(s: &'a System) -> Result<Self> {
901 let f = unsafe { kvm_create_vm(s.fd.as_raw_fd(), 0) };
902 if f == -1 {
903 return Err(Error::last_os_error());
904 }
905
906 let check_extension =
907 s.check_capability(Capability::CheckExtensionVm) != 0;
908 Ok(VirtualMachine {
909 fd: unsafe { File::from_raw_fd(f) },
910 sys: s,
911 mem_slots: Vec::new(),
912 num_vcpus: 0,
913 check_extension: check_extension,
914 })
915 }
916
917 pub fn check_capability(&mut self, cap: Capability) -> i32 {
919 if self.check_extension {
920 unsafe { kvm_check_extension(self.fd.as_raw_fd(), cap as c_int) }
921 } else {
922 self.sys.check_capability(cap)
923 }
924 }
925
926 pub fn set_user_memory_region(&mut self,
931 phys_addr: u64,
932 user_addr: &'a mut [u8],
933 flags: u32)
934 -> Result<()> {
935 let slot = self.mem_slots.len();
936 let region = UserspaceMemoryRegion {
937 slot: slot as u32,
938 flags: flags,
939 guest_phys_addr: phys_addr,
940 memory_size: user_addr.len() as u64,
941 userspace_addr: user_addr.as_mut_ptr() as u64,
942 };
943 let ret = unsafe {
944 kvm_set_user_memory_region(self.fd.as_raw_fd(), ®ion)
945 };
946 if ret == 0 {
947 self.mem_slots.push(user_addr);
948 Ok(())
949 } else {
950 Err(Error::new(ErrorKind::Other, "Unknown Error"))
951 }
952 }
953}
954
955impl<'a> Vcpu<'a> {
956 pub fn create(vm: &'a mut VirtualMachine<'a>) -> Result<Self> {
958 if vm.num_vcpus >= vm.sys.max_vcpus() {
959 return Err(Error::new(ErrorKind::AlreadyExists,
960 "Would exceed max_vcpus"));
961 } else if vm.num_vcpus >= vm.sys.recommended_vcpus() {
962 warn!("Exceeding recommended_vcpus");
963 }
964 let fd = unsafe {
965 File::from_raw_fd(kvm_create_vcpu(vm.fd.as_raw_fd(),
966 vm.num_vcpus as c_int))
967 };
968 vm.num_vcpus += 1;
969 let mmap_size = vm.sys.get_vcpu_mmap_size();
970 let m = try!(Mmap::open_with_offset(&fd,
971 Protection::ReadWrite,
972 0,
973 mmap_size));
974 Ok(Vcpu {
975 fd: fd,
976 vm: vm,
977 mmap: m,
978 })
979 }
980
981 pub unsafe fn run(&mut self) -> Result<Run> {
983 let ret = kvm_run(self.fd.as_raw_fd());
984 if ret == 0 {
985 Ok(*(self.mmap.mut_ptr() as *mut Run))
986 } else {
987 Err(Error::last_os_error())
988 }
989 }
990
991 pub fn get_regs(&self) -> Result<Regs> {
993 let mut regs = Regs::default();
994 let ret = unsafe { kvm_get_regs(self.fd.as_raw_fd(), &mut regs) };
995 if ret == 0 {
996 Ok(regs)
997 } else {
998 Err(Error::last_os_error())
999 }
1000 }
1001
1002 pub fn set_regs(&mut self, regs: &Regs) -> Result<()> {
1004 let ret = unsafe { kvm_set_regs(self.fd.as_raw_fd(), regs) };
1005 if ret == 0 {
1006 Ok(())
1007 } else {
1008 Err(Error::last_os_error())
1009 }
1010 }
1011}
1012
1013#[cfg(target_arch = "x86_64")]
1014impl<'a> Vcpu<'a> {
1015 pub fn set_cpuid2(&mut self, cpuid: &mut Cpuid2) -> Result<()> {
1017 let ptr: *mut Cpuid2 = cpuid;
1018 let ret = unsafe { kvm_set_cpuid2(self.fd.as_raw_fd(), ptr) };
1019 if ret == 0 {
1020 Ok(())
1021 } else {
1022 Err(Error::last_os_error())
1023 }
1024 }
1025 pub fn get_sregs(&self) -> Result<Sregs> {
1027 let mut sregs = Sregs::default();
1028 let ret = unsafe { kvm_get_sregs(self.fd.as_raw_fd(), &mut sregs) };
1029 if ret == 0 {
1030 Ok(sregs)
1031 } else {
1032 Err(Error::last_os_error())
1033 }
1034 }
1035 pub fn set_sregs(&mut self, sregs: &Sregs) -> Result<()> {
1037 let ret = unsafe { kvm_set_sregs(self.fd.as_raw_fd(), sregs) };
1038 if ret == 0 {
1039 Ok(())
1040 } else {
1041 Err(Error::last_os_error())
1042 }
1043 }
1044}
1045
1046#[test]
1047fn init_test() {
1048 System::initialize().unwrap();
1049}
1050
1051#[test]
1052fn check_capability_test() {
1053 let h = System::initialize().unwrap();
1054 assert!(h.check_capability(Capability::UserMemory) != 0);
1055}
1056
1057#[test]
1058fn vcpus_test() {
1059 let h = System::initialize().unwrap();
1060 assert!(h.max_vcpus() >= h.recommended_vcpus());
1061}
1062
1063#[test]
1064fn create_vm_test() {
1065 let h = System::initialize().unwrap();
1066 VirtualMachine::create(&h).unwrap();
1067}
1068
1069#[test]
1070fn set_memory_test() {
1071 let mut anon_mmap = Mmap::anonymous(16 * (1 << 12), Protection::ReadWrite)
1072 .unwrap();
1073 let slice = unsafe { anon_mmap.as_mut_slice() };
1074 let h = System::initialize().unwrap();
1075 let mut vm = VirtualMachine::create(&h).unwrap();
1076 vm.set_user_memory_region(0, slice, 0).unwrap();
1077}
1078
1079#[test]
1080fn create_vcpu_test() {
1081 let h = System::initialize().unwrap();
1082 let mut vm = VirtualMachine::create(&h).unwrap();
1083 Vcpu::create(&mut vm).unwrap();
1084}
1085
1086#[cfg(target_arch = "x86_64")]
1087#[test]
1088fn cpuid_test() {
1089 let h = System::initialize().unwrap();
1090 if h.check_capability(Capability::ExtCpuid) == 1 {
1091 let mut cpuid = h.get_supported_cpuid().unwrap();
1092 let mut vm = VirtualMachine::create(&h).unwrap();
1093 let mut vcpu = Vcpu::create(&mut vm).unwrap();
1094 vcpu.set_cpuid2(&mut cpuid).unwrap();
1095 }
1096}
1097
1098#[cfg(target_arch = "x86_64")]
1099#[test]
1100fn sreg_test() {
1101 let h = System::initialize().unwrap();
1102 let mut vm = VirtualMachine::create(&h).unwrap();
1103 let mut vcpu = Vcpu::create(&mut vm).unwrap();
1104 let mut sregs = vcpu.get_sregs().unwrap();
1105 sregs.cr0 = 0x1;
1106 vcpu.set_sregs(&sregs).unwrap();
1107 assert!(vcpu.get_sregs().unwrap().cr0 == 0x1);
1108}
1109
1110#[cfg(target_arch = "x86_64")]
1111#[test]
1112fn reg_test() {
1113 let h = System::initialize().unwrap();
1114 let mut vm = VirtualMachine::create(&h).unwrap();
1115 let mut vcpu = Vcpu::create(&mut vm).unwrap();
1116 let mut regs = vcpu.get_regs().unwrap();
1117 regs.rax = 0x1;
1118 vcpu.set_regs(®s).unwrap();
1119 assert!(vcpu.get_regs().unwrap().rax == 0x1);
1120}