Skip to content

Commit b63aff5

Browse files
Name VM TCBs in debug mode as well
Signed-off-by: Ivan-Velickovic <i.velickovic@unsw.edu.au>
1 parent dc10ac5 commit b63aff5

File tree

4 files changed

+73
-33
lines changed

4 files changed

+73
-33
lines changed

monitor/src/main.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565
#include "util.h"
6666
#include "debug.h"
6767

68+
#define MAX_VMS 64
6869
#define MAX_PDS 64
6970
#define MAX_NAME_LEN 64
70-
#define MAX_TCBS 64
7171

7272
#define MAX_UNTYPED_REGIONS 256
7373

@@ -87,12 +87,15 @@ char _stack[4096];
8787

8888
static char pd_names[MAX_PDS][MAX_NAME_LEN];
8989
seL4_Word pd_names_len;
90+
static char vm_names[MAX_VMS][MAX_NAME_LEN];
91+
seL4_Word vm_names_len;
9092

9193
seL4_Word fault_ep;
9294
seL4_Word reply;
93-
seL4_Word tcbs[MAX_TCBS];
94-
seL4_Word scheduling_contexts[MAX_TCBS];
95-
seL4_Word notification_caps[MAX_TCBS];
95+
seL4_Word pd_tcbs[MAX_PDS];
96+
seL4_Word vm_tcbs[MAX_VMS];
97+
seL4_Word scheduling_contexts[MAX_PDS];
98+
seL4_Word notification_caps[MAX_PDS];
9699

97100
/* For reporting potential stack overflows, keep track of the stack regions for each PD. */
98101
seL4_Word pd_stack_addrs[MAX_PDS];
@@ -806,7 +809,7 @@ static void monitor(void)
806809
tag = seL4_Recv(fault_ep, &badge, reply);
807810
label = seL4_MessageInfo_get_label(tag);
808811

809-
seL4_Word tcb_cap = tcbs[badge];
812+
seL4_Word tcb_cap = pd_tcbs[badge];
810813

