aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Walbran <qwandor@google.com>2022-06-29 13:42:26 +0000
committerAndrew Walbran <qwandor@google.com>2022-06-29 13:46:29 +0000
commita0be3ab677af6bf834818288b104a63d9a4dc168 (patch)
tree149aedfdc55b67e5726fde856430456a22ea7ca2
parent946dae8f6e7beebc35738b0320114855dcc0defb (diff)
downloadaarch64-paging-a0be3ab677af6bf834818288b104a63d9a4dc168.tar.gz
Update aarch64-paging to 0.2.1.
Test: m vmbase_example pvmfw Change-Id: Id04924062f4e8676174586b40826216b30173257
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp4
-rw-r--r--Cargo.toml2
-rw-r--r--Cargo.toml.orig2
-rw-r--r--METADATA6
-rw-r--r--src/idmap.rs4
-rw-r--r--src/lib.rs2
-rw-r--r--src/paging.rs125
8 files changed, 131 insertions, 16 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 98e0084..6eae027 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "ead9be980db36180d96eaf0c08cee61441d72f17"
+ "sha1": "c5c869961318cc95a5fb5e61a7da0783fea04510"
},
"path_in_vcs": ""
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 89e2f97..19fa983 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,7 +45,7 @@ rust_test {
host_supported: true,
crate_name: "aarch64_paging",
cargo_env_compat: true,
- cargo_pkg_version: "0.2.0",
+ cargo_pkg_version: "0.2.1",
srcs: ["src/lib.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -69,7 +69,7 @@ rust_library {
host_supported: true,
crate_name: "aarch64_paging",
cargo_env_compat: true,
- cargo_pkg_version: "0.2.0",
+ cargo_pkg_version: "0.2.1",
srcs: ["src/lib.rs"],
edition: "2021",
rustlibs: [
diff --git a/Cargo.toml b/Cargo.toml
index b0eada2..894c161 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2021"
name = "aarch64-paging"
-version = "0.2.0"
+version = "0.2.1"
authors = [
"Ard Biesheuvel <ardb@google.com>",
"Andrew Walbran <qwandor@google.com>",
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index c377d9d..74d0137 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "aarch64-paging"
-version = "0.2.0"
+version = "0.2.1"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "A library to manipulate AArch64 VMSA EL1 page tables."
diff --git a/METADATA b/METADATA
index 4cdf7fb..3ae9d2a 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/aarch64-paging/aarch64-paging-0.2.0.crate"
+ value: "https://static.crates.io/crates/aarch64-paging/aarch64-paging-0.2.1.crate"
}
- version: "0.2.0"
+ version: "0.2.1"
license_type: NOTICE
last_upgrade_date {
year: 2022
month: 6
- day: 24
+ day: 29
}
}
diff --git a/src/idmap.rs b/src/idmap.rs
index dcd6892..63918df 100644
--- a/src/idmap.rs
+++ b/src/idmap.rs
@@ -37,7 +37,7 @@ use core::arch::asm;
/// idmap.map_range(
/// &MemoryRegion::new(0x80200000, 0x80400000),
/// Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::EXECUTE_NEVER,
-/// );
+/// ).unwrap();
/// // Set `TTBR0_EL1` to activate the page table.
/// # #[cfg(target_arch = "aarch64")]
/// idmap.activate();
@@ -51,7 +51,7 @@ use core::arch::asm;
/// idmap.map_range(
/// &MemoryRegion::new(0x80200000, 0x80400000),
/// Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,
-/// );
+/// ).unwrap();
/// # #[cfg(target_arch = "aarch64")]
/// idmap.activate();
/// ```
diff --git a/src/lib.rs b/src/lib.rs
index 3c04017..40abedd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -30,7 +30,7 @@
//! idmap.map_range(
//! &MemoryRegion::new(0x80200000, 0x80400000),
//! Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,
-//! );
+//! ).unwrap();
//! // Set `TTBR0_EL1` to activate the page table.
//! # #[cfg(target_arch = "aarch64")]
//! idmap.activate();
diff --git a/src/paging.rs b/src/paging.rs
index e93d66c..d463bef 100644
--- a/src/paging.rs
+++ b/src/paging.rs
@@ -11,7 +11,7 @@ use bitflags::bitflags;
use core::alloc::Layout;
use core::fmt::{self, Debug, Display, Formatter};
use core::marker::PhantomData;
-use core::ops::Range;
+use core::ops::{Add, Range, Sub};
use core::ptr::NonNull;
const PAGE_SHIFT: usize = 12;
@@ -54,6 +54,22 @@ impl Debug for VirtualAddress {
}
}
+impl Sub for VirtualAddress {
+ type Output = usize;
+
+ fn sub(self, other: Self) -> Self::Output {
+ self.0 - other.0
+ }
+}
+
+impl Add<usize> for VirtualAddress {
+ type Output = Self;
+
+ fn add(self, other: usize) -> Self {
+ Self(self.0 + other)
+ }
+}
+
/// A range of virtual addresses which may be mapped in a page table.
#[derive(Clone, Eq, PartialEq)]
pub struct MemoryRegion(Range<VirtualAddress>);
@@ -75,6 +91,22 @@ impl Debug for PhysicalAddress {
}
}
+impl Sub for PhysicalAddress {
+ type Output = usize;
+
+ fn sub(self, other: Self) -> Self::Output {
+ self.0 - other.0
+ }
+}
+
+impl Add<usize> for PhysicalAddress {
+ type Output = Self;
+
+ fn add(self, other: usize) -> Self {
+ Self(self.0 + other)
+ }
+}
+
/// Returns the size in bytes of the address space covered by a single entry in the page table at
/// the given level.
fn granularity_at_level(level: usize) -> usize {
@@ -121,6 +153,24 @@ impl MemoryRegion {
}
}
+impl From<Range<VirtualAddress>> for MemoryRegion {
+ fn from(range: Range<VirtualAddress>) -> Self {
+ Self::new(range.start.0, range.end.0)
+ }
+}
+
+impl Display for MemoryRegion {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
+ write!(f, "{}..{}", self.0.start, self.0.end)
+ }
+}
+
+impl Debug for MemoryRegion {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
+ Display::fmt(self, f)
+ }
+}
+
/// A complete hierarchy of page tables including all levels.
#[derive(Debug)]
pub struct RootTable<T: Translation> {
@@ -240,8 +290,9 @@ bitflags! {
/// implement `Debug` and `Drop`, as walking the page table hierachy requires knowing the starting
/// level.
struct PageTableWithLevel<T: Translation> {
- table: NonNull<PageTable<T>>,
+ table: NonNull<PageTable>,
level: usize,
+ _phantom_data: PhantomData<T>,
}
impl<T: Translation> PageTableWithLevel<T> {
@@ -253,6 +304,7 @@ impl<T: Translation> PageTableWithLevel<T> {
// allocator, and the memory is zeroed which is valid initialisation for a PageTable.
table: unsafe { allocate_zeroed() },
level,
+ _phantom_data: PhantomData,
}
}
@@ -364,9 +416,8 @@ impl<T: Translation> Debug for PageTableWithLevel<T> {
/// A single level of a page table.
#[repr(C, align(4096))]
-struct PageTable<T: Translation> {
+struct PageTable {
entries: [Descriptor; 1 << BITS_PER_LEVEL],
- _phantom_data: PhantomData<T>,
}
/// An entry in a page table.
@@ -419,10 +470,11 @@ impl Descriptor {
if level < LEAF_LEVEL && self.is_table_or_page() {
if let Some(output_address) = self.output_address() {
let va = T::physical_to_virtual(output_address);
- let ptr = va.0 as *mut PageTable<T>;
+ let ptr = va.0 as *mut PageTable;
return Some(PageTableWithLevel {
level: level + 1,
table: NonNull::new(ptr).expect("Subtable pointer must be non-null."),
+ _phantom_data: PhantomData,
});
}
}
@@ -463,3 +515,66 @@ const fn align_down(value: usize, alignment: usize) -> usize {
const fn align_up(value: usize, alignment: usize) -> usize {
((value - 1) | (alignment - 1)) + 1
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use alloc::{format, string::ToString};
+
+ #[test]
+ fn display_memory_region() {
+ let region = MemoryRegion::new(0x1234, 0x56789);
+ assert_eq!(
+ &region.to_string(),
+ "0x0000000000001000..0x0000000000057000"
+ );
+ assert_eq!(
+ &format!("{:?}", region),
+ "0x0000000000001000..0x0000000000057000"
+ );
+ }
+
+ #[test]
+ fn subtract_virtual_address() {
+ let low = VirtualAddress(0x12);
+ let high = VirtualAddress(0x1234);
+ assert_eq!(high - low, 0x1222);
+ }
+
+ #[test]
+ #[should_panic]
+ fn subtract_virtual_address_overflow() {
+ let low = VirtualAddress(0x12);
+ let high = VirtualAddress(0x1234);
+
+ // This would overflow, so should panic.
+ let _ = low - high;
+ }
+
+ #[test]
+ fn add_virtual_address() {
+ assert_eq!(VirtualAddress(0x1234) + 0x42, VirtualAddress(0x1276));
+ }
+
+ #[test]
+ fn subtract_physical_address() {
+ let low = PhysicalAddress(0x12);
+ let high = PhysicalAddress(0x1234);
+ assert_eq!(high - low, 0x1222);
+ }
+
+ #[test]
+ #[should_panic]
+ fn subtract_physical_address_overflow() {
+ let low = PhysicalAddress(0x12);
+ let high = PhysicalAddress(0x1234);
+
+ // This would overflow, so should panic.
+ let _ = low - high;
+ }
+
+ #[test]
+ fn add_physical_address() {
+ assert_eq!(PhysicalAddress(0x1234) + 0x42, PhysicalAddress(0x1276));
+ }
+}