KVM
Macros | Functions
debug.c File Reference
#include <linux/kvm_host.h>
#include <linux/hw_breakpoint.h>
#include <asm/debug-monitors.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_arm.h>
#include <asm/kvm_emulate.h>
#include "trace.h"
Include dependency graph for debug.c:

Go to the source code of this file.

Macros

#define MDSCR_EL1_DEBUG_MASK
 

Functions

static DEFINE_PER_CPU (u64, mdcr_el2)
 
static void save_guest_debug_regs (struct kvm_vcpu *vcpu)
 
static void restore_guest_debug_regs (struct kvm_vcpu *vcpu)
 
void kvm_arm_init_debug (void)
 
static void kvm_arm_setup_mdcr_el2 (struct kvm_vcpu *vcpu)
 
void kvm_arm_vcpu_init_debug (struct kvm_vcpu *vcpu)
 
void kvm_arm_reset_debug_ptr (struct kvm_vcpu *vcpu)
 
void kvm_arm_setup_debug (struct kvm_vcpu *vcpu)
 
void kvm_arm_clear_debug (struct kvm_vcpu *vcpu)
 
void kvm_arch_vcpu_load_debug_state_flags (struct kvm_vcpu *vcpu)
 
void kvm_arch_vcpu_put_debug_state_flags (struct kvm_vcpu *vcpu)
 

Macro Definition Documentation

◆ MDSCR_EL1_DEBUG_MASK

#define MDSCR_EL1_DEBUG_MASK
Value:
(DBG_MDSCR_SS | \
DBG_MDSCR_KDE | \
DBG_MDSCR_MDE)

Definition at line 20 of file debug.c.

Function Documentation

◆ DEFINE_PER_CPU()

static DEFINE_PER_CPU ( u64  ,
mdcr_el2   
)
static

◆ kvm_arch_vcpu_load_debug_state_flags()

void kvm_arch_vcpu_load_debug_state_flags ( struct kvm_vcpu *  vcpu)

Definition at line 317 of file debug.c.

318 {
319  u64 dfr0;
320 
321  /* For VHE, there is nothing to do */
322  if (has_vhe())
323  return;
324 
325  dfr0 = read_sysreg(id_aa64dfr0_el1);
326  /*
327  * If SPE is present on this CPU and is available at current EL,
328  * we may need to check if the host state needs to be saved.
329  */
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);
333 
334  /* Check if we have TRBE implemented and available at the host */
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);
338 }
Here is the caller graph for this function:

◆ kvm_arch_vcpu_put_debug_state_flags()

void kvm_arch_vcpu_put_debug_state_flags ( struct kvm_vcpu *  vcpu)

Definition at line 340 of file debug.c.

341 {
342  vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
343  vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
344 }
Here is the caller graph for this function:

◆ kvm_arm_clear_debug()

void kvm_arm_clear_debug ( struct kvm_vcpu *  vcpu)

Definition at line 280 of file debug.c.

281 {
282  trace_kvm_arm_clear_debug(vcpu->guest_debug);
283 
284  /*
285  * Restore the guest's debug registers if we were using them.
286  */
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))
290  /*
291  * Mark the vcpu as ACTIVE_PENDING
292  * until Software Step exception is taken.
293  */
294  vcpu_set_flag(vcpu, DBG_SS_ACTIVE_PENDING);
295  }
296 
298 
299  /*
300  * If we were using HW debug we need to restore the
301  * debug_ptr to the guest debug state.
302  */
303  if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
305 
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]);
309 
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]);
313  }
314  }
315 }
void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
Definition: debug.c:148
static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
Definition: debug.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_arm_init_debug()

void kvm_arm_init_debug ( void  )

kvm_arm_init_debug - grab what we need for debug

Currently the sole task of this function is to retrieve the initial value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has presumably been set-up by some knowledgeable bootcode.

It is called once per-cpu during CPU hyp initialisation.

Definition at line 78 of file debug.c.

