MCPcopy Create free account
hub / github.com/IBM/ACE-RISCV / initialize_memory_layout

Function initialize_memory_layout

security-monitor/src/core/initialization/mod.rs:118–150  ·  view source on GitHub ↗

Reads the layout of physical memory from the flattened device tree (FDT), splitting it (logically) into confidential and non-confidential memory region. The FDT content is trusted. # Guarantees The end of the confidential memory is not lower than the start of the confidential memory

(fdt: &FlattenedDeviceTree)

Source from the content-addressed store, hash-verified

116///
117/// The end of the confidential memory is not lower than the start of the confidential memory
118fn initialize_memory_layout(fdt: &FlattenedDeviceTree) -> Result<(ConfidentialMemoryAddress, *const usize), Error> {
119 // TODO: FDT may contain multiple regions. For now, we assume there is only one region in the FDT.
120 // This assumption is fine for the emulated environment (QEMU).
121
122 // Information read from FDT is trusted assuming we are executing as part of a measured and secure boot. So we trust that we read the
123 // correct base and size of the memory.
124 let fdt_memory_region = fdt.memory()?;
125 // Safety: We own all the memory because we are early in the boot process and have full rights to split memory according to our needs.
126 // Thus, it is fine to cast `usize` to `*mut usize`.
127 let memory_start = fdt_memory_region.base as *mut usize;
128 // In assembly that executed this initialization function splitted the memory into two regions where
129 // the second region's size is equal or greater than the first ones.
130 let non_confidential_memory_size = fdt_memory_region.size.try_into().map_err(|_| Error::InvalidMemoryBoundary())?;
131 let confidential_memory_size = non_confidential_memory_size;
132 let memory_size = non_confidential_memory_size + confidential_memory_size;
133 let memory_end = memory_start.wrapping_byte_add(memory_size) as *const usize;
134 debug!("Memory 0x{:#?}-0x{:#?}", memory_start, memory_end);
135
136 // First region of memory is defined as non-confidential memory
137 let non_confidential_memory_start = memory_start;
138 let non_confidential_memory_end = ptr_byte_add_mut(non_confidential_memory_start, non_confidential_memory_size, memory_end)
139 .map_err(|_| Error::InvalidMemoryBoundary())?;
140 debug!("Non-confidential memory 0x{:#?}-0x{:#?}", non_confidential_memory_start, non_confidential_memory_end);
141
142 // Second region of memory is defined as confidential memory
143 let confidential_memory_start = non_confidential_memory_end;
144 let confidential_memory_end = memory_end;
145 debug!("Confidential memory 0x{:#?}-0x{:#?}", confidential_memory_start, confidential_memory_end);
146
147 unsafe {
148 MemoryLayout::init(non_confidential_memory_start, non_confidential_memory_end, confidential_memory_start, confidential_memory_end)
149 }
150}
151
152/// This function is called only once during the initialization of the security
153/// monitor during the boot process. This function initializes secure monitor's

Callers 1

init_security_monitorFunction · 0.85

Calls 2

ptr_byte_add_mutFunction · 0.85
memoryMethod · 0.80

Tested by

no test coverage detected