On Wed, 15 Dec 1999, Brian Hall wrote:
|>OK, I am actively working on this now (the Linux Alpha machines I have access
|>to have had problems; I've put the kernel tree on an NFS mount so I can
|>continue to work).
|>
|>Do I have to do the inline assembly to save the PC and RA registers, or can I
|>simply stuff them into the dump header structure? BTW, I notice lots of 32 bit
|>fields in the header, those will all have to be 64 bit for Alpha, won't they?
|>Certainly at least the registers will; I think having others in the structure
|>32 bit may cause alignment problems on the Alpha.
The problem is from panic(), you don't have the registers, so you
need to grab them. That way the 'lcrash' code has a point to start
with as far as the failing process is concerned. Hence the "if (regs)"
stuff.
|>So, can I just make the dh_esp and dh_eip uint64_t, remove the inline asm and
|>the call to __dump_save_panic_regs, and just do:
|>
|>/* This is __dump_execute */
|>
|>dump_header.dh_esp = regs->pc;
|>/* from arch/alpha/kernel/traps.c, r26 appears to be ra */
|>dump_header.dh_eip = regs->r26;
|>
|>/* dump out the header */
The dump_header uses pt_regs, and if the alpha stuff is translated
right for your build, it should be the right type without you having
to do anything. Such as:
regs->esp is 32-bit (long) for i386; however
regs->pc is 64-bit (unsigned long) for alpha.
No type-casting should be necessary, assuming architecture compatible
pt_regs stuff is being used.
If you do see a problem, however, let me know and I'll fix it in the
main code.
|>Also, what do you mean by putting a hook in die_if_kernel()? Do you mean to
|>call the kernel dump routine - dump_execute() ?
Correct. Be sure that panic() also calls dump_execute().
|>On 01-Dec-1999 Matt Robinson wrote:
|>> The first thing to do is to take the kernel code in
|>> arch/i386/kernel/vmdump.c and copy it to arch/alpha/kernel, modify
|>> the makefile, and then modify the calls for saving the pt_regs.
|>>
|>> The code for saving the registers is mostly correct, except for:
|>>
|>> if (regs) {
|>> memcpy((void *)&(dump_header.dh_regs), (const void *)regs,
|>> sizeof(struct pt_regs));
|>>> if (!user_mode(regs)) {
|>>> dump_header.dh_regs.esp = (unsigned long) (regs + 1);
|>>> }
|>> }
|>>
|>> Those lines aren't necessarily needed -- they are I386 specific. We
|>> have to adjust the esp based on the processor mode.
|>>
|>> Also, the code for:
|>>
|>> /* save the dump specific esp/eip */
|>> __asm__ __volatile__("
|>> pushl %%eax\n
|>> movl %%esp, %%eax\n
|>> movl %%eax, %0\n
|>> popl %%eax\n"
|>> : "=g" (dump_header.dh_esp)
|>> );
|>> __asm__ __volatile__("pushl %eax\n");
|>> __dump_save_panic_regs();
|>> __asm__ __volatile__("popl %eax\n");
|>>
|>> All of this is set up just to save the stack pointer and program
|>> counter for this box, as the pt_regs on I386 boxes don't necessarily
|>> point to the right location. We want to be able to walk back from
|>> the exception where that is possible.
|>>
|>> In looking at the Alpha stuff, I think you can start by saving the PC
|>> and RA values (not sure which $XX they represent), and also put a hook
|>> into die_if_kernel() in traps.c.
|>
|>--
|>Brian Hall <brianw.hall@xxxxxxxxxx>
|>Linux Consultant
|>
|