syscall.S 18.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
/* 
Matthew Wilcox's avatar
Matthew Wilcox committed
2
 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
Linus Torvalds's avatar
Linus Torvalds committed
3 4 5 6 7 8 9
 * 
 * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
 * Licensed under the GNU GPL.
 * thanks to Philipp Rumpf, Mike Shaver and various others
 * sorry about the wall, puffin..
 */

Matthew Wilcox's avatar
Matthew Wilcox committed
10
#include <asm/offsets.h>
Linus Torvalds's avatar
Linus Torvalds committed
11 12 13
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/psw.h>
Matthew Wilcox's avatar
Matthew Wilcox committed
14
#include <asm/thread_info.h>
Linus Torvalds's avatar
Linus Torvalds committed
15 16 17 18 19 20 21 22 23 24

#include <asm/assembly.h>
#include <asm/processor.h>

#ifdef __LP64__
	.level          2.0w
#else
	.level		1.1
#endif
	.text
Matthew Wilcox's avatar
Matthew Wilcox committed
25

Linus Torvalds's avatar
Linus Torvalds committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
	.import syscall_exit,code
	.import syscall_exit_rfi,code
	.export linux_gateway_page

	/* Linux gateway page is aliased to virtual page 0 in the kernel
	 * address space. Since it is a gateway page it cannot be
	 * dereferenced, so null pointers will still fault. We start
	 * the actual entry point at 0x100. We put break instructions
	 * at the beginning of the page to trap null indirect function
	 * pointers.
	 */

	.align 4096
linux_gateway_page:

Matthew Wilcox's avatar
Matthew Wilcox committed
41 42 43 44 45 46 47 48 49 50 51
	.rept 56
	break   0,0
	.endr

set_thread_pointer:
	gate	.+8, %r0		/* increase privilege */
	depi	3, 31, 2, %r31		/* Ensure we return into user mode. */
	be	0(%sr7,%r31)		/* return to user space */
	mtctl	%r26, %cr27		/* move arg0 to the control register */

	.rept 4
Linus Torvalds's avatar
Linus Torvalds committed
52
	break   0,0
Matthew Wilcox's avatar
Matthew Wilcox committed
53
	.endr
Linus Torvalds's avatar
Linus Torvalds committed
54

Matthew Wilcox's avatar
Matthew Wilcox committed
55
/* This address must remain fixed, or user binaries go splat. */
Linus Torvalds's avatar
Linus Torvalds committed
56 57 58 59 60 61
	.align 256
linux_gateway_entry:
	gate	.+8, %r0			/* become privileged */
	mtsp	%r0,%sr4			/* get kernel space into sr4 */
	mtsp	%r0,%sr5			/* get kernel space into sr5 */
	mtsp	%r0,%sr6			/* get kernel space into sr6 */
Matthew Wilcox's avatar
Matthew Wilcox committed
62 63 64
	mfsp    %sr7,%r1                        /* save user sr7 */
	mtsp    %r1,%sr3                        /* and store it in sr3 */

Linus Torvalds's avatar
Linus Torvalds committed
65 66 67 68 69 70 71 72
#ifdef __LP64__
	/* for now we can *always* set the W bit on entry to the syscall
	 * since we don't support wide userland processes.  We could
	 * also save the current SM other than in r0 and restore it on
	 * exit from the syscall, and also use that value to know
	 * whether to do narrow or wide syscalls. -PB
	 */
	ssm	PSW_SM_W, %r0
Matthew Wilcox's avatar
Matthew Wilcox committed
73 74 75 76 77 78 79 80 81
	/* The top halves of argument registers must be cleared on syscall
	 * entry.
	 */
	depdi	0, 31, 32, %r26
	depdi	0, 31, 32, %r25
	depdi	0, 31, 32, %r24
	depdi	0, 31, 32, %r23
	depdi	0, 31, 32, %r22
	depdi	0, 31, 32, %r21
Linus Torvalds's avatar
Linus Torvalds committed
82
#endif
Matthew Wilcox's avatar
Matthew Wilcox committed
83 84 85 86 87 88 89 90 91 92 93 94 95
	mfctl   %cr30,%r1
	xor     %r1,%r30,%r30                   /* ye olde xor trick */
	xor     %r1,%r30,%r1
	xor     %r1,%r30,%r30
	ldo     THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30  /* set up kernel stack */

	/* N.B.: It is critical that we don't set sr7 to 0 until r30
	 *       contains a valid kernel stack pointer. It is also
	 *       critical that we don't start using the kernel stack
	 *       until after sr7 has been set to 0.
	 */

	mtsp	%r0,%sr7			/* get kernel space into sr7 */
