diff options
author | Suleiman Souhlal <suleiman@google.com> | 2020-04-21 14:11:47 +0900 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-08 03:25:38 +0000 |
commit | 7dc915dd2af19ed4dbafb6b1b6e86733af5a922d (patch) | |
tree | d1820536e6f433eaf155b259c9d831b9360df807 /kvm | |
parent | a1c0e3c680c44ae4a949744b27f3cf0f7ea77939 (diff) | |
download | crosvm-7dc915dd2af19ed4dbafb6b1b6e86733af5a922d.tar crosvm-7dc915dd2af19ed4dbafb6b1b6e86733af5a922d.tar.gz crosvm-7dc915dd2af19ed4dbafb6b1b6e86733af5a922d.tar.bz2 crosvm-7dc915dd2af19ed4dbafb6b1b6e86733af5a922d.tar.lz crosvm-7dc915dd2af19ed4dbafb6b1b6e86733af5a922d.tar.xz crosvm-7dc915dd2af19ed4dbafb6b1b6e86733af5a922d.tar.zst crosvm-7dc915dd2af19ed4dbafb6b1b6e86733af5a922d.zip |
aarch64: Enable PMU in the guest.
This allows us to use perf/simpleperf in the guest. BUG=b:153708112 TEST=Use simpleperf in ARCVM guest on jacuzzi board. Change-Id: Ia3d7dc5bcd3ca033ddf05b5ee2593102c98e8b49 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2156592 Tested-by: kokoro <noreply+kokoro@google.com> Tested-by: Suleiman Souhlal <suleiman@chromium.org> Reviewed-by: Sonny Rao <sonnyrao@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org> Commit-Queue: Suleiman Souhlal <suleiman@chromium.org>
Diffstat (limited to 'kvm')
-rw-r--r-- | kvm/src/cap.rs | 1 | ||||
-rw-r--r-- | kvm/src/lib.rs | 44 |
2 files changed, 45 insertions, 0 deletions
diff --git a/kvm/src/cap.rs b/kvm/src/cap.rs index 7dfd965..ff65b59 100644 --- a/kvm/src/cap.rs +++ b/kvm/src/cap.rs @@ -119,4 +119,5 @@ pub enum Cap { CheckExtensionVm = KVM_CAP_CHECK_EXTENSION_VM, S390UserSigp = KVM_CAP_S390_USER_SIGP, ImmediateExit = KVM_CAP_IMMEDIATE_EXIT, + ArmPmuV3 = KVM_CAP_ARM_PMU_V3, } diff --git a/kvm/src/lib.rs b/kvm/src/lib.rs index b8cd12b..8b98b7c 100644 --- a/kvm/src/lib.rs +++ b/kvm/src/lib.rs @@ -1763,6 +1763,50 @@ impl Vcpu { if ret < 0 { return errno_result(); } + + Ok(()) + } + + #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] + pub fn arm_pmu_init(&self, irq: u64) -> Result<()> { + let irq_addr = &irq as *const u64; + + // The in-kernel PMU virtualization is initialized by setting the irq + // with KVM_ARM_VCPU_PMU_V3_IRQ and then by KVM_ARM_VCPU_PMU_V3_INIT. + + let irq_attr = kvm_device_attr { + group: kvm_sys::KVM_ARM_VCPU_PMU_V3_CTRL, + attr: kvm_sys::KVM_ARM_VCPU_PMU_V3_IRQ as u64, + addr: irq_addr as u64, + flags: 0, + }; + // safe becuase we allocated the struct and we know the kernel will read + // exactly the size of the struct + let ret = unsafe { ioctl_with_ref(self, kvm_sys::KVM_HAS_DEVICE_ATTR(), &irq_attr) }; + if ret < 0 { + return errno_result(); + } + + // safe becuase we allocated the struct and we know the kernel will read + // exactly the size of the struct + let ret = unsafe { ioctl_with_ref(self, kvm_sys::KVM_SET_DEVICE_ATTR(), &irq_attr) }; + if ret < 0 { + return errno_result(); + } + + let init_attr = kvm_device_attr { + group: kvm_sys::KVM_ARM_VCPU_PMU_V3_CTRL, + attr: kvm_sys::KVM_ARM_VCPU_PMU_V3_INIT as u64, + addr: 0, + flags: 0, + }; + // safe becuase we allocated the struct and we know the kernel will read + // exactly the size of the struct + let ret = unsafe { ioctl_with_ref(self, kvm_sys::KVM_SET_DEVICE_ATTR(), &init_attr) }; + if ret < 0 { + return errno_result(); + } + Ok(()) } |