33 * Debug and Guest Debug support
44 *
55 * Copyright (C) 2015 - Linaro Ltd
6- * Author: Alex Bennée <alex.bennee@linaro.org>
6+ * Authors: Alex Bennée <alex.bennee@linaro.org>
7+ * Oliver Upton <oliver.upton@linux.dev>
78 */
89
910#include <linux/kvm_host.h>
1415#include <asm/kvm_arm.h>
1516#include <asm/kvm_emulate.h>
1617
17-
18- /*
19- * save/restore_guest_debug_regs
20- *
21- * For some debug operations we need to tweak some guest registers. As
22- * a result we need to save the state of those registers before we
23- * make those modifications.
24- *
25- * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
26- * after we have restored the preserved value to the main context.
27- *
28- * When single-step is enabled by userspace, we tweak PSTATE.SS on every
29- * guest entry. Preserve PSTATE.SS so we can restore the original value
30- * for the vcpu after the single-step is disabled.
31- */
32- static void save_guest_debug_regs (struct kvm_vcpu * vcpu )
33- {
34- vcpu -> arch .guest_debug_preserved .pstate_ss =
35- (* vcpu_cpsr (vcpu ) & DBG_SPSR_SS );
36- }
37-
38- static void restore_guest_debug_regs (struct kvm_vcpu * vcpu )
39- {
40- if (vcpu -> arch .guest_debug_preserved .pstate_ss )
41- * vcpu_cpsr (vcpu ) |= DBG_SPSR_SS ;
42- else
43- * vcpu_cpsr (vcpu ) &= ~DBG_SPSR_SS ;
44- }
45-
4618/**
4719 * kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value
4820 *
@@ -91,83 +63,6 @@ static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
9163 preempt_enable ();
9264}
9365
94- /**
95- * kvm_arm_setup_debug - set up debug related stuff
96- *
97- * @vcpu: the vcpu pointer
98- *
99- * This is called before each entry into the hypervisor to setup any
100- * debug related registers.
101- *
102- * Additionally, KVM only traps guest accesses to the debug registers if
103- * the guest is not actively using them. Since the guest must not interfere
104- * with the hardware state when debugging the guest, we must ensure that
105- * trapping is enabled whenever we are debugging the guest using the
106- * debug registers.
107- */
108-
109- void kvm_arm_setup_debug (struct kvm_vcpu * vcpu )
110- {
111- /* Check if we need to use the debug registers. */
112- if (vcpu -> guest_debug || kvm_vcpu_os_lock_enabled (vcpu )) {
113- /* Save guest debug state */
114- save_guest_debug_regs (vcpu );
115-
116- /*
117- * Single Step (ARM ARM D2.12.3 The software step state
118- * machine)
119- *
120- * If we are doing Single Step we need to manipulate
121- * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the
122- * step has occurred the hypervisor will trap the
123- * debug exception and we return to userspace.
124- *
125- * If the guest attempts to single step its userspace
126- * we would have to deal with a trapped exception
127- * while in the guest kernel. Because this would be
128- * hard to unwind we suppress the guest's ability to
129- * do so by masking MDSCR_EL.SS.
130- *
131- * This confuses guest debuggers which use
132- * single-step behind the scenes but everything
133- * returns to normal once the host is no longer
134- * debugging the system.
135- */
136- if (vcpu -> guest_debug & KVM_GUESTDBG_SINGLESTEP ) {
137- /*
138- * If the software step state at the last guest exit
139- * was Active-pending, we don't set DBG_SPSR_SS so
140- * that the state is maintained (to not run another
141- * single-step until the pending Software Step
142- * exception is taken).
143- */
144- if (!vcpu_get_flag (vcpu , DBG_SS_ACTIVE_PENDING ))
145- * vcpu_cpsr (vcpu ) |= DBG_SPSR_SS ;
146- else
147- * vcpu_cpsr (vcpu ) &= ~DBG_SPSR_SS ;
148- }
149- }
150- }
151-
152- void kvm_arm_clear_debug (struct kvm_vcpu * vcpu )
153- {
154- /*
155- * Restore the guest's debug registers if we were using them.
156- */
157- if (vcpu -> guest_debug || kvm_vcpu_os_lock_enabled (vcpu )) {
158- if (vcpu -> guest_debug & KVM_GUESTDBG_SINGLESTEP ) {
159- if (!(* vcpu_cpsr (vcpu ) & DBG_SPSR_SS ))
160- /*
161- * Mark the vcpu as ACTIVE_PENDING
162- * until Software Step exception is taken.
163- */
164- vcpu_set_flag (vcpu , DBG_SS_ACTIVE_PENDING );
165- }
166-
167- restore_guest_debug_regs (vcpu );
168- }
169- }
170-
17166void kvm_init_host_debug_data (void )
17267{
17368 u64 dfr0 = read_sysreg (id_aa64dfr0_el1 );
@@ -246,6 +141,22 @@ void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu)
246141 if (vcpu -> guest_debug || kvm_vcpu_os_lock_enabled (vcpu )) {
247142 vcpu -> arch .debug_owner = VCPU_DEBUG_HOST_OWNED ;
248143 setup_external_mdscr (vcpu );
144+
145+ /*
146+ * Steal the guest's single-step state machine if userspace wants
147+ * single-step the guest.
148+ */
149+ if (vcpu -> guest_debug & KVM_GUESTDBG_SINGLESTEP ) {
150+ if (* vcpu_cpsr (vcpu ) & DBG_SPSR_SS )
151+ vcpu_clear_flag (vcpu , GUEST_SS_ACTIVE_PENDING );
152+ else
153+ vcpu_set_flag (vcpu , GUEST_SS_ACTIVE_PENDING );
154+
155+ if (!vcpu_get_flag (vcpu , HOST_SS_ACTIVE_PENDING ))
156+ * vcpu_cpsr (vcpu ) |= DBG_SPSR_SS ;
157+ else
158+ * vcpu_cpsr (vcpu ) &= ~DBG_SPSR_SS ;
159+ }
249160 } else {
250161 mdscr = vcpu_read_sys_reg (vcpu , MDSCR_EL1 );
251162
@@ -258,6 +169,26 @@ void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu)
258169 kvm_arm_setup_mdcr_el2 (vcpu );
259170}
260171
172+ void kvm_vcpu_put_debug (struct kvm_vcpu * vcpu )
173+ {
174+ if (likely (!(vcpu -> guest_debug & KVM_GUESTDBG_SINGLESTEP )))
175+ return ;
176+
177+ /*
178+ * Save the host's software step state and restore the guest's before
179+ * potentially returning to userspace.
180+ */
181+ if (!(* vcpu_cpsr (vcpu ) & DBG_SPSR_SS ))
182+ vcpu_set_flag (vcpu , HOST_SS_ACTIVE_PENDING );
183+ else
184+ vcpu_clear_flag (vcpu , HOST_SS_ACTIVE_PENDING );
185+
186+ if (vcpu_get_flag (vcpu , GUEST_SS_ACTIVE_PENDING ))
187+ * vcpu_cpsr (vcpu ) &= ~DBG_SPSR_SS ;
188+ else
189+ * vcpu_cpsr (vcpu ) |= DBG_SPSR_SS ;
190+ }
191+
261192/*
262193 * Updates ownership of the debug registers after a trapped guest access to a
263194 * breakpoint/watchpoint register. Host ownership of the debug registers is of
0 commit comments