Skip to main content

ostd/mm/kspace/
mod.rs

1// SPDX-License-Identifier: MPL-2.0
2//! Kernel memory space management.
3//!
4//! The kernel memory space is currently managed as follows, if the
5//! address width is 48 bits (with 47 bits kernel space).
6//!
7//! TODO: the cap of linear mapping (the start of vm alloc) are raised
8//! to workaround for high IO in TDX. We need actual vm alloc API to have
9//! a proper fix.
10//!
11//! ```text
12//! +-+ <- the highest used address (0xffff_ffff_ffff_0000)
13//! | |         For the kernel code, 1 GiB.
14//! +-+ <- 0xffff_ffff_8000_0000
15//! | |
16//! | |         Unused hole.
17//! +-+ <- 0xffff_e100_0000_0000
18//! | |         For frame metadata, 1 TiB.
19//! +-+ <- 0xffff_e000_0000_0000
20//! | |         For [`KVirtArea`], 32 TiB.
21//! +-+ <- the middle of the higher half (0xffff_c000_0000_0000)
22//! | |
23//! | |
24//! | |
25//! | |         For linear mappings, 64 TiB.
26//! | |         Mapped physical addresses are untracked.
27//! | |
28//! | |
29//! | |
30//! +-+ <- the base of high canonical address (0xffff_8000_0000_0000)
31//! ```
32//!
33//! If the address width is (according to [`crate::arch::mm::PagingConsts`])
34//! 39 bits or 57 bits, the memory space just adjust proportionally.
35use vstd::{atomic::PermissionU64, prelude::*, simple_pptr::PointsTo};
36use vstd_extra::{
37    once::OnceImpl, ownership::*, prelude::*, resource_invariant::TrivialResourceInvariant,
38};
39
40use crate::specs::{
41    arch::*,
42    mm::{
43        frame::{
44            frame_specs::FrameRawPerms, mapping::group_page_meta, meta_owners::MetaSlotStorage,
45            meta_region_owners::MetaRegionOwners,
46        },
47        page_table::{nr_pte_index_bits_spec, pte_index_bit_offset_spec},
48    },
49};
50
51use core::{marker::PhantomData, ops::Range};
52
53//use log::info;
54pub(crate) mod kvirt_area;
55#[cfg(ktest)]
56mod test;
57
58use super::{
59    Paddr, PagingConstsTrait, Vaddr,
60    frame::{
61        Frame, Segment,
62        meta::{AnyFrameMeta, MetaPageMeta, MetaSlot, mapping},
63    },
64    page_prop::{CachePolicy, PageFlags, PageProperty, PrivilegedPageFlags},
65    page_table::{PageTable, PageTableConfig},
66};
67use crate::mm::frame::DynFrame;
68use crate::mm::page_table::RCClone;
69use crate::{
70    arch::mm::{PageTableEntry, PagingConsts},
71    boot::memory_region::MemoryRegionType,
72    mm::{PagingLevel, largest_pages},
73    //task::disable_preempt,
74};
75
76verus! {
77
78/// The shortest supported address width is 39 bits. And the literal
79/// values are written for 48 bits address width. Adjust the values
80/// by arithmetic left shift.
81pub const ADDR_WIDTH_SHIFT: isize = 48 - 48;
82
83/// Start of the kernel address space.
84/// This is the _lowest_ address of the x86-64's _high_ canonical addresses.
85#[cfg(not(target_arch = "loongarch64"))]
86pub const KERNEL_BASE_VADDR: Vaddr = 0xffff_8000_0000_0000 << ADDR_WIDTH_SHIFT;
87
88#[cfg(target_arch = "loongarch64")]
89pub const KERNEL_BASE_VADDR: Vaddr = 0x9000_0000_0000_0000 << ADDR_WIDTH_SHIFT;
90
91/// End of the kernel address space (non inclusive).
92pub const KERNEL_END_VADDR: Vaddr = 0xffff_ffff_ffff_0000 << ADDR_WIDTH_SHIFT;
93
94/*
95/// The kernel code is linear mapped to this address.
96///
97/// FIXME: This offset should be randomly chosen by the loader or the
98/// boot compatibility layer. But we disabled it because OSTD
99/// doesn't support relocatable kernel yet.
100pub fn kernel_loaded_offset() -> usize {
101    KERNEL_CODE_BASE_VADDR
102}*/
103
104#[cfg(target_arch = "x86_64")]
105const KERNEL_CODE_BASE_VADDR: usize = 0xffff_ffff_8000_0000 << ADDR_WIDTH_SHIFT;
106
107#[cfg(target_arch = "riscv64")]
108const KERNEL_CODE_BASE_VADDR: usize = 0xffff_ffff_0000_0000 << ADDR_WIDTH_SHIFT;
109
110#[cfg(target_arch = "loongarch64")]
111const KERNEL_CODE_BASE_VADDR: usize = 0x9000_0000_0000_0000 << ADDR_WIDTH_SHIFT;
112
113pub const FRAME_METADATA_CAP_VADDR: Vaddr = 0xffff_e100_0000_0000 << ADDR_WIDTH_SHIFT;
114
115pub const FRAME_METADATA_BASE_VADDR: Vaddr = 0xffff_e000_0000_0000 << ADDR_WIDTH_SHIFT;
116
117pub const FRAME_METADATA_RANGE: Range<Vaddr> = 0xffff_e000_0000_0000..0xffff_e100_0000_0000;
118
119pub const VMALLOC_BASE_VADDR: Vaddr = 0xffff_c000_0000_0000 << ADDR_WIDTH_SHIFT;
120
121pub const VMALLOC_VADDR_RANGE: Range<Vaddr> = VMALLOC_BASE_VADDR..FRAME_METADATA_BASE_VADDR;
122
123/// The base address of the linear mapping of all physical
124/// memory in the kernel address space.
125#[cfg(not(target_arch = "loongarch64"))]
126pub const LINEAR_MAPPING_BASE_VADDR: Vaddr = 0xffff_8000_0000_0000 << ADDR_WIDTH_SHIFT;
127
128#[cfg(target_arch = "loongarch64")]
129pub const LINEAR_MAPPING_BASE_VADDR: Vaddr = 0x9000_0000_0000_0000 << ADDR_WIDTH_SHIFT;
130
131pub const LINEAR_MAPPING_VADDR_RANGE: Range<Vaddr> = LINEAR_MAPPING_BASE_VADDR..VMALLOC_BASE_VADDR;
132
133/// Convert physical address to virtual address using offset, only available inside `ostd`
134#[verus_verify(dual_spec, open)]
135#[verus_spec(
136    requires
137        pa + LINEAR_MAPPING_BASE_VADDR < usize::MAX,
138    returns
139        paddr_to_vaddr(pa),
140)]
141pub fn paddr_to_vaddr(pa: Paddr) -> usize {
142    //debug_assert!(pa < VMALLOC_BASE_VADDR - LINEAR_MAPPING_BASE_VADDR);
143    pa + LINEAR_MAPPING_BASE_VADDR
144}
145
146/// The kernel page table instance.
147///
148/// It manages the kernel mapping of all address spaces by sharing the kernel part. And it
149/// is unlikely to be activated.
150#[allow(private_interfaces)]
151pub exec static KERNEL_PAGE_TABLE: OnceImpl<PageTable<KernelPtConfig>, TrivialResourceInvariant> =
152    OnceImpl::new(Ghost(TrivialResourceInvariant));
153
154#[verifier::allow(autoderive_clone_without_spec)]
155#[derive(Clone, Debug)]
156pub(crate) struct KernelPtConfig {}
157
158// We use the first available PTE bit to mark the frame as tracked.
159// SAFETY: `item_into_raw` and `item_from_raw` are implemented correctly,
160unsafe impl PageTableConfig for KernelPtConfig {
161    open spec fn TOP_LEVEL_INDEX_RANGE_spec() -> Range<usize> {
162        256..512
163    }
164
165    proof fn lemma_page_table_config_constant_requirements() {
166        PageTableEntry::lemma_layout();
167    }
168
169    fn TOP_LEVEL_INDEX_RANGE() -> (r: Range<usize>) {
170        256..512
171    }
172
173    open spec fn TOP_LEVEL_CAN_UNMAP_spec() -> bool {
174        false
175    }
176
177    fn TOP_LEVEL_CAN_UNMAP() -> (b: bool) {
178        false
179    }
180
181    type E = PageTableEntry;
182
183    type C = PagingConsts;
184
185    type Item = MappedItem;
186
187    type Perm = FrameRawPerms;
188
189    open spec fn perm_well_formed_with_region(
190        pa: Paddr,
191        perm: Tracked<Option<Self::Perm>>,
192        regions: MetaRegionOwners,
193    ) -> bool {
194        perm@ is Some ==> {
195            let idx = crate::specs::mm::frame::mapping::frame_to_index(pa);
196            let frame_perm = perm@->0;
197            &&& frame_perm.slot_perm == regions.slots[idx]
198            &&& frame_perm.metadata_perm.frac() == 1
199            &&& frame_perm.metadata_perm.id() == regions.slot_owners[idx].metadata_perm.id()
200            &&& MetaSlot::perms_related(*frame_perm.slot_perm, frame_perm.metadata_perm.resource())
201        }
202    }
203
204    proof fn lemma_none_perm_well_formed(pa: Paddr, regions: MetaRegionOwners) {
205    }
206
207    open spec fn item_into_raw_spec(item: Self::Item) -> (
208        Paddr,
209        PagingLevel,
210        PageProperty,
211        Tracked<Option<Self::Perm>>,
212    ) {
213        match item {
214            MappedItem::Tracked(frame, prop) => (
215                crate::mm::frame::meta::mapping::meta_to_frame(frame.slot_vaddr()),
216                1,
217                Self::encode_tracked_prop(prop),
218                Tracked(
219                    Some(
220                        FrameRawPerms {
221                            slot_perm: frame.tracked_slot_perm@,
222                            metadata_perm: frame.tracked_metadata_perm@->0,
223                        },
224                    ),
225                ),
226            ),
227            MappedItem::Untracked(pa, level, prop) => (
228                pa,
229                level,
230                Self::decode_tracked_prop(prop),
231                Tracked(None),
232            ),
233        }
234    }
235
236    #[verifier::external_body]
237    fn item_into_raw(item: Self::Item) -> (res: (
238        Paddr,
239        PagingLevel,
240        PageProperty,
241        Tracked<Option<Self::Perm>>,
242    )) {
243        match item {
244            MappedItem::Tracked(frame, mut prop) => {
245                proof_decl! {
246                    let tracked raw_perm: FrameRawPerms;
247                }
248                debug_assert!(!prop.flags.contains(PageFlags::AVAIL1()));
249                prop.flags = prop.flags | PageFlags::AVAIL1();
250                let level = frame.map_level();
251                let paddr = frame.into_raw();
252                proof_with!(=> Tracked(raw_perm));
253                (paddr, level, prop, Tracked(Some(raw_perm)))
254            },
255            MappedItem::Untracked(pa, level, mut prop) => {
256                debug_assert!(!prop.flags.contains(PageFlags::AVAIL1()));
257                prop.flags = prop.flags - PageFlags::AVAIL1();
258                (pa, level, prop, Tracked(None))
259            },
260        }
261    }
262
263    open spec fn item_from_raw_spec(
264        paddr: Paddr,
265        level: PagingLevel,
266        prop: PageProperty,
267        perm: Tracked<Option<Self::Perm>>,
268    ) -> Self::Item {
269        if prop.flags.contains(PageFlags::AVAIL1()) {
270            MappedItem::Tracked(
271                Frame::<MetaSlotStorage> {
272                    ptr: vstd::simple_pptr::PPtr(mapping::frame_to_meta(paddr), PhantomData),
273                    _marker: PhantomData,
274                    #[cfg(verus_keep_ghost_body)]
275                    tracked_slot_perm: Tracked((perm@->0).slot_perm),
276                    #[cfg(verus_keep_ghost_body)]
277                    tracked_metadata_perm: Tracked(Some((perm@->0).metadata_perm)),
278                },
279                Self::decode_tracked_prop(prop),
280            )
281        } else {
282            MappedItem::Untracked(paddr, level, prop)
283        }
284    }
285
286    #[verifier::external_body]
287    unsafe fn item_from_raw(
288        paddr: Paddr,
289        level: PagingLevel,
290        prop: PageProperty,
291        Tracked(perm): Tracked<Option<Self::Perm>>,
292    ) -> Self::Item {
293        if prop.flags.contains(PageFlags::AVAIL1()) {
294            debug_assert_eq!(level, 1);
295            // [KNOWN] BUG FOUND BY FV: forgotting to clean `AVAIL1`. https://github.com/asterinas/vostd/issues/625
296            let mut item_prop = prop;
297            item_prop.flags = item_prop.flags - PageFlags::AVAIL1();
298            let tracked raw_perm = perm.tracked_unwrap();
299            // SAFETY: The caller ensures safety.
300            proof_with!(Tracked(raw_perm));
301            let frame = unsafe { Frame::<MetaSlotStorage>::from_raw(paddr) };
302            MappedItem::Tracked(frame, item_prop)
303        } else {
304            MappedItem::Untracked(paddr, level, prop)
305        }
306    }
307
308    proof fn lemma_item_into_raw_roundtrip(
309        pa: Paddr,
310        level: PagingLevel,
311        prop: PageProperty,
312        perm: Tracked<Option<Self::Perm>>,
313    ) {
314        broadcast use group_page_meta;
315
316        assert(Self::raw_item_well_formed((pa, level, prop, perm)));
317        prop.lemma_avail1_tag_encoding();
318        if prop.flags.contains(PageFlags::AVAIL1()) {
319            assert(Self::item_from_raw(pa, level, prop, perm) is Tracked);
320            assert(perm@ is Some);
321        } else {
322            assert(Self::item_from_raw(pa, level, prop, perm) is Untracked);
323            assert(perm@ is None);
324        }
325    }
326
327    proof fn lemma_item_from_raw_roundtrip(
328        item: Self::Item,
329        paddr: Paddr,
330        level: PagingLevel,
331        prop: PageProperty,
332        perm: Tracked<Option<Self::Perm>>,
333    ) {
334        broadcast use group_page_meta;
335
336        match item {
337            MappedItem::Tracked(frame, prop_actual) => {
338                assert(Self::item_well_formed(item));
339                prop_actual.lemma_avail1_tag_encoding();
340            },
341            MappedItem::Untracked(_, _, prop_actual) => {
342                assert(Self::item_well_formed(item));
343                prop_actual.lemma_avail1_tag_encoding();
344            },
345        }
346    }
347
348    open spec fn item_well_formed(item: Self::Item) -> bool {
349        match item {
350            MappedItem::Tracked(frame, prop) => {
351                &&& !prop.flags.contains(PageFlags::AVAIL1())
352                &&& frame.inv()
353            },
354            MappedItem::Untracked(_, _, prop) => !prop.flags.contains(PageFlags::AVAIL1()),
355        }
356    }
357
358    open spec fn raw_item_well_formed(
359        item: (Paddr, PagingLevel, PageProperty, Tracked<Option<Self::Perm>>),
360    ) -> bool {
361        let (pa, level, prop, perm) = item;
362        &&& (prop.flags.contains(PageFlags::AVAIL1()) <==> perm@ is Some)
363        &&& prop.flags.contains(PageFlags::AVAIL1()) ==> {
364            &&& level == 1
365            &&& (perm@->0).slot_perm.addr() == mapping::frame_to_meta(pa)
366            &&& (perm@->0).slot_perm.is_init()
367            &&& (perm@->0).metadata_perm.frac() == 1
368            &&& MetaSlot::perms_related(*(perm@->0).slot_perm, (perm@->0).metadata_perm.resource())
369        }
370    }
371
372    proof fn lemma_perm_well_formed_with_region_preserved(
373        pa: Paddr,
374        perm: Tracked<Option<Self::Perm>>,
375        old_regions: MetaRegionOwners,
376        new_regions: MetaRegionOwners,
377    ) {
378    }
379
380    proof fn lemma_raw_item_well_formed_preserved(
381        pa: Paddr,
382        level: PagingLevel,
383        old_prop: PageProperty,
384        new_prop: PageProperty,
385        perm: Tracked<Option<Self::Perm>>,
386    ) {
387    }
388
389    proof fn lemma_raw_item_well_formed_split(
390        pa: Paddr,
391        level: PagingLevel,
392        prop: PageProperty,
393        child_pa: Paddr,
394        child_idx: usize,
395        perm: Tracked<Option<Self::Perm>>,
396    ) {
397        assert(<PageTableEntry as crate::mm::page_table::PageTableEntryTrait>::new_page_req(
398            pa,
399            level,
400            prop,
401        ));
402        assert(<PageTableEntry as crate::mm::page_table::PageTableEntryTrait>::new_page_req(
403            child_pa,
404            (level - 1) as PagingLevel,
405            prop,
406        ));
407    }
408
409    proof fn lemma_huge_raw_item_untracked(
410        pa: Paddr,
411        level: PagingLevel,
412        prop: PageProperty,
413        perm: Tracked<Option<Self::Perm>>,
414    ) {
415    }
416
417    proof fn lemma_item_from_raw_well_formed(
418        pa: Paddr,
419        level: PagingLevel,
420        prop: PageProperty,
421        perm: Tracked<Option<Self::Perm>>,
422    ) {
423        broadcast use group_page_meta;
424
425        prop.lemma_avail1_tag_encoding();
426    }
427
428    proof fn lemma_clone_ensures_concrete(
429        item: Self::Item,
430        pa: Paddr,
431        old_regions: MetaRegionOwners,
432        new_regions: MetaRegionOwners,
433        res: Self::Item,
434    ) {
435        use crate::specs::mm::frame::mapping::{frame_to_index, meta_to_index};
436
437        match item {
438            MappedItem::Tracked(frame, _) => {
439                let frame_idx = meta_to_index(frame.slot_vaddr());
440                assert(frame.index() == frame_to_index(pa));
441                assert(<MappedItem as RCClone>::clone_ensures(item, old_regions, new_regions, res));
442            },
443            MappedItem::Untracked(_, _, _) => {},
444        }
445    }
446
447    proof fn lemma_clone_requires_concrete(
448        item: Self::Item,
449        pa: Paddr,
450        level: PagingLevel,
451        prop: PageProperty,
452        regions: MetaRegionOwners,
453    ) {
454        use crate::specs::mm::frame::mapping::frame_to_index;
455
456        use crate::mm::frame::meta::mapping::{frame_to_meta, meta_to_frame};
457        use crate::mm::frame::meta::{REF_COUNT_MAX, REF_COUNT_UNUSED};
458        broadcast use group_page_meta;
459
460        let perm = Self::item_into_raw(item).3;
461        Self::lemma_item_from_raw_well_formed(pa, level, prop, perm);
462        match item {
463            MappedItem::Tracked(frame, _) => {
464                crate::specs::mm::frame::mapping::lemma_paddr_to_meta_biinjective(pa);
465                regions.lemma_contains_valid_frame_paddr(pa);
466            },
467            MappedItem::Untracked(_, _, _) => {},
468        }
469    }
470}
471
472impl KernelPtConfig {
473    /// Adds the raw PTE bit used to identify a ref-counted mapping.
474    pub open spec fn encode_tracked_prop(prop: PageProperty) -> PageProperty {
475        PageProperty { flags: prop.flags.union(PageFlags::AVAIL1()), ..prop }
476    }
477
478    /// Removes the raw PTE trackedness bit from a caller-visible property.
479    pub open spec fn decode_tracked_prop(prop: PageProperty) -> PageProperty {
480        PageProperty { flags: prop.flags.difference(PageFlags::AVAIL1()), ..prop }
481    }
482}
483
484/*
485#[derive(Clone, Debug, PartialEq, Eq)]
486pub(crate) enum MappedItem {
487    Tracked(Frame<dyn AnyFrameMeta>, PageProperty),
488    Untracked(Paddr, PagingLevel, PageProperty),
489}
490*/
491
492pub enum MappedItem {
493    Tracked(DynFrame, PageProperty),
494    Untracked(Paddr, PagingLevel, PageProperty),
495}
496
497impl RCClone for MappedItem {
498    open spec fn clone_requires(self, perm: MetaRegionOwners) -> bool {
499        match self {
500            MappedItem::Tracked(frame, _) => frame.clone_requires(perm),
501            MappedItem::Untracked(_, _, _) => perm.inv(),
502        }
503    }
504
505    open spec fn clone_ensures(
506        self,
507        old_perm: MetaRegionOwners,
508        new_perm: MetaRegionOwners,
509        res: Self,
510    ) -> bool {
511        match (self, res) {
512            (MappedItem::Tracked(frame, prop), MappedItem::Tracked(res_frame, res_prop)) => {
513                &&& prop == res_prop
514                &&& frame.clone_ensures(old_perm, new_perm, res_frame)
515            },
516            (
517                MappedItem::Untracked(pa, level, prop),
518                MappedItem::Untracked(res_pa, res_level, res_prop),
519            ) => {
520                &&& pa == res_pa
521                &&& level == res_level
522                &&& prop == res_prop
523                &&& old_perm == new_perm
524            },
525            _ => false,
526        }
527    }
528
529    #[verifier::external_body]
530    fn clone(&self, Tracked(perm): Tracked<&mut MetaRegionOwners>) -> (res: Self) {
531        unimplemented!();
532    }
533}
534
535} // verus!
536// /// Initializes the kernel page table.
537// ///
538// /// This function should be called after:
539// ///  - the page allocator and the heap allocator are initialized;
540// ///  - the memory regions are initialized.
541// ///
542// /// This function should be called before:
543// ///  - any initializer that modifies the kernel page table.
544// pub fn init_kernel_page_table(meta_pages: Segment<MetaPageMeta>) {
545//     info!("Initializing the kernel page table");
546//     // Start to initialize the kernel page table.
547//     let kpt = PageTable::<KernelPtConfig>::new_kernel_page_table();
548//     let preempt_guard = disable_preempt();
549//     // In LoongArch64, we don't need to do linear mappings for the kernel because of DMW0.
550//     #[cfg(not(target_arch = "loongarch64"))]
551//     // Do linear mappings for the kernel.
552//     {
553//         let max_paddr = crate::mm::frame::max_paddr();
554//         let from = LINEAR_MAPPING_BASE_VADDR..LINEAR_MAPPING_BASE_VADDR + max_paddr;
555//         let prop = PageProperty {
556//             flags: PageFlags::RW,
557//             cache: CachePolicy::Writeback,
558//             priv_flags: PrivilegedPageFlags::GLOBAL,
559//         };
560//         let mut cursor = kpt.cursor_mut(&preempt_guard, &from).unwrap();
561//         for (pa, level) in largest_pages::<KernelPtConfig>(from.start, 0, max_paddr) {
562//             // SAFETY: we are doing the linear mapping for the kernel.
563//             unsafe { cursor.map(MappedItem::Untracked(pa, level, prop)) }
564//                 .expect("Kernel linear address space is mapped twice");
565//         }
566//     }
567//     // Map the metadata pages.
568//     {
569//         let start_va = mapping::frame_to_meta::<PagingConsts>(0);
570//         let from = start_va..start_va + meta_pages.size();
571//         let prop = PageProperty {
572//             flags: PageFlags::RW,
573//             cache: CachePolicy::Writeback,
574//             priv_flags: PrivilegedPageFlags::GLOBAL,
575//         };
576//         let mut cursor = kpt.cursor_mut(&preempt_guard, &from).unwrap();
577//         // We use untracked mapping so that we can benefit from huge pages.
578//         // We won't unmap them anyway, so there's no leaking problem yet.
579//         // TODO: support tracked huge page mapping.
580//         let pa_range = meta_pages.into_raw();
581//         for (pa, level) in
582//             largest_pages::<KernelPtConfig>(from.start, pa_range.start, pa_range.len())
583//         {
584//             // SAFETY: We are doing the metadata mappings for the kernel.
585//             unsafe { cursor.map(MappedItem::Untracked(pa, level, prop)) }
586//                 .expect("Frame metadata address space is mapped twice");
587//         }
588//     }
589//     // In LoongArch64, we don't need to do linear mappings for the kernel code because of DMW0.
590//     #[cfg(not(target_arch = "loongarch64"))]
591//     // Map for the kernel code itself.
592//     // TODO: set separated permissions for each segments in the kernel.
593//     {
594//         let regions = &crate::boot::EARLY_INFO.get().unwrap().memory_regions;
595//         let region = regions
596//             .iter()
597//             .find(|r| r.typ() == MemoryRegionType::Kernel)
598//             .unwrap();
599//         let offset = kernel_loaded_offset();
600//         let from = region.base() + offset..region.end() + offset;
601//         let prop = PageProperty {
602//             flags: PageFlags::RWX,
603//             cache: CachePolicy::Writeback,
604//             priv_flags: PrivilegedPageFlags::GLOBAL,
605//         };
606//         let mut cursor = kpt.cursor_mut(&preempt_guard, &from).unwrap();
607//         for (pa, level) in largest_pages::<KernelPtConfig>(from.start, region.base(), from.len()) {
608//             // SAFETY: we are doing the kernel code mapping.
609//             unsafe { cursor.map(MappedItem::Untracked(pa, level, prop)) }
610//                 .expect("Kernel code mapped twice");
611//         }
612//     }
613//     KERNEL_PAGE_TABLE.call_once(|| kpt);
614// }
615// /// Activates the kernel page table.
616// ///
617// /// # Safety
618// ///
619// /// This function should only be called once per CPU.
620// pub unsafe fn activate_kernel_page_table() {
621//     let kpt = KERNEL_PAGE_TABLE
622//         .get()
623//         .expect("The kernel page table is not initialized yet");
624//     // SAFETY: the kernel page table is initialized properly.
625//     unsafe {
626//         kpt.first_activate_unchecked();
627//         crate::arch::mm::tlb_flush_all_including_global();
628//     }
629//     // SAFETY: the boot page table is OK to be dismissed now since
630//     // the kernel page table is activated just now.
631//     unsafe {
632//         crate::mm::page_table::boot_pt::dismiss();
633//     }
634// }