Merge "Don't use *.rs for srcs" into main
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 6a6d199..cce0e73 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -83,6 +83,7 @@
         ":test_pvmfw_devices_vm_dtbo",
         ":test_pvmfw_devices_vm_dtbo_without_symbols",
         ":test_pvmfw_devices_vm_dtbo_with_duplicated_iommus",
+        ":test_pvmfw_devices_overlapping_pvmfw",
         ":test_pvmfw_devices_with_rng",
         ":test_pvmfw_devices_with_multiple_devices_iommus",
         ":test_pvmfw_devices_with_iommu_sharing",
@@ -142,6 +143,13 @@
 }
 
 genrule {
+    name: "test_pvmfw_devices_overlapping_pvmfw",
+    defaults: ["test_device_assignment_dts_to_dtb"],
+    srcs: ["testdata/test_pvmfw_devices_overlapping_pvmfw.dts"],
+    out: ["test_pvmfw_devices_overlapping_pvmfw.dtb"],
+}
+
+genrule {
     name: "test_pvmfw_devices_with_rng",
     defaults: ["test_device_assignment_dts_to_dtb"],
     srcs: ["testdata/test_pvmfw_devices_with_rng.dts"],
diff --git a/pvmfw/src/device_assignment.rs b/pvmfw/src/device_assignment.rs
index edfe000..c3ccf96 100644
--- a/pvmfw/src/device_assignment.rs
+++ b/pvmfw/src/device_assignment.rs
@@ -27,6 +27,7 @@
 use core::ffi::CStr;
 use core::iter::Iterator;
 use core::mem;
+use core::ops::Range;
 use hyp::DeviceAssigningHypervisor;
 use libfdt::{Fdt, FdtError, FdtNode, Phandle, Reg};
 use log::error;
@@ -419,6 +420,12 @@
     size: u64,
 }
 
+impl DeviceReg {
+    pub fn overlaps(&self, range: &Range<u64>) -> bool {
+        self.addr < range.end && range.start < self.addr.checked_add(self.size).unwrap()
+    }
+}
+
 impl TryFrom<Reg<u64>> for DeviceReg {
     type Error = DeviceAssignmentError;
 
@@ -530,13 +537,19 @@
     ) -> Result<()> {
         let mut virt_regs = device_reg.iter();
         let mut phys_regs = physical_device_reg.iter();
+        // TODO(b/308694211): Move this constant to vmbase::layout once vmbase is std-compatible.
+        const PVMFW_RANGE: Range<u64> = 0x7fc0_0000..0x8000_0000;
         // PV reg and physical reg should have 1:1 match in order.
         for (reg, phys_reg) in virt_regs.by_ref().zip(phys_regs.by_ref()) {
+            if reg.overlaps(&PVMFW_RANGE) {
+                return Err(DeviceAssignmentError::InvalidReg(reg.addr, reg.size));
+            }
+            // If this call returns successfully, hyp has mapped the MMIO region at `reg`.
             let addr = hypervisor.get_phys_mmio_token(reg.addr, reg.size).map_err(|e| {
                 error!("Hypervisor error while requesting MMIO token: {e}");
                 DeviceAssignmentError::InvalidReg(reg.addr, reg.size)
             })?;
-            // Only check address because hypervisor guaranatees size match when success.
+            // Only check address because hypervisor guarantees size match when success.
             if phys_reg.addr != addr {
                 error!("Assigned device {reg:x?} has unexpected physical address");
                 return Err(DeviceAssignmentError::InvalidPhysReg(addr, reg.size));
@@ -857,6 +870,7 @@
     const FDT_WITHOUT_IOMMUS_FILE_PATH: &str = "test_pvmfw_devices_without_iommus.dtb";
     const FDT_WITHOUT_DEVICE_FILE_PATH: &str = "test_pvmfw_devices_without_device.dtb";
     const FDT_FILE_PATH: &str = "test_pvmfw_devices_with_rng.dtb";
+    const FDT_WITH_DEVICE_OVERLAPPING_PVMFW: &str = "test_pvmfw_devices_overlapping_pvmfw.dtb";
     const FDT_WITH_MULTIPLE_DEVICES_IOMMUS_FILE_PATH: &str =
         "test_pvmfw_devices_with_multiple_devices_iommus.dtb";
     const FDT_WITH_IOMMU_SHARING: &str = "test_pvmfw_devices_with_iommu_sharing.dtb";
@@ -1407,6 +1421,22 @@
     }
 
     #[test]
+    fn device_info_overlaps_pvmfw() {
+        let mut fdt_data = fs::read(FDT_WITH_DEVICE_OVERLAPPING_PVMFW).unwrap();
+        let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
+        let fdt = Fdt::from_mut_slice(&mut fdt_data).unwrap();
+        let vm_dtbo = VmDtbo::from_mut_slice(&mut vm_dtbo_data).unwrap();
+
+        let hypervisor = MockHypervisor {
+            mmio_tokens: [((0x7fee0000, 0x1000), 0xF00000)].into(),
+            iommu_tokens: [((0xFF, 0xF), (0x40000, 0x4))].into(),
+        };
+        let device_info = DeviceAssignmentInfo::parse(fdt, vm_dtbo, &hypervisor);
+
+        assert_eq!(device_info, Err(DeviceAssignmentError::InvalidReg(0x7fee0000, 0x1000)));
+    }
+
+    #[test]
     fn device_assignment_clean() {
         let mut platform_dt_data = pvmfw_fdt_template::RAW.to_vec();
         let platform_dt = Fdt::from_mut_slice(&mut platform_dt_data).unwrap();
diff --git a/pvmfw/testdata/test_pvmfw_devices_overlapping_pvmfw.dts b/pvmfw/testdata/test_pvmfw_devices_overlapping_pvmfw.dts
new file mode 100644
index 0000000..2743dd8
--- /dev/null
+++ b/pvmfw/testdata/test_pvmfw_devices_overlapping_pvmfw.dts
@@ -0,0 +1,16 @@
+/dts-v1/;
+
+/include/ "test_crosvm_dt_base.dtsi"
+
+/ {
+    light {
+        reg = <0x0 0x7fee0000 0x0 0x1000>;
+        iommus = <&pviommu_0 0xF>;
+    };
+
+    pviommu_0: pviommu0 {
+        compatible = "pkvm,pviommu";
+        id = <0xFF>;
+        #iommu-cells = <1>;
+    };
+};