Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Debug and Guest Debug support
0004  *
0005  * Copyright (C) 2015 - Linaro Ltd
0006  * Author: Alex Bennée <alex.bennee@linaro.org>
0007  */
0008 
0009 #include <linux/kvm_host.h>
0010 #include <linux/hw_breakpoint.h>
0011 
0012 #include <asm/debug-monitors.h>
0013 #include <asm/kvm_asm.h>
0014 #include <asm/kvm_arm.h>
0015 #include <asm/kvm_emulate.h>
0016 
0017 #include "trace.h"
0018 
0019 /* These are the bits of MDSCR_EL1 we may manipulate */
0020 #define MDSCR_EL1_DEBUG_MASK    (DBG_MDSCR_SS | \
0021                 DBG_MDSCR_KDE | \
0022                 DBG_MDSCR_MDE)
0023 
0024 static DEFINE_PER_CPU(u64, mdcr_el2);
0025 
0026 /**
0027  * save/restore_guest_debug_regs
0028  *
0029  * For some debug operations we need to tweak some guest registers. As
0030  * a result we need to save the state of those registers before we
0031  * make those modifications.
0032  *
0033  * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
0034  * after we have restored the preserved value to the main context.
0035  */
0036 static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
0037 {
0038     u64 val = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
0039 
0040     vcpu->arch.guest_debug_preserved.mdscr_el1 = val;
0041 
0042     trace_kvm_arm_set_dreg32("Saved MDSCR_EL1",
0043                 vcpu->arch.guest_debug_preserved.mdscr_el1);
0044 }
0045 
0046 static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
0047 {
0048     u64 val = vcpu->arch.guest_debug_preserved.mdscr_el1;
0049 
0050     vcpu_write_sys_reg(vcpu, val, MDSCR_EL1);
0051 
0052     trace_kvm_arm_set_dreg32("Restored MDSCR_EL1",
0053                 vcpu_read_sys_reg(vcpu, MDSCR_EL1));
0054 }
0055 
0056 /**
0057  * kvm_arm_init_debug - grab what we need for debug
0058  *
0059  * Currently the sole task of this function is to retrieve the initial
0060  * value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has
0061  * presumably been set-up by some knowledgeable bootcode.
0062  *
0063  * It is called once per-cpu during CPU hyp initialisation.
0064  */
0065 
0066 void kvm_arm_init_debug(void)
0067 {
0068     __this_cpu_write(mdcr_el2, kvm_call_hyp_ret(__kvm_get_mdcr_el2));
0069 }
0070 
0071 /**
0072  * kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value
0073  *
0074  * @vcpu:   the vcpu pointer
0075  *
0076  * This ensures we will trap access to:
0077  *  - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR)
0078  *  - Debug ROM Address (MDCR_EL2_TDRA)
0079  *  - OS related registers (MDCR_EL2_TDOSA)
0080  *  - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB)
0081  *  - Self-hosted Trace Filter controls (MDCR_EL2_TTRF)
0082  *  - Self-hosted Trace (MDCR_EL2_TTRF/MDCR_EL2_E2TB)
0083  */
0084 static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
0085 {
0086     /*
0087      * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK
0088      * to disable guest access to the profiling and trace buffers
0089      */
0090     vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
0091     vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
0092                 MDCR_EL2_TPMS |
0093                 MDCR_EL2_TTRF |
0094                 MDCR_EL2_TPMCR |
0095                 MDCR_EL2_TDRA |
0096                 MDCR_EL2_TDOSA);
0097 
0098     /* Is the VM being debugged by userspace? */
0099     if (vcpu->guest_debug)
0100         /* Route all software debug exceptions to EL2 */
0101         vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
0102 
0103     /*
0104      * Trap debug register access when one of the following is true:
0105      *  - Userspace is using the hardware to debug the guest
0106      *  (KVM_GUESTDBG_USE_HW is set).
0107      *  - The guest is not using debug (DEBUG_DIRTY clear).
0108      *  - The guest has enabled the OS Lock (debug exceptions are blocked).
0109      */
0110     if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) ||
0111         !vcpu_get_flag(vcpu, DEBUG_DIRTY) ||
0112         kvm_vcpu_os_lock_enabled(vcpu))
0113         vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
0114 
0115     trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
0116 }
0117 
0118 /**
0119  * kvm_arm_vcpu_init_debug - setup vcpu debug traps
0120  *
0121  * @vcpu:   the vcpu pointer
0122  *
0123  * Set vcpu initial mdcr_el2 value.
0124  */
0125 void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu)
0126 {
0127     preempt_disable();
0128     kvm_arm_setup_mdcr_el2(vcpu);
0129     preempt_enable();
0130 }
0131 
0132 /**
0133  * kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state
0134  */
0135 
0136 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
0137 {
0138     vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state;
0139 }
0140 
0141 /**
0142  * kvm_arm_setup_debug - set up debug related stuff
0143  *
0144  * @vcpu:   the vcpu pointer
0145  *
0146  * This is called before each entry into the hypervisor to setup any
0147  * debug related registers.
0148  *
0149  * Additionally, KVM only traps guest accesses to the debug registers if
0150  * the guest is not actively using them (see the DEBUG_DIRTY
0151  * flag on vcpu->arch.iflags).  Since the guest must not interfere
0152  * with the hardware state when debugging the guest, we must ensure that
0153  * trapping is enabled whenever we are debugging the guest using the
0154  * debug registers.
0155  */
0156 
0157 void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
0158 {
0159     unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2;
0160 
0161     trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
0162 
0163     kvm_arm_setup_mdcr_el2(vcpu);
0164 
0165     /* Check if we need to use the debug registers. */
0166     if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) {
0167         /* Save guest debug state */
0168         save_guest_debug_regs(vcpu);
0169 
0170         /*
0171          * Single Step (ARM ARM D2.12.3 The software step state
0172          * machine)
0173          *
0174          * If we are doing Single Step we need to manipulate
0175          * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the
0176          * step has occurred the hypervisor will trap the
0177          * debug exception and we return to userspace.
0178          *
0179          * If the guest attempts to single step its userspace
0180          * we would have to deal with a trapped exception
0181          * while in the guest kernel. Because this would be
0182          * hard to unwind we suppress the guest's ability to
0183          * do so by masking MDSCR_EL.SS.
0184          *
0185          * This confuses guest debuggers which use
0186          * single-step behind the scenes but everything
0187          * returns to normal once the host is no longer
0188          * debugging the system.
0189          */
0190         if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
0191             *vcpu_cpsr(vcpu) |=  DBG_SPSR_SS;
0192             mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
0193             mdscr |= DBG_MDSCR_SS;
0194             vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
0195         } else {
0196             mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
0197             mdscr &= ~DBG_MDSCR_SS;
0198             vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
0199         }
0200 
0201         trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu));
0202 
0203         /*
0204          * HW Breakpoints and watchpoints
0205          *
0206          * We simply switch the debug_ptr to point to our new
0207          * external_debug_state which has been populated by the
0208          * debug ioctl. The existing DEBUG_DIRTY mechanism ensures
0209          * the registers are updated on the world switch.
0210          */
0211         if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
0212             /* Enable breakpoints/watchpoints */
0213             mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
0214             mdscr |= DBG_MDSCR_MDE;
0215             vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
0216 
0217             vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
0218             vcpu_set_flag(vcpu, DEBUG_DIRTY);
0219 
0220             trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
0221                         &vcpu->arch.debug_ptr->dbg_bcr[0],
0222                         &vcpu->arch.debug_ptr->dbg_bvr[0]);
0223 
0224             trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
0225                         &vcpu->arch.debug_ptr->dbg_wcr[0],
0226                         &vcpu->arch.debug_ptr->dbg_wvr[0]);
0227 
0228         /*
0229          * The OS Lock blocks debug exceptions in all ELs when it is
0230          * enabled. If the guest has enabled the OS Lock, constrain its
0231          * effects to the guest. Emulate the behavior by clearing
0232          * MDSCR_EL1.MDE. In so doing, we ensure that host debug
0233          * exceptions are unaffected by guest configuration of the OS
0234          * Lock.
0235          */
0236         } else if (kvm_vcpu_os_lock_enabled(vcpu)) {
0237             mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
0238             mdscr &= ~DBG_MDSCR_MDE;
0239             vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
0240         }
0241     }
0242 
0243     BUG_ON(!vcpu->guest_debug &&
0244         vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state);
0245 
0246     /* If KDE or MDE are set, perform a full save/restore cycle. */
0247     if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE))
0248         vcpu_set_flag(vcpu, DEBUG_DIRTY);
0249 
0250     /* Write mdcr_el2 changes since vcpu_load on VHE systems */
0251     if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2)
0252         write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
0253 
0254     trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1));
0255 }
0256 
0257 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
0258 {
0259     trace_kvm_arm_clear_debug(vcpu->guest_debug);
0260 
0261     /*
0262      * Restore the guest's debug registers if we were using them.
0263      */
0264     if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) {
0265         restore_guest_debug_regs(vcpu);
0266 
0267         /*
0268          * If we were using HW debug we need to restore the
0269          * debug_ptr to the guest debug state.
0270          */
0271         if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
0272             kvm_arm_reset_debug_ptr(vcpu);
0273 
0274             trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
0275                         &vcpu->arch.debug_ptr->dbg_bcr[0],
0276                         &vcpu->arch.debug_ptr->dbg_bvr[0]);
0277 
0278             trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
0279                         &vcpu->arch.debug_ptr->dbg_wcr[0],
0280                         &vcpu->arch.debug_ptr->dbg_wvr[0]);
0281         }
0282     }
0283 }
0284 
0285 void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu)
0286 {
0287     u64 dfr0;
0288 
0289     /* For VHE, there is nothing to do */
0290     if (has_vhe())
0291         return;
0292 
0293     dfr0 = read_sysreg(id_aa64dfr0_el1);
0294     /*
0295      * If SPE is present on this CPU and is available at current EL,
0296      * we may need to check if the host state needs to be saved.
0297      */
0298     if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_PMSVER_SHIFT) &&
0299         !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(SYS_PMBIDR_EL1_P_SHIFT)))
0300         vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE);
0301 
0302     /* Check if we have TRBE implemented and available at the host */
0303     if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRBE_SHIFT) &&
0304         !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_PROG))
0305         vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
0306 }
0307 
0308 void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
0309 {
0310     vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
0311     vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
0312 }