96 97 98
	STREGM	%r1,FRAME_SIZE(%r30)		/* save r1 (usp) here for now */
	mfctl	%cr30,%r1			/* get task ptr in %r1 */
	LDREG	TI_TASK(%r1),%r1
Linus Torvalds's avatar
Linus Torvalds committed
99 100 101

	/* Save some registers for sigcontext and potential task
	   switch (see entry.S for the details of which ones are
Matthew Wilcox's avatar
Matthew Wilcox committed
102 103 104 105
	   saved/restored).  TASK_PT_PSW is zeroed so we can see whether
	   a process is on a syscall or not.  For an interrupt the real
	   PSW value is stored.  This is needed for gdb and sys_ptrace. */
	STREG	%r0,  TASK_PT_PSW(%r1)
Linus Torvalds's avatar
Linus Torvalds committed
106
	STREG	%r2,  TASK_PT_GR2(%r1)		/* preserve rp */
107
	LDREGM	-FRAME_SIZE(%r30), %r2		/* get users sp back */
Matthew Wilcox's avatar
Matthew Wilcox committed
108
	STREG	%r2,  TASK_PT_GR30(%r1)		/* ... and save it */
Linus Torvalds's avatar
Linus Torvalds committed
109 110 111 112 113 114 115 116 117
	STREG	%r19, TASK_PT_GR19(%r1)
	STREG	%r20, TASK_PT_GR20(%r1)
	STREG	%r21, TASK_PT_GR21(%r1)
	STREG	%r22, TASK_PT_GR22(%r1)
	STREG	%r23, TASK_PT_GR23(%r1)		/* 4th argument */
	STREG	%r24, TASK_PT_GR24(%r1)		/* 3rd argument */
	STREG	%r25, TASK_PT_GR25(%r1)		/* 2nd argument */
	STREG	%r26, TASK_PT_GR26(%r1)	 	/* 1st argument */
	STREG	%r27, TASK_PT_GR27(%r1)		/* user dp */
Matthew Wilcox's avatar
Matthew Wilcox committed
118 119
	STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
	STREG   %r28, TASK_PT_ORIG_R28(%r1)     /* return value 0 (saved for signals) */
Linus Torvalds's avatar
Linus Torvalds committed
120 121 122 123 124 125 126 127 128 129 130
	STREG	%r29, TASK_PT_GR29(%r1)		/* return value 1 */
	STREG	%r31, TASK_PT_GR31(%r1)		/* preserve syscall return ptr */
	
	ldo	TASK_PT_FR0(%r1), %r27		/* save fpregs from the kernel */
	save_fp	%r27				/* or potential task switch  */

	mfctl	%cr11, %r27			/* i.e. SAR */
	STREG	%r27, TASK_PT_SAR(%r1)

	loadgp

Matthew Wilcox's avatar
Matthew Wilcox committed
131 132 133 134
#ifdef __LP64__
	ldo	-16(%r30),%r29			/* Reference param save area */
#else
	/* no need to save these on stack in wide mode because the first 8
Linus Torvalds's avatar
Linus Torvalds committed
135 136 137 138 139
	 * args are passed in registers */
	stw     %r22, -52(%r30)                 /* 5th argument */
	stw     %r21, -56(%r30)                 /* 6th argument */
#endif

Matthew Wilcox's avatar
Matthew Wilcox committed
140 141 142
	mfctl	%cr30, %r1
	LDREG	TI_FLAGS(%r1), %r19
	bb,<,n	%r19,31-TIF_SYSCALL_TRACE,.Ltracesys
Linus Torvalds's avatar
Linus Torvalds committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
	
	/* Note!  We cannot use the syscall table that is mapped
	nearby since the gateway page is mapped execute-only. */

	ldil	L%sys_call_table, %r1
	ldo     R%sys_call_table(%r1), %r19
	
	comiclr,>>=	__NR_Linux_syscalls, %r20, %r0
	b,n	.Lsyscall_nosys
	
#ifdef __LP64__
	ldd,s   %r20(%r19), %r19
#else
	ldwx,s  %r20(%r19), %r19
#endif
	/* If this is a sys_rt_sigreturn call, and the signal was received
	 * when not in_syscall, then we want to return via syscall_exit_rfi,
	 * not syscall_exit.  Signal no. in r20, in_syscall in r25 (see
	 * trampoline code in signal.c).
	 */
	ldi	__NR_rt_sigreturn,%r2
	comb,=	%r2,%r20,.Lrt_sigreturn
