pub fn save_core_registers(vcpu: &VcpuFd, state: &mut Vec<kvm_one_reg>) -> Result<()> {
    let mut off = offset__of!(user_pt_regs, regs);
    // There are 31 user_pt_regs:
    // https://elixir.free-electrons.com/linux/v4.14.174/source/arch/arm64/include/uapi/asm/ptrace.h#L72
    // These actually are the general-purpose registers of the Armv8-a
    // architecture (i.e x0-x30 if used as a 64bit register or w0-w30 when used as a 32bit register).
    for i in 0..NR_GP_REGS {
        let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
        state.push(kvm_one_reg {
            id,
            addr: vcpu
                .get_one_reg(id)
                .map_err(|e| Error::GetCoreRegister(e, format!("X{}", i)))?,
        });
        off += std::mem::size_of::<u64>();
    }

    // We are now entering the "Other register" section of the ARMv8-a architecture.
    // First one, stack pointer.
    let off = offset__of!(user_pt_regs, sp);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "stack pointer".to_string()))?,
    });

    // Second one, the program counter.
    let off = offset__of!(user_pt_regs, pc);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "program counter".to_string()))?,
    });

    // Next is the processor state.
    let off = offset__of!(user_pt_regs, pstate);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "processor state".to_string()))?,
    });

    // The stack pointer associated with EL1.
    let off = offset__of!(kvm_regs, sp_el1);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "SP_EL1".to_string()))?,
    });

    // Exception Link Register for EL1, when taking an exception to EL1, this register
    // holds the address to which to return afterwards.
    let off = offset__of!(kvm_regs, elr_el1);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "ELR_EL1".to_string()))?,
    });

    // Saved Program Status Registers, there are 5 of them used in the kernel.
    let mut off = offset__of!(kvm_regs, spsr);
    for i in 0..KVM_NR_SPSR {
        let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
        state.push(kvm_one_reg {
            id,
            addr: vcpu
                .get_one_reg(id)
                .map_err(|e| Error::GetCoreRegister(e, format!("SPSR{}", i)))?,
        });
        off += std::mem::size_of::<u64>();
    }

    // Now moving on to floating point registers which are stored in the user_fpsimd_state in the kernel:
    // https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
    let mut off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, vregs);
    for i in 0..NR_FP_VREGS {
        let id = arm64_core_reg_id!(KVM_REG_SIZE_U128, off);
        state.push(kvm_one_reg {
            id,
            addr: vcpu
                .get_one_reg(id)
                .map_err(|e| Error::GetCoreRegister(e, format!("FP_VREG{}", i)))?,
        });
        off += mem::size_of::<u128>();
    }

    // Floating-point Status Register.
    let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpsr);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U32, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "FPSR".to_string()))?,
    });

    // Floating-point Control Register.
    let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpcr);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U32, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "FPCR".to_string()))?,
    });

    Ok(())
}
/// Get the state of the core registers.
///
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
/// * `state` - Structure for returning the state of the core registers.
Get the state of the core registers.
Get the state of the core registers .
pub fn save_core_registers(vcpu: &VcpuFd, state: &mut Vec<kvm_one_reg>) -> Result<()> {
    let mut off = offset__of!(user_pt_regs, regs);
    // There are 31 user_pt_regs:
    // https://elixir.free-electrons.com/linux/v4.14.174/source/arch/arm64/include/uapi/asm/ptrace.h#L72
    // These actually are the general-purpose registers of the Armv8-a
    // architecture (i.e x0-x30 if used as a 64bit register or w0-w30 when used as a 32bit register).
    for i in 0..NR_GP_REGS {
        let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
        state.push(kvm_one_reg {
            id,
            addr: vcpu
                .get_one_reg(id)
                .map_err(|e| Error::GetCoreRegister(e, format!("X{}", i)))?,
        });
        off += std::mem::size_of::<u64>();
    }
    // We are now entering the "Other register" section of the ARMv8-a architecture.
    // First one, stack pointer.
    let off = offset__of!(user_pt_regs, sp);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "stack pointer".to_string()))?,
    });
    // Second one, the program counter.
    let off = offset__of!(user_pt_regs, pc);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "program counter".to_string()))?,
    });
    // Next is the processor state.
    let off = offset__of!(user_pt_regs, pstate);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "processor state".to_string()))?,
    });
    // The stack pointer associated with EL1.
    let off = offset__of!(kvm_regs, sp_el1);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "SP_EL1".to_string()))?,
    });
    // Exception Link Register for EL1, when taking an exception to EL1, this register
    // holds the address to which to return afterwards.
    let off = offset__of!(kvm_regs, elr_el1);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "ELR_EL1".to_string()))?,
    });
    // Saved Program Status Registers, there are 5 of them used in the kernel.
    let mut off = offset__of!(kvm_regs, spsr);
    for i in 0..KVM_NR_SPSR {
        let id = arm64_core_reg_id!(KVM_REG_SIZE_U64, off);
        state.push(kvm_one_reg {
            id,
            addr: vcpu
                .get_one_reg(id)
                .map_err(|e| Error::GetCoreRegister(e, format!("SPSR{}", i)))?,
        });
        off += std::mem::size_of::<u64>();
    }
    // Now moving on to floating point registers which are stored in the user_fpsimd_state in the kernel:
    // https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
    let mut off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, vregs);
    for i in 0..NR_FP_VREGS {
        let id = arm64_core_reg_id!(KVM_REG_SIZE_U128, off);
        state.push(kvm_one_reg {
            id,
            addr: vcpu
                .get_one_reg(id)
                .map_err(|e| Error::GetCoreRegister(e, format!("FP_VREG{}", i)))?,
        });
        off += mem::size_of::<u128>();
    }
    // Floating-point Status Register.
    let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpsr);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U32, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "FPSR".to_string()))?,
    });
    // Floating-point Control Register.
    let off = offset__of!(kvm_regs, fp_regs) + offset__of!(user_fpsimd_state, fpcr);
    let id = arm64_core_reg_id!(KVM_REG_SIZE_U32, off);
    state.push(kvm_one_reg {
        id,
        addr: vcpu
            .get_one_reg(id)
            .map_err(|e| Error::GetCoreRegister(e, "FPCR".to_string()))?,
    });
    Ok(())
}
pub fn save_core_registers ( vcpu : & VcpuFd , state : & mut Vec < kvm_one_reg > ) -> Result < ( ) > { let mut off = offset__of ! ( user_pt_regs regs ) ; // There are 31 user_pt_regs: // https://elixir.free-electrons.com/linux/v4.14.174/source/arch/arm64/include/uapi/asm/ptrace.h#L72 // These actually are the general-purpose registers of the Armv8-a // architecture (i.e x0-x30 if used as a 64bit register or w0-w30 when used as a 32bit register). for i in 0 .. NR_GP_REGS { let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U64 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , format ! ( " " i ) ) ) ? , } ) ; off += std :: mem :: size_of :: < u64 > ( ) ; } // We are now entering the "Other register" section of the ARMv8-a architecture. // First one, stack pointer. let off = offset__of ! ( user_pt_regs sp ) ; let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U64 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , " " . to_string ( ) ) ) ? , } ) ; // Second one, the program counter. let off = offset__of ! ( user_pt_regs pc ) ; let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U64 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , " " . to_string ( ) ) ) ? , } ) ; // Next is the processor state. let off = offset__of ! ( user_pt_regs pstate ) ; let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U64 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , " " . to_string ( ) ) ) ? , } ) ; // The stack pointer associated with EL1. let off = offset__of ! ( kvm_regs sp_el1 ) ; let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U64 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , " " . to_string ( ) ) ) ? , } ) ; // Exception Link Register for EL1, when taking an exception to EL1, this register // holds the address to which to return afterwards. let off = offset__of ! ( kvm_regs elr_el1 ) ; let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U64 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , " " . to_string ( ) ) ) ? , } ) ; // Saved Program Status Registers, there are 5 of them used in the kernel. let mut off = offset__of ! ( kvm_regs spsr ) ; for i in 0 .. KVM_NR_SPSR { let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U64 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , format ! ( " " i ) ) ) ? , } ) ; off += std :: mem :: size_of :: < u64 > ( ) ; } // Now moving on to floating point registers which are stored in the user_fpsimd_state in the kernel: // https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53 let mut off = offset__of ! ( kvm_regs fp_regs ) + offset__of ! ( user_fpsimd_state vregs ) ; for i in 0 .. NR_FP_VREGS { let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U128 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , format ! ( " " i ) ) ) ? , } ) ; off += mem :: size_of :: < u128 > ( ) ; } // Floating-point Status Register. let off = offset__of ! ( kvm_regs fp_regs ) + offset__of ! ( user_fpsimd_state fpsr ) ; let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U32 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , " " . to_string ( ) ) ) ? , } ) ; // Floating-point Control Register. let off = offset__of ! ( kvm_regs fp_regs ) + offset__of ! ( user_fpsimd_state fpcr ) ; let id = arm64_core_reg_id ! ( KVM_REG_SIZE_U32 off ) ; state . push ( kvm_one_reg { id , addr : vcpu . get_one_reg ( id ) . map_err ( | e | Error :: GetCoreRegister ( e , " " . to_string ( ) ) ) ? , } ) ; Ok ( ( ) ) }
Get the state of the core registers.
Get the state of the core registers .
vcpu
&VcpuFd
state
&mut Vec<kvm_one_reg>
vcpu
&VcpuFd
state
&mut Vec<kvm_one_reg>