Merge "Configure serial console input device" into main
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
index 66d0f4b..4d3bf2d 100644
--- a/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -90,6 +90,7 @@
private static final String KEY_PROTECTED_VM = "protectedVm";
private static final String KEY_MEMORY_BYTES = "memoryBytes";
private static final String KEY_CPU_TOPOLOGY = "cpuTopology";
+ private static final String KEY_CONSOLE_INPUT_DEVICE = "consoleInputDevice";
private static final String KEY_ENCRYPTED_STORAGE_BYTES = "encryptedStorageBytes";
private static final String KEY_VM_OUTPUT_CAPTURED = "vmOutputCaptured";
private static final String KEY_VM_CONSOLE_INPUT_SUPPORTED = "vmConsoleInputSupported";
@@ -173,6 +174,9 @@
/** CPU topology configuration of the VM. */
@CpuTopology private final int mCpuTopology;
+ /** The serial device for VM console input. */
+ @Nullable private final String mConsoleInputDevice;
+
/**
* Path within the APK to the payload config file that defines software aspects of the VM.
*/
@@ -229,6 +233,7 @@
boolean protectedVm,
long memoryBytes,
@CpuTopology int cpuTopology,
+ @Nullable String consoleInputDevice,
long encryptedStorageBytes,
boolean vmOutputCaptured,
boolean vmConsoleInputSupported,
@@ -250,6 +255,7 @@
mProtectedVm = protectedVm;
mMemoryBytes = memoryBytes;
mCpuTopology = cpuTopology;
+ mConsoleInputDevice = consoleInputDevice;
mEncryptedStorageBytes = encryptedStorageBytes;
mVmOutputCaptured = vmOutputCaptured;
mVmConsoleInputSupported = vmConsoleInputSupported;
@@ -330,6 +336,10 @@
builder.setMemoryBytes(memoryBytes);
}
builder.setCpuTopology(b.getInt(KEY_CPU_TOPOLOGY));
+ String consoleInputDevice = b.getString(KEY_CONSOLE_INPUT_DEVICE);
+ if (consoleInputDevice != null) {
+ builder.setConsoleInputDevice(consoleInputDevice);
+ }
long encryptedStorageBytes = b.getLong(KEY_ENCRYPTED_STORAGE_BYTES);
if (encryptedStorageBytes != 0) {
builder.setEncryptedStorageBytes(encryptedStorageBytes);
@@ -382,6 +392,9 @@
b.putInt(KEY_DEBUGLEVEL, mDebugLevel);
b.putBoolean(KEY_PROTECTED_VM, mProtectedVm);
b.putInt(KEY_CPU_TOPOLOGY, mCpuTopology);
+ if (mConsoleInputDevice != null) {
+ b.putString(KEY_CONSOLE_INPUT_DEVICE, mConsoleInputDevice);
+ }
if (mMemoryBytes > 0) {
b.putLong(KEY_MEMORY_BYTES, mMemoryBytes);
}
@@ -595,6 +608,7 @@
&& this.mVmOutputCaptured == other.mVmOutputCaptured
&& this.mVmConsoleInputSupported == other.mVmConsoleInputSupported
&& this.mConnectVmConsole == other.mConnectVmConsole
+ && this.mConsoleInputDevice == other.mConsoleInputDevice
&& (this.mVendorDiskImage == null) == (other.mVendorDiskImage == null)
&& Objects.equals(this.mPayloadConfigPath, other.mPayloadConfigPath)
&& Objects.equals(this.mPayloadBinaryName, other.mPayloadBinaryName)
@@ -666,6 +680,7 @@
config.protectedVm = this.mProtectedVm;
config.memoryMib = bytesToMebiBytes(mMemoryBytes);
config.cpuTopology = (byte) this.mCpuTopology;
+ config.consoleInputDevice = mConsoleInputDevice;
config.devices = EMPTY_STRING_ARRAY;
config.platformVersion = "~1.0";
return config;
@@ -804,6 +819,7 @@
private boolean mProtectedVmSet;
private long mMemoryBytes;
@CpuTopology private int mCpuTopology = CPU_TOPOLOGY_ONE_CPU;
+ @Nullable private String mConsoleInputDevice;
private long mEncryptedStorageBytes;
private boolean mVmOutputCaptured = false;
private boolean mVmConsoleInputSupported = false;
@@ -897,6 +913,7 @@
mProtectedVm,
mMemoryBytes,
mCpuTopology,
+ mConsoleInputDevice,
mEncryptedStorageBytes,
mVmOutputCaptured,
mVmConsoleInputSupported,
@@ -1080,6 +1097,17 @@
}
/**
+ * Sets the serial device for VM console input.
+ *
+ * @see android.system.virtualizationservice.ConsoleInputDevice
+ * @hide
+ */
+ public Builder setConsoleInputDevice(@Nullable String consoleInputDevice) {
+ mConsoleInputDevice = consoleInputDevice;
+ return this;
+ }
+
+ /**
* Sets the size (in bytes) of encrypted storage available to the VM. If not set, no
* encrypted storage is provided.
*
diff --git a/libs/vmconfig/src/lib.rs b/libs/vmconfig/src/lib.rs
index 7c917b0..1413b51 100644
--- a/libs/vmconfig/src/lib.rs
+++ b/libs/vmconfig/src/lib.rs
@@ -65,6 +65,8 @@
/// SysFS paths of devices assigned to the VM.
#[serde(default)]
pub devices: Vec<PathBuf>,
+ /// The serial device for VM console input.
+ pub console_input_device: Option<String>,
}
impl VmConfig {
@@ -124,6 +126,7 @@
x.to_str().map(String::from).ok_or(anyhow!("Failed to convert {x:?} to String"))
})
.collect::<Result<_>>()?,
+ consoleInputDevice: self.console_input_device.clone(),
..Default::default()
})
}
diff --git a/microdroid/microdroid.json b/microdroid/microdroid.json
index 00cedc8..e60c4ca 100644
--- a/microdroid/microdroid.json
+++ b/microdroid/microdroid.json
@@ -16,5 +16,6 @@
}
],
"memory_mib": 256,
+ "console_input_device": "hvc0",
"platform_version": "~1.0"
}
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index dd17b46..2df4fd7 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -657,6 +657,7 @@
hugepages: config.hugePages,
tap,
virtio_snd_backend,
+ console_input_device: config.consoleInputDevice.clone(),
};
let instance = Arc::new(
VmInstance::new(
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index 371a908..6408b84 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -82,6 +82,12 @@
const SYSPROP_CUSTOM_PVMFW_PATH: &str = "hypervisor.pvmfw.path";
+/// Serial device for VM console input.
+/// Hypervisor (virtio-console)
+const CONSOLE_HVC0: &str = "hvc0";
+/// Serial (emulated uart)
+const CONSOLE_TTYS0: &str = "ttyS0";
+
lazy_static! {
/// If the VM doesn't move to the Started state within this amount time, a hang-up error is
/// triggered.
@@ -124,6 +130,7 @@
pub hugepages: bool,
pub tap: Option<File>,
pub virtio_snd_backend: Option<String>,
+ pub console_input_device: Option<String>,
}
#[derive(Debug)]
@@ -919,19 +926,29 @@
let log_arg = format_serial_out_arg(&mut preserved_fds, &config.log_fd);
let failure_serial_path = add_preserved_fd(&mut preserved_fds, &failure_pipe_write);
let ramdump_arg = format_serial_out_arg(&mut preserved_fds, &config.ramdump);
+ let console_input_device = config.console_input_device.as_deref().unwrap_or(CONSOLE_HVC0);
+ match console_input_device {
+ CONSOLE_HVC0 | CONSOLE_TTYS0 => {}
+ _ => bail!("Unsupported serial device {console_input_device}"),
+ };
// Warning: Adding more serial devices requires you to shift the PCI device ID of the boot
// disks in bootconfig.x86_64. This is because x86 crosvm puts serial devices and the block
// devices in the same PCI bus and serial devices comes before the block devices. Arm crosvm
// doesn't have the issue.
// /dev/ttyS0
- command.arg(format!("--serial={},hardware=serial,num=1", &console_out_arg));
+ command.arg(format!(
+ "--serial={}{},hardware=serial,num=1",
+ &console_out_arg,
+ if console_input_device == CONSOLE_TTYS0 { &console_in_arg } else { "" }
+ ));
// /dev/ttyS1
command.arg(format!("--serial=type=file,path={},hardware=serial,num=2", &failure_serial_path));
// /dev/hvc0
command.arg(format!(
"--serial={}{},hardware=virtio-console,num=1",
- &console_out_arg, &console_in_arg
+ &console_out_arg,
+ if console_input_device == CONSOLE_HVC0 { &console_in_arg } else { "" }
));
// /dev/hvc1
command.arg(format!("--serial={},hardware=virtio-console,num=2", &ramdump_arg));
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
index a5a849a..c927c9b 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
@@ -88,4 +88,7 @@
/** Whether the VM should have network feature. */
boolean networkSupported;
+
+ /** The serial device for VM console input. */
+ @nullable @utf8InCpp String consoleInputDevice;
}
diff --git a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
index 4d79235..5355313 100644
--- a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
+++ b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
@@ -47,13 +47,12 @@
import android.view.WindowManager;
import android.view.WindowMetrics;
+import libcore.io.IoBridge;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-import libcore.io.IoBridge;
-
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
@@ -123,6 +122,9 @@
}
}
}
+ if (json.has("console_input_device")) {
+ configBuilder.setConsoleInputDevice(json.getString("console_input_device"));
+ }
configBuilder.setMemoryBytes(8L * 1024 * 1024 * 1024 /* 8 GB */);
WindowMetrics windowMetrics = getWindowManager().getCurrentWindowMetrics();