-
Notifications
You must be signed in to change notification settings - Fork 72
aarch64: Restrict address mappings in loader.rs #464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -485,20 +485,64 @@ impl<'a> Loader<'a> { | |
| let (boot_lvl0_upper_addr, boot_lvl0_upper_size) = elf | ||
| .find_symbol("boot_lvl0_upper") | ||
| .expect("Could not find 'boot_lvl0_upper' symbol"); | ||
| let (boot_lvl2_lower_addr, boot_lvl2_lower_size) = elf | ||
| .find_symbol("boot_lvl2_lower") | ||
| .expect("Could not find 'boot_lvl2_lower' symbol"); | ||
| let (start_addr, _) = elf | ||
| .find_symbol("_loader_start") | ||
| .expect("Could not find 'loader_start' symbol"); | ||
| let (end_addr, _) = elf | ||
| .find_symbol("_loader_end") | ||
| .expect("Could not find 'loader_end' symbol"); | ||
|
|
||
| if Aarch64::lvl1_index(start_addr) != Aarch64::lvl1_index(end_addr) { | ||
| panic!("We only map 1GiB, but elfloader paddr range covers multiple GiB"); | ||
| } | ||
|
|
||
| let mut boot_lvl0_lower: [u8; PAGE_TABLE_SIZE] = [0; PAGE_TABLE_SIZE]; | ||
| boot_lvl0_lower[..8].copy_from_slice(&(boot_lvl1_lower_addr | 3).to_le_bytes()); | ||
|
|
||
| let mut boot_lvl1_lower: [u8; PAGE_TABLE_SIZE] = [0; PAGE_TABLE_SIZE]; | ||
| for i in 0..512 { | ||
|
|
||
| // map optional UART MMIO in l1 1GB page, only available if CONFIG_PRINTING | ||
| if let Ok((uart_addr, _)) = elf.find_symbol("uart_addr") { | ||
| let data = elf | ||
| .get_data(uart_addr, 8) | ||
| .expect("uart_addr not initialized"); | ||
| let uart_base = u64::from_le_bytes(data[0..8].try_into().unwrap()); | ||
|
|
||
| let lvl1_idx = Aarch64::lvl1_index(uart_base); | ||
| #[allow(clippy::identity_op)] // keep the (0 << 2) for clarity | ||
| let pt_entry: u64 = ((i as u64) << AARCH64_1GB_BLOCK_BITS) | | ||
| let pt_entry: u64 = ((lvl1_idx as u64) << AARCH64_1GB_BLOCK_BITS) | | ||
| (1 << 10) | // access flag | ||
| (0 << 2) | // strongly ordered memory | ||
| (1); // 1G block | ||
| (1 << 0); // 1G block | ||
| let start = 8 * lvl1_idx; | ||
| let end = 8 * (lvl1_idx + 1); | ||
| boot_lvl1_lower[start..end].copy_from_slice(&pt_entry.to_le_bytes()); | ||
| } | ||
|
|
||
| let mut boot_lvl2_lower: [u8; PAGE_TABLE_SIZE] = [0; PAGE_TABLE_SIZE]; | ||
|
|
||
| // 1GB lvl1 Table entry | ||
| let pt_entry = (boot_lvl2_lower_addr | 3).to_le_bytes(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we be consistent with the other examples and split out the meanings of the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This this is a 2 bit marker for the 1GB L1 table entry here, not individual bits
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, right, we do
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, better to handle it globally yes. I’ll add a comment since “3” means different things depending on the granule (page or table) |
||
| let lvl1_idx = Aarch64::lvl1_index(start_addr); | ||
| let start = 8 * lvl1_idx; | ||
| let end = 8 * (lvl1_idx + 1); | ||
| boot_lvl1_lower[start..end].copy_from_slice(&pt_entry); | ||
|
|
||
| // map the loader 1:1 access into 2MB lvl2 Block entries for a 4KB granule | ||
| let lvl2_idx = Aarch64::lvl2_index(start_addr); | ||
| for i in lvl2_idx ..= Aarch64::lvl2_index(end_addr) { | ||
| let entry_idx = (i - Aarch64::lvl2_index(start_addr)) << AARCH64_2MB_BLOCK_BITS; | ||
| let pt_entry: u64 = (entry_idx as u64 + start_addr) | | ||
| (1 << 10) | // Access flag | ||
| (3 << 8) | // Sharable | ||
| (4 << 2) | // MT_NORMAL memory | ||
| (1 << 0); // 2M block | ||
| let start = 8 * i; | ||
| let end = 8 * (i + 1); | ||
| boot_lvl1_lower[start..end].copy_from_slice(&pt_entry.to_le_bytes()); | ||
| boot_lvl2_lower[start..end].copy_from_slice(&pt_entry.to_le_bytes()); | ||
| } | ||
|
|
||
| let boot_lvl0_upper: [u8; PAGE_TABLE_SIZE] = [0; PAGE_TABLE_SIZE]; | ||
|
|
@@ -536,6 +580,7 @@ impl<'a> Loader<'a> { | |
| (boot_lvl0_upper_addr, boot_lvl0_upper_size, boot_lvl0_upper), | ||
| (boot_lvl1_upper_addr, boot_lvl1_upper_size, boot_lvl1_upper), | ||
| (boot_lvl2_upper_addr, boot_lvl2_upper_size, boot_lvl2_upper), | ||
| (boot_lvl2_lower_addr, boot_lvl2_lower_size, boot_lvl2_lower), | ||
| ] | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.