mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
aarch64: fix vm clone fault in fork
This commit is contained in:
parent
35079e4193
commit
bfe03b8ea0
8
kernel/Cargo.lock
generated
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…
Reference in New Issue
Block a user