.Lin_syscall:
	ldil	L%syscall_exit,%r2
	be      0(%sr7,%r19)
	ldo	R%syscall_exit(%r2),%r2
.Lrt_sigreturn:
	comib,<> 0,%r25,.Lin_syscall
	ldil	L%syscall_exit_rfi,%r2
	be      0(%sr7,%r19)
	ldo	R%syscall_exit_rfi(%r2),%r2

	/* Note!  Because we are not running where we were linked, any
	calls to functions external to this file must be indirect.  To
	be safe, we apply the opposite rule to functions within this
	file, with local labels given to them to ensure correctness. */
	
.Lsyscall_nosys:
syscall_nosys:
	ldil	L%syscall_exit,%r1
	be	R%syscall_exit(%sr7,%r1)
	ldo	-ENOSYS(%r0),%r28		   /* set errno */


/* Warning! This trace code is a virtual duplicate of the code above so be
 * sure to maintain both! */
.Ltracesys:
tracesys:
	/* Need to save more registers so the debugger can see where we
Matthew Wilcox's avatar
Matthew Wilcox committed
192 193 194 195 196 197 198
	 * are.  This saves only the lower 8 bits of PSW, so that the C
	 * bit is still clear on syscalls, and the D bit is set if this
	 * full register save path has been executed.  We check the D
	 * bit on syscall_return_rfi to determine which registers to
	 * restore.  An interrupt results in a full PSW saved with the
	 * C bit set, a non-straced syscall entry results in C and D clear
	 * in the saved PSW.
Linus Torvalds's avatar
Linus Torvalds committed
199
	 */
Matthew Wilcox's avatar
Matthew Wilcox committed
200
	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
201
	LDREG	TI_TASK(%r1), %r1
Matthew Wilcox's avatar
Matthew Wilcox committed
202 203
	ssm	0,%r2
	STREG	%r2,TASK_PT_PSW(%r1)		/* Lower 8 bits only!! */
Linus Torvalds's avatar
Linus Torvalds committed
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
	mfsp	%sr0,%r2
	STREG	%r2,TASK_PT_SR0(%r1)
	mfsp	%sr1,%r2
	STREG	%r2,TASK_PT_SR1(%r1)
	mfsp	%sr2,%r2
	STREG	%r2,TASK_PT_SR2(%r1)
	mfsp	%sr3,%r2
	STREG	%r2,TASK_PT_SR3(%r1)
	STREG	%r2,TASK_PT_SR4(%r1)
	STREG	%r2,TASK_PT_SR5(%r1)
	STREG	%r2,TASK_PT_SR6(%r1)
	STREG	%r2,TASK_PT_SR7(%r1)
	STREG	%r2,TASK_PT_IASQ0(%r1)
	STREG	%r2,TASK_PT_IASQ1(%r1)
	LDREG	TASK_PT_GR31(%r1),%r2
	STREG	%r2,TASK_PT_IAOQ0(%r1)
	ldo	4(%r2),%r2
	STREG	%r2,TASK_PT_IAOQ1(%r1)
	ldo	TASK_REGS(%r1),%r2
	/* reg_save %r2 */
	STREG	%r3,PT_GR3(%r2)
	STREG	%r4,PT_GR4(%r2)
	STREG	%r5,PT_GR5(%r2)
	STREG	%r6,PT_GR6(%r2)
	STREG	%r7,PT_GR7(%r2)
	STREG	%r8,PT_GR8(%r2)
	STREG	%r9,PT_GR9(%r2)
	STREG	%r10,PT_GR10(%r2)
	STREG	%r11,PT_GR11(%r2)
	STREG	%r12,PT_GR12(%r2)
	STREG	%r13,PT_GR13(%r2)
	STREG	%r14,PT_GR14(%r2)
	STREG	%r15,PT_GR15(%r2)
	STREG	%r16,PT_GR16(%r2)
	STREG	%r17,PT_GR17(%r2)
	STREG	%r18,PT_GR18(%r2)
	/* Finished saving things for the debugger */

	ldil	L%syscall_trace,%r1
	ldil	L%tracesys_next,%r2
	be	R%syscall_trace(%sr7,%r1)
	ldo	R%tracesys_next(%r2),%r2
	
tracesys_next:	
	ldil	L%sys_call_table,%r1
	ldo     R%sys_call_table(%r1), %r19

Matthew Wilcox's avatar
Matthew Wilcox committed
251
	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
252
	LDREG	TI_TASK(%r1), %r1
