Skip to content

Commit dcd132f

Browse files
author
Serban Iorga
committed
[aarch64][snap] simplify construct_gicr_typer()
We only use construct_gicr_typer() for calling: - KVM_DEV_ARM_VGIC_GRP_REDIST_REGS - KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS But for this ioctls we don't need to construct the GICR_TYPER register. We only need a squashed MPIDR, as specified in the linux kernel documentation: Documentation/virt/kvm/devices/arm-vgic-v3.rst Signed-off-by: Serban Iorga <[email protected]>
1 parent 9a8f784 commit dcd132f

File tree

2 files changed

+25
-31
lines changed

2 files changed

+25
-31
lines changed

src/vmm/src/builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::os::unix::io::{AsRawFd, RawFd};
1010
use std::sync::{Arc, Mutex};
1111

1212
#[cfg(target_arch = "aarch64")]
13-
use crate::construct_gicr_typer;
13+
use crate::construct_kvm_mpidrs;
1414
#[cfg(target_arch = "x86_64")]
1515
use crate::device_manager::legacy::PortIODeviceManager;
1616
use crate::device_manager::mmio::MMIODeviceManager;
@@ -400,7 +400,7 @@ pub fn build_microvm_from_snapshot(
400400

401401
#[cfg(target_arch = "aarch64")]
402402
{
403-
let mpidrs = construct_gicr_typer(&microvm_state.vcpu_states);
403+
let mpidrs = construct_kvm_mpidrs(&microvm_state.vcpu_states);
404404
// Restore kvm vm state.
405405
vmm.vm
406406
.restore_state(&mpidrs, &microvm_state.vm_state)

src/vmm/src/lib.rs

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ impl Vmm {
372372
}
373373
#[cfg(target_arch = "aarch64")]
374374
{
375-
let mpidrs = construct_gicr_typer(&vcpu_states);
375+
let mpidrs = construct_kvm_mpidrs(&vcpu_states);
376376

377377
self.vm.save_state(&mpidrs).map_err(SaveVmState)?
378378
}
@@ -684,35 +684,29 @@ impl Vmm {
684684
}
685685
}
686686

687+
/// Process the content of the MPIDR_EL1 register in order to be able to pass it to KVM
688+
///
689+
/// The kernel expects to find the four affinity levels of the MPIDR in the first 32 bits of the
690+
/// VGIC register attribute:
691+
/// https://elixir.free-electrons.com/linux/v4.14.203/source/virt/kvm/arm/vgic/vgic-kvm-device.c#L445.
692+
///
693+
/// The format of the MPIDR_EL1 register is:
694+
/// | 39 .... 32 | 31 .... 24 | 23 .... 16 | 15 .... 8 | 7 .... 0 |
695+
/// | Aff3 | Other | Aff2 | Aff1 | Aff0 |
696+
///
697+
/// The KVM mpidr format is:
698+
/// | 63 .... 56 | 55 .... 48 | 47 .... 40 | 39 .... 32 |
699+
/// | Aff3 | Aff2 | Aff1 | Aff0 |
700+
/// As specified in the linux kernel: Documentation/virt/kvm/devices/arm-vgic-v3.rst
687701
#[cfg(target_arch = "aarch64")]
688-
fn construct_gicr_typer(vcpu_states: &[VcpuState]) -> Vec<u64> {
689-
/* Pre-construct the GICR_TYPER:
690-
* For our implementation:
691-
* Top 32 bits are the affinity value of the associated CPU
692-
* CommonLPIAff == 01 (redistributors with same Aff3 share LPI table)
693-
* Processor_Number == CPU index starting from 0
694-
* DPGS == 0 (GICR_CTLR.DPG* not supported)
695-
* Last == 1 if this is the last redistributor in a series of
696-
* contiguous redistributor pages
697-
* DirectLPI == 0 (direct injection of LPIs not supported)
698-
* VLPIS == 0 (virtual LPIs not supported)
699-
* PLPIS == 0 (physical LPIs not supported)
700-
*/
701-
let mut mpidrs: Vec<u64> = Vec::new();
702-
for (index, state) in vcpu_states.iter().enumerate() {
703-
let last = {
704-
if index == vcpu_states.len() - 1 {
705-
1
706-
} else {
707-
0
708-
}
709-
};
710-
//calculate affinity
711-
let mut cpu_affid = state.mpidr & 0xFF_00FF_FFFF;
712-
cpu_affid = ((cpu_affid & 0xFF_0000_0000) >> 8) | (cpu_affid & 0xFF_FFFF);
713-
mpidrs.push((cpu_affid << 32) | (1 << 24) | (index as u64) << 8 | (last << 4));
714-
}
715-
mpidrs
702+
fn construct_kvm_mpidrs(vcpu_states: &[VcpuState]) -> Vec<u64> {
703+
vcpu_states
704+
.iter()
705+
.map(|state| {
706+
let cpu_affid = ((state.mpidr & 0xFF_0000_0000) >> 8) | (state.mpidr & 0xFF_FFFF);
707+
cpu_affid << 32
708+
})
709+
.collect()
716710
}
717711

718712
impl Drop for Vmm {

0 commit comments

Comments
 (0)