Re: [PATCH 1/23] Make register values available to panic notifiers

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: David Howells
Date: Wednesday, April 14, 2010 - 4:52 pm

David VomLehn <dvomlehn@cisco.com> wrote:


How about something like Sparc, where you can pass up to 8 arguments (if I
remember correctly) in registers.  I'm not sure how Sparc handles varargs
functions, though.


Indeed, but you've probably already lost that by using va_start().


Well, they'll be the context of panic() in your implementation.


Yes.  The easiest way might be to write the saver in assembly and call it from
within an inline asm statement.


Indeed, but the more things panic() does, the more likely it is to clobber
registers anyway.

Note, also: panic() is __attribute__((noreturn)), which means that the
compiler calling it is not required to save the return address or registers
before jumping to panic() or even in panic() itself.


As I mentioned above, you can use asm for this.  For instance, you can write
an inline asm statement that saves onto the stack the registers that need to
be clobbered to make a jump, then make the jump, and then have the saver
routine retrieve the register values from the stack and place them in the
storage area.

In fact, you could insert a prologue wrapper on panic() with a bit of asm to
save the registers, for example on FRV:

	panic:
		subi	sp,#-8,sp
		stdi.p	gr4,@(sp,#0)		# save GR4/GR5 on stack
		addi	sp,#8,gr5
		sethi.p	%hi(__panic_reg_save),gr4  # get the save space addr
		setlo	%lo(__panic_reg_save),gr4
		sti	gr5,@(gr4,#REG_SP))	# save orig stack pointer
		stdi	gr2,@(gr4,#REG_GR(2))	# save GR2/GR3
		ldi	@(sp,#0),gr5
		sti	gr5,@(gr4,#REG_GR(4))	# save orig GR4
		ldi	@(sp,#4),gr5
		sti	gr5,@(gr4,#REG_GR(5))	# save orig GR5
		stdi	gr6,@(gr4,#REG_GR(6))	# save GR6/GR7
		stdi	gr8,@(gr4,#REG_GR(8))	# save GR8/GR9
		...
		lddi.p	@(sp,#0),gr4		# restore GR4/GR5 from stack
		addi	sp,#8,sp
		bra	real_panic		# chain

Then real_panic() would be the original C panic function.


Most load/store instructions come in two types, and you need to modify the
opcode according to the addressing mode and indicate that you're interpolating
a memory dereference argument rather than an address:

	asm("ldd%I1 %M1,%0"
	    : "=e"(counter)
	    : "m"(v->counter));

You're also trying to load data into GR0 which won't achieve anything.  GR0 is
hardwired to 0.  It's used as the target of instructions where you don't care
about the calculated result (eg: compare is implemented as subtract to GR0),
and as a source of 0.

David
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [PATCH 1/23] Make register values available to panic n ..., Martin Schwidefsky, (Mon Apr 12, 6:35 am)
Re: [PATCH 1/23] Make register values available to panic n ..., David Howells, (Wed Apr 14, 4:52 pm)