vminer_core/arch/
runtime.rs

1use crate::{arch, endian::RuntimeEndian, Endianness, HasVcpus, PhysicalAddress, VirtualAddress};
2
3#[derive(Debug, Clone, Copy)]
4pub enum Architecture {
5    X86_64(arch::X86_64),
6    Aarch64(arch::Aarch64),
7}
8
9#[derive(Debug, Clone, Copy)]
10pub enum Registers {
11    X86_64(arch::x86_64::Registers),
12    Aarch64(arch::aarch64::Registers),
13}
14
15#[allow(clippy::large_enum_variant)]
16#[derive(Debug, Clone, Copy)]
17pub enum SpecialRegisters {
18    X86_64(arch::x86_64::SpecialRegisters),
19    Aarch64(arch::aarch64::SpecialRegisters),
20}
21
22#[derive(Debug, Clone, Copy)]
23pub enum OtherRegisters {
24    X86_64(arch::x86_64::OtherRegisters),
25    Aarch64(arch::aarch64::OtherRegisters),
26}
27
28macro_rules! dispatch {
29    ($val:expr => |$arch:ident| $expr:expr) => {
30        match $val {
31            Architecture::X86_64($arch) => $expr,
32            Architecture::Aarch64($arch) => $expr,
33        }
34    };
35    ($val:expr, $vcpus:ident => |$arch:ident| $expr:expr) => {
36        match $val {
37            Architecture::X86_64($arch) => {
38                let $vcpus = &super::AssumeX86_64($vcpus);
39                $expr
40            }
41            Architecture::Aarch64($arch) => {
42                let $vcpus = &super::AssumeAarch64($vcpus);
43                $expr
44            }
45        }
46    };
47}
48
49impl arch::Architecture for Architecture {
50    type Endian = RuntimeEndian;
51
52    type Registers = Registers;
53    type SpecialRegisters = SpecialRegisters;
54    type OtherRegisters = OtherRegisters;
55
56    #[inline]
57    fn into_runtime(self) -> Architecture {
58        self
59    }
60
61    #[inline]
62    fn endianness(&self) -> RuntimeEndian {
63        dispatch!(self => |arch|arch.endianness().as_runtime_endian())
64    }
65
66    #[inline]
67    fn virtual_to_physical<M: crate::Memory + ?Sized>(
68        &self,
69        memory: &M,
70        mmu_addr: PhysicalAddress,
71        addr: VirtualAddress,
72    ) -> crate::TranslationResult<PhysicalAddress> {
73        dispatch!(self => |arch| arch.virtual_to_physical(memory, mmu_addr, addr))
74    }
75
76    #[inline]
77    fn find_kernel_pgd<M: crate::Memory + ?Sized>(
78        &self,
79        memory: &M,
80        vcpus: &(impl HasVcpus<Arch = Self> + ?Sized),
81        use_per_cpu: bool,
82        additional: &[VirtualAddress],
83    ) -> crate::VmResult<Option<PhysicalAddress>> {
84        dispatch!(self, vcpus => |arch| arch.find_kernel_pgd(memory, vcpus, use_per_cpu, additional))
85    }
86
87    #[inline]
88    fn find_in_kernel_memory_raw<M: crate::Memory + ?Sized>(
89        &self,
90        memory: &M,
91        mmu_addr: PhysicalAddress,
92        base_search_addr: VirtualAddress,
93        finder: &memchr::memmem::Finder,
94        buf: &mut [u8],
95    ) -> crate::MemoryAccessResult<Option<VirtualAddress>> {
96        dispatch!(self => |arch| arch.find_in_kernel_memory_raw(memory, mmu_addr, base_search_addr, finder, buf))
97    }
98
99    #[inline]
100    fn find_in_kernel_memory<M: crate::Memory + ?Sized>(
101        &self,
102        memory: &M,
103        mmu_addr: PhysicalAddress,
104        needle: &[u8],
105    ) -> crate::MemoryAccessResult<Option<VirtualAddress>> {
106        dispatch!(self => |arch| arch.find_in_kernel_memory(memory, mmu_addr, needle))
107    }
108
109    #[inline]
110    fn kernel_base(&self) -> VirtualAddress {
111        dispatch!(self => |arch| arch.kernel_base())
112    }
113
114    #[inline]
115    fn instruction_pointer<Vcpus: HasVcpus<Arch = Self> + ?Sized>(
116        &self,
117        vcpus: &Vcpus,
118        vcpu: crate::VcpuId,
119    ) -> crate::VcpuResult<VirtualAddress> {
120        dispatch!(self, vcpus => |arch| arch.instruction_pointer(vcpus, vcpu))
121    }
122
123    #[inline]
124    fn stack_pointer<Vcpus: HasVcpus<Arch = Self> + ?Sized>(
125        &self,
126        vcpus: &Vcpus,
127        vcpu: crate::VcpuId,
128    ) -> crate::VcpuResult<VirtualAddress> {
129        dispatch!(self, vcpus => |arch| arch.stack_pointer(vcpus, vcpu))
130    }
131
132    #[inline]
133    fn base_pointer<Vcpus: HasVcpus<Arch = Self> + ?Sized>(
134        &self,
135        vcpus: &Vcpus,
136        vcpu: crate::VcpuId,
137    ) -> crate::VcpuResult<Option<VirtualAddress>> {
138        dispatch!(self, vcpus => |arch| arch.base_pointer(vcpus, vcpu))
139    }
140
141    #[inline]
142    fn pgd<Vcpus: HasVcpus<Arch = Self> + ?Sized>(
143        &self,
144        vcpus: &Vcpus,
145        vcpu: crate::VcpuId,
146    ) -> crate::VcpuResult<PhysicalAddress> {
147        dispatch!(self, vcpus => |arch| arch.pgd(vcpus, vcpu))
148    }
149
150    #[inline]
151    fn kernel_per_cpu<Vcpus: HasVcpus<Arch = Self> + ?Sized>(
152        &self,
153        vcpus: &Vcpus,
154        vcpu: crate::VcpuId,
155    ) -> crate::VcpuResult<Option<VirtualAddress>> {
156        dispatch!(self, vcpus => |arch| arch.kernel_per_cpu(vcpus, vcpu))
157    }
158}