mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-08 19:33:07 +00:00
aarch64: Expose MTE to guests
A proposed set of kernel patches makes it possible to map anonymous MAP_SHARED mappings into the IPA space of a virtual machine with MTE enabled. With these patches we can use most features of crosvm with the exception of pmem which relies on being able to make file mappings in the IPA space. Therefore, we make MTE an opt-in feature via the --mte command line argument and forbid specifying --mte together with --pmem-device or --rw-pmem-device. Bug: b:234779841 Change-Id: I70bf2d0a8c1aff7c5956d6009ca5169a623bc6b2 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3892141 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Auto-Submit: Peter Collingbourne <pcc@chromium.org> Commit-Queue: Peter Collingbourne <pcc@chromium.org>
This commit is contained in:
parent
7150e63ee3
commit
96b95accf3
11 changed files with 51 additions and 3 deletions
|
@ -20,6 +20,7 @@ use libc::ENOTSUP;
|
|||
use libc::ENXIO;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
use super::Config;
|
||||
use super::Kvm;
|
||||
use super::KvmCap;
|
||||
use super::KvmVcpu;
|
||||
|
@ -76,6 +77,16 @@ impl Kvm {
|
|||
}
|
||||
|
||||
impl KvmVm {
|
||||
/// Does platform specific initialization for the KvmVm.
|
||||
pub fn init_arch(&self, cfg: &Config) -> Result<()> {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
if cfg.mte {
|
||||
// Safe because it does not take pointer arguments.
|
||||
unsafe { self.enable_raw_capability(KvmCap::ArmMte, 0, &[0, 0, 0, 0])? }
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Checks if a particular `VmCap` is available, or returns None if arch-independent
|
||||
/// Vm.check_capability() should handle the check.
|
||||
pub fn check_capability_arch(&self, _c: VmCap) -> Option<bool> {
|
||||
|
|
|
@ -238,13 +238,15 @@ impl KvmVm {
|
|||
}
|
||||
})?;
|
||||
|
||||
Ok(KvmVm {
|
||||
let vm = KvmVm {
|
||||
kvm: kvm.try_clone()?,
|
||||
vm: vm_descriptor,
|
||||
guest_mem,
|
||||
mem_regions: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
mem_slot_gaps: Arc::new(Mutex::new(BinaryHeap::new())),
|
||||
})
|
||||
};
|
||||
vm.init_arch(&cfg)?;
|
||||
Ok(vm)
|
||||
}
|
||||
|
||||
fn create_vcpu(&self, id: usize) -> Result<KvmVcpu> {
|
||||
|
|
|
@ -23,6 +23,7 @@ use libc::E2BIG;
|
|||
use libc::ENXIO;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
use super::Config;
|
||||
use super::Kvm;
|
||||
use super::KvmVcpu;
|
||||
use super::KvmVm;
|
||||
|
@ -158,6 +159,11 @@ impl HypervisorX86_64 for Kvm {
|
|||
}
|
||||
|
||||
impl KvmVm {
|
||||
/// Does platform specific initialization for the KvmVm.
|
||||
pub fn init_arch(&self, _cfg: &Config) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Checks if a particular `VmCap` is available, or returns None if arch-independent
|
||||
/// Vm.check_capability() should handle the check.
|
||||
pub fn check_capability_arch(&self, c: VmCap) -> Option<bool> {
|
||||
|
|
|
@ -561,12 +561,17 @@ pub enum ProtectionType {
|
|||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Config {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
/// enable the Memory Tagging Extension in the guest
|
||||
pub mte: bool,
|
||||
pub protection_type: ProtectionType,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Config {
|
||||
Config {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mte: false,
|
||||
protection_type: ProtectionType::Unprotected,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,4 +122,5 @@ pub enum Cap {
|
|||
ArmPmuV3 = KVM_CAP_ARM_PMU_V3,
|
||||
IoapicNumPins = KVM_CAP_IOAPIC_NUM_PINS,
|
||||
ArmProtectedVm = KVM_CAP_ARM_PROTECTED_VM,
|
||||
ArmMte = KVM_CAP_ARM_MTE,
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
|||
|
||||
source tools/impl/bindgen-common.sh
|
||||
|
||||
KVM_EXTRAS="// Added by kvm_sys/bindgen.sh
|
||||
KVM_EXTRAS="// TODO(pcc): Remove this when Chrome OS updates its kernel.
|
||||
pub const KVM_CAP_ARM_MTE: u32 = 205;
|
||||
// Added by kvm_sys/bindgen.sh
|
||||
pub const KVM_SYSTEM_EVENT_S2IDLE: u32 = 4;
|
||||
pub const KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2: u64 = 0x1;
|
||||
// TODO(tjeznach): Remove this when reporting KVM_IOAPIC_NUM_PINS is no longer required.
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#![allow(non_snake_case)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// TODO(pcc): Remove this when Chrome OS updates its kernel.
|
||||
pub const KVM_CAP_ARM_MTE: u32 = 205;
|
||||
// Added by kvm_sys/bindgen.sh
|
||||
pub const KVM_SYSTEM_EVENT_S2IDLE: u32 = 4;
|
||||
pub const KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2: u64 = 0x1;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#![allow(non_snake_case)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// TODO(pcc): Remove this when Chrome OS updates its kernel.
|
||||
pub const KVM_CAP_ARM_MTE: u32 = 205;
|
||||
// Added by kvm_sys/bindgen.sh
|
||||
pub const KVM_SYSTEM_EVENT_S2IDLE: u32 = 4;
|
||||
pub const KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2: u64 = 0x1;
|
||||
|
|
|
@ -753,6 +753,10 @@ pub struct RunCommand {
|
|||
)]
|
||||
/// MMIO address ranges
|
||||
pub mmio_address_ranges: Option<Vec<AddressRange>>,
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[argh(switch)]
|
||||
/// enable the Memory Tagging Extension in the guest
|
||||
pub mte: bool,
|
||||
#[cfg(unix)]
|
||||
#[argh(option, arg_name = "N")]
|
||||
/// virtio net virtual queue pairs. (default: 1)
|
||||
|
@ -1351,6 +1355,13 @@ impl TryFrom<RunCommand> for super::config::Config {
|
|||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
if cmd.mte && !(cmd.pmem_devices.is_empty() && cmd.rw_pmem_devices.is_empty()) {
|
||||
return Err(
|
||||
"--mte cannot be specified together with --pmem-device or --rw-pmem-device"
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
cfg.mte = cmd.mte;
|
||||
cfg.swiotlb = cmd.swiotlb;
|
||||
}
|
||||
|
||||
|
|
|
@ -1235,6 +1235,8 @@ pub struct Config {
|
|||
pub memory: Option<u64>,
|
||||
pub memory_file: Option<PathBuf>,
|
||||
pub mmio_address_ranges: Vec<AddressRange>,
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub mte: bool,
|
||||
#[cfg(windows)]
|
||||
pub net_vhost_user_tube: Option<Tube>,
|
||||
pub net_vq_pairs: Option<u16>,
|
||||
|
@ -1440,6 +1442,8 @@ impl Default for Config {
|
|||
memory: None,
|
||||
memory_file: None,
|
||||
mmio_address_ranges: Vec::new(),
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mte: false,
|
||||
#[cfg(windows)]
|
||||
net_vhost_user_tube: None,
|
||||
net_vq_pairs: None,
|
||||
|
|
|
@ -1150,6 +1150,8 @@ fn setup_vm_components(cfg: &Config) -> Result<VmComponents> {
|
|||
no_smt: cfg.no_smt,
|
||||
hugepages: cfg.hugepages,
|
||||
hv_cfg: hypervisor::Config {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mte: cfg.mte,
|
||||
protection_type: cfg.protection_type,
|
||||
},
|
||||
vm_image,
|
||||
|
|
Loading…
Reference in a new issue