Linus Torvalds's avatar
Linus Torvalds committed
253 254 255 256 257 258 259 260
	LDREG   TASK_PT_GR20(%r1), %r20
	LDREG   TASK_PT_GR26(%r1), %r26		/* Restore the users args */
	LDREG   TASK_PT_GR25(%r1), %r25
	LDREG   TASK_PT_GR24(%r1), %r24
	LDREG   TASK_PT_GR23(%r1), %r23
#ifdef __LP64__
	LDREG   TASK_PT_GR22(%r1), %r22
	LDREG   TASK_PT_GR21(%r1), %r21
Matthew Wilcox's avatar
Matthew Wilcox committed
261
	ldo	-16(%r30),%r29			/* Reference param save area */
Linus Torvalds's avatar
Linus Torvalds committed
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
#endif

	comiclr,>>=	__NR_Linux_syscalls, %r20, %r0
	b,n	.Lsyscall_nosys

#ifdef __LP64__
	ldd,s   %r20(%r19), %r19
#else
	ldwx,s  %r20(%r19), %r19
#endif
	/* If this is a sys_rt_sigreturn call, and the signal was received
	 * when not in_syscall, then we want to return via syscall_exit_rfi,
	 * not syscall_exit.  Signal no. in r20, in_syscall in r25 (see
	 * trampoline code in signal.c).
	 */
	ldi	__NR_rt_sigreturn,%r2
	comb,=	%r2,%r20,.Ltrace_rt_sigreturn
.Ltrace_in_syscall:
	ldil	L%tracesys_exit,%r2
	be      0(%sr7,%r19)
	ldo	R%tracesys_exit(%r2),%r2

	/* Do *not* call this function on the gateway page, because it
	makes a direct call to syscall_trace. */
	
tracesys_exit:
Matthew Wilcox's avatar
Matthew Wilcox committed
288
	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
289
	LDREG	TI_TASK(%r1), %r1
Matthew Wilcox's avatar
Matthew Wilcox committed
290 291 292
#ifdef __LP64__
	ldo	-16(%r30),%r29			/* Reference param save area */
#endif
Linus Torvalds's avatar
Linus Torvalds committed
293 294
	bl	syscall_trace, %r2
	STREG   %r28,TASK_PT_GR28(%r1)          /* save return value now */
Matthew Wilcox's avatar
Matthew Wilcox committed
295
	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
296
	LDREG	TI_TASK(%r1), %r1
Linus Torvalds's avatar
Linus Torvalds committed
297 298 299 300 301 302 303 304 305 306 307 308
	LDREG   TASK_PT_GR28(%r1), %r28		/* Restore return val. */

	ldil	L%syscall_exit,%r1
	be,n	R%syscall_exit(%sr7,%r1)

.Ltrace_rt_sigreturn:
	comib,<> 0,%r25,.Ltrace_in_syscall
	ldil	L%tracesys_sigexit,%r2
	be      0(%sr7,%r19)
	ldo	R%tracesys_sigexit(%r2),%r2

tracesys_sigexit:
Matthew Wilcox's avatar
Matthew Wilcox committed
309 310 311 312 313
	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
	LDREG	0(%r1), %r1
#ifdef __LP64__
	ldo	-16(%r30),%r29			/* Reference param save area */
#endif
Linus Torvalds's avatar
Linus Torvalds committed
314 315 316 317 318 319 320 321 322
	bl	syscall_trace, %r2
	nop

	ldil	L%syscall_exit_rfi,%r1
	be,n	R%syscall_exit_rfi(%sr7,%r1)

#ifdef __LP64__
/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
 * narrow palinux.  Use ENTRY_DIFF for those where a 32-bit specific
323 324
 * implementation is required on wide palinux.  Use ENTRY_COMP where
 * the compatability layer has a useful 32-bit implementation.
Linus Torvalds's avatar
Linus Torvalds committed
325 326 327
 */
#define ENTRY_SAME(_name_) .dword sys_##_name_
#define ENTRY_DIFF(_name_) .dword sys32_##_name_
Matthew Wilcox's avatar
Matthew Wilcox committed
328
#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
Matthew Wilcox's avatar
Matthew Wilcox committed
329
#define ENTRY_OURS(_name_) .dword parisc_##_name_
330
#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
Linus Torvalds's avatar
Linus Torvalds committed
331 332 333 334
#else
#define ENTRY_SAME(_name_) .word sys_##_name_
#define ENTRY_DIFF(_name_) .word sys_##_name_
#define ENTRY_UHOH(_name_) .word sys_##_name_
Matthew Wilcox's avatar
Matthew Wilcox committed
335
#define ENTRY_OURS(_name_) .word parisc_##_name_
336
#define ENTRY_COMP(_name_) .word sys_##_name_
Linus Torvalds's avatar
Linus Torvalds committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
#endif

	.align 8
	.export sys_call_table
