All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoffer Dall <christoffer.dall@linaro.org>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>,
	kvm@vger.kernel.org, marc.zyngier@arm.com,
	jan.kiszka@siemens.com, Will Deacon <will.deacon@arm.com>,
	open list <linux-kernel@vger.kernel.org>,
	dahi@linux.vnet.ibm.com,
	Catalin Marinas <catalin.marinas@arm.com>,
	zhichao.huang@linaro.org, r65777@freescale.com,
	pbonzini@redhat.com, bp@suse.de, Gleb Natapov <gleb@kernel.org>,
	kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v3 07/12] KVM: arm64: guest debug, add support for single-step
Date: Fri, 8 May 2015 13:52:42 +0200	[thread overview]
Message-ID: <20150508115242.GG24744@cbox> (raw)
In-Reply-To: <1430929407-3487-8-git-send-email-alex.bennee@linaro.org>

On Wed, May 06, 2015 at 05:23:22PM +0100, Alex Bennée wrote:
> This adds support for single-stepping the guest. To do this we need to
> manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits which we do in the
> kvm_arm_setup/clear_debug() so we don't affect the apparent state of the
> guest. Additionally while the host is debugging the guest we suppress
> the ability of the guest to single-step itself.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> 
> ---
> v2
>   - Move pstate/mdscr manipulation into C
>   - don't export guest_debug to assembly
>   - add accessor for saved_debug regs
>   - tweak save/restore of mdscr_el1
> v3
>   - don't save PC in debug information struct
>   - rename debug_saved_regs->guest_debug_state
>   - save whole value, only use bits in restore
>   - add save/restore_guest-debug_regs helper functions
>   - simplify commit message for clarity
>   - rm vcpu_debug_saved_reg access fn
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 064c105..9b3ed6d 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -302,7 +302,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  	kvm_arm_set_running_vcpu(NULL);
>  }
>  
> -#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
> +#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |    \
> +			    KVM_GUESTDBG_USE_SW_BP | \
> +			    KVM_GUESTDBG_SINGLESTEP)
>  
>  /**
>   * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 7cb99b5..b60fa7a 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -123,6 +123,12 @@ struct kvm_vcpu_arch {
>  	 * here.
>  	 */
>  
> +	/* Guest registers we preserve during guest debugging */
> +	struct {
> +		u32	pstate;

This could do a with a comment: /* preserve SPSR_DEBUG_MASK bits */

> +		u32	mdscr_el1;
> +	} guest_debug_state;
> +
>  	/* Don't run the guest */
>  	bool pause;
>  
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 5bee676..19346e8 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -19,11 +19,42 @@
>  
>  #include <linux/kvm_host.h>
>  
> +#include <asm/debug-monitors.h>
> +#include <asm/kvm_asm.h>
>  #include <asm/kvm_arm.h>
> +#include <asm/kvm_emulate.h>
> +
> +/* These are the bits of MDSCR_EL1 we may manipulate */
> +#define MDSCR_EL1_DEBUG_MASK	(DBG_MDSCR_SS | \
> +				DBG_MDSCR_KDE | \
> +				DBG_MDSCR_MDE)
> +
> +#define SPSR_DEBUG_MASK DBG_SPSR_SS
>  
>  static DEFINE_PER_CPU(u32, mdcr_el2);
>  
>  /**
> + * 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.
> + */
> +static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
> +{
> +	vcpu->arch.guest_debug_state.pstate = *vcpu_cpsr(vcpu);
> +	vcpu->arch.guest_debug_state.mdscr_el1 = vcpu_sys_reg(vcpu, MDSCR_EL1);
> +}
> +
> +static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
> +{
> +	*vcpu_cpsr(vcpu) |=
> +		(vcpu->arch.guest_debug_state.pstate & SPSR_DEBUG_MASK);
> +	vcpu_sys_reg(vcpu, MDSCR_EL1) |=
> +		(vcpu->arch.guest_debug_state.mdscr_el1 & MDSCR_EL1_DEBUG_MASK);

This doesn't look right.  Don't you need to also clear the values if
they were set by us for single-stepping the guest?  At least for the
MDSCR_EL1.SS bit.

What if we're single-stepping through guest code that modifies the SS bits
of these register for the guest state?  Is that possible and do we capture
this somehow?

> +}
> +
> +/**
>   * kvm_arm_init_debug - grab what we need for debug
>   *
>   * Currently the sole task of this function is to retrieve the initial
> @@ -38,7 +69,6 @@ void kvm_arm_init_debug(void)
>  	__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
>  }
>  
> -
>  /**
>   * kvm_arm_setup_debug - set up debug related stuff
>   *
> @@ -75,15 +105,37 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
>  	else
>  		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA;
>  
> -	/* Trap breakpoints? */
> -	if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
> +	/* Is Guest debugging in effect? */
> +	if (vcpu->guest_debug) {

you could have just checked the field like this in the original patch,
but ok.

>  		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
> -	else
> -		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;


>  
> +		/* Save guest debug state */
> +		save_guest_debug_regs(vcpu);
> +
> +		/*
> +		 * Single Step (ARM ARM D2.12.3 The software step state
> +		 * machine)
> +		 *
> +		 * If we are doing Single Step we need to manipulate
> +		 * MDSCR_EL1.SS and PSTATE.SS. If not we need to
> +		 * suppress the guests ability to trigger single step itself.
> +		 */
> +		if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
> +			*vcpu_cpsr(vcpu) |=  DBG_SPSR_SS;
> +			vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_SS;
> +		} else {
> +			*vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;

why must we clear PSTATE.SS when we have MDSCR_EL1.SS == 0 ?

> +			vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
> +		}
> +
> +	} else {
> +		/* Debug operations can go straight to the guest */
> +		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;

still don't think you need this.

> +	}
>  }
>  
>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
>  {
> -	/* Nothing to do yet */
> +	if (vcpu->guest_debug)
> +		restore_guest_debug_regs(vcpu);
>  }
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 27f38a9..e9de13e 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -103,6 +103,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  	run->debug.arch.hsr = hsr;
>  
>  	switch (hsr >> ESR_ELx_EC_SHIFT) {
> +	case ESR_ELx_EC_SOFTSTP_LOW:
>  	case ESR_ELx_EC_BKPT32:
>  	case ESR_ELx_EC_BRK64:
>  		break;
> @@ -130,6 +131,7 @@ static exit_handle_fn arm_exit_handlers[] = {
>  	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
>  	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
>  	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
> +	[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
>  	[ESR_ELx_EC_BKPT32]	= kvm_handle_guest_debug,
>  	[ESR_ELx_EC_BRK64]	= kvm_handle_guest_debug,
>  };
> -- 
> 2.3.5
> 

Thanks,
-Christoffer

WARNING: multiple messages have this Message-ID (diff)
From: christoffer.dall@linaro.org (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 07/12] KVM: arm64: guest debug, add support for single-step
Date: Fri, 8 May 2015 13:52:42 +0200	[thread overview]
Message-ID: <20150508115242.GG24744@cbox> (raw)
In-Reply-To: <1430929407-3487-8-git-send-email-alex.bennee@linaro.org>

On Wed, May 06, 2015 at 05:23:22PM +0100, Alex Benn?e wrote:
> This adds support for single-stepping the guest. To do this we need to
> manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits which we do in the
> kvm_arm_setup/clear_debug() so we don't affect the apparent state of the
> guest. Additionally while the host is debugging the guest we suppress
> the ability of the guest to single-step itself.
> 
> Signed-off-by: Alex Benn?e <alex.bennee@linaro.org>
> 
> ---
> v2
>   - Move pstate/mdscr manipulation into C
>   - don't export guest_debug to assembly
>   - add accessor for saved_debug regs
>   - tweak save/restore of mdscr_el1
> v3
>   - don't save PC in debug information struct
>   - rename debug_saved_regs->guest_debug_state
>   - save whole value, only use bits in restore
>   - add save/restore_guest-debug_regs helper functions
>   - simplify commit message for clarity
>   - rm vcpu_debug_saved_reg access fn
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 064c105..9b3ed6d 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -302,7 +302,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  	kvm_arm_set_running_vcpu(NULL);
>  }
>  
> -#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
> +#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |    \
> +			    KVM_GUESTDBG_USE_SW_BP | \
> +			    KVM_GUESTDBG_SINGLESTEP)
>  
>  /**
>   * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 7cb99b5..b60fa7a 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -123,6 +123,12 @@ struct kvm_vcpu_arch {
>  	 * here.
>  	 */
>  
> +	/* Guest registers we preserve during guest debugging */
> +	struct {
> +		u32	pstate;

This could do a with a comment: /* preserve SPSR_DEBUG_MASK bits */

> +		u32	mdscr_el1;
> +	} guest_debug_state;
> +
>  	/* Don't run the guest */
>  	bool pause;
>  
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 5bee676..19346e8 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -19,11 +19,42 @@
>  
>  #include <linux/kvm_host.h>
>  
> +#include <asm/debug-monitors.h>
> +#include <asm/kvm_asm.h>
>  #include <asm/kvm_arm.h>
> +#include <asm/kvm_emulate.h>
> +
> +/* These are the bits of MDSCR_EL1 we may manipulate */
> +#define MDSCR_EL1_DEBUG_MASK	(DBG_MDSCR_SS | \
> +				DBG_MDSCR_KDE | \
> +				DBG_MDSCR_MDE)
> +
> +#define SPSR_DEBUG_MASK DBG_SPSR_SS
>  
>  static DEFINE_PER_CPU(u32, mdcr_el2);
>  
>  /**
> + * 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.
> + */
> +static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
> +{
> +	vcpu->arch.guest_debug_state.pstate = *vcpu_cpsr(vcpu);
> +	vcpu->arch.guest_debug_state.mdscr_el1 = vcpu_sys_reg(vcpu, MDSCR_EL1);
> +}
> +
> +static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
> +{
> +	*vcpu_cpsr(vcpu) |=
> +		(vcpu->arch.guest_debug_state.pstate & SPSR_DEBUG_MASK);
> +	vcpu_sys_reg(vcpu, MDSCR_EL1) |=
> +		(vcpu->arch.guest_debug_state.mdscr_el1 & MDSCR_EL1_DEBUG_MASK);

This doesn't look right.  Don't you need to also clear the values if
they were set by us for single-stepping the guest?  At least for the
MDSCR_EL1.SS bit.

What if we're single-stepping through guest code that modifies the SS bits
of these register for the guest state?  Is that possible and do we capture
this somehow?

> +}
> +
> +/**
>   * kvm_arm_init_debug - grab what we need for debug
>   *
>   * Currently the sole task of this function is to retrieve the initial
> @@ -38,7 +69,6 @@ void kvm_arm_init_debug(void)
>  	__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
>  }
>  
> -
>  /**
>   * kvm_arm_setup_debug - set up debug related stuff
>   *
> @@ -75,15 +105,37 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
>  	else
>  		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA;
>  
> -	/* Trap breakpoints? */
> -	if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
> +	/* Is Guest debugging in effect? */
> +	if (vcpu->guest_debug) {

you could have just checked the field like this in the original patch,
but ok.

>  		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
> -	else
> -		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;


>  
> +		/* Save guest debug state */
> +		save_guest_debug_regs(vcpu);
> +
> +		/*
> +		 * Single Step (ARM ARM D2.12.3 The software step state
> +		 * machine)
> +		 *
> +		 * If we are doing Single Step we need to manipulate
> +		 * MDSCR_EL1.SS and PSTATE.SS. If not we need to
> +		 * suppress the guests ability to trigger single step itself.
> +		 */
> +		if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
> +			*vcpu_cpsr(vcpu) |=  DBG_SPSR_SS;
> +			vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_SS;
> +		} else {
> +			*vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;

why must we clear PSTATE.SS when we have MDSCR_EL1.SS == 0 ?

> +			vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
> +		}
> +
> +	} else {
> +		/* Debug operations can go straight to the guest */
> +		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;

still don't think you need this.

> +	}
>  }
>  
>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
>  {
> -	/* Nothing to do yet */
> +	if (vcpu->guest_debug)
> +		restore_guest_debug_regs(vcpu);
>  }
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 27f38a9..e9de13e 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -103,6 +103,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  	run->debug.arch.hsr = hsr;
>  
>  	switch (hsr >> ESR_ELx_EC_SHIFT) {
> +	case ESR_ELx_EC_SOFTSTP_LOW:
>  	case ESR_ELx_EC_BKPT32:
>  	case ESR_ELx_EC_BRK64:
>  		break;
> @@ -130,6 +131,7 @@ static exit_handle_fn arm_exit_handlers[] = {
>  	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
>  	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
>  	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
> +	[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
>  	[ESR_ELx_EC_BKPT32]	= kvm_handle_guest_debug,
>  	[ESR_ELx_EC_BRK64]	= kvm_handle_guest_debug,
>  };
> -- 
> 2.3.5
> 

Thanks,
-Christoffer

WARNING: multiple messages have this Message-ID (diff)
From: Christoffer Dall <christoffer.dall@linaro.org>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, marc.zyngier@arm.com,
	peter.maydell@linaro.org, agraf@suse.de, drjones@redhat.com,
	pbonzini@redhat.com, zhichao.huang@linaro.org,
	jan.kiszka@siemens.com, dahi@linux.vnet.ibm.com,
	r65777@freescale.com, bp@suse.de, Gleb Natapov <gleb@kernel.org>,
	Russell King <linux@arm.linux.org.uk>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will.deacon@arm.com>,
	open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3 07/12] KVM: arm64: guest debug, add support for single-step
Date: Fri, 8 May 2015 13:52:42 +0200	[thread overview]
Message-ID: <20150508115242.GG24744@cbox> (raw)
In-Reply-To: <1430929407-3487-8-git-send-email-alex.bennee@linaro.org>

On Wed, May 06, 2015 at 05:23:22PM +0100, Alex Bennée wrote:
> This adds support for single-stepping the guest. To do this we need to
> manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits which we do in the
> kvm_arm_setup/clear_debug() so we don't affect the apparent state of the
> guest. Additionally while the host is debugging the guest we suppress
> the ability of the guest to single-step itself.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> 
> ---
> v2
>   - Move pstate/mdscr manipulation into C
>   - don't export guest_debug to assembly
>   - add accessor for saved_debug regs
>   - tweak save/restore of mdscr_el1
> v3
>   - don't save PC in debug information struct
>   - rename debug_saved_regs->guest_debug_state
>   - save whole value, only use bits in restore
>   - add save/restore_guest-debug_regs helper functions
>   - simplify commit message for clarity
>   - rm vcpu_debug_saved_reg access fn
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 064c105..9b3ed6d 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -302,7 +302,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  	kvm_arm_set_running_vcpu(NULL);
>  }
>  
> -#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
> +#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |    \
> +			    KVM_GUESTDBG_USE_SW_BP | \
> +			    KVM_GUESTDBG_SINGLESTEP)
>  
>  /**
>   * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 7cb99b5..b60fa7a 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -123,6 +123,12 @@ struct kvm_vcpu_arch {
>  	 * here.
>  	 */
>  
> +	/* Guest registers we preserve during guest debugging */
> +	struct {
> +		u32	pstate;

This could do a with a comment: /* preserve SPSR_DEBUG_MASK bits */

> +		u32	mdscr_el1;
> +	} guest_debug_state;
> +
>  	/* Don't run the guest */
>  	bool pause;
>  
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 5bee676..19346e8 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -19,11 +19,42 @@
>  
>  #include <linux/kvm_host.h>
>  
> +#include <asm/debug-monitors.h>
> +#include <asm/kvm_asm.h>
>  #include <asm/kvm_arm.h>
> +#include <asm/kvm_emulate.h>
> +
> +/* These are the bits of MDSCR_EL1 we may manipulate */
> +#define MDSCR_EL1_DEBUG_MASK	(DBG_MDSCR_SS | \
> +				DBG_MDSCR_KDE | \
> +				DBG_MDSCR_MDE)
> +
> +#define SPSR_DEBUG_MASK DBG_SPSR_SS
>  
>  static DEFINE_PER_CPU(u32, mdcr_el2);
>  
>  /**
> + * 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.
> + */
> +static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
> +{
> +	vcpu->arch.guest_debug_state.pstate = *vcpu_cpsr(vcpu);
> +	vcpu->arch.guest_debug_state.mdscr_el1 = vcpu_sys_reg(vcpu, MDSCR_EL1);
> +}
> +
> +static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
> +{
> +	*vcpu_cpsr(vcpu) |=
> +		(vcpu->arch.guest_debug_state.pstate & SPSR_DEBUG_MASK);
> +	vcpu_sys_reg(vcpu, MDSCR_EL1) |=
> +		(vcpu->arch.guest_debug_state.mdscr_el1 & MDSCR_EL1_DEBUG_MASK);

This doesn't look right.  Don't you need to also clear the values if
they were set by us for single-stepping the guest?  At least for the
MDSCR_EL1.SS bit.

What if we're single-stepping through guest code that modifies the SS bits
of these register for the guest state?  Is that possible and do we capture
this somehow?

> +}
> +
> +/**
>   * kvm_arm_init_debug - grab what we need for debug
>   *
>   * Currently the sole task of this function is to retrieve the initial
> @@ -38,7 +69,6 @@ void kvm_arm_init_debug(void)
>  	__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
>  }
>  
> -
>  /**
>   * kvm_arm_setup_debug - set up debug related stuff
>   *
> @@ -75,15 +105,37 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
>  	else
>  		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA;
>  
> -	/* Trap breakpoints? */
> -	if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
> +	/* Is Guest debugging in effect? */
> +	if (vcpu->guest_debug) {

you could have just checked the field like this in the original patch,
but ok.

>  		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
> -	else
> -		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;


>  
> +		/* Save guest debug state */
> +		save_guest_debug_regs(vcpu);
> +
> +		/*
> +		 * Single Step (ARM ARM D2.12.3 The software step state
> +		 * machine)
> +		 *
> +		 * If we are doing Single Step we need to manipulate
> +		 * MDSCR_EL1.SS and PSTATE.SS. If not we need to
> +		 * suppress the guests ability to trigger single step itself.
> +		 */
> +		if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
> +			*vcpu_cpsr(vcpu) |=  DBG_SPSR_SS;
> +			vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_SS;
> +		} else {
> +			*vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;

why must we clear PSTATE.SS when we have MDSCR_EL1.SS == 0 ?

> +			vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
> +		}
> +
> +	} else {
> +		/* Debug operations can go straight to the guest */
> +		vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;

still don't think you need this.

> +	}
>  }
>  
>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
>  {
> -	/* Nothing to do yet */
> +	if (vcpu->guest_debug)
> +		restore_guest_debug_regs(vcpu);
>  }
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 27f38a9..e9de13e 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -103,6 +103,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  	run->debug.arch.hsr = hsr;
>  
>  	switch (hsr >> ESR_ELx_EC_SHIFT) {
> +	case ESR_ELx_EC_SOFTSTP_LOW:
>  	case ESR_ELx_EC_BKPT32:
>  	case ESR_ELx_EC_BRK64:
>  		break;
> @@ -130,6 +131,7 @@ static exit_handle_fn arm_exit_handlers[] = {
>  	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
>  	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
>  	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
> +	[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
>  	[ESR_ELx_EC_BKPT32]	= kvm_handle_guest_debug,
>  	[ESR_ELx_EC_BRK64]	= kvm_handle_guest_debug,
>  };
> -- 
> 2.3.5
> 

Thanks,
-Christoffer

  reply	other threads:[~2015-05-08 11:43 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-06 16:23 [PATCH v3 00/12] KVM Guest Debug support for arm64 Alex Bennée
2015-05-06 16:23 ` Alex Bennée
2015-05-06 16:23 ` [PATCH v3 01/12] KVM: add comments for kvm_debug_exit_arch struct Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-08  9:19   ` Christoffer Dall
2015-05-08  9:19     ` Christoffer Dall
2015-05-06 16:23 ` [PATCH v3 02/12] KVM: define common __KVM_GUESTDBG_USE_SW/HW_BP values Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
     [not found]   ` <1430929407-3487-3-git-send-email-alex.bennee-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-05-08  9:23     ` Christoffer Dall
2015-05-08  9:23       ` Christoffer Dall
2015-05-08  9:23       ` Christoffer Dall
2015-05-08  9:23       ` Christoffer Dall
2015-05-08  9:23       ` Christoffer Dall
2015-05-08 11:09       ` Paolo Bonzini
2015-05-08 11:09         ` Paolo Bonzini
2015-05-08 11:09         ` Paolo Bonzini
2015-05-06 16:23 ` [PATCH v3 03/12] KVM: arm64: guest debug, define API headers Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-08  9:28   ` Christoffer Dall
2015-05-08  9:28     ` Christoffer Dall
2015-05-06 16:23 ` [PATCH v3 04/12] KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-08 11:52   ` Christoffer Dall
2015-05-08 11:52     ` Christoffer Dall
2015-05-06 16:23 ` [PATCH v3 05/12] KVM: arm: introduce kvm_arm_init/setup/clear_debug Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-08 11:52   ` Christoffer Dall
2015-05-08 11:52     ` Christoffer Dall
2015-05-08 11:52     ` Christoffer Dall
2015-05-06 16:23 ` [PATCH v3 06/12] KVM: arm64: guest debug, add SW break point support Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-08 11:52   ` Christoffer Dall
2015-05-08 11:52     ` Christoffer Dall
2015-05-08 11:52     ` Christoffer Dall
2015-05-06 16:23 ` [PATCH v3 07/12] KVM: arm64: guest debug, add support for single-step Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-06 16:23   ` Alex Bennée
2015-05-08 11:52   ` Christoffer Dall [this message]
2015-05-08 11:52     ` Christoffer Dall
2015-05-08 11:52     ` Christoffer Dall
2015-05-07  9:07 ` [PATCH v3 08/12] KVM: arm64: re-factor hyp.S debug register code Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-08 14:12   ` Christoffer Dall
2015-05-08 14:12     ` Christoffer Dall
2015-05-08 14:12     ` Christoffer Dall
2015-05-07  9:07 ` [PATCH v3 09/12] KVM: arm64: guest debug, HW assisted debug support Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-07  9:07   ` Alex Bennée
     [not found]   ` <1430989647-22501-2-git-send-email-alex.bennee-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-05-08 16:32     ` Christoffer Dall
2015-05-08 16:32       ` Christoffer Dall
2015-05-08 16:32       ` Christoffer Dall
2015-05-08 16:32       ` Christoffer Dall
2015-05-07  9:07 ` [PATCH v3 10/12] KVM: arm64: trap nested debug register access Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-08 16:46   ` Christoffer Dall
2015-05-08 16:46     ` Christoffer Dall
2015-05-08 16:46     ` Christoffer Dall
2015-05-07  9:07 ` [PATCH v3 11/12] KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-08 17:21   ` Christoffer Dall
2015-05-08 17:21     ` Christoffer Dall
2015-05-07  9:07 ` [PATCH v3 12/12] KVM: arm64: add trace points for guest_debug debug Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-07  9:07   ` Alex Bennée
2015-05-08 17:25   ` Christoffer Dall
2015-05-08 17:25     ` Christoffer Dall
2015-05-08 17:25     ` Christoffer Dall
2015-05-08 16:33 ` [PATCH v3 00/12] KVM Guest Debug support for arm64 Christoffer Dall
2015-05-08 16:33   ` Christoffer Dall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150508115242.GG24744@cbox \
    --to=christoffer.dall@linaro.org \
    --cc=alex.bennee@linaro.org \
    --cc=bp@suse.de \
    --cc=catalin.marinas@arm.com \
    --cc=dahi@linux.vnet.ibm.com \
    --cc=gleb@kernel.org \
    --cc=jan.kiszka@siemens.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=marc.zyngier@arm.com \
    --cc=pbonzini@redhat.com \
    --cc=r65777@freescale.com \
    --cc=will.deacon@arm.com \
    --cc=zhichao.huang@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.