79 {
80  __this_cpu_write(mdcr_el2, kvm_call_hyp_ret(__kvm_get_mdcr_el2));
81 }
u64 __kvm_get_mdcr_el2(void)
Definition: debug-sr.c:110
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_arm_reset_debug_ptr()

void kvm_arm_reset_debug_ptr ( struct kvm_vcpu *  vcpu)

kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state

Definition at line 148 of file debug.c.

149 {
150  vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state;
151 }
Here is the caller graph for this function:

◆ kvm_arm_setup_debug()

void kvm_arm_setup_debug ( struct kvm_vcpu *  vcpu)

kvm_arm_setup_debug - set up debug related stuff

@vcpu: the vcpu pointer

This is called before each entry into the hypervisor to setup any debug related registers.

Additionally, KVM only traps guest accesses to the debug registers if the guest is not actively using them (see the DEBUG_DIRTY flag on vcpu->arch.iflags). Since the guest must not interfere with the hardware state when debugging the guest, we must ensure that trapping is enabled whenever we are debugging the guest using the debug registers.

Definition at line 169 of file debug.c.

170 {
171  unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2;
172 
173  trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
174 
176 
177  /* Check if we need to use the debug registers. */
178  if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) {
179  /* Save guest debug state */
180  save_guest_debug_regs(vcpu);
181 
182  /*
183  * Single Step (ARM ARM D2.12.3 The software step state
184  * machine)
185  *
186  * If we are doing Single Step we need to manipulate
187  * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the
188  * step has occurred the hypervisor will trap the
189  * debug exception and we return to userspace.
190  *
191  * If the guest attempts to single step its userspace
192  * we would have to deal with a trapped exception
193  * while in the guest kernel. Because this would be
194  * hard to unwind we suppress the guest's ability to
195  * do so by masking MDSCR_EL.SS.
196  *
197  * This confuses guest debuggers which use
198  * single-step behind the scenes but everything
199  * returns to normal once the host is no longer
200  * debugging the system.
201  */
202  if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
203  /*
204  * If the software step state at the last guest exit
205  * was Active-pending, we don't set DBG_SPSR_SS so
206  * that the state is maintained (to not run another
207  * single-step until the pending Software Step
208  * exception is taken).
209  */
210  if (!vcpu_get_flag(vcpu, DBG_SS_ACTIVE_PENDING))
211  *vcpu_cpsr(vcpu) |= DBG_SPSR_SS;
212  else
213  *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
214 
215  mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
216  mdscr |= DBG_MDSCR_SS;
217  vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
218  } else {
219  mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
220  mdscr &= ~DBG_MDSCR_SS;
221  vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
222  }
223 
224  trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu));
225 
226  /*
227  * HW Breakpoints and watchpoints
228  *
229  * We simply switch the debug_ptr to point to our new
230  * external_debug_state which has been populated by the
231  * debug ioctl. The existing DEBUG_DIRTY mechanism ensures
232  * the registers are updated on the world switch.
233  */
234  if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
235  /* Enable breakpoints/watchpoints */
236  mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
237  mdscr |= DBG_MDSCR_MDE;
238  vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
239 
240  vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
241  vcpu_set_flag(vcpu, DEBUG_DIRTY);
242 
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]);
246 
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]);
250 
251  /*
252  * The OS Lock blocks debug exceptions in all ELs when it is
253  * enabled. If the guest has enabled the OS Lock, constrain its
254  * effects to the guest. Emulate the behavior by clearing
255  * MDSCR_EL1.MDE. In so doing, we ensure that host debug
256  * exceptions are unaffected by guest configuration of the OS
257  * Lock.
258  */
259  } else if (kvm_vcpu_os_lock_enabled(vcpu)) {
260  mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
261  mdscr &= ~DBG_MDSCR_MDE;
262  vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
263  }
264  }
265 
266  BUG_ON(!vcpu->guest_debug &&
267  vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state);
268 
269  /* If KDE or MDE are set, perform a full save/restore cycle. */
270  if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE))
271  vcpu_set_flag(vcpu, DEBUG_DIRTY);
272 
273  /* Write mdcr_el2 changes since vcpu_load on VHE systems */
274  if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2)
275  write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
276 
277  trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1));
278 }
static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
Definition: debug.c:96
static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
Definition: debug.c:40
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
Definition: sys_regs.c:128
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
Definition: sys_regs.c:172
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_arm_setup_mdcr_el2()

static void kvm_arm_setup_mdcr_el2 ( struct kvm_vcpu *  vcpu)
static

kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value

@vcpu: the vcpu pointer

This ensures we will trap access to:

  • Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR)
  • Debug ROM Address (MDCR_EL2_TDRA)
  • OS related registers (MDCR_EL2_TDOSA)
  • Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB)
  • Self-hosted Trace Filter controls (MDCR_EL2_TTRF)
  • Self-hosted Trace (MDCR_EL2_TTRF/MDCR_EL2_E2TB)

Definition at line 96 of file debug.c.

97 {
98  /*
99  * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK
100  * to disable guest access to the profiling and trace buffers
101  */
102  vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
103  vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
104  MDCR_EL2_TPMS |
105  MDCR_EL2_TTRF |
106  MDCR_EL2_TPMCR |
107  MDCR_EL2_TDRA |
108  MDCR_EL2_TDOSA);
109 
110  /* Is the VM being debugged by userspace? */
111  if (vcpu->guest_debug)
112  /* Route all software debug exceptions to EL2 */
113  vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
114 
115  /*
116  * Trap debug register access when one of the following is true:
117  * - Userspace is using the hardware to debug the guest
118  * (KVM_GUESTDBG_USE_HW is set).
119  * - The guest is not using debug (DEBUG_DIRTY clear).
120  * - The guest has enabled the OS Lock (debug exceptions are blocked).
121  */
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;
126 
127  trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
128 }
Here is the caller graph for this function:

◆ kvm_arm_vcpu_init_debug()

void kvm_arm_vcpu_init_debug ( struct kvm_vcpu *  vcpu)

kvm_arm_vcpu_init_debug - setup vcpu debug traps

@vcpu: the vcpu pointer

Set vcpu initial mdcr_el2 value.

Definition at line 137 of file debug.c.

138 {
139  preempt_disable();
141  preempt_enable();
142 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ restore_guest_debug_regs()

static void restore_guest_debug_regs ( struct kvm_vcpu *  vcpu)
static

Definition at line 53 of file debug.c.

54 {
55  u64 val = vcpu->arch.guest_debug_preserved.mdscr_el1;
56 
57  vcpu_write_sys_reg(vcpu, val, MDSCR_EL1);
58 
59  trace_kvm_arm_set_dreg32("Restored MDSCR_EL1",
60  vcpu_read_sys_reg(vcpu, MDSCR_EL1));
61 
62  if (vcpu->arch.guest_debug_preserved.pstate_ss)
63  *vcpu_cpsr(vcpu) |= DBG_SPSR_SS;
64  else
65  *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
66 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ save_guest_debug_regs()

static void save_guest_debug_regs ( struct kvm_vcpu *  vcpu)
static

save/restore_guest_debug_regs

For some debug operations we need to tweak some guest registers. As a result we need to save the state of those registers before we make those modifications.

Guest access to MDSCR_EL1 is trapped by the hypervisor and handled after we have restored the preserved value to the main context.

When single-step is enabled by userspace, we tweak PSTATE.SS on every guest entry. Preserve PSTATE.SS so we can restore the original value for the vcpu after the single-step is disabled.

Definition at line 40 of file debug.c.

41 {
42  u64 val = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
43 
44  vcpu->arch.guest_debug_preserved.mdscr_el1 = val;
45 
46  trace_kvm_arm_set_dreg32("Saved MDSCR_EL1",
47  vcpu->arch.guest_debug_preserved.mdscr_el1);
48 
49  vcpu->arch.guest_debug_preserved.pstate_ss =
50  (*vcpu_cpsr(vcpu) & DBG_SPSR_SS);
51 }
Here is the call graph for this function:
Here is the caller graph for this function: