mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
devices: refactor TPM CRB helpers
Extract CRB completion, register-read, and data-buffer range handling so the fixed access rules can be tested without a live TPM backend. Assisted-by: Copilot:GPT-5.5 Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
@@ -232,6 +232,31 @@ fn update_reg(regs: &mut [u32; TPM_CRB_R_MAX], offset: u32, data: &[u8]) -> u32
|
||||
regs[reg_offset]
|
||||
}
|
||||
|
||||
fn read_reg_value(value: u32, offset: u32) -> u32 {
|
||||
let byte_offset = (offset & 0x3) as usize;
|
||||
|
||||
value >> (byte_offset * 8)
|
||||
}
|
||||
|
||||
fn complete_request(regs: &mut [u32; TPM_CRB_R_MAX], success: bool) {
|
||||
regs[CRB_CTRL_START as usize] &= !CRB_START_INVOKE;
|
||||
if !success {
|
||||
set_reg_field(regs, CrbRegister::CtrlSts(CtrlStsFields::TpmSts), 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn data_buffer_range(offset: u32, len: usize, buffer_len: usize) -> Option<std::ops::Range<usize>> {
|
||||
let end_offset = offset.checked_add(len as u32)?;
|
||||
let buffer_end = CRB_DATA_BUFFER.checked_add(buffer_len as u32)?;
|
||||
|
||||
if offset >= CRB_DATA_BUFFER && end_offset <= buffer_end {
|
||||
let start = (offset - CRB_DATA_BUFFER) as usize;
|
||||
Some(start..start + len)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Tpm {
|
||||
emulator: Emulator,
|
||||
regs: [u32; TPM_CRB_R_MAX],
|
||||
@@ -270,14 +295,7 @@ impl Tpm {
|
||||
}
|
||||
|
||||
fn request_completed(&mut self, success: bool) {
|
||||
self.regs[CRB_CTRL_START as usize] &= !CRB_START_INVOKE;
|
||||
if !success {
|
||||
set_reg_field(
|
||||
&mut self.regs,
|
||||
CrbRegister::CtrlSts(CtrlStsFields::TpmSts),
|
||||
1,
|
||||
);
|
||||
}
|
||||
complete_request(&mut self.regs, success);
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> Result<()> {
|
||||
@@ -365,13 +383,9 @@ impl BusDevice for Tpm {
|
||||
let mut offset: u32 = offset as u32;
|
||||
let read_len: usize = data.len();
|
||||
|
||||
if offset >= CRB_DATA_BUFFER
|
||||
&& (offset + read_len as u32) <= (CRB_DATA_BUFFER + self.data_buff.len() as u32)
|
||||
{
|
||||
if let Some(range) = data_buffer_range(offset, read_len, self.data_buff.len()) {
|
||||
// Read from Data Buffer
|
||||
let start: usize = (offset as usize) - (CRB_DATA_BUFFER as usize);
|
||||
let end: usize = start + read_len;
|
||||
data[..].clone_from_slice(&self.data_buff[start..end]);
|
||||
data[..].clone_from_slice(&self.data_buff[range]);
|
||||
} else {
|
||||
offset &= 0xff;
|
||||
let reg_offset = offset & !0x3;
|
||||
@@ -383,12 +397,10 @@ impl BusDevice for Tpm {
|
||||
if reg_offset == CRB_LOC_STATE && self.emulator.get_established_bit() {
|
||||
val |= 0x1;
|
||||
}
|
||||
val = read_reg_value(val, offset);
|
||||
|
||||
if data.len() <= 4 {
|
||||
let byte_offset = (offset & 0x3) as usize;
|
||||
data.clone_from_slice(
|
||||
(val >> (byte_offset * 8)).to_ne_bytes()[0..read_len].as_ref(),
|
||||
);
|
||||
data.clone_from_slice(val.to_ne_bytes()[0..read_len].as_ref());
|
||||
} else {
|
||||
error!(
|
||||
"Invalid tpm read: offset {:#X}, data length {:?}",
|
||||
@@ -419,17 +431,14 @@ impl BusDevice for Tpm {
|
||||
let locality = locality_from_addr(offset) as u32;
|
||||
let write_len = data.len();
|
||||
|
||||
if offset >= CRB_DATA_BUFFER
|
||||
&& (offset + write_len as u32) <= (CRB_DATA_BUFFER + self.data_buff.len() as u32)
|
||||
{
|
||||
let start: usize = (offset as usize) - (CRB_DATA_BUFFER as usize);
|
||||
if let Some(range) = data_buffer_range(offset, write_len, self.data_buff.len()) {
|
||||
let start = range.start;
|
||||
if start == 0 {
|
||||
// If filling data_buff at index 0, reset length to 0
|
||||
self.data_buff_len = 0;
|
||||
self.data_buff.fill(0);
|
||||
}
|
||||
let end: usize = start + data.len();
|
||||
self.data_buff[start..end].clone_from_slice(data);
|
||||
self.data_buff[range].clone_from_slice(data);
|
||||
self.data_buff_len += data.len();
|
||||
} else {
|
||||
// Ctrl Commands that take more than 4 bytes as input are not yet supported
|
||||
|
||||
Reference in New Issue
Block a user