18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Debug and Guest Debug support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2015 - Linaro Ltd 68c2ecf20Sopenharmony_ci * Author: Alex Bennée <alex.bennee@linaro.org> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/kvm_host.h> 108c2ecf20Sopenharmony_ci#include <linux/hw_breakpoint.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <asm/debug-monitors.h> 138c2ecf20Sopenharmony_ci#include <asm/kvm_asm.h> 148c2ecf20Sopenharmony_ci#include <asm/kvm_arm.h> 158c2ecf20Sopenharmony_ci#include <asm/kvm_emulate.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "trace.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* These are the bits of MDSCR_EL1 we may manipulate */ 208c2ecf20Sopenharmony_ci#define MDSCR_EL1_DEBUG_MASK (DBG_MDSCR_SS | \ 218c2ecf20Sopenharmony_ci DBG_MDSCR_KDE | \ 228c2ecf20Sopenharmony_ci DBG_MDSCR_MDE) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic DEFINE_PER_CPU(u32, mdcr_el2); 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/** 278c2ecf20Sopenharmony_ci * save/restore_guest_debug_regs 288c2ecf20Sopenharmony_ci * 298c2ecf20Sopenharmony_ci * For some debug operations we need to tweak some guest registers. As 308c2ecf20Sopenharmony_ci * a result we need to save the state of those registers before we 318c2ecf20Sopenharmony_ci * make those modifications. 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled 348c2ecf20Sopenharmony_ci * after we have restored the preserved value to the main context. 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_cistatic void save_guest_debug_regs(struct kvm_vcpu *vcpu) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci u64 val = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci vcpu->arch.guest_debug_preserved.mdscr_el1 = val; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci trace_kvm_arm_set_dreg32("Saved MDSCR_EL1", 438c2ecf20Sopenharmony_ci vcpu->arch.guest_debug_preserved.mdscr_el1); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic void restore_guest_debug_regs(struct kvm_vcpu *vcpu) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci u64 val = vcpu->arch.guest_debug_preserved.mdscr_el1; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci vcpu_write_sys_reg(vcpu, val, MDSCR_EL1); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci trace_kvm_arm_set_dreg32("Restored MDSCR_EL1", 538c2ecf20Sopenharmony_ci vcpu_read_sys_reg(vcpu, MDSCR_EL1)); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/** 578c2ecf20Sopenharmony_ci * kvm_arm_init_debug - grab what we need for debug 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * Currently the sole task of this function is to retrieve the initial 608c2ecf20Sopenharmony_ci * value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has 618c2ecf20Sopenharmony_ci * presumably been set-up by some knowledgeable bootcode. 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * It is called once per-cpu during CPU hyp initialisation. 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_civoid kvm_arm_init_debug(void) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci __this_cpu_write(mdcr_el2, kvm_call_hyp_ret(__kvm_get_mdcr_el2)); 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/** 728c2ecf20Sopenharmony_ci * kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value 738c2ecf20Sopenharmony_ci * 748c2ecf20Sopenharmony_ci * @vcpu: the vcpu pointer 758c2ecf20Sopenharmony_ci * 768c2ecf20Sopenharmony_ci * This ensures we will trap access to: 778c2ecf20Sopenharmony_ci * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) 788c2ecf20Sopenharmony_ci * - Debug ROM Address (MDCR_EL2_TDRA) 798c2ecf20Sopenharmony_ci * - OS related registers (MDCR_EL2_TDOSA) 808c2ecf20Sopenharmony_ci * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) 818c2ecf20Sopenharmony_ci * - Self-hosted Trace Filter controls (MDCR_EL2_TTRF) 828c2ecf20Sopenharmony_ci */ 838c2ecf20Sopenharmony_cistatic void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci /* 868c2ecf20Sopenharmony_ci * This also clears MDCR_EL2_E2PB_MASK to disable guest access 878c2ecf20Sopenharmony_ci * to the profiling buffer. 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_ci vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; 908c2ecf20Sopenharmony_ci vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | 918c2ecf20Sopenharmony_ci MDCR_EL2_TPMS | 928c2ecf20Sopenharmony_ci MDCR_EL2_TTRF | 938c2ecf20Sopenharmony_ci MDCR_EL2_TPMCR | 948c2ecf20Sopenharmony_ci MDCR_EL2_TDRA | 958c2ecf20Sopenharmony_ci MDCR_EL2_TDOSA); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* Is the VM being debugged by userspace? */ 988c2ecf20Sopenharmony_ci if (vcpu->guest_debug) 998c2ecf20Sopenharmony_ci /* Route all software debug exceptions to EL2 */ 1008c2ecf20Sopenharmony_ci vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci /* 1038c2ecf20Sopenharmony_ci * Trap debug register access when one of the following is true: 1048c2ecf20Sopenharmony_ci * - Userspace is using the hardware to debug the guest 1058c2ecf20Sopenharmony_ci * (KVM_GUESTDBG_USE_HW is set). 1068c2ecf20Sopenharmony_ci * - The guest is not using debug (KVM_ARM64_DEBUG_DIRTY is clear). 1078c2ecf20Sopenharmony_ci */ 1088c2ecf20Sopenharmony_ci if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) || 1098c2ecf20Sopenharmony_ci !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY)) 1108c2ecf20Sopenharmony_ci vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2); 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci/** 1168c2ecf20Sopenharmony_ci * kvm_arm_vcpu_init_debug - setup vcpu debug traps 1178c2ecf20Sopenharmony_ci * 1188c2ecf20Sopenharmony_ci * @vcpu: the vcpu pointer 1198c2ecf20Sopenharmony_ci * 1208c2ecf20Sopenharmony_ci * Set vcpu initial mdcr_el2 value. 1218c2ecf20Sopenharmony_ci */ 1228c2ecf20Sopenharmony_civoid kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci preempt_disable(); 1258c2ecf20Sopenharmony_ci kvm_arm_setup_mdcr_el2(vcpu); 1268c2ecf20Sopenharmony_ci preempt_enable(); 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci/** 1308c2ecf20Sopenharmony_ci * kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_civoid kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) 1348c2ecf20Sopenharmony_ci{ 1358c2ecf20Sopenharmony_ci vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state; 1368c2ecf20Sopenharmony_ci} 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci/** 1398c2ecf20Sopenharmony_ci * kvm_arm_setup_debug - set up debug related stuff 1408c2ecf20Sopenharmony_ci * 1418c2ecf20Sopenharmony_ci * @vcpu: the vcpu pointer 1428c2ecf20Sopenharmony_ci * 1438c2ecf20Sopenharmony_ci * This is called before each entry into the hypervisor to setup any 1448c2ecf20Sopenharmony_ci * debug related registers. 1458c2ecf20Sopenharmony_ci * 1468c2ecf20Sopenharmony_ci * Additionally, KVM only traps guest accesses to the debug registers if 1478c2ecf20Sopenharmony_ci * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY 1488c2ecf20Sopenharmony_ci * flag on vcpu->arch.flags). Since the guest must not interfere 1498c2ecf20Sopenharmony_ci * with the hardware state when debugging the guest, we must ensure that 1508c2ecf20Sopenharmony_ci * trapping is enabled whenever we are debugging the guest using the 1518c2ecf20Sopenharmony_ci * debug registers. 1528c2ecf20Sopenharmony_ci */ 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_civoid kvm_arm_setup_debug(struct kvm_vcpu *vcpu) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci kvm_arm_setup_mdcr_el2(vcpu); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci /* Is Guest debugging in effect? */ 1638c2ecf20Sopenharmony_ci if (vcpu->guest_debug) { 1648c2ecf20Sopenharmony_ci /* Save guest debug state */ 1658c2ecf20Sopenharmony_ci save_guest_debug_regs(vcpu); 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci /* 1688c2ecf20Sopenharmony_ci * Single Step (ARM ARM D2.12.3 The software step state 1698c2ecf20Sopenharmony_ci * machine) 1708c2ecf20Sopenharmony_ci * 1718c2ecf20Sopenharmony_ci * If we are doing Single Step we need to manipulate 1728c2ecf20Sopenharmony_ci * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the 1738c2ecf20Sopenharmony_ci * step has occurred the hypervisor will trap the 1748c2ecf20Sopenharmony_ci * debug exception and we return to userspace. 1758c2ecf20Sopenharmony_ci * 1768c2ecf20Sopenharmony_ci * If the guest attempts to single step its userspace 1778c2ecf20Sopenharmony_ci * we would have to deal with a trapped exception 1788c2ecf20Sopenharmony_ci * while in the guest kernel. Because this would be 1798c2ecf20Sopenharmony_ci * hard to unwind we suppress the guest's ability to 1808c2ecf20Sopenharmony_ci * do so by masking MDSCR_EL.SS. 1818c2ecf20Sopenharmony_ci * 1828c2ecf20Sopenharmony_ci * This confuses guest debuggers which use 1838c2ecf20Sopenharmony_ci * single-step behind the scenes but everything 1848c2ecf20Sopenharmony_ci * returns to normal once the host is no longer 1858c2ecf20Sopenharmony_ci * debugging the system. 1868c2ecf20Sopenharmony_ci */ 1878c2ecf20Sopenharmony_ci if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { 1888c2ecf20Sopenharmony_ci *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 1898c2ecf20Sopenharmony_ci mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 1908c2ecf20Sopenharmony_ci mdscr |= DBG_MDSCR_SS; 1918c2ecf20Sopenharmony_ci vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 1928c2ecf20Sopenharmony_ci } else { 1938c2ecf20Sopenharmony_ci mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 1948c2ecf20Sopenharmony_ci mdscr &= ~DBG_MDSCR_SS; 1958c2ecf20Sopenharmony_ci vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 1968c2ecf20Sopenharmony_ci } 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu)); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* 2018c2ecf20Sopenharmony_ci * HW Breakpoints and watchpoints 2028c2ecf20Sopenharmony_ci * 2038c2ecf20Sopenharmony_ci * We simply switch the debug_ptr to point to our new 2048c2ecf20Sopenharmony_ci * external_debug_state which has been populated by the 2058c2ecf20Sopenharmony_ci * debug ioctl. The existing KVM_ARM64_DEBUG_DIRTY 2068c2ecf20Sopenharmony_ci * mechanism ensures the registers are updated on the 2078c2ecf20Sopenharmony_ci * world switch. 2088c2ecf20Sopenharmony_ci */ 2098c2ecf20Sopenharmony_ci if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 2108c2ecf20Sopenharmony_ci /* Enable breakpoints/watchpoints */ 2118c2ecf20Sopenharmony_ci mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 2128c2ecf20Sopenharmony_ci mdscr |= DBG_MDSCR_MDE; 2138c2ecf20Sopenharmony_ci vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state; 2168c2ecf20Sopenharmony_ci vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci trace_kvm_arm_set_regset("BKPTS", get_num_brps(), 2198c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bcr[0], 2208c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bvr[0]); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), 2238c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wcr[0], 2248c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wvr[0]); 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci BUG_ON(!vcpu->guest_debug && 2298c2ecf20Sopenharmony_ci vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci /* If KDE or MDE are set, perform a full save/restore cycle. */ 2328c2ecf20Sopenharmony_ci if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE)) 2338c2ecf20Sopenharmony_ci vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci /* Write mdcr_el2 changes since vcpu_load on VHE systems */ 2368c2ecf20Sopenharmony_ci if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2) 2378c2ecf20Sopenharmony_ci write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1)); 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_civoid kvm_arm_clear_debug(struct kvm_vcpu *vcpu) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci trace_kvm_arm_clear_debug(vcpu->guest_debug); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci if (vcpu->guest_debug) { 2478c2ecf20Sopenharmony_ci restore_guest_debug_regs(vcpu); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci /* 2508c2ecf20Sopenharmony_ci * If we were using HW debug we need to restore the 2518c2ecf20Sopenharmony_ci * debug_ptr to the guest debug state. 2528c2ecf20Sopenharmony_ci */ 2538c2ecf20Sopenharmony_ci if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 2548c2ecf20Sopenharmony_ci kvm_arm_reset_debug_ptr(vcpu); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci trace_kvm_arm_set_regset("BKPTS", get_num_brps(), 2578c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bcr[0], 2588c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bvr[0]); 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), 2618c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wcr[0], 2628c2ecf20Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wvr[0]); 2638c2ecf20Sopenharmony_ci } 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci} 266