Check if pci range is within platform memory range

Also update the platform memory range to 0x100_0000_0000 (0x1<<40) to
correctly reflect the 40-bit IPA.

Bug: 249054080
Test: TH
Change-Id: Id00558a5e450c5d395a595d38c5c4fa573718f3f
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index fca4583..7d88455 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -18,8 +18,12 @@
 use crate::helpers::flatten;
 use crate::helpers::GUEST_PAGE_SIZE;
 use crate::helpers::SIZE_4KB;
+use crate::memory::BASE_ADDR;
+use crate::memory::MAX_ADDR;
 use crate::RebootReason;
 use alloc::ffi::CString;
+use core::cmp::max;
+use core::cmp::min;
 use core::ffi::CStr;
 use core::mem::size_of;
 use core::ops::Range;
@@ -103,8 +107,8 @@
 /// Check if memory range is ok
 fn validate_memory_range(range: &Range<usize>) -> Result<(), RebootReason> {
     let base = range.start;
-    if base as u64 != DeviceTreeInfo::RAM_BASE_ADDR {
-        error!("Memory base address {:#x} is not {:#x}", base, DeviceTreeInfo::RAM_BASE_ADDR);
+    if base != BASE_ADDR {
+        error!("Memory base address {:#x} is not {:#x}", base, BASE_ADDR);
         return Err(RebootReason::InvalidFdt);
     }
 
@@ -123,10 +127,9 @@
 
 fn patch_memory_range(fdt: &mut Fdt, memory_range: &Range<usize>) -> libfdt::Result<()> {
     let size = memory_range.len() as u64;
-    fdt.node_mut(cstr!("/memory"))?.ok_or(FdtError::NotFound)?.setprop_inplace(
-        cstr!("reg"),
-        flatten(&[DeviceTreeInfo::RAM_BASE_ADDR.to_be_bytes(), size.to_be_bytes()]),
-    )
+    fdt.node_mut(cstr!("/memory"))?
+        .ok_or(FdtError::NotFound)?
+        .setprop_inplace(cstr!("reg"), flatten(&[BASE_ADDR.to_be_bytes(), size.to_be_bytes()]))
 }
 
 /// Read the number of CPUs from DT
@@ -225,9 +228,9 @@
     Ok(PciInfo { ranges: [range0, range1], irq_masks, irq_maps })
 }
 
-fn validate_pci_info(pci_info: &PciInfo) -> Result<(), RebootReason> {
+fn validate_pci_info(pci_info: &PciInfo, memory_range: &Range<usize>) -> Result<(), RebootReason> {
     for range in pci_info.ranges.iter() {
-        validate_pci_addr_range(range)?;
+        validate_pci_addr_range(range, memory_range)?;
     }
     for irq_mask in pci_info.irq_masks.iter() {
         validate_pci_irq_mask(irq_mask)?;
@@ -238,7 +241,10 @@
     Ok(())
 }
 
-fn validate_pci_addr_range(range: &PciAddrRange) -> Result<(), RebootReason> {
+fn validate_pci_addr_range(
+    range: &PciAddrRange,
+    memory_range: &Range<usize>,
+) -> Result<(), RebootReason> {
     let mem_flags = PciMemoryFlags(range.addr.0);
     let range_type = mem_flags.range_type();
     let prefetchable = mem_flags.prefetchable();
@@ -260,8 +266,23 @@
         return Err(RebootReason::InvalidFdt);
     }
 
-    if bus_addr.checked_add(size).is_none() {
-        error!("PCI address range size {:#x} too big", size);
+    let Some(bus_end) = bus_addr.checked_add(size) else {
+        error!("PCI address range size {:#x} overflows", size);
+        return Err(RebootReason::InvalidFdt);
+    };
+    if bus_end > MAX_ADDR.try_into().unwrap() {
+        error!("PCI address end {:#x} is outside of translatable range", bus_end);
+        return Err(RebootReason::InvalidFdt);
+    }
+
+    let memory_start = memory_range.start.try_into().unwrap();
+    let memory_end = memory_range.end.try_into().unwrap();
+
+    if max(bus_addr, memory_start) < min(bus_end, memory_end) {
+        error!(
+            "PCI address range {:#x}-{:#x} overlaps with main memory range {:#x}-{:#x}",
+            bus_addr, bus_end, memory_start, memory_end
+        );
         return Err(RebootReason::InvalidFdt);
     }
 
@@ -517,7 +538,6 @@
 }
 
 impl DeviceTreeInfo {
-    const RAM_BASE_ADDR: u64 = 0x8000_0000;
     const GIC_REDIST_SIZE_PER_CPU: u64 = (32 * SIZE_4KB) as u64;
 }
 
@@ -566,7 +586,7 @@
         error!("Failed to read pci info from DT: {e}");
         RebootReason::InvalidFdt
     })?;
-    validate_pci_info(&pci_info)?;
+    validate_pci_info(&pci_info, &memory_range)?;
 
     let serial_info = read_serial_info_from(fdt).map_err(|e| {
         error!("Failed to read serial info from DT: {e}");
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index 17dd36b..b223f82 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -35,6 +35,11 @@
 use log::error;
 use tinyvec::ArrayVec;
 
+/// Base of the system's contiguous "main" memory.
+pub const BASE_ADDR: usize = 0x8000_0000;
+/// First address that can't be translated by a level 1 TTBR0_EL1.
+pub const MAX_ADDR: usize = 1 << 40;
+
 pub type MemoryRange = Range<usize>;
 
 #[derive(Clone, Copy, Debug, Default)]
@@ -129,15 +134,11 @@
 impl MemoryTracker {
     const CAPACITY: usize = 5;
     const MMIO_CAPACITY: usize = 5;
-    /// Base of the system's contiguous "main" memory.
-    const BASE: usize = 0x8000_0000;
-    /// First address that can't be translated by a level 1 TTBR0_EL1.
-    const MAX_ADDR: usize = 1 << 39;
 
     /// Create a new instance from an active page table, covering the maximum RAM size.
     pub fn new(page_table: mmu::PageTable) -> Self {
         Self {
-            total: Self::BASE..Self::MAX_ADDR,
+            total: BASE_ADDR..MAX_ADDR,
             page_table,
             regions: ArrayVec::new(),
             mmio_regions: ArrayVec::new(),