811814
if (label == seL4_Fault_NullFault && badge < MAX_PDS) {
812815
/* This is a request from our PD to become passive */
@@ -970,7 +973,7 @@ void main(seL4_BootInfo *bi)
970973

971974
#if CONFIG_DEBUG_BUILD
972975
/*
973-
* Assign PD names to each TCB with seL4, this helps debugging when an error
976+
* Assign PD/VM names to each TCB with seL4, this helps debugging when an error
974977
* message is printed by seL4 or if we dump the scheduler state.
975978
* This is done specifically in the monitor rather than being prepared as an
976979
* invocation like everything else because it is technically a separate system
@@ -979,7 +982,10 @@ void main(seL4_BootInfo *bi)
979982
* support in the tooling and make the monitor generic.
980983
*/
981984
for (unsigned idx = 1; idx < pd_names_len + 1; idx++) {
982-
seL4_DebugNameThread(tcbs[idx], pd_names[idx]);
985+
seL4_DebugNameThread(pd_tcbs[idx], pd_names[idx]);
986+
}
987+
for (unsigned idx = 1; idx < vm_names_len + 1; idx++) {
988+
seL4_DebugNameThread(vm_tcbs[idx], vm_names[idx]);
983989
}
984990
#endif
985991

tool/microkit/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ use sel4::BootInfo;
1414
use std::cmp::min;
1515
use std::fmt;
1616

17-
// Note that this value is used in the monitor so should also be changed there
18-
// if this was to change.
17+
// Note that these values are used in the monitor so should also be changed there
18+
// if any of these were to change.
1919
pub const MAX_PDS: usize = 63;
20+
pub const MAX_VMS: usize = 63;
2021
// It should be noted that if you were to change the value of
21-
// the maximum PD name length, you would also have to change
22+
// the maximum PD/VM name length, you would also have to change
2223
// the monitor and libmicrokit.
2324
pub const PD_MAX_NAME_LENGTH: usize = 64;
25+
pub const VM_MAX_NAME_LENGTH: usize = 64;
2426

2527
#[derive(Debug, Copy, Clone, PartialEq)]
2628
pub struct UntypedObject {

tool/microkit/src/main.rs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use elf::ElfFile;
1111
use loader::Loader;
1212
use microkit_tool::{
1313
elf, loader, sdf, sel4, util, DisjointMemoryRegion, MemoryRegion, ObjectAllocator, Region,
14-
UntypedObject, MAX_PDS, PD_MAX_NAME_LENGTH,
14+
UntypedObject, MAX_PDS, MAX_VMS, PD_MAX_NAME_LENGTH, VM_MAX_NAME_LENGTH,
1515
};
1616
use sdf::{
1717
parse, ProtectionDomain, SysMap, SysMapPerms, SysMemoryRegion, SystemDescription,
@@ -31,7 +31,7 @@ use std::mem::size_of;
3131
use std::path::{Path, PathBuf};
3232
use util::{
3333
bytes_to_struct, comma_sep_u64, comma_sep_usize, json_str, json_str_as_bool, json_str_as_u64,
34-
monitor_serialise_u64_vec, struct_to_bytes,
34+
monitor_serialise_names, monitor_serialise_u64_vec, struct_to_bytes,
3535
};
3636

3737
// Corresponds to the IPC buffer symbol in libmicrokit and the monitor
@@ -448,7 +448,8 @@ struct BuiltSystem {
448448
fault_ep_cap_address: u64,
449449
reply_cap_address: u64,
450450
cap_lookup: HashMap<u64, String>,
451-
tcb_caps: Vec<u64>,
451+
pd_tcb_caps: Vec<u64>,
452+
vm_tcb_caps: Vec<u64>,
452453
sched_caps: Vec<u64>,
453454
ntfn_caps: Vec<u64>,
454455
pd_elf_regions: Vec<Vec<Region>>,
@@ -2864,7 +2865,8 @@ fn build_system(
28642865
fault_ep_cap_address: fault_ep_endpoint_object.cap_addr,
28652866
reply_cap_address: reply_obj.cap_addr,
28662867
cap_lookup: cap_address_names,
2867-
tcb_caps: tcb_caps[..system.protection_domains.len()].to_vec(),
2868+
pd_tcb_caps: tcb_caps[..system.protection_domains.len()].to_vec(),
2869+
vm_tcb_caps: tcb_caps[system.protection_domains.len()..].to_vec(),
28682870
sched_caps: sched_context_caps,
28692871
ntfn_caps: notification_caps,
28702872
pd_elf_regions,
@@ -3534,38 +3536,42 @@ fn main() -> Result<(), String> {
35343536
&bootstrap_invocation_data,
35353537
)?;
35363538

3537-
let tcb_cap_bytes = monitor_serialise_u64_vec(&built_system.tcb_caps);
3539+
let pd_tcb_cap_bytes = monitor_serialise_u64_vec(&built_system.pd_tcb_caps);
3540+
let vm_tcb_cap_bytes = monitor_serialise_u64_vec(&built_system.vm_tcb_caps);
35383541
let sched_cap_bytes = monitor_serialise_u64_vec(&built_system.sched_caps);
35393542
let ntfn_cap_bytes = monitor_serialise_u64_vec(&built_system.ntfn_caps);
35403543
let pd_stack_addrs_bytes = monitor_serialise_u64_vec(&built_system.pd_stack_addrs);
35413544

35423545
monitor_elf.write_symbol("fault_ep", &built_system.fault_ep_cap_address.to_le_bytes())?;
35433546
monitor_elf.write_symbol("reply", &built_system.reply_cap_address.to_le_bytes())?;
3544-
monitor_elf.write_symbol("tcbs", &tcb_cap_bytes)?;
3547+
monitor_elf.write_symbol("pd_tcbs", &pd_tcb_cap_bytes)?;
3548+
monitor_elf.write_symbol("vm_tcbs", &vm_tcb_cap_bytes)?;
35453549
monitor_elf.write_symbol("scheduling_contexts", &sched_cap_bytes)?;
35463550
monitor_elf.write_symbol("notification_caps", &ntfn_cap_bytes)?;
35473551
monitor_elf.write_symbol("pd_stack_addrs", &pd_stack_addrs_bytes)?;
3548-
// We do MAX_PDS + 1 due to the index that the monitor uses (the badge) starting at 1.
3549-
let mut pd_names_bytes = vec![0; (MAX_PDS + 1) * PD_MAX_NAME_LENGTH];
3550-
for (i, pd) in system.protection_domains.iter().enumerate() {
3551-
// The monitor will index into the array of PD names based on the badge, which
3552-
// starts at 1 and hence we cannot use the 0th entry in the array.
3553-
let name = pd.name.as_bytes();
3554-
let start = (i + 1) * PD_MAX_NAME_LENGTH;
3555-
// Here instead of giving an error we simply take the minimum of the PD's name
3556-
// and how large of a name we can encode
3557-
let name_length = min(name.len(), PD_MAX_NAME_LENGTH);
3558-
let end = start + name_length;
3559-
pd_names_bytes[start..end].copy_from_slice(&name[..name_length]);
3560-
// These bytes will be interpreted as a C string, so we must include
3561-
// a null-terminator.
3562-
pd_names_bytes[start + PD_MAX_NAME_LENGTH - 1] = 0;
3563-
}
3564-
monitor_elf.write_symbol("pd_names", &pd_names_bytes)?;
3552+
let pd_names = system
3553+
.protection_domains
3554+
.iter()
3555+
.map(|pd| &pd.name)
3556+
.collect();
3557+
monitor_elf.write_symbol(
3558+
"pd_names",
3559+
&monitor_serialise_names(pd_names, MAX_PDS, PD_MAX_NAME_LENGTH),
3560+
)?;
35653561
monitor_elf.write_symbol(
35663562
"pd_names_len",
35673563
&system.protection_domains.len().to_le_bytes(),
35683564
)?;
3565+
let vm_names: Vec<&String> = system
3566+
.protection_domains
3567+
.iter()
3568+
.filter_map(|pd| pd.virtual_machine.as_ref().map(|vm| &vm.name))
3569+
.collect();
3570+
monitor_elf.write_symbol("vm_names_len", &vm_names.len().to_le_bytes())?;
3571+
monitor_elf.write_symbol(
3572+
"vm_names",
3573+
&monitor_serialise_names(vm_names, MAX_VMS, VM_MAX_NAME_LENGTH),
3574+
)?;
35693575

35703576
// Write out all the symbols for each PD
35713577
pd_write_symbols(

tool/microkit/src/util.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,32 @@ pub fn monitor_serialise_u64_vec(vec: &[u64]) -> Vec<u8> {
194194
bytes
195195
}
196196

197+
/// For serialising an array of PD or VM names. Pads the Vector of bytes such that
198+
/// the first entry is empty.
199+
pub fn monitor_serialise_names(
200+
names: Vec<&String>,
201+
max_len: usize,
202+
max_name_len: usize,
203+
) -> Vec<u8> {
204+
let mut names_bytes = vec![0; (max_len + 1) * max_name_len];
205+
for (i, name) in names.iter().enumerate() {
206+
// The monitor will index into the array of names based on the badge, which
207+
// starts at 1 and hence we cannot use the 0th entry in the array.
208+
let name_bytes = name.as_bytes();
209+
let start = (i + 1) * max_name_len;
210+
// Here instead of giving an error we simply take the minimum of the name
211+
// and how large of a name we can encode
212+
let name_length = std::cmp::min(name_bytes.len(), max_name_len);
213+
let end = start + name_length;
214+
names_bytes[start..end].copy_from_slice(&name_bytes[..name_length]);
215+
// These bytes will be interpreted as a C string, so we must include
216+
// a null-terminator.
217+
names_bytes[start + max_name_len - 1] = 0;
218+
}
219+
220+
names_bytes
221+
}
222+
197223
#[cfg(test)]
198224
mod tests {
199225
// Note this useful idiom: importing names from outer (for mod tests) scope.

0 commit comments

Comments
 (0)