Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / LINUX / osi_syscall.c
CommitLineData
805e021f
CE
1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10/*
11 * Linux module support routines.
12 *
13 */
14#include <afsconfig.h>
15#include "afs/param.h"
16
17#ifdef LINUX_KEYRING_SUPPORT
18/* The syscall probing stuff is unnecessary (and is never called) if we have
19 * keyrings support; we rely on keyrings instead of group ids to track PAGs.
20 * So if we have keyrings, just stub out the syscall functions to do nothing. */
21int
22osi_syscall_init(void)
23{
24 return 0;
25}
26void
27osi_syscall_clean(void)
28{
29 return;
30}
31
32#else /* LINUX_KEYRING_SUPPORT */
33
34#include <linux/module.h> /* early to avoid printf->printk mapping */
35#include "afs/sysincludes.h"
36#include "afsincludes.h"
37#include <linux/unistd.h> /* For syscall numbers. */
38#include <linux/mm.h>
39
40#ifdef AFS_AMD64_LINUX20_ENV
41#include <asm/ia32_unistd.h>
42#endif
43
44#include <linux/proc_fs.h>
45#include <linux/slab.h>
46#include <linux/init.h>
47#include <linux/sched.h>
48
49#ifndef NR_syscalls
50#define NR_syscalls 222
51#endif
52
53/* On SPARC64 and S390X, sys_call_table contains 32-bit entries
54 * even though pointers are 64 bit quantities.
55 * XXX unify this with osi_probe.c
56 */
57#if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_S390X_LINUX24_ENV)
58#define SYSCALLTYPE unsigned int
59#define POINTER2SYSCALL (unsigned int)(unsigned long)
60#define SYSCALL2POINTER (void *)(long)
61#else
62#define SYSCALLTYPE void *
63#define POINTER2SYSCALL (void *)
64#define SYSCALL2POINTER (void *)
65#endif
66
67#if defined(AFS_S390X_LINUX24_ENV)
68#define INSERT_SYSCALL(SLOT, TMPPAGE, FUNC) \
69 if (SYSCALL2POINTER FUNC > 0x7fffffff) { \
70 TMPPAGE = kmalloc ( PAGE_SIZE, GFP_DMA|GFP_KERNEL ); \
71 if (SYSCALL2POINTER TMPPAGE > 0x7fffffff) { \
72 printf("Cannot allocate page for FUNC syscall jump vector\n"); \
73 return EINVAL; \
74 } \
75 memcpy(TMPPAGE, syscall_jump_code, sizeof(syscall_jump_code)); \
76 *(void **)(TMPPAGE + 0x0c) = &FUNC; \
77 afs_sys_call_table[_S(SLOT)] = POINTER2SYSCALL TMPPAGE; \
78 } else \
79 afs_sys_call_table[_S(SLOT)] = POINTER2SYSCALL FUNC;
80#else
81#define INSERT_SYSCALL(SLOT, TMPPAGE, FUNC) \
82 afs_sys_call_table[_S(SLOT)] = POINTER2SYSCALL FUNC;
83#endif
84
85#if defined(AFS_IA64_LINUX20_ENV)
86#define _S(x) ((x)-1024)
87#else
88#define _S(x) x
89#endif
90
91
92/***** ALL PLATFORMS *****/
93extern asmlinkage long
94afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4);
95
96static SYSCALLTYPE *afs_sys_call_table;
97static SYSCALLTYPE afs_ni_syscall = 0;
98
99#ifdef AFS_S390X_LINUX24_ENV
100static void *afs_sys_setgroups_page = 0;
101#if defined(__NR_setgroups32)
102static void *afs_sys_setgroups32_page = 0;
103#endif
104static void *afs_syscall_page = 0;
105
106/* Because of how the syscall table is handled, we need to ensure our
107 syscalls are within the first 2gb of address space. This means we need
108 self-modifying code we can inject to call our handlers if the module
109 is loaded high. If keyrings had advanced as fast as false protection
110 this would be unnecessary. */
111
112uint32_t syscall_jump_code[] = {
113 0xe3d0f030, 0x00240dd0, 0xa7f40006, 0xffffffff, 0xffffffff, 0xe310d004,
114 0x0004e3d0, 0xf0300004, 0x07f10000,
115};
116#endif
117
118extern asmlinkage long afs_xsetgroups(int gidsetsize, gid_t * grouplist);
119asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist);
120
121extern asmlinkage long afs_xsetgroups32(int gidsetsize, gid_t * grouplist);
122asmlinkage int (*sys_setgroups32p) (int gidsetsize,
123 __kernel_gid32_t * grouplist);
124
125/***** AMD64 *****/
126#ifdef AFS_AMD64_LINUX20_ENV
127static SYSCALLTYPE *afs_ia32_sys_call_table;
128static SYSCALLTYPE ia32_ni_syscall = 0;
129
130extern asmlinkage long afs32_xsetgroups(int gidsetsize, u16 * grouplist);
131asmlinkage long (*sys32_setgroupsp) (int gidsetsize, u16 * grouplist);
132extern asmlinkage long afs32_xsetgroups32(int gidsetsize, gid_t * grouplist);
133asmlinkage long (*sys32_setgroups32p) (int gidsetsize, gid_t * grouplist);
134#endif /* AFS_AMD64_LINUX20_ENV */
135
136
137/***** PPC64 *****/
138#ifdef AFS_PPC64_LINUX26_ENV
139static SYSCALLTYPE *afs_sys_call_table32;
140static SYSCALLTYPE afs_ni_syscall32 = 0;
141static SYSCALLTYPE old_sys_setgroupsp = 0;
142static SYSCALLTYPE old_sys32_setgroupsp = 0;
143
144asmlinkage long afs32_xsetgroups(int gidsetsize, gid_t *grouplist);
145asmlinkage long (*sys32_setgroupsp)(int gidsetsize, gid_t *grouplist);
146
147asmlinkage long sys_close(unsigned int fd);
148static void sys_setgroups_stub(void)
149 __attribute__ ((pure,const,no_instrument_function));
150static void sys_setgroups_stub(void)
151{
152 printf("*** error! sys_setgroups_stub called\n");
153}
154
155static void sys32_setgroups_stub(void)
156 __attribute__ ((pure,const,no_instrument_function));
157static void sys32_setgroups_stub(void)
158{
159 printf("*** error! sys32_setgroups_stub called\n");
160}
161
162#endif /* AFS_PPC64_LINUX26_ENV */
163
164
165/***** SPARC64 *****/
166#ifdef AFS_SPARC64_LINUX26_ENV
167static SYSCALLTYPE *afs_sys_call_table32;
168static SYSCALLTYPE afs_ni_syscall32 = 0;
169
170extern asmlinkage long afs32_xsetgroups(int gidsetsize, u16 * grouplist);
171asmlinkage int (*sys32_setgroupsp) (int gidsetsize,
172 __kernel_gid32_t * grouplist);
173/* This number is not exported for some bizarre reason. */
174#define __NR_setgroups32 82
175extern asmlinkage long afs32_xsetgroups32(int gidsetsize, gid_t * grouplist);
176asmlinkage int (*sys32_setgroups32p) (int gidsetsize,
177 __kernel_gid32_t * grouplist);
178
179asmlinkage int
180afs_syscall32(long syscall, long parm1, long parm2, long parm3, long parm4,
181 long parm5)
182{
183 __asm__ __volatile__("srl %o4, 0, %o4\n\t"
184 "mov %o7, %i7\n\t"
185 "call afs_syscall\n\t"
186 "srl %o5, 0, %o5\n\t"
187 "ret\n\t"
188 "nop");
189}
190#endif /* AFS_SPARC64_LINUX20_ENV */
191
192
193/***** IA64 *****/
194#ifdef AFS_IA64_LINUX20_ENV
195
196asmlinkage long
197afs_syscall_stub(int r0, int r1, long r2, long r3, long r4, long gp)
198{
199 __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t"
200 "mov r41 = b0\n\t" /* save rp */
201 "mov out0 = in0\n\t"
202 "mov out1 = in1\n\t"
203 "mov out2 = in2\n\t"
204 "mov out3 = in3\n\t"
205 "mov out4 = in4\n\t"
206 "mov out5 = gp\n\t" /* save gp */
207 ";;\n"
208 ".L1:\n\t"
209 "mov r3 = ip\n\t"
210 ";;\n\t"
211 "addl r15=.fptr_afs_syscall-.L1,r3\n\t"
212 ";;\n\t"
213 "ld8 r15=[r15]\n\t"
214 ";;\n\t"
215 "ld8 r16=[r15],8\n\t"
216 ";;\n\t"
217 "ld8 gp=[r15]\n\t"
218 "mov b6=r16\n\t"
219 "br.call.sptk.many b0 = b6\n\t"
220 ";;\n\t"
221 "mov ar.pfs = r42\n\t"
222 "mov b0 = r41\n\t"
223 "mov gp = r48\n\t" /* restore gp */
224 "br.ret.sptk.many b0\n"
225 ".fptr_afs_syscall:\n\t"
226 "data8 @fptr(afs_syscall)\n\t"
227 ".skip 8");
228}
229
230asmlinkage long
231afs_xsetgroups_stub(int r0, int r1, long r2, long r3, long r4, long gp)
232{
233 __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t"
234 "mov r41 = b0\n\t" /* save rp */
235 "mov out0 = in0\n\t"
236 "mov out1 = in1\n\t"
237 "mov out2 = in2\n\t"
238 "mov out3 = in3\n\t"
239 "mov out4 = in4\n\t"
240 "mov out5 = gp\n\t" /* save gp */
241 ";;\n"
242 ".L2:\n\t"
243 "mov r3 = ip\n\t"
244 ";;\n\t"
245 "addl r15=.fptr_afs_xsetgroups - .L2,r3\n\t"
246 ";;\n\t"
247 "ld8 r15=[r15]\n\t"
248 ";;\n\t"
249 "ld8 r16=[r15],8\n\t"
250 ";;\n\t"
251 "ld8 gp=[r15]\n\t"
252 "mov b6=r16\n\t"
253 "br.call.sptk.many b0 = b6\n\t"
254 ";;\n\t"
255 "mov ar.pfs = r42\n\t"
256 "mov b0 = r41\n\t"
257 "mov gp = r48\n\t" /* restore gp */
258 "br.ret.sptk.many b0\n"
259 ".fptr_afs_xsetgroups:\n\t"
260 "data8 @fptr(afs_xsetgroups)\n\t"
261 ".skip 8");
262}
263
264struct fptr {
265 void *ip;
266 unsigned long gp;
267};
268
269#endif /* AFS_IA64_LINUX20_ENV */
270
271/***** PPC64 *****
272 * Spring 2005
273 * sys_call_table hook for PPC64
274 * by Soewono Effendi <Soewono.Effendi@sysgo.de>
275 * for IBM Deutschland
276 * Thanks go to SYSGO's team for their support:
277 * Horst Birthelmer <Horst.Birthelmer@sysgo.de>
278 * Marius Groeger <Marius.Groeger@sysgo.de>
279 */
280#if defined(AFS_PPC64_LINUX26_ENV)
281extern void flush_cache(void *, unsigned long);
282#define PPC_LO(v) ((v) & 0xffff)
283#define PPC_HI(v) (((v) >> 16) & 0xffff)
284#define PPC_HA(v) PPC_HI ((v) + 0x8000)
285#define PPC_HLO(v) ((short)(((v) >> 32) & 0xffff))
286#define PPC_HHI(v) ((short)(((v) >> 48) & 0xffff))
287
288struct ppc64_opd
289{
290 unsigned long funcaddr;
291 unsigned long r2;
292};
293
294struct ppc64_stub
295{
296 unsigned char jump[136];
297 unsigned long r2;
298 unsigned long lr;
299 struct ppc64_opd opd;
300} __attribute__ ((packed));
301
302/* a stub to fix up r2 (TOC ptr) and to jump to our sys_call hook
303 function. We patch the new r2 value and function pointer into
304 the stub. */
305#define PPC64_STUB(stub) \
306static struct ppc64_stub stub = \
307{ .jump = { \
308 0xf8, 0x41, 0x00, 0x28, /* std r2,40(r1) */ \
309 0xfb, 0xc1, 0xff, 0xf0, /* std r30,-16(r1) */ \
310 0xfb, 0xa1, 0xff, 0xe8, /* std r29,-24(r1) */ \
311 0x7c, 0x5d, 0x13, 0x78, /* mr r29,r2 */ \
312 0x3c, 0x40, 0x12, 0x34, /*16: lis r2,4660 */ \
313 0x60, 0x42, 0x56, 0x78, /*20: ori r2,r2,22136 */ \
314 0x78, 0x42, 0x07, 0xc6, /* rldicr r2,r2,32,31 */ \
315 0x64, 0x42, 0x90, 0xab, /*28: oris r2,r2,37035 */ \
316 0x60, 0x42, 0xcd, 0xef, /*32: ori r2,r2,52719 */ \
317 0x3f, 0xc2, 0x00, 0x00, /*36: addis r30,r2,0 */ \
318 0x3b, 0xde, 0x00, 0x00, /*40: addi r30,r30,0 */ \
319 0xfb, 0xbe, 0x00, 0x88, /* std r29,136(r30) */ \
320 0x7f, 0xa8, 0x02, 0xa6, /* mflr r29 */ \
321 0xfb, 0xbe, 0x00, 0x90, /* std r29,144(r30) */ \
322 0xeb, 0xde, 0x00, 0x98, /* ld r30,152(r30) */ \
323 0x7f, 0xc8, 0x03, 0xa6, /* mtlr r30 */ \
324 0xeb, 0xa1, 0xff, 0xe8, /* ld r29,-24(r1) */ \
325 0xeb, 0xc1, 0xff, 0xf0, /* ld r30,-16(r1) */ \
326 0x4e, 0x80, 0x00, 0x21, /* blrl */ \
327 0x3c, 0x40, 0x12, 0x34, /*76: lis r2,4660 */ \
328 0x60, 0x42, 0x56, 0x78, /*80: ori r2,r2,22136 */ \
329 0x78, 0x42, 0x07, 0xc6, /* rldicr r2,r2,32,31 */ \
330 0x64, 0x42, 0x90, 0xab, /*88: oris r2,r2,37035 */ \
331 0x60, 0x42, 0xcd, 0xef, /*92: ori r2,r2,52719 */ \
332 0xfb, 0xc1, 0xff, 0xf0, /* std r30,-16(r1) */ \
333 0xfb, 0xa1, 0xff, 0xe8, /* std r29,-24(r1) */ \
334 0x3f, 0xc2, 0xab, 0xcd, /*104: addis r30,r2,-21555 */ \
335 0x3b, 0xde, 0x78, 0x90, /*108: addi r30,r30,30864 */ \
336 0xeb, 0xbe, 0x00, 0x90, /* ld r29,144(r30) */ \
337 0x7f, 0xa8, 0x03, 0xa6, /* mtlr r29 */ \
338 0xe8, 0x5e, 0x00, 0x88, /* ld r2,136(r30) */ \
339 0xeb, 0xa1, 0xff, 0xe8, /* ld r29,-24(r1) */ \
340 0xeb, 0xc1, 0xff, 0xf0, /* ld r30,-16(r1) */ \
341 0x4e, 0x80, 0x00, 0x20 /* blr */ \
342}}
343
344static void * create_stub(struct ppc64_stub *stub,
345 struct ppc64_opd *opd)
346{
347 unsigned short *p1, *p2, *p3, *p4;
348 unsigned long addr;
349
350 stub->opd.funcaddr = opd->funcaddr;
351 stub->opd.r2 = opd->r2;
352 addr = (unsigned long) opd->r2;
353 p1 = (unsigned short*) &stub->jump[18];
354 p2 = (unsigned short*) &stub->jump[22];
355 p3 = (unsigned short*) &stub->jump[30];
356 p4 = (unsigned short*) &stub->jump[34];
357
358 *p1 = PPC_HHI(addr);
359 *p2 = PPC_HLO(addr);
360 *p3 = PPC_HI(addr);
361 *p4 = PPC_LO(addr);
362
363 addr = (unsigned long) stub - opd->r2;
364 p1 = (unsigned short*) &stub->jump[38];
365 p2 = (unsigned short*) &stub->jump[42];
366 *p1 = PPC_HA(addr);
367 *p2 = PPC_LO(addr);
368 p1 = (unsigned short*) &stub->jump[106];
369 p2 = (unsigned short*) &stub->jump[110];
370 *p1 = PPC_HA(addr);
371 *p2 = PPC_LO(addr);
372
373 addr = (unsigned long) opd->r2;
374 p1 = (unsigned short*) &stub->jump[78];
375 p2 = (unsigned short*) &stub->jump[82];
376 p3 = (unsigned short*) &stub->jump[90];
377 p4 = (unsigned short*) &stub->jump[94];
378
379 *p1 = PPC_HHI(addr);
380 *p2 = PPC_HLO(addr);
381 *p3 = PPC_HI(addr);
382 *p4 = PPC_LO(addr);
383
384 flush_cache((void *)stub, sizeof(*stub));
385 return ((void*)(stub));
386}
387
388PPC64_STUB(afs_sys_call_stub);
389PPC64_STUB(afs_xsetgroups_stub);
390PPC64_STUB(afs_xsetgroups32_stub);
391#endif /* AFS_PPC64_LINUX26_ENV */
392
393
394/**********************************************************************/
395/********************* System Call Initialization *********************/
396/**********************************************************************/
397
398int osi_syscall_init(void)
399{
400/***** IA64 *****/
401#ifdef AFS_IA64_LINUX20_ENV
402 /* This needs to be first because we are declaring variables, and
403 * also because the handling of syscall pointers is bizarre enough
404 * that we want to special-case even the "common" part.
405 */
406 unsigned long kernel_gp = 0;
407 static struct fptr sys_setgroups;
408
409 afs_sys_call_table = osi_find_syscall_table(0);
410 if (afs_sys_call_table) {
411
412 /* check we aren't already loaded */
413 /* XXX this can't be right */
414 if (SYSCALL2POINTER afs_sys_call_table[_S(__NR_afs_syscall)]
415 == afs_syscall) {
416 printf("AFS syscall entry point already in use!\n");
417 return -EBUSY;
418 }
419
420 /* setup AFS entry point */
421 afs_ni_syscall = afs_sys_call_table[_S(__NR_afs_syscall)];
422 afs_sys_call_table[_S(__NR_afs_syscall)] =
423 POINTER2SYSCALL((struct fptr *)afs_syscall_stub)->ip;
424
425 /* setup setgroups */
426 sys_setgroupsp = (void *)&sys_setgroups;
427
428 ((struct fptr *)sys_setgroupsp)->ip =
429 SYSCALL2POINTER afs_sys_call_table[_S(__NR_setgroups)];
430 ((struct fptr *)sys_setgroupsp)->gp = kernel_gp;
431
432 afs_sys_call_table[_S(__NR_setgroups)] =
433 POINTER2SYSCALL((struct fptr *)afs_xsetgroups_stub)->ip;
434 }
435
436 /* XXX no 32-bit syscalls on IA64? */
437
438
439#elif defined(AFS_PPC64_LINUX26_ENV)
440
441 afs_sys_call_table = osi_find_syscall_table(0);
442 if (afs_sys_call_table) {
443 SYSCALLTYPE p;
444 struct ppc64_opd* opd = (struct ppc64_opd*) sys_close;
445 unsigned long r2 = opd->r2;
446 opd = (struct ppc64_opd*) afs_syscall;
447 afs_sys_call_table32 = (unsigned long)afs_sys_call_table -
448 NR_syscalls * sizeof(SYSCALLTYPE);
449 /* check we aren't already loaded */
450 p = SYSCALL2POINTER afs_sys_call_table[_S(__NR_afs_syscall)];
451 if ((unsigned long)p == opd->funcaddr) {
452 printf("AFS syscall entry point already in use!\n");
453 return -EBUSY;
454 }
455 /* setup AFS entry point */
456 p = create_stub(&afs_sys_call_stub, opd);
457 afs_ni_syscall = afs_sys_call_table[_S(__NR_afs_syscall)];
458 afs_sys_call_table[_S(__NR_afs_syscall)] = POINTER2SYSCALL p;
459
460 /* setup setgroups */
461 opd = (struct ppc64_opd*) afs_xsetgroups;
462 p = create_stub(&afs_xsetgroups_stub, opd);
463 old_sys_setgroupsp = SYSCALL2POINTER afs_sys_call_table[_S(__NR_setgroups)];
464 afs_sys_call_table[_S(__NR_setgroups)] = POINTER2SYSCALL p;
465 opd = (struct ppc64_opd*) sys_setgroups_stub;
466 opd->funcaddr = old_sys_setgroupsp;
467 opd->r2 = r2;
468
469 /* setup setgroups32 */
470 opd = (struct ppc64_opd*) afs32_xsetgroups;
471 p = create_stub(&afs_xsetgroups32_stub, opd);
472 old_sys32_setgroupsp = SYSCALL2POINTER afs_sys_call_table32[_S(__NR_setgroups)];
473 afs_sys_call_table32[_S(__NR_setgroups)] = POINTER2SYSCALL p;
474 opd = (struct ppc64_opd*) sys32_setgroups_stub;
475 opd->funcaddr = old_sys32_setgroupsp;
476 opd->r2 = r2;
477
478 flush_cache((void *)afs_sys_call_table, 2*NR_syscalls*sizeof(void*));
479
480 sys_setgroupsp = POINTER2SYSCALL sys_setgroups_stub;
481 sys32_setgroupsp = POINTER2SYSCALL sys32_setgroups_stub;
482 }
483/***** COMMON (except IA64 or PPC64) *****/
484#else /* !AFS_IA64_LINUX20_ENV */
485
486 afs_sys_call_table = osi_find_syscall_table(0);
487 if (afs_sys_call_table) {
488
489 /* check we aren't already loaded */
490 if (SYSCALL2POINTER afs_sys_call_table[_S(__NR_afs_syscall)]
491 == afs_syscall) {
492 printf("AFS syscall entry point already in use!\n");
493 return -EBUSY;
494 }
495
496 /* setup AFS entry point */
497 afs_ni_syscall = afs_sys_call_table[_S(__NR_afs_syscall)];
498
499 INSERT_SYSCALL(__NR_afs_syscall, afs_syscall_page, afs_syscall)
500
501 /* setup setgroups */
502 sys_setgroupsp = SYSCALL2POINTER afs_sys_call_table[_S(__NR_setgroups)];
503 INSERT_SYSCALL(__NR_setgroups, afs_sys_setgroups_page, afs_xsetgroups)
504
505#if defined(__NR_setgroups32)
506 /* setup setgroups32 */
507 sys_setgroups32p = SYSCALL2POINTER afs_sys_call_table[__NR_setgroups32];
508 INSERT_SYSCALL(__NR_setgroups32, afs_sys_setgroups32_page, afs_xsetgroups32)
509#endif
510 }
511#endif /* !AFS_IA64_LINUX20_ENV */
512
513
514/***** AMD64 *****/
515#ifdef AFS_AMD64_LINUX20_ENV
516 afs_ia32_sys_call_table = osi_find_syscall_table(1);
517 if (afs_ia32_sys_call_table) {
518 /* setup AFS entry point for IA32 */
519 ia32_ni_syscall = afs_ia32_sys_call_table[__NR_ia32_afs_syscall];
520 afs_ia32_sys_call_table[__NR_ia32_afs_syscall] =
521 POINTER2SYSCALL afs_syscall;
522
523 /* setup setgroups for IA32 */
524 sys32_setgroupsp =
525 SYSCALL2POINTER afs_ia32_sys_call_table[__NR_ia32_setgroups];
526 afs_ia32_sys_call_table[__NR_ia32_setgroups] =
527 POINTER2SYSCALL afs32_xsetgroups;
528
529 /* setup setgroups32 for IA32 */
530 sys32_setgroups32p =
531 SYSCALL2POINTER afs_ia32_sys_call_table[__NR_ia32_setgroups32];
532 afs_ia32_sys_call_table[__NR_ia32_setgroups32] =
533 POINTER2SYSCALL afs32_xsetgroups32;
534 }
535#endif /* AFS_AMD64_LINUX20_ENV */
536
537
538/***** SPARC64 *****/
539#ifdef AFS_SPARC64_LINUX20_ENV
540 afs_sys_call_table32 = osi_find_syscall_table(1);
541 if (afs_sys_call_table32) {
542 /* setup AFS entry point for 32-bit SPARC */
543 afs_ni_syscall32 = afs_sys_call_table32[__NR_afs_syscall];
544 afs_sys_call_table32[__NR_afs_syscall] = POINTER2SYSCALL afs_syscall32;
545
546 /* setup setgroups for 32-bit SPARC */
547 sys32_setgroupsp = SYSCALL2POINTER afs_sys_call_table32[__NR_setgroups];
548 afs_sys_call_table32[__NR_setgroups] = POINTER2SYSCALL afs32_xsetgroups;
549
550 /* setup setgroups32 for 32-bit SPARC */
551 sys32_setgroups32p =
552 SYSCALL2POINTER afs_sys_call_table32[__NR_setgroups32];
553 afs_sys_call_table32[__NR_setgroups32] =
554 POINTER2SYSCALL afs32_xsetgroups32;
555 }
556#endif /* AFS_SPARC64_LINUX20_ENV */
557 return 0;
558}
559
560
561
562/**********************************************************************/
563/************************ System Call Cleanup *************************/
564/**********************************************************************/
565
566void osi_syscall_clean(void)
567{
568/***** COMMON *****/
569 if (afs_sys_call_table) {
570 /* put back the AFS entry point */
571 afs_sys_call_table[_S(__NR_afs_syscall)] = afs_ni_syscall;
572
573 /* put back setgroups */
574#if defined(AFS_IA64_LINUX20_ENV)
575 afs_sys_call_table[_S(__NR_setgroups)] =
576 POINTER2SYSCALL((struct fptr *)sys_setgroupsp)->ip;
577#elif defined(AFS_PPC64_LINUX26_ENV)
578 afs_sys_call_table[_S(__NR_setgroups)] =
579 POINTER2SYSCALL old_sys_setgroupsp;
580 /* put back setgroups32 for PPC64 */
581 afs_sys_call_table32[__NR_setgroups] =
582 POINTER2SYSCALL old_sys32_setgroupsp;
583#else /* AFS_IA64_LINUX20_ENV */
584 afs_sys_call_table[_S(__NR_setgroups)] =
585 POINTER2SYSCALL sys_setgroupsp;
586#endif
587
588#if defined(__NR_setgroups32) && !defined(AFS_IA64_LINUX20_ENV)
589 /* put back setgroups32 */
590 afs_sys_call_table[__NR_setgroups32] = POINTER2SYSCALL sys_setgroups32p;
591#endif
592#if defined(AFS_S390X_LINUX24_ENV)
593#if defined(__NR_setgroups32) && !defined(AFS_IA64_LINUX20_ENV)
594 if (afs_sys_setgroups32_page)
595 kfree(afs_sys_setgroups32_page);
596#endif
597 if (afs_sys_setgroups_page)
598 kfree(afs_sys_setgroups_page);
599 if (afs_syscall_page)
600 kfree(afs_syscall_page);
601#endif
602 }
603
604
605/***** IA64 *****/
606#ifdef AFS_IA64_LINUX20_ENV
607 /* XXX no 32-bit syscalls on IA64? */
608#endif
609
610
611/***** AMD64 *****/
612#ifdef AFS_AMD64_LINUX20_ENV
613 if (afs_ia32_sys_call_table) {
614 /* put back AFS entry point for IA32 */
615 afs_ia32_sys_call_table[__NR_ia32_afs_syscall] =
616 POINTER2SYSCALL ia32_ni_syscall;
617
618 /* put back setgroups for IA32 */
619 afs_ia32_sys_call_table[__NR_ia32_setgroups] =
620 POINTER2SYSCALL sys32_setgroupsp;
621
622 /* put back setgroups32 for IA32 */
623 afs_ia32_sys_call_table[__NR_ia32_setgroups32] =
624 POINTER2SYSCALL sys32_setgroups32p;
625 }
626#endif
627
628
629/***** SPARC64 *****/
630#ifdef AFS_SPARC64_LINUX20_ENV
631 if (afs_sys_call_table32) {
632 /* put back AFS entry point for 32-bit SPARC */
633 afs_sys_call_table32[__NR_afs_syscall] = afs_ni_syscall32;
634
635 /* put back setgroups for IA32 */
636 afs_sys_call_table32[__NR_setgroups] =
637 POINTER2SYSCALL sys32_setgroupsp;
638
639 /* put back setgroups32 for IA32 */
640 afs_sys_call_table32[__NR_setgroups32] =
641 POINTER2SYSCALL sys32_setgroups32p;
642 }
643#endif
644}
645
646#endif /* !LINUX_KEYRING_SUPPORT */