Skip to content

Commit b157ad0

Browse files
committed
IOMMU: Validate IOMMU Kernel Support
Ensure that the sel4::Config struct has the iommu flag asserted, indicating the kernel was built with IOMMU support. If not we fail parsing any io address space elements encountered in the sdf. Signed-off-by: Callum <c.berry@student.unsw.edu.au>
1 parent 6871f48 commit b157ad0

5 files changed

Lines changed: 98 additions & 9 deletions

File tree

tool/microkit/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ fn main() -> Result<(), String> {
210210
_ => false,
211211
};
212212

213+
let iommu = match arch {
214+
Arch::X86_64 => json_str_as_bool(&kernel_config_json, "IOMMU")?,
215+
_ => false,
216+
};
217+
213218
let arm_pa_size_bits = match arch {
214219
Arch::Aarch64 => {
215220
if json_str_as_bool(&kernel_config_json, "ARM_PA_SIZE_BITS_40")? {
@@ -248,6 +253,7 @@ fn main() -> Result<(), String> {
248253
"MAX_NUM_BOOTINFO_UNTYPED_CAPS",
249254
)?,
250255
hypervisor,
256+
iommu,
251257
benchmark: args.config == "benchmark",
252258
num_cores: if json_str_as_bool(&kernel_config_json, "ENABLE_SMP_SUPPORT")? {
253259
json_str_as_u64(&kernel_config_json, "MAX_NUM_NODES")?

tool/microkit/src/sdf.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -696,20 +696,12 @@ impl SysMap {
696696

697697
impl SysIOMap {
698698
fn from_xml(
699-
config: &Config,
699+
_config: &Config,
700700
xml_sdf: &XmlSystemDescription,
701701
node: &roxmltree::Node,
702702
device: &str,
703703
identifier: IommuDeviceIdentifier,
704704
) -> Result<SysIOMap, String> {
705-
if config.arch != Arch::X86_64 {
706-
return Err(value_error(
707-
xml_sdf,
708-
node,
709-
"IOMMU is not yet supported on ARM and RISC-V by Microkit".to_string(),
710-
));
711-
}
712-
713705
let attrs = vec!["mr", "iovaddr", "perms"];
714706

715707
check_attributes(xml_sdf, node, &attrs)?;
@@ -771,6 +763,14 @@ impl IOAddressSpace {
771763
device_names: &mut HashSet<String>,
772764
iommu_device_identifiers: &mut HashSet<IommuDeviceIdentifier>,
773765
) -> Result<IOAddressSpace, String> {
766+
let pos = xml_sdf.doc.text_pos_at(node.range().start);
767+
if !config.iommu {
768+
return Err(format!(
769+
"Error: io address space requires seL4 to be built with IOMMU support: {}",
770+
loc_string(xml_sdf, pos)
771+
));
772+
}
773+
774774
check_attributes(xml_sdf, node, &["name", "peripheral_id"])?;
775775
let device_name = checked_lookup(xml_sdf, node, "name")?;
776776
if !device_names.insert(device_name.to_string()) {

tool/microkit/src/sel4.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ pub struct Config {
289289
pub cap_address_bits: u64,
290290
pub fan_out_limit: u64,
291291
pub max_num_bootinfo_untypeds: u64,
292+
pub iommu: bool,
292293
pub hypervisor: bool,
293294
pub benchmark: bool,
294295
pub num_cores: u8,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2026, UNSW.
4+
5+
SPDX-License-Identifier: BSD-2-Clause
6+
-->
7+
<system>
8+
<memory_region name="region" size="0x1000" />
9+
<io_address_space name="test_device" peripheral_id="0:3.0">
10+
<iomap mr="region" iovaddr="0x80_0000_0000" />
11+
</io_address_space>
12+
<protection_domain name="test">
13+
<program_image path="test" />
14+
15+
<map mr="region" vaddr="0x5_000_000" />
16+
17+
</protection_domain>
18+
</system>

tool/microkit/tests/test.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const DEFAULT_AARCH64_KERNEL_CONFIG: sel4::Config = sel4::Config {
2222
max_num_bootinfo_untypeds: 230,
2323
fan_out_limit: 256,
2424
hypervisor: true,
25+
iommu: true,
2526
benchmark: false,
2627
num_cores: 1,
2728
fpu: true,
@@ -46,6 +47,7 @@ const DEFAULT_X86_64_KERNEL_CONFIG: sel4::Config = sel4::Config {
4647
max_num_bootinfo_untypeds: 230,
4748
fan_out_limit: 256,
4849
hypervisor: true,
50+
iommu: true,
4951
benchmark: false,
5052
num_cores: 1,
5153
fpu: true,
@@ -707,6 +709,68 @@ mod protection_domain {
707709
mod iommu {
708710
use super::*;
709711

712+
#[test]
713+
fn test_iommu_missing_from_config() {
714+
check_error(
715+
&sel4::Config {
716+
iommu: false,
717+
..DEFAULT_X86_64_KERNEL_CONFIG
718+
},
719+
"iommu_missing_from_config.system",
720+
"Error: io address space requires seL4 to be built with IOMMU support: ",
721+
);
722+
}
723+
724+
#[test]
725+
fn test_iommu_missing_from_aarch64_config() {
726+
check_error(
727+
&sel4::Config {
728+
iommu: false,
729+
..DEFAULT_AARCH64_KERNEL_CONFIG
730+
},
731+
"iommu_missing_from_config.system",
732+
"Error: io address space requires seL4 to be built with IOMMU support: ",
733+
);
734+
}
735+
736+
#[test]
737+
fn test_iommu_missing_from_riscv64_config() {
738+
check_error(
739+
&sel4::Config {
740+
arch: sel4::Arch::Riscv64,
741+
iommu: false,
742+
..DEFAULT_AARCH64_KERNEL_CONFIG
743+
},
744+
"iommu_missing_from_config.system",
745+
"Error: io address space requires seL4 to be built with IOMMU support: ",
746+
);
747+
}
748+
749+
#[test]
750+
fn test_iommu_unsupported_on_aarch64() {
751+
check_error(
752+
&sel4::Config {
753+
iommu: true,
754+
..DEFAULT_AARCH64_KERNEL_CONFIG
755+
},
756+
"iommu_missing_from_config.system",
757+
"Error: failed to parse device peripheral_id '0:3.0': IOMMU device identifiers are not supported on AArch64 on element 'io_address_space':",
758+
);
759+
}
760+
761+
#[test]
762+
fn test_iommu_unsupported_on_riscv64() {
763+
check_error(
764+
&sel4::Config {
765+
arch: sel4::Arch::Riscv64,
766+
iommu: true,
767+
..DEFAULT_AARCH64_KERNEL_CONFIG
768+
},
769+
"iommu_missing_from_config.system",
770+
"Error: failed to parse device peripheral_id '0:3.0': IOMMU device identifiers are not supported on RISC-V (64-bit) on element 'io_address_space':",
771+
);
772+
}
773+
710774
#[test]
711775
fn test_out_of_bound() {
712776
check_error(

0 commit comments

Comments
 (0)