blob: 3bc19ea6c6d157cd6dcd789130a1bae57c6aa0ee [file] [log] [blame]
* @file oprofile_stubs.S
* Assembly language system call interceptor stubs
* @remark Copyright 2001-2002 Hewlett-Packard Company
* @remark Read the file COPYING
* @author Bob Montgomery <>
* This interceptor for execve was stolen from ia64/kernel/entry.S
* Kernel entry points.
* Copyright (C) 1998-2001 Hewlett-Packard Co
* David Mosberger-Tang <>
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <>
* Copyright (C) 1999 Asit Mallick <>
* Copyright (C) 1999 Don Dugger <>
* ia64_switch_to now places correct virtual mapping in in TR2 for
* kernel stack. This allows us to handle interrupts without changing
* to physical mode.
* Jonathan Nicklin <>
* Patrick O'Rourke <>
* 11/07/2000
* Global (preserved) predicate usage on syscall entry/exit path:
* pKern: See entry.h.
* pUser: See entry.h.
* pSys: See entry.h.
* pNonSys: !pSys
#include <linux/config.h>
#include <asm/cache.h>
#include <asm/errno.h>
#include <asm/kregs.h>
#include <asm/offsets.h>
#include <asm/processor.h>
#include <asm/unistd.h>
#include <asm/asmmacro.h>
#include <asm/pgtable.h>
#include "IA64minstate.h"
* execve() is special because in case of success, we need to
* setup a null register window frame.
alloc loc1=ar.pfs, 3, 3, 4, 0
mov loc0=rp
mov loc2=gp
mov out0=in0 // filename
;; // stop bit between alloc and call
mov out1=in1 // argv
mov out2=in2 // envp
add out3=16, sp // regs
* We are here with the kernel's gp register value but we need
* to find the module's gp value before we can call our own
* routine. That's why we can't just use:
* rp=my_sys_execve
* Use ip-relative addressing to get to the fptr since I can't
* use gp-relative anything without the module's gp.
mov r3 = ip
addl r14 = .fptr_execve - .L1_execve, r3
ld8 r14=[r14]
ld8 r15=[r14], 8
ld8 gp=[r14]
mov b6=r15 b0=b6
.ret0: p6, p7=r8, r0
mov ar.pfs=loc1 // restore ar.pfs
sxt4 r8=r8 // return 64-bit result
stf.spill [sp]=f0
(p6) pKern, pUser=r0, r0 // a successful execve() lands us in user-mode...
mov gp=loc2
mov rp=loc0
(p6) mov ar.pfs=r0 // clear ar.pfs on success
(p7) br.ret.sptk.many rp
* In theory, we'd have to zap this state only to prevent leaking of
* security sensitive state (e.g., if current->mm->dumpable is zero). However,
* this executes in less than 20 cycles even on Itanium, so it's not worth
* optimizing for...).
mov r4=0; mov f2=f0; mov b1=r0
mov r5=0; mov f3=f0; mov b2=r0
mov r6=0; mov f4=f0; mov b3=r0
mov r7=0; mov f5=f0; mov b4=r0
mov ar.unat=0; mov f10=f0; mov b5=r0
ldf.fill f11=[sp]; ldf.fill f12=[sp]; mov f13=f0
ldf.fill f14=[sp]; ldf.fill f15=[sp]; mov f16=f0
ldf.fill f17=[sp]; ldf.fill f18=[sp]; mov f19=f0
ldf.fill f20=[sp]; ldf.fill f21=[sp]; mov f22=f0
ldf.fill f23=[sp]; ldf.fill f24=[sp]; mov f25=f0
ldf.fill f26=[sp]; ldf.fill f27=[sp]; mov f28=f0
ldf.fill f29=[sp]; ldf.fill f30=[sp]; mov f31=f0
br.ret.sptk.many rp
.align 16
data8 @fptr(my_sys_execve)
/* These interceptors are from IA64syscallstub.h macros */
#include "IA64syscallstub.h"