diff --git a/11_virtual_memory/README.md b/11_virtual_memory/README.md index 4d8b8d01..df126ca8 100644 --- a/11_virtual_memory/README.md +++ b/11_virtual_memory/README.md @@ -265,7 +265,7 @@ make chainbot diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/aarch64/mmu.rs --- 10_privilege_level/src/arch/aarch64/mmu.rs +++ 11_virtual_memory/src/arch/aarch64/mmu.rs -@@ -0,0 +1,316 @@ +@@ -0,0 +1,300 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter @@ -347,18 +347,22 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + ] +} + -+// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into -+// a PageDescriptor slot in `struct PageTables`, and vice versa. ++const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024) ++const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) ++ ++/// A table descriptor for 64 KiB aperture. ++/// ++/// The output points to the next table. +#[derive(Copy, Clone)] +#[repr(transparent)] -+struct RawTableDescriptor(u64); ++struct TableDescriptor(u64); + ++/// A page descriptor with 64 KiB aperture. ++/// ++/// The output points to physical memory. +#[derive(Copy, Clone)] +#[repr(transparent)] -+struct RawPageDescriptor(u64); -+ -+const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024) -+const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) ++struct PageDescriptor(u64); + +/// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned, +/// hence the "reverse" order of appearance. @@ -366,9 +370,9 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ +#[repr(align(65536))] +struct PageTables { + // Page descriptors, covering 64 KiB windows per entry. -+ lvl3: [[RawPageDescriptor; 8192]; N], ++ lvl3: [[PageDescriptor; 8192]; N], + // Table descriptors, covering 512 MiB windows. -+ lvl2: [RawTableDescriptor; N], ++ lvl2: [TableDescriptor; N], +} + +/// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4. @@ -378,8 +382,8 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ +/// +/// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. +static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables { -+ lvl3: [[RawPageDescriptor(0); 8192]; ENTRIES_512_MIB], -+ lvl2: [RawTableDescriptor(0); ENTRIES_512_MIB], ++ lvl3: [[PageDescriptor(0); 8192]; ENTRIES_512_MIB], ++ lvl2: [TableDescriptor(0); ENTRIES_512_MIB], +}; + +trait BaseAddr { @@ -397,24 +401,15 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + } +} + -+/// A descriptor pointing to the next page table. -+struct TableDescriptor(register::FieldValue); -+ -+impl TableDescriptor { -+ fn new(next_lvl_table_addr: usize) -> TableDescriptor { ++impl convert::From for TableDescriptor { ++ fn from(next_lvl_table_addr: usize) -> Self { + let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT; ++ let val = (STAGE1_TABLE_DESCRIPTOR::VALID::True ++ + STAGE1_TABLE_DESCRIPTOR::TYPE::Table ++ + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64)) ++ .value; + -+ TableDescriptor( -+ STAGE1_TABLE_DESCRIPTOR::VALID::True -+ + STAGE1_TABLE_DESCRIPTOR::TYPE::Table -+ + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64), -+ ) -+ } -+} -+ -+impl convert::From for RawTableDescriptor { -+ fn from(desc: TableDescriptor) -> Self { -+ RawTableDescriptor(desc.0.value) ++ TableDescriptor(val) + } +} + @@ -452,28 +447,17 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + } +} + -+/// A page descriptor with 64 KiB aperture. -+/// -+/// The output points to physical memory. -+struct PageDescriptor(register::FieldValue); -+ +impl PageDescriptor { + fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor { + let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT; -+ -+ PageDescriptor( -+ STAGE1_PAGE_DESCRIPTOR::VALID::True -+ + STAGE1_PAGE_DESCRIPTOR::AF::True -+ + attribute_fields.into() -+ + STAGE1_PAGE_DESCRIPTOR::TYPE::Table -+ + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64), -+ ) -+ } -+} -+ -+impl convert::From for RawPageDescriptor { -+ fn from(desc: PageDescriptor) -> Self { -+ RawPageDescriptor(desc.0.value) ++ let val = (STAGE1_PAGE_DESCRIPTOR::VALID::True ++ + STAGE1_PAGE_DESCRIPTOR::AF::True ++ + attribute_fields.into() ++ + STAGE1_PAGE_DESCRIPTOR::TYPE::Table ++ + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64)) ++ .value; ++ ++ PageDescriptor(val) + } +} + @@ -505,7 +489,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ +/// - Modifies a `static mut`. Ensure it only happens from here. +unsafe fn populate_pt_entries() -> Result<(), &'static str> { + for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { -+ *l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); ++ *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); + + for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { + let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); @@ -513,7 +497,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + let (output_addr, attribute_fields) = + bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; + -+ *l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); ++ *l3_entry = PageDescriptor::new(output_addr, attribute_fields); + } + } + diff --git a/11_virtual_memory/kernel b/11_virtual_memory/kernel index a319a0bd..5d939853 100755 Binary files a/11_virtual_memory/kernel and b/11_virtual_memory/kernel differ diff --git a/11_virtual_memory/src/arch/aarch64/mmu.rs b/11_virtual_memory/src/arch/aarch64/mmu.rs index a81e68de..34d5f71e 100644 --- a/11_virtual_memory/src/arch/aarch64/mmu.rs +++ b/11_virtual_memory/src/arch/aarch64/mmu.rs @@ -79,18 +79,22 @@ register_bitfields! {u64, ] } -// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into -// a PageDescriptor slot in `struct PageTables`, and vice versa. +const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024) +const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) + +/// A table descriptor for 64 KiB aperture. +/// +/// The output points to the next table. #[derive(Copy, Clone)] #[repr(transparent)] -struct RawTableDescriptor(u64); +struct TableDescriptor(u64); +/// A page descriptor with 64 KiB aperture. +/// +/// The output points to physical memory. #[derive(Copy, Clone)] #[repr(transparent)] -struct RawPageDescriptor(u64); - -const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024) -const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) +struct PageDescriptor(u64); /// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned, /// hence the "reverse" order of appearance. @@ -98,9 +102,9 @@ const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) #[repr(align(65536))] struct PageTables { // Page descriptors, covering 64 KiB windows per entry. - lvl3: [[RawPageDescriptor; 8192]; N], + lvl3: [[PageDescriptor; 8192]; N], // Table descriptors, covering 512 MiB windows. - lvl2: [RawTableDescriptor; N], + lvl2: [TableDescriptor; N], } /// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4. @@ -110,8 +114,8 @@ const ENTRIES_512_MIB: usize = bsp::addr_space_size() >> FIVETWELVE_MIB_SHIFT; /// /// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables { - lvl3: [[RawPageDescriptor(0); 8192]; ENTRIES_512_MIB], - lvl2: [RawTableDescriptor(0); ENTRIES_512_MIB], + lvl3: [[PageDescriptor(0); 8192]; ENTRIES_512_MIB], + lvl2: [TableDescriptor(0); ENTRIES_512_MIB], }; trait BaseAddr { @@ -129,24 +133,15 @@ impl BaseAddr for [T; N] { } } -/// A descriptor pointing to the next page table. -struct TableDescriptor(register::FieldValue); - -impl TableDescriptor { - fn new(next_lvl_table_addr: usize) -> TableDescriptor { +impl convert::From for TableDescriptor { + fn from(next_lvl_table_addr: usize) -> Self { let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT; + let val = (STAGE1_TABLE_DESCRIPTOR::VALID::True + + STAGE1_TABLE_DESCRIPTOR::TYPE::Table + + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64)) + .value; - TableDescriptor( - STAGE1_TABLE_DESCRIPTOR::VALID::True - + STAGE1_TABLE_DESCRIPTOR::TYPE::Table - + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64), - ) - } -} - -impl convert::From for RawTableDescriptor { - fn from(desc: TableDescriptor) -> Self { - RawTableDescriptor(desc.0.value) + TableDescriptor(val) } } @@ -184,28 +179,17 @@ impl convert::From } } -/// A page descriptor with 64 KiB aperture. -/// -/// The output points to physical memory. -struct PageDescriptor(register::FieldValue); - impl PageDescriptor { fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor { let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT; - - PageDescriptor( - STAGE1_PAGE_DESCRIPTOR::VALID::True - + STAGE1_PAGE_DESCRIPTOR::AF::True - + attribute_fields.into() - + STAGE1_PAGE_DESCRIPTOR::TYPE::Table - + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64), - ) - } -} - -impl convert::From for RawPageDescriptor { - fn from(desc: PageDescriptor) -> Self { - RawPageDescriptor(desc.0.value) + let val = (STAGE1_PAGE_DESCRIPTOR::VALID::True + + STAGE1_PAGE_DESCRIPTOR::AF::True + + attribute_fields.into() + + STAGE1_PAGE_DESCRIPTOR::TYPE::Table + + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64)) + .value; + + PageDescriptor(val) } } @@ -237,7 +221,7 @@ fn set_up_mair() { /// - Modifies a `static mut`. Ensure it only happens from here. unsafe fn populate_pt_entries() -> Result<(), &'static str> { for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { - *l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); + *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); @@ -245,7 +229,7 @@ unsafe fn populate_pt_entries() -> Result<(), &'static str> { let (output_addr, attribute_fields) = bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; - *l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); + *l3_entry = PageDescriptor::new(output_addr, attribute_fields); } } diff --git a/12_cpu_exceptions_part1/README.md b/12_cpu_exceptions_part1/README.md index d0874c53..fda1281f 100644 --- a/12_cpu_exceptions_part1/README.md +++ b/12_cpu_exceptions_part1/README.md @@ -459,9 +459,9 @@ General purpose register: ## Diff to previous ```diff -diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_exceptions_part1/src/arch/aarch64/exception.rs +diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_cpu_exceptions_part1/src/arch/aarch64/exception.rs --- 11_virtual_memory/src/arch/aarch64/exception.rs -+++ 12_exceptions_part1/src/arch/aarch64/exception.rs ++++ 12_cpu_exceptions_part1/src/arch/aarch64/exception.rs @@ -4,12 +4,248 @@ //! Exception handling. @@ -713,9 +713,9 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_exceptions_part1/sr fn daif_field() -> register::Field; } -diff -uNr 11_virtual_memory/src/arch/aarch64/exception.S 12_exceptions_part1/src/arch/aarch64/exception.S +diff -uNr 11_virtual_memory/src/arch/aarch64/exception.S 12_cpu_exceptions_part1/src/arch/aarch64/exception.S --- 11_virtual_memory/src/arch/aarch64/exception.S -+++ 12_exceptions_part1/src/arch/aarch64/exception.S ++++ 12_cpu_exceptions_part1/src/arch/aarch64/exception.S @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: MIT +// @@ -853,9 +853,9 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.S 12_exceptions_part1/src + + eret -diff -uNr 11_virtual_memory/src/arch/aarch64.rs 12_exceptions_part1/src/arch/aarch64.rs +diff -uNr 11_virtual_memory/src/arch/aarch64.rs 12_cpu_exceptions_part1/src/arch/aarch64.rs --- 11_virtual_memory/src/arch/aarch64.rs -+++ 12_exceptions_part1/src/arch/aarch64.rs ++++ 12_cpu_exceptions_part1/src/arch/aarch64.rs @@ -106,6 +106,15 @@ } } @@ -873,9 +873,9 @@ diff -uNr 11_virtual_memory/src/arch/aarch64.rs 12_exceptions_part1/src/arch/aar pub fn mmu() -> &'static impl interface::mm::MMU { &MMU -diff -uNr 11_virtual_memory/src/bsp.rs 12_exceptions_part1/src/bsp.rs +diff -uNr 11_virtual_memory/src/bsp.rs 12_cpu_exceptions_part1/src/bsp.rs --- 11_virtual_memory/src/bsp.rs -+++ 12_exceptions_part1/src/bsp.rs ++++ 12_cpu_exceptions_part1/src/bsp.rs @@ -4,7 +4,7 @@ //! Conditional exporting of Board Support Packages. @@ -886,9 +886,9 @@ diff -uNr 11_virtual_memory/src/bsp.rs 12_exceptions_part1/src/bsp.rs #[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))] mod rpi; -diff -uNr 11_virtual_memory/src/main.rs 12_exceptions_part1/src/main.rs +diff -uNr 11_virtual_memory/src/main.rs 12_cpu_exceptions_part1/src/main.rs --- 11_virtual_memory/src/main.rs -+++ 12_exceptions_part1/src/main.rs ++++ 12_cpu_exceptions_part1/src/main.rs @@ -22,6 +22,7 @@ #![allow(incomplete_features)] #![feature(const_generics)] diff --git a/12_cpu_exceptions_part1/kernel b/12_cpu_exceptions_part1/kernel index 238fb808..f0b221c2 100755 Binary files a/12_cpu_exceptions_part1/kernel and b/12_cpu_exceptions_part1/kernel differ diff --git a/12_cpu_exceptions_part1/kernel8.img b/12_cpu_exceptions_part1/kernel8.img index 79e5ec6c..4b51eea0 100755 Binary files a/12_cpu_exceptions_part1/kernel8.img and b/12_cpu_exceptions_part1/kernel8.img differ diff --git a/12_cpu_exceptions_part1/src/arch/aarch64/mmu.rs b/12_cpu_exceptions_part1/src/arch/aarch64/mmu.rs index a81e68de..34d5f71e 100644 --- a/12_cpu_exceptions_part1/src/arch/aarch64/mmu.rs +++ b/12_cpu_exceptions_part1/src/arch/aarch64/mmu.rs @@ -79,18 +79,22 @@ register_bitfields! {u64, ] } -// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into -// a PageDescriptor slot in `struct PageTables`, and vice versa. +const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024) +const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) + +/// A table descriptor for 64 KiB aperture. +/// +/// The output points to the next table. #[derive(Copy, Clone)] #[repr(transparent)] -struct RawTableDescriptor(u64); +struct TableDescriptor(u64); +/// A page descriptor with 64 KiB aperture. +/// +/// The output points to physical memory. #[derive(Copy, Clone)] #[repr(transparent)] -struct RawPageDescriptor(u64); - -const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024) -const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) +struct PageDescriptor(u64); /// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned, /// hence the "reverse" order of appearance. @@ -98,9 +102,9 @@ const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024) #[repr(align(65536))] struct PageTables { // Page descriptors, covering 64 KiB windows per entry. - lvl3: [[RawPageDescriptor; 8192]; N], + lvl3: [[PageDescriptor; 8192]; N], // Table descriptors, covering 512 MiB windows. - lvl2: [RawTableDescriptor; N], + lvl2: [TableDescriptor; N], } /// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4. @@ -110,8 +114,8 @@ const ENTRIES_512_MIB: usize = bsp::addr_space_size() >> FIVETWELVE_MIB_SHIFT; /// /// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables { - lvl3: [[RawPageDescriptor(0); 8192]; ENTRIES_512_MIB], - lvl2: [RawTableDescriptor(0); ENTRIES_512_MIB], + lvl3: [[PageDescriptor(0); 8192]; ENTRIES_512_MIB], + lvl2: [TableDescriptor(0); ENTRIES_512_MIB], }; trait BaseAddr { @@ -129,24 +133,15 @@ impl BaseAddr for [T; N] { } } -/// A descriptor pointing to the next page table. -struct TableDescriptor(register::FieldValue); - -impl TableDescriptor { - fn new(next_lvl_table_addr: usize) -> TableDescriptor { +impl convert::From for TableDescriptor { + fn from(next_lvl_table_addr: usize) -> Self { let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT; + let val = (STAGE1_TABLE_DESCRIPTOR::VALID::True + + STAGE1_TABLE_DESCRIPTOR::TYPE::Table + + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64)) + .value; - TableDescriptor( - STAGE1_TABLE_DESCRIPTOR::VALID::True - + STAGE1_TABLE_DESCRIPTOR::TYPE::Table - + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64), - ) - } -} - -impl convert::From for RawTableDescriptor { - fn from(desc: TableDescriptor) -> Self { - RawTableDescriptor(desc.0.value) + TableDescriptor(val) } } @@ -184,28 +179,17 @@ impl convert::From } } -/// A page descriptor with 64 KiB aperture. -/// -/// The output points to physical memory. -struct PageDescriptor(register::FieldValue); - impl PageDescriptor { fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor { let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT; - - PageDescriptor( - STAGE1_PAGE_DESCRIPTOR::VALID::True - + STAGE1_PAGE_DESCRIPTOR::AF::True - + attribute_fields.into() - + STAGE1_PAGE_DESCRIPTOR::TYPE::Table - + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64), - ) - } -} - -impl convert::From for RawPageDescriptor { - fn from(desc: PageDescriptor) -> Self { - RawPageDescriptor(desc.0.value) + let val = (STAGE1_PAGE_DESCRIPTOR::VALID::True + + STAGE1_PAGE_DESCRIPTOR::AF::True + + attribute_fields.into() + + STAGE1_PAGE_DESCRIPTOR::TYPE::Table + + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64)) + .value; + + PageDescriptor(val) } } @@ -237,7 +221,7 @@ fn set_up_mair() { /// - Modifies a `static mut`. Ensure it only happens from here. unsafe fn populate_pt_entries() -> Result<(), &'static str> { for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { - *l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); + *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); @@ -245,7 +229,7 @@ unsafe fn populate_pt_entries() -> Result<(), &'static str> { let (output_addr, attribute_fields) = bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; - *l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); + *l3_entry = PageDescriptor::new(output_addr, attribute_fields); } }