Mapping an executable page
Thomas De Schampheleire
patrickdepinguin+linuxppc at gmail.com
Fri May 27 23:25:17 EST 2011
Hi,
To cover a specific reset scenario, I need to jump back to the reset
vector of a powerpc processor (e500mc core). In order to be able to
jump there directly, the code where I jump to should have a TLB
mapping associated with it.
I tried achieving this as follows:
typedef void (*funcptr)(void);
void __iomem *vaddr = __ioremap(0xfffff000, 0x1000,
(_PAGE_BASE | _PAGE_KERNEL_RWX));
printk(KERN_ERR "reboot_helper: 0xfffff000 mapped to
%p\n", vaddr);
/* Disable interrupts to avoid the boot code to be
interrupted */
local_irq_disable();
funcptr resetvector = (funcptr)(vaddr + 0xfec);
resetvector();
Unfortunately, I'm experiencing problems with this approach. I get :
[ 23.384639] reboot_helper: event: val=1
[ 23.384699] reboot_helper: 0xfffff000 mapped to f127e000
[ 23.384781] reboot_helper: 0xfffe1000 mapped to f1420000
[ 23.384856] Unable to handle kernel paging request for instruction fetch
[ 23.384949] Faulting instruction address: 0xf126b8d0
[ 23.385021] Oops: Kernel access of bad area, sig: 11 [#1]
[ 23.385096] P4080 DS
[ 23.385129] last sysfs file: /sys/class/uio/uio0/name
[ 23.385200] Modules linked in: reboot_helper
[ 23.385310] NIP: f126b8d0 LR: f127a190 CTR: f127efec
[ 23.385382] REGS: ec459cf0 TRAP: 0400 Not tainted (2.6.34.6-hg378747c1a102
-dirty)
[ 23.385489] MSR: 00029002 <EE,ME,CE> CR: 22002082 XER: 20000000
[ 23.385591] TASK = ec08a590[1094] 'init' THREAD: ec458000
[ 23.385664] GPR00: 00000001 ec459da0 ec08a590 00000042 0000388b ffffffff c01e
4388 00000000
[ 23.385800] GPR08: 00000001 c0490000 00000001 c04972d8 0fffffff 100bea58 0000
0000 00000201
[ 23.385936] GPR16: ff800002 ff80003f 00000000 00000000 00000001 effff000 c04b
8000 00000000
[ 23.386072] GPR24: bfdb9be8 100891a4 bfdb9d7c 00000000 00000000 fffffffe 0000
0001 f127efec
[ 23.386216] NIP [f126b8d0] 0xf126b8d0
[ 23.386275] LR [f127a190] isam_reboot_handler+0xa0/0xc4 [reboot_helper]
[ 23.386366] Call Trace:
[ 23.386410] [ec459da0] [f127a168] isam_reboot_handler+0x78/0xc4 [reboot_helpe
r] (unreliable)
[ 23.386534] [ec459db0] [c00422a0] notifier_call_chain+0x5c/0xc8
[ 23.386624] [ec459dd0] [c00426d4] __blocking_notifier_call_chain+0x5c/0x88
[ 23.386725] [ec459e00] [c0036850] kernel_restart_prepare+0x20/0x44
[ 23.386816] [ec459e10] [c00368c4] kernel_restart+0x18/0x5c
[ 23.386899] [ec459e20] [c0036a94] sys_reboot+0x184/0x1cc
[ 23.386980] [ec459f40] [c000fbe0] ret_from_syscall+0x0/0x3c
[ 23.387059] Instruction dump:
[ 23.387104] XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XX
XXXXXX
[ 23.387228] XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XX
XXXXXX
[ 23.387355] ---[ end trace 48808de79275a83d ]---
Although I realize that what I need to achieve is unconventional, what
is the correct way of mapping a certain address range into memory, and
be able to execute from it?
Thanks,
Thomas
More information about the Linuxppc-dev
mailing list