Skip to content

Commit

Permalink
fix MemTypePTE
Browse files Browse the repository at this point in the history
  • Loading branch information
yfblock committed Feb 20, 2024
1 parent 3375a74 commit 553fc20
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 116 deletions.
4 changes: 2 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 编译的目标平台
[build]
# target = 'riscv64imac-unknown-none-elf'
target = 'x86_64-unknown-none'
target = 'riscv64imac-unknown-none-elf'
# target = 'x86_64-unknown-none'

# This flags also can be set from every target.
rustflags = [
Expand Down
6 changes: 6 additions & 0 deletions arch/src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ impl From<usize> for PhysPage {
}
}

impl From<PhysAddr> for PhysPage {
fn from(value: PhysAddr) -> Self {
Self(value.0 >> 12)
}
}

impl From<PhysPage> for usize {
fn from(value: PhysPage) -> Self {
value.0
Expand Down
2 changes: 1 addition & 1 deletion arch/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub trait ArchInterface {
/// kernel main function, entry point.
fn main(hartid: usize, device_tree: usize);
/// Alloc a persistent memory page.
fn frame_alloc_persist() -> Option<PhysPage>;
fn frame_alloc_persist() -> PhysPage;
/// Unalloc a persistent memory page
fn frame_unalloc(ppn: PhysPage);
}
2 changes: 1 addition & 1 deletion arch/src/riscv64/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ fn kernel_callback(context: &mut Context) -> usize {
stval,
context.sepc
);
panic!("未知中断")
panic!("未知中断: {:#x?}", context);
}
};
crate::api::ArchInterface::interrupt_table()(context, trap_type);
Expand Down
9 changes: 0 additions & 9 deletions arch/src/riscv64/page_table/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
pub mod sigtrx;
mod sv39;

use riscv::register::satp;
pub use sv39::*;

use crate::PhysAddr;

#[inline]
pub fn current_page_table() -> PageTable {
let addr = satp::read().ppn() << 12;
PageTable::new(PhysAddr(addr))
}
80 changes: 49 additions & 31 deletions arch/src/riscv64/page_table/sv39.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use core::arch::{asm, riscv64::sfence_vma};

use alloc::sync::Arc;
use bitflags::bitflags;

use crate::{
sigtrx::get_trx_mapping, PhysAddr, PhysPage, VirtAddr, VirtPage, PAGE_ITEM_COUNT, PAGE_SIZE
sigtrx::get_trx_mapping, ArchInterface, PhysAddr, PhysPage, VirtAddr, VirtPage, PAGE_ITEM_COUNT, PAGE_SIZE
};

#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -82,6 +83,14 @@ impl PTE {
|| self.flags().contains(PTEFlags::W)
|| self.flags().contains(PTEFlags::X));
}

#[inline]
pub fn is_leaf(&self) -> bool {
return self.flags().contains(PTEFlags::V)
&& !(self.flags().contains(PTEFlags::R)
|| self.flags().contains(PTEFlags::W)
|| self.flags().contains(PTEFlags::X));
}
}

bitflags! {
Expand Down Expand Up @@ -121,24 +130,36 @@ bitflags! {
}
}

#[derive(Debug, Clone, Copy)]
#[inline]
pub fn get_pte_list(paddr: PhysAddr) -> &'static mut [PTE] {
unsafe { core::slice::from_raw_parts_mut(paddr.get_mut_ptr::<PTE>(), PAGE_ITEM_COUNT) }
}

fn destory_pte_leaf(paddr: PhysAddr) {
let pte_list = get_pte_list(paddr);
for pte in pte_list {
if pte.is_leaf() {
destory_pte_leaf(pte.to_ppn().into());
ArchInterface::frame_unalloc(pte.to_ppn());
}
}
ArchInterface::frame_unalloc(paddr.into());
}

#[derive(Debug)]
pub struct PageTable(pub(crate) PhysAddr);

impl PageTable {
pub fn new(addr: PhysAddr) -> Self {
pub fn alloc() -> Arc<Self> {
let addr = ArchInterface::frame_alloc_persist().into();
let page_table = Self(addr);
page_table.restore();
page_table
}

#[inline]
pub fn from_ppn(ppn: PhysPage) -> Self {
Self::new(PhysAddr(ppn.0 << 12))
Arc::new(page_table)
}

#[inline]
pub fn restore(&self) {
let arr = self.get_pte_list();
let arr = get_pte_list(self.0);
arr[0x100] = PTE::from_addr(0x0000_0000, PTEFlags::ADGVRWX);
arr[0x101] = PTE::from_addr(0x4000_0000, PTEFlags::ADGVRWX);
arr[0x102] = PTE::from_addr(0x8000_0000, PTEFlags::ADGVRWX);
Expand All @@ -147,11 +168,6 @@ impl PageTable {
arr[0..0x100].fill(PTE::from_addr(0, PTEFlags::NONE));
}

#[inline]
pub fn get_pte_list(&self) -> &'static mut [PTE] {
unsafe { core::slice::from_raw_parts_mut(self.0.get_mut_ptr::<PTE>(), PAGE_ITEM_COUNT) }
}

#[inline]
pub const fn get_satp(&self) -> usize {
(8 << 60) | (self.0 .0 >> 12)
Expand All @@ -161,33 +177,30 @@ impl PageTable {
pub fn change(&self) {
unsafe {
asm!("csrw satp, {0}", in(reg) self.get_satp());
// satp::set(Mode::Sv39, 0, self.0.0 >> 12);
riscv::asm::sfence_vma_all();
}
}

#[inline]
pub fn map<G>(&self, ppn: PhysPage, vpn: VirtPage, flags: PTEFlags, mut falloc: G, level: usize)
where
G: FnMut() -> PhysPage,
pub fn map(&self, ppn: PhysPage, vpn: VirtPage, flags: PTEFlags, level: usize)
{
// TODO: Add huge page support.
let mut page_table = PageTable(self.0);
let mut pte_list = get_pte_list(self.0);
for i in (1..level).rev() {
let value = (vpn.0 >> 9 * i) & 0x1ff;
let pte = &mut page_table.get_pte_list()[value];
let pte = &mut pte_list[value];
if i == 0 {
break;
}
if !pte.is_valid() {
let ppn = falloc();
*pte = PTE::from_ppn(ppn.0, PTEFlags::V);
*pte = PTE::from_ppn(ArchInterface::frame_alloc_persist().0, PTEFlags::V);
}

page_table = PageTable(pte.to_ppn().into());
// page_table = PageTable(pte.to_ppn().into());
pte_list = get_pte_list(pte.to_ppn().into());
}

page_table.get_pte_list()[vpn.0 & 0x1ff] = PTE::from_ppn(ppn.0, flags);
pte_list[vpn.0 & 0x1ff] = PTE::from_ppn(ppn.0, flags);
unsafe {
sfence_vma(vpn.to_addr(), 0);
}
Expand All @@ -196,17 +209,17 @@ impl PageTable {
#[inline]
pub fn unmap(&self, vpn: VirtPage) {
// TODO: Add huge page support.
let mut page_table = PageTable(self.0);
let mut pte_list = get_pte_list(self.0);
for i in (1..3).rev() {
let value = (vpn.0 >> 9 * i) & 0x1ff;
let pte = &mut page_table.get_pte_list()[value];
let pte = &mut pte_list[value];
if !pte.is_valid() {
return;
}
page_table = PageTable(pte.to_ppn().into());
pte_list = get_pte_list(pte.to_ppn().into());
}

page_table.get_pte_list()[vpn.0 & 0x1ff] = PTE::new();
pte_list[vpn.0 & 0x1ff] = PTE::new();
unsafe {
sfence_vma(vpn.to_addr(), 0);
}
Expand All @@ -216,9 +229,8 @@ impl PageTable {
pub fn virt_to_phys(&self, vaddr: VirtAddr) -> PhysAddr {
let mut paddr = self.0;
for i in (0..3).rev() {
let page_table = PageTable(paddr);
let value = (vaddr.0 >> 12 + 9 * i) & 0x1ff;
let pte = &page_table.get_pte_list()[value];
let pte = &get_pte_list(paddr)[value];
// 如果当前页是大页 返回相关的位置
// vaddr.0 % (1 << (12 + 9 * i)) 是大页内偏移
if pte.is_huge() {
Expand All @@ -229,3 +241,9 @@ impl PageTable {
PhysAddr(paddr.0 | vaddr.0 % PAGE_SIZE)
}
}

impl Drop for PageTable {
fn drop(&mut self) {
destory_pte_leaf(self.0);
}
}
6 changes: 0 additions & 6 deletions arch/src/x86_64/page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,6 @@ impl PageTable {
}
}

#[inline]
pub fn current_page_table() -> PageTable {
// PhysAddr::new(unsafe { controlregs::cr3() } as usize).align_down_4k()
todo!()
}

pub fn switch_to_kernel_page_table() {
unsafe {
// riscv::register::satp::set(
Expand Down
25 changes: 11 additions & 14 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,13 @@ impl ArchInterface for ArchInterfaceImpl {
frame_allocator::add_frame_map(start, end)
}

fn frame_alloc_persist() -> Option<PhysPage> {
unsafe {
frame_alloc_persist()
}
fn frame_alloc_persist() -> PhysPage {
unsafe { frame_alloc_persist().expect("can't alloc frame") }
}

fn frame_unalloc(ppn: PhysPage) {
unsafe {
frame_unalloc(ppn)
}
unsafe { frame_unalloc(ppn) }
ppn.drop_clear();
}
}

Expand Down Expand Up @@ -144,13 +141,13 @@ fn main(hart_id: usize, device_tree: usize) {
enable_irq();

// cache task with task templates
// cache_task_template("/bin/busybox").expect("can't cache task");
// cache_task_template("./busybox").expect("can't cache task");
// cache_task_template("busybox").expect("can't cache task");
// cache_task_template("./runtest.exe").expect("can't cache task");
// cache_task_template("entry-static.exe").expect("can't cache task");
// cache_task_template("libc.so").expect("can't cache task");
// cache_task_template("lmbench_all").expect("can't cache task");
// crate::syscall::cache_task_template("/bin/busybox").expect("can't cache task");
// crate::syscall::cache_task_template("./busybox").expect("can't cache task");
// crate::syscall::cache_task_template("busybox").expect("can't cache task");
// crate::syscall::cache_task_template("./runtest.exe").expect("can't cache task");
// crate::syscall::cache_task_template("entry-static.exe").expect("can't cache task");
// crate::syscall::cache_task_template("libc.so").expect("can't cache task");
// crate::syscall::cache_task_template("lmbench_all").expect("can't cache task");

// init kernel threads and async executor
tasks::init();
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/syscall/mm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub async fn sys_mmap(
task.pcb
.lock()
.memset
.sub_area(addr.addr(), addr.addr() + len, task.page_table);
.sub_area(addr.addr(), addr.addr() + len, &task.page_table);
}
} else if task
.pcb
Expand Down Expand Up @@ -159,7 +159,7 @@ pub async fn sys_munmap(start: usize, len: usize) -> Result<usize, LinuxError> {
debug!("sys_munmap @ start: {:#x}, len: {:#x}", start, len);
let task = current_user_task();
task.inner_map(|pcb| {
pcb.memset.sub_area(start, start + len, task.page_table);
pcb.memset.sub_area(start, start + len, &task.page_table);
});
Ok(0)
}
Expand Down
6 changes: 4 additions & 2 deletions kernel/src/syscall/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@ pub async fn sys_execve(
);
// TODO: use map_err insteads of unwrap and unsafe code.
let filename = filename.get_cstr().map_err(|_| LinuxError::EINVAL)?;
debug!("test0");
let args = args
.slice_until_valid(|x| x.is_valid())
.into_iter()
.map(|x| x.get_cstr().unwrap())
.collect();
debug!("test1: envp: {:?}", envp);
let envp: Vec<&str> = envp
.slice_until_valid(|x| x.is_valid())
.into_iter()
Expand Down Expand Up @@ -294,7 +296,7 @@ pub async fn exec_with_process<'a>(
for area in &cache_task.maps {
user_task.inner_map(|pcb| {
pcb.memset
.sub_area(area.start, area.start + area.len, user_task.page_table);
.sub_area(area.start, area.start + area.len, &user_task.page_table);
pcb.memset.push(area.clone());
});
for mtracker in area.mtrackers.iter() {
Expand Down Expand Up @@ -461,7 +463,7 @@ pub async fn sys_clone(

let new_task = match flags.contains(CloneFlags::CLONE_THREAD) {
true => curr_task.clone().thread_clone(user_entry()),
// false => curr_task.clone().fork(unsafe { user_entry() }),
// false => curr_task.clone().fork(user_entry()),
// use cow(Copy On Write) to save memory.
false => curr_task.clone().cow_fork(user_entry()),
};
Expand Down
6 changes: 4 additions & 2 deletions kernel/src/tasks/initproc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,9 @@ pub async fn initproc() {
// command("busybox sh busybox_testcode.sh").await;

// command("busybox echo run libctest_testcode.sh").await;
// command("busybox sh libctest_testcode.sh").await;
command("busybox sh libctest_testcode.sh").await;
// command("./run-static.sh").await;
// command("./runtest.exe -w entry-static.exe argv").await;

// command("busybox echo run lua_testcode.sh").await;
// command("busybox sh lua_testcode.sh").await;
Expand Down Expand Up @@ -310,7 +312,7 @@ pub async fn initproc() {
// command("busybox sh ./tst.sh ./sort.src").await;
// command("entry-dynamic.exe pthread_cancel_points").await;
// command("bin/sh").await;
command("busybox sh").await;
// command("busybox sh").await;
// command("cloudreve").await;
// command("miniftpd").await;
// command("/server_ftp.out").await;
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/user/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use ::signal::SignalFlags;
use alloc::sync::Arc;
use arch::{get_time, trap_pre_handle, user_restore, Context, ContextOps, PTEFlags, VirtPage};
use devices::get_int_device;
use executor::{AsyncTask, MapTrack, MemType, UserTask};
use executor::{AsyncTask, MapTrack, UserTask};
use frame_allocator::frame_alloc;
use log::{debug, warn};

Expand Down Expand Up @@ -30,7 +30,6 @@ pub fn user_cow_int(task: Arc<UserTask>, _cx_ref: &mut Context, addr: usize) {
let area = pcb
.memset
.iter_mut()
.filter(|x| x.mtype != MemType::PTE)
.find(|x| x.contains(addr));
if let Some(area) = area {
let finded = area.mtrackers.iter_mut().find(|x| x.vpn == vpn);
Expand Down Expand Up @@ -169,7 +168,6 @@ pub fn task_ilegal(task: &Arc<UserTask>, addr: usize, cx_ref: &mut Context) {
let area = pcb
.memset
.iter_mut()
.filter(|x| x.mtype != MemType::PTE)
.find(|x| x.contains(addr));
if let Some(area) = area {
let finded = area.mtrackers.iter_mut().find(|x| x.vpn == vpn);
Expand Down
Loading

0 comments on commit 553fc20

Please sign in to comment.