Skip to content

Commit

Permalink
fix: Use offset_of macro
Browse files Browse the repository at this point in the history
The `offset_of` macro is stable since Rust 1.77.0, meaning we can use it
to replace various home-grown alternatives.

Fixes #4504

Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
  • Loading branch information
roypat authored and zulinx86 committed Jul 22, 2024
1 parent 0c2d2af commit 6abc075
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 33 deletions.
37 changes: 8 additions & 29 deletions src/vmm/src/arch/aarch64/regs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.

use std::mem::offset_of;

use kvm_bindings::*;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

Expand All @@ -19,28 +21,9 @@ const PSR_D_BIT: u64 = 0x0000_0200;
/// Taken from arch/arm64/kvm/inject_fault.c.
pub const PSTATE_FAULT_BITS_64: u64 = PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT;

// Following are macros that help with getting the ID of a aarch64 core register.
// The core register are represented by the user_pt_regs structure. Look for it in
// arch/arm64/include/uapi/asm/ptrace.h.

/// Gets offset of a member (`field`) within a struct (`container`).
/// Same as bindgen offset tests.
macro_rules! offset__of {
($container:ty, $field:ident) => {
// SAFETY: The implementation closely matches that of the memoffset crate,
// which have been under extensive review.
unsafe {
let uninit = std::mem::MaybeUninit::<$container>::uninit();
let ptr = uninit.as_ptr();
std::ptr::addr_of!((*ptr).$field) as usize - ptr as usize
}
};
}
pub(crate) use offset__of;

/// Gets a core id.
macro_rules! arm64_core_reg_id {
($size: tt, $offset: tt) => {
($size: ident, $offset: expr) => {
// The core registers of an arm64 machine are represented
// in kernel by the `kvm_regs` structure. This structure is a
// mix of 32, 64 and 128 bit fields:
Expand Down Expand Up @@ -130,15 +113,11 @@ pub const KVM_REG_ARM64_SVE_VLS: u64 =
///
/// https://github.com/torvalds/linux/blob/master/Documentation/virt/kvm/api.rst#L2578
/// > 0x6030 0000 0010 0040 PC 64 regs.pc
pub const PC: u64 = arm64_core_reg_id!(KVM_REG_SIZE_U64, 0x100);

// TODO: Once `core::mem::offset_of!()` macro becomes stable (maybe since 1.77.0?), use the
// following instead: https://github.com/firecracker-microvm/firecracker/issues/4504
// pub const PC: u64 = {
// let kreg_off = offset_of!(kvm_regs, regs);
// let pc_off = offset_of!(user_pt_regs, pc);
// arm64_core_reg_id!(KVM_REG_SIZE_U64, kreg_off + pc_off)
// };
pub const PC: u64 = {
let kreg_off = offset_of!(kvm_regs, regs);
let pc_off = offset_of!(user_pt_regs, pc);
arm64_core_reg_id!(KVM_REG_SIZE_U64, kreg_off + pc_off)
};

/// Different aarch64 registers sizes
#[derive(Debug)]
Expand Down
9 changes: 5 additions & 4 deletions src/vmm/src/arch/aarch64/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.

use std::mem::offset_of;
use std::path::PathBuf;

use kvm_bindings::*;
Expand Down Expand Up @@ -78,10 +79,10 @@ pub fn setup_boot_regs(
boot_ip: u64,
mem: &GuestMemoryMmap,
) -> Result<(), VcpuError> {
let kreg_off = offset__of!(kvm_regs, regs);
let kreg_off = offset_of!(kvm_regs, regs);

// Get the register index of the PSTATE (Processor State) register.
let pstate = offset__of!(user_pt_regs, pstate) + kreg_off;
let pstate = offset_of!(user_pt_regs, pstate) + kreg_off;
let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, pstate);
vcpufd
.set_one_reg(id, &PSTATE_FAULT_BITS_64.to_le_bytes())
Expand All @@ -90,7 +91,7 @@ pub fn setup_boot_regs(
// Other vCPUs are powered off initially awaiting PSCI wakeup.
if cpu_id == 0 {
// Setting the PC (Processor Counter) to the current program address (kernel address).
let pc = offset__of!(user_pt_regs, pc) + kreg_off;
let pc = offset_of!(user_pt_regs, pc) + kreg_off;
let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, pc);
vcpufd
.set_one_reg(id, &boot_ip.to_le_bytes())
Expand All @@ -100,7 +101,7 @@ pub fn setup_boot_regs(
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
let regs0 = offset__of!(user_pt_regs, regs) + kreg_off;
let regs0 = offset_of!(user_pt_regs, regs) + kreg_off;
let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0);
vcpufd
.set_one_reg(id, &get_fdt_addr(mem).to_le_bytes())
Expand Down

0 comments on commit 6abc075

Please sign in to comment.