.Lsys_call_table:
sys_call_table:
	ENTRY_SAME(ni_syscall)	/* 0  -  old "setup()" system call*/
	ENTRY_SAME(exit)
	ENTRY_SAME(fork_wrapper)
	ENTRY_SAME(read)
	ENTRY_SAME(write)
	ENTRY_SAME(open)		/* 5 */
	ENTRY_SAME(close)
	ENTRY_SAME(waitpid)
	ENTRY_SAME(creat)
	ENTRY_SAME(link)
	ENTRY_SAME(unlink)		/* 10 */
	ENTRY_DIFF(execve_wrapper)
	ENTRY_SAME(chdir)
	/* See comments in kernel/time.c!!! Maybe we don't need this? */
	ENTRY_DIFF(time)
	ENTRY_SAME(mknod)
	ENTRY_SAME(chmod)		/* 15 */
	ENTRY_SAME(lchown)
	ENTRY_SAME(socket)
	/* struct stat is MAYBE identical wide and narrow ?? */
363
	ENTRY_COMP(newstat)
Matthew Wilcox's avatar
Matthew Wilcox committed
364
	ENTRY_DIFF(lseek)
Linus Torvalds's avatar
Linus Torvalds committed
365 366 367 368 369 370 371 372 373 374 375 376 377
	ENTRY_SAME(getpid)		/* 20 */
	/* the 'void * data' parameter may need re-packing in wide */
	ENTRY_DIFF(mount)
	/* concerned about struct sockaddr in wide/narrow */
	/* ---> I think sockaddr is OK unless the compiler packs the struct */
	/*      differently to align the char array */
	ENTRY_SAME(bind)
	ENTRY_SAME(setuid)
	ENTRY_SAME(getuid)
	ENTRY_SAME(stime)		/* 25 */
	ENTRY_SAME(ptrace)
	ENTRY_SAME(alarm)
	/* see stat comment */
378
	ENTRY_COMP(newfstat)
Linus Torvalds's avatar
Linus Torvalds committed
379 380
	ENTRY_SAME(pause)
	/* struct utimbuf uses time_t which might vary */
381
	ENTRY_COMP(utime)		/* 30 */
Linus Torvalds's avatar
Linus Torvalds committed
382 383 384 385 386 387 388 389 390 391 392 393 394 395
	/* struct sockaddr... */
	ENTRY_SAME(connect)
	ENTRY_SAME(listen)
	ENTRY_SAME(access)
	ENTRY_SAME(nice)
	/* struct sockaddr... */
	ENTRY_SAME(accept)		/* 35 */
	ENTRY_SAME(sync)
	ENTRY_SAME(kill)
	ENTRY_SAME(rename)
	ENTRY_SAME(mkdir)
	ENTRY_SAME(rmdir)		/* 40 */
	ENTRY_SAME(dup)
	ENTRY_SAME(pipe)
396
	ENTRY_COMP(times)
Linus Torvalds's avatar
Linus Torvalds committed
397 398 399
	/* struct sockaddr... */
	ENTRY_SAME(getsockname)
	/* it seems possible brk() could return a >4G pointer... */
Matthew Wilcox's avatar
Matthew Wilcox committed
400
	ENTRY_SAME(brk)			/* 45 */
Linus Torvalds's avatar
Linus Torvalds committed
401 402 403 404 405 406 407 408 409 410 411
	ENTRY_SAME(setgid)
	ENTRY_SAME(getgid)
	ENTRY_SAME(signal)
	ENTRY_SAME(geteuid)
	ENTRY_SAME(getegid)		/* 50 */
	ENTRY_SAME(acct)
	ENTRY_SAME(umount)
	/* struct sockaddr... */
	ENTRY_SAME(getpeername)
	/* This one's a huge ugly mess */
	ENTRY_DIFF(ioctl)
412
	ENTRY_COMP(fcntl)		/* 55 */
Linus Torvalds's avatar
Linus Torvalds committed
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
	ENTRY_SAME(socketpair)
	ENTRY_SAME(setpgid)
	ENTRY_SAME(send)
	ENTRY_SAME(newuname)
	ENTRY_SAME(umask)		/* 60 */
	ENTRY_SAME(chroot)
	ENTRY_SAME(ustat)
	ENTRY_SAME(dup2)
	ENTRY_SAME(getppid)
	ENTRY_SAME(getpgrp)		/* 65 */
	ENTRY_SAME(setsid)
	ENTRY_SAME(pivot_root)
	/* I don't like this */
	ENTRY_UHOH(sgetmask)
	ENTRY_UHOH(ssetmask)
428
	ENTRY_SAME(setreuid)		/* 70 */
Linus Torvalds's avatar
Linus Torvalds committed
429 430
	ENTRY_SAME(setregid)
	ENTRY_SAME(mincore)
431
	ENTRY_COMP(sigpending)
Linus Torvalds's avatar
Linus Torvalds committed
432 433
	ENTRY_SAME(sethostname)
	/* Following 3 have linux-common-code structs containing longs -( */
434
	ENTRY_DIFF(setrlimit)		/* 75 */
Linus Torvalds's avatar
Linus Torvalds committed
435 436 437
	ENTRY_DIFF(getrlimit)
	ENTRY_DIFF(getrusage)
	/* struct timeval and timezone are maybe?? consistent wide and narrow */
Matthew Wilcox's avatar
Matthew Wilcox committed
438 439
	ENTRY_DIFF(gettimeofday)
	ENTRY_DIFF(settimeofday)
440
	ENTRY_SAME(getgroups)		/* 80 */
Linus Torvalds's avatar
Linus Torvalds committed
441 442 443 444 445
	ENTRY_SAME(setgroups)
	/* struct socketaddr... */
	ENTRY_SAME(sendto)
	ENTRY_SAME(symlink)
	/* see stat comment */
446
	ENTRY_COMP(newlstat)
447 448
	ENTRY_SAME(readlink)		/* 85 */
	ENTRY_SAME(ni_syscall)	/* was uselib */
Linus Torvalds's avatar
Linus Torvalds committed
449 450
	ENTRY_SAME(swapon)
	ENTRY_SAME(reboot)
Matthew Wilcox's avatar
Matthew Wilcox committed
451
	ENTRY_SAME(mmap2)
Linus Torvalds's avatar
Linus Torvalds committed
452 453 454 455 456 457 458 459 460
	ENTRY_SAME(mmap)		/* 90 */
	ENTRY_SAME(munmap)
	ENTRY_SAME(truncate)
	ENTRY_SAME(ftruncate)
	ENTRY_SAME(fchmod)
	ENTRY_SAME(fchown)		/* 95 */
	ENTRY_SAME(getpriority)
	ENTRY_SAME(setpriority)
	ENTRY_SAME(recv)
461 462
	ENTRY_COMP(statfs)
	ENTRY_COMP(fstatfs)		/* 100 */
Matthew Wilcox's avatar
Matthew Wilcox committed
463
	ENTRY_SAME(stat64)
464
	ENTRY_SAME(ni_syscall)	/* was socketcall */
Linus Torvalds's avatar
Linus Torvalds committed
465 466 467
	ENTRY_SAME(syslog)
	/* even though manpage says struct timeval contains longs, ours has
	 * time_t and suseconds_t -- both of which are safe wide/narrow */
468
	ENTRY_COMP(setitimer)
469
	ENTRY_COMP(getitimer)		/* 105 */
Linus Torvalds's avatar
Linus Torvalds committed
470 471
	ENTRY_SAME(capget)
	ENTRY_SAME(capset)
Matthew Wilcox's avatar
Matthew Wilcox committed
472 473
	ENTRY_OURS(pread64)
	ENTRY_OURS(pwrite64)
Linus Torvalds's avatar
Linus Torvalds committed
474 475
	ENTRY_SAME(getcwd)		/* 110 */
	ENTRY_SAME(vhangup)
Matthew Wilcox's avatar
Matthew Wilcox committed
476
	ENTRY_SAME(fstat64)
Linus Torvalds's avatar
Linus Torvalds committed
477 478 479 480
	ENTRY_SAME(vfork_wrapper)
	/* struct rusage contains longs... */
	ENTRY_DIFF(wait4)
	ENTRY_SAME(swapoff)		/* 115 */
Matthew Wilcox's avatar
Matthew Wilcox committed
481
	ENTRY_DIFF(sysinfo)
Linus Torvalds's avatar
Linus Torvalds committed
482 483 484 485 486 487 488 489 490
	ENTRY_SAME(shutdown)
	ENTRY_SAME(fsync)
	ENTRY_SAME(madvise)
	ENTRY_SAME(clone_wrapper)	/* 120 */
	ENTRY_SAME(setdomainname)
	ENTRY_SAME(sendfile)
	/* struct sockaddr... */
	ENTRY_SAME(recvfrom)
	/* struct timex contains longs */
