mirror of
https://github.com/google/alioth.git
synced 2024-11-28 09:26:21 +00:00
feat: skeleton for running KVM VMs on aarch64
Signed-off-by: Changyuan Lyu <changyuanl@google.com>
This commit is contained in:
parent
6368c4fb38
commit
038329b721
24 changed files with 339 additions and 43 deletions
|
@ -88,6 +88,7 @@ struct RunArgs {
|
|||
#[arg(short, long)]
|
||||
kernel: Option<PathBuf>,
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[arg(long)]
|
||||
pvh: Option<PathBuf>,
|
||||
|
||||
|
@ -198,6 +199,7 @@ fn main_run(args: RunArgs) -> Result<(), Error> {
|
|||
.add_fw_cfg(params.into_iter())
|
||||
.context(error::CreateDevice)?;
|
||||
let mut dev = fw_cfg.lock();
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
if let Some(kernel) = &args.kernel {
|
||||
dev.add_kernel_data(File::open(kernel).with_context(|_| error::OpenFile {
|
||||
path: kernel.to_owned(),
|
||||
|
@ -267,14 +269,19 @@ fn main_run(args: RunArgs) -> Result<(), Error> {
|
|||
initramfs: args.initramfs,
|
||||
cmd_line: args.cmd_line,
|
||||
})
|
||||
} else if let Some(pvh_kernel) = args.pvh {
|
||||
Some(Payload {
|
||||
executable: pvh_kernel,
|
||||
exec_type: ExecType::Pvh,
|
||||
initramfs: args.initramfs,
|
||||
cmd_line: args.cmd_line,
|
||||
})
|
||||
} else {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
if let Some(pvh_kernel) = args.pvh {
|
||||
Some(Payload {
|
||||
executable: pvh_kernel,
|
||||
exec_type: ExecType::Pvh,
|
||||
initramfs: args.initramfs,
|
||||
cmd_line: args.cmd_line,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
None
|
||||
};
|
||||
if let Some(payload) = payload {
|
||||
|
|
|
@ -12,4 +12,5 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub mod layout;
|
||||
pub mod reg;
|
||||
|
|
19
alioth/src/arch/aarch64/layout.rs
Normal file
19
alioth/src/arch/aarch64/layout.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub const MMIO_32_START: usize = 0x1000_0000; // 256 MiB
|
||||
pub const MMIO_32_END: usize = 0x3000_0000; // 768 MiB, size = 512 MiB
|
||||
pub const PCIE_CONFIG_START: usize = 0x3000_0000; // 768 MiB
|
||||
pub const MEM_64_START: usize = 0x1_0000_0000; // 4GiB
|
||||
pub const PAGE_SIZE: usize = 0x1000; // 4KiB
|
63
alioth/src/board/aarch64.rs
Normal file
63
alioth/src/board/aarch64.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::board::{Board, BoardConfig, Result, VcpuGuard};
|
||||
use crate::hv::{Hypervisor, Vm};
|
||||
use crate::loader::InitState;
|
||||
use crate::mem::mapped::ArcMemPages;
|
||||
|
||||
pub struct ArchBoard {}
|
||||
|
||||
impl ArchBoard {
|
||||
pub fn new<H: Hypervisor>(_hv: &H, _config: &BoardConfig) -> Result<Self> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Board<V>
|
||||
where
|
||||
V: Vm,
|
||||
{
|
||||
pub fn setup_firmware(&self, _fw: &mut ArcMemPages) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn init_ap(&self, _id: u32, _vcpu: &mut V::Vcpu, _vcpus: &VcpuGuard) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn init_boot_vcpu(&self, _vcpu: &mut V::Vcpu, _init_state: &InitState) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn init_vcpu(&self, _id: u32, _vcpu: &mut V::Vcpu) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn create_ram(&self) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn coco_init(&self, _id: u32) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn coco_finalize(&self, _id: u32, _vcpus: &VcpuGuard) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn create_firmware_data(&self, _init_state: &InitState) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
||||
|
||||
|
|
|
@ -12,11 +12,16 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod acpi;
|
||||
|
||||
use core::fmt;
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::io::{ErrorKind, Read, Result, Seek, SeekFrom};
|
||||
use std::mem::{size_of, size_of_val};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::mem::size_of;
|
||||
use std::mem::size_of_val;
|
||||
use std::os::unix::fs::FileExt;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
@ -28,17 +33,19 @@ use serde::de::{self, MapAccess, Visitor};
|
|||
use serde::{Deserialize, Deserializer};
|
||||
use zerocopy::{AsBytes, FromBytes, FromZeroes};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::firmware::acpi::AcpiTable;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::loader::linux::bootparams::{
|
||||
BootE820Entry, BootParams, E820_ACPI, E820_PMEM, E820_RAM, E820_RESERVED,
|
||||
};
|
||||
use crate::mem;
|
||||
use crate::mem::emulated::Mmio;
|
||||
use crate::mem::mapped::RamBus;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::mem::{MemRegionEntry, MemRegionType};
|
||||
|
||||
pub mod acpi;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use acpi::create_acpi_loader;
|
||||
|
||||
pub const PORT_SELECTOR: u16 = 0x510;
|
||||
|
@ -238,6 +245,7 @@ impl FwCfg {
|
|||
self.get_file_dir_mut()[0..4].copy_from_slice(header.as_bytes());
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub(crate) fn add_e820(&mut self, mem_regions: &[(usize, MemRegionEntry)]) -> Result<()> {
|
||||
let mut bytes = vec![];
|
||||
for (addr, region) in mem_regions.iter() {
|
||||
|
@ -262,6 +270,7 @@ impl FwCfg {
|
|||
self.add_item(item)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub(crate) fn add_acpi(&mut self, acpi_table: AcpiTable) -> Result<()> {
|
||||
let [table_loader, acpi_rsdp, apci_tables] = create_acpi_loader(acpi_table);
|
||||
self.add_item(table_loader)?;
|
||||
|
@ -269,6 +278,7 @@ impl FwCfg {
|
|||
self.add_item(apci_tables)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn add_kernel_data(&mut self, file: File) -> Result<()> {
|
||||
let mut buffer = vec![0u8; size_of::<BootParams>()];
|
||||
file.read_exact_at(buffer.as_bytes_mut(), 0)?;
|
||||
|
|
|
@ -13,4 +13,5 @@
|
|||
// limitations under the License.
|
||||
|
||||
#[path = "acpi/acpi.rs"]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod acpi;
|
||||
|
|
|
@ -33,7 +33,7 @@ use crate::arch::cpuid::Cpuid;
|
|||
use crate::arch::reg::Reg;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::reg::{DtReg, DtRegVal, SReg, SegReg, SegRegVal};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::sev::{SevPolicy, SnpPageType, SnpPolicy};
|
||||
|
||||
#[trace_error]
|
||||
|
@ -212,8 +212,10 @@ pub trait IrqFd: Debug + Send + Sync + AsFd + 'static {
|
|||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub enum Coco {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[serde(alias = "sev")]
|
||||
AmdSev { policy: SevPolicy },
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[serde(alias = "snp", alias = "sev-snp")]
|
||||
AmdSnp { policy: SnpPolicy },
|
||||
}
|
||||
|
@ -226,10 +228,12 @@ pub struct VmConfig {
|
|||
pub trait Vm {
|
||||
type Vcpu: Vcpu;
|
||||
type Memory: VmMemory;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
type IntxSender: IntxSender + Send + Sync;
|
||||
type MsiSender: MsiSender;
|
||||
type IoeventFdRegistry: IoeventFdRegistry;
|
||||
fn create_vcpu(&self, id: u32) -> Result<Self::Vcpu, Error>;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn create_intx_sender(&self, pin: u8) -> Result<Self::IntxSender, Error>;
|
||||
fn create_msi_sender(&self) -> Result<Self::MsiSender>;
|
||||
fn create_vm_memory(&mut self) -> Result<Self::Memory, Error>;
|
||||
|
|
42
alioth/src/hv/kvm/aarch64.rs
Normal file
42
alioth/src/hv/kvm/aarch64.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::os::fd::OwnedFd;
|
||||
|
||||
use crate::hv::kvm::bindings::KvmVmType;
|
||||
use crate::hv::kvm::vm::{KvmVm, VmArch};
|
||||
use crate::hv::kvm::Kvm;
|
||||
use crate::hv::{Result, VmConfig};
|
||||
|
||||
impl Kvm {
|
||||
pub(super) fn determine_vm_type(_config: &VmConfig) -> Result<KvmVmType> {
|
||||
Ok(KvmVmType(0))
|
||||
}
|
||||
|
||||
pub(super) fn create_guest_memfd(
|
||||
&self,
|
||||
_config: &VmConfig,
|
||||
_vm_fd: &OwnedFd,
|
||||
) -> Result<Option<OwnedFd>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub(super) fn create_vm_arch(&self, _config: &VmConfig) -> Result<VmArch> {
|
||||
Ok(VmArch {})
|
||||
}
|
||||
|
||||
pub(super) fn vm_init_arch(&self, _config: &VmConfig, _kvm_vm: &KvmVm) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ use crate::c_enum;
|
|||
pub const KVMIO: u8 = 0xAE;
|
||||
pub const KVM_API_VERSION: i32 = 12;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
c_enum! {
|
||||
pub struct KvmVmType(u64);
|
||||
{
|
||||
|
@ -32,6 +33,10 @@ c_enum! {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub struct KvmVmType(#[allow(dead_code)] pub u64);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub const KVM_MAX_CPUID_ENTRIES: usize = 256;
|
||||
|
||||
bitflags! {
|
||||
|
@ -54,6 +59,7 @@ pub struct KvmCpuidEntry2 {
|
|||
pub padding: [u32; 3],
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KvmCpuid2<const N: usize> {
|
||||
|
@ -119,6 +125,7 @@ pub struct KvmCreateGuestMemfd {
|
|||
pub reserved: [u64; 6],
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
pub struct KvmRegs {
|
||||
|
@ -314,6 +321,7 @@ pub struct KvmIrqfd {
|
|||
pub const KVM_IRQ_ROUTING_IRQCHIP: u32 = 1;
|
||||
pub const KVM_IRQ_ROUTING_MSI: u32 = 2;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub const KVM_IRQCHIP_IOAPIC: u32 = 2;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
|
@ -462,6 +470,7 @@ pub struct KvmEncRegion {
|
|||
pub size: u64,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KvmEnableCap {
|
||||
|
|
|
@ -13,15 +13,19 @@
|
|||
// limitations under the License.
|
||||
|
||||
use crate::hv::kvm::bindings::{
|
||||
KvmCap, KvmCpuid2, KvmCreateGuestMemfd, KvmEnableCap, KvmEncRegion, KvmIoEventFd,
|
||||
KvmIrqRouting, KvmIrqfd, KvmMemoryAttributes, KvmMsi, KvmRegs, KvmSregs, KvmSregs2,
|
||||
KvmCap, KvmEncRegion, KvmIoEventFd, KvmIrqRouting, KvmIrqfd, KvmMemoryAttributes, KvmMsi,
|
||||
KvmUserspaceMemoryRegion, KvmUserspaceMemoryRegion2, KvmVmType, KVMIO,
|
||||
};
|
||||
use crate::utils::ioctls::{ioctl_io, ioctl_ior, ioctl_iowr};
|
||||
use crate::{
|
||||
ioctl_none, ioctl_read, ioctl_write_buf, ioctl_write_ptr, ioctl_write_val, ioctl_writeread,
|
||||
ioctl_writeread_buf,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::hv::kvm::bindings::{
|
||||
KvmCpuid2, KvmCreateGuestMemfd, KvmEnableCap, KvmRegs, KvmSregs, KvmSregs2,
|
||||
};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::utils::ioctls::ioctl_iowr;
|
||||
use crate::utils::ioctls::{ioctl_io, ioctl_ior};
|
||||
use crate::{ioctl_none, ioctl_write_buf, ioctl_write_ptr, ioctl_write_val};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::{ioctl_read, ioctl_writeread, ioctl_writeread_buf};
|
||||
|
||||
ioctl_none!(kvm_get_api_version, KVMIO, 0x00, 0);
|
||||
ioctl_write_val!(kvm_create_vm, ioctl_io(KVMIO, 0x01), KvmVmType);
|
||||
|
@ -48,6 +52,7 @@ ioctl_write_ptr!(
|
|||
KvmUserspaceMemoryRegion2
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_none!(kvm_create_irqchip, KVMIO, 0x60, 0);
|
||||
ioctl_write_buf!(kvm_set_gsi_routing, KVMIO, 0x6a, KvmIrqRouting);
|
||||
|
||||
|
@ -55,7 +60,9 @@ ioctl_write_ptr!(kvm_irqfd, KVMIO, 0x76, KvmIrqfd);
|
|||
ioctl_write_ptr!(kvm_ioeventfd, KVMIO, 0x79, KvmIoEventFd);
|
||||
|
||||
ioctl_none!(kvm_run, KVMIO, 0x80, 0);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_read!(kvm_get_regs, KVMIO, 0x81, KvmRegs);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_write_ptr!(kvm_set_regs, KVMIO, 0x82, KvmRegs);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_read!(kvm_get_sregs, KVMIO, 0x83, KvmSregs);
|
||||
|
@ -65,9 +72,11 @@ ioctl_write_ptr!(kvm_set_sregs, KVMIO, 0x84, KvmSregs);
|
|||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_write_buf!(kvm_set_cpuid2, KVMIO, 0x90, KvmCpuid2);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_write_ptr!(kvm_enable_cap, KVMIO, 0xa3, KvmEnableCap);
|
||||
ioctl_write_ptr!(kvm_signal_msi, KVMIO, 0xa5, KvmMsi);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_writeread!(kvm_memory_encrypt_op, ioctl_iowr::<u64>(KVMIO, 0xba));
|
||||
|
||||
ioctl_write_ptr!(
|
||||
|
@ -89,4 +98,5 @@ ioctl_write_ptr!(kvm_set_sregs2, KVMIO, 0xcd, KvmSregs2);
|
|||
|
||||
ioctl_write_ptr!(kvm_set_memory_attributes, KVMIO, 0xd2, KvmMemoryAttributes);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
ioctl_writeread!(kvm_create_guest_memfd, KVMIO, 0xd4, KvmCreateGuestMemfd);
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
||||
|
||||
mod bindings;
|
||||
mod ioctls;
|
||||
#[path = "sev/sev.rs"]
|
||||
|
@ -22,8 +27,6 @@ mod vcpu;
|
|||
mod vm;
|
||||
mod vmentry;
|
||||
mod vmexit;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
|
@ -45,7 +48,9 @@ use crate::ffi;
|
|||
use crate::hv::Cpuid;
|
||||
use crate::hv::{error, Hypervisor, MemMapOption, Result, VmConfig};
|
||||
|
||||
use bindings::{KvmCpuid2, KvmCpuid2Flag, KvmCpuidEntry2, KVM_API_VERSION, KVM_MAX_CPUID_ENTRIES};
|
||||
use bindings::KVM_API_VERSION;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use bindings::{KvmCpuid2, KvmCpuid2Flag, KvmCpuidEntry2, KVM_MAX_CPUID_ENTRIES};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use ioctls::kvm_get_supported_cpuid;
|
||||
use ioctls::{kvm_create_vm, kvm_get_api_version, kvm_get_vcpu_mmap_size};
|
||||
|
@ -101,6 +106,7 @@ pub struct Kvm {
|
|||
pub struct KvmConfig {
|
||||
#[serde(default)]
|
||||
pub dev_kvm: Option<PathBuf>,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[serde(default)]
|
||||
pub dev_sev: Option<PathBuf>,
|
||||
}
|
||||
|
|
27
alioth/src/hv/kvm/vcpu/aarch64.rs
Normal file
27
alioth/src/hv/kvm/vcpu/aarch64.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::arch::reg::Reg;
|
||||
use crate::hv::kvm::vcpu::KvmVcpu;
|
||||
use crate::hv::Result;
|
||||
|
||||
impl KvmVcpu {
|
||||
pub fn kvm_set_regs(&self, _vals: &[(Reg, u64)]) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn kvm_get_reg(&self, _reg: Reg) -> Result<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
||||
|
||||
|
|
16
alioth/src/hv/kvm/vm/aarch64.rs
Normal file
16
alioth/src/hv/kvm/vm/aarch64.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VmArch {}
|
|
@ -12,6 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
||||
|
||||
|
@ -22,7 +24,9 @@ use std::sync::atomic::{AtomicU32, Ordering};
|
|||
use std::sync::Arc;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
use libc::{eventfd, write, EFD_CLOEXEC, EFD_NONBLOCK, SIGRTMIN};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use libc::write;
|
||||
use libc::{eventfd, EFD_CLOEXEC, EFD_NONBLOCK, SIGRTMIN};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use snafu::ResultExt;
|
||||
|
||||
|
@ -31,10 +35,11 @@ use crate::arch::sev::{SnpPageType, SnpPolicy};
|
|||
use crate::ffi;
|
||||
use crate::hv::kvm::bindings::{
|
||||
KvmCap, KvmEncRegion, KvmIoEventFd, KvmIoEventFdFlag, KvmIrqRouting, KvmIrqRoutingEntry,
|
||||
KvmIrqRoutingIrqchip, KvmIrqRoutingMsi, KvmIrqfd, KvmIrqfdFlag, KvmMemFlag, KvmMemoryAttribute,
|
||||
KvmMemoryAttributes, KvmMsi, KvmUserspaceMemoryRegion, KvmUserspaceMemoryRegion2,
|
||||
KVM_IRQCHIP_IOAPIC, KVM_IRQ_ROUTING_IRQCHIP, KVM_IRQ_ROUTING_MSI,
|
||||
KvmIrqRoutingMsi, KvmIrqfd, KvmIrqfdFlag, KvmMemFlag, KvmMemoryAttribute, KvmMemoryAttributes,
|
||||
KvmMsi, KvmUserspaceMemoryRegion, KvmUserspaceMemoryRegion2, KVM_IRQ_ROUTING_MSI,
|
||||
};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::hv::kvm::bindings::{KvmIrqRoutingIrqchip, KVM_IRQCHIP_IOAPIC, KVM_IRQ_ROUTING_IRQCHIP};
|
||||
use crate::hv::kvm::ioctls::{
|
||||
kvm_check_extension, kvm_create_vcpu, kvm_ioeventfd, kvm_irqfd, kvm_memory_encrypt_reg_region,
|
||||
kvm_memory_encrypt_unreg_region, kvm_set_gsi_routing, kvm_set_memory_attributes,
|
||||
|
@ -42,11 +47,15 @@ use crate::hv::kvm::ioctls::{
|
|||
};
|
||||
use crate::hv::kvm::vcpu::{KvmRunBlock, KvmVcpu};
|
||||
use crate::hv::kvm::{kvm_error, KvmError};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::hv::IntxSender;
|
||||
use crate::hv::{
|
||||
error, Error, IntxSender, IoeventFd, IoeventFdRegistry, IrqFd, MemMapOption, MsiSender, Result,
|
||||
Vm, VmMemory,
|
||||
error, Error, IoeventFd, IoeventFdRegistry, IrqFd, MemMapOption, MsiSender, Result, Vm,
|
||||
VmMemory,
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use aarch64::VmArch;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use x86_64::VmArch;
|
||||
|
||||
|
@ -63,19 +72,22 @@ pub(super) struct VmInner {
|
|||
impl VmInner {
|
||||
fn update_routing_table(&self, table: &HashMap<u32, KvmMsiEntryData>) -> Result<(), KvmError> {
|
||||
let mut entries = [KvmIrqRoutingEntry::default(); MAX_GSI_ROUTES];
|
||||
let pin_map = self.arch.pin_map.load(Ordering::Acquire);
|
||||
let mut index = 0;
|
||||
for pin in 0..24 {
|
||||
if pin_map & (1 << pin) == 0 {
|
||||
continue;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
let pin_map = self.arch.pin_map.load(Ordering::Acquire);
|
||||
for pin in 0..24 {
|
||||
if pin_map & (1 << pin) == 0 {
|
||||
continue;
|
||||
}
|
||||
entries[index].gsi = pin;
|
||||
entries[index].type_ = KVM_IRQ_ROUTING_IRQCHIP;
|
||||
entries[index].routing.irqchip = KvmIrqRoutingIrqchip {
|
||||
irqchip: KVM_IRQCHIP_IOAPIC,
|
||||
pin,
|
||||
};
|
||||
index += 1;
|
||||
}
|
||||
entries[index].gsi = pin;
|
||||
entries[index].type_ = KVM_IRQ_ROUTING_IRQCHIP;
|
||||
entries[index].routing.irqchip = KvmIrqRoutingIrqchip {
|
||||
irqchip: KVM_IRQCHIP_IOAPIC,
|
||||
pin,
|
||||
};
|
||||
index += 1;
|
||||
}
|
||||
for (gsi, entry) in table.iter() {
|
||||
if entry.masked {
|
||||
|
@ -242,6 +254,7 @@ impl VmMemory for KvmMemory {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[derive(Debug)]
|
||||
pub struct KvmIntxSender {
|
||||
pin: u8,
|
||||
|
@ -249,6 +262,7 @@ pub struct KvmIntxSender {
|
|||
event_fd: OwnedFd,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
impl Drop for KvmIntxSender {
|
||||
fn drop(&mut self) {
|
||||
let pin_flag = 1 << (self.pin as u32);
|
||||
|
@ -269,6 +283,7 @@ impl Drop for KvmIntxSender {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
impl IntxSender for KvmIntxSender {
|
||||
fn send(&self) -> Result<(), Error> {
|
||||
ffi!(unsafe { write(self.event_fd.as_raw_fd(), &1u64 as *const _ as _, 8) })
|
||||
|
@ -538,6 +553,7 @@ impl IoeventFdRegistry for KvmIoeventFdRegistry {
|
|||
|
||||
impl Vm for KvmVm {
|
||||
type Vcpu = KvmVcpu;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
type IntxSender = KvmIntxSender;
|
||||
type MsiSender = KvmMsiSender;
|
||||
type Memory = KvmMemory;
|
||||
|
@ -570,6 +586,7 @@ impl Vm for KvmVm {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn create_intx_sender(&self, pin: u8) -> Result<Self::IntxSender, Error> {
|
||||
let pin_flag = 1 << pin;
|
||||
if self.vm.arch.pin_map.fetch_or(pin_flag, Ordering::AcqRel) & pin_flag == pin_flag {
|
||||
|
|
23
alioth/src/loader/firmware/aarch64.rs
Normal file
23
alioth/src/loader/firmware/aarch64.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::loader::{InitState, Result};
|
||||
use crate::mem::mapped::ArcMemPages;
|
||||
use crate::mem::Memory;
|
||||
|
||||
pub fn load<P: AsRef<Path>>(_memory: &Memory, _path: P) -> Result<(InitState, ArcMemPages)> {
|
||||
unimplemented!()
|
||||
}
|
|
@ -12,7 +12,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use aarch64::load;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use x86_64::load;
|
||||
|
|
29
alioth/src/loader/linux/aarch64.rs
Normal file
29
alioth/src/loader/linux/aarch64.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::loader::{InitState, Result};
|
||||
use crate::mem::mapped::RamBus;
|
||||
use crate::mem::MemRegionEntry;
|
||||
|
||||
pub fn load<P: AsRef<Path>>(
|
||||
_memory: &RamBus,
|
||||
_mem_regions: &[(usize, MemRegionEntry)],
|
||||
_kernel: P,
|
||||
_cmd_line: Option<&str>,
|
||||
_initramfs: Option<P>,
|
||||
) -> Result<InitState> {
|
||||
unimplemented!()
|
||||
}
|
|
@ -12,10 +12,14 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod bootparams;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use aarch64::load;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use x86_64::load;
|
||||
|
|
|
@ -27,6 +27,7 @@ pub mod elf;
|
|||
pub mod firmware;
|
||||
#[path = "linux/linux.rs"]
|
||||
pub mod linux;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[path = "xen/xen.rs"]
|
||||
pub mod xen;
|
||||
|
||||
|
@ -41,6 +42,7 @@ pub struct Payload {
|
|||
#[derive(Debug)]
|
||||
pub enum ExecType {
|
||||
Linux,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Pvh,
|
||||
Firmware,
|
||||
}
|
||||
|
|
|
@ -332,12 +332,10 @@ impl Memory {
|
|||
entries
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn add_io_dev(&self, port: Option<u16>, dev: MmioRange) -> Result<u16, Error> {
|
||||
self.add_io_region(port, Arc::new(IoRegion::new(dev)))
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn add_io_region(&self, port: Option<u16>, region: Arc<IoRegion>) -> Result<u16, Error> {
|
||||
let mut regions = self.io_regions.lock();
|
||||
// TODO: allocate port dynamically
|
||||
|
@ -351,7 +349,6 @@ impl Memory {
|
|||
Ok(port.unwrap())
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn unmap_io_region(&self, port: u16, region: &IoRegion) -> Result<()> {
|
||||
self.io_bus.remove(port as usize)?;
|
||||
let callbacks = region.callbacks.lock();
|
||||
|
@ -361,7 +358,6 @@ impl Memory {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn remove_io_region(&self, port: u16) -> Result<Arc<IoRegion>> {
|
||||
let mut io_regions = self.io_regions.lock();
|
||||
let io_region = io_regions.remove(port as usize)?;
|
||||
|
|
|
@ -264,7 +264,7 @@ fn setup_tap(file: &mut File, if_name: Option<&str>) -> Result<()> {
|
|||
Some(name) => {
|
||||
let mut tap_ifconfig = unsafe { MaybeUninit::<libc::ifreq>::zeroed().assume_init() };
|
||||
for (s, d) in zip(name.as_bytes(), tap_ifconfig.ifr_name.as_mut()) {
|
||||
*d = *s as i8;
|
||||
*d = *s as _;
|
||||
}
|
||||
tap_ifconfig
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ use thiserror::Error;
|
|||
use crate::board::{self, ArchBoard, Board, BoardConfig, STATE_CREATED, STATE_RUNNING};
|
||||
use crate::device::fw_cfg::{FwCfg, FwCfgItemParam, PORT_SELECTOR};
|
||||
use crate::device::pvpanic::PvPanic;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::device::serial::Serial;
|
||||
use crate::hv::{self, Hypervisor, IoeventFdRegistry, Vm, VmConfig};
|
||||
use crate::loader::{self, Payload};
|
||||
|
|
Loading…
Reference in a new issue