Skip to content

Commit

Permalink
spdm_transport: generic: refactor IO buffers
Browse files Browse the repository at this point in the history
This allows us to remove alot of repeated code for buffer `set/get`. This
approach uses a heap allocated vector and just passes a reference to
`libspdm` when required.

The assocaited memory shall be explicitly freed
by taking ownership when the buffer are no longer required. Which can be
done by calling `libspdm_drop_io_buffers()`.

Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
  • Loading branch information
twilfredo committed Oct 31, 2024
1 parent 7ad6129 commit d7cf66f
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 683 deletions.
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
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
142 changes: 5 additions & 137 deletions src/qemu_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! to implement and emulate an SPDM responder.
//!
use crate::io_buffers;
use crate::spdm::TransportLayer;
use crate::*;
use libspdm::spdm::LIBSPDM_MAX_SPDM_MSG_SIZE;
Expand All @@ -22,10 +23,6 @@ const SOCKET_SPDM_COMMAND_NORMAL: u32 = 0x01;

const SOCKET_TRANSPORT_TYPE_MCTP: u32 = 0x01;
const SOCKET_TRANSPORT_TYPE_PCI_DOE: u32 = 0x02;

static mut SEND_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();

static mut CLIENT_CONNECTION: OnceCell<TcpStream> = OnceCell::new();

/// # Summary
Expand Down Expand Up @@ -326,119 +323,6 @@ unsafe extern "C" fn qemu_receive_message_mctp(
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 qemu_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 qemu_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 qemu_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 qemu_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 `qemu_server` backend.
Expand All @@ -455,8 +339,6 @@ pub fn register_device(
port: u16,
transport: TransportLayer,
) -> Result<(), ()> {
let buffer_send = [0; SEND_RECEIVE_BUFFER_LEN];
let buffer_receive = [0; SEND_RECEIVE_BUFFER_LEN];
let ip = "127.0.0.1";
let addr = format!("{}:{}", ip, port);

Expand Down Expand Up @@ -496,15 +378,6 @@ pub fn register_device(
}

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 receive buffer: {e:?}");
()
})?;

match transport {
TransportLayer::Doe => {
libspdm_register_device_io_func(
Expand All @@ -521,16 +394,11 @@ pub fn register_device(
);
}
}

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(qemu_acquire_sender_buffer),
Some(qemu_release_sender_buffer),
Some(qemu_acquire_receiver_buffer),
Some(qemu_release_receiver_buffer),
);
SEND_RECEIVE_BUFFER_LEN,
SEND_RECEIVE_BUFFER_LEN,
)?;
}

Ok(())
Expand Down
Loading

0 comments on commit d7cf66f

Please sign in to comment.