Skip to content
Open
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
5 changes: 4 additions & 1 deletion litebox_platform_lvbs/src/mshv/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ pub enum VsmError {

#[error("discontiguous memory range")]
DiscontiguousMemoryRange,


#[error("failed to map VTL0 physical memory range")]
MapVtl0PhysRangeFailed,
// Symbol Table Errors
#[error("symbol table data empty")]
SymbolTableEmpty,
Expand Down Expand Up @@ -172,6 +174,7 @@ impl From<VsmError> for Errno {
| VsmError::BootSignalWriteFailed
| VsmError::CpuOnlineMaskCopyFailed
| VsmError::HekiPagesCopyFailed
| VsmError::MapVtl0PhysRangeFailed
| VsmError::Vtl0CopyFailed => Errno::EFAULT,

// Not found errors
Expand Down
40 changes: 27 additions & 13 deletions litebox_platform_lvbs/src/mshv/ringbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@

use core::fmt;
use spin::{Mutex, Once};
use x86_64::PhysAddr;

pub struct RingBuffer {
rb_pa: PhysAddr,
pub struct RingBuffer{
rb_va: *mut u8,
write_offset: usize,
size: usize,
}

impl RingBuffer {
pub fn new(phys_addr: PhysAddr, requested_size: usize) -> Self {
pub fn new(virt_addr: *mut u8 , requested_size: usize) -> Self {
RingBuffer {
rb_pa: phys_addr,
rb_va: virt_addr,
write_offset: 0,
size: requested_size,
}
Expand All @@ -28,7 +27,11 @@ impl RingBuffer {
if buf.len() >= self.size {
let single_slice = &buf[(buf.len() - self.size)..];
unsafe {
crate::platform_low().copy_slice_to_vtl0_phys(self.rb_pa, single_slice);
let _ = litebox::mm::exception_table::memcpy_fallible(
self.rb_va,
single_slice.as_ptr(),
self.size);

}
self.write_offset = 0;
return;
Expand All @@ -40,24 +43,35 @@ impl RingBuffer {
let first_slice = &buf[..space_remaining];
let wraparound_slice = &buf[space_remaining..];
unsafe {
crate::platform_low()
.copy_slice_to_vtl0_phys(self.rb_pa + self.write_offset as u64, first_slice);
crate::platform_low().copy_slice_to_vtl0_phys(self.rb_pa, wraparound_slice);
let _ = litebox::mm::exception_table::memcpy_fallible(
self.rb_va.add(self.write_offset),
first_slice.as_ptr(),
first_slice.len());
let _ = litebox::mm::exception_table::memcpy_fallible(
self.rb_va,
wraparound_slice.as_ptr(),
wraparound_slice.len());
}
} else {
unsafe {
crate::platform_low()
.copy_slice_to_vtl0_phys(self.rb_pa + self.write_offset as u64, buf);
let _ = litebox::mm::exception_table::memcpy_fallible(
self.rb_va.add(self.write_offset),
buf.as_ptr(),
buf.len());
}
}
self.write_offset = (self.write_offset + buf.len()) % self.size;
}
}

// SAFETY: RingBuffer is only accessed through a Mutex, and rb_va is a valid
// pointer to mapped memory that outlives the RingBuffer.
unsafe impl Send for RingBuffer {}

static RINGBUFFER_ONCE: Once<Mutex<RingBuffer>> = Once::new();
pub(crate) fn set_ringbuffer(pa: PhysAddr, size: usize) -> &'static Mutex<RingBuffer> {
pub(crate) fn set_ringbuffer(va: *mut u8, size: usize) -> &'static Mutex<RingBuffer> {
RINGBUFFER_ONCE.call_once(|| {
let ring_buffer = RingBuffer::new(pa, size);
let ring_buffer = RingBuffer::new(va, size);
Mutex::new(ring_buffer)
})
}
Expand Down
19 changes: 14 additions & 5 deletions litebox_platform_lvbs/src/mshv/vsm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use spin::Once;
use thiserror::Error;
use x86_64::{
PhysAddr, VirtAddr,
structures::paging::{PageSize, PhysFrame, Size4KiB, frame::PhysFrameRange},
structures::paging::{PageSize, PageTableFlags, PhysFrame, Size4KiB, frame::PhysFrameRange},
};
use x509_cert::{Certificate, der::Decode};
use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout};
Expand Down Expand Up @@ -882,15 +882,24 @@ fn apply_vtl0_text_patch(heki_patch: HekiPatch) -> Result<(), VsmError> {
}

fn mshv_vsm_allocate_ringbuffer_memory(phys_addr: u64, size: usize) -> Result<i64, VsmError> {
set_ringbuffer(PhysAddr::new(phys_addr), size);
let phys_addr = PhysAddr::new(phys_addr);
protect_physical_memory_range(
PhysFrame::range(
PhysFrame::containing_address(PhysAddr::new(phys_addr)),
PhysFrame::containing_address(PhysAddr::new(phys_addr + (size as u64))),
PhysFrame::containing_address(phys_addr),
PhysFrame::containing_address(phys_addr + (size as u64)),
),
MemAttr::MEM_ATTR_READ,
)?;
debug_serial_println!("VSM: Ring buffer allocated");
if let Ok((page_addr, _)) =
crate::platform_low().map_vtl0_phys_range(
phys_addr,
phys_addr + size.try_into().unwrap(),
PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::NO_EXECUTE) {
set_ringbuffer(page_addr, size);
} else {
return Err(VsmError::MapVtl0PhysRangeFailed);
}
debug_serial_println!("VSM: Ringbuffer initialized");
Ok(0)
}

Expand Down
Loading