diff options
author | Andrew Walbran <qwandor@google.com> | 2022-06-29 13:42:26 +0000 |
---|---|---|
committer | Andrew Walbran <qwandor@google.com> | 2022-06-29 13:46:29 +0000 |
commit | a0be3ab677af6bf834818288b104a63d9a4dc168 (patch) | |
tree | 149aedfdc55b67e5726fde856430456a22ea7ca2 | |
parent | 946dae8f6e7beebc35738b0320114855dcc0defb (diff) | |
download | aarch64-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.json | 2 | ||||
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | Cargo.toml.orig | 2 | ||||
-rw-r--r-- | METADATA | 6 | ||||
-rw-r--r-- | src/idmap.rs | 4 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/paging.rs | 125 |
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 @@ -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: [ @@ -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." @@ -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(); /// ``` @@ -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!( + ®ion.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)); + } +} |