Matthew Wilcox's avatar
Matthew Wilcox committed
491
	ENTRY_DIFF(adjtimex)
492
	ENTRY_SAME(mprotect)		/* 125 */
Linus Torvalds's avatar
Linus Torvalds committed
493
	/* old_sigset_t forced to 32 bits.  Beware glibc sigset_t */
494 495
	ENTRY_COMP(sigprocmask)
	ENTRY_SAME(ni_syscall)	/* create_module */
Linus Torvalds's avatar
Linus Torvalds committed
496 497
	ENTRY_SAME(init_module)
	ENTRY_SAME(delete_module)
498
	ENTRY_SAME(ni_syscall)		/* 130: get_kernel_syms */
Matthew Wilcox's avatar
Matthew Wilcox committed
499 500
	/* time_t inside struct dqblk */
	ENTRY_DIFF(quotactl) /* -- FIXME, doesn't work */
Linus Torvalds's avatar
Linus Torvalds committed
501 502
	ENTRY_SAME(getpgid)
	ENTRY_SAME(fchdir)
Matthew Wilcox's avatar
Matthew Wilcox committed
503
	ENTRY_SAME(bdflush)
Linus Torvalds's avatar
Linus Torvalds committed
504 505 506 507 508 509 510 511 512 513 514 515
	ENTRY_SAME(sysfs)		/* 135 */
	ENTRY_SAME(personality)
	ENTRY_SAME(ni_syscall)	/* for afs_syscall */
	ENTRY_SAME(setfsuid)
	ENTRY_SAME(setfsgid)
	/* I think this might work */
	ENTRY_SAME(llseek)		/* 140 */
	/* struct linux_dirent has longs, like 'unsigned long d_ino' which
	 * almost definitely should be 'ino_t d_ino' but it's too late now */
	ENTRY_DIFF(getdents)
	/* it is POSSIBLE that select will be OK because even though fd_set
	 * contains longs, the macros and sizes are clever. */
Matthew Wilcox's avatar
Matthew Wilcox committed
516
	ENTRY_DIFF(select)
Linus Torvalds's avatar
Linus Torvalds committed
517 518 519
	ENTRY_SAME(flock)
	ENTRY_SAME(msync)
	/* struct iovec contains pointers */
Matthew Wilcox's avatar
Matthew Wilcox committed
520 521
	ENTRY_DIFF(readv)		/* 145 */
	ENTRY_DIFF(writev)
Linus Torvalds's avatar
Linus Torvalds committed
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
	ENTRY_SAME(getsid)
	ENTRY_SAME(fdatasync)
	/* struct __sysctl_args is a mess */
	ENTRY_DIFF(sysctl)
	ENTRY_SAME(mlock)		/* 150 */
	ENTRY_SAME(munlock)
	ENTRY_SAME(mlockall)
	ENTRY_SAME(munlockall)
	/* struct sched_param is ok for now */
	ENTRY_SAME(sched_setparam)
	ENTRY_SAME(sched_getparam)	/* 155 */
	ENTRY_SAME(sched_setscheduler)
	ENTRY_SAME(sched_getscheduler)
	ENTRY_SAME(sched_yield)
	ENTRY_SAME(sched_get_priority_max)
	ENTRY_SAME(sched_get_priority_min)	/* 160 */
	/* These 2 would've worked if someone had defined struct timespec
	 * carefully, like timeval for example (which is about the same).
	 * Unfortunately it contains a long :-( */
	ENTRY_DIFF(sched_rr_get_interval)
542
	ENTRY_COMP(nanosleep)
Linus Torvalds's avatar
Linus Torvalds committed
543 544
	ENTRY_SAME(mremap)
	ENTRY_SAME(setresuid)
545
	ENTRY_SAME(getresuid)		/* 165 */
Matthew Wilcox's avatar
Matthew Wilcox committed
546
	ENTRY_DIFF(sigaltstack_wrapper)
547
	ENTRY_SAME(ni_syscall)		/* query_module */
Linus Torvalds's avatar
Linus Torvalds committed
548 549
	ENTRY_SAME(poll)
	/* structs contain pointers and an in_addr... */
Matthew Wilcox's avatar
Matthew Wilcox committed
550
	ENTRY_DIFF(nfsservctl)
551
	ENTRY_SAME(setresgid)		/* 170 */
Linus Torvalds's avatar
Linus Torvalds committed
552 553 554 555 556 557 558 559
	ENTRY_SAME(getresgid)
	ENTRY_SAME(prctl)
	/* signals need a careful review */
	ENTRY_SAME(rt_sigreturn_wrapper)
	ENTRY_DIFF(rt_sigaction)
	ENTRY_DIFF(rt_sigprocmask)	/* 175 */
	ENTRY_DIFF(rt_sigpending)
	ENTRY_UHOH(rt_sigtimedwait)
