1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 16:16:16 +04:00

aarch64: fix vm clone fault in fork

This commit is contained in:
equation314 2019-05-06 23:30:01 +08:00
parent 35079e4193
commit bfe03b8ea0
3 changed files with 15 additions and 34 deletions

8
kernel/Cargo.lock generated
View File

@ -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)" = "<none>"
"checksum aarch64 2.2.2 (git+https://github.com/rcore-os/aarch64)" = "<none>"
"checksum aarch64 2.5.0 (git+https://github.com/rcore-os/aarch64)" = "<none>"
"checksum apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)" = "<none>"
"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"

View File

@ -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]

View File

@ -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<T>(&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| {