18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file oprofile_stubs.S
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Assembly language system call interceptor stubs
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2001-2002 Hewlett-Packard Company
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Bob Montgomery <bob_montgomery@hp.com>
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This interceptor for execve was stolen from ia64/kernel/entry.S
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Kernel entry points.
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright (C) 1998-2001 Hewlett-Packard Co
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	David Mosberger-Tang <davidm@hpl.hp.com>
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright (C) 1999 VA Linux Systems
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com>
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com>
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * ia64_switch_to now places correct virtual mapping in in TR2 for
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * kernel stack. This allows us to handle interrupts without changing
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * to physical mode.
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Jonathan Nicklin	<nicklin@missioncriticallinux.com>
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Patrick O'Rourke	<orourke@missioncriticallinux.com>
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 11/07/2000
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Global (preserved) predicate usage on syscall entry/exit path:
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	pKern:		See entry.h.
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	pUser:		See entry.h.
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	pSys:		See entry.h.
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	pNonSys:	!pSys
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <linux/config.h>
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/cache.h>
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/errno.h>
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/kregs.h>
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/offsets.h>
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/processor.h>
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/unistd.h>
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/asmmacro.h>
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <asm/pgtable.h>
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "IA64minstate.h"
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/*
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * execve() is special because in case of success, we need to
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * setup a null register window frame.
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddGLOBAL_ENTRY(my_ia64_execve)
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	alloc loc1=ar.pfs, 3, 3, 4, 0
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov loc0=rp
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov loc2=gp
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	.body
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov out0=in0			// filename
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;				// stop bit between alloc and call
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov out1=in1			// argv
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov out2=in2			// envp
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add out3=16, sp			// regs
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/*
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * We are here with the kernel's gp register value but we need
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * to find the module's gp value before we can call our own
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * routine.  That's why we can't just use:
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 *	br.call.sptk.many rp=my_sys_execve
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Use ip-relative addressing to get to the fptr since I can't
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * use gp-relative anything without the module's gp.
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.L1_execve:
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r3 = ip
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	addl r14 = .fptr_execve - .L1_execve, r3
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ld8 r14=[r14]
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ld8 r15=[r14], 8
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ld8 gp=[r14]
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov b6=r15
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	br.call.sptk.many b0=b6
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.ret0:	cmp4.ge p6, p7=r8, r0
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov ar.pfs=loc1			// restore ar.pfs
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sxt4 r8=r8			// return 64-bit result
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	stf.spill [sp]=f0
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(p6)	cmp.ne pKern, pUser=r0, r0	// a successful execve() lands us in user-mode...
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov gp=loc2
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rp=loc0
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(p6)	mov ar.pfs=r0			// clear ar.pfs on success
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(p7)	br.ret.sptk.many rp
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/*
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * In theory, we'd have to zap this state only to prevent leaking of
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * security sensitive state (e.g., if current->mm->dumpable is zero).  However,
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * this executes in less than 20 cycles even on Itanium, so it's not worth
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * optimizing for...).
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r4=0;		mov f2=f0;		mov b1=r0
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r5=0;		mov f3=f0;		mov b2=r0
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r6=0;		mov f4=f0;		mov b3=r0
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r7=0;		mov f5=f0;		mov b4=r0
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov ar.unat=0;		mov f10=f0;		mov b5=r0
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ldf.fill f11=[sp];	ldf.fill f12=[sp];	mov f13=f0
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ldf.fill f14=[sp];	ldf.fill f15=[sp];	mov f16=f0
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ldf.fill f17=[sp];	ldf.fill f18=[sp];	mov f19=f0
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ldf.fill f20=[sp];	ldf.fill f21=[sp];	mov f22=f0
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov ar.lc=0
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	br.ret.sptk.many rp
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	.align 16
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.fptr_execve:
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	data8 @fptr(my_sys_execve)
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddEND(my_ia64_execve)
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* These interceptors are from IA64syscallstub.h macros */
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "IA64syscallstub.h"
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddSYSCALLSTUB_POST(clone)
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddSYSCALLSTUB_POST(clone2)
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddSYSCALLSTUB_POST(mmap)
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddSYSCALLSTUB_POST(mmap2)
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddSYSCALLSTUB_POST(init_module)
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddSYSCALLSTUB_PRE(exit)
141