vmm: Boot kernel

Our command line was not copied properly since we were not allocating
enough space for it.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2019-03-06 12:04:14 +01:00
parent 044f664135
commit 7e2d1aca2d

View File

@ -10,7 +10,7 @@ extern crate linux_loader;
extern crate vm_memory; extern crate vm_memory;
extern crate vmm_sys_util; extern crate vmm_sys_util;
use kvm_bindings::kvm_userspace_memory_region; use kvm_bindings::{kvm_pit_config, kvm_userspace_memory_region, KVM_PIT_SPEAKER_DUMMY};
use kvm_ioctls::*; use kvm_ioctls::*;
use libc::{c_void, siginfo_t}; use libc::{c_void, siginfo_t};
use linux_loader::cmdline; use linux_loader::cmdline;
@ -27,8 +27,8 @@ use vm_memory::{
use vmm_sys_util::signal::register_signal_handler; use vmm_sys_util::signal::register_signal_handler;
const VCPU_RTSIG_OFFSET: i32 = 0; const VCPU_RTSIG_OFFSET: i32 = 0;
const DEFAULT_CMDLINE: &str = const DEFAULT_CMDLINE: &str = "console=ttyS0 reboot=k panic=1 pci=off nomodules \
"console=ttyS0,115200n8 init=/init tsc=reliable no_timer_check cryptomgr.notests"; i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd";
const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000); const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000);
/// Errors associated with the wrappers over KVM ioctls. /// Errors associated with the wrappers over KVM ioctls.
@ -157,8 +157,8 @@ struct VmConfig<'a> {
impl<'a> Default for VmConfig<'a> { impl<'a> Default for VmConfig<'a> {
fn default() -> Self { fn default() -> Self {
let line = String::from(DEFAULT_CMDLINE); let line = String::from(DEFAULT_CMDLINE);
let mut cmdline = cmdline::Cmdline::new(line.capacity()); let mut cmdline = cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE);
cmdline.insert_str(line); cmdline.insert_str(line).unwrap();
VmConfig { VmConfig {
kernel_path: Path::new(""), kernel_path: Path::new(""),
@ -220,6 +220,13 @@ impl<'a> Vm<'a> {
// Create IRQ chip // Create IRQ chip
fd.create_irq_chip().map_err(Error::VmSetup)?; fd.create_irq_chip().map_err(Error::VmSetup)?;
// Creates an in-kernel device model for the PIT.
let mut pit_config = kvm_pit_config::default();
// We need to enable the emulation of a dummy speaker port stub so that writing to port 0x61
// (i.e. KVM_SPEAKER_BASE_ADDRESS) does not trigger an exit to user space.
pit_config.flags = KVM_PIT_SPEAKER_DUMMY;
fd.create_pit2(pit_config).map_err(Error::VmSetup)?;
// Supported CPUID // Supported CPUID
let cpuid = kvm let cpuid = kvm
.get_supported_cpuid(MAX_KVM_CPUID_ENTRIES) .get_supported_cpuid(MAX_KVM_CPUID_ENTRIES)
@ -269,16 +276,16 @@ impl<'a> Vm<'a> {
pub fn start(&mut self, entry_addr: GuestAddress) -> Result<()> { pub fn start(&mut self, entry_addr: GuestAddress) -> Result<()> {
let vcpu_count = self.config.vcpu_count; let vcpu_count = self.config.vcpu_count;
let mut vcpus = Vec::with_capacity(vcpu_count as usize); let mut vcpus: Vec<thread::JoinHandle<()>> = Vec::with_capacity(vcpu_count as usize);
let vcpu_thread_barrier = Arc::new(Barrier::new((vcpu_count + 1) as usize)); let vcpu_thread_barrier = Arc::new(Barrier::new((vcpu_count + 1) as usize));
for cpu_id in 0..vcpu_count { for cpu_id in 0..vcpu_count {
println!("Starting VCPU {:?}", cpu_id); println!("Starting VCPU {:?}", cpu_id);
let mut vcpu = Vcpu::new(cpu_id, &self)?; let mut vcpu = Vcpu::new(cpu_id, &self)?;
let vcpu_thread_barrier = vcpu_thread_barrier.clone();
vcpu.configure(entry_addr, &self)?; vcpu.configure(entry_addr, &self)?;
let vcpu_thread_barrier = vcpu_thread_barrier.clone();
vcpus.push( vcpus.push(
thread::Builder::new() thread::Builder::new()
.name(format!("cloud-hypervisor_vcpu{}", vcpu.id)) .name(format!("cloud-hypervisor_vcpu{}", vcpu.id))
@ -296,29 +303,30 @@ impl<'a> Vm<'a> {
.expect("Failed to register vcpu signal handler"); .expect("Failed to register vcpu signal handler");
} }
// Block until all CPUs are ready.
vcpu_thread_barrier.wait(); vcpu_thread_barrier.wait();
loop { loop {
match vcpu.run() { match vcpu.run() {
Ok(run) => match run { Ok(run) => match run {
VcpuExit::IoIn(addr, data) => { VcpuExit::IoIn(_addr, _data) => {}
println!(
"IO in -- addr: {:#x} data [{:?}]",
addr,
str::from_utf8(&data).unwrap()
);
}
VcpuExit::IoOut(addr, data) => { VcpuExit::IoOut(addr, data) => {
println!( if addr == 0x3f8 {
"IO out -- addr: {:#x} data [{:?}]", print!("{}", str::from_utf8(&data).unwrap());
addr, }
str::from_utf8(&data).unwrap() }
); VcpuExit::MmioRead(addr, _data) => {
println!("MMIO R -- addr: {:#x}", addr);
}
VcpuExit::MmioWrite(addr, _data) => {
println!("MMIO W -- addr: {:#x}", addr);
}
VcpuExit::Unknown => {
println!("Unknown");
}
VcpuExit::Exception => {
println!("Exception");
} }
VcpuExit::MmioRead(_addr, _data) => {}
VcpuExit::MmioWrite(_addr, _data) => {}
VcpuExit::Unknown => {}
VcpuExit::Exception => {}
VcpuExit::Hypercall => {} VcpuExit::Hypercall => {}
VcpuExit::Debug => {} VcpuExit::Debug => {}
VcpuExit::Hlt => { VcpuExit::Hlt => {
@ -347,7 +355,7 @@ impl<'a> Vm<'a> {
VcpuExit::Hyperv => {} VcpuExit::Hyperv => {}
}, },
Err(e) => { Err(e) => {
println! {"VCPU {:?} error {:?}", cpu_id, e} println! {"VCPU {:?} error {:?}", cpu_id, e};
break; break;
} }
} }
@ -357,7 +365,13 @@ impl<'a> Vm<'a> {
); );
} }
// Unblock all CPU threads.
vcpu_thread_barrier.wait(); vcpu_thread_barrier.wait();
for vcpu_barrier in vcpus {
vcpu_barrier.join().unwrap();
}
Ok(()) Ok(())
} }