1/* 2 * Linux/PA-RISC Project (http://www.parisc-linux.org/) 3 * 4 * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai> 5 * Licensed under the GNU GPL. 6 * thanks to Philipp Rumpf, Mike Shaver and various others 7 * sorry about the wall, puffin.. 8 */ 9 10#include <asm/offset.h> 11#include <asm/unistd.h> 12#include <asm/errno.h> 13#include <asm/psw.h> 14 15#include <asm/assembly.h> 16#include <asm/processor.h> 17#include <linux/version.h> 18 19#ifdef __LP64__ 20 .level 2.0w 21#else 22 .level 1.1 23#endif 24 .text 25 26#ifdef __LP64__ 27#define FRAME_SIZE 128 28#else 29#define FRAME_SIZE 64 30#endif 31 32 .import syscall_exit,code 33 .import syscall_exit_rfi,code 34 .export linux_gateway_page 35 36 /* Linux gateway page is aliased to virtual page 0 in the kernel 37 * address space. Since it is a gateway page it cannot be 38 * dereferenced, so null pointers will still fault. We start 39 * the actual entry point at 0x100. We put break instructions 40 * at the beginning of the page to trap null indirect function 41 * pointers. 42 */ 43 44 .align 4096 45linux_gateway_page: 46 47 .rept 56 48 break 0,0 49 .endr 50 51set_thread_pointer: 52 gate .+8, %r0 /* increase privilege */ 53 depi 3, 31, 2, %r31 /* Ensure we return into user mode. */ 54 be 0(%sr7,%r31) /* return to user space */ 55 mtctl %r26, %cr27 /* move arg0 to the control register */ 56 57 .rept 4 58 break 0,0 59 .endr 60 61/* This address must remain fixed, or user binaries go splat. */ 62 .align 256 63linux_gateway_entry: 64 gate .+8, %r0 /* become privileged */ 65 mtsp %r0,%sr4 /* get kernel space into sr4 */ 66 mtsp %r0,%sr5 /* get kernel space into sr5 */ 67 mtsp %r0,%sr6 /* get kernel space into sr6 */ 68 mfsp %sr7,%r1 /* save user sr7 */ 69 mtsp %r1,%sr3 /* and store it in sr3 */ 70 71#ifdef __LP64__ 72 /* for now we can *always* set the W bit on entry to the syscall 73 * since we don't support wide userland processes. We could 74 * also save the current SM other than in r0 and restore it on 75 * exit from the syscall, and also use that value to know 76 * whether to do narrow or wide syscalls. -PB 77 */ 78 ssm PSW_SM_W, %r0 79 /* The top halves of argument registers must be cleared on syscall 80 * entry. 81 */ 82 depdi 0, 31, 32, %r26 83 depdi 0, 31, 32, %r25 84 depdi 0, 31, 32, %r24 85 depdi 0, 31, 32, %r23 86 depdi 0, 31, 32, %r22 87 depdi 0, 31, 32, %r21 88#endif 89 mfctl %cr30,%r1 90 xor %r1,%r30,%r30 /* ye olde xor trick */ 91 xor %r1,%r30,%r1 92 xor %r1,%r30,%r30 93 ldo TASK_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */ 94 95 /* N.B.: It is critical that we don't set sr7 to 0 until r30 96 * contains a valid kernel stack pointer. It is also 97 * critical that we don't start using the kernel stack 98 * until after sr7 has been set to 0. 99 */ 100 101 mtsp %r0,%sr7 /* get kernel space into sr7 */ 102 STREG %r1,TASK_PT_GR30-TASK_SZ_ALGN-FRAME_SIZE(%r30) /* save usp */ 103 ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr in %r1 */ 104 105 /* Save some registers for sigcontext and potential task 106 switch (see entry.S for the details of which ones are 107 saved/restored). TASK_PT_PSW is zeroed so we can see whether 108 a process is on a syscall or not. For an interrupt the real 109 PSW value is stored. This is needed for gdb and sys_ptrace. */ 110 STREG %r0, TASK_PT_PSW(%r1) 111 STREG %r2, TASK_PT_GR2(%r1) /* preserve rp */ 112 STREG %r19, TASK_PT_GR19(%r1) 113 STREG %r20, TASK_PT_GR20(%r1) 114 STREG %r21, TASK_PT_GR21(%r1) 115 STREG %r22, TASK_PT_GR22(%r1) 116 STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */ 117 STREG %r24, TASK_PT_GR24(%r1) /* 3rd argument */ 118 STREG %r25, TASK_PT_GR25(%r1) /* 2nd argument */ 119 STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ 120 STREG %r27, TASK_PT_GR27(%r1) /* user dp */ 121 STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ 122 STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */ 123 STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */ 124 STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ 125 126 ldo TASK_PT_FR0(%r1), %r27 /* save fpregs from the kernel */ 127 save_fp %r27 /* or potential task switch */ 128 129 mfctl %cr11, %r27 /* i.e. SAR */ 130 STREG %r27, TASK_PT_SAR(%r1) 131 132 loadgp 133 134#ifdef __LP64__ 135 ldo -16(%r30),%r29 /* Reference param save area */ 136#else 137 /* no need to save these on stack in wide mode because the first 8 138 * args are passed in registers */ 139 stw %r22, -52(%r30) /* 5th argument */ 140 stw %r21, -56(%r30) /* 6th argument */ 141#endif 142 143 /* for some unknown reason, task_struct.ptrace is an unsigned long so use LDREG */ 144 LDREG TASK_PTRACE(%r1), %r19 /* Are we being ptraced? */ 145 146 bb,<,n %r19, 31, .Ltracesys /* must match PT_PTRACE bit */ 147 148 /* Note! We cannot use the syscall table that is mapped 149 nearby since the gateway page is mapped execute-only. */ 150 151 ldil L%sys_call_table, %r1 152 ldo R%sys_call_table(%r1), %r19 153 154 comiclr,>>= __NR_Linux_syscalls, %r20, %r0 155 b,n .Lsyscall_nosys 156 157#ifdef __LP64__ 158 ldd,s %r20(%r19), %r19 159#else 160 ldwx,s %r20(%r19), %r19 161#endif 162 /* If this is a sys_rt_sigreturn call, and the signal was received 163 * when not in_syscall, then we want to return via syscall_exit_rfi, 164 * not syscall_exit. Signal no. in r20, in_syscall in r25 (see 165 * trampoline code in signal.c). 166 */ 167 ldi __NR_rt_sigreturn,%r2 168 comb,= %r2,%r20,.Lrt_sigreturn 169.Lin_syscall: 170 ldil L%syscall_exit,%r2 171 be 0(%sr7,%r19) 172 ldo R%syscall_exit(%r2),%r2 173.Lrt_sigreturn: 174 comib,<> 0,%r25,.Lin_syscall 175 ldil L%syscall_exit_rfi,%r2 176 be 0(%sr7,%r19) 177 ldo R%syscall_exit_rfi(%r2),%r2 178 179 /* Note! Because we are not running where we were linked, any 180 calls to functions external to this file must be indirect. To 181 be safe, we apply the opposite rule to functions within this 182 file, with local labels given to them to ensure correctness. */ 183 184.Lsyscall_nosys: 185syscall_nosys: 186 ldil L%syscall_exit,%r1 187 be R%syscall_exit(%sr7,%r1) 188 ldo -ENOSYS(%r0),%r28 /* set errno */ 189 190 191/* Warning! This trace code is a virtual duplicate of the code above so be 192 * sure to maintain both! */ 193.Ltracesys: 194tracesys: 195 /* Need to save more registers so the debugger can see where we 196 * are. This saves only the lower 8 bits of PSW, so that the C 197 * bit is still clear on syscalls, and the D bit is set if this 198 * full register save path has been executed. We check the D 199 * bit on syscall_return_rfi to determine which registers to 200 * restore. An interrupt results in a full PSW saved with the 201 * C bit set, a non-straced syscall entry results in C and D clear 202 * in the saved PSW. 203 */ 204 ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 205 ssm 0,%r2 206 STREG %r2,TASK_PT_PSW(%r1) /* Lower 8 bits only!! */ 207 mfsp %sr0,%r2 208 STREG %r2,TASK_PT_SR0(%r1) 209 mfsp %sr1,%r2 210 STREG %r2,TASK_PT_SR1(%r1) 211 mfsp %sr2,%r2 212 STREG %r2,TASK_PT_SR2(%r1) 213 mfsp %sr3,%r2 214 STREG %r2,TASK_PT_SR3(%r1) 215 STREG %r2,TASK_PT_SR4(%r1) 216 STREG %r2,TASK_PT_SR5(%r1) 217 STREG %r2,TASK_PT_SR6(%r1) 218 STREG %r2,TASK_PT_SR7(%r1) 219 STREG %r2,TASK_PT_IASQ0(%r1) 220 STREG %r2,TASK_PT_IASQ1(%r1) 221 LDREG TASK_PT_GR31(%r1),%r2 222 STREG %r2,TASK_PT_IAOQ0(%r1) 223 ldo 4(%r2),%r2 224 STREG %r2,TASK_PT_IAOQ1(%r1) 225 ldo TASK_REGS(%r1),%r2 226 /* reg_save %r2 */ 227 STREG %r3,PT_GR3(%r2) 228 STREG %r4,PT_GR4(%r2) 229 STREG %r5,PT_GR5(%r2) 230 STREG %r6,PT_GR6(%r2) 231 STREG %r7,PT_GR7(%r2) 232 STREG %r8,PT_GR8(%r2) 233 STREG %r9,PT_GR9(%r2) 234 STREG %r10,PT_GR10(%r2) 235 STREG %r11,PT_GR11(%r2) 236 STREG %r12,PT_GR12(%r2) 237 STREG %r13,PT_GR13(%r2) 238 STREG %r14,PT_GR14(%r2) 239 STREG %r15,PT_GR15(%r2) 240 STREG %r16,PT_GR16(%r2) 241 STREG %r17,PT_GR17(%r2) 242 STREG %r18,PT_GR18(%r2) 243 /* Finished saving things for the debugger */ 244 245 ldil L%syscall_trace,%r1 246 ldil L%tracesys_next,%r2 247 be R%syscall_trace(%sr7,%r1) 248 ldo R%tracesys_next(%r2),%r2 249 250tracesys_next: 251 ldil L%sys_call_table,%r1 252 ldo R%sys_call_table(%r1), %r19 253 254 ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 255 LDREG TASK_PT_GR20(%r1), %r20 256 LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */ 257 LDREG TASK_PT_GR25(%r1), %r25 258 LDREG TASK_PT_GR24(%r1), %r24 259 LDREG TASK_PT_GR23(%r1), %r23 260#ifdef __LP64__ 261 LDREG TASK_PT_GR22(%r1), %r22 262 LDREG TASK_PT_GR21(%r1), %r21 263 ldo -16(%r30),%r29 /* Reference param save area */ 264#endif 265 266 comiclr,>>= __NR_Linux_syscalls, %r20, %r0 267 b,n .Lsyscall_nosys 268 269#ifdef __LP64__ 270 ldd,s %r20(%r19), %r19 271#else 272 ldwx,s %r20(%r19), %r19 273#endif 274 /* If this is a sys_rt_sigreturn call, and the signal was received 275 * when not in_syscall, then we want to return via syscall_exit_rfi, 276 * not syscall_exit. Signal no. in r20, in_syscall in r25 (see 277 * trampoline code in signal.c). 278 */ 279 ldi __NR_rt_sigreturn,%r2 280 comb,= %r2,%r20,.Ltrace_rt_sigreturn 281.Ltrace_in_syscall: 282 ldil L%tracesys_exit,%r2 283 be 0(%sr7,%r19) 284 ldo R%tracesys_exit(%r2),%r2 285 286 /* Do *not* call this function on the gateway page, because it 287 makes a direct call to syscall_trace. */ 288 289tracesys_exit: 290 ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 291#ifdef __LP64__ 292 ldo -16(%r30),%r29 /* Reference param save area */ 293#endif 294 bl syscall_trace, %r2 295 STREG %r28,TASK_PT_GR28(%r1) /* save return value now */ 296 ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 297 LDREG TASK_PT_GR28(%r1), %r28 /* Restore return val. */ 298 299 ldil L%syscall_exit,%r1 300 be,n R%syscall_exit(%sr7,%r1) 301 302.Ltrace_rt_sigreturn: 303 comib,<> 0,%r25,.Ltrace_in_syscall 304 ldil L%tracesys_sigexit,%r2 305 be 0(%sr7,%r19) 306 ldo R%tracesys_sigexit(%r2),%r2 307 308tracesys_sigexit: 309 ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 310#ifdef __LP64__ 311 ldo -16(%r30),%r29 /* Reference param save area */ 312#endif 313 bl syscall_trace, %r2 314 nop 315 316 ldil L%syscall_exit_rfi,%r1 317 be,n R%syscall_exit_rfi(%sr7,%r1) 318 319#ifdef __LP64__ 320/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and 321 * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific 322 * implementation is required on wide palinux. 323 */ 324#define ENTRY_SAME(_name_) .dword sys_/**/_name_ 325#define ENTRY_DIFF(_name_) .dword sys32_/**/_name_ 326#define ENTRY_UHOH(_name_) .dword sys32_/**/unimplemented 327#else 328#define ENTRY_SAME(_name_) .word sys_/**/_name_ 329#define ENTRY_DIFF(_name_) .word sys_/**/_name_ 330#define ENTRY_UHOH(_name_) .word sys_/**/_name_ 331#endif 332 333 .align 8 334 .export sys_call_table 335.Lsys_call_table: 336sys_call_table: 337 ENTRY_SAME(ni_syscall) /* 0 - old "setup()" system call*/ 338 ENTRY_SAME(exit) 339 ENTRY_SAME(fork_wrapper) 340 ENTRY_SAME(read) 341 ENTRY_SAME(write) 342 ENTRY_SAME(open) /* 5 */ 343 ENTRY_SAME(close) 344 ENTRY_SAME(waitpid) 345 ENTRY_SAME(creat) 346 ENTRY_SAME(link) 347 ENTRY_SAME(unlink) /* 10 */ 348 ENTRY_DIFF(execve_wrapper) 349 ENTRY_SAME(chdir) 350 /* See comments in kernel/time.c!!! Maybe we don't need this? */ 351 ENTRY_DIFF(time) 352 ENTRY_SAME(mknod) 353 ENTRY_SAME(chmod) /* 15 */ 354 ENTRY_SAME(lchown) 355 ENTRY_SAME(socket) 356 /* struct stat is MAYBE identical wide and narrow ?? */ 357 ENTRY_DIFF(newstat) 358 ENTRY_DIFF(lseek) 359 ENTRY_SAME(getpid) /* 20 */ 360 /* the 'void * data' parameter may need re-packing in wide */ 361 ENTRY_DIFF(mount) 362 /* concerned about struct sockaddr in wide/narrow */ 363 /* ---> I think sockaddr is OK unless the compiler packs the struct */ 364 /* differently to align the char array */ 365 ENTRY_SAME(bind) 366 ENTRY_SAME(setuid) 367 ENTRY_SAME(getuid) 368 ENTRY_SAME(stime) /* 25 */ 369 ENTRY_SAME(ptrace) 370 ENTRY_SAME(alarm) 371 /* see stat comment */ 372 ENTRY_DIFF(newfstat) 373 ENTRY_SAME(pause) 374 /* struct utimbuf uses time_t which might vary */ 375 ENTRY_DIFF(utime) /* 30 */ 376 /* struct sockaddr... */ 377 ENTRY_SAME(connect) 378 ENTRY_SAME(listen) 379 ENTRY_SAME(access) 380 ENTRY_SAME(nice) 381 /* struct sockaddr... */ 382 ENTRY_SAME(accept) /* 35 */ 383 ENTRY_SAME(sync) 384 ENTRY_SAME(kill) 385 ENTRY_SAME(rename) 386 ENTRY_SAME(mkdir) 387 ENTRY_SAME(rmdir) /* 40 */ 388 ENTRY_SAME(dup) 389 ENTRY_SAME(pipe) 390 ENTRY_DIFF(times) 391 /* struct sockaddr... */ 392 ENTRY_SAME(getsockname) 393 /* it seems possible brk() could return a >4G pointer... */ 394 ENTRY_SAME(brk) /* 45 */ 395 ENTRY_SAME(setgid) 396 ENTRY_SAME(getgid) 397 ENTRY_SAME(signal) 398 ENTRY_SAME(geteuid) 399 ENTRY_SAME(getegid) /* 50 */ 400 ENTRY_SAME(acct) 401 ENTRY_SAME(umount) 402 /* struct sockaddr... */ 403 ENTRY_SAME(getpeername) 404 /* This one's a huge ugly mess */ 405 ENTRY_DIFF(ioctl) 406 /* struct flock? */ 407 ENTRY_DIFF(fcntl) /* 55 */ 408 ENTRY_SAME(socketpair) 409 ENTRY_SAME(setpgid) 410 ENTRY_SAME(send) 411 ENTRY_SAME(newuname) 412 ENTRY_SAME(umask) /* 60 */ 413 ENTRY_SAME(chroot) 414 ENTRY_SAME(ustat) 415 ENTRY_SAME(dup2) 416 ENTRY_SAME(getppid) 417 ENTRY_SAME(getpgrp) /* 65 */ 418 ENTRY_SAME(setsid) 419 ENTRY_SAME(pivot_root) 420 /* I don't like this */ 421 ENTRY_UHOH(sgetmask) 422 ENTRY_UHOH(ssetmask) 423 ENTRY_SAME(setreuid) /* 70 */ 424 ENTRY_SAME(setregid) 425 ENTRY_SAME(mincore) 426 ENTRY_DIFF(sigpending) 427 ENTRY_SAME(sethostname) 428 /* Following 3 have linux-common-code structs containing longs -( */ 429 ENTRY_DIFF(setrlimit) /* 75 */ 430 ENTRY_DIFF(getrlimit) 431 ENTRY_DIFF(getrusage) 432 /* struct timeval and timezone are maybe?? consistent wide and narrow */ 433 ENTRY_DIFF(gettimeofday) 434 ENTRY_DIFF(settimeofday) 435 ENTRY_SAME(getgroups) /* 80 */ 436 ENTRY_SAME(setgroups) 437 /* struct socketaddr... */ 438 ENTRY_SAME(sendto) 439 ENTRY_SAME(symlink) 440 /* see stat comment */ 441 ENTRY_DIFF(newlstat) 442 ENTRY_SAME(readlink) /* 85 */ 443 /* suspect we'll need some work for narrow shlibs on wide kernel */ 444 /* NOTE this doesn't get used when I boot 32-bit userspace */ 445 /* containing working shlib apps -- can this be nuked? */ 446 ENTRY_UHOH(uselib) 447 ENTRY_SAME(swapon) 448 ENTRY_SAME(reboot) 449 ENTRY_SAME(mmap2) 450 ENTRY_SAME(mmap) /* 90 */ 451 ENTRY_SAME(munmap) 452 ENTRY_SAME(truncate) 453 ENTRY_SAME(ftruncate) 454 ENTRY_SAME(fchmod) 455 ENTRY_SAME(fchown) /* 95 */ 456 ENTRY_SAME(getpriority) 457 ENTRY_SAME(setpriority) 458 ENTRY_SAME(recv) 459 ENTRY_DIFF(statfs) 460 ENTRY_DIFF(fstatfs) /* 100 */ 461 ENTRY_SAME(stat64) 462 /* don't think hppa glibc even provides an entry pt for this 463 * so disable for now */ 464 ENTRY_UHOH(socketcall) 465 ENTRY_SAME(syslog) 466 /* even though manpage says struct timeval contains longs, ours has 467 * time_t and suseconds_t -- both of which are safe wide/narrow */ 468 ENTRY_DIFF(setitimer) 469 ENTRY_DIFF(getitimer) /* 105 */ 470 ENTRY_SAME(capget) 471 ENTRY_SAME(capset) 472 ENTRY_DIFF(pread) 473 ENTRY_DIFF(pwrite) 474 ENTRY_SAME(getcwd) /* 110 */ 475 ENTRY_SAME(vhangup) 476 ENTRY_SAME(fstat64) 477 ENTRY_SAME(vfork_wrapper) 478 /* struct rusage contains longs... */ 479 ENTRY_DIFF(wait4) 480 ENTRY_SAME(swapoff) /* 115 */ 481 ENTRY_DIFF(sysinfo) 482 ENTRY_SAME(shutdown) 483 ENTRY_SAME(fsync) 484 ENTRY_SAME(madvise) 485 ENTRY_SAME(clone_wrapper) /* 120 */ 486 ENTRY_SAME(setdomainname) 487 ENTRY_SAME(sendfile) 488 /* struct sockaddr... */ 489 ENTRY_SAME(recvfrom) 490 /* struct timex contains longs */ 491 ENTRY_DIFF(adjtimex) 492 ENTRY_SAME(mprotect) /* 125 */ 493 /* old_sigset_t forced to 32 bits. Beware glibc sigset_t */ 494 ENTRY_DIFF(sigprocmask) 495 ENTRY_SAME(create_module) 496 /* struct module contains longs, but insmod builds a 64 bit struct 497 * if running under a 64 bit kernel */ 498 ENTRY_SAME(init_module) 499 ENTRY_SAME(delete_module) 500 /* struct kernel_sym contains a long. Linus never heard of size_t? */ 501 ENTRY_DIFF(get_kernel_syms) /* 130 */ 502 /* time_t inside struct dqblk */ 503 ENTRY_DIFF(quotactl) 504 ENTRY_SAME(getpgid) 505 ENTRY_SAME(fchdir) 506 ENTRY_SAME(bdflush) 507 ENTRY_SAME(sysfs) /* 135 */ 508 ENTRY_SAME(personality) 509 ENTRY_SAME(ni_syscall) /* for afs_syscall */ 510 ENTRY_SAME(setfsuid) 511 ENTRY_SAME(setfsgid) 512 /* I think this might work */ 513 ENTRY_SAME(llseek) /* 140 */ 514 /* struct linux_dirent has longs, like 'unsigned long d_ino' which 515 * almost definitely should be 'ino_t d_ino' but it's too late now */ 516 ENTRY_DIFF(getdents) 517 /* it is POSSIBLE that select will be OK because even though fd_set 518 * contains longs, the macros and sizes are clever. */ 519 ENTRY_DIFF(select) 520 ENTRY_SAME(flock) 521 ENTRY_SAME(msync) 522 /* struct iovec contains pointers */ 523 ENTRY_DIFF(readv) /* 145 */ 524 ENTRY_DIFF(writev) 525 ENTRY_SAME(getsid) 526 ENTRY_SAME(fdatasync) 527 /* struct __sysctl_args is a mess */ 528 ENTRY_DIFF(sysctl) 529 ENTRY_SAME(mlock) /* 150 */ 530 ENTRY_SAME(munlock) 531 ENTRY_SAME(mlockall) 532 ENTRY_SAME(munlockall) 533 /* struct sched_param is ok for now */ 534 ENTRY_SAME(sched_setparam) 535 ENTRY_SAME(sched_getparam) /* 155 */ 536 ENTRY_SAME(sched_setscheduler) 537 ENTRY_SAME(sched_getscheduler) 538 ENTRY_SAME(sched_yield) 539 ENTRY_SAME(sched_get_priority_max) 540 ENTRY_SAME(sched_get_priority_min) /* 160 */ 541 /* These 2 would've worked if someone had defined struct timespec 542 * carefully, like timeval for example (which is about the same). 543 * Unfortunately it contains a long :-( */ 544 ENTRY_DIFF(sched_rr_get_interval) 545 ENTRY_DIFF(nanosleep) 546 ENTRY_SAME(mremap) 547 ENTRY_SAME(setresuid) 548 ENTRY_SAME(getresuid) /* 165 */ 549 ENTRY_DIFF(sigaltstack_wrapper) 550 /* struct passed back to user can contain long symbol values */ 551 ENTRY_DIFF(query_module) 552 ENTRY_SAME(poll) 553 /* structs contain pointers and an in_addr... */ 554 ENTRY_DIFF(nfsservctl) 555 ENTRY_SAME(setresgid) /* 170 */ 556 ENTRY_SAME(getresgid) 557 ENTRY_SAME(prctl) 558 /* signals need a careful review */ 559 ENTRY_SAME(rt_sigreturn_wrapper) 560 ENTRY_DIFF(rt_sigaction) 561 ENTRY_DIFF(rt_sigprocmask) /* 175 */ 562 ENTRY_DIFF(rt_sigpending) 563 ENTRY_UHOH(rt_sigtimedwait) 564 /* even though the struct siginfo_t is different, it appears like 565 * all the paths use values which should be same wide and narrow. 566 * Also the struct is padded to 128 bytes which means we don't have 567 * to worry about faulting trying to copy in a larger 64-bit 568 * struct from a 32-bit user-space app. 569 */ 570 ENTRY_SAME(rt_sigqueueinfo) 571 ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */ 572 ENTRY_SAME(chown) /* 180 */ 573 /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */ 574 ENTRY_DIFF(setsockopt) 575 ENTRY_SAME(getsockopt) 576 ENTRY_DIFF(sendmsg) 577 ENTRY_DIFF(recvmsg) 578 ENTRY_SAME(semop) /* 185 */ 579 ENTRY_SAME(semget) 580 ENTRY_DIFF(semctl_broken) 581 ENTRY_DIFF(msgsnd) 582 ENTRY_DIFF(msgrcv) 583 ENTRY_SAME(msgget) /* 190 */ 584 ENTRY_SAME(msgctl_broken) 585 ENTRY_SAME(shmat_wrapper) 586 ENTRY_SAME(shmdt) 587 ENTRY_SAME(shmget) 588 ENTRY_SAME(shmctl_broken) /* 195 */ 589 ENTRY_SAME(ni_syscall) /* streams1 */ 590 ENTRY_SAME(ni_syscall) /* streams2 */ 591 ENTRY_SAME(lstat64) 592 ENTRY_DIFF(truncate64) 593 ENTRY_DIFF(ftruncate64) /* 200 */ 594 ENTRY_SAME(getdents64) 595 ENTRY_DIFF(fcntl64) 596#ifdef CONFIG_XFS_FS 597 ENTRY_SAME(attrctl) 598 ENTRY_SAME(acl_get) 599 ENTRY_SAME(acl_set) /* 205 */ 600#else 601 ENTRY_SAME(ni_syscall) 602 ENTRY_SAME(ni_syscall) 603 ENTRY_SAME(ni_syscall) /* 205 */ 604#endif 605 ENTRY_SAME(gettid) 606 ENTRY_SAME(readahead) 607 ENTRY_SAME(tkill) 608 609.end 610 611 /* Make sure nothing else is placed on this page */ 612 613 .align 4096 614 .export end_linux_gateway_page 615end_linux_gateway_page: 616 617