pvmfw: Use new VM DTBO format
Bug: 277993056
Test: atest libpvmfw.device_assignment.test, launch protected VM
Change-Id: Iac3f799f793dab50eacbeac0c0b9339692f149e5
diff --git a/pvmfw/src/device_assignment.rs b/pvmfw/src/device_assignment.rs
index 19ace5f..8d4d840 100644
--- a/pvmfw/src/device_assignment.rs
+++ b/pvmfw/src/device_assignment.rs
@@ -183,6 +183,15 @@
}
}
+fn is_overlayable_node(dtbo_path: &CStr) -> bool {
+ dtbo_path
+ .to_bytes()
+ .split(|char| *char == b'/')
+ .filter(|&component| !component.is_empty())
+ .nth(1)
+ .map_or(false, |name| name == b"__overlay__")
+}
+
impl AsRef<Fdt> for VmDtbo {
fn as_ref(&self) -> &Fdt {
&self.0
@@ -417,6 +426,9 @@
let symbol_prop_value = symbol_prop.value()?;
let dtbo_node_path = CStr::from_bytes_with_nul(symbol_prop_value)
.or(Err(DeviceAssignmentError::InvalidSymbols))?;
+ if !is_overlayable_node(dtbo_node_path) {
+ continue;
+ }
let assigned_device =
AssignedDeviceInfo::parse(fdt, vm_dtbo, dtbo_node_path, &pviommus, hypervisor)?;
if let Some(assigned_device) = assigned_device {
@@ -428,7 +440,15 @@
if assigned_devices.is_empty() {
return Ok(None);
}
+
+ // Clean up any nodes that wouldn't be overlaid but may contain reference to filtered nodes.
+ // Otherwise, `fdt_apply_overlay()` would fail because of missing phandle reference.
filtered_dtbo_paths.push(CString::new("/__symbols__").unwrap());
+ // TODO(b/277993056): Also filter other unused nodes/props in __local_fixups__
+ filtered_dtbo_paths.push(CString::new("/__local_fixups__/host").unwrap());
+
+ // Note: Any node without __overlay__ will be ignored by fdt_apply_overlay,
+ // so doesn't need to be filtered.
Ok(Some(Self { pviommus: unique_pviommus, assigned_devices, filtered_dtbo_paths }))
}
@@ -449,22 +469,6 @@
node.nop()?;
}
- // Filters pvmfw-specific properties in assigned device node.
- const FILTERED_VM_DTBO_PROP: [&CStr; 3] = [
- cstr!("android,pvmfw,phy-reg"),
- cstr!("android,pvmfw,phy-iommu"),
- cstr!("android,pvmfw,phy-sid"),
- ];
- for assigned_device in &self.assigned_devices {
- let mut node = vm_dtbo.node_mut(&assigned_device.dtbo_node_path).unwrap().unwrap();
- for prop in FILTERED_VM_DTBO_PROP {
- match node.nop_property(prop) {
- Err(FdtError::NotFound) => Ok(()), // allows not exists
- other => other,
- }?;
- }
- }
-
Ok(())
}
@@ -649,8 +653,8 @@
let device_info = DeviceAssignmentInfo::parse(fdt, vm_dtbo, &hypervisor).unwrap().unwrap();
let expected = [AssignedDeviceInfo {
- node_path: CString::new("/backlight").unwrap(),
- dtbo_node_path: cstr!("/fragment@backlight/__overlay__/backlight").into(),
+ node_path: CString::new("/bus0/backlight").unwrap(),
+ dtbo_node_path: cstr!("/fragment@backlight/__overlay__/bus0/backlight").into(),
reg: vec![[0x9, 0xFF].into()],
interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
iommus: vec![],
@@ -721,7 +725,8 @@
let led = vm_dtbo.node(cstr!("/fragment@led/__overlay__/led")).unwrap();
assert_eq!(led, None);
- let backlight = vm_dtbo.node(cstr!("/fragment@backlight/__overlay__/backlight")).unwrap();
+ let backlight =
+ vm_dtbo.node(cstr!("/fragment@backlight/__overlay__/bus0/backlight")).unwrap();
assert_eq!(backlight, None);
let symbols_node = vm_dtbo.symbols().unwrap();
@@ -750,6 +755,10 @@
}
device_info.patch(platform_dt).unwrap();
+ let rng_node = platform_dt.node(cstr!("/bus0/backlight")).unwrap().unwrap();
+ let phandle = rng_node.getprop_u32(cstr!("phandle")).unwrap();
+ assert_ne!(None, phandle);
+
// Note: Intentionally not using AssignedDeviceNode for matching all props.
type FdtResult<T> = libfdt::Result<T>;
let expected: Vec<(FdtResult<&CStr>, FdtResult<Vec<u8>>)> = vec![
@@ -757,10 +766,10 @@
(Ok(cstr!("compatible")), Ok(Vec::from(*b"android,backlight\0"))),
(Ok(cstr!("interrupts")), Ok(into_fdt_prop(vec![0x0, 0xF, 0x4]))),
(Ok(cstr!("iommus")), Ok(Vec::new())),
+ (Ok(cstr!("phandle")), Ok(into_fdt_prop(vec![phandle.unwrap()]))),
(Ok(cstr!("reg")), Ok(into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]))),
];
- let rng_node = platform_dt.node(cstr!("/backlight")).unwrap().unwrap();
let mut properties: Vec<_> = rng_node
.properties()
.unwrap()
diff --git a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts
index 691d15a..91693f7 100644
--- a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts
@@ -1,61 +1,118 @@
/dts-v1/;
-/plugin/;
/ {
- fragment@rng {
- target-path = "/";
- __overlay__ {
- rng {
- compatible = "android,rng";
- android,rng,ignore-gctrl-reset;
- android,pvmfw,phy-reg = <0x0 0x12F00000 0x1000>;
- android,pvmfw,phy-iommu = <0x0 0x12E40000>;
- android,pvmfw,phy-sid = <3>;
- };
- };
- };
-
- fragment@sensor {
- target-path = "/";
- __overlay__ {
- light {
- compatible = "android,light";
- version = <0x1 0x2>;
- android,pvmfw,phy-reg = <0x0 0xF00000 0x1000>, <0x0 0xF10000 0x1000>;
- android,pvmfw,phy-iommu = <0x0 0x40000>, <0x0 0x50000>;
- android,pvmfw,phy-sid = <4>, <5>;
- };
- };
- };
-
- fragment@led {
- target-path = "/";
- __overlay__ {
- led {
- compatible = "android,led";
- prop = <0x555>;
- android,pvmfw,phy-reg = <0x0 0x12000000 0x1000>;
- android,pvmfw,phy-iommu = <0x0 0x12E40000>;
- android,pvmfw,phy-sid = <3>;
- };
- };
- };
-
- fragment@backlight {
- target-path = "/";
- __overlay__ {
- backlight {
- compatible = "android,backlight";
- android,backlight,ignore-gctrl-reset;
- android,pvmfw,phy-reg = <0x0 0x300 0x100>;
- };
- };
- };
-
- __symbols__ {
- rng = "/fragment@rng/__overlay__/rng";
- sensor = "/fragment@sensor/__overlay__/light";
- led = "/fragment@led/__overlay__/led";
- backlight = "/fragment@backlight/__overlay__/backlight";
- };
+ host {
+ #address-cells = <0x2>;
+ #size-cells = <0x1>;
+ rng {
+ reg = <0x0 0x12f00000 0x1000>;
+ iommus = <0x1 0x3>;
+ android,pvmfw,target = <0x2>;
+ };
+ light {
+ reg = <0x0 0x00f00000 0x1000>, <0x0 0x00f10000 0x1000>;
+ iommus = <0x3 0x4>, <0x4 0x5>;
+ android,pvmfw,target = <0x5>;
+ };
+ led {
+ reg = <0x0 0x12000000 0x1000>;
+ iommus = <0x1 0x3>;
+ android,pvmfw,target = <0x6>;
+ };
+ bus0 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ backlight {
+ reg = <0x300 0x100>;
+ android,pvmfw,target = <0x7>;
+ };
+ };
+ iommu0 {
+ #iommu-cells = <0x1>;
+ android,pvmfw,token = <0x0 0x12e40000>;
+ phandle = <0x1>;
+ };
+ iommu1 {
+ #iommu-cells = <0x1>;
+ android,pvmfw,token = <0x0 0x40000>;
+ phandle = <0x3>;
+ };
+ iommu2 {
+ #iommu-cells = <0x1>;
+ android,pvmfw,token = <0x0 0x50000>;
+ phandle = <0x4>;
+ };
+ };
+ fragment@rng {
+ target-path = "/";
+ __overlay__ {
+ rng {
+ compatible = "android,rng";
+ android,rng,ignore-gctrl-reset;
+ phandle = <0x2>;
+ };
+ };
+ };
+ fragment@sensor {
+ target-path = "/";
+ __overlay__ {
+ light {
+ compatible = "android,light";
+ version = <0x1 0x2>;
+ phandle = <0x5>;
+ };
+ };
+ };
+ fragment@led {
+ target-path = "/";
+ __overlay__ {
+ led {
+ compatible = "android,led";
+ prop = <0x555>;
+ phandle = <0x6>;
+ };
+ };
+ };
+ fragment@backlight {
+ target-path = "/";
+ __overlay__ {
+ bus0 {
+ backlight {
+ compatible = "android,backlight";
+ android,backlight,ignore-gctrl-reset;
+ phandle = <0x7>;
+ };
+ };
+ };
+ };
+ __symbols__ {
+ iommu0 = "/host/iommu0";
+ iommu1 = "/host/iommu1";
+ iommu2 = "/host/iommu2";
+ rng = "/fragment@rng/__overlay__/rng";
+ light = "/fragment@sensor/__overlay__/light";
+ led = "/fragment@led/__overlay__/led";
+ backlight = "/fragment@backlight/__overlay__/bus0/backlight";
+ };
+ __local_fixups__ {
+ host {
+ rng {
+ iommus = <0x0>;
+ android,pvmfw,target = <0x0>;
+ };
+ light {
+ iommus = <0x0 0x8>;
+ android,pvmfw,target = <0x0>;
+ };
+ led {
+ iommus = <0x0>;
+ android,pvmfw,target = <0x0>;
+ };
+ bus0 {
+ backlight {
+ android,pvmfw,target = <0x0>;
+ };
+ };
+ };
+ };
};
diff --git a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts
index 18b9e79..2bc8081 100644
--- a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts
@@ -1,43 +1,114 @@
/dts-v1/;
-/plugin/;
/ {
- fragment@rng {
- target-path = "/";
- __overlay__ {
- rng {
- compatible = "android,rng";
- android,rng,ignore-gctrl-reset;
- android,pvmfw,phy-reg = <0x0 0x12F00000 0x1000>;
- android,pvmfw,phy-iommu = <0x0 0x12E40000>;
- android,pvmfw,phy-sid = <3>;
- };
- };
- };
-
- fragment@sensor {
- target-path = "/";
- __overlay__ {
- light {
- compatible = "android,light";
- version = <0x1 0x2>;
- android,pvmfw,phy-reg = <0x0 0xF00000 0x1000>;
- android,pvmfw,phy-iommu = <0x0 0x40000>, <0x0 0x50000>;
- android,pvmfw,phy-sid = <4>, <5>;
- };
- };
- };
-
- fragment@led {
- target-path = "/";
- __overlay__ {
- led {
- compatible = "android,led";
- prop;
- android,pvmfw,phy-reg = <0x0 0x12F00000 0x1000>;
- android,pvmfw,phy-iommu = <0x0 0x20000>, <0x0 0x30000>;
- android,pvmfw,phy-sid = <7>, <8>;
- };
- };
- };
+ host {
+ #address-cells = <0x2>;
+ #size-cells = <0x1>;
+ rng {
+ reg = <0x0 0x12f00000 0x1000>;
+ iommus = <0x1 0x3>;
+ android,pvmfw,target = <0x2>;
+ };
+ light {
+ reg = <0x0 0x00f00000 0x1000>, <0x0 0x00f10000 0x1000>;
+ iommus = <0x3 0x4>, <0x4 0x5>;
+ android,pvmfw,target = <0x5>;
+ };
+ led {
+ reg = <0x0 0x12000000 0x1000>;
+ iommus = <0x1 0x3>;
+ android,pvmfw,target = <0x6>;
+ };
+ bus0 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ backlight {
+ reg = <0x300 0x100>;
+ android,pvmfw,target = <0x7>;
+ };
+ };
+ iommu0 {
+ #iommu-cells = <0x1>;
+ android,pvmfw,token = <0x0 0x12e40000>;
+ phandle = <0x1>;
+ };
+ iommu1 {
+ #iommu-cells = <0x1>;
+ android,pvmfw,token = <0x0 0x40000>;
+ phandle = <0x3>;
+ };
+ iommu2 {
+ #iommu-cells = <0x1>;
+ android,pvmfw,token = <0x0 0x50000>;
+ phandle = <0x4>;
+ };
+ };
+ fragment@rng {
+ target-path = "/";
+ __overlay__ {
+ rng {
+ compatible = "android,rng";
+ android,rng,ignore-gctrl-reset;
+ phandle = <0x2>;
+ };
+ };
+ };
+ fragment@sensor {
+ target-path = "/";
+ __overlay__ {
+ light {
+ compatible = "android,light";
+ version = <0x1 0x2>;
+ phandle = <0x5>;
+ };
+ };
+ };
+ fragment@led {
+ target-path = "/";
+ __overlay__ {
+ led {
+ compatible = "android,led";
+ prop = <0x555>;
+ phandle = <0x6>;
+ };
+ };
+ };
+ fragment@backlight {
+ target-path = "/";
+ __overlay__ {
+ bus0 {
+ backlight {
+ compatible = "android,backlight";
+ android,backlight,ignore-gctrl-reset;
+ phandle = <0x7>;
+ };
+ };
+ };
+ };
+ __symbols__ {
+ iommu0 = "/host/iommu0";
+ iommu1 = "/host/iommu1";
+ iommu2 = "/host/iommu2";
+ };
+ __local_fixups__ {
+ host {
+ rng {
+ iommus = <0x0>;
+ android,pvmfw,target = <0x0>;
+ };
+ light {
+ iommus = <0x0 0x8>;
+ android,pvmfw,target = <0x0>;
+ };
+ led {
+ iommus = <0x0>;
+ android,pvmfw,target = <0x0>;
+ };
+ bus0 {
+ backlight {
+ android,pvmfw,target = <0x0>;
+ };
+ };
+ };
+ };
};
diff --git a/pvmfw/testdata/test_pvmfw_devices_without_iommus.dts b/pvmfw/testdata/test_pvmfw_devices_without_iommus.dts
index 2036c9c..1a12c87 100644
--- a/pvmfw/testdata/test_pvmfw_devices_without_iommus.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_without_iommus.dts
@@ -4,11 +4,16 @@
/include/ "test_crosvm_dt_base.dtsi"
/ {
- backlight@90000000 {
- compatible = "android,backlight";
- reg = <0x0 0x9 0x0 0xFF>;
- interrupts = <0x0 0xF 0x4>;
- google,eh,ignore-gctrl-reset;
- status = "okay";
+ bus0 {
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ backlight@90000000 {
+ compatible = "android,backlight";
+ reg = <0x0 0x9 0x0 0xFF>;
+ interrupts = <0x0 0xF 0x4>;
+ google,eh,ignore-gctrl-reset;
+ status = "okay";
+ };
};
};