aarch64: fix vm clone fault in fork

master
equation314 6 years ago
parent 35079e4193
commit bfe03b8ea0

8
kernel/Cargo.lock generated

@ -14,8 +14,8 @@ dependencies = [
[[package]] [[package]]
name = "aarch64" name = "aarch64"
version = "2.2.2" version = "2.5.0"
source = "git+https://github.com/rcore-os/aarch64#14a08f4d285ae0ff515b03bff9f5e66eb68feaed" source = "git+https://github.com/rcore-os/aarch64#e52eae8dc35069661bb948b2c4443af98d1e62d7"
dependencies = [ dependencies = [
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -359,7 +359,7 @@ dependencies = [
name = "rcore" name = "rcore"
version = "0.2.0" version = "0.2.0"
dependencies = [ 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)", "apic 0.1.0 (git+https://github.com/rcore-os/apic-rs)",
"bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)", "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)", "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] [metadata]
"checksum aarch64 2.2.2 (git+https://github.com/equation314/aarch64)" = "<none>" "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 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 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" "checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a"

@ -81,7 +81,7 @@ pc-keyboard = "0.5"
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
[target.'cfg(target_arch = "aarch64")'.dependencies] [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 } bcm2837 = { git = "https://github.com/rcore-os/bcm2837", optional = true }
[target.'cfg(target_arch = "mips")'.dependencies] [target.'cfg(target_arch = "mips")'.dependencies]

@ -12,7 +12,7 @@ use rcore_memory::paging::*;
use crate::consts::{KERNEL_OFFSET, KERNEL_PML4, RECURSIVE_INDEX}; use crate::consts::{KERNEL_OFFSET, KERNEL_PML4, RECURSIVE_INDEX};
use crate::memory::{active_table, alloc_frame, dealloc_frame}; use crate::memory::{active_table, alloc_frame, dealloc_frame};
pub struct ActivePageTable(RecursivePageTable<'static>); pub struct ActivePageTable(RecursivePageTable);
pub struct PageEntry(PageTableEntry); pub struct PageEntry(PageTableEntry);
@ -34,8 +34,7 @@ impl PageTable for ActivePageTable {
} }
fn unmap(&mut self, addr: usize) { fn unmap(&mut self, addr: usize) {
let (_frame, flush) = self.0.unmap(Page::of_addr(addr as u64)).unwrap(); self.0.unmap(Page::of_addr(addr as u64)).unwrap().1.flush();
flush.flush();
} }
fn get_entry(&mut self, vaddr: usize) -> Option<&mut Entry> { 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 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 { impl ActivePageTable {
pub unsafe fn new() -> Self { 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 { impl InactivePageTable for InactivePageTable0 {
type Active = ActivePageTable; 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 { fn new_bare() -> Self {
let target = alloc_frame().expect("failed to allocate frame"); let target = alloc_frame().expect("failed to allocate frame");
let frame = Frame::of_addr(target as u64); let frame = Frame::of_addr(target as u64);
@ -220,17 +206,8 @@ impl InactivePageTable for InactivePageTable0 {
} }
fn map_kernel(&mut self) { fn map_kernel(&mut self) {
let table = unsafe { &mut *ROOT_PAGE_TABLE }; // When the new InactivePageTable is created for the user MemorySet, it's use ttbr0 as the
let e0 = table[KERNEL_PML4].clone(); // TTBR. And the kernel TTBR ttbr1 will never changed, so we needn't call map_kernel()
assert!(!e0.is_unused());
self.edit(|_| {
table[KERNEL_PML4].set_frame(
Frame::containing_address(e0.addr()),
EF::default(),
MairNormal::attr_value(),
);
});
} }
fn token(&self) -> usize { 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 { 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( active_table().with_temporary_map(
target, target,
|active_table, p4_table: &mut Aarch64PageTable| { |active_table, p4_table: &mut Aarch64PageTable| {

Loading…
Cancel
Save