Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spdm_transport: generic: refactor IO buffers #120

Merged
merged 1 commit into from
Nov 8, 2024
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
140 changes: 4 additions & 136 deletions src/doe_pci_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ use std::slice::{from_raw_parts, from_raw_parts_mut};
const SEND_RECEIVE_BUFFER_LEN: usize = LIBSPDM_MAX_SPDM_MSG_SIZE as usize;
const LIBSPDM_STATUS_ERROR_PEER: u32 =
libspdm_status_construct!(LIBSPDM_SEVERITY_ERROR, LIBSPDM_SOURCE_CORE, 0x000a);
static mut SEND_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();

const DOE_CONTROL: i32 = 0x08;
const DOE_CONTROL_GO: u32 = 1 << 31;
Expand Down Expand Up @@ -180,122 +178,6 @@ unsafe extern "C" fn doe_pci_cfg_receive_message(
0
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = SEND_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the SEND_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the sender buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_release_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

SEND_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = RECEIVE_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the RECEIVE_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the receiver buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_release_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

RECEIVE_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// Registers the SPDM `context` for a PCIe DOE backend.
Expand All @@ -314,21 +196,11 @@ unsafe extern "C" fn doe_pci_cfg_release_receiver_buffer(
///
/// Panics if `SEND_BUFFER/RECEIVE_BUFFER` is occupied
pub fn register_device(context: *mut c_void, pcie_vid: u16, pcie_devid: u16) -> Result<(), ()> {
let buffer_send = [0; SEND_RECEIVE_BUFFER_LEN];
let buffer_receive = [0; SEND_RECEIVE_BUFFER_LEN];
let pcie_ids = PcieIdentifiers {
vid: pcie_vid,
devid: pcie_devid,
};
unsafe {
SEND_BUFFER.set(buffer_send).map_err(|e| {
error!("Failed to set send buffer: {e:?}");
()
})?;
RECEIVE_BUFFER.set(buffer_receive).map_err(|e| {
error!("Failed to set receive buffer: {e:?}");
()
})?;
PCIE_IDENTIFIERS.set(pcie_ids).map_err(|e| {
error!("Failed to set device PCIe Identifiers: {e:?}");
()
Expand All @@ -339,15 +211,11 @@ pub fn register_device(context: *mut c_void, pcie_vid: u16, pcie_devid: u16) ->
Some(doe_pci_cfg_send_message),
Some(doe_pci_cfg_receive_message),
);
libspdm_register_device_buffer_func(
io_buffers::libspdm_setup_io_buffers(
context,
SEND_RECEIVE_BUFFER_LEN as u32,
SEND_RECEIVE_BUFFER_LEN as u32,
Some(doe_pci_cfg_acquire_sender_buffer),
Some(doe_pci_cfg_release_sender_buffer),
Some(doe_pci_cfg_acquire_receiver_buffer),
Some(doe_pci_cfg_release_receiver_buffer),
);
SEND_RECEIVE_BUFFER_LEN,
SEND_RECEIVE_BUFFER_LEN,
)?;
}

Ok(())
Expand Down
125 changes: 125 additions & 0 deletions src/io_buffers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
use once_cell::sync::OnceCell;
use std::ffi::c_void;

static mut SEND_BUFFER: OnceCell<Vec<u8>> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<Vec<u8>> = OnceCell::new();

pub fn libspdm_setup_io_buffers(
context: *mut c_void,
send_recv_len: usize,
libsdpm_buff_len: usize,
) -> Result<(), ()> {
let result = std::panic::catch_unwind(|| {
let buffer_send = vec![0; send_recv_len];
let buffer_receive = vec![0; send_recv_len];
(buffer_send, buffer_receive)
});

match result {
Ok(buffers) => {
unsafe {
SEND_BUFFER.set(buffers.0).map_err(|_| {
error!("Failed to set send buffer");
()
})?;
RECEIVE_BUFFER.set(buffers.1).map_err(|_| {
error!("Failed to set receive buffer");
()
})?;
}

unsafe {
libspdm::libspdm_rs::libspdm_register_device_buffer_func(
context,
libsdpm_buff_len as u32,
libsdpm_buff_len as u32,
Some(acquire_sender_buffer),
Some(release_sender_buffer),
Some(acquire_receiver_buffer),
Some(release_receiver_buffer),
)
}
Ok(())
}
Err(_) => {
error!("Failed to allocate transport buffers");
Err(())
}
}
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
#[no_mangle]
pub unsafe extern "C" fn acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
if let Some(buffer) = SEND_BUFFER.get() {
let buf_ptr = buffer.as_ptr() as *mut c_void;
*msg_buf_ptr = buf_ptr;
return 0;
}
error!("Sender buffer is lost or not initialized");
return 1;
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
#[no_mangle]
pub unsafe extern "C" fn acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
if let Some(buffer) = RECEIVE_BUFFER.get() {
let buf_ptr = buffer.as_ptr() as *mut c_void;
*msg_buf_ptr = buf_ptr;
return 0;
}
error!("Receiver buffer is lost or not initialized");
return 1;
}

/// We are only passing a reference to heap allocated memory, no-op required
#[no_mangle]
pub unsafe extern "C" fn release_receiver_buffer(
_context: *mut c_void,
_msg_buf_ptr: *const c_void,
) {
}

/// We are only passing a reference to heap allocated memory, no-op required
#[no_mangle]
pub unsafe extern "C" fn release_sender_buffer(_context: *mut c_void, _msg_buf_ptr: *const c_void) {
}

/// # Summary
///
/// Take ownership of the IO buffer and drop them out of context allowing the
/// underlying memory to be freed.
pub unsafe fn libspdm_drop_io_buffers() {
if let Some(_) = SEND_BUFFER.take() {}
if let Some(_) = RECEIVE_BUFFER.take() {}
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub static SOCKET_PATH: &str = "SPDM-Utils-loopback-socket";

mod cli_helpers;
mod doe_pci_cfg;
mod io_buffers;
mod qemu_server;
mod request;
mod socket_client;
Expand Down Expand Up @@ -890,6 +891,7 @@ async fn main() -> Result<(), ()> {
}
}
}
unsafe { io_buffers::libspdm_drop_io_buffers() }
Ok(())
}

Expand Down
Loading
Loading