vm_aarch64.rs0.00%
1
// Copyright 2024 Google LLC2
//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 at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// 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 and13
// limitations under the License.14
15
use std::os::fd::OwnedFd;16
17
use crate::hv::kvm::Result;18
use crate::hv::kvm::device::KvmDevice;19
use crate::hv::kvm::vm::KvmVm;20
use crate::hv::{GicV2, GicV2m, GicV3, Its, Kvm, VmConfig};21
use crate::sys::kvm::{22
KvmDevArmVgicCtrl, KvmDevArmVgicGrp, KvmDevType, KvmVgicAddrType, KvmVgicV3RedistRegion,23
KvmVmType,24
};25
26
pub fn translate_msi_addr(addr_lo: u32, addr_hi: u32) -> (u32, u32) {27
(addr_lo, addr_hi)28
}29
30
#[derive(Debug)]31
pub struct KvmGicV2m;32
33
impl GicV2m for KvmGicV2m {34
fn init(&self) -> Result<()> {35
unreachable!()36
}37
}38
39
#[derive(Debug)]40
pub struct KvmGicV2 {41
dev: KvmDevice,42
}43
44
impl 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
62
impl 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.dev81
.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.dev94
.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.dev105
.set_attr(KvmDevArmVgicGrp::NR_IRQS.raw(), 0, &val)?;106
Ok(())107
}108
}109
110
#[derive(Debug)]111
pub struct KvmGicV3 {112
dev: KvmDevice,113
}114
115
impl 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
139
impl 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)]151
pub struct KvmIts {152
dev: KvmDevice,153
}154
155
impl 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
167
impl 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)]179
pub struct VmArch;180
181
impl VmArch {182
pub fn new(_kvm: &Kvm, _config: &VmConfig) -> Result<Self> {183
Ok(VmArch)184
}185
}186
187
impl 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