Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions alioth/src/board/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod aarch64;
mod x86_64;

use std::ffi::CStr;
use std::os::fd::BorrowedFd;
use std::sync::Arc;

use libc::{MAP_PRIVATE, MAP_SHARED};
Expand Down Expand Up @@ -187,11 +188,21 @@ where
Ok(())
}

fn dev_mem_added(&self, gpa: u64, pages: &ArcMemPages) -> mem::Result<()> {
fn dev_mem_added(
&self,
gpa: u64,
pages: &ArcMemPages,
_: Option<BorrowedFd>,
) -> mem::Result<()> {
self.ram_added(gpa, pages)
}

fn dev_mem_removed(&self, gpa: u64, pages: &ArcMemPages) -> mem::Result<()> {
fn dev_mem_removed(
&self,
gpa: u64,
pages: &ArcMemPages,
_: Option<BorrowedFd>,
) -> mem::Result<()> {
self.ram_removed(gpa, pages)
}
}
Expand Down
5 changes: 3 additions & 2 deletions alioth/src/board/board_amd64/sev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use std::arch::x86_64::{__cpuid, CpuidResult};
use std::collections::HashMap;
use std::os::fd::BorrowedFd;
use std::sync::Arc;

use crate::arch::cpuid::{
Expand Down Expand Up @@ -149,11 +150,11 @@ where
Ok(())
}

fn dev_mem_added(&self, _: u64, _: &ArcMemPages) -> mem::Result<()> {
fn dev_mem_added(&self, _: u64, _: &ArcMemPages, _: Option<BorrowedFd>) -> mem::Result<()> {
Ok(())
}

fn dev_mem_removed(&self, _: u64, _: &ArcMemPages) -> mem::Result<()> {
fn dev_mem_removed(&self, _: u64, _: &ArcMemPages, _: Option<BorrowedFd>) -> mem::Result<()> {
Ok(())
}
}
44 changes: 27 additions & 17 deletions alioth/src/mem/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub mod mapped;

use std::any::{Any, type_name};
use std::fmt::Debug;
use std::os::fd::{AsFd, BorrowedFd, OwnedFd};
use std::sync::Arc;

use parking_lot::{Mutex, RwLock};
Expand Down Expand Up @@ -124,15 +125,18 @@ impl MemSpec {
#[derive(Debug)]
pub enum MemRange {
Ram(ArcMemPages),
DevMem(ArcMemPages),
DevMem {
pages: ArcMemPages,
dma_buf: Option<OwnedFd>,
},
Emulated(Arc<dyn Mmio>),
Span(u64),
}

impl MemRange {
pub fn size(&self) -> u64 {
match self {
MemRange::Ram(pages) | MemRange::DevMem(pages) => pages.size(),
MemRange::Ram(pages) | MemRange::DevMem { pages, .. } => pages.size(),
MemRange::Emulated(range) => Mmio::size(range),
MemRange::Span(size) => *size,
}
Expand Down Expand Up @@ -186,7 +190,10 @@ impl MemRegion {
pub fn with_dev_mem(pages: ArcMemPages, type_: MemRegionType) -> MemRegion {
let size = pages.size();
MemRegion {
ranges: vec![MemRange::DevMem(pages)],
ranges: vec![MemRange::DevMem {
pages,
dma_buf: None,
}],
entries: vec![MemRegionEntry { type_, size }],
callbacks: Mutex::new(vec![]),
}
Expand Down Expand Up @@ -245,8 +252,8 @@ impl SlotBackend for Arc<IoRegion> {
pub trait LayoutChanged: Debug + Send + Sync + 'static {
fn ram_added(&self, gpa: u64, pages: &ArcMemPages) -> Result<()>;
fn ram_removed(&self, gpa: u64, pages: &ArcMemPages) -> Result<()>;
fn dev_mem_added(&self, gpa: u64, pages: &ArcMemPages) -> Result<()>;
fn dev_mem_removed(&self, gpa: u64, pages: &ArcMemPages) -> Result<()>;
fn dev_mem_added(&self, gpa: u64, pages: &ArcMemPages, fd: Option<BorrowedFd>) -> Result<()>;
fn dev_mem_removed(&self, gpa: u64, pages: &ArcMemPages, fd: Option<BorrowedFd>) -> Result<()>;
}

pub trait LayoutUpdated: Debug + Send + Sync + 'static {
Expand Down Expand Up @@ -285,7 +292,10 @@ impl Memory {
let gpa = addr + offset;
match range {
MemRange::Ram(r) => callback.ram_added(gpa, r)?,
MemRange::Span(_) | MemRange::Emulated(_) | MemRange::DevMem(_) => {}
MemRange::DevMem { pages, dma_buf } => {
callback.dev_mem_added(gpa, pages, dma_buf.as_ref().map(AsFd::as_fd))?
}
MemRange::Span(_) | MemRange::Emulated(_) => {}
}
offset += range.size();
}
Expand Down Expand Up @@ -327,8 +337,8 @@ impl Memory {
let mut ram_updated = false;
for range in &region.ranges {
let gpa = addr + offset;
if let MemRange::Ram(r) | MemRange::DevMem(r) = range {
self.ram_bus.add(gpa, r.clone())?;
if let MemRange::Ram(pages) | MemRange::DevMem { pages, .. } = range {
self.ram_bus.add(gpa, pages.clone())?;
ram_updated = true;
}
match range {
Expand All @@ -341,9 +351,9 @@ impl Memory {
callback.ram_added(gpa, r)?;
}
}
MemRange::DevMem(r) => {
MemRange::DevMem { pages: r, dma_buf } => {
for callback in &callbacks.changed {
callback.dev_mem_added(gpa, r)?;
callback.dev_mem_added(gpa, r, dma_buf.as_ref().map(AsFd::as_fd))?;
}
}
MemRange::Span(_) => {}
Expand All @@ -369,7 +379,7 @@ impl Memory {
let mut ram_updated = false;
for range in &region.ranges {
let gpa = addr + offset;
if let MemRange::Ram(_) | MemRange::DevMem(_) = range {
if let MemRange::Ram(_) | MemRange::DevMem { .. } = range {
self.ram_bus.remove(gpa)?;
ram_updated = true;
}
Expand All @@ -383,9 +393,9 @@ impl Memory {
callback.ram_removed(gpa, r)?;
}
}
MemRange::DevMem(r) => {
MemRange::DevMem { pages, dma_buf } => {
for callback in callbacks.changed.iter().rev() {
callback.dev_mem_removed(gpa, r)?;
callback.dev_mem_removed(gpa, pages, dma_buf.as_ref().map(AsFd::as_fd))?;
}
}
MemRange::Span(_) => {}
Expand Down Expand Up @@ -511,11 +521,11 @@ impl Memory {
'out: while let Some((mut addr, region)) = regions.search_next(start) {
let next_start = addr + region.size();
for range in &region.ranges {
let (MemRange::DevMem(r) | MemRange::Ram(r)) = range else {
let (MemRange::DevMem { pages, .. } | MemRange::Ram(pages)) = range else {
addr += range.size();
continue;
};
let range_end = addr + r.size();
let range_end = addr + pages.size();
if range_end <= start {
addr = range_end;
continue;
Expand Down Expand Up @@ -602,11 +612,11 @@ where
Ok(())
}

fn dev_mem_added(&self, _: u64, _: &ArcMemPages) -> Result<()> {
fn dev_mem_added(&self, _: u64, _: &ArcMemPages, _: Option<BorrowedFd>) -> Result<()> {
Ok(())
}

fn dev_mem_removed(&self, _: u64, _: &ArcMemPages) -> Result<()> {
fn dev_mem_removed(&self, _: u64, _: &ArcMemPages, _: Option<BorrowedFd>) -> Result<()> {
Ok(())
}
}
7 changes: 5 additions & 2 deletions alioth/src/sys/linux/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ macro_rules! ioctl_write_val {

#[macro_export]
macro_rules! ioctl_write_ptr {
($name:ident, $code:expr, $ty:ty) => {
($name:ident, $code:expr, $ty:ty, $($g:ident),*) => {
#[allow(clippy::missing_safety_doc)]
pub unsafe fn $name<F: ::std::os::fd::AsFd>(
pub unsafe fn $name<F: ::std::os::fd::AsFd, $($g),*>(
fd: &F,
val: &$ty,
) -> ::std::io::Result<libc::c_int> {
Expand All @@ -96,6 +96,9 @@ macro_rules! ioctl_write_ptr {
})
}
};
($name:ident, $code:expr, $ty:ty) => {
$crate::ioctl_write_ptr!($name, $code, $ty, );
};
($name:ident, $type_:expr, $nr:expr, $ty:ty) => {
$crate::ioctl_write_ptr!(
$name,
Expand Down
36 changes: 36 additions & 0 deletions alioth/src/sys/linux/iommufd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2026 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::ioctl_write_ptr;
use crate::sys::ioctl::ioctl_io;
use crate::sys::vfio::IommuIoasMapFlag;

pub const IOMMUFD_TYPE: u8 = b';';

#[repr(C)]
pub struct IommuIoasMapFile {
pub size: u32,
pub flags: IommuIoasMapFlag,
pub ioas_id: u32,
pub fd: i32,
pub start: u64,
pub length: u64,
pub iova: u64,
}

ioctl_write_ptr! {
iommu_ioas_map_file,
ioctl_io(IOMMUFD_TYPE, 0x8f),
IommuIoasMapFile
}
1 change: 1 addition & 0 deletions alioth/src/sys/linux/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

pub mod if_tun;
pub mod ioctl;
pub mod iommufd;
pub mod kvm;
pub mod sev;
pub mod tdx;
Expand Down
51 changes: 51 additions & 0 deletions alioth/src/sys/linux/vfio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use bitfield::bitfield;

use crate::sys::ioctl::ioctl_io;
use crate::{
bitflags, consts, ioctl_none, ioctl_write_buf, ioctl_write_ptr, ioctl_write_val,
Expand Down Expand Up @@ -262,6 +264,48 @@ consts! {
}
}

consts! {
pub struct DeviceFeature(u16) {
DMA_BUF = 11;
}
}

#[derive(Debug, Clone)]
#[repr(C)]
pub struct VfioRegionDmaRange {
pub offset: u64,
pub length: u64,
}

#[derive(Debug, Clone)]
#[repr(C)]
pub struct VfioDeviceFeatureDmaBuf<const N: usize> {
pub region_index: u32,
pub open_flags: u32,
pub flags: u32,
pub nr_ranges: u32,
pub dma_ranges: [VfioRegionDmaRange; N],
}

bitfield! {
#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)]
pub struct VfioDeviceFeatureFlag(u32);
impl Debug;
impl new;
pub u16, from into DeviceFeature, index, set_index: 15, 0;
pub get, set_get: 16;
pub set, set_set: 17;
pub probe, set_probe: 18;
}

#[repr(C)]
#[derive(Debug, Clone)]
pub struct VfioDeviceFeature<T> {
pub argsz: u32,
pub flags: VfioDeviceFeatureFlag,
pub data: T,
}

ioctl_writeread!(
vfio_device_get_info,
ioctl_io(VFIO_TYPE, 107),
Expand All @@ -282,6 +326,13 @@ ioctl_write_buf!(vfio_device_set_irqs, ioctl_io(VFIO_TYPE, 110), VfioIrqSet);

ioctl_none!(vfio_device_reset, VFIO_TYPE, 111);

ioctl_write_ptr!(
vfio_device_feature,
ioctl_io(VFIO_TYPE, 117),
VfioDeviceFeature<T>,
T
);

ioctl_write_ptr!(
vfio_device_bind_iommufd,
ioctl_io(VFIO_TYPE, 118),
Expand Down
16 changes: 13 additions & 3 deletions alioth/src/vfio/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

use std::fs::File;
use std::os::fd::AsRawFd;
use std::os::fd::{AsRawFd, BorrowedFd};
use std::path::Path;
use std::sync::Arc;

Expand Down Expand Up @@ -120,11 +120,21 @@ impl LayoutChanged for UpdateContainerMapping {
Ok(())
}

fn dev_mem_added(&self, gpa: u64, pages: &ArcMemPages) -> mem::Result<()> {
fn dev_mem_added(
&self,
gpa: u64,
pages: &ArcMemPages,
_: Option<BorrowedFd>,
) -> mem::Result<()> {
self.ram_added(gpa, pages)
}

fn dev_mem_removed(&self, gpa: u64, pages: &ArcMemPages) -> mem::Result<()> {
fn dev_mem_removed(
&self,
gpa: u64,
pages: &ArcMemPages,
_: Option<BorrowedFd>,
) -> mem::Result<()> {
self.ram_removed(gpa, pages)
}
}
Loading