Alioth Code Coverage

vm_aarch64.rs0.00%

1// Copyright 2024 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::os::fd::OwnedFd;
16
17use crate::hv::kvm::Result;
18use crate::hv::kvm::device::KvmDevice;
19use crate::hv::kvm::vm::KvmVm;
20use crate::hv::{GicV2, GicV2m, GicV3, Its, Kvm, VmConfig};
21use crate::sys::kvm::{
22 KvmDevArmVgicCtrl, KvmDevArmVgicGrp, KvmDevType, KvmVgicAddrType, KvmVgicV3RedistRegion,
23 KvmVmType,
24};
25
26pub fn translate_msi_addr(addr_lo: u32, addr_hi: u32) -> (u32, u32) {
27 (addr_lo, addr_hi)
28}
29
30#[derive(Debug)]
31pub struct KvmGicV2m;
32
33impl GicV2m for KvmGicV2m {
34 fn init(&self) -> Result<()> {
35 unreachable!()
36 }
37}
38
39#[derive(Debug)]
40pub struct KvmGicV2 {
41 dev: KvmDevice,
42}
43
44impl KvmGicV2 {
45 pub fn new(vm: &KvmVm, distributor_base: u64, cpu_interface_base: u64) -> Result<Self> {
46 let dev = KvmDevice::new(vm, KvmDevType::ARM_VGIC_V2)?;
47 let gic = KvmGicV2 { dev };
48 gic.dev.set_attr(
49 KvmDevArmVgicGrp::ADDR.raw(),
50 KvmVgicAddrType::DIST_V2.raw(),
51 &distributor_base,
52 )?;
53 gic.dev.set_attr(
54 KvmDevArmVgicGrp::ADDR.raw(),
55 KvmVgicAddrType::CPU_V2.raw(),
56 &cpu_interface_base,
57 )?;
58 Ok(gic)
59 }
60}
61
62impl GicV2 for KvmGicV2 {
63 fn init(&self) -> Result<()> {
64 self.dev.set_attr(
65 KvmDevArmVgicGrp::CTL.raw(),
66 KvmDevArmVgicCtrl::INIT.raw(),
67 &(),
68 )?;
69 Ok(())
70 }
71
72 fn get_dist_reg(&self, cpu_index: u32, offset: u16) -> Result<u32> {
73 let attr = ((cpu_index as u64) << 32) | (offset as u64);
74 let v = self.dev.get_attr(KvmDevArmVgicGrp::DIST_REGS.raw(), attr)?;
75 Ok(v)
76 }
77
78 fn set_dist_reg(&self, cpu_index: u32, offset: u16, val: u32) -> Result<()> {
79 let attr = ((cpu_index as u64) << 32) | (offset as u64);
80 self.dev
81 .set_attr(KvmDevArmVgicGrp::DIST_REGS.raw(), attr, &val)?;
82 Ok(())
83 }
84
85 fn get_cpu_reg(&self, cpu_index: u32, offset: u16) -> Result<u32> {
86 let attr = ((cpu_index as u64) << 32) | (offset as u64);
87 let v = self.dev.get_attr(KvmDevArmVgicGrp::CPU_REGS.raw(), attr)?;
88 Ok(v)
89 }
90
91 fn set_cpu_reg(&self, cpu_index: u32, offset: u16, val: u32) -> Result<()> {
92 let attr = ((cpu_index as u64) << 32) | (offset as u64);
93 self.dev
94 .set_attr(KvmDevArmVgicGrp::CPU_REGS.raw(), attr, &val)?;
95 Ok(())
96 }
97
98 fn get_num_irqs(&self) -> Result<u32> {
99 let n = self.dev.get_attr(KvmDevArmVgicGrp::NR_IRQS.raw(), 0)?;
100 Ok(n)
101 }
102
103 fn set_num_irqs(&self, val: u32) -> Result<()> {
104 self.dev
105 .set_attr(KvmDevArmVgicGrp::NR_IRQS.raw(), 0, &val)?;
106 Ok(())
107 }
108}
109
110#[derive(Debug)]
111pub struct KvmGicV3 {
112 dev: KvmDevice,
113}
114
115impl KvmGicV3 {
116 pub fn new(
117 vm: &KvmVm,
118 distributor_base: u64,
119 redistributor_base: u64,
120 redistributor_count: u16,
121 ) -> Result<Self> {
122 let dev = KvmDevice::new(vm, KvmDevType::ARM_VGIC_V3)?;
123 dev.set_attr(
124 KvmDevArmVgicGrp::ADDR.raw(),
125 KvmVgicAddrType::DIST_V3.raw(),
126 &distributor_base,
127 )?;
128 let mut redist_region = KvmVgicV3RedistRegion(redistributor_base);
129 redist_region.set_count(redistributor_count as u64);
130 dev.set_attr(
131 KvmDevArmVgicGrp::ADDR.raw(),
132 KvmVgicAddrType::REDIST_REGION_V3.raw(),
133 &redist_region,
134 )?;
135 Ok(KvmGicV3 { dev })
136 }
137}
138
139impl GicV3 for KvmGicV3 {
140 fn init(&self) -> Result<()> {
141 self.dev.set_attr(
142 KvmDevArmVgicGrp::CTL.raw(),
143 KvmDevArmVgicCtrl::INIT.raw(),
144 &(),
145 )?;
146 Ok(())
147 }
148}
149
150#[derive(Debug)]
151pub struct KvmIts {
152 dev: KvmDevice,
153}
154
155impl KvmIts {
156 pub fn new(vm: &KvmVm, base: u64) -> Result<Self> {
157 let dev = KvmDevice::new(vm, KvmDevType::ARM_ITS)?;
158 dev.set_attr(
159 KvmDevArmVgicGrp::ADDR.raw(),
160 KvmVgicAddrType::ITS.raw(),
161 &base,
162 )?;
163 Ok(KvmIts { dev })
164 }
165}
166
167impl Its for KvmIts {
168 fn init(&self) -> Result<()> {
169 self.dev.set_attr(
170 KvmDevArmVgicGrp::CTL.raw(),
171 KvmDevArmVgicCtrl::INIT.raw(),
172 &(),
173 )?;
174 Ok(())
175 }
176}
177
178#[derive(Debug)]
179pub struct VmArch;
180
181impl VmArch {
182 pub fn new(_kvm: &Kvm, _config: &VmConfig) -> Result<Self> {
183 Ok(VmArch)
184 }
185}
186
187impl KvmVm {
188 pub fn determine_vm_type(_config: &VmConfig) -> KvmVmType {
189 KvmVmType(0)
190 }
191
192 pub fn create_guest_memfd(_config: &VmConfig, _fd: &OwnedFd) -> Result<Option<OwnedFd>> {
193 Ok(None)
194 }
195
196 pub fn init(&self, _config: &VmConfig) -> Result<()> {
197 Ok(())
198 }
199}
200