Ok. I have seen this change in the pt_regs struct before but did not connect it to this
problem. I see these new field in pt_regs in earlier kernel versions than 4.7, but it is
probably backports. It really does not matter for the solution of the problem. The
following change works for me:
Change:
#define USER_EFRAME_OFFSET (304)
to:
#define USER_EFRAME_OFFSET (STRUCT_SIZE("pt_regs") + 16)
Then you might want to avoid the recalculation of the struct size. I think your patch does
the same thing.
Jan
________________________________________
Från: crash-utility-bounces(a)redhat.com <crash-utility-bounces(a)redhat.com> för Dave
Anderson <anderson(a)redhat.com>
Skickat: den 21 september 2017 17:38
Till: Discussion list for crash utility usage, maintenance and development
Ämne: Re: [Crash-utility] Problem in bt for ARM64
----- Original Message -----
----- Original Message -----
> Hi Dave
>
> I have experienced some problems in the bt command for ARM64. It seems that
> the test in arm64_print_exception_frame in arm64.c if the task is running
> in
> 32 or 64-bit mode in userland does not work. It "always" becomes 32-bit
> mode. Example:
>
> crash> bt 1
> PID: 1 TASK: ffffffe1f90f8000 CPU: 2 COMMAND: "init"
> #0 [ffffffe1f9103c80] __switch_to at ffffff85b6a862f8
> #1 [ffffffe1f9103ca0] __schedule at ffffff85b7b0d9b0
> #2 [ffffffe1f9103d00] schedule at ffffff85b7b0df28
> #3 [ffffffe1f9103d20] schedule_hrtimeout_range_clock at ffffff85b7b11308
> #4 [ffffffe1f9103da0] schedule_hrtimeout_range at ffffff85b7b11320
> #5 [ffffffe1f9103db0] sys_epoll_wait at ffffff85b6c394c8
> #6 [ffffffe1f9103e70] sys_epoll_pwait at ffffff85b6c396fc
> #7 [ffffffe1f9103ed0] el0_svc_naked at ffffff85b6a8312c
> PC: 00000004 LR: 00000000 SP: 00000000 PSTATE: 00000016
> X12: 00546694 X11: 3431206c616e6769 X10: 00546338 X9: 00000000
> X8: 00000112 X7: dfdab819254dd1e8 X6: 00000016 X5: 0000000a
> X4: 00000031 X3: 00000008 X2: 00000000 X1: ffffffff
> X0: 00000001
>
> The register values are:
> r0: 4 r1: 7ff0b27f90
> r2: 1 r3: ffffffff
> r4: 0 r5: 8
> r6: 31 r7: a
> r8: 16 r9: dfdab819254dd1e8
> r10: 112 r11: 0
> r12: 546338 r13: 3431206c616e6769
> r14: 546694 r15: 0
> r16: 0 r17: f04245b7
> r18: 51f2a993 r19: 5783c0
> r20: 415254 r21: 527a5c
> r22: 527e04 r23: ffffffff
> r24: ffffffff r25: 576000
> r26: 578000 r27: 578000
> r28: 3e8 fp: 7ff0b27ec0
> lr: 4f4f24 sp: 7ff0b27eb0
> pc: 4fb8d4 psr: 40000000
>
> I have unfortunately not had the time to look for a solution, so I just want
> to report what I have seen. The kernel running in the example above is
> 4.4.74 and I have seen the same problem for a 4.9.40 kernel.
>
> Jan
Yeah, even the functions that do show 64-bit user mode exception frames
appear to have invalid contents. It looks like the pt_regs is not at the
same fixed location on the stack where it has always been, i.e., as it gets
set here unconditionally at the bottom of arm64_back_trace_cmd():
complete_user:
exception_frame = bt->stacktop - USER_EFRAME_OFFSET;
arm64_print_exception_frame(bt, exception_frame, USER_MODE, ofp);
Jan,
I don't see the problem in anything before 4.7, and I do have a set
of 4.5 dumpfiles and an early 4.7-rc0 dumpfile that do not show the
problem. Are you sure about seeing it in a "4.4.74" kernel?
I say that because it does seem to be confluent with v4.7-rc7 commit
e19a6ee2460bdd0d0055a6029383422773f9999a that has this:
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index a307eb6..7f94755 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -117,6 +117,8 @@ struct pt_regs {
};
u64 orig_x0;
u64 syscallno;
+ u64 orig_addr_limit;
+ u64 unused; // maintain 16 byte alignment
};
Does the attached patch work for you?
Thanks,
Dave
diff --git a/arm64.c b/arm64.c
index 0ab8396..9fe0c87 100644
--- a/arm64.c
+++ b/arm64.c
@@ -393,6 +393,11 @@ arm64_init(int when)
get_symbol_data("nr_irqs", sizeof(unsigned int),
&machdep->nr_irqs);
+ if (MEMBER_EXISTS("pt_regs", "orig_addr_limit"))
+ ms->user_eframe_offset = 320;
+ else
+ ms->user_eframe_offset = 304;
+
if (!machdep->hz)
machdep->hz = 100;
@@ -608,6 +613,7 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " exp_entry2_start: %lx\n", ms->exp_entry2_start);
fprintf(fp, " exp_entry2_end: %lx\n", ms->exp_entry2_end);
fprintf(fp, " panic_task_regs: %lx\n",
(ulong)ms->panic_task_regs);
+ fprintf(fp, " user_eframe_offset: %ld\n",
ms->user_eframe_offset);
fprintf(fp, " PTE_PROT_NONE: %lx\n", ms->PTE_PROT_NONE);
fprintf(fp, " PTE_FILE: ");
if (ms->PTE_FILE)
@@ -1461,7 +1467,7 @@ arm64_stackframe_init(void)
#define KERNEL_MODE (1)
#define USER_MODE (2)
-#define USER_EFRAME_OFFSET (304)
+#define USER_EFRAME_OFFSET (machdep->machspec->user_eframe_offset)
/*
* PSR bits
diff --git a/defs.h b/defs.h
index fd97ffe..8534d40 100644
--- a/defs.h
+++ b/defs.h
@@ -3110,6 +3110,7 @@ struct machine_specific {
ulong kimage_voffset;
ulong kimage_text;
ulong kimage_end;
+ ulong user_eframe_offset;
};
struct arm64_stackframe {