Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,7 @@ It supports the following attributes:
Must be be between 4KiB and 16MiB and be 4K page-aligned. Defaults to 8KiB.
* `cpu`: (optional) set the physical CPU core this PD will run on. Defaults to zero.
* `smc`: (optional, only on ARM) Allow the PD to give an SMC call for the kernel to perform.. Defaults to false.
* `fpu`: (optional) disable the FPU support for this PD. Defaults to true.

Additionally, it supports the following child elements:

Expand Down
5 changes: 4 additions & 1 deletion tool/microkit/src/capdl/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ impl CapDLSpecContainer {
prio: 0,
max_prio: 0,
resume: false,
fpu: true,
ip: entry_point.into(),
sp: 0.into(),
gprs: Vec::new(),
Expand Down Expand Up @@ -468,7 +469,7 @@ pub fn build_capdl_spec(
)
.unwrap();

// At this point, all of the required objects for the monitor have been created and it caps inserted into
// At this point, all of the required objects for the monitor have been created and its caps inserted into
// the correct slot in the CSpace. We need to bind those objects into the TCB for the monitor to use them.
// In addition, `add_elf_to_spec()` doesn't fill most the details in the TCB.
// Now fill them in: stack ptr, priority, ipc buf vaddr, etc.
Expand Down Expand Up @@ -911,6 +912,7 @@ pub fn build_capdl_spec(
affinity: Word(vcpu.cpu.0.into()),
prio: virtual_machine.priority,
max_prio: virtual_machine.priority,
fpu: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably have a VM fpu attribute here too

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very small chance anyone would want to disable the FPU for a VM though.

Also, this wouldn't work for x86, where the flag is used for the host task and the FPU is always enabled for the guest itself.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it it will be refined at a later step during the system setup as mentioned below:

As discussed offline, fpu: true is fine here. As this function's purpose is to only create what can be inferred from just the ELF, while leaving everything else with reasonable defaults. Refining the TCB will happen at a later step in the caller at

// Step 3-14 Set the TCB parameters and all the various caps that we need to bind to this TCB.

resume: false,
// VMs do not have program images associated with them so these are always zero.
ip: Word(0),
Expand Down Expand Up @@ -979,6 +981,7 @@ pub fn build_capdl_spec(
pd_tcb.extra.master_fault_ep = None; // Not used on MCS kernel.
pd_tcb.extra.prio = pd.priority;
pd_tcb.extra.max_prio = pd.priority;
pd_tcb.extra.fpu = pd.fpu;
pd_tcb.extra.resume = true;

pd_tcb.slots.extend(caps_to_bind_to_tcb);
Expand Down
17 changes: 17 additions & 0 deletions tool/microkit/src/sdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ pub struct ProtectionDomain {
pub smc: bool,
pub cpu: CpuCore,
pub program_image: PathBuf,
/// Enable FPU for this PD.
pub fpu: bool,
pub maps: Vec<SysMap>,
pub irqs: Vec<SysIrq>,
pub ioports: Vec<IOPort>,
Expand Down Expand Up @@ -456,6 +458,7 @@ impl ProtectionDomain {
// but we do the error-checking further down.
"smc",
"cpu",
"fpu",
];
if is_child {
attrs.push("id");
Expand Down Expand Up @@ -607,6 +610,19 @@ impl ProtectionDomain {
));
}

// FPU is enabled by default
let fpu = if let Some(xml_fpu) = node.attribute("fpu") {
match str_to_bool(xml_fpu) {
Some(val) => val,
None => {
return Err(value_error(xml_sdf, node, "fpu must be 'true' or 'false'".to_string(),))
}
}
} else {
// Default to fpu enabled
true
};

for child in node.children() {
if !child.is_element() {
continue;
Expand Down Expand Up @@ -1074,6 +1090,7 @@ impl ProtectionDomain {
smc,
cpu,
program_image: program_image.unwrap(),
fpu,
maps,
irqs,
ioports,
Expand Down
10 changes: 10 additions & 0 deletions tool/microkit/tests/sdf/wrong_fpu_flag_value.system
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2025, UNSW

SPDX-License-Identifier: BSD-2-Clause
-->
<system>
<protection_domain name="test" fpu="foo">
</protection_domain>
</system>
9 changes: 9 additions & 0 deletions tool/microkit/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,4 +828,13 @@ mod system {
"Error: too many protection domains (64) defined. Maximum is 63.",
)
}

#[test]
fn test_fpu_flag_wrong_value() {
check_error(
&DEFAULT_AARCH64_KERNEL_CONFIG,
"wrong_fpu_flag_value.system",
"Error: fpu must be 'true' or 'false'",
)
}
}