cmdline: Add --protected-vm-with-firmware

Add a mode where the VM is placed in protected mode but the protected
firmware has been provided to crosvm and preloaded at its usual address,
instead of being loaded by the hypervisor at VM boot time. This is
useful for automated testing of firmware builds and development.

BUG=b:243646855
TEST=build

Change-Id: I849f3c6f0de55607893862d1d7739f6e1b410990
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3944853
Commit-Queue: Pierre-Clément Tosi <ptosi@google.com>
Reviewed-by: Keiichi Watanabe <keiichiw@chromium.org>
Reviewed-by: Andrew Walbran <qwandor@google.com>
Reviewed-by: Jiyong Park <jiyong@google.com>
This commit is contained in:
Pierre-Clément Tosi 2022-08-24 23:35:00 +01:00 committed by crosvm LUCI
parent b779c5cdef
commit ee4c635de2
2 changed files with 23 additions and 2 deletions

View file

@ -550,6 +550,9 @@ pub enum ProtectionType {
/// The VM should be run in protected mode, so the host cannot access its memory directly. It
/// should be booted via the protected VM firmware, so that it can access its secrets.
Protected,
/// The VM should be run in protected mode, so the host cannot access its memory directly. It
/// should be booted via a custom VM firmware, useful for debugging and testing.
ProtectedWithCustomFirmware,
/// The VM should be run in protected mode, but booted directly without pVM firmware. The host
/// will still be unable to access the VM memory, but it won't be given any secrets.
ProtectedWithoutFirmware,
@ -562,12 +565,18 @@ pub enum ProtectionType {
impl ProtectionType {
/// Returns whether the hypervisor will prevent us from accessing the VM's memory.
pub fn isolates_memory(&self) -> bool {
matches!(self, Self::Protected | Self::ProtectedWithoutFirmware)
matches!(
self,
Self::Protected | Self::ProtectedWithCustomFirmware | Self::ProtectedWithoutFirmware
)
}
/// Returns whether the VMM needs to load the pVM firmware.
pub fn loads_firmware(&self) -> bool {
matches!(self, Self::UnprotectedWithFirmware)
matches!(
self,
Self::UnprotectedWithFirmware | Self::ProtectedWithCustomFirmware
)
}
/// Returns whether the VM runs a pVM firmware.

View file

@ -947,6 +947,9 @@ pub struct RunCommand {
#[argh(switch)]
/// prevent host access to guest memory
pub protected_vm: bool,
#[argh(option, long = "protected-vm-with-firmware", arg_name = "PATH")]
/// (EXPERIMENTAL/FOR DEBUGGING) Use custom VM firmware to run in protected mode
pub protected_vm_with_firmware: Option<PathBuf>,
#[argh(switch)]
/// (EXPERIMENTAL) prevent host access to guest memory, but don't use protected VM firmware
protected_vm_without_firmware: bool,
@ -1782,6 +1785,7 @@ impl TryFrom<RunCommand> for super::config::Config {
let protection_flags = [
cmd.protected_vm,
cmd.protected_vm_with_firmware.is_some(),
cmd.protected_vm_without_firmware,
cmd.unprotected_vm_with_firmware.is_some(),
];
@ -1794,6 +1798,14 @@ impl TryFrom<RunCommand> for super::config::Config {
ProtectionType::Protected
} else if cmd.protected_vm_without_firmware {
ProtectionType::ProtectedWithoutFirmware
} else if let Some(p) = cmd.protected_vm_with_firmware {
if !p.exists() || !p.is_file() {
return Err(
"protected-vm-with-firmware path should be an existing file".to_string()
);
}
cfg.pvm_fw = Some(p);
ProtectionType::ProtectedWithCustomFirmware
} else if let Some(p) = cmd.unprotected_vm_with_firmware {
if !p.exists() || !p.is_file() {
return Err(