Skip to content

Commit

Permalink
tool: check for valid mappings in virtual machines
Browse files Browse the repository at this point in the history
Forgot to do this for virtual machines as well.

Signed-off-by: Ivan-Velickovic <[email protected]>
  • Loading branch information
Ivan-Velickovic committed Oct 30, 2024
1 parent 01a2780 commit dba5260
Showing 1 changed file with 77 additions and 42 deletions.
119 changes: 77 additions & 42 deletions tool/microkit/src/sdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,31 @@ pub struct VirtualCpu {
pub id: u64,
}

trait Entity {
fn name(&self) -> &String;
fn kind(&self) -> &'static str;
}

impl Entity for ProtectionDomain {
fn name(&self) -> &String {
&self.name
}

fn kind(&self) -> &'static str {
"protection domain"
}
}

impl Entity for VirtualMachine {
fn name(&self) -> &String {
&self.name
}

fn kind(&self) -> &'static str {
"virtual machine"
}
}

impl SysMapPerms {
fn from_str(s: &str) -> Result<u8, ()> {
let mut perms = 0;
Expand Down Expand Up @@ -893,6 +918,55 @@ pub struct SystemDescription {
pub channels: Vec<Channel>,
}

fn check_maps(xml_sdf: &XmlSystemDescription, mrs: &Vec<SysMemoryRegion>, entity: &dyn Entity, maps: &Vec<SysMap>) -> Result<(), String> {
let mut checked_maps = Vec::with_capacity(maps.len());
for map in maps {
let maybe_mr = mrs.iter().find(|mr| mr.name == map.mr);
let pos = map.text_pos.unwrap();
match maybe_mr {
Some(mr) => {
if map.vaddr % mr.page_size as u64 != 0 {
return Err(format!(
"Error: invalid vaddr alignment on 'map' @ {}",
loc_string(&xml_sdf, pos)
));
}

let map_start = map.vaddr;
let map_end = map.vaddr + mr.size;
for (name, start, end) in &checked_maps {
if !(map_start >= *end || map_end <= *start) {
return Err(
format!(
"Error: map for '{}' has virtual address range [0x{:x}..0x{:x}) which overlaps with map for '{}' [0x{:x}..0x{:x}) in {} '{}' @ {}",
map.mr,
map_start,
map_end,
name,
start,
end,
entity.kind(),
entity.name(),
loc_string(&xml_sdf, map.text_pos.unwrap())
)
);
}
}
checked_maps.push((&map.mr, map_start, map_end));
}
None => {
return Err(format!(
"Error: invalid memory region name '{}' on 'map' @ {}",
map.mr,
loc_string(&xml_sdf, pos)
))
}
};
}

Ok(())
}

fn check_attributes(
xml_sdf: &XmlSystemDescription,
node: &roxmltree::Node,
Expand Down Expand Up @@ -1223,48 +1297,9 @@ pub fn parse(filename: &str, xml: &str, config: &Config) -> Result<SystemDescrip

// Ensure that all maps are correct
for pd in &pds {
let mut checked_maps = Vec::with_capacity(pd.maps.len());
for map in &pd.maps {
let maybe_mr = mrs.iter().find(|mr| mr.name == map.mr);
let pos = map.text_pos.unwrap();
match maybe_mr {
Some(mr) => {
if map.vaddr % mr.page_size as u64 != 0 {
return Err(format!(
"Error: invalid vaddr alignment on 'map' @ {}",
loc_string(&xml_sdf, pos)
));
}

let map_start = map.vaddr;
let map_end = map.vaddr + mr.size;
for (name, start, end) in &checked_maps {
if !(map_start >= *end || map_end <= *start) {
return Err(
format!(
"Error: map for '{}' has virtual address range [0x{:x}..0x{:x}) which overlaps with map for '{}' [0x{:x}..0x{:x}) in protection domain '{}' @ {}",
map.mr,
map_start,
map_end,
name,
start,
end,
pd.name,
loc_string(&xml_sdf, map.text_pos.unwrap())
)
);
}
}
checked_maps.push((&map.mr, map_start, map_end));
}
None => {
return Err(format!(
"Error: invalid memory region name '{}' on 'map' @ {}",
map.mr,
loc_string(&xml_sdf, pos)
))
}
};
check_maps(&xml_sdf, &mrs, pd, &pd.maps)?;
if let Some(vm) = &pd.virtual_machine {
check_maps(&xml_sdf, &mrs, vm, &vm.maps)?;
}
}

Expand Down

0 comments on commit dba5260

Please sign in to comment.