Matthew Wilcox's avatar
Matthew Wilcox committed
560 561 562 563 564 565 566
	/* even though the struct siginfo_t is different, it appears like
	 * all the paths use values which should be same wide and narrow.
	 * Also the struct is padded to 128 bytes which means we don't have
	 * to worry about faulting trying to copy in a larger 64-bit
	 * struct from a 32-bit user-space app.
	 */
	ENTRY_SAME(rt_sigqueueinfo)
Linus Torvalds's avatar
Linus Torvalds committed
567 568
	ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
	ENTRY_SAME(chown)		/* 180 */
Matthew Wilcox's avatar
Matthew Wilcox committed
569 570
	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
	ENTRY_DIFF(setsockopt)
Linus Torvalds's avatar
Linus Torvalds committed
571
	ENTRY_SAME(getsockopt)
Matthew Wilcox's avatar
Matthew Wilcox committed
572 573
	ENTRY_DIFF(sendmsg)
	ENTRY_DIFF(recvmsg)
Linus Torvalds's avatar
Linus Torvalds committed
574 575
	ENTRY_SAME(semop)		/* 185 */
	ENTRY_SAME(semget)
Matthew Wilcox's avatar
Matthew Wilcox committed
576 577 578
	ENTRY_DIFF(semctl_broken)
	ENTRY_DIFF(msgsnd)
	ENTRY_DIFF(msgrcv)
Linus Torvalds's avatar
Linus Torvalds committed
579
	ENTRY_SAME(msgget)		/* 190 */
Matthew Wilcox's avatar
Matthew Wilcox committed
580
	ENTRY_SAME(msgctl_broken)
Linus Torvalds's avatar
Linus Torvalds committed
581 582 583
	ENTRY_SAME(shmat_wrapper)
	ENTRY_SAME(shmdt)
	ENTRY_SAME(shmget)
Matthew Wilcox's avatar
Matthew Wilcox committed
584
	ENTRY_SAME(shmctl_broken)	/* 195 */
Linus Torvalds's avatar
Linus Torvalds committed
585 586
	ENTRY_SAME(ni_syscall)		/* streams1 */
	ENTRY_SAME(ni_syscall)		/* streams2 */
Matthew Wilcox's avatar
Matthew Wilcox committed
587
	ENTRY_SAME(lstat64)
Matthew Wilcox's avatar
Matthew Wilcox committed
588 589
	ENTRY_OURS(truncate64)
	ENTRY_OURS(ftruncate64)		/* 200 */
Matthew Wilcox's avatar
Matthew Wilcox committed
590
	ENTRY_SAME(getdents64)
591
	ENTRY_COMP(fcntl64)
Matthew Wilcox's avatar
Matthew Wilcox committed
592 593
	ENTRY_SAME(ni_syscall)
	ENTRY_SAME(ni_syscall)
594
	ENTRY_SAME(ni_syscall)		/* 205 */
Matthew Wilcox's avatar
Matthew Wilcox committed
595 596 597
	ENTRY_SAME(gettid)             
	ENTRY_SAME(readahead)          
	ENTRY_SAME(ni_syscall)		/* tkill */
598 599

	ENTRY_SAME(sendfile64)
600
	ENTRY_COMP(futex)		/* 210 */
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
	ENTRY_SAME(sched_setaffinity)
	ENTRY_SAME(sched_getaffinity)
	ENTRY_SAME(set_thread_area)
	ENTRY_SAME(get_thread_area)
	ENTRY_SAME(io_setup)		/* 215 */
	ENTRY_SAME(io_destroy)
	ENTRY_SAME(io_getevents)
	ENTRY_SAME(io_submit)
	ENTRY_SAME(io_cancel)
	ENTRY_SAME(alloc_hugepages)	/* 220 */
	ENTRY_SAME(free_hugepages)
	ENTRY_SAME(exit_group)
	ENTRY_DIFF(lookup_dcookie)
	ENTRY_SAME(epoll_create)
	ENTRY_SAME(epoll_ctl)		/* 225 */
	ENTRY_SAME(epoll_wait)
 	ENTRY_SAME(remap_file_pages)
Linus Torvalds's avatar
Linus Torvalds committed
618 619 620 621 622 623 624 625
.end

	/* Make sure nothing else is placed on this page */

	.align 4096
	.export end_linux_gateway_page
end_linux_gateway_page: