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@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility