All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christophe Leroy <christophe.leroy@c-s.fr>
To: Ravi Bangoria <ravi.bangoria@linux.ibm.com>,
	mpe@ellerman.id.au, mikey@neuling.org
Cc: apopple@linux.ibm.com, paulus@samba.org, npiggin@gmail.com,
	naveen.n.rao@linux.vnet.ibm.com, peterz@infradead.org,
	jolsa@kernel.org, oleg@redhat.com, fweisbec@gmail.com,
	mingo@kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 09/16] powerpc/watchpoint: Convert thread_struct->hw_brk to an array
Date: Wed, 1 Apr 2020 08:43:57 +0200	[thread overview]
Message-ID: <e5af5ed7-b9df-e334-1bdb-e7f82ae32697@c-s.fr> (raw)
In-Reply-To: <20200401061309.92442-10-ravi.bangoria@linux.ibm.com>



Le 01/04/2020 à 08:13, Ravi Bangoria a écrit :
> So far powerpc hw supported only one watchpoint. But Future Power
> architecture is introducing 2nd DAWR. Convert thread_struct->hw_brk
> into an array.
> 
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
> ---
>   arch/powerpc/include/asm/processor.h      |  2 +-
>   arch/powerpc/kernel/process.c             | 61 ++++++++++++++---------
>   arch/powerpc/kernel/ptrace/ptrace-noadv.c | 40 +++++++++++----
>   arch/powerpc/kernel/ptrace/ptrace32.c     |  4 +-
>   arch/powerpc/kernel/signal.c              |  9 +++-
>   5 files changed, 77 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
> index 90f6dbc7ff00..65b03162cd67 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -187,7 +187,7 @@ struct thread_struct {
>   	 */
>   	struct perf_event *last_hit_ubp;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
> -	struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
> +	struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint info */
>   	unsigned long	trap_nr;	/* last trap # on this thread */
>   	u8 load_slb;			/* Ages out SLB preload cache entries */
>   	u8 load_fp;
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index e0275fcd0c55..f5b4f21e822b 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -704,21 +704,50 @@ void switch_booke_debug_regs(struct debug_reg *new_debug)
>   EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
>   #else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
>   #ifndef CONFIG_HAVE_HW_BREAKPOINT
> -static void set_breakpoint(struct arch_hw_breakpoint *brk)
> +static void set_breakpoint(struct arch_hw_breakpoint *brk, int i)
>   {
>   	preempt_disable();
> -	__set_breakpoint(brk, 0);
> +	__set_breakpoint(brk, i);
>   	preempt_enable();
>   }
>   
>   static void set_debug_reg_defaults(struct thread_struct *thread)
>   {
> -	thread->hw_brk.address = 0;
> -	thread->hw_brk.type = 0;
> -	thread->hw_brk.len = 0;
> -	thread->hw_brk.hw_len = 0;
> -	if (ppc_breakpoint_available())
> -		set_breakpoint(&thread->hw_brk);
> +	int i;
> +
> +	for (i = 0; i < nr_wp_slots(); i++) {

Maybe you could add the following that you added other places:

	struct arch_hw_breakpoint null_brk = {0};

Then do

	thread->hw_brk[i] = null_brk;

> +		thread->hw_brk[i].address = 0;
> +		thread->hw_brk[i].type = 0;
> +		thread->hw_brk[i].len = 0;
> +		thread->hw_brk[i].hw_len = 0;
> +		if (ppc_breakpoint_available())
> +			set_breakpoint(&thread->hw_brk[i], i);
> +	}
> +}
> +
> +static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
> +				struct arch_hw_breakpoint *b)
> +{
> +	if (a->address != b->address)
> +		return false;
> +	if (a->type != b->type)
> +		return false;
> +	if (a->len != b->len)
> +		return false;
> +	/* no need to check hw_len. it's calculated from address and len */
> +	return true;
> +}
> +
> +static void switch_hw_breakpoint(struct task_struct *new)
> +{
> +	int i;
> +
> +	for (i = 0; i < nr_wp_slots(); i++) {
> +		if (unlikely(!hw_brk_match(this_cpu_ptr(&current_brk[i]),
> +					   &new->thread.hw_brk[i]))) {
> +			__set_breakpoint(&new->thread.hw_brk[i], i);
> +		}

Or could be:

		if (likely(hw_brk_match(this_cpu_ptr(&current_brk[i]),
					&new->thread.hw_brk[i])))
			continue;
		__set_breakpoint(&new->thread.hw_brk[i], i);


> +	}
>   }
>   #endif /* !CONFIG_HAVE_HW_BREAKPOINT */
>   #endif	/* CONFIG_PPC_ADV_DEBUG_REGS */
> @@ -822,19 +851,6 @@ bool ppc_breakpoint_available(void)
>   }
>   EXPORT_SYMBOL_GPL(ppc_breakpoint_available);
>   
> -static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
> -			      struct arch_hw_breakpoint *b)
> -{
> -	if (a->address != b->address)
> -		return false;
> -	if (a->type != b->type)
> -		return false;
> -	if (a->len != b->len)
> -		return false;
> -	/* no need to check hw_len. it's calculated from address and len */
> -	return true;
> -}
> -
>   #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
>   
>   static inline bool tm_enabled(struct task_struct *tsk)
> @@ -1167,8 +1183,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
>    * schedule DABR
>    */
>   #ifndef CONFIG_HAVE_HW_BREAKPOINT
> -	if (unlikely(!hw_brk_match(this_cpu_ptr(&current_brk[0]), &new->thread.hw_brk)))
> -		__set_breakpoint(&new->thread.hw_brk, 0);
> +	switch_hw_breakpoint(new);
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
>   #endif
>   
> diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
> index 12962302d6a4..0dbb35392dd2 100644
> --- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
> +++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
> @@ -67,11 +67,16 @@ int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
>   	/* We only support one DABR and no IABRS at the moment */
>   	if (addr > 0)
>   		return -EINVAL;
> -	dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
> -		     (child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
> +	dabr_fake = ((child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) |
> +		     (child->thread.hw_brk[0].type & HW_BRK_TYPE_DABR));
>   	return put_user(dabr_fake, datalp);
>   }
>   
> +/*
> + * ptrace_set_debugreg() fakes DABR and DABR is only one. So even if
> + * internal hw supports more than one watchpoint, we support only one
> + * watchpoint with this interface.
> + */
>   int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data)
>   {
>   #ifdef CONFIG_HAVE_HW_BREAKPOINT
> @@ -137,7 +142,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned l
>   			return ret;
>   
>   		thread->ptrace_bps[0] = bp;
> -		thread->hw_brk = hw_brk;
> +		thread->hw_brk[0] = hw_brk;
>   		return 0;
>   	}
>   
> @@ -159,12 +164,24 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned l
>   	if (set_bp && (!ppc_breakpoint_available()))
>   		return -ENODEV;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
> -	task->thread.hw_brk = hw_brk;
> +	task->thread.hw_brk[0] = hw_brk;
>   	return 0;
>   }
>   
> +static int find_empty_hw_brk(struct thread_struct *thread)
> +{
> +	int i;
> +
> +	for (i = 0; i < nr_wp_slots(); i++) {
> +		if (!thread->hw_brk[i].address)
> +			return i;
> +	}
> +	return -1;
> +}
> +
>   long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
>   {
> +	int i;
>   #ifdef CONFIG_HAVE_HW_BREAKPOINT
>   	int len = 0;
>   	struct thread_struct *thread = &child->thread;
> @@ -223,15 +240,16 @@ long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_inf
>   	if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
>   		return -EINVAL;
>   
> -	if (child->thread.hw_brk.address)
> +	i = find_empty_hw_brk(&child->thread);
> +	if (i < 0)
>   		return -ENOSPC;
>   
>   	if (!ppc_breakpoint_available())
>   		return -ENODEV;
>   
> -	child->thread.hw_brk = brk;
> +	child->thread.hw_brk[i] = brk;
>   
> -	return 1;
> +	return i + 1;
>   }
>   
>   long ppc_del_hwdebug(struct task_struct *child, long data)
> @@ -241,7 +259,7 @@ long ppc_del_hwdebug(struct task_struct *child, long data)
>   	struct thread_struct *thread = &child->thread;
>   	struct perf_event *bp;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
> -	if (data != 1)
> +	if (data < 1 || data > nr_wp_slots())
>   		return -EINVAL;
>   
>   #ifdef CONFIG_HAVE_HW_BREAKPOINT
> @@ -254,11 +272,11 @@ long ppc_del_hwdebug(struct task_struct *child, long data)
>   	}
>   	return ret;
>   #else /* CONFIG_HAVE_HW_BREAKPOINT */
> -	if (child->thread.hw_brk.address == 0)
> +	if (child->thread.hw_brk[data - 1].address == 0)
>   		return -ENOENT;
>   
> -	child->thread.hw_brk.address = 0;
> -	child->thread.hw_brk.type = 0;
> +	child->thread.hw_brk[data - 1].address = 0;
> +	child->thread.hw_brk[data - 1].type = 0;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
>   
>   	return 0;
> diff --git a/arch/powerpc/kernel/ptrace/ptrace32.c b/arch/powerpc/kernel/ptrace/ptrace32.c
> index 7976ddf29c0e..7589a9665ffb 100644
> --- a/arch/powerpc/kernel/ptrace/ptrace32.c
> +++ b/arch/powerpc/kernel/ptrace/ptrace32.c
> @@ -259,8 +259,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
>   		ret = put_user(child->thread.debug.dac1, (u32 __user *)data);
>   #else
>   		dabr_fake = (
> -			(child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
> -			(child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
> +			(child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) |
> +			(child->thread.hw_brk[0].type & HW_BRK_TYPE_DABR));
>   		ret = put_user(dabr_fake, (u32 __user *)data);
>   #endif
>   		break;
> diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
> index bbf237f072d4..b559b114d03d 100644
> --- a/arch/powerpc/kernel/signal.c
> +++ b/arch/powerpc/kernel/signal.c
> @@ -107,6 +107,9 @@ static void do_signal(struct task_struct *tsk)
>   	struct ksignal ksig = { .sig = 0 };
>   	int ret;
>   	int is32 = is_32bit_task();
> +#ifndef CONFIG_PPC_ADV_DEBUG_REGS
> +	int i;
> +#endif >
>   	BUG_ON(tsk != current);
>   
> @@ -128,8 +131,10 @@ static void do_signal(struct task_struct *tsk)
>   	 * user space. The DABR will have been cleared if it
>   	 * triggered inside the kernel.
>   	 */
> -	if (tsk->thread.hw_brk.address && tsk->thread.hw_brk.type)
> -		__set_breakpoint(&tsk->thread.hw_brk, 0);
> +	for (i = 0; i < nr_wp_slots(); i++) {
> +		if (tsk->thread.hw_brk[i].address && tsk->thread.hw_brk[i].type)
> +			__set_breakpoint(&tsk->thread.hw_brk[i], i);
> +	}

thread.hwbrk also exists when CONFIG_PPC_ADV_DEBUG_REGS is selected.

You could replace the #ifndef CONFIG_PPC_ADV_DEBUG_REGS by an if 
(!IS_ENABLED(CONFIG_PPC_ADV_DEBUG_REGS)) and then no need of an ifdef 
when declaring the int i;

>   #endif
>   	/* Re-enable the breakpoints for the signal stack */
>   	thread_change_pc(tsk, tsk->thread.regs);
> 

Christophe

WARNING: multiple messages have this Message-ID (diff)
From: Christophe Leroy <christophe.leroy@c-s.fr>
To: Ravi Bangoria <ravi.bangoria@linux.ibm.com>,
	mpe@ellerman.id.au, mikey@neuling.org
Cc: apopple@linux.ibm.com, peterz@infradead.org, fweisbec@gmail.com,
	oleg@redhat.com, npiggin@gmail.com, linux-kernel@vger.kernel.org,
	paulus@samba.org, jolsa@kernel.org,
	naveen.n.rao@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org,
	mingo@kernel.org
Subject: Re: [PATCH v2 09/16] powerpc/watchpoint: Convert thread_struct->hw_brk to an array
Date: Wed, 1 Apr 2020 08:43:57 +0200	[thread overview]
Message-ID: <e5af5ed7-b9df-e334-1bdb-e7f82ae32697@c-s.fr> (raw)
In-Reply-To: <20200401061309.92442-10-ravi.bangoria@linux.ibm.com>



Le 01/04/2020 à 08:13, Ravi Bangoria a écrit :
> So far powerpc hw supported only one watchpoint. But Future Power
> architecture is introducing 2nd DAWR. Convert thread_struct->hw_brk
> into an array.
> 
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
> ---
>   arch/powerpc/include/asm/processor.h      |  2 +-
>   arch/powerpc/kernel/process.c             | 61 ++++++++++++++---------
>   arch/powerpc/kernel/ptrace/ptrace-noadv.c | 40 +++++++++++----
>   arch/powerpc/kernel/ptrace/ptrace32.c     |  4 +-
>   arch/powerpc/kernel/signal.c              |  9 +++-
>   5 files changed, 77 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
> index 90f6dbc7ff00..65b03162cd67 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -187,7 +187,7 @@ struct thread_struct {
>   	 */
>   	struct perf_event *last_hit_ubp;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
> -	struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
> +	struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint info */
>   	unsigned long	trap_nr;	/* last trap # on this thread */
>   	u8 load_slb;			/* Ages out SLB preload cache entries */
>   	u8 load_fp;
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index e0275fcd0c55..f5b4f21e822b 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -704,21 +704,50 @@ void switch_booke_debug_regs(struct debug_reg *new_debug)
>   EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
>   #else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
>   #ifndef CONFIG_HAVE_HW_BREAKPOINT
> -static void set_breakpoint(struct arch_hw_breakpoint *brk)
> +static void set_breakpoint(struct arch_hw_breakpoint *brk, int i)
>   {
>   	preempt_disable();
> -	__set_breakpoint(brk, 0);
> +	__set_breakpoint(brk, i);
>   	preempt_enable();
>   }
>   
>   static void set_debug_reg_defaults(struct thread_struct *thread)
>   {
> -	thread->hw_brk.address = 0;
> -	thread->hw_brk.type = 0;
> -	thread->hw_brk.len = 0;
> -	thread->hw_brk.hw_len = 0;
> -	if (ppc_breakpoint_available())
> -		set_breakpoint(&thread->hw_brk);
> +	int i;
> +
> +	for (i = 0; i < nr_wp_slots(); i++) {

Maybe you could add the following that you added other places:

	struct arch_hw_breakpoint null_brk = {0};

Then do

	thread->hw_brk[i] = null_brk;

> +		thread->hw_brk[i].address = 0;
> +		thread->hw_brk[i].type = 0;
> +		thread->hw_brk[i].len = 0;
> +		thread->hw_brk[i].hw_len = 0;
> +		if (ppc_breakpoint_available())
> +			set_breakpoint(&thread->hw_brk[i], i);
> +	}
> +}
> +
> +static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
> +				struct arch_hw_breakpoint *b)
> +{
> +	if (a->address != b->address)
> +		return false;
> +	if (a->type != b->type)
> +		return false;
> +	if (a->len != b->len)
> +		return false;
> +	/* no need to check hw_len. it's calculated from address and len */
> +	return true;
> +}
> +
> +static void switch_hw_breakpoint(struct task_struct *new)
> +{
> +	int i;
> +
> +	for (i = 0; i < nr_wp_slots(); i++) {
> +		if (unlikely(!hw_brk_match(this_cpu_ptr(&current_brk[i]),
> +					   &new->thread.hw_brk[i]))) {
> +			__set_breakpoint(&new->thread.hw_brk[i], i);
> +		}

Or could be:

		if (likely(hw_brk_match(this_cpu_ptr(&current_brk[i]),
					&new->thread.hw_brk[i])))
			continue;
		__set_breakpoint(&new->thread.hw_brk[i], i);


> +	}
>   }
>   #endif /* !CONFIG_HAVE_HW_BREAKPOINT */
>   #endif	/* CONFIG_PPC_ADV_DEBUG_REGS */
> @@ -822,19 +851,6 @@ bool ppc_breakpoint_available(void)
>   }
>   EXPORT_SYMBOL_GPL(ppc_breakpoint_available);
>   
> -static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
> -			      struct arch_hw_breakpoint *b)
> -{
> -	if (a->address != b->address)
> -		return false;
> -	if (a->type != b->type)
> -		return false;
> -	if (a->len != b->len)
> -		return false;
> -	/* no need to check hw_len. it's calculated from address and len */
> -	return true;
> -}
> -
>   #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
>   
>   static inline bool tm_enabled(struct task_struct *tsk)
> @@ -1167,8 +1183,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
>    * schedule DABR
>    */
>   #ifndef CONFIG_HAVE_HW_BREAKPOINT
> -	if (unlikely(!hw_brk_match(this_cpu_ptr(&current_brk[0]), &new->thread.hw_brk)))
> -		__set_breakpoint(&new->thread.hw_brk, 0);
> +	switch_hw_breakpoint(new);
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
>   #endif
>   
> diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
> index 12962302d6a4..0dbb35392dd2 100644
> --- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
> +++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
> @@ -67,11 +67,16 @@ int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
>   	/* We only support one DABR and no IABRS at the moment */
>   	if (addr > 0)
>   		return -EINVAL;
> -	dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
> -		     (child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
> +	dabr_fake = ((child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) |
> +		     (child->thread.hw_brk[0].type & HW_BRK_TYPE_DABR));
>   	return put_user(dabr_fake, datalp);
>   }
>   
> +/*
> + * ptrace_set_debugreg() fakes DABR and DABR is only one. So even if
> + * internal hw supports more than one watchpoint, we support only one
> + * watchpoint with this interface.
> + */
>   int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data)
>   {
>   #ifdef CONFIG_HAVE_HW_BREAKPOINT
> @@ -137,7 +142,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned l
>   			return ret;
>   
>   		thread->ptrace_bps[0] = bp;
> -		thread->hw_brk = hw_brk;
> +		thread->hw_brk[0] = hw_brk;
>   		return 0;
>   	}
>   
> @@ -159,12 +164,24 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned l
>   	if (set_bp && (!ppc_breakpoint_available()))
>   		return -ENODEV;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
> -	task->thread.hw_brk = hw_brk;
> +	task->thread.hw_brk[0] = hw_brk;
>   	return 0;
>   }
>   
> +static int find_empty_hw_brk(struct thread_struct *thread)
> +{
> +	int i;
> +
> +	for (i = 0; i < nr_wp_slots(); i++) {
> +		if (!thread->hw_brk[i].address)
> +			return i;
> +	}
> +	return -1;
> +}
> +
>   long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
>   {
> +	int i;
>   #ifdef CONFIG_HAVE_HW_BREAKPOINT
>   	int len = 0;
>   	struct thread_struct *thread = &child->thread;
> @@ -223,15 +240,16 @@ long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_inf
>   	if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
>   		return -EINVAL;
>   
> -	if (child->thread.hw_brk.address)
> +	i = find_empty_hw_brk(&child->thread);
> +	if (i < 0)
>   		return -ENOSPC;
>   
>   	if (!ppc_breakpoint_available())
>   		return -ENODEV;
>   
> -	child->thread.hw_brk = brk;
> +	child->thread.hw_brk[i] = brk;
>   
> -	return 1;
> +	return i + 1;
>   }
>   
>   long ppc_del_hwdebug(struct task_struct *child, long data)
> @@ -241,7 +259,7 @@ long ppc_del_hwdebug(struct task_struct *child, long data)
>   	struct thread_struct *thread = &child->thread;
>   	struct perf_event *bp;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
> -	if (data != 1)
> +	if (data < 1 || data > nr_wp_slots())
>   		return -EINVAL;
>   
>   #ifdef CONFIG_HAVE_HW_BREAKPOINT
> @@ -254,11 +272,11 @@ long ppc_del_hwdebug(struct task_struct *child, long data)
>   	}
>   	return ret;
>   #else /* CONFIG_HAVE_HW_BREAKPOINT */
> -	if (child->thread.hw_brk.address == 0)
> +	if (child->thread.hw_brk[data - 1].address == 0)
>   		return -ENOENT;
>   
> -	child->thread.hw_brk.address = 0;
> -	child->thread.hw_brk.type = 0;
> +	child->thread.hw_brk[data - 1].address = 0;
> +	child->thread.hw_brk[data - 1].type = 0;
>   #endif /* CONFIG_HAVE_HW_BREAKPOINT */
>   
>   	return 0;
> diff --git a/arch/powerpc/kernel/ptrace/ptrace32.c b/arch/powerpc/kernel/ptrace/ptrace32.c
> index 7976ddf29c0e..7589a9665ffb 100644
> --- a/arch/powerpc/kernel/ptrace/ptrace32.c
> +++ b/arch/powerpc/kernel/ptrace/ptrace32.c
> @@ -259,8 +259,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
>   		ret = put_user(child->thread.debug.dac1, (u32 __user *)data);
>   #else
>   		dabr_fake = (
> -			(child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
> -			(child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
> +			(child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) |
> +			(child->thread.hw_brk[0].type & HW_BRK_TYPE_DABR));
>   		ret = put_user(dabr_fake, (u32 __user *)data);
>   #endif
>   		break;
> diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
> index bbf237f072d4..b559b114d03d 100644
> --- a/arch/powerpc/kernel/signal.c
> +++ b/arch/powerpc/kernel/signal.c
> @@ -107,6 +107,9 @@ static void do_signal(struct task_struct *tsk)
>   	struct ksignal ksig = { .sig = 0 };
>   	int ret;
>   	int is32 = is_32bit_task();
> +#ifndef CONFIG_PPC_ADV_DEBUG_REGS
> +	int i;
> +#endif >
>   	BUG_ON(tsk != current);
>   
> @@ -128,8 +131,10 @@ static void do_signal(struct task_struct *tsk)
>   	 * user space. The DABR will have been cleared if it
>   	 * triggered inside the kernel.
>   	 */
> -	if (tsk->thread.hw_brk.address && tsk->thread.hw_brk.type)
> -		__set_breakpoint(&tsk->thread.hw_brk, 0);
> +	for (i = 0; i < nr_wp_slots(); i++) {
> +		if (tsk->thread.hw_brk[i].address && tsk->thread.hw_brk[i].type)
> +			__set_breakpoint(&tsk->thread.hw_brk[i], i);
> +	}

thread.hwbrk also exists when CONFIG_PPC_ADV_DEBUG_REGS is selected.

You could replace the #ifndef CONFIG_PPC_ADV_DEBUG_REGS by an if 
(!IS_ENABLED(CONFIG_PPC_ADV_DEBUG_REGS)) and then no need of an ifdef 
when declaring the int i;

>   #endif
>   	/* Re-enable the breakpoints for the signal stack */
>   	thread_change_pc(tsk, tsk->thread.regs);
> 

Christophe

  reply	other threads:[~2020-04-01  6:44 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-01  6:12 [PATCH v2 00/16] powerpc/watchpoint: Preparation for more than one watchpoint Ravi Bangoria
2020-04-01  6:12 ` Ravi Bangoria
2020-04-01  6:12 ` [PATCH v2 01/16] powerpc/watchpoint: Rename current DAWR macros Ravi Bangoria
2020-04-01  6:12   ` Ravi Bangoria
2020-04-01  6:12 ` [PATCH v2 02/16] powerpc/watchpoint: Add SPRN macros for second DAWR Ravi Bangoria
2020-04-01  6:12   ` Ravi Bangoria
2020-04-01  6:12 ` [PATCH v2 03/16] powerpc/watchpoint: Introduce function to get nr watchpoints dynamically Ravi Bangoria
2020-04-01  6:12   ` Ravi Bangoria
2020-04-01  6:29   ` Christophe Leroy
2020-04-01  6:29     ` Christophe Leroy
2020-04-01  6:50     ` Ravi Bangoria
2020-04-01  6:50       ` Ravi Bangoria
2020-04-01  7:05       ` Christophe Leroy
2020-04-01  7:05         ` Christophe Leroy
2020-04-01  6:12 ` [PATCH v2 04/16] powerpc/watchpoint/ptrace: Return actual num of available watchpoints Ravi Bangoria
2020-04-01  6:12   ` Ravi Bangoria
2020-04-01  6:12 ` [PATCH v2 05/16] powerpc/watchpoint: Provide DAWR number to set_dawr Ravi Bangoria
2020-04-01  6:12   ` Ravi Bangoria
2020-04-01  7:03   ` Christophe Leroy
2020-04-01  7:03     ` Christophe Leroy
2020-04-01  6:12 ` [PATCH v2 06/16] powerpc/watchpoint: Provide DAWR number to __set_breakpoint Ravi Bangoria
2020-04-01  6:12   ` Ravi Bangoria
2020-04-01  7:03   ` Christophe Leroy
2020-04-01  7:03     ` Christophe Leroy
2020-04-01  8:57     ` Ravi Bangoria
2020-04-01  8:57       ` Ravi Bangoria
2020-04-01  9:11       ` Christophe Leroy
2020-04-01  9:11         ` Christophe Leroy
2020-04-01  9:44         ` Christophe Leroy
2020-04-01  9:44           ` Christophe Leroy
2020-04-01  6:13 ` [PATCH v2 07/16] powerpc/watchpoint: Get watchpoint count dynamically while disabling them Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:32   ` Christophe Leroy
2020-04-01  6:32     ` Christophe Leroy
2020-04-01  9:19     ` Ravi Bangoria
2020-04-01  9:19       ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 08/16] powerpc/watchpoint: Disable all available watchpoints when !dawr_force_enable Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:33   ` Christophe Leroy
2020-04-01  6:33     ` Christophe Leroy
2020-04-01  9:00     ` Ravi Bangoria
2020-04-01  9:00       ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 09/16] powerpc/watchpoint: Convert thread_struct->hw_brk to an array Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:43   ` Christophe Leroy [this message]
2020-04-01  6:43     ` Christophe Leroy
2020-04-01  9:06     ` Ravi Bangoria
2020-04-01  9:06       ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 10/16] powerpc/watchpoint: Use loop for thread_struct->ptrace_bps Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 11/16] powerpc/watchpoint: Introduce is_ptrace_bp() function Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 12/16] powerpc/watchpoint: Use builtin ALIGN*() macros Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 13/16] powerpc/watchpoint: Prepare handler to handle more than one watcnhpoint Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:50   ` Christophe Leroy
2020-04-01  6:50     ` Christophe Leroy
2020-04-01  9:13     ` Ravi Bangoria
2020-04-01  9:13       ` Ravi Bangoria
2020-04-01  9:20       ` Christophe Leroy
2020-04-01  9:20         ` Christophe Leroy
2020-04-01  9:23         ` Ravi Bangoria
2020-04-01  9:23           ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 14/16] powerpc/watchpoint: Don't allow concurrent perf and ptrace events Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:52   ` Christophe Leroy
2020-04-01  6:52     ` Christophe Leroy
2020-04-01  6:13 ` [PATCH v2 15/16] powerpc/watchpoint/xmon: Don't allow breakpoint overwriting Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria
2020-04-01  6:13 ` [PATCH v2 16/16] powerpc/watchpoint/xmon: Support 2nd dawr Ravi Bangoria
2020-04-01  6:13   ` Ravi Bangoria

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=e5af5ed7-b9df-e334-1bdb-e7f82ae32697@c-s.fr \
    --to=christophe.leroy@c-s.fr \
    --cc=apopple@linux.ibm.com \
    --cc=fweisbec@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mikey@neuling.org \
    --cc=mingo@kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=naveen.n.rao@linux.vnet.ibm.com \
    --cc=npiggin@gmail.com \
    --cc=oleg@redhat.com \
    --cc=paulus@samba.org \
    --cc=peterz@infradead.org \
    --cc=ravi.bangoria@linux.ibm.com \
    /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.