mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-28 17:44:10 +00:00
arch: provide one vcpu_init per vcpu
Rather than having a single vcpu_init instance that is used for all VCPUs, make vcpu_init into a Vec so it can store different initial state for each VCPU. This allows us to set up e.g. bootstrap processor state differently than other processors, and it also means that the VcpuInit struct doesn't need to be Copy. BUG=b:237095693 TEST=Boot Linux with >1 CPU Change-Id: I0ebfdc2dbd84d0817e3f75c2c852e4320b9e77c5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3723798 Reviewed-by: Alexandre Courbot <acourbot@chromium.org> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
20085de68b
commit
1b7d5b8fba
7 changed files with 23 additions and 16 deletions
|
@ -525,11 +525,13 @@ impl arch::LinuxArch for AArch64 {
|
|||
)
|
||||
.map_err(Error::CreateFdt)?;
|
||||
|
||||
let vcpu_init = vec![VcpuInitAArch64::default(); vcpu_count];
|
||||
|
||||
Ok(RunnableLinuxVm {
|
||||
vm,
|
||||
vcpu_count,
|
||||
vcpus: Some(vcpus),
|
||||
vcpu_init: VcpuInitAArch64 {},
|
||||
vcpu_init,
|
||||
vcpu_affinity: components.vcpu_affinity,
|
||||
no_smt: components.no_smt,
|
||||
irq_chip: irq_chip.try_box_clone().map_err(Error::CloneIrqChip)?,
|
||||
|
@ -553,7 +555,7 @@ impl arch::LinuxArch for AArch64 {
|
|||
_hypervisor: &dyn Hypervisor,
|
||||
_irq_chip: &mut dyn IrqChipAArch64,
|
||||
_vcpu: &mut dyn VcpuAArch64,
|
||||
_vcpu_init: &VcpuInitAArch64,
|
||||
_vcpu_init: VcpuInitAArch64,
|
||||
_vcpu_id: usize,
|
||||
_num_cpus: usize,
|
||||
_has_bios: bool,
|
||||
|
|
|
@ -148,7 +148,8 @@ pub struct RunnableLinuxVm<V: VmArch, Vcpu: VcpuArch> {
|
|||
pub suspend_evt: Event,
|
||||
pub vcpu_affinity: Option<VcpuAffinity>,
|
||||
pub vcpu_count: usize,
|
||||
pub vcpu_init: VcpuInitArch,
|
||||
/// Per-VCPU initialization data, indexed by vcpu_id.
|
||||
pub vcpu_init: Vec<VcpuInitArch>,
|
||||
/// If vcpus is None, then it's the responsibility of the vcpu thread to create vcpus.
|
||||
/// If it's Some, then `build_vm` already created the vcpus.
|
||||
pub vcpus: Option<Vec<Vcpu>>,
|
||||
|
@ -244,7 +245,7 @@ pub trait LinuxArch {
|
|||
hypervisor: &dyn HypervisorArch,
|
||||
irq_chip: &mut dyn IrqChipArch,
|
||||
vcpu: &mut dyn VcpuArch,
|
||||
vcpu_init: &VcpuInitArch,
|
||||
vcpu_init: VcpuInitArch,
|
||||
vcpu_id: usize,
|
||||
num_cpus: usize,
|
||||
has_bios: bool,
|
||||
|
|
|
@ -122,7 +122,7 @@ pub trait VcpuAArch64: Vcpu {
|
|||
impl_downcast!(VcpuAArch64);
|
||||
|
||||
/// Initial state for AArch64 VCPUs.
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct VcpuInitAArch64 {}
|
||||
|
||||
// Convenience constructors for IrqRoutes
|
||||
|
|
|
@ -172,7 +172,7 @@ pub(crate) fn host_phys_addr_bits() -> u8 {
|
|||
}
|
||||
|
||||
/// Initial state for x86_64 VCPUs.
|
||||
#[derive(Copy, Clone, Default)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct VcpuInitX86_64 {
|
||||
/// General-purpose registers.
|
||||
pub regs: Regs,
|
||||
|
|
|
@ -1952,7 +1952,11 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
|
||||
let guest_suspended_cvar = Arc::new((Mutex::new(false), Condvar::new()));
|
||||
|
||||
for (cpu_id, vcpu) in vcpus.into_iter().enumerate() {
|
||||
// Architecture-specific code must supply a vcpu_init element for each VCPU.
|
||||
assert_eq!(vcpus.len(), linux.vcpu_init.len());
|
||||
|
||||
for ((cpu_id, vcpu), vcpu_init) in vcpus.into_iter().enumerate().zip(linux.vcpu_init.drain(..))
|
||||
{
|
||||
let (to_vcpu_channel, from_main_channel) = mpsc::channel();
|
||||
let vcpu_affinity = match linux.vcpu_affinity.clone() {
|
||||
Some(VcpuAffinity::Global(v)) => v,
|
||||
|
@ -1963,7 +1967,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
cpu_id,
|
||||
vcpu_ids[cpu_id],
|
||||
vcpu,
|
||||
linux.vcpu_init,
|
||||
vcpu_init,
|
||||
linux.vm.try_clone().context("failed to clone vm")?,
|
||||
linux
|
||||
.irq_chip
|
||||
|
|
|
@ -133,7 +133,7 @@ pub fn runnable_vcpu<V>(
|
|||
cpu_id: usize,
|
||||
vcpu_id: usize,
|
||||
vcpu: Option<V>,
|
||||
vcpu_init: &VcpuInitArch,
|
||||
vcpu_init: VcpuInitArch,
|
||||
vm: impl VmArch,
|
||||
irq_chip: &mut dyn IrqChipArch,
|
||||
vcpu_count: usize,
|
||||
|
@ -609,7 +609,7 @@ where
|
|||
cpu_id,
|
||||
vcpu_id,
|
||||
vcpu,
|
||||
&vcpu_init,
|
||||
vcpu_init,
|
||||
vm,
|
||||
irq_chip.as_mut(),
|
||||
vcpu_count,
|
||||
|
|
|
@ -698,7 +698,7 @@ impl arch::LinuxArch for X8664arch {
|
|||
.map_err(Error::Cmdline)?;
|
||||
}
|
||||
|
||||
let mut vcpu_init = VcpuInitX86_64::default();
|
||||
let mut vcpu_init = vec![VcpuInitX86_64::default(); vcpu_count];
|
||||
|
||||
match components.vm_image {
|
||||
VmImage::Bios(ref mut bios) => {
|
||||
|
@ -724,11 +724,11 @@ impl arch::LinuxArch for X8664arch {
|
|||
params,
|
||||
)?;
|
||||
|
||||
// Configure the VCPU for the Linux/x86 64-bit boot protocol.
|
||||
// Configure the bootstrap VCPU for the Linux/x86 64-bit boot protocol.
|
||||
// <https://www.kernel.org/doc/html/latest/x86/boot.html>
|
||||
vcpu_init.regs.rip = kernel_entry.offset();
|
||||
vcpu_init.regs.rsp = BOOT_STACK_POINTER;
|
||||
vcpu_init.regs.rsi = ZERO_PAGE_OFFSET;
|
||||
vcpu_init[0].regs.rip = kernel_entry.offset();
|
||||
vcpu_init[0].regs.rsp = BOOT_STACK_POINTER;
|
||||
vcpu_init[0].regs.rsi = ZERO_PAGE_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -762,7 +762,7 @@ impl arch::LinuxArch for X8664arch {
|
|||
hypervisor: &dyn HypervisorX86_64,
|
||||
irq_chip: &mut dyn IrqChipX86_64,
|
||||
vcpu: &mut dyn VcpuX86_64,
|
||||
vcpu_init: &VcpuInitX86_64,
|
||||
vcpu_init: VcpuInitX86_64,
|
||||
vcpu_id: usize,
|
||||
num_cpus: usize,
|
||||
has_bios: bool,
|
||||
|
|
Loading…
Reference in a new issue