xref: /aosp_15_r20/external/crosvm/hypervisor/src/gunyah/aarch64.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2023 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker use base::error;
8*bb4ee6a4SAndroid Build Coastguard Worker use base::Error;
9*bb4ee6a4SAndroid Build Coastguard Worker use base::Result;
10*bb4ee6a4SAndroid Build Coastguard Worker use cros_fdt::Fdt;
11*bb4ee6a4SAndroid Build Coastguard Worker use cros_fdt::FdtNode;
12*bb4ee6a4SAndroid Build Coastguard Worker use libc::ENOENT;
13*bb4ee6a4SAndroid Build Coastguard Worker use libc::ENOTSUP;
14*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress;
15*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::MemoryRegionPurpose;
16*bb4ee6a4SAndroid Build Coastguard Worker 
17*bb4ee6a4SAndroid Build Coastguard Worker use super::GunyahVcpu;
18*bb4ee6a4SAndroid Build Coastguard Worker use super::GunyahVm;
19*bb4ee6a4SAndroid Build Coastguard Worker use crate::AArch64SysRegId;
20*bb4ee6a4SAndroid Build Coastguard Worker use crate::Hypervisor;
21*bb4ee6a4SAndroid Build Coastguard Worker use crate::PsciVersion;
22*bb4ee6a4SAndroid Build Coastguard Worker use crate::VcpuAArch64;
23*bb4ee6a4SAndroid Build Coastguard Worker use crate::VcpuRegAArch64;
24*bb4ee6a4SAndroid Build Coastguard Worker use crate::VmAArch64;
25*bb4ee6a4SAndroid Build Coastguard Worker use crate::PSCI_0_2;
26*bb4ee6a4SAndroid Build Coastguard Worker 
27*bb4ee6a4SAndroid Build Coastguard Worker const GIC_FDT_IRQ_TYPE_SPI: u32 = 0;
28*bb4ee6a4SAndroid Build Coastguard Worker 
29*bb4ee6a4SAndroid Build Coastguard Worker const IRQ_TYPE_EDGE_RISING: u32 = 0x00000001;
30*bb4ee6a4SAndroid Build Coastguard Worker const IRQ_TYPE_LEVEL_HIGH: u32 = 0x00000004;
31*bb4ee6a4SAndroid Build Coastguard Worker 
fdt_create_shm_device( parent: &mut FdtNode, index: u32, guest_addr: GuestAddress, ) -> cros_fdt::Result<()>32*bb4ee6a4SAndroid Build Coastguard Worker fn fdt_create_shm_device(
33*bb4ee6a4SAndroid Build Coastguard Worker     parent: &mut FdtNode,
34*bb4ee6a4SAndroid Build Coastguard Worker     index: u32,
35*bb4ee6a4SAndroid Build Coastguard Worker     guest_addr: GuestAddress,
36*bb4ee6a4SAndroid Build Coastguard Worker ) -> cros_fdt::Result<()> {
37*bb4ee6a4SAndroid Build Coastguard Worker     let shm_name = format!("shm-{:x}", index);
38*bb4ee6a4SAndroid Build Coastguard Worker     let shm_node = parent.subnode_mut(&shm_name)?;
39*bb4ee6a4SAndroid Build Coastguard Worker     shm_node.set_prop("vdevice-type", "shm")?;
40*bb4ee6a4SAndroid Build Coastguard Worker     shm_node.set_prop("peer-default", ())?;
41*bb4ee6a4SAndroid Build Coastguard Worker     shm_node.set_prop("dma_base", 0u64)?;
42*bb4ee6a4SAndroid Build Coastguard Worker     let mem_node = shm_node.subnode_mut("memory")?;
43*bb4ee6a4SAndroid Build Coastguard Worker     // We have to add the shm device for RM to accept the swiotlb memparcel.
44*bb4ee6a4SAndroid Build Coastguard Worker     // Memparcel is only used on android14-6.1. Once android14-6.1 is EOL
45*bb4ee6a4SAndroid Build Coastguard Worker     // we should be able to remove all the times we call fdt_create_shm_device()
46*bb4ee6a4SAndroid Build Coastguard Worker     mem_node.set_prop("optional", ())?;
47*bb4ee6a4SAndroid Build Coastguard Worker     mem_node.set_prop("label", index)?;
48*bb4ee6a4SAndroid Build Coastguard Worker     mem_node.set_prop("#address-cells", 2u32)?;
49*bb4ee6a4SAndroid Build Coastguard Worker     mem_node.set_prop("base", guest_addr.offset())
50*bb4ee6a4SAndroid Build Coastguard Worker }
51*bb4ee6a4SAndroid Build Coastguard Worker 
52*bb4ee6a4SAndroid Build Coastguard Worker impl VmAArch64 for GunyahVm {
get_hypervisor(&self) -> &dyn Hypervisor53*bb4ee6a4SAndroid Build Coastguard Worker     fn get_hypervisor(&self) -> &dyn Hypervisor {
54*bb4ee6a4SAndroid Build Coastguard Worker         &self.gh
55*bb4ee6a4SAndroid Build Coastguard Worker     }
56*bb4ee6a4SAndroid Build Coastguard Worker 
load_protected_vm_firmware( &mut self, fw_addr: GuestAddress, fw_max_size: u64, ) -> Result<()>57*bb4ee6a4SAndroid Build Coastguard Worker     fn load_protected_vm_firmware(
58*bb4ee6a4SAndroid Build Coastguard Worker         &mut self,
59*bb4ee6a4SAndroid Build Coastguard Worker         fw_addr: GuestAddress,
60*bb4ee6a4SAndroid Build Coastguard Worker         fw_max_size: u64,
61*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
62*bb4ee6a4SAndroid Build Coastguard Worker         self.set_protected_vm_firmware_ipa(fw_addr, fw_max_size)
63*bb4ee6a4SAndroid Build Coastguard Worker     }
64*bb4ee6a4SAndroid Build Coastguard Worker 
create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuAArch64>>65*bb4ee6a4SAndroid Build Coastguard Worker     fn create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuAArch64>> {
66*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Box::new(GunyahVm::create_vcpu(self, id)?))
67*bb4ee6a4SAndroid Build Coastguard Worker     }
68*bb4ee6a4SAndroid Build Coastguard Worker 
create_fdt(&self, fdt: &mut Fdt, phandles: &BTreeMap<&str, u32>) -> cros_fdt::Result<()>69*bb4ee6a4SAndroid Build Coastguard Worker     fn create_fdt(&self, fdt: &mut Fdt, phandles: &BTreeMap<&str, u32>) -> cros_fdt::Result<()> {
70*bb4ee6a4SAndroid Build Coastguard Worker         let top_node = fdt.root_mut().subnode_mut("gunyah-vm-config")?;
71*bb4ee6a4SAndroid Build Coastguard Worker 
72*bb4ee6a4SAndroid Build Coastguard Worker         top_node.set_prop("image-name", "crosvm-vm")?;
73*bb4ee6a4SAndroid Build Coastguard Worker         top_node.set_prop("os-type", "linux")?;
74*bb4ee6a4SAndroid Build Coastguard Worker 
75*bb4ee6a4SAndroid Build Coastguard Worker         let memory_node = top_node.subnode_mut("memory")?;
76*bb4ee6a4SAndroid Build Coastguard Worker         memory_node.set_prop("#address-cells", 2u32)?;
77*bb4ee6a4SAndroid Build Coastguard Worker         memory_node.set_prop("#size-cells", 2u32)?;
78*bb4ee6a4SAndroid Build Coastguard Worker 
79*bb4ee6a4SAndroid Build Coastguard Worker         let mut base_set = false;
80*bb4ee6a4SAndroid Build Coastguard Worker         let mut firmware_set = false;
81*bb4ee6a4SAndroid Build Coastguard Worker         for region in self.guest_mem.regions() {
82*bb4ee6a4SAndroid Build Coastguard Worker             match region.options.purpose {
83*bb4ee6a4SAndroid Build Coastguard Worker                 MemoryRegionPurpose::GuestMemoryRegion => {
84*bb4ee6a4SAndroid Build Coastguard Worker                     // Assume first GuestMemoryRegion contains the payload
85*bb4ee6a4SAndroid Build Coastguard Worker                     if !base_set {
86*bb4ee6a4SAndroid Build Coastguard Worker                         base_set = true;
87*bb4ee6a4SAndroid Build Coastguard Worker                         memory_node.set_prop("base-address", region.guest_addr.offset())?;
88*bb4ee6a4SAndroid Build Coastguard Worker                     }
89*bb4ee6a4SAndroid Build Coastguard Worker                 }
90*bb4ee6a4SAndroid Build Coastguard Worker                 MemoryRegionPurpose::ProtectedFirmwareRegion => {
91*bb4ee6a4SAndroid Build Coastguard Worker                     if firmware_set {
92*bb4ee6a4SAndroid Build Coastguard Worker                         // Should only have one protected firmware memory region.
93*bb4ee6a4SAndroid Build Coastguard Worker                         error!("Multiple ProtectedFirmwareRegions unexpected.");
94*bb4ee6a4SAndroid Build Coastguard Worker                         unreachable!()
95*bb4ee6a4SAndroid Build Coastguard Worker                     }
96*bb4ee6a4SAndroid Build Coastguard Worker                     firmware_set = true;
97*bb4ee6a4SAndroid Build Coastguard Worker                     memory_node.set_prop("firmware-address", region.guest_addr.offset())?;
98*bb4ee6a4SAndroid Build Coastguard Worker                 }
99*bb4ee6a4SAndroid Build Coastguard Worker                 _ => {}
100*bb4ee6a4SAndroid Build Coastguard Worker             }
101*bb4ee6a4SAndroid Build Coastguard Worker         }
102*bb4ee6a4SAndroid Build Coastguard Worker 
103*bb4ee6a4SAndroid Build Coastguard Worker         let interrupts_node = top_node.subnode_mut("interrupts")?;
104*bb4ee6a4SAndroid Build Coastguard Worker         interrupts_node.set_prop("config", *phandles.get("intc").unwrap())?;
105*bb4ee6a4SAndroid Build Coastguard Worker 
106*bb4ee6a4SAndroid Build Coastguard Worker         let vcpus_node = top_node.subnode_mut("vcpus")?;
107*bb4ee6a4SAndroid Build Coastguard Worker         vcpus_node.set_prop("affinity", "proxy")?;
108*bb4ee6a4SAndroid Build Coastguard Worker 
109*bb4ee6a4SAndroid Build Coastguard Worker         let vdev_node = top_node.subnode_mut("vdevices")?;
110*bb4ee6a4SAndroid Build Coastguard Worker         vdev_node.set_prop("generate", "/hypervisor")?;
111*bb4ee6a4SAndroid Build Coastguard Worker 
112*bb4ee6a4SAndroid Build Coastguard Worker         for irq in self.routes.lock().iter() {
113*bb4ee6a4SAndroid Build Coastguard Worker             let bell_name = format!("bell-{:x}", irq.irq);
114*bb4ee6a4SAndroid Build Coastguard Worker             let bell_node = vdev_node.subnode_mut(&bell_name)?;
115*bb4ee6a4SAndroid Build Coastguard Worker             bell_node.set_prop("vdevice-type", "doorbell")?;
116*bb4ee6a4SAndroid Build Coastguard Worker             let path_name = format!("/hypervisor/bell-{:x}", irq.irq);
117*bb4ee6a4SAndroid Build Coastguard Worker             bell_node.set_prop("generate", path_name)?;
118*bb4ee6a4SAndroid Build Coastguard Worker             bell_node.set_prop("label", irq.irq)?;
119*bb4ee6a4SAndroid Build Coastguard Worker             bell_node.set_prop("peer-default", ())?;
120*bb4ee6a4SAndroid Build Coastguard Worker             bell_node.set_prop("source-can-clear", ())?;
121*bb4ee6a4SAndroid Build Coastguard Worker 
122*bb4ee6a4SAndroid Build Coastguard Worker             let interrupt_type = if irq.level {
123*bb4ee6a4SAndroid Build Coastguard Worker                 IRQ_TYPE_LEVEL_HIGH
124*bb4ee6a4SAndroid Build Coastguard Worker             } else {
125*bb4ee6a4SAndroid Build Coastguard Worker                 IRQ_TYPE_EDGE_RISING
126*bb4ee6a4SAndroid Build Coastguard Worker             };
127*bb4ee6a4SAndroid Build Coastguard Worker             let interrupts = [GIC_FDT_IRQ_TYPE_SPI, irq.irq, interrupt_type];
128*bb4ee6a4SAndroid Build Coastguard Worker             bell_node.set_prop("interrupts", &interrupts)?;
129*bb4ee6a4SAndroid Build Coastguard Worker         }
130*bb4ee6a4SAndroid Build Coastguard Worker 
131*bb4ee6a4SAndroid Build Coastguard Worker         let mut base_set = false;
132*bb4ee6a4SAndroid Build Coastguard Worker         for region in self.guest_mem.regions() {
133*bb4ee6a4SAndroid Build Coastguard Worker             let create_shm_node = match region.options.purpose {
134*bb4ee6a4SAndroid Build Coastguard Worker                 MemoryRegionPurpose::GuestMemoryRegion => {
135*bb4ee6a4SAndroid Build Coastguard Worker                     // Assume first GuestMemoryRegion contains the payload
136*bb4ee6a4SAndroid Build Coastguard Worker                     // This memory region is described by the "base-address" property
137*bb4ee6a4SAndroid Build Coastguard Worker                     // and doesn't get re-described as a separate shm node.
138*bb4ee6a4SAndroid Build Coastguard Worker                     let ret = base_set;
139*bb4ee6a4SAndroid Build Coastguard Worker                     base_set = true;
140*bb4ee6a4SAndroid Build Coastguard Worker                     ret
141*bb4ee6a4SAndroid Build Coastguard Worker                 }
142*bb4ee6a4SAndroid Build Coastguard Worker                 // Described by the "firmware-address" property
143*bb4ee6a4SAndroid Build Coastguard Worker                 MemoryRegionPurpose::ProtectedFirmwareRegion => false,
144*bb4ee6a4SAndroid Build Coastguard Worker                 MemoryRegionPurpose::StaticSwiotlbRegion => true,
145*bb4ee6a4SAndroid Build Coastguard Worker             };
146*bb4ee6a4SAndroid Build Coastguard Worker 
147*bb4ee6a4SAndroid Build Coastguard Worker             if create_shm_node {
148*bb4ee6a4SAndroid Build Coastguard Worker                 fdt_create_shm_device(
149*bb4ee6a4SAndroid Build Coastguard Worker                     vdev_node,
150*bb4ee6a4SAndroid Build Coastguard Worker                     region.index.try_into().unwrap(),
151*bb4ee6a4SAndroid Build Coastguard Worker                     region.guest_addr,
152*bb4ee6a4SAndroid Build Coastguard Worker                 )?;
153*bb4ee6a4SAndroid Build Coastguard Worker             }
154*bb4ee6a4SAndroid Build Coastguard Worker         }
155*bb4ee6a4SAndroid Build Coastguard Worker 
156*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
157*bb4ee6a4SAndroid Build Coastguard Worker     }
158*bb4ee6a4SAndroid Build Coastguard Worker 
init_arch( &self, payload_entry_address: GuestAddress, fdt_address: GuestAddress, fdt_size: usize, ) -> Result<()>159*bb4ee6a4SAndroid Build Coastguard Worker     fn init_arch(
160*bb4ee6a4SAndroid Build Coastguard Worker         &self,
161*bb4ee6a4SAndroid Build Coastguard Worker         payload_entry_address: GuestAddress,
162*bb4ee6a4SAndroid Build Coastguard Worker         fdt_address: GuestAddress,
163*bb4ee6a4SAndroid Build Coastguard Worker         fdt_size: usize,
164*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
165*bb4ee6a4SAndroid Build Coastguard Worker         // Gunyah initializes the PC to be the payload entry (except for protected VMs)
166*bb4ee6a4SAndroid Build Coastguard Worker         // and assumes that the image is loaded at the beginning of the "primary"
167*bb4ee6a4SAndroid Build Coastguard Worker         // memory parcel (region). This parcel contains both DTB and kernel Image, so
168*bb4ee6a4SAndroid Build Coastguard Worker         // make sure that DTB and payload are in the same memory region and that
169*bb4ee6a4SAndroid Build Coastguard Worker         // payload is at the start of that region.
170*bb4ee6a4SAndroid Build Coastguard Worker 
171*bb4ee6a4SAndroid Build Coastguard Worker         let (dtb_mapping, _, dtb_obj_offset) = self
172*bb4ee6a4SAndroid Build Coastguard Worker             .guest_mem
173*bb4ee6a4SAndroid Build Coastguard Worker             .find_region(fdt_address)
174*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(|_| Error::new(ENOENT))?;
175*bb4ee6a4SAndroid Build Coastguard Worker         let (payload_mapping, payload_offset, payload_obj_offset) = self
176*bb4ee6a4SAndroid Build Coastguard Worker             .guest_mem
177*bb4ee6a4SAndroid Build Coastguard Worker             .find_region(payload_entry_address)
178*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(|_| Error::new(ENOENT))?;
179*bb4ee6a4SAndroid Build Coastguard Worker 
180*bb4ee6a4SAndroid Build Coastguard Worker         if !std::ptr::eq(dtb_mapping, payload_mapping) || dtb_obj_offset != payload_obj_offset {
181*bb4ee6a4SAndroid Build Coastguard Worker             panic!("DTB and payload are not part of same memory region.");
182*bb4ee6a4SAndroid Build Coastguard Worker         }
183*bb4ee6a4SAndroid Build Coastguard Worker 
184*bb4ee6a4SAndroid Build Coastguard Worker         if payload_offset != 0 {
185*bb4ee6a4SAndroid Build Coastguard Worker             panic!("Payload offset must be zero");
186*bb4ee6a4SAndroid Build Coastguard Worker         }
187*bb4ee6a4SAndroid Build Coastguard Worker 
188*bb4ee6a4SAndroid Build Coastguard Worker         self.set_dtb_config(fdt_address, fdt_size)?;
189*bb4ee6a4SAndroid Build Coastguard Worker 
190*bb4ee6a4SAndroid Build Coastguard Worker         self.start()?;
191*bb4ee6a4SAndroid Build Coastguard Worker 
192*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
193*bb4ee6a4SAndroid Build Coastguard Worker     }
194*bb4ee6a4SAndroid Build Coastguard Worker }
195*bb4ee6a4SAndroid Build Coastguard Worker 
196*bb4ee6a4SAndroid Build Coastguard Worker impl VcpuAArch64 for GunyahVcpu {
init(&self, _features: &[crate::VcpuFeature]) -> Result<()>197*bb4ee6a4SAndroid Build Coastguard Worker     fn init(&self, _features: &[crate::VcpuFeature]) -> Result<()> {
198*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
199*bb4ee6a4SAndroid Build Coastguard Worker     }
200*bb4ee6a4SAndroid Build Coastguard Worker 
init_pmu(&self, _irq: u64) -> Result<()>201*bb4ee6a4SAndroid Build Coastguard Worker     fn init_pmu(&self, _irq: u64) -> Result<()> {
202*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
203*bb4ee6a4SAndroid Build Coastguard Worker     }
204*bb4ee6a4SAndroid Build Coastguard Worker 
has_pvtime_support(&self) -> bool205*bb4ee6a4SAndroid Build Coastguard Worker     fn has_pvtime_support(&self) -> bool {
206*bb4ee6a4SAndroid Build Coastguard Worker         false
207*bb4ee6a4SAndroid Build Coastguard Worker     }
208*bb4ee6a4SAndroid Build Coastguard Worker 
init_pvtime(&self, _pvtime_ipa: u64) -> Result<()>209*bb4ee6a4SAndroid Build Coastguard Worker     fn init_pvtime(&self, _pvtime_ipa: u64) -> Result<()> {
210*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
211*bb4ee6a4SAndroid Build Coastguard Worker     }
212*bb4ee6a4SAndroid Build Coastguard Worker 
set_one_reg(&self, _reg_id: VcpuRegAArch64, _data: u64) -> Result<()>213*bb4ee6a4SAndroid Build Coastguard Worker     fn set_one_reg(&self, _reg_id: VcpuRegAArch64, _data: u64) -> Result<()> {
214*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
215*bb4ee6a4SAndroid Build Coastguard Worker     }
216*bb4ee6a4SAndroid Build Coastguard Worker 
get_one_reg(&self, _reg_id: VcpuRegAArch64) -> Result<u64>217*bb4ee6a4SAndroid Build Coastguard Worker     fn get_one_reg(&self, _reg_id: VcpuRegAArch64) -> Result<u64> {
218*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
219*bb4ee6a4SAndroid Build Coastguard Worker     }
220*bb4ee6a4SAndroid Build Coastguard Worker 
set_vector_reg(&self, _reg_num: u8, _data: u128) -> Result<()>221*bb4ee6a4SAndroid Build Coastguard Worker     fn set_vector_reg(&self, _reg_num: u8, _data: u128) -> Result<()> {
222*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
223*bb4ee6a4SAndroid Build Coastguard Worker     }
224*bb4ee6a4SAndroid Build Coastguard Worker 
get_vector_reg(&self, _reg_num: u8) -> Result<u128>225*bb4ee6a4SAndroid Build Coastguard Worker     fn get_vector_reg(&self, _reg_num: u8) -> Result<u128> {
226*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
227*bb4ee6a4SAndroid Build Coastguard Worker     }
228*bb4ee6a4SAndroid Build Coastguard Worker 
get_psci_version(&self) -> Result<PsciVersion>229*bb4ee6a4SAndroid Build Coastguard Worker     fn get_psci_version(&self) -> Result<PsciVersion> {
230*bb4ee6a4SAndroid Build Coastguard Worker         Ok(PSCI_0_2)
231*bb4ee6a4SAndroid Build Coastguard Worker     }
232*bb4ee6a4SAndroid Build Coastguard Worker 
set_guest_debug(&self, _addrs: &[GuestAddress], _enable_singlestep: bool) -> Result<()>233*bb4ee6a4SAndroid Build Coastguard Worker     fn set_guest_debug(&self, _addrs: &[GuestAddress], _enable_singlestep: bool) -> Result<()> {
234*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
235*bb4ee6a4SAndroid Build Coastguard Worker     }
236*bb4ee6a4SAndroid Build Coastguard Worker 
get_max_hw_bps(&self) -> Result<usize>237*bb4ee6a4SAndroid Build Coastguard Worker     fn get_max_hw_bps(&self) -> Result<usize> {
238*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
239*bb4ee6a4SAndroid Build Coastguard Worker     }
240*bb4ee6a4SAndroid Build Coastguard Worker 
get_system_regs(&self) -> Result<BTreeMap<AArch64SysRegId, u64>>241*bb4ee6a4SAndroid Build Coastguard Worker     fn get_system_regs(&self) -> Result<BTreeMap<AArch64SysRegId, u64>> {
242*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
243*bb4ee6a4SAndroid Build Coastguard Worker     }
244*bb4ee6a4SAndroid Build Coastguard Worker 
get_cache_info(&self) -> Result<BTreeMap<u8, u64>>245*bb4ee6a4SAndroid Build Coastguard Worker     fn get_cache_info(&self) -> Result<BTreeMap<u8, u64>> {
246*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
247*bb4ee6a4SAndroid Build Coastguard Worker     }
248*bb4ee6a4SAndroid Build Coastguard Worker 
set_cache_info(&self, _cache_info: BTreeMap<u8, u64>) -> Result<()>249*bb4ee6a4SAndroid Build Coastguard Worker     fn set_cache_info(&self, _cache_info: BTreeMap<u8, u64>) -> Result<()> {
250*bb4ee6a4SAndroid Build Coastguard Worker         Err(Error::new(ENOTSUP))
251*bb4ee6a4SAndroid Build Coastguard Worker     }
252*bb4ee6a4SAndroid Build Coastguard Worker 
hypervisor_specific_snapshot(&self) -> anyhow::Result<serde_json::Value>253*bb4ee6a4SAndroid Build Coastguard Worker     fn hypervisor_specific_snapshot(&self) -> anyhow::Result<serde_json::Value> {
254*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
255*bb4ee6a4SAndroid Build Coastguard Worker     }
256*bb4ee6a4SAndroid Build Coastguard Worker 
hypervisor_specific_restore(&self, _data: serde_json::Value) -> anyhow::Result<()>257*bb4ee6a4SAndroid Build Coastguard Worker     fn hypervisor_specific_restore(&self, _data: serde_json::Value) -> anyhow::Result<()> {
258*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
259*bb4ee6a4SAndroid Build Coastguard Worker     }
260*bb4ee6a4SAndroid Build Coastguard Worker }
261