9 #include <linux/kvm_host.h>
10 #include <linux/hw_breakpoint.h>
12 #include <asm/debug-monitors.h>
13 #include <asm/kvm_asm.h>
14 #include <asm/kvm_arm.h>
15 #include <asm/kvm_emulate.h>
20 #define MDSCR_EL1_DEBUG_MASK (DBG_MDSCR_SS | \
44 vcpu->arch.guest_debug_preserved.mdscr_el1 = val;
46 trace_kvm_arm_set_dreg32(
"Saved MDSCR_EL1",
47 vcpu->arch.guest_debug_preserved.mdscr_el1);
49 vcpu->arch.guest_debug_preserved.pstate_ss =
50 (*vcpu_cpsr(vcpu) & DBG_SPSR_SS);
55 u64 val = vcpu->arch.guest_debug_preserved.mdscr_el1;
59 trace_kvm_arm_set_dreg32(
"Restored MDSCR_EL1",
62 if (vcpu->arch.guest_debug_preserved.pstate_ss)
63 *vcpu_cpsr(vcpu) |= DBG_SPSR_SS;
65 *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
102 vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
103 vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
111 if (vcpu->guest_debug)
113 vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
122 if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) ||
123 !vcpu_get_flag(vcpu, DEBUG_DIRTY) ||
124 kvm_vcpu_os_lock_enabled(vcpu))
125 vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
127 trace_kvm_arm_set_dreg32(
"MDCR_EL2", vcpu->arch.mdcr_el2);
150 vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state;
171 unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2;
173 trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
178 if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) {
202 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
210 if (!vcpu_get_flag(vcpu, DBG_SS_ACTIVE_PENDING))
211 *vcpu_cpsr(vcpu) |= DBG_SPSR_SS;
213 *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
216 mdscr |= DBG_MDSCR_SS;
220 mdscr &= ~DBG_MDSCR_SS;
224 trace_kvm_arm_set_dreg32(
"SPSR_EL2", *vcpu_cpsr(vcpu));
234 if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
237 mdscr |= DBG_MDSCR_MDE;
240 vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
241 vcpu_set_flag(vcpu, DEBUG_DIRTY);
243 trace_kvm_arm_set_regset(
"BKPTS", get_num_brps(),
244 &vcpu->arch.debug_ptr->dbg_bcr[0],
245 &vcpu->arch.debug_ptr->dbg_bvr[0]);
247 trace_kvm_arm_set_regset(
"WAPTS", get_num_wrps(),
248 &vcpu->arch.debug_ptr->dbg_wcr[0],
249 &vcpu->arch.debug_ptr->dbg_wvr[0]);
259 }
else if (kvm_vcpu_os_lock_enabled(vcpu)) {
261 mdscr &= ~DBG_MDSCR_MDE;
266 BUG_ON(!vcpu->guest_debug &&
267 vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state);
271 vcpu_set_flag(vcpu, DEBUG_DIRTY);
274 if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2)
275 write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
282 trace_kvm_arm_clear_debug(vcpu->guest_debug);
287 if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) {
288 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
289 if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS))
294 vcpu_set_flag(vcpu, DBG_SS_ACTIVE_PENDING);
303 if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
306 trace_kvm_arm_set_regset(
"BKPTS", get_num_brps(),
307 &vcpu->arch.debug_ptr->dbg_bcr[0],
308 &vcpu->arch.debug_ptr->dbg_bvr[0]);
310 trace_kvm_arm_set_regset(
"WAPTS", get_num_wrps(),
311 &vcpu->arch.debug_ptr->dbg_wcr[0],
312 &vcpu->arch.debug_ptr->dbg_wvr[0]);
325 dfr0 = read_sysreg(id_aa64dfr0_el1);
330 if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) &&
331 !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(PMBIDR_EL1_P_SHIFT)))
332 vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE);
335 if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
336 !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
337 vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
342 vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
343 vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu)
void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
static DEFINE_PER_CPU(u64, mdcr_el2)
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu)
void kvm_arm_init_debug(void)
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
u64 __kvm_get_mdcr_el2(void)
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)