@@ -302,6 +302,7 @@
#define MDCR_EL2_TPMS (UL(1) << 14)
#define MDCR_EL2_E2PB_MASK (UL(0x3))
#define MDCR_EL2_E2PB_SHIFT (UL(12))
+#define MDCR_EL2_E2PB_TRAP_EL1 (UL(2))
#define MDCR_EL2_TDRA (UL(1) << 11)
#define MDCR_EL2_TDOSA (UL(1) << 10)
#define MDCR_EL2_TDA (UL(1) << 9)
@@ -77,24 +77,39 @@ void kvm_arm_init_debug(void)
* - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR)
* - Debug ROM Address (MDCR_EL2_TDRA)
* - OS related registers (MDCR_EL2_TDOSA)
- * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB)
* - Self-hosted Trace Filter controls (MDCR_EL2_TTRF)
* - Self-hosted Trace (MDCR_EL2_TTRF/MDCR_EL2_E2TB)
*/
static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
{
/*
- * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK
- * to disable guest access to the profiling and trace buffers
+ * This also clears MDCR_EL2_E2TB_MASK to disable guest access to the
+ * trace buffers.
*/
vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
- MDCR_EL2_TPMS |
MDCR_EL2_TTRF |
MDCR_EL2_TPMCR |
MDCR_EL2_TDRA |
MDCR_EL2_TDOSA);
+ if (kvm_supports_spe() && kvm_vcpu_has_spe(vcpu)) {
+ /*
+ * Use EL1&0 for the profiling buffer translation regime and
+ * trap accesses to the buffer control registers; leave
+ * MDCR_EL2.TPMS unset and do not trap accesses to the profiling
+ * control registers.
+ */
+ vcpu->arch.mdcr_el2 |= MDCR_EL2_E2PB_TRAP_EL1 << MDCR_EL2_E2PB_SHIFT;
+ } else {
+ /*
+ * Trap accesses to the profiling control registers; leave
+ * MDCR_EL2.E2PB unset and use the EL2&0 translation regime for
+ * the profiling buffer.
+ */
+ vcpu->arch.mdcr_el2 |= MDCR_EL2_TPMS;
+ }
+
/* Is the VM being debugged by userspace? */
if (vcpu->guest_debug)
/* Route all software debug exceptions to EL2 */
Allow the guest running at EL1 to use SPE when that feature is enabled for the VCPU by setting the profiling buffer owning translation regime to EL1&0 and disabling traps to the profiling control registers. Keep trapping accesses to the buffer control registers because that's needed to emulate the buffer management interrupt. Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com> --- arch/arm64/include/asm/kvm_arm.h | 1 + arch/arm64/kvm/debug.c | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-)