linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* somewhat OT -- trying to build code on the fly then run it
@ 2005-04-04 23:32 Chris Friesen
  2005-04-05  1:03 ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 5+ messages in thread
From: Chris Friesen @ 2005-04-04 23:32 UTC (permalink / raw)
  To: linuxppc-dev


I'm writing a testcase to test some code we wrote to allow userspace to 
flush the whole dcache and invalidate the whole icache.  This requires 
me to write self-modifying code.  For the first stage I'm just trying to 
build a routine (that just increments r3 and returns) on the heap and 
then call it.

Everything seems to be fine right up until I jump to the code that I've 
written, then I get a segfault.  The debugger shows my registers and 
data values are as expected, and the page of memory has xwr permissions.

Can anyone tell me what I'm missing?  I'm sure its something simple.

Thanks,

Chris.


PS.  Here's my current test code.

#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdio.h>
#include <sys/mman.h>

/* these next two lines are the hex equivalents of the instructions:
  * addi r3,r3,1
  * blr
  */
unsigned int incr_code[] = {
	0x38630001,
	0x4e800020
};

int dotest(unsigned long *addr)
{
         int i=0;
         asm volatile (" \n\
                 mr 3,%1 \n\
                 bla %2  \n\
                 mr %0,3 \n"
                 : "=r" (i)
                 : "r" (i), "r" (addr));
         return i;
}

void alter_opcode(unsigned long *addr, unsigned long opcode)
{
	unsigned long offset = 0;
	
	asm volatile(
                 "stw    %1,0(%0)  \n\t"
                 "dcbf   %0,%2     \n\t"
                 "sync             \n\t"
                 "icbi   %0,%2     \n\t"
                 "sync             \n\t"
                 "isync            \n\t"
                     :: "r" (addr), "r" (opcode), "r" (offset));
}

int main()
{
	unsigned long *addr;
	void *p = mmap(0, 4096, PROT_EXEC|PROT_WRITE|PROT_READ,
		MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
	if (p == MAP_FAILED) {
		perror("mmap");
		goto error;
	}
	
	addr = (unsigned long *)p;
	
	alter_opcode(addr, incr_code[0]);
	alter_opcode(addr+1, incr_code[1]);
	
	printf("%d\n", dotest(addr));
	return 0;
	
error:
	return -1;
}

^ permalink raw reply	[flat|nested] 5+ messages in thread
* RE: somewhat OT -- trying to build code on the fly then run it
@ 2005-04-05 15:08 Fillod Stephane
  2005-04-05 16:43 ` Chris Friesen
  0 siblings, 1 reply; 5+ messages in thread
From: Fillod Stephane @ 2005-04-05 15:08 UTC (permalink / raw)
  To: Chris Friesen; +Cc: linuxppc-dev

Chris Friesen wrote:=20
> I'm writing a testcase to test some code we wrote to allow userspace
to=20
> flush the whole dcache and invalidate the whole icache. =20

Your testcase sounds like this kernel module for RT load generator:

	http://rtai.dk/cgi-bin/gratiswiki.pl?Latency_Killer/Flushy


Comments welcome.
--=20
Stephane

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-04-05 17:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-04 23:32 somewhat OT -- trying to build code on the fly then run it Chris Friesen
2005-04-05  1:03 ` Benjamin Herrenschmidt
2005-04-05 17:03   ` Chris Friesen
  -- strict thread matches above, loose matches on Subject: below --
2005-04-05 15:08 Fillod Stephane
2005-04-05 16:43 ` Chris Friesen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).