Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84e690bf authored by Alex Bennée's avatar Alex Bennée Committed by Marc Zyngier
Browse files

KVM: arm64: introduce vcpu->arch.debug_ptr



This introduces a level of indirection for the debug registers. Instead
of using the sys_regs[] directly we store registers in a structure in
the vcpu. The new kvm_arm_reset_debug_ptr() sets the debug ptr to the
guest context.

Because we no longer give the sys_regs offset for the sys_reg_desc->reg
field, but instead the index into a debug-specific struct we need to
add a number of additional trap functions for each register. Also as the
generic generic user-space access code no longer works we have
introduced a new pair of function pointers to the sys_reg_desc structure
to override the generic code when needed.

Reviewed-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent e0a1b9a9
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -234,5 +234,6 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arm_init_debug(void) {}
static inline void kvm_arm_init_debug(void) {}
static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}


#endif /* __ARM_KVM_HOST_H__ */
#endif /* __ARM_KVM_HOST_H__ */
+2 −0
Original line number Original line Diff line number Diff line
@@ -278,6 +278,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
	/* Set up the timer */
	/* Set up the timer */
	kvm_timer_vcpu_init(vcpu);
	kvm_timer_vcpu_init(vcpu);


	kvm_arm_reset_debug_ptr(vcpu);

	return 0;
	return 0;
}
}


+8 −16
Original line number Original line Diff line number Diff line
@@ -46,24 +46,16 @@
#define	CNTKCTL_EL1	20	/* Timer Control Register (EL1) */
#define	CNTKCTL_EL1	20	/* Timer Control Register (EL1) */
#define	PAR_EL1		21	/* Physical Address Register */
#define	PAR_EL1		21	/* Physical Address Register */
#define MDSCR_EL1	22	/* Monitor Debug System Control Register */
#define MDSCR_EL1	22	/* Monitor Debug System Control Register */
#define DBGBCR0_EL1	23	/* Debug Breakpoint Control Registers (0-15) */
#define MDCCINT_EL1	23	/* Monitor Debug Comms Channel Interrupt Enable Reg */
#define DBGBCR15_EL1	38
#define DBGBVR0_EL1	39	/* Debug Breakpoint Value Registers (0-15) */
#define DBGBVR15_EL1	54
#define DBGWCR0_EL1	55	/* Debug Watchpoint Control Registers (0-15) */
#define DBGWCR15_EL1	70
#define DBGWVR0_EL1	71	/* Debug Watchpoint Value Registers (0-15) */
#define DBGWVR15_EL1	86
#define MDCCINT_EL1	87	/* Monitor Debug Comms Channel Interrupt Enable Reg */


/* 32bit specific registers. Keep them at the end of the range */
/* 32bit specific registers. Keep them at the end of the range */
#define	DACR32_EL2	88	/* Domain Access Control Register */
#define	DACR32_EL2	24	/* Domain Access Control Register */
#define	IFSR32_EL2	89	/* Instruction Fault Status Register */
#define	IFSR32_EL2	25	/* Instruction Fault Status Register */
#define	FPEXC32_EL2	90	/* Floating-Point Exception Control Register */
#define	FPEXC32_EL2	26	/* Floating-Point Exception Control Register */
#define	DBGVCR32_EL2	91	/* Debug Vector Catch Register */
#define	DBGVCR32_EL2	27	/* Debug Vector Catch Register */
#define	TEECR32_EL1	92	/* ThumbEE Configuration Register */
#define	TEECR32_EL1	28	/* ThumbEE Configuration Register */
#define	TEEHBR32_EL1	93	/* ThumbEE Handler Base Register */
#define	TEEHBR32_EL1	29	/* ThumbEE Handler Base Register */
#define	NR_SYS_REGS	94
#define	NR_SYS_REGS	30


/* 32bit mapping */
/* 32bit mapping */
#define c0_MPIDR	(MPIDR_EL1 * 2)	/* MultiProcessor ID Register */
#define c0_MPIDR	(MPIDR_EL1 * 2)	/* MultiProcessor ID Register */
+16 −1
Original line number Original line Diff line number Diff line
@@ -108,11 +108,25 @@ struct kvm_vcpu_arch {
	/* Exception Information */
	/* Exception Information */
	struct kvm_vcpu_fault_info fault;
	struct kvm_vcpu_fault_info fault;


	/* Debug state */
	/* Guest debug state */
	u64 debug_flags;
	u64 debug_flags;


	/*
	 * We maintain more than a single set of debug registers to support
	 * debugging the guest from the host and to maintain separate host and
	 * guest state during world switches. vcpu_debug_state are the debug
	 * registers of the vcpu as the guest sees them.  host_debug_state are
	 * the host registers which are saved and restored during world switches.
	 *
	 * debug_ptr points to the set of debug registers that should be loaded
	 * onto the hardware when running the guest.
	 */
	struct kvm_guest_debug_arch *debug_ptr;
	struct kvm_guest_debug_arch vcpu_debug_state;

	/* Pointer to host CPU context */
	/* Pointer to host CPU context */
	kvm_cpu_context_t *host_cpu_context;
	kvm_cpu_context_t *host_cpu_context;
	struct kvm_guest_debug_arch host_debug_state;


	/* VGIC state */
	/* VGIC state */
	struct vgic_cpu vgic_cpu;
	struct vgic_cpu vgic_cpu;
@@ -242,5 +256,6 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
void kvm_arm_init_debug(void);
void kvm_arm_init_debug(void);
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);


#endif /* __ARM64_KVM_HOST_H__ */
#endif /* __ARM64_KVM_HOST_H__ */
+6 −0
Original line number Original line Diff line number Diff line
@@ -116,10 +116,16 @@ int main(void)
  DEFINE(VCPU_FAR_EL2,		offsetof(struct kvm_vcpu, arch.fault.far_el2));
  DEFINE(VCPU_FAR_EL2,		offsetof(struct kvm_vcpu, arch.fault.far_el2));
  DEFINE(VCPU_HPFAR_EL2,	offsetof(struct kvm_vcpu, arch.fault.hpfar_el2));
  DEFINE(VCPU_HPFAR_EL2,	offsetof(struct kvm_vcpu, arch.fault.hpfar_el2));
  DEFINE(VCPU_DEBUG_FLAGS,	offsetof(struct kvm_vcpu, arch.debug_flags));
  DEFINE(VCPU_DEBUG_FLAGS,	offsetof(struct kvm_vcpu, arch.debug_flags));
  DEFINE(VCPU_DEBUG_PTR,	offsetof(struct kvm_vcpu, arch.debug_ptr));
  DEFINE(DEBUG_BCR, 		offsetof(struct kvm_guest_debug_arch, dbg_bcr));
  DEFINE(DEBUG_BVR, 		offsetof(struct kvm_guest_debug_arch, dbg_bvr));
  DEFINE(DEBUG_WCR, 		offsetof(struct kvm_guest_debug_arch, dbg_wcr));
  DEFINE(DEBUG_WVR, 		offsetof(struct kvm_guest_debug_arch, dbg_wvr));
  DEFINE(VCPU_HCR_EL2,		offsetof(struct kvm_vcpu, arch.hcr_el2));
  DEFINE(VCPU_HCR_EL2,		offsetof(struct kvm_vcpu, arch.hcr_el2));
  DEFINE(VCPU_MDCR_EL2,	offsetof(struct kvm_vcpu, arch.mdcr_el2));
  DEFINE(VCPU_MDCR_EL2,	offsetof(struct kvm_vcpu, arch.mdcr_el2));
  DEFINE(VCPU_IRQ_LINES,	offsetof(struct kvm_vcpu, arch.irq_lines));
  DEFINE(VCPU_IRQ_LINES,	offsetof(struct kvm_vcpu, arch.irq_lines));
  DEFINE(VCPU_HOST_CONTEXT,	offsetof(struct kvm_vcpu, arch.host_cpu_context));
  DEFINE(VCPU_HOST_CONTEXT,	offsetof(struct kvm_vcpu, arch.host_cpu_context));
  DEFINE(VCPU_HOST_DEBUG_STATE, offsetof(struct kvm_vcpu, arch.host_debug_state));
  DEFINE(VCPU_TIMER_CNTV_CTL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
  DEFINE(VCPU_TIMER_CNTV_CTL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
  DEFINE(VCPU_TIMER_CNTV_CVAL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval));
  DEFINE(VCPU_TIMER_CNTV_CVAL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval));
  DEFINE(KVM_TIMER_CNTVOFF,	offsetof(struct kvm, arch.timer.cntvoff));
  DEFINE(KVM_TIMER_CNTVOFF,	offsetof(struct kvm, arch.timer.cntvoff));
Loading