Commit | Line | Data |
---|---|---|
56c7f5e7 AB |
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> | |
eef8c85a | 21 | #include <linux/hw_breakpoint.h> |
56c7f5e7 | 22 | |
337b99bf AB |
23 | #include <asm/debug-monitors.h> |
24 | #include <asm/kvm_asm.h> | |
56c7f5e7 | 25 | #include <asm/kvm_arm.h> |
337b99bf AB |
26 | #include <asm/kvm_emulate.h> |
27 | ||
eef8c85a AB |
28 | #include "trace.h" |
29 | ||
337b99bf AB |
30 | /* These are the bits of MDSCR_EL1 we may manipulate */ |
31 | #define MDSCR_EL1_DEBUG_MASK (DBG_MDSCR_SS | \ | |
32 | DBG_MDSCR_KDE | \ | |
33 | DBG_MDSCR_MDE) | |
56c7f5e7 AB |
34 | |
35 | static DEFINE_PER_CPU(u32, mdcr_el2); | |
36 | ||
337b99bf AB |
37 | /** |
38 | * save/restore_guest_debug_regs | |
39 | * | |
40 | * For some debug operations we need to tweak some guest registers. As | |
41 | * a result we need to save the state of those registers before we | |
42 | * make those modifications. | |
43 | * | |
44 | * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled | |
45 | * after we have restored the preserved value to the main context. | |
46 | */ | |
47 | static void save_guest_debug_regs(struct kvm_vcpu *vcpu) | |
48 | { | |
49 | vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, MDSCR_EL1); | |
eef8c85a AB |
50 | |
51 | trace_kvm_arm_set_dreg32("Saved MDSCR_EL1", | |
52 | vcpu->arch.guest_debug_preserved.mdscr_el1); | |
337b99bf AB |
53 | } |
54 | ||
55 | static void restore_guest_debug_regs(struct kvm_vcpu *vcpu) | |
56 | { | |
57 | vcpu_sys_reg(vcpu, MDSCR_EL1) = vcpu->arch.guest_debug_preserved.mdscr_el1; | |
eef8c85a AB |
58 | |
59 | trace_kvm_arm_set_dreg32("Restored MDSCR_EL1", | |
60 | vcpu_sys_reg(vcpu, MDSCR_EL1)); | |
337b99bf AB |
61 | } |
62 | ||
56c7f5e7 AB |
63 | /** |
64 | * kvm_arm_init_debug - grab what we need for debug | |
65 | * | |
66 | * Currently the sole task of this function is to retrieve the initial | |
67 | * value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has | |
68 | * presumably been set-up by some knowledgeable bootcode. | |
69 | * | |
70 | * It is called once per-cpu during CPU hyp initialisation. | |
71 | */ | |
72 | ||
73 | void kvm_arm_init_debug(void) | |
74 | { | |
75 | __this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2)); | |
76 | } | |
77 | ||
84e690bf AB |
78 | /** |
79 | * kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state | |
80 | */ | |
81 | ||
82 | void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) | |
83 | { | |
84 | vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state; | |
85 | } | |
86 | ||
56c7f5e7 AB |
87 | /** |
88 | * kvm_arm_setup_debug - set up debug related stuff | |
89 | * | |
90 | * @vcpu: the vcpu pointer | |
91 | * | |
92 | * This is called before each entry into the hypervisor to setup any | |
93 | * debug related registers. Currently this just ensures we will trap | |
94 | * access to: | |
95 | * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) | |
96 | * - Debug ROM Address (MDCR_EL2_TDRA) | |
97 | * - OS related registers (MDCR_EL2_TDOSA) | |
f85279b4 | 98 | * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) |
56c7f5e7 AB |
99 | * |
100 | * Additionally, KVM only traps guest accesses to the debug registers if | |
101 | * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY | |
102 | * flag on vcpu->arch.debug_flags). Since the guest must not interfere | |
103 | * with the hardware state when debugging the guest, we must ensure that | |
104 | * trapping is enabled whenever we are debugging the guest using the | |
105 | * debug registers. | |
106 | */ | |
107 | ||
108 | void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) | |
109 | { | |
110 | bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY); | |
111 | ||
eef8c85a AB |
112 | trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug); |
113 | ||
f85279b4 WD |
114 | /* |
115 | * This also clears MDCR_EL2_E2PB_MASK to disable guest access | |
116 | * to the profiling buffer. | |
117 | */ | |
56c7f5e7 AB |
118 | vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; |
119 | vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | | |
f85279b4 | 120 | MDCR_EL2_TPMS | |
56c7f5e7 AB |
121 | MDCR_EL2_TPMCR | |
122 | MDCR_EL2_TDRA | | |
123 | MDCR_EL2_TDOSA); | |
124 | ||
337b99bf AB |
125 | /* Is Guest debugging in effect? */ |
126 | if (vcpu->guest_debug) { | |
127 | /* Route all software debug exceptions to EL2 */ | |
4bd611ca | 128 | vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; |
337b99bf AB |
129 | |
130 | /* Save guest debug state */ | |
131 | save_guest_debug_regs(vcpu); | |
132 | ||
133 | /* | |
134 | * Single Step (ARM ARM D2.12.3 The software step state | |
135 | * machine) | |
136 | * | |
137 | * If we are doing Single Step we need to manipulate | |
138 | * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the | |
139 | * step has occurred the hypervisor will trap the | |
140 | * debug exception and we return to userspace. | |
141 | * | |
142 | * If the guest attempts to single step its userspace | |
143 | * we would have to deal with a trapped exception | |
144 | * while in the guest kernel. Because this would be | |
145 | * hard to unwind we suppress the guest's ability to | |
146 | * do so by masking MDSCR_EL.SS. | |
147 | * | |
148 | * This confuses guest debuggers which use | |
149 | * single-step behind the scenes but everything | |
150 | * returns to normal once the host is no longer | |
151 | * debugging the system. | |
152 | */ | |
153 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { | |
154 | *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; | |
155 | vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_SS; | |
156 | } else { | |
157 | vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS; | |
158 | } | |
834bf887 | 159 | |
eef8c85a AB |
160 | trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu)); |
161 | ||
834bf887 AB |
162 | /* |
163 | * HW Breakpoints and watchpoints | |
164 | * | |
165 | * We simply switch the debug_ptr to point to our new | |
166 | * external_debug_state which has been populated by the | |
167 | * debug ioctl. The existing KVM_ARM64_DEBUG_DIRTY | |
168 | * mechanism ensures the registers are updated on the | |
169 | * world switch. | |
170 | */ | |
171 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { | |
172 | /* Enable breakpoints/watchpoints */ | |
173 | vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_MDE; | |
174 | ||
175 | vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state; | |
176 | vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; | |
177 | trap_debug = true; | |
eef8c85a AB |
178 | |
179 | trace_kvm_arm_set_regset("BKPTS", get_num_brps(), | |
180 | &vcpu->arch.debug_ptr->dbg_bcr[0], | |
181 | &vcpu->arch.debug_ptr->dbg_bvr[0]); | |
182 | ||
183 | trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), | |
184 | &vcpu->arch.debug_ptr->dbg_wcr[0], | |
185 | &vcpu->arch.debug_ptr->dbg_wvr[0]); | |
834bf887 | 186 | } |
337b99bf | 187 | } |
834bf887 AB |
188 | |
189 | BUG_ON(!vcpu->guest_debug && | |
190 | vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state); | |
191 | ||
192 | /* Trap debug register access */ | |
193 | if (trap_debug) | |
194 | vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; | |
eef8c85a AB |
195 | |
196 | trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2); | |
197 | trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_sys_reg(vcpu, MDSCR_EL1)); | |
56c7f5e7 AB |
198 | } |
199 | ||
200 | void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) | |
201 | { | |
eef8c85a AB |
202 | trace_kvm_arm_clear_debug(vcpu->guest_debug); |
203 | ||
834bf887 | 204 | if (vcpu->guest_debug) { |
337b99bf | 205 | restore_guest_debug_regs(vcpu); |
834bf887 AB |
206 | |
207 | /* | |
208 | * If we were using HW debug we need to restore the | |
209 | * debug_ptr to the guest debug state. | |
210 | */ | |
eef8c85a | 211 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { |
834bf887 AB |
212 | kvm_arm_reset_debug_ptr(vcpu); |
213 | ||
eef8c85a AB |
214 | trace_kvm_arm_set_regset("BKPTS", get_num_brps(), |
215 | &vcpu->arch.debug_ptr->dbg_bcr[0], | |
216 | &vcpu->arch.debug_ptr->dbg_bvr[0]); | |
217 | ||
218 | trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), | |
219 | &vcpu->arch.debug_ptr->dbg_wcr[0], | |
220 | &vcpu->arch.debug_ptr->dbg_wvr[0]); | |
221 | } | |
834bf887 | 222 | } |
56c7f5e7 | 223 | } |
696673d1 AB |
224 | |
225 | ||
226 | /* | |
227 | * After successfully emulating an instruction, we might want to | |
228 | * return to user space with a KVM_EXIT_DEBUG. We can only do this | |
229 | * once the emulation is complete, though, so for userspace emulations | |
230 | * we have to wait until we have re-entered KVM before calling this | |
231 | * helper. | |
232 | * | |
233 | * Return true (and set exit_reason) to return to userspace or false | |
234 | * if no further action is required. | |
235 | */ | |
236 | bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run) | |
237 | { | |
238 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { | |
239 | run->exit_reason = KVM_EXIT_DEBUG; | |
240 | run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << ESR_ELx_EC_SHIFT; | |
241 | return true; | |
242 | } | |
243 | return false; | |
244 | } |