xref: /DragonOS/kernel/src/mm/fault.rs (revision a17651b14b86dd70655090381db4a2f710853aa1)
1*a17651b1SMemoryShore use core::{alloc::Layout, intrinsics::unlikely, panic};
2*a17651b1SMemoryShore 
3*a17651b1SMemoryShore use alloc::sync::Arc;
4*a17651b1SMemoryShore 
5*a17651b1SMemoryShore use crate::{
6*a17651b1SMemoryShore     arch::{mm::PageMapper, MMArch},
7*a17651b1SMemoryShore     mm::{
8*a17651b1SMemoryShore         page::{page_manager_lock_irqsave, PageFlags},
9*a17651b1SMemoryShore         ucontext::LockedVMA,
10*a17651b1SMemoryShore         VirtAddr, VmFaultReason, VmFlags,
11*a17651b1SMemoryShore     },
12*a17651b1SMemoryShore     process::{ProcessManager, ProcessState},
13*a17651b1SMemoryShore };
14*a17651b1SMemoryShore 
15*a17651b1SMemoryShore use crate::mm::MemoryManagementArch;
16*a17651b1SMemoryShore 
17*a17651b1SMemoryShore bitflags! {
18*a17651b1SMemoryShore     pub struct FaultFlags: u64{
19*a17651b1SMemoryShore     const FAULT_FLAG_WRITE = 1 << 0;
20*a17651b1SMemoryShore     const FAULT_FLAG_MKWRITE = 1 << 1;
21*a17651b1SMemoryShore     const FAULT_FLAG_ALLOW_RETRY = 1 << 2;
22*a17651b1SMemoryShore     const FAULT_FLAG_RETRY_NOWAIT = 1 << 3;
23*a17651b1SMemoryShore     const FAULT_FLAG_KILLABLE = 1 << 4;
24*a17651b1SMemoryShore     const FAULT_FLAG_TRIED = 1 << 5;
25*a17651b1SMemoryShore     const FAULT_FLAG_USER = 1 << 6;
26*a17651b1SMemoryShore     const FAULT_FLAG_REMOTE = 1 << 7;
27*a17651b1SMemoryShore     const FAULT_FLAG_INSTRUCTION = 1 << 8;
28*a17651b1SMemoryShore     const FAULT_FLAG_INTERRUPTIBLE =1 << 9;
29*a17651b1SMemoryShore     const FAULT_FLAG_UNSHARE = 1 << 10;
30*a17651b1SMemoryShore     const FAULT_FLAG_ORIG_PTE_VALID = 1 << 11;
31*a17651b1SMemoryShore     const FAULT_FLAG_VMA_LOCK = 1 << 12;
32*a17651b1SMemoryShore     }
33*a17651b1SMemoryShore }
34*a17651b1SMemoryShore 
35*a17651b1SMemoryShore /// # 缺页异常信息结构体
36*a17651b1SMemoryShore /// 包含了页面错误处理的相关信息,例如出错的地址、VMA等
37*a17651b1SMemoryShore #[derive(Debug)]
38*a17651b1SMemoryShore pub struct PageFaultMessage {
39*a17651b1SMemoryShore     vma: Arc<LockedVMA>,
40*a17651b1SMemoryShore     address: VirtAddr,
41*a17651b1SMemoryShore     flags: FaultFlags,
42*a17651b1SMemoryShore }
43*a17651b1SMemoryShore 
44*a17651b1SMemoryShore impl PageFaultMessage {
45*a17651b1SMemoryShore     pub fn new(vma: Arc<LockedVMA>, address: VirtAddr, flags: FaultFlags) -> Self {
46*a17651b1SMemoryShore         Self {
47*a17651b1SMemoryShore             vma: vma.clone(),
48*a17651b1SMemoryShore             address,
49*a17651b1SMemoryShore             flags,
50*a17651b1SMemoryShore         }
51*a17651b1SMemoryShore     }
52*a17651b1SMemoryShore 
53*a17651b1SMemoryShore     #[inline(always)]
54*a17651b1SMemoryShore     #[allow(dead_code)]
55*a17651b1SMemoryShore     pub fn vma(&self) -> Arc<LockedVMA> {
56*a17651b1SMemoryShore         self.vma.clone()
57*a17651b1SMemoryShore     }
58*a17651b1SMemoryShore 
59*a17651b1SMemoryShore     #[inline(always)]
60*a17651b1SMemoryShore     #[allow(dead_code)]
61*a17651b1SMemoryShore     pub fn address(&self) -> VirtAddr {
62*a17651b1SMemoryShore         self.address
63*a17651b1SMemoryShore     }
64*a17651b1SMemoryShore 
65*a17651b1SMemoryShore     #[inline(always)]
66*a17651b1SMemoryShore     #[allow(dead_code)]
67*a17651b1SMemoryShore     pub fn address_aligned_down(&self) -> VirtAddr {
68*a17651b1SMemoryShore         VirtAddr::new(crate::libs::align::page_align_down(self.address.data()))
69*a17651b1SMemoryShore     }
70*a17651b1SMemoryShore 
71*a17651b1SMemoryShore     #[inline(always)]
72*a17651b1SMemoryShore     #[allow(dead_code)]
73*a17651b1SMemoryShore     pub fn flags(&self) -> FaultFlags {
74*a17651b1SMemoryShore         self.flags
75*a17651b1SMemoryShore     }
76*a17651b1SMemoryShore }
77*a17651b1SMemoryShore 
78*a17651b1SMemoryShore /// 缺页中断处理结构体
79*a17651b1SMemoryShore pub struct PageFaultHandler;
80*a17651b1SMemoryShore 
81*a17651b1SMemoryShore impl PageFaultHandler {
82*a17651b1SMemoryShore     /// 处理缺页异常
83*a17651b1SMemoryShore     /// ## 参数
84*a17651b1SMemoryShore     ///
85*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
86*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
87*a17651b1SMemoryShore     ///
88*a17651b1SMemoryShore     /// ## 返回值
89*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
90*a17651b1SMemoryShore     pub unsafe fn handle_mm_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
91*a17651b1SMemoryShore         let flags = pfm.flags();
92*a17651b1SMemoryShore         let vma = pfm.vma();
93*a17651b1SMemoryShore         let current_pcb = ProcessManager::current_pcb();
94*a17651b1SMemoryShore         let mut guard = current_pcb.sched_info().inner_lock_write_irqsave();
95*a17651b1SMemoryShore         guard.set_state(ProcessState::Runnable);
96*a17651b1SMemoryShore 
97*a17651b1SMemoryShore         if !MMArch::vma_access_permitted(
98*a17651b1SMemoryShore             vma.clone(),
99*a17651b1SMemoryShore             flags.contains(FaultFlags::FAULT_FLAG_WRITE),
100*a17651b1SMemoryShore             flags.contains(FaultFlags::FAULT_FLAG_INSTRUCTION),
101*a17651b1SMemoryShore             flags.contains(FaultFlags::FAULT_FLAG_REMOTE),
102*a17651b1SMemoryShore         ) {
103*a17651b1SMemoryShore             return VmFaultReason::VM_FAULT_SIGSEGV;
104*a17651b1SMemoryShore         }
105*a17651b1SMemoryShore 
106*a17651b1SMemoryShore         let guard = vma.lock();
107*a17651b1SMemoryShore         let vm_flags = *guard.vm_flags();
108*a17651b1SMemoryShore         drop(guard);
109*a17651b1SMemoryShore         if unlikely(vm_flags.contains(VmFlags::VM_HUGETLB)) {
110*a17651b1SMemoryShore             //TODO: 添加handle_hugetlb_fault处理大页缺页异常
111*a17651b1SMemoryShore         } else {
112*a17651b1SMemoryShore             Self::handle_normal_fault(pfm, mapper);
113*a17651b1SMemoryShore         }
114*a17651b1SMemoryShore 
115*a17651b1SMemoryShore         VmFaultReason::VM_FAULT_COMPLETED
116*a17651b1SMemoryShore     }
117*a17651b1SMemoryShore 
118*a17651b1SMemoryShore     /// 处理普通页缺页异常
119*a17651b1SMemoryShore     /// ## 参数
120*a17651b1SMemoryShore     ///
121*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
122*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
123*a17651b1SMemoryShore     ///
124*a17651b1SMemoryShore     /// ## 返回值
125*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
126*a17651b1SMemoryShore     pub unsafe fn handle_normal_fault(
127*a17651b1SMemoryShore         pfm: PageFaultMessage,
128*a17651b1SMemoryShore         mapper: &mut PageMapper,
129*a17651b1SMemoryShore     ) -> VmFaultReason {
130*a17651b1SMemoryShore         let address = pfm.address_aligned_down();
131*a17651b1SMemoryShore         let vma = pfm.vma.clone();
132*a17651b1SMemoryShore         if mapper.get_entry(address, 3).is_none() {
133*a17651b1SMemoryShore             mapper
134*a17651b1SMemoryShore                 .allocate_table(address, 2)
135*a17651b1SMemoryShore                 .expect("failed to allocate PUD table");
136*a17651b1SMemoryShore         }
137*a17651b1SMemoryShore         let page_flags = vma.lock().flags();
138*a17651b1SMemoryShore 
139*a17651b1SMemoryShore         for level in 2..=3 {
140*a17651b1SMemoryShore             let level = MMArch::PAGE_LEVELS - level;
141*a17651b1SMemoryShore             if mapper.get_entry(address, level).is_none() {
142*a17651b1SMemoryShore                 if vma.is_hugepage() {
143*a17651b1SMemoryShore                     if vma.is_anonymous() {
144*a17651b1SMemoryShore                         mapper.map_huge_page(address, page_flags);
145*a17651b1SMemoryShore                     }
146*a17651b1SMemoryShore                 } else if mapper.allocate_table(address, level - 1).is_none() {
147*a17651b1SMemoryShore                     return VmFaultReason::VM_FAULT_OOM;
148*a17651b1SMemoryShore                 }
149*a17651b1SMemoryShore             }
150*a17651b1SMemoryShore         }
151*a17651b1SMemoryShore 
152*a17651b1SMemoryShore         Self::handle_pte_fault(pfm, mapper)
153*a17651b1SMemoryShore     }
154*a17651b1SMemoryShore 
155*a17651b1SMemoryShore     /// 处理页表项异常
156*a17651b1SMemoryShore     /// ## 参数
157*a17651b1SMemoryShore     ///
158*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
159*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
160*a17651b1SMemoryShore     ///
161*a17651b1SMemoryShore     /// ## 返回值
162*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
163*a17651b1SMemoryShore     pub unsafe fn handle_pte_fault(
164*a17651b1SMemoryShore         pfm: PageFaultMessage,
165*a17651b1SMemoryShore         mapper: &mut PageMapper,
166*a17651b1SMemoryShore     ) -> VmFaultReason {
167*a17651b1SMemoryShore         let address = pfm.address_aligned_down();
168*a17651b1SMemoryShore         let flags = pfm.flags;
169*a17651b1SMemoryShore         let vma = pfm.vma.clone();
170*a17651b1SMemoryShore         if let Some(mut entry) = mapper.get_entry(address, 0) {
171*a17651b1SMemoryShore             if !entry.present() {
172*a17651b1SMemoryShore                 return Self::do_swap_page(pfm, mapper);
173*a17651b1SMemoryShore             }
174*a17651b1SMemoryShore             if entry.protnone() && vma.is_accessible() {
175*a17651b1SMemoryShore                 return Self::do_numa_page(pfm, mapper);
176*a17651b1SMemoryShore             }
177*a17651b1SMemoryShore             if flags.intersects(FaultFlags::FAULT_FLAG_WRITE | FaultFlags::FAULT_FLAG_UNSHARE) {
178*a17651b1SMemoryShore                 if !entry.write() {
179*a17651b1SMemoryShore                     return Self::do_wp_page(pfm, mapper);
180*a17651b1SMemoryShore                 } else {
181*a17651b1SMemoryShore                     entry.set_flags(PageFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
182*a17651b1SMemoryShore                 }
183*a17651b1SMemoryShore             }
184*a17651b1SMemoryShore         } else if vma.is_anonymous() {
185*a17651b1SMemoryShore             return Self::do_anonymous_page(pfm, mapper);
186*a17651b1SMemoryShore         } else {
187*a17651b1SMemoryShore             return Self::do_fault(pfm, mapper);
188*a17651b1SMemoryShore         }
189*a17651b1SMemoryShore 
190*a17651b1SMemoryShore         VmFaultReason::VM_FAULT_COMPLETED
191*a17651b1SMemoryShore     }
192*a17651b1SMemoryShore 
193*a17651b1SMemoryShore     /// 处理匿名映射页缺页异常
194*a17651b1SMemoryShore     /// ## 参数
195*a17651b1SMemoryShore     ///
196*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
197*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
198*a17651b1SMemoryShore     ///
199*a17651b1SMemoryShore     /// ## 返回值
200*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
201*a17651b1SMemoryShore     pub unsafe fn do_anonymous_page(
202*a17651b1SMemoryShore         pfm: PageFaultMessage,
203*a17651b1SMemoryShore         mapper: &mut PageMapper,
204*a17651b1SMemoryShore     ) -> VmFaultReason {
205*a17651b1SMemoryShore         let address = pfm.address_aligned_down();
206*a17651b1SMemoryShore         let vma = pfm.vma.clone();
207*a17651b1SMemoryShore         let guard = vma.lock();
208*a17651b1SMemoryShore         if let Some(flush) = mapper.map(address, guard.flags()) {
209*a17651b1SMemoryShore             flush.flush();
210*a17651b1SMemoryShore             crate::debug::klog::mm::mm_debug_log(
211*a17651b1SMemoryShore                 klog_types::AllocatorLogType::LazyAlloc(klog_types::AllocLogItem::new(
212*a17651b1SMemoryShore                     Layout::from_size_align(MMArch::PAGE_SIZE, MMArch::PAGE_SIZE).unwrap(),
213*a17651b1SMemoryShore                     Some(address.data()),
214*a17651b1SMemoryShore                     Some(mapper.translate(address).unwrap().0.data()),
215*a17651b1SMemoryShore                 )),
216*a17651b1SMemoryShore                 klog_types::LogSource::Buddy,
217*a17651b1SMemoryShore             );
218*a17651b1SMemoryShore             let paddr = mapper.translate(address).unwrap().0;
219*a17651b1SMemoryShore             let mut anon_vma_guard = page_manager_lock_irqsave();
220*a17651b1SMemoryShore             let page = anon_vma_guard.get_mut(&paddr);
221*a17651b1SMemoryShore             page.insert_vma(vma.clone());
222*a17651b1SMemoryShore             VmFaultReason::VM_FAULT_COMPLETED
223*a17651b1SMemoryShore         } else {
224*a17651b1SMemoryShore             VmFaultReason::VM_FAULT_OOM
225*a17651b1SMemoryShore         }
226*a17651b1SMemoryShore     }
227*a17651b1SMemoryShore 
228*a17651b1SMemoryShore     /// 处理文件映射页的缺页异常
229*a17651b1SMemoryShore     /// ## 参数
230*a17651b1SMemoryShore     ///
231*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
232*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
233*a17651b1SMemoryShore     ///
234*a17651b1SMemoryShore     /// ## 返回值
235*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
236*a17651b1SMemoryShore     #[allow(unused_variables)]
237*a17651b1SMemoryShore     pub unsafe fn do_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
238*a17651b1SMemoryShore         panic!(
239*a17651b1SMemoryShore             "do_fault has not yet been implemented,
240*a17651b1SMemoryShore         fault message: {:?},
241*a17651b1SMemoryShore         pid: {}\n",
242*a17651b1SMemoryShore             pfm,
243*a17651b1SMemoryShore             crate::process::ProcessManager::current_pid().data()
244*a17651b1SMemoryShore         );
245*a17651b1SMemoryShore         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_fault
246*a17651b1SMemoryShore     }
247*a17651b1SMemoryShore 
248*a17651b1SMemoryShore     /// 处理私有文件映射的写时复制
249*a17651b1SMemoryShore     /// ## 参数
250*a17651b1SMemoryShore     ///
251*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
252*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
253*a17651b1SMemoryShore     ///
254*a17651b1SMemoryShore     /// ## 返回值
255*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
256*a17651b1SMemoryShore     #[allow(dead_code, unused_variables)]
257*a17651b1SMemoryShore     pub unsafe fn do_cow_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
258*a17651b1SMemoryShore         panic!(
259*a17651b1SMemoryShore             "do_cow_fault has not yet been implemented,
260*a17651b1SMemoryShore         fault message: {:?},
261*a17651b1SMemoryShore         pid: {}\n",
262*a17651b1SMemoryShore             pfm,
263*a17651b1SMemoryShore             crate::process::ProcessManager::current_pid().data()
264*a17651b1SMemoryShore         );
265*a17651b1SMemoryShore         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_cow_fault
266*a17651b1SMemoryShore     }
267*a17651b1SMemoryShore 
268*a17651b1SMemoryShore     /// 处理文件映射页的缺页异常
269*a17651b1SMemoryShore     /// ## 参数
270*a17651b1SMemoryShore     ///
271*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
272*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
273*a17651b1SMemoryShore     ///
274*a17651b1SMemoryShore     /// ## 返回值
275*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
276*a17651b1SMemoryShore     #[allow(dead_code, unused_variables)]
277*a17651b1SMemoryShore     pub unsafe fn do_read_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
278*a17651b1SMemoryShore         panic!(
279*a17651b1SMemoryShore             "do_read_fault has not yet been implemented,
280*a17651b1SMemoryShore         fault message: {:?},
281*a17651b1SMemoryShore         pid: {}\n",
282*a17651b1SMemoryShore             pfm,
283*a17651b1SMemoryShore             crate::process::ProcessManager::current_pid().data()
284*a17651b1SMemoryShore         );
285*a17651b1SMemoryShore         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_read_fault
286*a17651b1SMemoryShore     }
287*a17651b1SMemoryShore 
288*a17651b1SMemoryShore     /// 处理对共享文件映射区写入引起的缺页
289*a17651b1SMemoryShore     /// ## 参数
290*a17651b1SMemoryShore     ///
291*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
292*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
293*a17651b1SMemoryShore     ///
294*a17651b1SMemoryShore     /// ## 返回值
295*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
296*a17651b1SMemoryShore     #[allow(dead_code, unused_variables)]
297*a17651b1SMemoryShore     pub unsafe fn do_shared_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
298*a17651b1SMemoryShore         panic!(
299*a17651b1SMemoryShore             "do_shared_fault has not yet been implemented,
300*a17651b1SMemoryShore         fault message: {:?},
301*a17651b1SMemoryShore         pid: {}\n",
302*a17651b1SMemoryShore             pfm,
303*a17651b1SMemoryShore             crate::process::ProcessManager::current_pid().data()
304*a17651b1SMemoryShore         );
305*a17651b1SMemoryShore         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_shared_fault
306*a17651b1SMemoryShore     }
307*a17651b1SMemoryShore 
308*a17651b1SMemoryShore     /// 处理被置换页面的缺页异常
309*a17651b1SMemoryShore     /// ## 参数
310*a17651b1SMemoryShore     ///
311*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
312*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
313*a17651b1SMemoryShore     ///
314*a17651b1SMemoryShore     /// ## 返回值
315*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
316*a17651b1SMemoryShore     #[allow(unused_variables)]
317*a17651b1SMemoryShore     pub unsafe fn do_swap_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
318*a17651b1SMemoryShore         panic!(
319*a17651b1SMemoryShore             "do_swap_page has not yet been implemented,
320*a17651b1SMemoryShore         fault message: {:?},
321*a17651b1SMemoryShore         pid: {}\n",
322*a17651b1SMemoryShore             pfm,
323*a17651b1SMemoryShore             crate::process::ProcessManager::current_pid().data()
324*a17651b1SMemoryShore         );
325*a17651b1SMemoryShore         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_swap_page
326*a17651b1SMemoryShore     }
327*a17651b1SMemoryShore 
328*a17651b1SMemoryShore     /// 处理NUMA的缺页异常
329*a17651b1SMemoryShore     /// ## 参数
330*a17651b1SMemoryShore     ///
331*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
332*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
333*a17651b1SMemoryShore     ///
334*a17651b1SMemoryShore     /// ## 返回值
335*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
336*a17651b1SMemoryShore     #[allow(unused_variables)]
337*a17651b1SMemoryShore     pub unsafe fn do_numa_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
338*a17651b1SMemoryShore         panic!(
339*a17651b1SMemoryShore             "do_numa_page has not yet been implemented,
340*a17651b1SMemoryShore         fault message: {:?},
341*a17651b1SMemoryShore         pid: {}\n",
342*a17651b1SMemoryShore             pfm,
343*a17651b1SMemoryShore             crate::process::ProcessManager::current_pid().data()
344*a17651b1SMemoryShore         );
345*a17651b1SMemoryShore         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_numa_page
346*a17651b1SMemoryShore     }
347*a17651b1SMemoryShore 
348*a17651b1SMemoryShore     /// 处理写保护页面的写保护异常
349*a17651b1SMemoryShore     /// ## 参数
350*a17651b1SMemoryShore     ///
351*a17651b1SMemoryShore     /// - `pfm`: 缺页异常信息
352*a17651b1SMemoryShore     /// - `mapper`: 页表映射器
353*a17651b1SMemoryShore     ///
354*a17651b1SMemoryShore     /// ## 返回值
355*a17651b1SMemoryShore     /// - VmFaultReason: 页面错误处理信息标志
356*a17651b1SMemoryShore     pub unsafe fn do_wp_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
357*a17651b1SMemoryShore         let address = pfm.address_aligned_down();
358*a17651b1SMemoryShore         let vma = pfm.vma.clone();
359*a17651b1SMemoryShore         let old_paddr = mapper.translate(address).unwrap().0;
360*a17651b1SMemoryShore         let mut page_manager = page_manager_lock_irqsave();
361*a17651b1SMemoryShore         let map_count = page_manager.get_mut(&old_paddr).map_count();
362*a17651b1SMemoryShore         drop(page_manager);
363*a17651b1SMemoryShore 
364*a17651b1SMemoryShore         let mut entry = mapper.get_entry(address, 0).unwrap();
365*a17651b1SMemoryShore         let new_flags = entry.flags().set_write(true);
366*a17651b1SMemoryShore 
367*a17651b1SMemoryShore         if map_count == 1 {
368*a17651b1SMemoryShore             let table = mapper.get_table(address, 0).unwrap();
369*a17651b1SMemoryShore             let i = table.index_of(address).unwrap();
370*a17651b1SMemoryShore             entry.set_flags(new_flags);
371*a17651b1SMemoryShore             table.set_entry(i, entry);
372*a17651b1SMemoryShore             VmFaultReason::VM_FAULT_COMPLETED
373*a17651b1SMemoryShore         } else if let Some(flush) = mapper.map(address, new_flags) {
374*a17651b1SMemoryShore             let mut page_manager = page_manager_lock_irqsave();
375*a17651b1SMemoryShore             let old_page = page_manager.get_mut(&old_paddr);
376*a17651b1SMemoryShore             old_page.remove_vma(&vma);
377*a17651b1SMemoryShore             drop(page_manager);
378*a17651b1SMemoryShore 
379*a17651b1SMemoryShore             flush.flush();
380*a17651b1SMemoryShore             let paddr = mapper.translate(address).unwrap().0;
381*a17651b1SMemoryShore             let mut anon_vma_guard = page_manager_lock_irqsave();
382*a17651b1SMemoryShore             let page = anon_vma_guard.get_mut(&paddr);
383*a17651b1SMemoryShore             page.insert_vma(vma.clone());
384*a17651b1SMemoryShore 
385*a17651b1SMemoryShore             (MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8).copy_from_nonoverlapping(
386*a17651b1SMemoryShore                 MMArch::phys_2_virt(old_paddr).unwrap().data() as *mut u8,
387*a17651b1SMemoryShore                 MMArch::PAGE_SIZE,
388*a17651b1SMemoryShore             );
389*a17651b1SMemoryShore 
390*a17651b1SMemoryShore             VmFaultReason::VM_FAULT_COMPLETED
391*a17651b1SMemoryShore         } else {
392*a17651b1SMemoryShore             VmFaultReason::VM_FAULT_OOM
393*a17651b1SMemoryShore         }
394*a17651b1SMemoryShore     }
395*a17651b1SMemoryShore }
396