Home | History | Annotate | Download | only in ia64
      1 /**
      2  * @file oprofile_stubs.S
      3  * Assembly language system call interceptor stubs
      4  *
      5  * @remark Copyright 2001-2002 Hewlett-Packard Company
      6  * @remark Read the file COPYING
      7  *
      8  * @author Bob Montgomery <bob_montgomery (at) hp.com>
      9  */
     10 
     11 /*
     12  * This interceptor for execve was stolen from ia64/kernel/entry.S
     13  *
     14  * Kernel entry points.
     15  *
     16  * Copyright (C) 1998-2001 Hewlett-Packard Co
     17  *	David Mosberger-Tang <davidm (at) hpl.hp.com>
     18  * Copyright (C) 1999 VA Linux Systems
     19  * Copyright (C) 1999 Walt Drummond <drummond (at) valinux.com>
     20  * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick (at) intel.com>
     21  * Copyright (C) 1999 Don Dugger <Don.Dugger (at) intel.com>
     22  */
     23 /*
     24  * ia64_switch_to now places correct virtual mapping in in TR2 for
     25  * kernel stack. This allows us to handle interrupts without changing
     26  * to physical mode.
     27  *
     28  * Jonathan Nicklin	<nicklin (at) missioncriticallinux.com>
     29  * Patrick O'Rourke	<orourke (at) missioncriticallinux.com>
     30  * 11/07/2000
     31  */
     32 /*
     33  * Global (preserved) predicate usage on syscall entry/exit path:
     34  *
     35  *	pKern:		See entry.h.
     36  *	pUser:		See entry.h.
     37  *	pSys:		See entry.h.
     38  *	pNonSys:	!pSys
     39  */
     40 
     41 #include <linux/config.h>
     42 
     43 #include <asm/cache.h>
     44 #include <asm/errno.h>
     45 #include <asm/kregs.h>
     46 #include <asm/offsets.h>
     47 #include <asm/processor.h>
     48 #include <asm/unistd.h>
     49 #include <asm/asmmacro.h>
     50 #include <asm/pgtable.h>
     51 
     52 #include "IA64minstate.h"
     53 
     54 	/*
     55 	 * execve() is special because in case of success, we need to
     56 	 * setup a null register window frame.
     57 	 */
     58 GLOBAL_ENTRY(my_ia64_execve)
     59 	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
     60 	alloc loc1=ar.pfs, 3, 3, 4, 0
     61 	mov loc0=rp
     62 	mov loc2=gp
     63 	.body
     64 	mov out0=in0			// filename
     65 	;;				// stop bit between alloc and call
     66 	mov out1=in1			// argv
     67 	mov out2=in2			// envp
     68 	add out3=16, sp			// regs
     69 	/*
     70 	 * We are here with the kernel's gp register value but we need
     71 	 * to find the module's gp value before we can call our own
     72 	 * routine.  That's why we can't just use:
     73 	 *	br.call.sptk.many rp=my_sys_execve
     74 	 * Use ip-relative addressing to get to the fptr since I can't
     75 	 * use gp-relative anything without the module's gp.
     76 	 */
     77 .L1_execve:
     78 	mov r3 = ip
     79 	;;
     80 	addl r14 = .fptr_execve - .L1_execve, r3
     81 	;;
     82 	ld8 r14=[r14]
     83 	;;
     84 	ld8 r15=[r14], 8
     85 	;;
     86 	ld8 gp=[r14]
     87 	;;
     88 	mov b6=r15
     89 	br.call.sptk.many b0=b6
     90 	;;
     91 .ret0:	cmp4.ge p6, p7=r8, r0
     92 	mov ar.pfs=loc1			// restore ar.pfs
     93 	sxt4 r8=r8			// return 64-bit result
     94 	;;
     95 	stf.spill [sp]=f0
     96 (p6)	cmp.ne pKern, pUser=r0, r0	// a successful execve() lands us in user-mode...
     97 	mov gp=loc2
     98 	mov rp=loc0
     99 (p6)	mov ar.pfs=r0			// clear ar.pfs on success
    100 (p7)	br.ret.sptk.many rp
    101 
    102 	/*
    103 	 * In theory, we'd have to zap this state only to prevent leaking of
    104 	 * security sensitive state (e.g., if current->mm->dumpable is zero).  However,
    105 	 * this executes in less than 20 cycles even on Itanium, so it's not worth
    106 	 * optimizing for...).
    107 	 */
    108 	mov r4=0;		mov f2=f0;		mov b1=r0
    109 	mov r5=0;		mov f3=f0;		mov b2=r0
    110 	mov r6=0;		mov f4=f0;		mov b3=r0
    111 	mov r7=0;		mov f5=f0;		mov b4=r0
    112 	mov ar.unat=0;		mov f10=f0;		mov b5=r0
    113 	ldf.fill f11=[sp];	ldf.fill f12=[sp];	mov f13=f0
    114 	ldf.fill f14=[sp];	ldf.fill f15=[sp];	mov f16=f0
    115 	ldf.fill f17=[sp];	ldf.fill f18=[sp];	mov f19=f0
    116 	ldf.fill f20=[sp];	ldf.fill f21=[sp];	mov f22=f0
    117 	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
    118 	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
    119 	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
    120 	mov ar.lc=0
    121 	br.ret.sptk.many rp
    122 	.align 16
    123 .fptr_execve:
    124 	data8 @fptr(my_sys_execve)
    125 END(my_ia64_execve)
    126 
    127 /* These interceptors are from IA64syscallstub.h macros */
    128 #include "IA64syscallstub.h"
    129 
    130 SYSCALLSTUB_POST(clone)
    131 
    132 SYSCALLSTUB_POST(clone2)
    133 
    134 SYSCALLSTUB_POST(mmap)
    135 
    136 SYSCALLSTUB_POST(mmap2)
    137 
    138 SYSCALLSTUB_POST(init_module)
    139 
    140 SYSCALLSTUB_PRE(exit)
    141