mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 10:10:41 +00:00
aarch64: fdt: Fix format of properties containing multiple values
When a FDT's property contains multiple values, the property must be a byte array which uses the null character ('\0') as the delimiter, but we didn't so. This CL fixes the format so the guest kernel can parse PSCI versions properly. BUG=b:174224484 TEST=arc.Reboot.vm on kukui-arc-r Change-Id: I61a983251cdbe8c021f5999cbf5efd026bbc0c27 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2567837 Tested-by: Keiichi Watanabe <keiichiw@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Marc Zyngier <mzyngier@google.com> Reviewed-by: Lepton Wu <lepton@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
This commit is contained in:
parent
80f76b9558
commit
22f808ff13
2 changed files with 30 additions and 14 deletions
|
@ -8,7 +8,8 @@ use std::io::Read;
|
|||
|
||||
use arch::fdt::{
|
||||
begin_node, end_node, finish_fdt, generate_prop32, generate_prop64, property, property_cstring,
|
||||
property_null, property_string, property_u32, property_u64, start_fdt, Error, Result,
|
||||
property_null, property_string, property_string_list, property_u32, property_u64, start_fdt,
|
||||
Error, Result,
|
||||
};
|
||||
use arch::SERIAL_ADDR;
|
||||
use devices::{PciAddress, PciInterruptPin};
|
||||
|
@ -184,17 +185,14 @@ fn create_serial_nodes(fdt: &mut Vec<u8>) -> Result<()> {
|
|||
}
|
||||
|
||||
fn create_psci_node(fdt: &mut Vec<u8>, version: &PsciVersion) -> Result<()> {
|
||||
let compatible = if version.major == 1 {
|
||||
let mut compatible = vec![format!("arm,psci-{}.{}", version.major, version.minor)];
|
||||
if version.major == 1 {
|
||||
// Put `psci-0.2` as well because PSCI 1.0 is compatible with PSCI 0.2.
|
||||
format!(
|
||||
"\"arm,psci-{}.{}\", \"arm,psci-0.2\"",
|
||||
version.major, version.minor
|
||||
)
|
||||
} else {
|
||||
format!("arm,psci-{}.{}", version.major, version.minor)
|
||||
compatible.push(format!("arm,psci-0.2"))
|
||||
};
|
||||
|
||||
begin_node(fdt, "psci")?;
|
||||
property_string(fdt, "compatible", &compatible)?;
|
||||
property_string_list(fdt, "compatible", compatible)?;
|
||||
// Only support aarch64 guest
|
||||
property_string(fdt, "method", "hvc")?;
|
||||
end_node(fdt)?;
|
||||
|
|
|
@ -156,17 +156,16 @@ pub fn property_null(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn property_cstring(fdt: &mut Vec<u8>, name: &str, cstr_value: &CStr) -> Result<()> {
|
||||
let value_bytes = cstr_value.to_bytes_with_nul();
|
||||
pub fn property_bytes(fdt: &mut Vec<u8>, name: &str, bytes: &[u8]) -> Result<()> {
|
||||
let cstr_name = CString::new(name).unwrap();
|
||||
|
||||
// Safe because we allocated fdt, converted name and value to CStrings
|
||||
// Safe because we allocated fdt, converted name to CStrings
|
||||
let fdt_ret = unsafe {
|
||||
fdt_property(
|
||||
fdt.as_mut_ptr() as *mut c_void,
|
||||
cstr_name.as_ptr(),
|
||||
value_bytes.as_ptr() as *mut c_void,
|
||||
value_bytes.len() as i32,
|
||||
bytes.as_ptr() as *mut c_void,
|
||||
bytes.len() as i32,
|
||||
)
|
||||
};
|
||||
if fdt_ret != 0 {
|
||||
|
@ -175,11 +174,30 @@ pub fn property_cstring(fdt: &mut Vec<u8>, name: &str, cstr_value: &CStr) -> Res
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn property_cstring(fdt: &mut Vec<u8>, name: &str, cstr_value: &CStr) -> Result<()> {
|
||||
let value_bytes = cstr_value.to_bytes_with_nul();
|
||||
property_bytes(fdt, name, value_bytes)
|
||||
}
|
||||
|
||||
pub fn property_string(fdt: &mut Vec<u8>, name: &str, value: &str) -> Result<()> {
|
||||
let cstr_value = CString::new(value).unwrap();
|
||||
property_cstring(fdt, name, &cstr_value)
|
||||
}
|
||||
|
||||
pub fn property_string_list(fdt: &mut Vec<u8>, name: &str, values: Vec<String>) -> Result<()> {
|
||||
let bytes = values
|
||||
.into_iter()
|
||||
.map(|s| {
|
||||
let mut bytes = s.into_bytes();
|
||||
// Each value must be null-terminated.
|
||||
bytes.push(0);
|
||||
bytes
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<u8>>();
|
||||
property_bytes(fdt, name, &bytes)
|
||||
}
|
||||
|
||||
pub fn start_fdt(fdt: &mut Vec<u8>, fdt_max_size: usize) -> Result<()> {
|
||||
// Safe since we allocated this array with fdt_max_size
|
||||
let mut fdt_ret = unsafe { fdt_create(fdt.as_mut_ptr() as *mut c_void, fdt_max_size as c_int) };
|
||||
|
|
Loading…
Reference in a new issue