[Crash-utility] [PATCH] arm64: support compat user mode prstatus

Andrew Jones drjones at redhat.com
Mon Dec 21 20:04:59 UTC 2015


On Fri, Dec 18, 2015 at 11:55:07PM +0100, Andrew Jones wrote:
> compat user mode prstatus already just works, almost. This missing
> pieces are that pt_regs->sp and pt_regs->fp are not in their usual
> locations. We need to pull them out of their architecturally mapped
> general purpose registers.
> ---
>  arm64.c | 42 ++++++++++++++++++++++++++++++++++--------
>  1 file changed, 34 insertions(+), 8 deletions(-)
> 
> diff --git a/arm64.c b/arm64.c
> index 183e768498fe8..3a82d20cdd465 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -993,6 +993,25 @@ arm64_stackframe_init(void)
>  #define PSR_MODE_EL3h   0x0000000d
>  #define PSR_MODE_MASK   0x0000000f
>  
> +/* Architecturally defined mapping between AArch32 and AArch64 registers */
> +#define compat_usr(x)   regs[(x)]
> +#define compat_fp       regs[11]
> +#define compat_sp       regs[13]
> +#define compat_lr       regs[14]
> +
> +#define user_mode(ptregs) \
> +	(((ptregs)->pstate & PSR_MODE_MASK) == PSR_MODE_EL0t)
> +
> +#define compat_user_mode(ptregs)  \
> +	(((ptregs)->pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) == \
> +	 (PSR_MODE32_BIT | PSR_MODE_EL0t))
> +
> +#define user_stack_pointer(ptregs) \
> +	(!compat_user_mode(ptregs) ? (ptregs)->sp : (ptregs)->compat_sp)
> +
> +#define user_frame_pointer(ptregs) \
> +	(!compat_user_mode(ptregs) ? (ptregs)->regs[29] : (ptregs)->compat_fp)
> +
>  static int
>  arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr)
>  {
> @@ -1340,21 +1359,28 @@ arm64_get_dumpfile_stackframe(struct bt_info *bt, struct arm64_stackframe *frame
>  	struct machine_specific *ms = machdep->machspec;
>  	struct arm64_pt_regs *ptregs;
>  
> -	if (!ms->panic_task_regs ||
> -	    (!ms->panic_task_regs[bt->tc->processor].sp && 
> -	     !ms->panic_task_regs[bt->tc->processor].pc)) {
> +	if (!ms->panic_task_regs || !ms->panic_task_regs[bt->tc->processor].pc) {

Hi Dave,

I'm having second thoughts about keeping the
!ms->panic_task_regs[bt->tc->processor].pc test. pc being zero sounds
like a good reason to crash, or a potential status of a pc after a crash.
I don't think we should be too hasty to reject the rest of the registers.
Is there anyway we can relax the sanity checking, but still keep the crash
utility happy?

Thanks,
drew

>  		bt->flags |= BT_REGS_NOT_FOUND;
>  		return FALSE;
>  	}
>  
>  	ptregs = &ms->panic_task_regs[bt->tc->processor];
> -	frame->sp = ptregs->sp;
>  	frame->pc = ptregs->pc;
> -	frame->fp = ptregs->regs[29];
> -
> -	if (!is_kernel_text(frame->pc) && 
> -	    in_user_stack(bt->tc->task, frame->sp))
> +	if (user_mode(ptregs)) {
> +		frame->sp = user_stack_pointer(ptregs);
> +		frame->fp = user_frame_pointer(ptregs);
> +		if (is_kernel_text(frame->pc) ||
> +		    !in_user_stack(bt->tc->task, frame->sp)) {
> +			error(WARNING, "Corrupt prstatus? pstate=0x%lx, but no user frame found\n",
> +										ptregs->pstate);
> +			bt->flags |= BT_REGS_NOT_FOUND;
> +			return FALSE;
> +		}
>  		bt->flags |= BT_USER_SPACE;
> +	} else {
> +		frame->sp = ptregs->sp;
> +		frame->fp = ptregs->regs[29];
> +	}
>  
>  	if (arm64_in_kdump_text(bt, frame))
>  		bt->flags |= BT_KDUMP_ADJUST;
> -- 
> 1.8.3.1
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility




More information about the Crash-utility mailing list