crash-utility-bounces@redhat.com wrote on 27/09/2007
20:03:24:
> Richard J Moore wrote:
> >
> >
> > crash-utility-bounces@redhat.com wrote on 27/09/2007 17:13:45:
> >
> > > Richard J Moore wrote:
> > > >
> > > > crash-utility-bounces@redhat.com wrote on 27/09/2007
15:45:21:
> > > >
> > > > > Richard J Moore wrote:
> > > > >
> > > > > > On looking at the code in entry.S
at page_fault and the other
> > > > exception
> > > > > > entry points I see no attempt
to save regs to create a pt_regs
> > struct.
> > > > > > The fact that do_page_fault takes
pt_regs as the first arg is a
> > > > hack to
> > > > > > get at CS:EIP and SS:ESP at the
time of exception.
> > > > >
> > > > > KPROBE_ENTRY(page_fault)
> > > > > RING0_EC_FRAME
> > > > > pushl $do_page_fault
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > ALIGN
> > > > > error_code:
> > > > > /* the function address
is in %fs's slot on the stack */
> > > > > pushl %es
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > /*CFI_REL_OFFSET es,
0*/
> > > > > pushl %ds
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > /*CFI_REL_OFFSET ds,
0*/
> > > > > pushl %eax
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > CFI_REL_OFFSET eax, 0
> > > > > pushl %ebp
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > CFI_REL_OFFSET ebp, 0
> > > > > pushl %edi
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > CFI_REL_OFFSET edi, 0
> > > > > pushl %esi
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > CFI_REL_OFFSET esi, 0
> > > > > pushl %edx
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > CFI_REL_OFFSET edx, 0
> > > > > pushl %ecx
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > CFI_REL_OFFSET ecx, 0
> > > > > pushl %ebx
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > CFI_REL_OFFSET ebx, 0
> > > > > cld
> > > > > pushl %fs
> > > > > CFI_ADJUST_CFA_OFFSET
4
> > > > > /*CFI_REL_OFFSET fs,
0*/
> > > > > movl $(__KERNEL_PERCPU),
%ecx
> > > > > movl %ecx, %fs
> > > > > UNWIND_ESPFIX_STACK
> > > > > popl %ecx
> > > > > CFI_ADJUST_CFA_OFFSET
-4
> > > > > /*CFI_REGISTER es, ecx*/
> > > > > movl PT_FS(%esp), %edi
# get the function address
> > > > > movl PT_ORIG_EAX(%esp),
%edx # get the error code
> > > > > movl $-1, PT_ORIG_EAX(%esp)
# no syscall to restart
> > > > > mov %ecx, PT_FS(%esp)
> > > > > /*CFI_REL_OFFSET fs,
ES*/
> > > > > movl $(__USER_DS), %ecx
> > > > > movl %ecx, %ds
> > > > > movl %ecx, %es
> > > > > movl %esp,%eax
# pt_regs pointer
> > > > > call *%edi
> > > > > jmp ret_from_exception
> > > > > CFI_ENDPROC
> > > > > KPROBE_END(page_fault)
> > > > >
> > > >
> > > > Dave, it looks like error_code: has been change
relatively
> > recently. My
> > > > source starts:
> > > > error_code:
> > > > pushl %ds
> > > > pushl %eax
> > > > xorl %eax,%eax
> > > > pushl %ebp
> > > >
> > > > and so on. Clearly not a valid pt_regs struct.
> > > > The source I'm working with is from FC5. On your
version of the kernel
> > > > only the ERR, SS and ESP would be invalid.
> > > > What tree is yours taken from?
> > > >
> > >
> > > My example was from upstream 2.6.22-5. RHEL5
(2.6.18-based)
> > > is slightly different, as the "error_code:"
chunk is located
> > > in the "divide_error" entry point, but like
2.6.22-5, all of
> > > the other exceptions jmp to it.
> > >
> > > But even your code is creating the remainder of the
pt_regs
> > > after the essential registers laid down by the hardware
> > > exception mechanism, by pushing the remaining registers,
> > > "upwards" towards the beginning of the structure:
> > >
> > > struct pt_regs {
> > > long ebx;
> > > long ecx;
> > > long edx;
> > > long esi;
> > > long edi;
> > > long ebp;
> > > long eax;
> > > int xds;
> > > int xes;
> > > long orig_eax;
> > > long eip;
> > > int xcs;
> > > long eflags;
> > > long esp;
> > > int xss;
> > > };
> > >
> > > Right?
> > >
> > > Dave
> > >
> >
> > I don't think so. Am I misreading this:
> >
> > we take a page fault at ring 0. The cpu pushes eflags, cs, eip,
error-code
> > we enter the kernel at:
> > ENTRY(page_fault)
> > pushl $do_page_fault
> > jmp error_code
> >
> > we have errror code in orig_eax
> >
> >
> > error_code:
> > pushl %ds
> > pushl %eax
> > xorl %eax, %eax
> > pushl %ebp
> > pushl %edi
> > pushl %esi
> > pushl %edx
> > decl %eax
# eax = -1
> > pushl %ecx
> > pushl %ebx
> > cld
> > pushl %es
> > UNWIND_ESPFIX_STACK
> > popl %ecx
> > movl ES(%esp), %edi
# get the function address
> > movl ORIG_EAX(%esp), %edx
# get the error code
> > movl %eax, ORIG_EAX(%esp)
> > movl %ecx, ES(%esp)
> > movl $(__USER_DS), %ecx
> > movl %ecx, %ds
> > movl %ecx, %es
> > movl %esp,%eax
# pt_regs
pointer
> > call *%edi
> > jmp ret_from_exception
> >
> >
> > Aren't we sorting ds in the pt_regs.ES ? and therefore one register
out?
> >
> > Maybe I'm missing something?
>
> This code piece does seem to change from version to version,
> but I think it gets the ES register into the proper pt_regs
> location by pushing it here:
>
> > pushl %es
>
> and then popping it into %ecx here:
>
> > popl %ecx
>
> and then later storing it in the pt_regs here:
>
> > movl %ecx, ES(%esp)
>
> I think...
>
> Dave
>
Everything is still one word out apart from ES. All
this does (I think - and it is confusing code) is replace DS with ES instead
of inserting ES by moving all the other regs, previously stored, down the
stack 4 bytes then storing ES. I think we are shifted by one register wrt
pt_regs from ebx to xds in the earlier versions of error_code. Certainly
the later version of error_code from 2.6.22 is correct in terms of pt_regs.
But even in that case, ERR is not correct ever and
SS:ESP are not correct for kernel exceptions as formatted in bt. I guess
this comes down to a wrong assumption on my part: that regs formatted by
bt were meant to be the regs at time of exception rather than a verbatim
formatting of pt_regs. The problem is we don't yet have a comprehensive
register logout capability for fatal exceptions. I think there is a case
for adding some additional capability to panic. Especially the saving of
the control regs, the system selector regs, the debug regs and possibly
a few MSRs (sysenter/exit, machine check, debugging )
Richard
>
>
>
> --
> Crash-utility mailing list
> Crash-utility@redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU