Nothing to see here, move along
1use x86_64::structures::paging::page_table::PageTableFlags;
2
3crate::kernel_test!(
4 fn boot_pml4_is_nonzero() {
5 let phys = crate::proc::address_space::boot_pml4_phys();
6 assert!(phys.as_u64() != 0, "boot PML4 physical address is zero");
7 }
8);
9
10crate::kernel_test!(
11 fn user_pml4_kernel_entries_cloned() {
12 let mut allocator = crate::mem::phys::BitmapFrameAllocator;
13 let user_phys = crate::proc::address_space::create_user_pml4(&mut allocator)
14 .expect("failed to allocate user PML4");
15
16 let boot_phys = crate::proc::address_space::boot_pml4_phys();
17 let hhdm = crate::mem::addr::hhdm_offset();
18
19 let boot_table = unsafe {
20 &*x86_64::VirtAddr::new(boot_phys.as_u64() + hhdm)
21 .as_ptr::<x86_64::structures::paging::page_table::PageTable>()
22 };
23 let user_table = unsafe {
24 &*x86_64::VirtAddr::new(user_phys.as_u64() + hhdm)
25 .as_ptr::<x86_64::structures::paging::page_table::PageTable>()
26 };
27
28 let mismatch = (256..512)
29 .filter(|&i| {
30 let boot_entry = &boot_table[i];
31 let user_entry = &user_table[i];
32 let expected_flags = boot_entry.flags() & !PageTableFlags::USER_ACCESSIBLE;
33 boot_entry.addr() != user_entry.addr() || user_entry.flags() != expected_flags
34 })
35 .count();
36
37 assert!(
38 mismatch == 0,
39 "{} kernel PML4 entries (256..512) differ between boot and user tables",
40 mismatch
41 );
42
43 let user_accessible_count = (256..512)
44 .filter(|&i| {
45 user_table[i]
46 .flags()
47 .contains(PageTableFlags::USER_ACCESSIBLE)
48 })
49 .count();
50
51 assert!(
52 user_accessible_count == 0,
53 "{} kernel PML4 entries in user table have USER_ACCESSIBLE set",
54 user_accessible_count
55 );
56
57 crate::mem::phys::BitmapFrameAllocator.deallocate_frame(
58 x86_64::structures::paging::PhysFrame::containing_address(user_phys),
59 );
60 }
61);
62
63crate::kernel_test!(
64 fn user_pml4_user_half_empty() {
65 let mut allocator = crate::mem::phys::BitmapFrameAllocator;
66 let user_phys = crate::proc::address_space::create_user_pml4(&mut allocator)
67 .expect("failed to allocate user PML4");
68
69 let hhdm = crate::mem::addr::hhdm_offset();
70 let user_table = unsafe {
71 &*x86_64::VirtAddr::new(user_phys.as_u64() + hhdm)
72 .as_ptr::<x86_64::structures::paging::page_table::PageTable>()
73 };
74
75 let present_count = (0..256)
76 .filter(|&i| user_table[i].flags().contains(PageTableFlags::PRESENT))
77 .count();
78
79 assert!(
80 present_count == 0,
81 "{} user-half PML4 entries (0..256) are present in a fresh address space",
82 present_count
83 );
84
85 crate::mem::phys::BitmapFrameAllocator.deallocate_frame(
86 x86_64::structures::paging::PhysFrame::containing_address(user_phys),
87 );
88 }
89);
90
91crate::kernel_test!(
92 fn pml4_phys_round_trip() {
93 let mut allocator = crate::mem::phys::BitmapFrameAllocator;
94 let raw_phys = crate::proc::address_space::create_user_pml4(&mut allocator)
95 .expect("failed to allocate user PML4");
96
97 let typed = crate::mem::typed_addr::Pml4Phys::from_create(raw_phys);
98 let extracted = typed.raw();
99
100 assert!(
101 extracted == raw_phys,
102 "Pml4Phys round-trip failed: raw={:#x}, extracted={:#x}",
103 raw_phys.as_u64(),
104 extracted.as_u64()
105 );
106
107 assert!(
108 raw_phys.as_u64() != 0,
109 "PML4 physical address must be non-zero"
110 );
111
112 assert!(
113 raw_phys.as_u64() & 0xFFF == 0,
114 "PML4 physical address must be page-aligned, got {:#x}",
115 raw_phys.as_u64()
116 );
117
118 crate::mem::phys::BitmapFrameAllocator.deallocate_frame(
119 x86_64::structures::paging::PhysFrame::containing_address(raw_phys),
120 );
121 }
122);
123
124crate::kernel_test!(
125 fn unmap_unmapped_via_pml4_phys_returns_error() {
126 let mut allocator = crate::mem::phys::BitmapFrameAllocator;
127 let mut ptable = crate::proc::PROCESSES.lock();
128 let created = ptable.allocate(&mut allocator).expect("alloc process");
129 let pid = created.pid();
130 let pml4 = ptable[pid].pml4_phys;
131 drop(ptable);
132
133 let virt = x86_64::VirtAddr::new(0x0000_6000_0000_0000);
134 let result = crate::proc::address_space::unmap_user_page(pml4, virt);
135 assert!(
136 result == Err(crate::error::KernelError::InvalidAddress),
137 "unmapping a never-mapped page via Pml4Phys must return InvalidAddress, got {:?}",
138 result
139 );
140
141 let mut ptable = crate::proc::PROCESSES.lock();
142 ptable.destroy(pid, &mut crate::mem::phys::BitmapFrameAllocator);
143 }
144);
145
146crate::kernel_test!(
147 fn process_zero_exists_and_runnable() {
148 let ptable = crate::proc::PROCESSES.lock();
149 let pid0 = crate::types::Pid::new(0);
150 let proc0 = ptable.get(pid0).expect("process 0 does not exist");
151 assert!(
152 proc0.is_runnable(),
153 "process 0 is not runnable (state: {:?})",
154 proc0.state()
155 );
156 }
157);