2 * Copyright 2000, International Business Machines Corporation and others.
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
11 * Linux module support routines.
14 #include <afsconfig.h>
15 #include "afs/param.h"
20 #include "afs/sysincludes.h"
21 #include "afsincludes.h"
22 #include "h/unistd.h" /* For syscall numbers. */
25 #ifdef AFS_AMD64_LINUX20_ENV
26 #include "../asm/ia32_unistd.h"
29 #include <linux/module.h>
30 #include <linux/proc_fs.h>
31 #include <linux/slab.h>
32 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
33 #include <linux/init.h>
34 #include <linux/sched.h>
36 #if !defined(EXPORTED_SYS_CALL_TABLE) && defined(HAVE_KERNEL_LINUX_SYSCALL_H)
37 #include <linux/syscall.h>
40 #if defined(AFS_LINUX26_ENV)
41 #include <linux/vermagic.h>
42 #include <linux/compiler.h>
44 MODULE_INFO(vermagic, VERMAGIC_STRING);
48 #ifdef AFS_SPARC64_LINUX24_ENV
49 #define __NR_setgroups32 82 /* This number is not exported for some bizarre reason. */
52 #if !defined(AFS_LINUX24_ENV)
53 asmlinkage int (*sys_settimeofdayp) (struct timeval * tv,
54 struct timezone * tz);
56 asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist);
57 #ifdef EXPORTED_SYS_CALL_TABLE
58 #ifdef AFS_SPARC64_LINUX20_ENV
59 extern unsigned int sys_call_table[]; /* changed to uint because SPARC64 has syscaltable of 32bit items */
61 extern void *sys_call_table[]; /* safer for other linuces */
63 #else /* EXPORTED_SYS_CALL_TABLE */
64 #ifdef AFS_SPARC64_LINUX20_ENV
65 static unsigned int *sys_call_table; /* changed to uint because SPARC64 has syscaltable of 32bit items */
67 static void **sys_call_table; /* safer for other linuces */
70 extern struct file_system_type afs_fs_type;
72 static long get_page_offset(void);
74 #if defined(AFS_LINUX24_ENV)
75 DECLARE_MUTEX(afs_global_lock);
77 struct semaphore afs_global_lock = MUTEX;
79 int afs_global_owner = 0;
80 #if !defined(AFS_LINUX24_ENV)
81 unsigned long afs_linux_page_offset = 0; /* contains the PAGE_OFFSET value */
84 /* Since sys_ni_syscall is not exported, I need to cache it in order to restore
87 #ifdef AFS_SPARC64_LINUX20_ENV
88 static unsigned int afs_ni_syscall = 0;
90 static void *afs_ni_syscall = 0;
93 #ifdef AFS_AMD64_LINUX20_ENV
94 #ifdef EXPORTED_IA32_SYS_CALL_TABLE
95 extern void *ia32_sys_call_table[];
97 static void **ia32_sys_call_table;
100 static void *ia32_ni_syscall = 0;
101 asmlinkage long (*sys32_setgroupsp) (int gidsetsize, u16 * grouplist);
102 #if defined(__NR_ia32_setgroups32)
103 asmlinkage long (*sys32_setgroups32p) (int gidsetsize, gid_t * grouplist);
104 #endif /* __NR_ia32_setgroups32 */
105 #endif /* AFS_AMD64_LINUX20_ENV */
107 #ifdef AFS_PPC64_LINUX20_ENV
108 asmlinkage long (*sys32_setgroupsp)(int gidsetsize, gid_t *grouplist);
109 #endif /* AFS_AMD64_LINUX20_ENV */
111 #ifdef AFS_SPARC64_LINUX20_ENV
112 static unsigned int afs_ni_syscall32 = 0;
113 asmlinkage int (*sys32_setgroupsp) (int gidsetsize,
114 __kernel_gid_t32 * grouplist);
115 #if defined(__NR_setgroups32)
116 asmlinkage int (*sys32_setgroups32p) (int gidsetsize,
117 __kernel_gid_t32 * grouplist);
118 #endif /* __NR_setgroups32 */
119 #ifdef EXPORTED_SYS_CALL_TABLE
120 extern unsigned int sys_call_table32[];
121 #else /* EXPORTED_SYS_CALL_TABLE */
122 static unsigned int *sys_call_table32;
123 #endif /* EXPORTED_SYS_CALL_TABLE */
126 afs_syscall32(long syscall, long parm1, long parm2, long parm3, long parm4,
129 __asm__ __volatile__("srl %o4, 0, %o4\n\t" "mov %o7, %i7\n\t"
130 "call afs_syscall\n\t" "srl %o5, 0, %o5\n\t"
133 #endif /* AFS_SPARC64_LINUX20_ENV */
135 static int afs_ioctl(struct inode *, struct file *, unsigned int,
138 static struct file_operations afs_syscall_fops = {
142 static struct proc_dir_entry *openafs_procfs;
147 struct proc_dir_entry *entry1;
149 openafs_procfs = proc_mkdir(PROC_FSDIRNAME, proc_root_fs);
150 entry1 = create_proc_entry(PROC_SYSCALL_NAME, 0, openafs_procfs);
152 entry1->proc_fops = &afs_syscall_fops;
154 entry1->owner = THIS_MODULE;
162 remove_proc_entry(PROC_SYSCALL_NAME, openafs_procfs);
163 remove_proc_entry(PROC_FSDIRNAME, proc_root_fs);
167 afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
171 struct afsprocdata sysargs;
173 if (cmd != VIOC_SYSCALL) return -EINVAL;
175 if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata)))
178 return afs_syscall(sysargs.syscall, sysargs.param1,
179 sysargs.param2, sysargs.param3, sysargs.param4);
182 #ifdef AFS_IA64_LINUX20_ENV
185 afs_syscall_stub(int r0, int r1, long r2, long r3, long r4, long gp)
187 __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t" "mov r41 = b0\n\t" /* save rp */
188 "mov out0 = in0\n\t" "mov out1 = in1\n\t" "mov out2 = in2\n\t" "mov out3 = in3\n\t" "mov out4 = in4\n\t" "mov out5 = gp\n\t" /* save gp */
189 ";;\n" ".L1: mov r3 = ip\n\t" ";;\n\t" "addl r15=.fptr_afs_syscall-.L1,r3\n\t" ";;\n\t" "ld8 r15=[r15]\n\t" ";;\n\t" "ld8 r16=[r15],8\n\t" ";;\n\t" "ld8 gp=[r15]\n\t" "mov b6=r16\n\t" "br.call.sptk.many b0 = b6\n\t" ";;\n\t" "mov ar.pfs = r42\n\t" "mov b0 = r41\n\t" "mov gp = r48\n\t" /* restore gp */
190 "br.ret.sptk.many b0\n" ".fptr_afs_syscall:\n\t"
191 "data8 @fptr(afs_syscall)");
195 afs_xsetgroups_stub(int r0, int r1, long r2, long r3, long r4, long gp)
197 __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t" "mov r41 = b0\n\t" /* save rp */
198 "mov out0 = in0\n\t" "mov out1 = in1\n\t" "mov out2 = in2\n\t" "mov out3 = in3\n\t" "mov out4 = in4\n\t" "mov out5 = gp\n\t" /* save gp */
199 ";;\n" ".L2: mov r3 = ip\n\t" ";;\n\t" "addl r15=.fptr_afs_xsetgroups - .L2,r3\n\t" ";;\n\t" "ld8 r15=[r15]\n\t" ";;\n\t" "ld8 r16=[r15],8\n\t" ";;\n\t" "ld8 gp=[r15]\n\t" "mov b6=r16\n\t" "br.call.sptk.many b0 = b6\n\t" ";;\n\t" "mov ar.pfs = r42\n\t" "mov b0 = r41\n\t" "mov gp = r48\n\t" /* restore gp */
200 "br.ret.sptk.many b0\n" ".fptr_afs_xsetgroups:\n\t"
201 "data8 @fptr(afs_xsetgroups)");
209 #endif /* AFS_IA64_LINUX20_ENV */
211 #ifdef AFS_LINUX24_ENV
212 asmlinkage int (*sys_setgroups32p) (int gidsetsize,
213 __kernel_gid32_t * grouplist);
214 #endif /* AFS_LINUX24_ENV */
216 #ifdef AFS_SPARC64_LINUX20_ENV
217 #define POINTER2SYSCALL (unsigned int)(unsigned long)
218 #define SYSCALL2POINTER (void *)(long)
220 #define POINTER2SYSCALL (void *)
221 #define SYSCALL2POINTER (void *)
224 #ifdef AFS_PPC64_LINUX20_ENV
225 extern void *set_afs_syscall(void*);
226 extern void *set_afs_xsetgroups_syscall(void*);
227 extern void *set_afs_xsetgroups_syscall32(void*);
230 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
238 #if defined(AFS_IA64_LINUX20_ENV)
239 unsigned long kernel_gp = 0;
240 static struct fptr sys_setgroups;
241 #endif /* defined(AFS_IA64_LINUX20_ENV) */
242 extern int afs_syscall();
243 extern long afs_xsetgroups();
244 #if defined(__NR_setgroups32)
245 extern int afs_xsetgroups32();
246 #endif /* __NR_setgroups32 */
247 #if defined(AFS_SPARC64_LINUX20_ENV) || defined (AFS_AMD64_LINUX20_ENV) || defined(AFS_PPC64_LINUX20_ENV)
248 extern int afs32_xsetgroups();
249 #if (defined(__NR_setgroups32) && defined(AFS_SPARC64_LINUX20_ENV))
250 extern int afs32_xsetgroups32();
251 #endif /* defined(__NR_setgroups32) && defined(AFS_SPARC64_LINUX20_ENV) */
252 #if (defined(__NR_ia32_setgroups32) && defined(AFS_AMD64_LINUX20_ENV))
253 extern int afs32_xsetgroups32();
254 #endif /* (defined(__NR_ia32_setgroups32) && defined(AFS_AMD64_LINUX20_ENV) */
255 #endif /* AFS_SPARC64_LINUX20_ENV || AFS_AMD64_LINUX20_ENV || AFS_PPC64_LINUX20_ENV */
257 #if !defined(EXPORTED_SYS_CALL_TABLE) || (defined(AFS_AMD64_LINUX20_ENV) && !defined(EXPORTED_IA32_SYS_CALL_TABLE))
259 unsigned long offset=0;
260 unsigned long datalen=0;
262 unsigned long token=0;
264 unsigned long mod_start=0;
265 unsigned long mod_end=0;
267 unsigned long sec_start=0;
268 unsigned long sec_end=0;
270 unsigned long sym_start=0;
271 unsigned long sym_end=0;
272 #endif /* EXPORTED_SYS_CALL_TABLE */
274 RWLOCK_INIT(&afs_xosi, "afs_xosi");
276 #if !defined(AFS_LINUX24_ENV)
277 /* obtain PAGE_OFFSET value */
278 afs_linux_page_offset = get_page_offset();
280 #ifndef AFS_S390_LINUX22_ENV
281 if (afs_linux_page_offset == 0) {
282 /* couldn't obtain page offset so can't continue */
283 printf("afs: Unable to obtain PAGE_OFFSET. Exiting..");
286 #endif /* AFS_S390_LINUX22_ENV */
287 #endif /* !defined(AFS_LINUX24_ENV) */
289 #ifndef EXPORTED_SYS_CALL_TABLE
292 #ifdef EXPORTED_KALLSYMS_SYMBOL
298 kallsyms_symbol_to_address("sys_call_table", &token, &mod_name,
299 &mod_start, &mod_end, &sec_name,
300 &sec_start, &sec_end, &sym_name,
301 &sym_start, &sym_end);
302 if (ret && !strcmp(mod_name, "kernel"))
305 if (ret && sym_start) {
306 sys_call_table = sym_start;
308 #elif defined(EXPORTED_KALLSYMS_ADDRESS)
310 kallsyms_address_to_symbol((unsigned long)&init_mm, &mod_name,
311 &mod_start, &mod_end, &sec_name,
312 &sec_start, &sec_end, &sym_name,
313 &sym_start, &sym_end);
314 ptr = (unsigned long *)sec_start;
315 datalen = (sec_end - sec_start) / sizeof(unsigned long);
316 #elif defined(AFS_IA64_LINUX20_ENV)
317 ptr = (unsigned long *)(&sys_close - 0x180000);
318 datalen = 0x180000 / sizeof(ptr);
319 #elif defined(AFS_AMD64_LINUX20_ENV)
320 ptr = (unsigned long *)&init_mm;
321 datalen = 0x360000 / sizeof(ptr);
323 ptr = (unsigned long *)&init_mm;
326 for (offset = 0; offset < datalen; ptr++, offset++) {
327 #if defined(AFS_IA64_LINUX20_ENV)
328 unsigned long close_ip =
329 (unsigned long)((struct fptr *)&sys_close)->ip;
330 unsigned long chdir_ip =
331 (unsigned long)((struct fptr *)&sys_chdir)->ip;
332 unsigned long write_ip =
333 (unsigned long)((struct fptr *)&sys_write)->ip;
334 if (ptr[0] == close_ip && ptr[__NR_chdir - __NR_close] == chdir_ip
335 && ptr[__NR_write - __NR_close] == write_ip) {
336 sys_call_table = (void *)&(ptr[-1 * (__NR_close - 1024)]);
339 #elif defined(EXPORTED_SYS_WAIT4) && defined(EXPORTED_SYS_CLOSE)
340 if (ptr[0] == (unsigned long)&sys_close
341 && ptr[__NR_wait4 - __NR_close] == (unsigned long)&sys_wait4) {
342 sys_call_table = ptr - __NR_close;
345 #elif defined(EXPORTED_SYS_CHDIR) && defined(EXPORTED_SYS_CLOSE)
346 if (ptr[0] == (unsigned long)&sys_close
347 && ptr[__NR_chdir - __NR_close] == (unsigned long)&sys_chdir) {
348 sys_call_table = ptr - __NR_close;
351 #elif defined(EXPORTED_SYS_OPEN)
352 if (ptr[0] == (unsigned long)&sys_exit
353 && ptr[__NR_open - __NR_exit] == (unsigned long)&sys_open) {
354 sys_call_table = ptr - __NR_exit;
357 #else /* EXPORTED_SYS_OPEN */
359 #endif /* EXPORTED_KALLSYMS_ADDRESS */
361 #ifdef EXPORTED_KALLSYMS_ADDRESS
363 kallsyms_address_to_symbol((unsigned long)sys_call_table, &mod_name,
364 &mod_start, &mod_end, &sec_name,
365 &sec_start, &sec_end, &sym_name,
366 &sym_start, &sym_end);
367 if (ret && strcmp(sym_name, "sys_call_table"))
369 #endif /* EXPORTED_KALLSYMS_ADDRESS */
370 if (!sys_call_table) {
371 printf("Failed to find address of sys_call_table\n");
372 sys_settimeofdayp = 0;
374 printf("Found sys_call_table at %x\n", sys_call_table);
375 #ifdef AFS_SPARC64_LINUX20_ENV
376 error cant support this yet.;
377 #endif /* AFS_SPARC64_LINUX20_ENV */
378 #endif /* EXPORTED_SYS_CALL_TABLE */
380 #ifdef AFS_AMD64_LINUX20_ENV
381 #ifndef EXPORTED_IA32_SYS_CALL_TABLE
382 ia32_sys_call_table = 0;
383 #ifdef EXPORTED_KALLSYMS_SYMBOL
388 ret = kallsyms_symbol_to_address("ia32_sys_call_table", &token,
389 &mod_name, &mod_start, &mod_end,
390 &sec_name, &sec_start, &sec_end,
391 &sym_name, &sym_start, &sym_end);
392 if (ret && !strcmp(mod_name, "kernel"))
395 if (ret && sym_start) {
396 ia32_sys_call_table = sym_start;
398 #else /* EXPORTED_KALLSYMS_SYMBOL */
399 #ifdef EXPORTED_KALLSYMS_ADDRESS
400 ret = kallsyms_address_to_symbol((unsigned long)
401 &interruptible_sleep_on,
402 &mod_name, &mod_start, &mod_end,
403 &sec_name, &sec_start, &sec_end,
404 &sym_name, &sym_start, &sym_end);
405 ptr = (unsigned long *)sec_start;
406 datalen = (sec_end - sec_start) / sizeof(unsigned long);
407 #else /* EXPORTED_KALLSYMS_ADDRESS */
408 #if defined(AFS_AMD64_LINUX20_ENV)
409 ptr = (unsigned long *)&interruptible_sleep_on;
410 datalen = 0x180000 / sizeof(ptr);
411 #else /* AFS_AMD64_LINUX20_ENV */
412 ptr = (unsigned long *)&interruptible_sleep_on;
414 #endif /* AFS_AMD64_LINUX20_ENV */
415 #endif /* EXPORTED_KALLSYMS_ADDRESS */
416 for (offset = 0; offset < datalen; ptr++, offset++) {
417 if (ptr[0] == (unsigned long)&sys_exit
418 && ptr[__NR_ia32_open - __NR_ia32_exit] ==
419 (unsigned long)&sys_open) {
420 ia32_sys_call_table = ptr - __NR_ia32_exit;
424 #ifdef EXPORTED_KALLSYMS_ADDRESS
425 ret = kallsyms_address_to_symbol((unsigned long)ia32_sys_call_table,
426 &mod_name, &mod_start, &mod_end,
427 &sec_name, &sec_start, &sec_end,
428 &sym_name, &sym_start, &sym_end);
429 if (ret && strcmp(sym_name, "ia32_sys_call_table"))
430 ia32_sys_call_table = 0;
431 #endif /* EXPORTED_KALLSYMS_ADDRESS */
432 #endif /* EXPORTED_KALLSYMS_SYMBOL */
433 if (!ia32_sys_call_table) {
434 printf("Warning: Failed to find address of ia32_sys_call_table\n");
436 printf("Found ia32_sys_call_table at %x\n", ia32_sys_call_table);
439 printf("Found ia32_sys_call_table at %x\n", ia32_sys_call_table);
440 #endif /* IA32_SYS_CALL_TABLE */
443 /* Initialize pointers to kernel syscalls. */
444 #if !defined(AFS_LINUX24_ENV)
445 sys_settimeofdayp = SYSCALL2POINTER sys_call_table[__NR_settimeofday];
446 #endif /* AFS_IA64_LINUX20_ENV */
448 /* setup AFS entry point. */
450 #if defined(AFS_IA64_LINUX20_ENV)
451 SYSCALL2POINTER sys_call_table[__NR_afs_syscall - 1024]
453 SYSCALL2POINTER sys_call_table[__NR_afs_syscall]
456 printf("AFS syscall entry point already in use!\n");
459 #if defined(AFS_IA64_LINUX20_ENV)
460 afs_ni_syscall = sys_call_table[__NR_afs_syscall - 1024];
461 sys_call_table[__NR_afs_syscall - 1024] =
462 POINTER2SYSCALL((struct fptr *)afs_syscall_stub)->ip;
463 #else /* AFS_IA64_LINUX20_ENV */
464 afs_ni_syscall = sys_call_table[__NR_afs_syscall];
465 sys_call_table[__NR_afs_syscall] = POINTER2SYSCALL afs_syscall;
466 #ifdef AFS_SPARC64_LINUX20_ENV
467 afs_ni_syscall32 = sys_call_table32[__NR_afs_syscall];
468 sys_call_table32[__NR_afs_syscall] = POINTER2SYSCALL afs_syscall32;
470 #endif /* AFS_IA64_LINUX20_ENV */
471 #ifdef AFS_AMD64_LINUX20_ENV
472 if (ia32_sys_call_table) {
473 ia32_ni_syscall = ia32_sys_call_table[__NR_ia32_afs_syscall];
474 ia32_sys_call_table[__NR_ia32_afs_syscall] =
475 POINTER2SYSCALL afs_syscall;
477 #endif /* AFS_S390_LINUX22_ENV */
478 #ifndef EXPORTED_SYS_CALL_TABLE
480 #endif /* EXPORTED_SYS_CALL_TABLE */
482 register_filesystem(&afs_fs_type);
484 /* Intercept setgroups calls */
485 if (sys_call_table) {
486 #if defined(AFS_IA64_LINUX20_ENV)
487 sys_setgroupsp = (void *)&sys_setgroups;
489 ((struct fptr *)sys_setgroupsp)->ip =
490 SYSCALL2POINTER sys_call_table[__NR_setgroups - 1024];
491 ((struct fptr *)sys_setgroupsp)->gp = kernel_gp;
493 sys_call_table[__NR_setgroups - 1024] =
494 POINTER2SYSCALL((struct fptr *)afs_xsetgroups_stub)->ip;
495 #else /* AFS_IA64_LINUX20_ENV */
496 sys_setgroupsp = SYSCALL2POINTER sys_call_table[__NR_setgroups];
497 sys_call_table[__NR_setgroups] = POINTER2SYSCALL afs_xsetgroups;
498 #ifdef AFS_SPARC64_LINUX20_ENV
499 sys32_setgroupsp = SYSCALL2POINTER sys_call_table32[__NR_setgroups];
500 sys_call_table32[__NR_setgroups] = POINTER2SYSCALL afs32_xsetgroups;
501 #endif /* AFS_SPARC64_LINUX20_ENV */
502 #if defined(__NR_setgroups32)
503 sys_setgroups32p = SYSCALL2POINTER sys_call_table[__NR_setgroups32];
504 sys_call_table[__NR_setgroups32] = POINTER2SYSCALL afs_xsetgroups32;
505 #ifdef AFS_SPARC64_LINUX20_ENV
507 SYSCALL2POINTER sys_call_table32[__NR_setgroups32];
508 sys_call_table32[__NR_setgroups32] =
509 POINTER2SYSCALL afs32_xsetgroups32;
510 #endif /* AFS_SPARC64_LINUX20_ENV */
511 #endif /* __NR_setgroups32 */
512 #ifdef AFS_AMD64_LINUX20_ENV
513 if (ia32_sys_call_table) {
515 SYSCALL2POINTER ia32_sys_call_table[__NR_ia32_setgroups];
516 ia32_sys_call_table[__NR_ia32_setgroups] =
517 POINTER2SYSCALL afs32_xsetgroups;
518 #if defined(__NR_ia32_setgroups32)
520 SYSCALL2POINTER ia32_sys_call_table[__NR_ia32_setgroups32];
521 ia32_sys_call_table[__NR_ia32_setgroups32] =
522 POINTER2SYSCALL afs32_xsetgroups32;
523 #endif /* __NR_ia32_setgroups32 */
525 #endif /* AFS_AMD64_LINUX20_ENV */
526 #endif /* AFS_IA64_LINUX20_ENV */
528 #ifdef AFS_PPC64_LINUX20_ENV
529 afs_ni_syscall = set_afs_syscall(afs_syscall);
530 sys_setgroupsp = set_afs_xsetgroups_syscall(afs_xsetgroups);
531 sys32_setgroupsp = set_afs_xsetgroups_syscall32(afs32_xsetgroups);
541 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
549 struct task_struct *t;
552 if (sys_call_table) {
553 #if defined(AFS_IA64_LINUX20_ENV)
554 sys_call_table[__NR_setgroups - 1024] =
555 POINTER2SYSCALL((struct fptr *)sys_setgroupsp)->ip;
556 sys_call_table[__NR_afs_syscall - 1024] = afs_ni_syscall;
557 #else /* AFS_IA64_LINUX20_ENV */
558 sys_call_table[__NR_setgroups] = POINTER2SYSCALL sys_setgroupsp;
559 sys_call_table[__NR_afs_syscall] = afs_ni_syscall;
560 # ifdef AFS_SPARC64_LINUX20_ENV
561 sys_call_table32[__NR_setgroups] = POINTER2SYSCALL sys32_setgroupsp;
562 sys_call_table32[__NR_afs_syscall] = afs_ni_syscall32;
564 # if defined(__NR_setgroups32)
565 sys_call_table[__NR_setgroups32] = POINTER2SYSCALL sys_setgroups32p;
566 # ifdef AFS_SPARC64_LINUX20_ENV
567 sys_call_table32[__NR_setgroups32] =
568 POINTER2SYSCALL sys32_setgroups32p;
571 #endif /* AFS_IA64_LINUX20_ENV */
572 #ifdef AFS_AMD64_LINUX20_ENV
573 if (ia32_sys_call_table) {
574 ia32_sys_call_table[__NR_ia32_setgroups] =
575 POINTER2SYSCALL sys32_setgroupsp;
576 ia32_sys_call_table[__NR_ia32_afs_syscall] =
577 POINTER2SYSCALL ia32_ni_syscall;
578 # if defined(__NR_setgroups32)
579 ia32_sys_call_table[__NR_ia32_setgroups32] =
580 POINTER2SYSCALL sys32_setgroups32p;
585 #ifdef AFS_PPC64_LINUX20_ENV
586 set_afs_syscall(afs_ni_syscall);
587 set_afs_xsetgroups_syscall(sys_setgroupsp);
588 set_afs_xsetgroups_syscall32(sys32_setgroupsp);
590 unregister_filesystem(&afs_fs_type);
592 osi_linux_free_inode_pages(); /* Invalidate all pages using AFS inodes. */
593 osi_linux_free_afs_memory();
599 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
600 module_init(afs_init);
601 module_exit(afs_cleanup);
605 #if !defined(AFS_LINUX24_ENV)
607 get_page_offset(void)
609 #if defined(AFS_PPC_LINUX22_ENV) || defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || defined(AFS_ALPHA_LINUX20_ENV) || defined(AFS_S390_LINUX22_ENV) || defined(AFS_IA64_LINUX20_ENV) || defined(AFS_PARISC_LINUX24_ENV) || defined(AFS_AMD64_LINUX20_ENV) || defined(AFS_PPC64_LINUX20_ENV)
612 struct task_struct *p, *q;
614 /* search backward thru the circular list */
615 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
616 read_lock(&tasklist_lock);
618 /* search backward thru the circular list */
619 #ifdef DEFINED_PREV_TASK
620 for (q = current; p = q; q = prev_task(p)) {
622 for (p = current; p; p = p->prev_task) {
625 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
626 read_unlock(&tasklist_lock);
628 return p->addr_limit.seg;
632 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
633 read_unlock(&tasklist_lock);
638 #endif /* !AFS_LINUX24_ENV */