Alex Bennée | 56c7f5e | 2015-07-07 17:29:56 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Debug and Guest Debug support |
| 3 | * |
| 4 | * Copyright (C) 2015 - Linaro Ltd |
| 5 | * Author: Alex Bennée <alex.bennee@linaro.org> |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as |
| 9 | * published by the Free Software Foundation. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ |
| 19 | |
| 20 | #include <linux/kvm_host.h> |
| 21 | |
| 22 | #include <asm/kvm_arm.h> |
| 23 | |
| 24 | static DEFINE_PER_CPU(u32, mdcr_el2); |
| 25 | |
| 26 | /** |
| 27 | * kvm_arm_init_debug - grab what we need for debug |
| 28 | * |
| 29 | * Currently the sole task of this function is to retrieve the initial |
| 30 | * value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has |
| 31 | * presumably been set-up by some knowledgeable bootcode. |
| 32 | * |
| 33 | * It is called once per-cpu during CPU hyp initialisation. |
| 34 | */ |
| 35 | |
| 36 | void kvm_arm_init_debug(void) |
| 37 | { |
| 38 | __this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2)); |
| 39 | } |
| 40 | |
| 41 | |
| 42 | /** |
| 43 | * kvm_arm_setup_debug - set up debug related stuff |
| 44 | * |
| 45 | * @vcpu: the vcpu pointer |
| 46 | * |
| 47 | * This is called before each entry into the hypervisor to setup any |
| 48 | * debug related registers. Currently this just ensures we will trap |
| 49 | * access to: |
| 50 | * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) |
| 51 | * - Debug ROM Address (MDCR_EL2_TDRA) |
| 52 | * - OS related registers (MDCR_EL2_TDOSA) |
| 53 | * |
| 54 | * Additionally, KVM only traps guest accesses to the debug registers if |
| 55 | * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY |
| 56 | * flag on vcpu->arch.debug_flags). Since the guest must not interfere |
| 57 | * with the hardware state when debugging the guest, we must ensure that |
| 58 | * trapping is enabled whenever we are debugging the guest using the |
| 59 | * debug registers. |
| 60 | */ |
| 61 | |
| 62 | void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) |
| 63 | { |
| 64 | bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY); |
| 65 | |
| 66 | vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; |
| 67 | vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | |
| 68 | MDCR_EL2_TPMCR | |
| 69 | MDCR_EL2_TDRA | |
| 70 | MDCR_EL2_TDOSA); |
| 71 | |
| 72 | /* Trap on access to debug registers? */ |
| 73 | if (trap_debug) |
| 74 | vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; |
| 75 | |
Alex Bennée | 4bd611c | 2015-07-07 17:29:57 +0100 | [diff] [blame^] | 76 | /* Trap breakpoints? */ |
| 77 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) |
| 78 | vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; |
Alex Bennée | 56c7f5e | 2015-07-07 17:29:56 +0100 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) |
| 82 | { |
| 83 | /* Nothing to do yet */ |
| 84 | } |