Snap for 8841009 from a0be3ab677af6bf834818288b104a63d9a4dc168 to gki13-boot-release

Change-Id: I09301246c0890c3adbc95c876b0fb41d052d6724
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 @@
     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 @@
     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 @@
   }
   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 @@
 /// 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 @@
 /// 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 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 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 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 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 @@
 /// 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 @@
             // 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 @@
 
 /// 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 @@
         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_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));
+    }
+}