From 16f2bedbb7f8f2d394db60e04312b6608c33170b Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 22 Feb 2019 17:04:35 +0100 Subject: [PATCH] cloud-hypervisor: Add a vmm crate Signed-off-by: Samuel Ortiz --- vmm/Cargo.toml | 13 ++++++ vmm/src/lib.rs | 113 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 vmm/Cargo.toml create mode 100644 vmm/src/lib.rs diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml new file mode 100644 index 000000000..d501b8964 --- /dev/null +++ b/vmm/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "vmm" +version = "0.1.0" +authors = ["The Cloud Hypervisor Authors"] +edition = "2018" + +[dependencies] +kvm-bindings = "0.1" +kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls" } + +[dependencies.vm-memory] +git = "https://github.com/rust-vmm/vm-memory" +features = ["backend-mmap"] diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs new file mode 100644 index 000000000..76aa532fd --- /dev/null +++ b/vmm/src/lib.rs @@ -0,0 +1,113 @@ +// Copyright © 2019 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +extern crate kvm_ioctls; +extern crate vm_memory; + +use kvm_bindings::kvm_userspace_memory_region; +use kvm_ioctls::*; +use std::str; +use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion}; + +pub fn test_vm() { + // This example based on https://lwn.net/Articles/658511/ + let code = [ + 0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */ + 0x00, 0xd8, /* add %bl, %al */ + 0x04, '0' as u8, /* add $'0', %al */ + 0xee, /* out %al, (%dx) */ + 0xb0, '\n' as u8, /* mov $'\n', %al */ + 0xee, /* out %al, (%dx) */ + 0xf4, /* hlt */ + ]; + + let mem_size = 0x1000; + let load_addr = GuestAddress(0x1000); + let mem = GuestMemoryMmap::new(&vec![(load_addr, mem_size)]).unwrap(); + + let kvm = Kvm::new().expect("new KVM instance creation failed"); + let vm_fd = kvm.create_vm().expect("new VM fd creation failed"); + + mem.with_regions(|index, region| { + let mem_region = kvm_userspace_memory_region { + slot: index as u32, + guest_phys_addr: region.start_addr().raw_value(), + memory_size: region.len() as u64, + userspace_addr: region.as_ptr() as u64, + flags: 0, + }; + + // Safe because the guest regions are guaranteed not to overlap. + vm_fd.set_user_memory_region(mem_region) + }) + .expect("Cannot configure guest memory"); + + mem.write_slice(&code, load_addr) + .expect("Writing code to memory failed"); + + let vcpu_fd = vm_fd.create_vcpu(0).expect("new VcpuFd failed"); + + let mut vcpu_sregs = vcpu_fd.get_sregs().expect("get sregs failed"); + vcpu_sregs.cs.base = 0; + vcpu_sregs.cs.selector = 0; + vcpu_fd.set_sregs(&vcpu_sregs).expect("set sregs failed"); + + let mut vcpu_regs = vcpu_fd.get_regs().expect("get regs failed"); + vcpu_regs.rip = 0x1000; + vcpu_regs.rax = 2; + vcpu_regs.rbx = 3; + vcpu_regs.rflags = 2; + vcpu_fd.set_regs(&vcpu_regs).expect("set regs failed"); + + loop { + match vcpu_fd.run().expect("run failed") { + VcpuExit::IoIn(addr, data) => { + println!( + "IO in -- addr: {:#x} data [{:?}]", + addr, + str::from_utf8(&data).unwrap() + ); + } + VcpuExit::IoOut(addr, data) => { + println!( + "IO out -- addr: {:#x} data [{:?}]", + addr, + str::from_utf8(&data).unwrap() + ); + } + VcpuExit::MmioRead(_addr, _data) => {} + VcpuExit::MmioWrite(_addr, _data) => {} + VcpuExit::Unknown => {} + VcpuExit::Exception => {} + VcpuExit::Hypercall => {} + VcpuExit::Debug => {} + VcpuExit::Hlt => { + println!("HLT"); + } + VcpuExit::IrqWindowOpen => {} + VcpuExit::Shutdown => {} + VcpuExit::FailEntry => {} + VcpuExit::Intr => {} + VcpuExit::SetTpr => {} + VcpuExit::TprAccess => {} + VcpuExit::S390Sieic => {} + VcpuExit::S390Reset => {} + VcpuExit::Dcr => {} + VcpuExit::Nmi => {} + VcpuExit::InternalError => {} + VcpuExit::Osi => {} + VcpuExit::PaprHcall => {} + VcpuExit::S390Ucontrol => {} + VcpuExit::Watchdog => {} + VcpuExit::S390Tsch => {} + VcpuExit::Epr => {} + VcpuExit::SystemEvent => {} + VcpuExit::S390Stsi => {} + VcpuExit::IoapicEoi => {} + VcpuExit::Hyperv => {} + } + // r => panic!("unexpected exit reason: {:?}", r), + } +}