Read assignable device list from vendor config xml
Bug: 297313212
Test: add /vendor/etc/avf/assignable_devices.xml and run vm info
Change-Id: I1e4a3991df930581a58da65830060c366fe58662
diff --git a/virtualizationservice/Android.bp b/virtualizationservice/Android.bp
index 67890e2..f96c76b 100644
--- a/virtualizationservice/Android.bp
+++ b/virtualizationservice/Android.bp
@@ -37,6 +37,15 @@
"libstatslog_virtualization_rust",
"libtombstoned_client_rust",
"libvsock",
+ "libserde",
+ "libserde_xml_rs",
],
apex_available: ["com.android.virt"],
}
+
+xsd_config {
+ name: "assignable_devices",
+ srcs: ["assignable_devices.xsd"],
+ api_dir: "schema",
+ package_name: "android.system.virtualizationservice",
+}
diff --git a/virtualizationservice/assignable_devices.xsd b/virtualizationservice/assignable_devices.xsd
new file mode 100644
index 0000000..842542e
--- /dev/null
+++ b/virtualizationservice/assignable_devices.xsd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- KEEP IN SYNC WITH aidl.rs -->
+<xs:schema version="2.0"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="devices">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="device" type="device" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="device">
+ <xs:attribute name="kind" type="xs:string"/>
+ <xs:attribute name="sysfs_path" type="xs:string"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/virtualizationservice/schema/current.txt b/virtualizationservice/schema/current.txt
new file mode 100644
index 0000000..ed0763a
--- /dev/null
+++ b/virtualizationservice/schema/current.txt
@@ -0,0 +1,25 @@
+// Signature format: 2.0
+package android.system.virtualizationservice {
+
+ public class Device {
+ ctor public Device();
+ method public String getKind();
+ method public String getSysfs_path();
+ method public void setKind(String);
+ method public void setSysfs_path(String);
+ }
+
+ public class Devices {
+ ctor public Devices();
+ method public java.util.List<android.system.virtualizationservice.Device> getDevice();
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static android.system.virtualizationservice.Devices read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/virtualizationservice/schema/last_current.txt b/virtualizationservice/schema/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/virtualizationservice/schema/last_current.txt
diff --git a/virtualizationservice/schema/last_removed.txt b/virtualizationservice/schema/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/virtualizationservice/schema/last_removed.txt
diff --git a/virtualizationservice/schema/removed.txt b/virtualizationservice/schema/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/virtualizationservice/schema/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index b2513d9..f94dd4e 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -38,8 +38,9 @@
use libc::VMADDR_CID_HOST;
use log::{error, info, warn};
use rustutils::system_properties;
-use std::collections::HashMap;
-use std::fs::{create_dir, remove_dir_all, set_permissions, Permissions};
+use serde::Deserialize;
+use std::collections::{HashMap, HashSet};
+use std::fs::{self, create_dir, remove_dir_all, set_permissions, Permissions};
use std::io::{Read, Write};
use std::os::unix::fs::PermissionsExt;
use std::os::unix::raw::{pid_t, uid_t};
@@ -172,13 +173,41 @@
fn getAssignableDevices(&self) -> binder::Result<Vec<AssignableDevice>> {
check_use_custom_virtual_machine()?;
- // TODO(b/291191362): read VM DTBO to find assignable devices.
- let mut devices = Vec::new();
- let eh_path = "/sys/bus/platform/devices/16d00000.eh";
- if Path::new(eh_path).exists() {
- devices.push(AssignableDevice { kind: "eh".to_owned(), node: eh_path.to_owned() });
+ let mut ret = Vec::new();
+ let xml_path = Path::new("/vendor/etc/avf/assignable_devices.xml");
+ if !xml_path.exists() {
+ return Ok(ret);
}
- Ok(devices)
+
+ let xml = fs::read(xml_path)
+ .context("Failed to read assignable_devices.xml")
+ .with_log()
+ .or_service_specific_exception(-1)?;
+
+ let xml = String::from_utf8(xml)
+ .context("assignable_devices.xml is not a valid UTF-8 file")
+ .with_log()
+ .or_service_specific_exception(-1)?;
+
+ let devices: Devices = serde_xml_rs::from_str(&xml)
+ .context("can't parse assignable_devices.xml")
+ .with_log()
+ .or_service_specific_exception(-1)?;
+
+ let mut device_set = HashSet::new();
+
+ for device in devices.device.into_iter() {
+ if device_set.contains(&device.sysfs_path) {
+ warn!("duplicated assignable device {device:?}; ignoring...")
+ } else if Path::new(&device.sysfs_path).exists() {
+ device_set.insert(device.sysfs_path.clone());
+ ret.push(AssignableDevice { kind: device.kind, node: device.sysfs_path });
+ } else {
+ warn!("assignable device {device:?} doesn't exist; ignoring...");
+ }
+ }
+
+ Ok(ret)
}
fn bindDevicesToVfioDriver(
@@ -196,6 +225,18 @@
}
}
+// KEEP IN SYNC WITH assignable_devices.xsd
+#[derive(Debug, Deserialize)]
+struct Device {
+ kind: String,
+ sysfs_path: String,
+}
+
+#[derive(Debug, Deserialize)]
+struct Devices {
+ device: Vec<Device>,
+}
+
#[derive(Debug, Default)]
struct GlobalVmInstance {
/// The unique CID assigned to the VM for vsock communication.