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
9 changes: 7 additions & 2 deletions kernel/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use tdp::TdpPlatform;

use core::arch::asm;
use core::fmt::Debug;
use core::mem::MaybeUninit;

use crate::address::{PhysAddr, VirtAddr};
use crate::config::SvsmConfig;
Expand Down Expand Up @@ -224,9 +225,13 @@ pub trait SvsmPlatform: Sync {
///
/// # Safety
///
/// Caller must ensure that `pa` points to a properly aligned memory location and the
/// Caller must ensure that `paddr` points to a properly aligned memory location and the
/// memory accessed is part of a valid MMIO range.
unsafe fn mmio_read(&self, _paddr: PhysAddr, _data: &mut [u8]) -> Result<(), SvsmError>;
unsafe fn mmio_read(
&self,
paddr: PhysAddr,
data: &mut [MaybeUninit<u8>],
) -> Result<(), SvsmError>;
}

//FIXME - remove Copy trait
Expand Down
6 changes: 5 additions & 1 deletion kernel/src/platform/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,11 @@ impl SvsmPlatform for NativePlatform {
unimplemented!()
}

unsafe fn mmio_read(&self, _paddr: PhysAddr, _data: &mut [u8]) -> Result<(), SvsmError> {
unsafe fn mmio_read(
&self,
_paddr: PhysAddr,
_data: &mut [MaybeUninit<u8>],
) -> Result<(), SvsmError> {
unimplemented!()
}
}
7 changes: 6 additions & 1 deletion kernel/src/platform/snp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::utils::immut_after_init::ImmutAfterInitCell;
use crate::utils::MemoryRegion;
use syscall::GlobalFeatureFlags;

use core::mem::MaybeUninit;
use core::sync::atomic::{AtomicU32, Ordering};

#[cfg(test)]
Expand Down Expand Up @@ -393,7 +394,11 @@ impl SvsmPlatform for SnpPlatform {
///
/// Caller must ensure that `paddr` points to a properly aligned memory location and the
/// memory accessed is part of a valid MMIO range.
unsafe fn mmio_read(&self, paddr: PhysAddr, data: &mut [u8]) -> Result<(), SvsmError> {
unsafe fn mmio_read(
&self,
paddr: PhysAddr,
data: &mut [MaybeUninit<u8>],
) -> Result<(), SvsmError> {
// SAFETY: We are trusting the caller to ensure validity of `paddr` and alignment of data.
unsafe { crate::cpu::percpu::current_ghcb().mmio_read(paddr, data) }
}
Expand Down
6 changes: 5 additions & 1 deletion kernel/src/platform/tdp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,11 @@ impl SvsmPlatform for TdpPlatform {
unimplemented!()
}

unsafe fn mmio_read(&self, _paddr: PhysAddr, _data: &mut [u8]) -> Result<(), SvsmError> {
unsafe fn mmio_read(
&self,
_paddr: PhysAddr,
_data: &mut [MaybeUninit<u8>],
) -> Result<(), SvsmError> {
unimplemented!()
}
}
Expand Down
16 changes: 12 additions & 4 deletions kernel/src/sev/ghcb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::utils::MemoryRegion;

use crate::mm::PageBox;
use core::arch::global_asm;
use core::mem::{self, offset_of};
use core::mem::{self, offset_of, MaybeUninit};
use core::ops::Deref;
use core::ptr;
use core::sync::atomic::{AtomicU16, AtomicU32, AtomicU64, AtomicU8, Ordering};
Expand Down Expand Up @@ -548,15 +548,19 @@ impl GHCB {
Ok(())
}

fn read_buffer_slice(&self, data: &mut [u8], offset: usize) -> Result<(), GhcbError> {
fn read_buffer_slice(
&self,
data: &mut [MaybeUninit<u8>],
offset: usize,
) -> Result<(), GhcbError> {
let src = &self
.buffer
.get(offset..)
.ok_or(GhcbError::InvalidOffset)?
.get(..data.len())
.ok_or(GhcbError::InvalidOffset)?;
for (d, s) in data.iter_mut().zip(src.iter()) {
*d = s.load(Ordering::Relaxed);
d.write(s.load(Ordering::Relaxed));
}
Ok(())
}
Expand Down Expand Up @@ -587,7 +591,11 @@ impl GHCB {
///
/// Caller must ensure that `pa` points to a properly aligned memory location and the
/// memory accessed is part of a valid MMIO range.
pub unsafe fn mmio_read(&self, pa: PhysAddr, value: &mut [u8]) -> Result<(), SvsmError> {
pub unsafe fn mmio_read(
&self,
pa: PhysAddr,
value: &mut [MaybeUninit<u8>],
) -> Result<(), SvsmError> {
self.clear();
self.pepare_buffer();
self.vmgexit(GHCBExitCode::MMIO_READ, u64::from(pa), value.len() as u64)?;
Expand Down
17 changes: 13 additions & 4 deletions kernel/src/virtio/hal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{locking::SpinLock, platform::SVSM_PLATFORM};
use alloc::vec::Vec;
use core::{
cell::OnceCell,
mem::{size_of, MaybeUninit},
ptr::{addr_of, NonNull},
};
use zerocopy::{FromBytes, Immutable, IntoBytes};
Expand Down Expand Up @@ -202,13 +203,21 @@ unsafe impl virtio_drivers::Hal for SvsmHal {
.phys_addr(VirtAddr::from(addr_of!(*src)))
.unwrap();

let mut b = alloc::vec![0; size_of::<T>()];
let mut b = MaybeUninit::<T>::uninit();
// SAFETY: We are trusting the caller (the virtio driver) to ensure `src` is a valid MMIO
// address and that it is alinged properly.
// address and that it is aligned properly. If SVSM_PLATFORM.mmio_read() doesn't fail
// we can assume that all the bytes are read from the device.
unsafe {
SVSM_PLATFORM.mmio_read(paddr, &mut b).unwrap();
// MaybeUninit::as_bytes_mut() can avoid this, but it's still
// unstable. When it will be stabilized, we can simply use
// `b.as_bytes_mut()` instead of creating `b_slice`.
let b_slice = core::slice::from_raw_parts_mut(
b.as_mut_ptr().cast::<MaybeUninit<u8>>(),
size_of::<T>(),
);
SVSM_PLATFORM.mmio_read(paddr, b_slice).unwrap();
b.assume_init()
}
T::try_read_from_bytes(b.as_slice()).unwrap()
}

/// Performs memory mapped write of `value` to the location of `dst`.
Expand Down