Thread (9 messages) flat view 9 messages, 3 authors, 2016-03-09

Re: [v5][PATCH] livepatch/ppc: Enable livepatching on powerpc

From: Torsten Duwe <hidden>
Date: 2016-03-08 15:34:47
Also in: lkml

On Wed, Mar 09, 2016 at 12:52:03AM +1100, Balbir Singh wrote:
On 08/03/16 21:45, Torsten Duwe wrote:
quoted
To be fair, my last mail still was not 100% correct, but the conclusion
Wrote a correction to the correction. It should be clear now. Please nag me
if it isn't clear why klp_return_helper and its stack frame is needed.
quoted
that the mini frame is not needed at all is invalid. Please leave it as it
was, I'm working on a test / demonstrator for how to handle these.
Why, the magic will be in the patched function? Please share the test/demonstrator
Here it comes...
quoted
NAKed-by: Torsten Duwe [off-list ref]
Why? For using CR+4 or removing the frame? Or you believe there is a better way to
handle this that work, IOW what is broken?
The stack frame removal. You're risking a memory access or jump into nirvana
or and endless loop.

klp_return_helper will do the right thing, and functions like e.g. printk
I would live patch like this (untested :-) :

------------------------8<----------------------
#include <stdarg.h>

/* compile using "-ffixed-r14"! */
register unsigned long pass_TOC asm("r14");

/*
 * Function pre-prologue to pop the klp_return_helper
 * mini stack frame. The saved r2 TOC value is read and
 * passed in pass_TOC (r14), the original LR is passed
 * in r0 and the LR itself. R12 is updated appropriately
 * for local TOC recalculation.
 */
extern void caller(void) asm("printk");
void caller(void)
{
  asm("ld %0,24(1)" : "=r" (pass_TOC));
  asm("addi 1,1,32");
  asm("addi 12,12,(real_printk-printk)@l");
  asm("ld 0,16(1)\n\tmtlr 0");
  asm("b real_printk");
}

extern int vprintk_default(const char *fmt, va_list args);

extern int printk(const char *fmt, ...) asm("real_printk");
int printk(const char *fmt, ...)
{
        va_list args;
        int r;

        va_start(args, fmt);

        r = vprintk_default(fmt, args);

        va_end(args);

	asm("mr 2,%0" : : "r" (pass_TOC));
        return r;
}
------------------------8<----------------------
Signed-off-by: Torsten Duwe <redacted>

As you can see, the extra effort for args on the stack is limited.

	Torsten
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help