Skip to content

Commit

Permalink
td-shim: remove the use of Vec in e820
Browse files Browse the repository at this point in the history
Reducing the use of heap can improve the functional safety. For e820
implementation, use an fixed `MAX_E820_ENTRY` size array to replace the
vector.

Signed-off-by: Jiaqi Gao <jiaqi.gao@intel.com>
  • Loading branch information
gaojiaqi7 committed May 20, 2024
1 parent 6efea8c commit 36a587b
Showing 1 changed file with 45 additions and 15 deletions.
60 changes: 45 additions & 15 deletions td-shim/src/bin/td-shim/e820.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,30 @@
// SPDX-License-Identifier: BSD-2-Clause-Patent

use core::ptr::slice_from_raw_parts;

use alloc::vec::Vec;
use td_shim::e820::{E820Entry, E820Type};

// Linux BootParam supports 128 e820 entries, so...
const MAX_E820_ENTRY: usize = 128;

#[derive(Debug)]
pub struct E820Table {
entries: Vec<E820Entry>,
entries: [E820Entry; MAX_E820_ENTRY],
num_entries: usize,
}

#[derive(Debug)]
pub enum E820Error {
RangeAlreadyExists,
RangeNotExists,
TooManyEntries,
InvalidIndex,
}

impl Default for E820Table {
fn default() -> Self {
Self {
entries: Vec::new(),
entries: [E820Entry::default(); MAX_E820_ENTRY],
num_entries: 0,
}
}
}
Expand Down Expand Up @@ -64,8 +65,7 @@ impl E820Table {
if self.entries.len() == MAX_E820_ENTRY && !self.able_to_merge(pos, r#type, start, length) {
return Err(E820Error::TooManyEntries);
}
self.entries
.insert(pos, E820Entry::new(start, length, r#type));
self.insert_entry(pos, E820Entry::new(start, length, r#type));
self.merge();
Ok(())
}
Expand Down Expand Up @@ -108,8 +108,7 @@ impl E820Table {
}
self.entries[idx].size -= length;
self.entries[idx].addr = start + length;
self.entries
.insert(idx, E820Entry::new(start, length, r#type))
self.insert_entry(idx, E820Entry::new(start, length, r#type))?;
} else if self.entries[idx].addr + self.entries[idx].size == start + length {
// check if the new entry can be merged with the right one
if entry_num == MAX_E820_ENTRY
Expand All @@ -118,20 +117,18 @@ impl E820Table {
return Err(E820Error::TooManyEntries);
}
self.entries[idx].size -= length;
self.entries
.insert(idx + 1, E820Entry::new(start, length, r#type))
self.insert_entry(idx + 1, E820Entry::new(start, length, r#type))?;
} else {
self.entries[idx].size = start - self.entries[idx].addr;
self.entries
.insert(idx + 1, E820Entry::new(start, length, r#type));
self.entries.insert(
self.insert_entry(idx + 1, E820Entry::new(start, length, r#type))?;
self.insert_entry(
idx + 2,
E820Entry::new(
start + length,
entry_end - (start + length),
self.entries[idx].r#type.into(),
),
);
)?;
}
self.merge();
return Ok(());
Expand Down Expand Up @@ -169,14 +166,47 @@ impl E820Table {
&& self.entries[idx].r#type == self.entries[idx + 1].r#type
{
self.entries[idx].size += self.entries[idx + 1].size;
self.entries.remove(idx + 1);
self.remove_entry(idx + 1);
entry_num -= 1;
continue;
}
idx += 1;
}
}

fn insert_entry(&mut self, index: usize, entry: E820Entry) -> Result<(), E820Error> {
if index >= MAX_E820_ENTRY {
return Err(E820Error::InvalidIndex);
}
if self.num_entries >= MAX_E820_ENTRY {
return Err(E820Error::TooManyEntries);
}

// Move all entries after the index back one position
for idx in (index + 1..self.num_entries + 1).rev() {
self.entries[idx] = self.entries[idx - 1];
}

self.entries[index] = entry;
self.num_entries += 1;
Ok(())
}

fn remove_entry(&mut self, index: usize) -> Result<(), E820Error> {
if index >= MAX_E820_ENTRY {
return Err(E820Error::InvalidIndex);
}

// Move all entries after the index forward one position
for idx in index + 1..self.num_entries {
self.entries[idx - 1] = self.entries[idx];
}

self.entries[self.num_entries - 1] = E820Entry::default();
self.num_entries -= 1;
Ok(())
}

pub fn as_slice(&self) -> &[E820Entry] {
&self.entries
}
Expand Down

0 comments on commit 36a587b

Please sign in to comment.