Skip to content

Commit 98520ef

Browse files
committed
macos/vstate: unify MPIDR generation
With HVF, we generate MPIDR by taking Vcpu.id and setting Aff1 to that value by doing a left-shift, as this is what the GIC expects to be found in the distributor. But, in vstate::Vcpu::configure_aarch64, we were using the Vcpu.id without left-shifting it. For consistency, let's generate MPIDR for the Vcpu once and use it everywhere. Signed-off-by: Sergio Lopez <[email protected]>
1 parent 42612d0 commit 98520ef

File tree

3 files changed

+19
-19
lines changed

3 files changed

+19
-19
lines changed

src/hvf/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ pub struct HvfVcpu<'a> {
231231
}
232232

233233
impl HvfVcpu<'_> {
234-
pub fn new() -> Result<Self, Error> {
234+
pub fn new(mpidr: u64) -> Result<Self, Error> {
235235
let mut vcpuid: hv_vcpu_t = 0;
236236
let vcpu_exit_ptr: *mut hv_vcpu_exit_t = std::ptr::null_mut();
237237

@@ -257,8 +257,7 @@ impl HvfVcpu<'_> {
257257

258258
// We write vcpuid to Aff1 as otherwise it won't match the redistributor ID
259259
// when using HVF in-kernel GICv3.
260-
let ret =
261-
unsafe { hv_vcpu_set_sys_reg(vcpuid, hv_sys_reg_t_HV_SYS_REG_MPIDR_EL1, vcpuid << 8) };
260+
let ret = unsafe { hv_vcpu_set_sys_reg(vcpuid, hv_sys_reg_t_HV_SYS_REG_MPIDR_EL1, mpidr) };
262261
if ret != HV_SUCCESS {
263262
return Err(Error::VcpuCreate);
264263
}

src/vmm/src/builder.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#[cfg(target_os = "macos")]
77
use crossbeam_channel::{unbounded, Sender};
88
use kernel::cmdline::Cmdline;
9+
use std::collections::HashMap;
910
use std::fmt::{Display, Formatter};
1011
use std::fs::File;
1112
use std::io::{self, Read};
@@ -1460,15 +1461,14 @@ fn create_vcpus_aarch64(
14601461
vcpu_list: Arc<VcpuList>,
14611462
) -> super::Result<Vec<Vcpu>> {
14621463
let mut vcpus = Vec::with_capacity(vcpu_config.vcpu_count as usize);
1463-
let mut boot_senders = Vec::with_capacity(vcpu_config.vcpu_count as usize - 1);
1464+
let mut boot_senders: HashMap<u64, Sender<u64>> = HashMap::new();
14641465

14651466
for cpu_index in 0..vcpu_config.vcpu_count {
1466-
let boot_receiver = if cpu_index != 0 {
1467+
let (boot_sender, boot_receiver) = if cpu_index != 0 {
14671468
let (boot_sender, boot_receiver) = unbounded();
1468-
boot_senders.push(boot_sender);
1469-
Some(boot_receiver)
1469+
(Some(boot_sender), Some(boot_receiver))
14701470
} else {
1471-
None
1471+
(None, None)
14721472
};
14731473

14741474
let mut vcpu = Vcpu::new_aarch64(
@@ -1482,6 +1482,10 @@ fn create_vcpus_aarch64(
14821482

14831483
vcpu.configure_aarch64(guest_mem).map_err(Error::Vcpu)?;
14841484

1485+
if let Some(boot_sender) = boot_sender {
1486+
boot_senders.insert(vcpu.get_mpidr(), boot_sender);
1487+
}
1488+
14851489
vcpus.push(vcpu);
14861490
}
14871491

src/vmm/src/macos/vstate.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// found in the THIRD-PARTY file.
77

88
use std::cell::Cell;
9+
use std::collections::HashMap;
910
use std::fmt::{Display, Formatter};
1011
use std::io;
1112
use std::result;
@@ -176,7 +177,7 @@ pub struct Vcpu {
176177
id: u8,
177178
boot_entry_addr: u64,
178179
boot_receiver: Option<Receiver<u64>>,
179-
boot_senders: Option<Vec<Sender<u64>>>,
180+
boot_senders: Option<HashMap<u64, Sender<u64>>>,
180181
fdt_addr: u64,
181182
mmio_bus: Option<devices::Bus>,
182183
#[cfg_attr(all(test, target_arch = "aarch64"), allow(unused))]
@@ -280,7 +281,7 @@ impl Vcpu {
280281
fdt_addr: 0,
281282
mmio_bus: None,
282283
exit_evt,
283-
mpidr: 0,
284+
mpidr: id as u64,
284285
event_receiver,
285286
event_sender: Some(event_sender),
286287
response_receiver: Some(response_receiver),
@@ -304,19 +305,16 @@ impl Vcpu {
304305
self.mmio_bus = Some(mmio_bus);
305306
}
306307

307-
pub fn set_boot_senders(&mut self, boot_senders: Vec<Sender<u64>>) {
308+
pub fn set_boot_senders(&mut self, boot_senders: HashMap<u64, Sender<u64>>) {
308309
self.boot_senders = Some(boot_senders);
309310
}
310311

311312
/// Configures an aarch64 specific vcpu.
312313
///
313314
/// # Arguments
314315
///
315-
/// * `vm_fd` - The kvm `VmFd` for this microvm.
316316
/// * `guest_mem` - The guest memory used by this microvm.
317-
/// * `kernel_load_addr` - Offset from `guest_mem` at which the kernel is loaded.
318317
pub fn configure_aarch64(&mut self, guest_mem: &GuestMemoryMmap) -> Result<()> {
319-
self.mpidr = self.id as u64;
320318
self.fdt_addr = arch::aarch64::get_fdt_addr(guest_mem);
321319

322320
Ok(())
@@ -369,13 +367,12 @@ impl Vcpu {
369367
"CpuOn: mpidr=0x{:x} entry=0x{:x} context_id={}",
370368
mpidr, entry, context_id
371369
);
372-
// assuming a flat CPU hierarchy, only the bottom bits of mpidr should be used,
373-
// and cpuid == mpidr
374-
let cpuid: usize = mpidr as usize;
375370
if let Some(boot_senders) = &self.boot_senders {
376-
if let Some(sender) = boot_senders.get(cpuid - 1) {
371+
if let Some(sender) = boot_senders.get(&mpidr) {
377372
sender.send(entry).unwrap()
378373
}
374+
} else {
375+
error!("CpuOn request coming from an unexpected vCPU={}", self.id);
379376
}
380377
Ok(VcpuEmulation::Handled)
381378
}
@@ -432,7 +429,7 @@ impl Vcpu {
432429

433430
/// Main loop of the vCPU thread.
434431
pub fn run(&mut self, init_tls_sender: Sender<bool>) {
435-
let mut hvf_vcpu = HvfVcpu::new().expect("Can't create HVF vCPU");
432+
let mut hvf_vcpu = HvfVcpu::new(self.mpidr).expect("Can't create HVF vCPU");
436433
let hvf_vcpuid = hvf_vcpu.id();
437434

438435
init_tls_sender

0 commit comments

Comments
 (0)