-
Notifications
You must be signed in to change notification settings - Fork 14
Satisfy page cache #48
base: main
Are you sure you want to change the base?
Changes from 1 commit
3b78850
a6661b0
841fb0a
e4dfb2c
2a901f9
45fe967
aef3d94
354271e
e888909
5e92e32
ad8397e
511c2b6
31cd9b0
342ca05
fb449ac
e7890a8
0a246a3
c6b1193
70eca61
94a88d6
9c9baa7
f28657c
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 |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ use core::fmt; | |
|
|
||
| use axerrno::{AxError, AxResult, ax_err}; | ||
| use axhal::mem::phys_to_virt; | ||
| use axhal::paging::{MappingFlags, PageTable, PagingError}; | ||
| use axhal::paging::{MappingFlags, PageTable, PagingError, PageSize}; | ||
| use memory_addr::{ | ||
| MemoryAddr, PAGE_SIZE_4K, PageIter4K, PhysAddr, VirtAddr, VirtAddrRange, is_aligned_4k, | ||
| }; | ||
|
|
@@ -161,6 +161,58 @@ impl AddrSpace { | |
| Ok(()) | ||
| } | ||
|
|
||
| pub fn map_shm( | ||
| &mut self, | ||
| start: VirtAddr, | ||
| size: usize, | ||
| flags: MappingFlags, | ||
| populate: bool, | ||
| ) -> AxResult { | ||
| panic!("Unimplement"); | ||
| } | ||
|
|
||
| /// Add a new file mapping | ||
| pub fn map_file( | ||
| &mut self, | ||
| start: VirtAddr, | ||
| size: usize, | ||
| flags: MappingFlags, | ||
| fd: i32, | ||
| offset: usize, | ||
| shared: bool, | ||
| populate: bool, | ||
| ) -> AxResult { | ||
| self.validate_region(start, size)?; | ||
| // warn!("map file flags: {}", flags.contains(MappingFlags::WRITE)); | ||
| let area = MemoryArea::new(start, size, flags, Backend::new_file(fd, offset, shared, populate)); | ||
| self.areas | ||
| .map(area, &mut self.pt, false) | ||
| .map_err(mapping_err_to_ax_err)?; | ||
| Ok(()) | ||
| } | ||
|
|
||
| /// Forcely set the page table | ||
| pub fn force_map_page( | ||
| &mut self, | ||
| vaddr: VirtAddr, | ||
| paddr: PhysAddr, | ||
| access_flags: MappingFlags | ||
| ) -> bool { | ||
| match self.areas.find(vaddr) { | ||
| Some(area) => { | ||
| if area.flags().contains(access_flags) { | ||
| self.pt.map(vaddr, paddr, PageSize::Size4K, area.flags()) | ||
| .map(|_| true) | ||
| .unwrap_or_else(|_| panic!("FORCE MAP PAGE FAILED(PAGE TABLE FAILEDA): {:#x} => {:#x}!", vaddr, paddr)); | ||
| } else { | ||
| panic!("FORCE MAP PAGE FAILED(ACCESS MOD): {:#x} => {:#x}!", vaddr, paddr); | ||
| } | ||
| }, | ||
| _ => panic!("FORCE MAP PAGE FAILED(NO AREA): {:#x} => {:#x}!", vaddr, paddr), | ||
| }; | ||
| true | ||
| } | ||
|
|
||
| /// Populates the area with physical frames, returning false if the area | ||
| /// contains unmapped area. | ||
| pub fn populate_area(&mut self, mut start: VirtAddr, size: usize) -> AxResult { | ||
|
|
@@ -360,10 +412,25 @@ impl AddrSpace { | |
| false | ||
| } | ||
|
|
||
| /// Returns (fd, offset, shared, popoulate, virtaddr_start) | ||
| pub fn get_file_metadata(&mut self, vaddr: VirtAddr) -> Option<(i32, usize, bool, bool, VirtAddr)> { | ||
| if !self.va_range.contains(vaddr) { | ||
| return None; | ||
| } | ||
| if let Some(area) = self.areas.find(vaddr) { | ||
| match area.backend() { | ||
| Backend::File { fd, offset, shared, populate } | ||
| => return Some((*fd, *offset, *shared, *populate, area.start())), | ||
| _ => return None, | ||
| } | ||
| } | ||
| None | ||
| } | ||
|
|
||
| /// Handles a page fault at the given address. | ||
| /// | ||
| /// `access_flags` indicates the access type that caused the page fault. | ||
| /// | ||
| /// | ||
|
||
| /// Returns `true` if the page fault is handled successfully (not a real | ||
| /// fault). | ||
| pub fn handle_page_fault(&mut self, vaddr: VirtAddr, access_flags: MappingFlags) -> bool { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| use super::Backend; | ||
|
|
||
| impl Backend { | ||
| /// Creates a new allocation mapping backend. | ||
| pub const fn new_file(fd: i32, offset: usize, populate: bool, shared: bool) -> Self { | ||
| Self::File { fd, offset, shared, populate} | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ use memory_set::MappingBackend; | |
|
|
||
| mod alloc; | ||
| mod linear; | ||
| mod file; | ||
|
|
||
| /// A unified enum type for different memory mapping backends. | ||
| /// | ||
|
|
@@ -36,6 +37,13 @@ pub enum Backend { | |
| /// Whether to populate the physical frames when creating the mapping. | ||
| populate: bool, | ||
| }, | ||
| /// File mapping backend. | ||
|
||
| File { | ||
| fd: i32, | ||
| offset: usize, | ||
| shared: bool, | ||
| populate: bool, | ||
| }, | ||
| } | ||
|
|
||
| impl MappingBackend for Backend { | ||
|
|
@@ -46,13 +54,15 @@ impl MappingBackend for Backend { | |
| match *self { | ||
| Self::Linear { pa_va_offset } => Self::map_linear(start, size, flags, pt, pa_va_offset), | ||
| Self::Alloc { populate } => Self::map_alloc(start, size, flags, pt, populate), | ||
| Self::File { .. } => true, | ||
| } | ||
| } | ||
|
|
||
| fn unmap(&self, start: VirtAddr, size: usize, pt: &mut PageTable) -> bool { | ||
| match *self { | ||
| Self::Linear { pa_va_offset } => Self::unmap_linear(start, size, pt, pa_va_offset), | ||
| Self::Alloc { populate } => Self::unmap_alloc(start, size, pt, populate), | ||
| Self::File { .. } => true, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -81,7 +91,8 @@ impl Backend { | |
| Self::Linear { .. } => false, // Linear mappings should not trigger page faults. | ||
| Self::Alloc { populate } => { | ||
| Self::handle_page_fault_alloc(vaddr, orig_flags, page_table, populate) | ||
| } | ||
| }, | ||
| Self::File { .. } => false, | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we don't need to add this function?