pvmfw: Accept either swiotlb DT reg or size/align
In accordance with the Linux documentation for "restricted-dma-pool",
either expect a static region through the <reg> property OR a dynamic
one with the <size> property, not both. When <reg> is used, assume that
<alignment> isn't needed either as no allocation is required (docs are
currently unclear on this).
Remove properties that aren't deemed necessary from the template DT,
when modifying it to generate the guest DT. To do so, NOP the properties
instead of deleting them, this has the same effect of removing them from
the DT but is O(1) instead of O(n) in the length of the DT; as we
fdt.pack() it once done, the final result remains as compact as possible
anyway.
Bug: 244630071
Test: m pvmfw_img
Change-Id: I22ae4bbb7fdc5030de4fd6db95a4103e3459c401
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index 5ecb038..97db601 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -440,7 +440,7 @@
pub struct SwiotlbInfo {
addr: Option<usize>,
size: usize,
- align: usize,
+ align: Option<usize>,
}
impl SwiotlbInfo {
@@ -452,17 +452,16 @@
fn read_swiotlb_info_from(fdt: &Fdt) -> libfdt::Result<SwiotlbInfo> {
let node =
fdt.compatible_nodes(cstr!("restricted-dma-pool"))?.next().ok_or(FdtError::NotFound)?;
- let align =
- node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
- let (addr, size) = if let Some(mut reg) = node.reg()? {
+ let (addr, size, align) = if let Some(mut reg) = node.reg()? {
let reg = reg.next().ok_or(FdtError::NotFound)?;
let size = reg.size.ok_or(FdtError::NotFound)?;
reg.addr.checked_add(size).ok_or(FdtError::BadValue)?;
- (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap())
+ (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap(), None)
} else {
- let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
- (None, size)
+ let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?;
+ let align = node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?;
+ (None, size.try_into().unwrap(), Some(align.try_into().unwrap()))
};
Ok(SwiotlbInfo { addr, size, align })
@@ -480,7 +479,7 @@
return Err(RebootReason::InvalidFdt);
}
- if (align % GUEST_PAGE_SIZE) != 0 {
+ if let Some(align) = align.filter(|&a| a % GUEST_PAGE_SIZE != 0) {
error!("Invalid swiotlb alignment {:#x}", align);
return Err(RebootReason::InvalidFdt);
}
@@ -498,7 +497,6 @@
fn patch_swiotlb_info(fdt: &mut Fdt, swiotlb_info: &SwiotlbInfo) -> libfdt::Result<()> {
let mut node =
fdt.root_mut()?.next_compatible(cstr!("restricted-dma-pool"))?.ok_or(FdtError::NotFound)?;
- node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.to_be_bytes())?;
if let Some(range) = swiotlb_info.fixed_range() {
node.appendprop_addrrange(
@@ -506,8 +504,11 @@
range.start.try_into().unwrap(),
range.len().try_into().unwrap(),
)?;
+ node.nop_property(cstr!("size"))?;
+ node.nop_property(cstr!("alignment"))?;
} else {
node.setprop_inplace(cstr!("size"), &swiotlb_info.size.to_be_bytes())?;
+ node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.unwrap().to_be_bytes())?;
}
Ok(())