<br>
<br><tt><font size=2>crash-utility-bounces@redhat.com wrote on 27/09/2007
20:03:24:<br>
<br>
> Richard J Moore wrote:<br>
> > <br>
> > <br>
> > crash-utility-bounces@redhat.com wrote on 27/09/2007 17:13:45:<br>
> > <br>
> > > Richard J Moore wrote:<br>
> > > ><br>
> > > > crash-utility-bounces@redhat.com wrote on 27/09/2007
15:45:21:<br>
> > > ><br>
> > > > > Richard J Moore wrote:<br>
> > > > ><br>
> > > > > > On looking at the code in entry.S
at page_fault and the other<br>
> > > > exception<br>
> > > > > > entry points I see no attempt
to save regs to create a pt_regs <br>
> > struct.<br>
> > > > > > The fact that do_page_fault takes
pt_regs as the first arg is a<br>
> > > > hack to<br>
> > > > > > get at CS:EIP and SS:ESP at the
time of exception.<br>
> > > > ><br>
> > > > > KPROBE_ENTRY(page_fault)<br>
> > > > > RING0_EC_FRAME<br>
> > > > > pushl $do_page_fault<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > ALIGN<br>
> > > > > error_code:<br>
> > > > > /* the function address
is in %fs's slot on the stack */<br>
> > > > > pushl %es<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > /*CFI_REL_OFFSET es,
0*/<br>
> > > > > pushl %ds<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > /*CFI_REL_OFFSET ds,
0*/<br>
> > > > > pushl %eax<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > CFI_REL_OFFSET eax, 0<br>
> > > > > pushl %ebp<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > CFI_REL_OFFSET ebp, 0<br>
> > > > > pushl %edi<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > CFI_REL_OFFSET edi, 0<br>
> > > > > pushl %esi<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > CFI_REL_OFFSET esi, 0<br>
> > > > > pushl %edx<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > CFI_REL_OFFSET edx, 0<br>
> > > > > pushl %ecx<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > CFI_REL_OFFSET ecx, 0<br>
> > > > > pushl %ebx<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > CFI_REL_OFFSET ebx, 0<br>
> > > > > cld<br>
> > > > > pushl %fs<br>
> > > > > CFI_ADJUST_CFA_OFFSET
4<br>
> > > > > /*CFI_REL_OFFSET fs,
0*/<br>
> > > > > movl $(__KERNEL_PERCPU),
%ecx<br>
> > > > > movl %ecx, %fs<br>
> > > > > UNWIND_ESPFIX_STACK<br>
> > > > > popl %ecx<br>
> > > > > CFI_ADJUST_CFA_OFFSET
-4<br>
> > > > > /*CFI_REGISTER es, ecx*/<br>
> > > > > movl PT_FS(%esp), %edi
# get the function address<br>
> > > > > movl PT_ORIG_EAX(%esp),
%edx # get the error code<br>
> > > > > movl $-1, PT_ORIG_EAX(%esp)
# no syscall to restart<br>
> > > > > mov %ecx, PT_FS(%esp)<br>
> > > > > /*CFI_REL_OFFSET fs,
ES*/<br>
> > > > > movl $(__USER_DS), %ecx<br>
> > > > > movl %ecx, %ds<br>
> > > > > movl %ecx, %es<br>
> > > > > movl %esp,%eax
# pt_regs pointer<br>
> > > > > call *%edi<br>
> > > > > jmp ret_from_exception<br>
> > > > > CFI_ENDPROC<br>
> > > > > KPROBE_END(page_fault)<br>
> > > > ><br>
> > > ><br>
> > > > Dave, it looks like error_code: has been change
relatively <br>
> > recently. My<br>
> > > > source starts:<br>
> > > > error_code:<br>
> > > > pushl %ds<br>
> > > > pushl %eax<br>
> > > > xorl %eax,%eax<br>
> > > > pushl %ebp<br>
> > > > <br>
> > > > and so on. Clearly not a valid pt_regs struct.<br>
> > > > The source I'm working with is from FC5. On your
version of the kernel<br>
> > > > only the ERR, SS and ESP would be invalid.<br>
> > > > What tree is yours taken from?<br>
> > > ><br>
> > ><br>
> > > My example was from upstream 2.6.22-5. RHEL5
(2.6.18-based)<br>
> > > is slightly different, as the "error_code:"
chunk is located<br>
> > > in the "divide_error" entry point, but like
2.6.22-5, all of<br>
> > > the other exceptions jmp to it.<br>
> > ><br>
> > > But even your code is creating the remainder of the
pt_regs<br>
> > > after the essential registers laid down by the hardware<br>
> > > exception mechanism, by pushing the remaining registers,<br>
> > > "upwards" towards the beginning of the structure:<br>
> > ><br>
> > > struct pt_regs {<br>
> > > long ebx;<br>
> > > long ecx;<br>
> > > long edx;<br>
> > > long esi;<br>
> > > long edi;<br>
> > > long ebp;<br>
> > > long eax;<br>
> > > int xds;<br>
> > > int xes;<br>
> > > long orig_eax;<br>
> > > long eip;<br>
> > > int xcs;<br>
> > > long eflags;<br>
> > > long esp;<br>
> > > int xss;<br>
> > > };<br>
> > ><br>
> > > Right?<br>
> > ><br>
> > > Dave<br>
> > ><br>
> > <br>
> > I don't think so. Am I misreading this:<br>
> > <br>
> > we take a page fault at ring 0. The cpu pushes eflags, cs, eip,
error-code<br>
> > we enter the kernel at:<br>
> > ENTRY(page_fault)<br>
> > pushl $do_page_fault<br>
> > jmp error_code<br>
> > <br>
> > we have errror code in orig_eax<br>
> > <br>
> > <br>
> > error_code:<br>
> > pushl %ds<br>
> > pushl %eax<br>
> > xorl %eax, %eax<br>
> > pushl %ebp<br>
> > pushl %edi<br>
> > pushl %esi<br>
> > pushl %edx<br>
> > decl %eax
# eax = -1<br>
> > pushl %ecx<br>
> > pushl %ebx<br>
> > cld<br>
> > pushl %es<br>
> > UNWIND_ESPFIX_STACK<br>
> > popl %ecx<br>
> > movl ES(%esp), %edi
# get the function address<br>
> > movl ORIG_EAX(%esp), %edx
# get the error code<br>
> > movl %eax, ORIG_EAX(%esp)<br>
> > movl %ecx, ES(%esp)<br>
> > movl $(__USER_DS), %ecx<br>
> > movl %ecx, %ds<br>
> > movl %ecx, %es<br>
> > movl %esp,%eax
# pt_regs
pointer<br>
> > call *%edi<br>
> > jmp ret_from_exception<br>
> > <br>
> > <br>
> > Aren't we sorting ds in the pt_regs.ES ? and therefore one register
out?<br>
> > <br>
> > Maybe I'm missing something?<br>
> <br>
> This code piece does seem to change from version to version,<br>
> but I think it gets the ES register into the proper pt_regs<br>
> location by pushing it here:<br>
> <br>
> > pushl %es<br>
> <br>
> and then popping it into %ecx here:<br>
> <br>
> > popl %ecx<br>
> <br>
> and then later storing it in the pt_regs here:<br>
> <br>
> > movl %ecx, ES(%esp)<br>
> <br>
> I think...<br>
> <br>
> Dave<br>
> </font></tt>
<br>
<br><tt><font size=2>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.
</font></tt>
<br>
<br><tt><font size=2>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 )</font></tt>
<br>
<br><tt><font size=2>Richard</font></tt>
<br><tt><font size=2><br>
> <br>
> <br>
> <br>
> --<br>
> Crash-utility mailing list<br>
> Crash-utility@redhat.com<br>
> </font></tt><a href="https://www.redhat.com/mailman/listinfo/crash-utility"><tt><font size=2>https://www.redhat.com/mailman/listinfo/crash-utility</font></tt></a><tt><font size=2><br>
</font></tt><font size=3 face="sans-serif"><br>
</font>
<br><font size=3 face="sans-serif"><br>
</font>
<hr><font size=2 face="sans-serif"><br>
<i><br>
</i></font>
<p><font size=2 face="sans-serif"><i>Unless stated otherwise above:<br>
IBM United Kingdom Limited - Registered in England and Wales with number
741598. <br>
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU</i></font>
<p><font size=2 face="sans-serif"><br>
</font><font size=3 face="sans-serif"><br>
</font>
<br>
<br><font size=3 face="sans-serif"><br>
</font>