From bfe03b8ea04d4fb6acae3a1a23408a41804f2848 Mon Sep 17 00:00:00 2001 From: equation314 Date: Mon, 6 May 2019 23:30:01 +0800 Subject: [PATCH] aarch64: fix vm clone fault in fork --- kernel/Cargo.lock | 8 +++---- kernel/Cargo.toml | 2 +- kernel/src/arch/aarch64/paging.rs | 39 ++++++++----------------------- 3 files changed, 15 insertions(+), 34 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index eea1e412..b76366e7 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -14,8 +14,8 @@ dependencies = [ [[package]] name = "aarch64" -version = "2.2.2" -source = "git+https://github.com/rcore-os/aarch64#14a08f4d285ae0ff515b03bff9f5e66eb68feaed" +version = "2.5.0" +source = "git+https://github.com/rcore-os/aarch64#e52eae8dc35069661bb948b2c4443af98d1e62d7" dependencies = [ "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -359,7 +359,7 @@ dependencies = [ name = "rcore" version = "0.2.0" dependencies = [ - "aarch64 2.2.2 (git+https://github.com/rcore-os/aarch64)", + "aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)", "apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)", "bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -653,7 +653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aarch64 2.2.2 (git+https://github.com/equation314/aarch64)" = "" -"checksum aarch64 2.2.2 (git+https://github.com/rcore-os/aarch64)" = "" +"checksum aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)" = "" "checksum apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)" = "" "checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" "checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 8ef38d74..2c3ed115 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -81,7 +81,7 @@ pc-keyboard = "0.5" riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } [target.'cfg(target_arch = "aarch64")'.dependencies] -aarch64 = { git = "https://github.com/rcore-os/aarch64" } +aarch64 = { git = "https://github.com/rcore-os/aarch64", version = "2.5.0" } bcm2837 = { git = "https://github.com/rcore-os/bcm2837", optional = true } [target.'cfg(target_arch = "mips")'.dependencies] diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index fc03b451..4d9e4a35 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -12,7 +12,7 @@ use rcore_memory::paging::*; use crate::consts::{KERNEL_OFFSET, KERNEL_PML4, RECURSIVE_INDEX}; use crate::memory::{active_table, alloc_frame, dealloc_frame}; -pub struct ActivePageTable(RecursivePageTable<'static>); +pub struct ActivePageTable(RecursivePageTable); pub struct PageEntry(PageTableEntry); @@ -34,8 +34,7 @@ impl PageTable for ActivePageTable { } fn unmap(&mut self, addr: usize) { - let (_frame, flush) = self.0.unmap(Page::of_addr(addr as u64)).unwrap(); - flush.flush(); + self.0.unmap(Page::of_addr(addr as u64)).unwrap().1.flush(); } fn get_entry(&mut self, vaddr: usize) -> Option<&mut Entry> { @@ -50,16 +49,9 @@ impl PageTableExt for ActivePageTable { const TEMP_PAGE_ADDR: usize = KERNEL_OFFSET | 0xcafeb000; } -const ROOT_PAGE_TABLE: *mut Aarch64PageTable = (KERNEL_OFFSET - | (RECURSIVE_INDEX << 39) - | (RECURSIVE_INDEX << 30) - | (RECURSIVE_INDEX << 21) - | (RECURSIVE_INDEX << 12)) - as *mut Aarch64PageTable; - impl ActivePageTable { pub unsafe fn new() -> Self { - ActivePageTable(RecursivePageTable::new(&mut *(ROOT_PAGE_TABLE as *mut _)).unwrap()) + ActivePageTable(RecursivePageTable::new(RECURSIVE_INDEX as u16)) } } @@ -198,12 +190,6 @@ pub struct InactivePageTable0 { impl InactivePageTable for InactivePageTable0 { type Active = ActivePageTable; - fn new() -> Self { - // When the new InactivePageTable is created for the user MemorySet, it's use ttbr1 as the - // TTBR. And the kernel TTBR ttbr0 will never changed, so we needn't call map_kernel() - Self::new_bare() - } - fn new_bare() -> Self { let target = alloc_frame().expect("failed to allocate frame"); let frame = Frame::of_addr(target as u64); @@ -220,17 +206,8 @@ impl InactivePageTable for InactivePageTable0 { } fn map_kernel(&mut self) { - let table = unsafe { &mut *ROOT_PAGE_TABLE }; - let e0 = table[KERNEL_PML4].clone(); - assert!(!e0.is_unused()); - - self.edit(|_| { - table[KERNEL_PML4].set_frame( - Frame::containing_address(e0.addr()), - EF::default(), - MairNormal::attr_value(), - ); - }); + // When the new InactivePageTable is created for the user MemorySet, it's use ttbr0 as the + // TTBR. And the kernel TTBR ttbr1 will never changed, so we needn't call map_kernel() } fn token(&self) -> usize { @@ -250,7 +227,11 @@ impl InactivePageTable for InactivePageTable0 { } fn edit(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T { - let target = ttbr_el1_read(1).start_address().as_u64() as usize; + let target = ttbr_el1_read(1); + if self.p4_frame == target { + return f(&mut active_table()); + } + let target = target.start_address().as_u64() as usize; active_table().with_temporary_map( target, |active_table, p4_table: &mut Aarch64PageTable| {