Skip to content

Commit 9d76d22

Browse files
authored
Merge pull request #20 from AsakuraMizu/feat/copy
feat: copy and clear
2 parents 33ad75a + e0c6561 commit 9d76d22

File tree

5 files changed

+55
-21
lines changed

5 files changed

+55
-21
lines changed

Cargo.lock

Lines changed: 9 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
[workspace]
22
resolver = "2"
33

4-
members = [
5-
"page_table_multiarch",
6-
"page_table_entry",
7-
]
4+
members = ["page_table_multiarch", "page_table_entry"]
85

96
[workspace.package]
107
version = "0.5.3"
@@ -17,3 +14,6 @@ repository = "https://github.com/arceos-org/page_table_multiarch"
1714
keywords = ["arceos", "paging", "page-table", "virtual-memory"]
1815
categories = ["os", "hardware-support", "memory-management", "no-std"]
1916
rust-version = "1.85"
17+
18+
[workspace.dependencies]
19+
memory_addr = "0.4"

page_table_entry/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ arm-el2 = []
1717

1818
[dependencies]
1919
bitflags = "2.6"
20-
memory_addr = "0.3"
20+
memory_addr.workspace = true
2121

2222
[target.'cfg(any(target_arch = "aarch64", doc))'.dependencies]
2323
aarch64-cpu = "10.0"
@@ -26,4 +26,4 @@ aarch64-cpu = "10.0"
2626
x86_64 = "0.15.2"
2727

2828
[package.metadata.docs.rs]
29-
rustc-args = [ "--cfg" , "doc"]
29+
rustc-args = ["--cfg", "doc"]

page_table_multiarch/Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@ keywords.workspace = true
1212
categories.workspace = true
1313
rust-version.workspace = true
1414

15+
[features]
16+
default = []
17+
copy-from = ["dep:bitmaps"]
18+
1519
[dependencies]
1620
log = "0.4"
17-
memory_addr = "0.3"
21+
memory_addr.workspace = true
1822
page_table_entry = { path = "../page_table_entry", version = "0.5.2" }
23+
bitmaps = { version = "3.2", default-features = false, optional = true }
1924

2025
[target.'cfg(any(target_arch = "x86_64", doc))'.dependencies]
2126
x86 = "0.52"
@@ -24,4 +29,4 @@ x86 = "0.52"
2429
riscv = { version = "0.12", default-features = false }
2530

2631
[package.metadata.docs.rs]
27-
rustc-args = [ "--cfg" , "doc"]
32+
rustc-args = ["--cfg", "doc"]

page_table_multiarch/src/bits64.rs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const fn p1_index(vaddr: usize) -> usize {
2727
/// When the [`PageTable64`] itself is dropped.
2828
pub struct PageTable64<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> {
2929
root_paddr: PhysAddr,
30+
#[cfg(feature = "copy-from")]
31+
borrowed_entries: bitmaps::Bitmap<ENTRY_COUNT>,
3032
_phantom: PhantomData<(M, PTE, H)>,
3133
}
3234

@@ -38,6 +40,8 @@ impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> PageTable64<M, PTE, H
3840
let root_paddr = Self::alloc_table()?;
3941
Ok(Self {
4042
root_paddr,
43+
#[cfg(feature = "copy-from")]
44+
borrowed_entries: bitmaps::Bitmap::new(),
4145
_phantom: PhantomData,
4246
})
4347
}
@@ -325,6 +329,7 @@ impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> PageTable64<M, PTE, H
325329
}
326330

327331
/// Copy entries from another page table within the given virtual memory range.
332+
#[cfg(feature = "copy-from")]
328333
pub fn copy_from(&mut self, other: &Self, start: M::VirtAddr, size: usize) {
329334
if size == 0 {
330335
return;
@@ -342,7 +347,13 @@ impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> PageTable64<M, PTE, H
342347
let end_idx = index_fn(start.into() + size - 1) + 1;
343348
assert!(start_idx < ENTRY_COUNT);
344349
assert!(end_idx <= ENTRY_COUNT);
345-
dst_table[start_idx..end_idx].copy_from_slice(&src_table[start_idx..end_idx]);
350+
for i in start_idx..end_idx {
351+
let entry = &mut dst_table[i];
352+
if !self.borrowed_entries.set(i, true) {
353+
self.dealloc_tree(entry, 1);
354+
}
355+
*entry = src_table[i];
356+
}
346357
}
347358
}
348359

@@ -520,20 +531,31 @@ impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> PageTable64<M, PTE, H
520531
}
521532
Ok(())
522533
}
534+
535+
fn dealloc_tree(&self, table_entry: &PTE, level: usize) {
536+
// don't free the entries in last level, they are not array.
537+
if level < M::LEVELS - 1 {
538+
if let Ok(table) = self.next_table(table_entry) {
539+
for entry in table {
540+
self.dealloc_tree(entry, level + 1);
541+
}
542+
H::dealloc_frame(table_entry.paddr());
543+
}
544+
}
545+
}
523546
}
524547

525548
impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> Drop for PageTable64<M, PTE, H> {
526549
fn drop(&mut self) {
527-
// don't free the entries in last level, they are not array.
528-
let _ = self.walk(
529-
usize::MAX,
530-
None,
531-
Some(&|level, _index, _vaddr, entry: &PTE| {
532-
if level < M::LEVELS - 1 && entry.is_present() && !entry.is_huge() {
533-
H::dealloc_frame(entry.paddr());
534-
}
535-
}),
536-
);
550+
let root = self.table_of(self.root_paddr);
551+
#[allow(unused_variables)]
552+
for (i, entry) in root.iter().enumerate() {
553+
#[cfg(feature = "copy-from")]
554+
if self.borrowed_entries.get(i) {
555+
continue;
556+
}
557+
self.dealloc_tree(entry, 1);
558+
}
537559
H::dealloc_frame(self.root_paddr());
538560
}
539561
}

0 commit comments

Comments
 (0)