18cd80ea3SRuoqing He // Copyright © 2024 Institute of Software, CAS. All rights reserved.
28cd80ea3SRuoqing He //
356a16385SMuminul Islam // Copyright © 2019 Intel Corporation
456a16385SMuminul Islam //
572ae1577SMuminul Islam // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
656a16385SMuminul Islam //
756a16385SMuminul Islam // Copyright © 2020, Microsoft Corporation
856a16385SMuminul Islam //
956a16385SMuminul Islam // Copyright 2018-2019 CrowdStrike, Inc.
1056a16385SMuminul Islam //
11f9b51a41SMuminul Islam //
12f9b51a41SMuminul Islam
13f9b51a41SMuminul Islam //! A generic abstraction around hypervisor functionality
14f9b51a41SMuminul Islam //!
15f9b51a41SMuminul Islam //! This crate offers a trait abstraction for underlying hypervisors
16f9b51a41SMuminul Islam //!
17f9b51a41SMuminul Islam //! # Platform support
18f9b51a41SMuminul Islam //!
19f9b51a41SMuminul Islam //! - x86_64
20f9b51a41SMuminul Islam //! - arm64
218cd80ea3SRuoqing He //! - riscv64 (experimental)
22f9b51a41SMuminul Islam //!
23f9b51a41SMuminul Islam
240f1ab38dSSebastien Boeuf #[macro_use]
250f1ab38dSSebastien Boeuf extern crate anyhow;
26fdcc8539SJinank Jain #[allow(unused_imports)]
270f1ab38dSSebastien Boeuf #[macro_use]
280f1ab38dSSebastien Boeuf extern crate log;
29c48d0c1aSMuminul Islam
308c85dd32SMuminul Islam /// Architecture specific definitions
318c85dd32SMuminul Islam #[macro_use]
328c85dd32SMuminul Islam pub mod arch;
338c85dd32SMuminul Islam
349ce6c3b7SMuminul Islam #[cfg(feature = "kvm")]
35f9b51a41SMuminul Islam /// KVM implementation module
36f9b51a41SMuminul Islam pub mod kvm;
37f9b51a41SMuminul Islam
389919dec1SMuminul Islam /// Microsoft Hypervisor implementation module
39*960d7022SJinank Jain #[cfg(feature = "mshv")]
409919dec1SMuminul Islam pub mod mshv;
419919dec1SMuminul Islam
42442ac905SPhilipp Schuster /// Hypervisor related module
43288cea91SRob Bradford mod hypervisor;
44683210d6SMuminul Islam
45f5afc288SMuminul Islam /// Vm related module
46d3f66f87SRob Bradford mod vm;
47f5afc288SMuminul Islam
48f9b51a41SMuminul Islam /// CPU related module
49f9b51a41SMuminul Islam mod cpu;
50f9b51a41SMuminul Islam
51e7288888SMichael Zhao /// Device related module
52e7288888SMichael Zhao mod device;
53e7288888SMichael Zhao
5488a9f799SRob Bradford use std::sync::Arc;
5588a9f799SRob Bradford
568f3bd4d9SJinank Jain use concat_idents::concat_idents;
577df80220SAnatol Belski #[cfg(target_arch = "x86_64")]
587df80220SAnatol Belski pub use cpu::CpuVendor;
59a4f484bcSWei Liu pub use cpu::{HypervisorCpuError, Vcpu, VmExit};
60a96a5d78SWei Liu pub use device::HypervisorDeviceError;
61c2862b69SMichael Zhao #[cfg(all(feature = "kvm", target_arch = "aarch64"))]
626bb33601SJinank Jain pub use kvm::aarch64;
638cd80ea3SRuoqing He #[cfg(all(feature = "kvm", target_arch = "riscv64"))]
648cd80ea3SRuoqing He pub use kvm::{riscv64, AiaState};
65d3f66f87SRob Bradford pub use vm::{
66d3f66f87SRob Bradford DataMatch, HypervisorVmError, InterruptSourceConfig, LegacyIrqSourceConfig, MsiIrqSourceConfig,
67d3f66f87SRob Bradford Vm, VmOps,
68d3f66f87SRob Bradford };
69a83bd97eSWei Liu
7088a9f799SRob Bradford pub use crate::hypervisor::{Hypervisor, HypervisorError};
7188a9f799SRob Bradford
727d8f7954SMuminul Islam #[derive(Debug, Copy, Clone)]
739fc3379eSWei Liu pub enum HypervisorType {
74a48d7c28SRob Bradford #[cfg(feature = "kvm")]
759fc3379eSWei Liu Kvm,
76a48d7c28SRob Bradford #[cfg(feature = "mshv")]
779fc3379eSWei Liu Mshv,
789fc3379eSWei Liu }
799fc3379eSWei Liu
new() -> std::result::Result<Arc<dyn Hypervisor>, HypervisorError>80a83bd97eSWei Liu pub fn new() -> std::result::Result<Arc<dyn Hypervisor>, HypervisorError> {
81a83bd97eSWei Liu #[cfg(feature = "kvm")]
82bb19c3d2SWei Liu if kvm::KvmHypervisor::is_available()? {
83bb19c3d2SWei Liu return kvm::KvmHypervisor::new();
84bb19c3d2SWei Liu }
85a83bd97eSWei Liu
8623c46b16SMuminul Islam #[cfg(feature = "mshv")]
87bb19c3d2SWei Liu if mshv::MshvHypervisor::is_available()? {
88bb19c3d2SWei Liu return mshv::MshvHypervisor::new();
89bb19c3d2SWei Liu }
9023c46b16SMuminul Islam
91bb19c3d2SWei Liu Err(HypervisorError::HypervisorCreate(anyhow!(
92bb19c3d2SWei Liu "no supported hypervisor"
93bb19c3d2SWei Liu )))
94a83bd97eSWei Liu }
957fad74cbSVineeth Pillai
967fad74cbSVineeth Pillai // Returns a `Vec<T>` with a size in bytes at least as large as `size_in_bytes`.
vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T>977fad74cbSVineeth Pillai fn vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T> {
986164aa08SRuoqing He let rounded_size = size_in_bytes.div_ceil(size_of::<T>());
997fad74cbSVineeth Pillai let mut v = Vec::with_capacity(rounded_size);
1007fad74cbSVineeth Pillai v.resize_with(rounded_size, T::default);
1017fad74cbSVineeth Pillai v
1027fad74cbSVineeth Pillai }
1037fad74cbSVineeth Pillai
1047fad74cbSVineeth Pillai // The kvm API has many structs that resemble the following `Foo` structure:
1057fad74cbSVineeth Pillai //
1067fad74cbSVineeth Pillai // ```
1077fad74cbSVineeth Pillai // #[repr(C)]
1087fad74cbSVineeth Pillai // struct Foo {
1097fad74cbSVineeth Pillai // some_data: u32
1107fad74cbSVineeth Pillai // entries: __IncompleteArrayField<__u32>,
1117fad74cbSVineeth Pillai // }
1127fad74cbSVineeth Pillai // ```
1137fad74cbSVineeth Pillai //
1147fad74cbSVineeth Pillai // In order to allocate such a structure, `size_of::<Foo>()` would be too small because it would not
1157fad74cbSVineeth Pillai // include any space for `entries`. To make the allocation large enough while still being aligned
1167fad74cbSVineeth Pillai // for `Foo`, a `Vec<Foo>` is created. Only the first element of `Vec<Foo>` would actually be used
1177fad74cbSVineeth Pillai // as a `Foo`. The remaining memory in the `Vec<Foo>` is for `entries`, which must be contiguous
1187fad74cbSVineeth Pillai // with `Foo`. This function is used to make the `Vec<Foo>` with enough space for `count` entries.
1197fad74cbSVineeth Pillai use std::mem::size_of;
vec_with_array_field<T: Default, F>(count: usize) -> Vec<T>1207fad74cbSVineeth Pillai pub fn vec_with_array_field<T: Default, F>(count: usize) -> Vec<T> {
1217fad74cbSVineeth Pillai let element_space = count * size_of::<F>();
1227fad74cbSVineeth Pillai let vec_size_bytes = size_of::<T>() + element_space;
1237fad74cbSVineeth Pillai vec_with_size_in_bytes(vec_size_bytes)
1247fad74cbSVineeth Pillai }
125fabc940bSWei Liu
126fabc940bSWei Liu ///
127fabc940bSWei Liu /// User memory region structure
128fabc940bSWei Liu ///
129fabc940bSWei Liu #[derive(Debug, Default, Eq, PartialEq)]
130fabc940bSWei Liu pub struct UserMemoryRegion {
131fabc940bSWei Liu pub slot: u32,
132fabc940bSWei Liu pub guest_phys_addr: u64,
133fabc940bSWei Liu pub memory_size: u64,
134fabc940bSWei Liu pub userspace_addr: u64,
135fabc940bSWei Liu pub flags: u32,
136fabc940bSWei Liu }
137fabc940bSWei Liu
138fabc940bSWei Liu ///
139fabc940bSWei Liu /// Flags for user memory region
140fabc940bSWei Liu ///
141fabc940bSWei Liu pub const USER_MEMORY_REGION_READ: u32 = 1;
142fabc940bSWei Liu pub const USER_MEMORY_REGION_WRITE: u32 = 1 << 1;
143fabc940bSWei Liu pub const USER_MEMORY_REGION_EXECUTE: u32 = 1 << 2;
144fabc940bSWei Liu pub const USER_MEMORY_REGION_LOG_DIRTY: u32 = 1 << 3;
145321d6f47SJinank Jain pub const USER_MEMORY_REGION_ADJUSTABLE: u32 = 1 << 4;
1469810ed44SWei Liu
1479810ed44SWei Liu #[derive(Debug)]
1489810ed44SWei Liu pub enum MpState {
1499810ed44SWei Liu #[cfg(feature = "kvm")]
1509810ed44SWei Liu Kvm(kvm_bindings::kvm_mp_state),
151*960d7022SJinank Jain #[cfg(feature = "mshv")]
1527bf0cc1eSPhilipp Schuster Mshv, /* MSHV does not support MpState yet */
1539810ed44SWei Liu }
154f9f0a60dSWei Liu
155f9f0a60dSWei Liu #[derive(Debug, Clone, Copy)]
156f9f0a60dSWei Liu pub enum IoEventAddress {
157f9f0a60dSWei Liu Pio(u64),
158f9f0a60dSWei Liu Mmio(u64),
159f9f0a60dSWei Liu }
16072d552e5SWei Liu
16172d552e5SWei Liu #[derive(Clone, serde::Serialize, serde::Deserialize)]
1627b99bd94SWei Liu #[allow(clippy::large_enum_variant)]
16372d552e5SWei Liu pub enum CpuState {
16472d552e5SWei Liu #[cfg(feature = "kvm")]
16572d552e5SWei Liu Kvm(kvm::VcpuKvmState),
166f5a2f847SJinank Jain #[cfg(feature = "mshv")]
16772d552e5SWei Liu Mshv(mshv::VcpuMshvState),
16872d552e5SWei Liu }
1694201bf40SWei Liu
1704201bf40SWei Liu #[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
1714201bf40SWei Liu #[cfg(target_arch = "x86_64")]
1724201bf40SWei Liu pub enum ClockData {
1734201bf40SWei Liu #[cfg(feature = "kvm")]
1744201bf40SWei Liu Kvm(kvm_bindings::kvm_clock_data),
1754201bf40SWei Liu #[cfg(feature = "mshv")]
1764847f5c4SMuminul Islam Mshv(mshv::MshvClockData),
1774201bf40SWei Liu }
1784201bf40SWei Liu
1794201bf40SWei Liu #[cfg(target_arch = "x86_64")]
1804201bf40SWei Liu impl ClockData {
reset_flags(&mut self)1814201bf40SWei Liu pub fn reset_flags(&mut self) {
1824201bf40SWei Liu match self {
1834201bf40SWei Liu #[cfg(feature = "kvm")]
1844201bf40SWei Liu ClockData::Kvm(s) => s.flags = 0,
1854201bf40SWei Liu #[allow(unreachable_patterns)]
1864201bf40SWei Liu _ => {}
1874201bf40SWei Liu }
1884201bf40SWei Liu }
1894201bf40SWei Liu }
190d20f647bSWei Liu
191d20f647bSWei Liu #[derive(Copy, Clone)]
192d20f647bSWei Liu pub enum IrqRoutingEntry {
193d20f647bSWei Liu #[cfg(feature = "kvm")]
194d20f647bSWei Liu Kvm(kvm_bindings::kvm_irq_routing_entry),
195d20f647bSWei Liu #[cfg(feature = "mshv")]
1969f08aa6dSNuno Das Neves Mshv(mshv_bindings::mshv_user_irq_entry),
197d20f647bSWei Liu }
198feb0a360SJinank Jain
1995b929cb2SJinank Jain #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
2005b929cb2SJinank Jain pub enum VcpuInit {
2015b929cb2SJinank Jain #[cfg(all(feature = "kvm", target_arch = "aarch64"))]
2025b929cb2SJinank Jain Kvm(kvm_bindings::kvm_vcpu_init),
2038c796e6dSJinank Jain #[cfg(all(feature = "mshv", target_arch = "aarch64"))]
2048c796e6dSJinank Jain Mshv(mshv_bindings::MshvVcpuInit),
2055b929cb2SJinank Jain }
2065b929cb2SJinank Jain
207ee0b0d43SJinank Jain #[derive(Debug, Clone, PartialEq)]
208ee0b0d43SJinank Jain pub enum RegList {
209ee0b0d43SJinank Jain #[cfg(all(feature = "kvm", any(target_arch = "aarch64", target_arch = "riscv64")))]
210ee0b0d43SJinank Jain Kvm(kvm_bindings::RegList),
211630f5c1fSJinank Jain #[cfg(all(feature = "mshv", target_arch = "aarch64"))]
212630f5c1fSJinank Jain Mshv(mshv_bindings::MshvRegList),
213ee0b0d43SJinank Jain }
214ee0b0d43SJinank Jain
21506148234SJinank Jain pub enum Register {
21606148234SJinank Jain #[cfg(feature = "kvm")]
21706148234SJinank Jain Kvm(kvm_bindings::kvm_one_reg),
21806148234SJinank Jain }
21906148234SJinank Jain
2207da8ae9cSJinank Jain #[allow(clippy::large_enum_variant)]
221feb0a360SJinank Jain #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
222feb0a360SJinank Jain pub enum StandardRegisters {
2238cd80ea3SRuoqing He #[cfg(all(feature = "kvm", not(target_arch = "riscv64")))]
224feb0a360SJinank Jain Kvm(kvm_bindings::kvm_regs),
2258cd80ea3SRuoqing He #[cfg(all(feature = "kvm", target_arch = "riscv64"))]
2268cd80ea3SRuoqing He Kvm(kvm_bindings::kvm_riscv_core),
2277da8ae9cSJinank Jain #[cfg(any(feature = "mshv", feature = "mshv_emulator"))]
228feb0a360SJinank Jain Mshv(mshv_bindings::StandardRegisters),
229feb0a360SJinank Jain }
2308f3bd4d9SJinank Jain
2318f3bd4d9SJinank Jain macro_rules! set_x86_64_reg {
2328f3bd4d9SJinank Jain ($reg_name:ident) => {
2338f3bd4d9SJinank Jain concat_idents!(method_name = "set_", $reg_name {
2348f3bd4d9SJinank Jain #[cfg(target_arch = "x86_64")]
2358f3bd4d9SJinank Jain impl StandardRegisters {
2368f3bd4d9SJinank Jain pub fn method_name(&mut self, val: u64) {
2378f3bd4d9SJinank Jain match self {
2388f3bd4d9SJinank Jain #[cfg(feature = "kvm")]
2398f3bd4d9SJinank Jain StandardRegisters::Kvm(s) => s.$reg_name = val,
240fe24a7a2SWei Liu #[cfg(any(feature = "mshv", feature = "mshv_emulator"))]
2418f3bd4d9SJinank Jain StandardRegisters::Mshv(s) => s.$reg_name = val,
2428f3bd4d9SJinank Jain }
2438f3bd4d9SJinank Jain }
2448f3bd4d9SJinank Jain }
2458f3bd4d9SJinank Jain });
2468f3bd4d9SJinank Jain }
2478f3bd4d9SJinank Jain }
2488f3bd4d9SJinank Jain
2498f3bd4d9SJinank Jain macro_rules! get_x86_64_reg {
2508f3bd4d9SJinank Jain ($reg_name:ident) => {
2518f3bd4d9SJinank Jain concat_idents!(method_name = "get_", $reg_name {
2528f3bd4d9SJinank Jain #[cfg(target_arch = "x86_64")]
2538f3bd4d9SJinank Jain impl StandardRegisters {
2548f3bd4d9SJinank Jain pub fn method_name(&self) -> u64 {
2558f3bd4d9SJinank Jain match self {
2568f3bd4d9SJinank Jain #[cfg(feature = "kvm")]
2578f3bd4d9SJinank Jain StandardRegisters::Kvm(s) => s.$reg_name,
258fe24a7a2SWei Liu #[cfg(any(feature = "mshv", feature = "mshv_emulator"))]
2598f3bd4d9SJinank Jain StandardRegisters::Mshv(s) => s.$reg_name,
2608f3bd4d9SJinank Jain }
2618f3bd4d9SJinank Jain }
2628f3bd4d9SJinank Jain }
2638f3bd4d9SJinank Jain });
2648f3bd4d9SJinank Jain }
2658f3bd4d9SJinank Jain }
2668f3bd4d9SJinank Jain
2678f3bd4d9SJinank Jain set_x86_64_reg!(rax);
2688f3bd4d9SJinank Jain set_x86_64_reg!(rbx);
2698f3bd4d9SJinank Jain set_x86_64_reg!(rcx);
2708f3bd4d9SJinank Jain set_x86_64_reg!(rdx);
2718f3bd4d9SJinank Jain set_x86_64_reg!(rsi);
2728f3bd4d9SJinank Jain set_x86_64_reg!(rdi);
2738f3bd4d9SJinank Jain set_x86_64_reg!(rsp);
2748f3bd4d9SJinank Jain set_x86_64_reg!(rbp);
2758f3bd4d9SJinank Jain set_x86_64_reg!(r8);
2768f3bd4d9SJinank Jain set_x86_64_reg!(r9);
2778f3bd4d9SJinank Jain set_x86_64_reg!(r10);
2788f3bd4d9SJinank Jain set_x86_64_reg!(r11);
2798f3bd4d9SJinank Jain set_x86_64_reg!(r12);
2808f3bd4d9SJinank Jain set_x86_64_reg!(r13);
2818f3bd4d9SJinank Jain set_x86_64_reg!(r14);
2828f3bd4d9SJinank Jain set_x86_64_reg!(r15);
2838f3bd4d9SJinank Jain set_x86_64_reg!(rip);
2848f3bd4d9SJinank Jain set_x86_64_reg!(rflags);
2858f3bd4d9SJinank Jain
2868f3bd4d9SJinank Jain get_x86_64_reg!(rax);
2878f3bd4d9SJinank Jain get_x86_64_reg!(rbx);
2888f3bd4d9SJinank Jain get_x86_64_reg!(rcx);
2898f3bd4d9SJinank Jain get_x86_64_reg!(rdx);
2908f3bd4d9SJinank Jain get_x86_64_reg!(rsi);
2918f3bd4d9SJinank Jain get_x86_64_reg!(rdi);
2928f3bd4d9SJinank Jain get_x86_64_reg!(rsp);
2938f3bd4d9SJinank Jain get_x86_64_reg!(rbp);
2948f3bd4d9SJinank Jain get_x86_64_reg!(r8);
2958f3bd4d9SJinank Jain get_x86_64_reg!(r9);
2968f3bd4d9SJinank Jain get_x86_64_reg!(r10);
2978f3bd4d9SJinank Jain get_x86_64_reg!(r11);
2988f3bd4d9SJinank Jain get_x86_64_reg!(r12);
2998f3bd4d9SJinank Jain get_x86_64_reg!(r13);
3008f3bd4d9SJinank Jain get_x86_64_reg!(r14);
3018f3bd4d9SJinank Jain get_x86_64_reg!(r15);
3028f3bd4d9SJinank Jain get_x86_64_reg!(rip);
3038f3bd4d9SJinank Jain get_x86_64_reg!(rflags);
304a987c3d0SJinank Jain
305a987c3d0SJinank Jain macro_rules! set_aarch64_reg {
306a987c3d0SJinank Jain ($reg_name:ident, $type:ty) => {
307a987c3d0SJinank Jain concat_idents!(method_name = "set_", $reg_name {
308a987c3d0SJinank Jain #[cfg(target_arch = "aarch64")]
309a987c3d0SJinank Jain impl StandardRegisters {
310a987c3d0SJinank Jain pub fn method_name(&mut self, val: $type) {
311a987c3d0SJinank Jain match self {
312a987c3d0SJinank Jain #[cfg(feature = "kvm")]
313a987c3d0SJinank Jain StandardRegisters::Kvm(s) => s.regs.$reg_name = val,
3147da8ae9cSJinank Jain #[cfg(feature = "mshv")]
3157da8ae9cSJinank Jain StandardRegisters::Mshv(s) => s.$reg_name = val,
316a987c3d0SJinank Jain }
317a987c3d0SJinank Jain }
318a987c3d0SJinank Jain }
319a987c3d0SJinank Jain });
320a987c3d0SJinank Jain }
321a987c3d0SJinank Jain }
322a987c3d0SJinank Jain
323a987c3d0SJinank Jain macro_rules! get_aarch64_reg {
324a987c3d0SJinank Jain ($reg_name:ident, $type:ty) => {
325a987c3d0SJinank Jain concat_idents!(method_name = "get_", $reg_name {
326a987c3d0SJinank Jain #[cfg(target_arch = "aarch64")]
327a987c3d0SJinank Jain impl StandardRegisters {
328a987c3d0SJinank Jain pub fn method_name(&self) -> $type {
329a987c3d0SJinank Jain match self {
330a987c3d0SJinank Jain #[cfg(feature = "kvm")]
331a987c3d0SJinank Jain StandardRegisters::Kvm(s) => s.regs.$reg_name,
3327da8ae9cSJinank Jain #[cfg(feature = "mshv")]
3337da8ae9cSJinank Jain StandardRegisters::Mshv(s) => s.$reg_name,
334a987c3d0SJinank Jain }
335a987c3d0SJinank Jain }
336a987c3d0SJinank Jain }
337a987c3d0SJinank Jain });
338a987c3d0SJinank Jain }
339a987c3d0SJinank Jain }
340a987c3d0SJinank Jain
341a987c3d0SJinank Jain set_aarch64_reg!(regs, [u64; 31usize]);
342a987c3d0SJinank Jain set_aarch64_reg!(sp, u64);
343a987c3d0SJinank Jain set_aarch64_reg!(pc, u64);
344a987c3d0SJinank Jain set_aarch64_reg!(pstate, u64);
345a987c3d0SJinank Jain
346a987c3d0SJinank Jain get_aarch64_reg!(regs, [u64; 31usize]);
347a987c3d0SJinank Jain get_aarch64_reg!(sp, u64);
348a987c3d0SJinank Jain get_aarch64_reg!(pc, u64);
349a987c3d0SJinank Jain get_aarch64_reg!(pstate, u64);
3508cd80ea3SRuoqing He
3518cd80ea3SRuoqing He macro_rules! set_riscv64_reg {
3528cd80ea3SRuoqing He (mode) => {
3538cd80ea3SRuoqing He #[cfg(target_arch = "riscv64")]
3548cd80ea3SRuoqing He impl StandardRegisters {
3558cd80ea3SRuoqing He pub fn set_mode(&mut self, val: u64) {
3568cd80ea3SRuoqing He match self {
3578cd80ea3SRuoqing He #[cfg(feature = "kvm")]
3588cd80ea3SRuoqing He StandardRegisters::Kvm(s) => s.mode = val,
3598cd80ea3SRuoqing He }
3608cd80ea3SRuoqing He }
3618cd80ea3SRuoqing He }
3628cd80ea3SRuoqing He };
3638cd80ea3SRuoqing He ($reg_name:ident) => {
3648cd80ea3SRuoqing He concat_idents!(method_name = "set_", $reg_name {
3658cd80ea3SRuoqing He #[cfg(target_arch = "riscv64")]
3668cd80ea3SRuoqing He impl StandardRegisters {
3678cd80ea3SRuoqing He pub fn method_name(&mut self, val: u64) {
3688cd80ea3SRuoqing He match self {
3698cd80ea3SRuoqing He #[cfg(feature = "kvm")]
3708cd80ea3SRuoqing He StandardRegisters::Kvm(s) => s.regs.$reg_name = val,
3718cd80ea3SRuoqing He }
3728cd80ea3SRuoqing He }
3738cd80ea3SRuoqing He }
3748cd80ea3SRuoqing He });
3758cd80ea3SRuoqing He }
3768cd80ea3SRuoqing He }
3778cd80ea3SRuoqing He
3788cd80ea3SRuoqing He macro_rules! get_riscv64_reg {
3798cd80ea3SRuoqing He (mode) => {
3808cd80ea3SRuoqing He #[cfg(target_arch = "riscv64")]
3818cd80ea3SRuoqing He impl StandardRegisters {
3828cd80ea3SRuoqing He pub fn get_mode(&self) -> u64 {
3838cd80ea3SRuoqing He match self {
3848cd80ea3SRuoqing He #[cfg(feature = "kvm")]
3858cd80ea3SRuoqing He StandardRegisters::Kvm(s) => s.mode,
3868cd80ea3SRuoqing He }
3878cd80ea3SRuoqing He }
3888cd80ea3SRuoqing He }
3898cd80ea3SRuoqing He };
3908cd80ea3SRuoqing He ($reg_name:ident) => {
3918cd80ea3SRuoqing He concat_idents!(method_name = "get_", $reg_name {
3928cd80ea3SRuoqing He #[cfg(target_arch = "riscv64")]
3938cd80ea3SRuoqing He impl StandardRegisters {
3948cd80ea3SRuoqing He pub fn method_name(&self) -> u64 {
3958cd80ea3SRuoqing He match self {
3968cd80ea3SRuoqing He #[cfg(feature = "kvm")]
3978cd80ea3SRuoqing He StandardRegisters::Kvm(s) => s.regs.$reg_name,
3988cd80ea3SRuoqing He }
3998cd80ea3SRuoqing He }
4008cd80ea3SRuoqing He }
4018cd80ea3SRuoqing He });
4028cd80ea3SRuoqing He }
4038cd80ea3SRuoqing He }
4048cd80ea3SRuoqing He
4058cd80ea3SRuoqing He set_riscv64_reg!(pc);
4068cd80ea3SRuoqing He set_riscv64_reg!(ra);
4078cd80ea3SRuoqing He set_riscv64_reg!(sp);
4088cd80ea3SRuoqing He set_riscv64_reg!(gp);
4098cd80ea3SRuoqing He set_riscv64_reg!(tp);
4108cd80ea3SRuoqing He set_riscv64_reg!(t0);
4118cd80ea3SRuoqing He set_riscv64_reg!(t1);
4128cd80ea3SRuoqing He set_riscv64_reg!(t2);
4138cd80ea3SRuoqing He set_riscv64_reg!(s0);
4148cd80ea3SRuoqing He set_riscv64_reg!(s1);
4158cd80ea3SRuoqing He set_riscv64_reg!(a0);
4168cd80ea3SRuoqing He set_riscv64_reg!(a1);
4178cd80ea3SRuoqing He set_riscv64_reg!(a2);
4188cd80ea3SRuoqing He set_riscv64_reg!(a3);
4198cd80ea3SRuoqing He set_riscv64_reg!(a4);
4208cd80ea3SRuoqing He set_riscv64_reg!(a5);
4218cd80ea3SRuoqing He set_riscv64_reg!(a6);
4228cd80ea3SRuoqing He set_riscv64_reg!(a7);
4238cd80ea3SRuoqing He set_riscv64_reg!(s2);
4248cd80ea3SRuoqing He set_riscv64_reg!(s3);
4258cd80ea3SRuoqing He set_riscv64_reg!(s4);
4268cd80ea3SRuoqing He set_riscv64_reg!(s5);
4278cd80ea3SRuoqing He set_riscv64_reg!(s6);
4288cd80ea3SRuoqing He set_riscv64_reg!(s7);
4298cd80ea3SRuoqing He set_riscv64_reg!(s8);
4308cd80ea3SRuoqing He set_riscv64_reg!(s9);
4318cd80ea3SRuoqing He set_riscv64_reg!(s10);
4328cd80ea3SRuoqing He set_riscv64_reg!(s11);
4338cd80ea3SRuoqing He set_riscv64_reg!(t3);
4348cd80ea3SRuoqing He set_riscv64_reg!(t4);
4358cd80ea3SRuoqing He set_riscv64_reg!(t5);
4368cd80ea3SRuoqing He set_riscv64_reg!(t6);
4378cd80ea3SRuoqing He set_riscv64_reg!(mode);
4388cd80ea3SRuoqing He
4398cd80ea3SRuoqing He get_riscv64_reg!(pc);
4408cd80ea3SRuoqing He get_riscv64_reg!(ra);
4418cd80ea3SRuoqing He get_riscv64_reg!(sp);
4428cd80ea3SRuoqing He get_riscv64_reg!(gp);
4438cd80ea3SRuoqing He get_riscv64_reg!(tp);
4448cd80ea3SRuoqing He get_riscv64_reg!(t0);
4458cd80ea3SRuoqing He get_riscv64_reg!(t1);
4468cd80ea3SRuoqing He get_riscv64_reg!(t2);
4478cd80ea3SRuoqing He get_riscv64_reg!(s0);
4488cd80ea3SRuoqing He get_riscv64_reg!(s1);
4498cd80ea3SRuoqing He get_riscv64_reg!(a0);
4508cd80ea3SRuoqing He get_riscv64_reg!(a1);
4518cd80ea3SRuoqing He get_riscv64_reg!(a2);
4528cd80ea3SRuoqing He get_riscv64_reg!(a3);
4538cd80ea3SRuoqing He get_riscv64_reg!(a4);
4548cd80ea3SRuoqing He get_riscv64_reg!(a5);
4558cd80ea3SRuoqing He get_riscv64_reg!(a6);
4568cd80ea3SRuoqing He get_riscv64_reg!(a7);
4578cd80ea3SRuoqing He get_riscv64_reg!(s2);
4588cd80ea3SRuoqing He get_riscv64_reg!(s3);
4598cd80ea3SRuoqing He get_riscv64_reg!(s4);
4608cd80ea3SRuoqing He get_riscv64_reg!(s5);
4618cd80ea3SRuoqing He get_riscv64_reg!(s6);
4628cd80ea3SRuoqing He get_riscv64_reg!(s7);
4638cd80ea3SRuoqing He get_riscv64_reg!(s8);
4648cd80ea3SRuoqing He get_riscv64_reg!(s9);
4658cd80ea3SRuoqing He get_riscv64_reg!(s10);
4668cd80ea3SRuoqing He get_riscv64_reg!(s11);
4678cd80ea3SRuoqing He get_riscv64_reg!(t3);
4688cd80ea3SRuoqing He get_riscv64_reg!(t4);
4698cd80ea3SRuoqing He get_riscv64_reg!(t5);
4708cd80ea3SRuoqing He get_riscv64_reg!(t6);
4718cd80ea3SRuoqing He get_riscv64_reg!(mode);
472