feat: skeleton for running KVM VMs on aarch64

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
This commit is contained in:
Changyuan Lyu 2024-06-16 18:24:59 -07:00 committed by Lencerf
parent 6368c4fb38
commit 038329b721
24 changed files with 339 additions and 43 deletions

View file

@ -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 {

View file

@ -12,4 +12,5 @@
// See the License for the specific language governing permissions and
// limitations under the License.
pub mod layout;
pub mod reg;

View 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

View 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!()
}
}

View file

@ -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;

View file

@ -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)?;

View file

@ -13,4 +13,5 @@
// limitations under the License.
#[path = "acpi/acpi.rs"]
#[cfg(target_arch = "x86_64")]
pub mod acpi;

View file

@ -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>;

View 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(())
}
}

View file

@ -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 {

View file

@ -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);

View file

@ -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>,
}

View 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!()
}
}

View file

@ -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;

View 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 {}

View file

@ -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 {

View 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!()
}

View file

@ -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;

View 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!()
}

View file

@ -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;

View file

@ -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,
}

View file

@ -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)?;

View file

@ -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
}

View file

@ -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};