vmm: Change booting process to cover AArch64 requirements

Between X86 and AArch64, there is some difference in booting a VM:
- X86_64 can setup IOAPIC before creating any VCPU.
- AArch64 have to create VCPU's before creating GIC.

The old process is:
1. load_kernel()
    load kernel binary
    configure system
2. activate_vcpus()
    create & start VCPU's

So we need to separate "activate_vcpus" into "create_vcpus" and
"activate_vcpus" (to start vcpus only). Setup GIC and create FDT
between the 2 steps.

The new procedure is:
1. load_kernel()
    load kernel binary
    (X86_64) configure system
2. create VCPU's
3. (AArch64) setup GIC
4. (AArch64) configure system
5. start VCPU's

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
Michael Zhao
2020-05-26 15:20:22 +08:00
committed by Sebastien Boeuf
parent 61aa4615e2
commit 20cf21cd9d
2 changed files with 120 additions and 77 deletions
+19 -2
View File
@@ -527,7 +527,6 @@ impl Vm {
};
let boot_vcpus = self.cpu_manager.lock().unwrap().boot_vcpus();
let _max_vcpus = self.cpu_manager.lock().unwrap().max_vcpus();
#[allow(unused_mut, unused_assignments)]
let mut rsdp_addr: Option<GuestAddress> = None;
@@ -601,6 +600,11 @@ impl Vm {
}
}
#[cfg(target_arch = "aarch64")]
fn configure_system(&mut self) -> Result<()> {
unimplemented!();
}
pub fn shutdown(&mut self) -> Result<()> {
let mut state = self.state.try_write().map_err(|_| Error::PoisonedState)?;
let new_state = VmState::Shutdown;
@@ -980,12 +984,25 @@ impl Vm {
let new_state = VmState::Running;
current_state.valid_transition(new_state)?;
// On x86_64, load_kernel() invokes configure_system().
// But on aarch64, it only loads kernel, configure_system()
// need to be postponed after VCPU's are created.
let entry_addr = self.load_kernel()?;
// create and configure vcpus
self.cpu_manager
.lock()
.unwrap()
.create_boot_vcpus(entry_addr)
.map_err(Error::CpuManager)?;
#[cfg(target_arch = "aarch64")]
self.configure_system()?;
self.cpu_manager
.lock()
.unwrap()
.start_boot_vcpus(entry_addr)
.start_boot_vcpus()
.map_err(Error::CpuManager)?;
if self