From f675629a2ba6f1e7d799efab7ba754cadccd4962 Mon Sep 17 00:00:00 2001 From: Jeffrey Hutzelman Date: Mon, 21 Feb 2005 01:15:34 +0000 Subject: [PATCH] STABLE14-unified-osi-probe-2-20050216 FIXES 17548 update osi_probe (cherry picked from commit cb3ec9004e095a11db6e349d6feef6d08243aa19) --- src/afs/LINUX/osi_module.c | 45 +++++++- src/afs/LINUX/osi_probe.c | 164 ++++++++++++++++++++++------ src/afs/LINUX/osi_syscall.c | 81 +++++++++++--- src/afs/afs.h | 2 +- src/afs/afs_call.c | 16 ++- src/afs/afs_pioctl.c | 20 ++-- src/cf/osconf.m4 | 20 +--- src/config/afs_args.h | 8 ++ src/config/afs_sysnames.h | 1 + src/config/param.s390x_linux26.h | 173 ++++++++++++++++++++++++++++++ src/libafs/MakefileProto.LINUX.in | 6 +- 11 files changed, 454 insertions(+), 82 deletions(-) create mode 100644 src/config/param.s390x_linux26.h diff --git a/src/afs/LINUX/osi_module.c b/src/afs/LINUX/osi_module.c index f018ac416..df214bbca 100644 --- a/src/afs/LINUX/osi_module.c +++ b/src/afs/LINUX/osi_module.c @@ -134,14 +134,51 @@ afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, { struct afsprocdata sysargs; + struct afsprocdata32 sysargs32; if (cmd != VIOC_SYSCALL) return -EINVAL; - if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata))) - return -EFAULT; +#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) +#ifdef AFS_SPARC64_LINUX24_ENV + if (current->thread.flags & SPARC_FLAG_32BIT) +#elif defined(AFS_SPARC64_LINUX20_ENV) + if (current->tss.flags & SPARC_FLAG_32BIT) +#elif defined(AFS_AMD64_LINUX20_ENV) +#ifdef AFS_LINUX26_ENV + if (test_thread_flag(TIF_IA32)) +#else + if (current->thread.flags & THREAD_IA32) +#endif +#elif defined(AFS_PPC64_LINUX20_ENV) +#ifdef AFS_PPC64_LINUX26_ENV + if (current->thread_info->flags & _TIF_32BIT) +#else /*Linux 2.6 */ + if (current->thread.flags & PPC_FLAG_32BIT) +#endif +#elif defined(AFS_S390X_LINUX20_ENV) + if (current->thread.flags & S390_FLAG_31BIT) +#else +#error Not done for this linux type +#endif + { + if (copy_from_user(&sysargs32, (void *)arg, + sizeof(struct afsprocdata32))) + return -EFAULT; + + return afs_syscall((unsigned long)sysargs32.syscall, + (unsigned long)sysargs32.param1, + (unsigned long)sysargs32.param2, + (unsigned long)sysargs32.param3, + (unsigned long)sysargs32.param4); + } else +#endif + { + if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata))) + return -EFAULT; - return afs_syscall(sysargs.syscall, sysargs.param1, - sysargs.param2, sysargs.param3, sysargs.param4); + return afs_syscall(sysargs.syscall, sysargs.param1, + sysargs.param2, sysargs.param3, sysargs.param4); + } } diff --git a/src/afs/LINUX/osi_probe.c b/src/afs/LINUX/osi_probe.c index fc9c3945a..83f3a191d 100644 --- a/src/afs/LINUX/osi_probe.c +++ b/src/afs/LINUX/osi_probe.c @@ -68,10 +68,6 @@ #include #endif -#ifdef HAVE_KERNEL_LINUX_SYSCALL_H -#include -#endif - /* number of syscalls */ /* NB: on MIPS we care about the 4xxx range */ #ifndef NR_syscalls @@ -79,11 +75,11 @@ #endif /* lower bound of valid kernel text pointers */ -//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#ifdef AFS_IA64_LINUX20_ENV +#define ktxt_lower_bound (((unsigned long)&kernel_thread ) & 0xfff00000L) +#else #define ktxt_lower_bound (((unsigned long)&kernel_thread ) & ~0xfffffL) -//#else -//#define ktxt_lower_bound (((unsigned long)&empty_zero_page) & ~0xfffffL) -//#endif +#endif /* On SPARC64 and S390X, sys_call_table contains 32-bit entries * even though pointers are 64 bit quantities. @@ -96,6 +92,14 @@ #define PROBETYPE long #endif +#if defined(AFS_S390X_LINUX20_ENV) && !defined(AFS_S390X_LINUX26_ENV) +#define _SS(x) ((x) << 1) +#define _SX(x) ((x) &~ 1) +#else +#define _SS(x) (x) +#define _SX(x) (x) +#endif + /* Allow the user to specify sys_call_table addresses */ static unsigned long sys_call_table_addr[4] = { 0,0,0,0 }; @@ -143,7 +147,16 @@ MODULE_PARM_DESC(probe_debug_tag, "Debugging output start tag"); /* Weak references are our friends. They are supported by the in-kernel * linker in Linux 2.6 and by all versions of modutils back to 2.2pre1. * A weak reference not satisified by the kernel will have value zero. + * + * Unfortunately, weak references to functions don't work right on + * IA64; specifically, if you actually try to make a call through + * such a reference, and the symbol doesn't exist in the kernel, then + * the module relocation code will oops. A workaround for this is + * probably possible, but the use of kallsyms_* is of limited value, + * so I'm not bothing with the effort for now. + * -- jhutz, 10-Feb-2005 */ +#ifdef OSI_PROBE_KALLSYMS extern int kallsyms_symbol_to_address(char *name, unsigned long *token, char **mod_name, unsigned long *mod_start, @@ -167,20 +180,22 @@ extern int kallsyms_address_to_symbol(unsigned long address, unsigned long *sym_start, unsigned long *sym_end ) __attribute__((weak)); +#endif extern SYSCALLTYPE sys_call_table[] __attribute__((weak)); extern SYSCALLTYPE ia32_sys_call_table[] __attribute__((weak)); extern SYSCALLTYPE sys_call_table32[] __attribute__((weak)); +extern SYSCALLTYPE sys_call_table_emu[] __attribute__((weak)); extern asmlinkage long sys_close(unsigned int) __attribute__((weak)); extern asmlinkage long sys_chdir(const char *) __attribute__((weak)); -extern asmlinkage int sys_write(unsigned int, const char *, size_t) __attribute__((weak)); +extern asmlinkage ssize_t sys_write(unsigned int, const char *, size_t) __attribute__((weak)); #ifdef AFS_LINUX26_ENV extern asmlinkage long sys_wait4(pid_t, int *, int, struct rusage *) __attribute__((weak)); #else extern asmlinkage long sys_wait4(pid_t, unsigned int *, int, struct rusage *) __attribute__((weak)); #endif -extern asmlinkage int sys_exit (int) __attribute__((weak)); +extern asmlinkage long sys_exit (int) __attribute__((weak)); extern asmlinkage long sys_open (const char *, int, int) __attribute__((weak)); extern asmlinkage long sys_ioctl(unsigned int, unsigned int, unsigned long) __attribute__((weak)); @@ -306,7 +321,7 @@ static int main_zapped_syscalls[] = { * corresponding __NR macros are not defined, so the tests above fail. * Instead, we just have to know the numbers for these. */ -#ifdef AFS_S390_LINUX20_ENV +#if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV) /* break, stty, gtty, ftime, prof, lock, mpx */ 17, 31, 32, 35, 44, 53, 56, #endif @@ -400,6 +415,13 @@ static int main_zapped_syscalls[] = { /* unique syscalls for try_harder */ static int main_unique_syscalls[] = { +#if defined(AFS_SPARC64_LINUX24_ENV) || defined(AFS_SPARC_LINUX24_ENV) + /* + * On SPARC, we need some additional unique calls to make sure + * we don't match the SunOS-compatibility table. + */ + __NR_sgetmask, __NR_ssetmask, +#endif __NR_exit, __NR_mount, __NR_read, __NR_write, __NR_open, __NR_close, __NR_unlink }; @@ -428,7 +450,7 @@ static probectl main_probe = { main_try, /* array of combinations to try */ /* symbol in section to try scanning */ -#if defined(AFS_SPARC64_LINUX20_ENV) +#if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV) (unsigned long)&sys_close, #elif defined(AFS_AMD64_LINUX20_ENV) /* On this platform, it's in a different section! */ @@ -444,13 +466,22 @@ static probectl main_probe = { (unsigned long)(&sys_close), 0xfffff, 0x10000, +#elif defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV) + /* bleah; this is so suboptimal */ + (unsigned long)(&sys_close), + 0xfffff, + 0x20000, #elif defined(AFS_IA64_LINUX20_ENV) - (unsigned long)(&sys_close - 0x180000), - 0, - (0x180000 / sizeof(unsigned long *)), + (unsigned long)(&init_mm), + 0x1fffff, + 0x30000, #elif defined(AFS_AMD64_LINUX20_ENV) - (unsigned long)(&tasklist_lock - 0x1000), + (unsigned long)(&tasklist_lock) - 0x30000, 0, + 0x6000, +#elif defined(AFS_PPC_LINUX20_ENV) || defined(AFS_PPC_LINUX20_ENV) + (unsigned long)&init_mm, + 0xffff, 16384, #else (unsigned long)&init_mm, @@ -570,6 +601,19 @@ static probectl *probe_list[] = { }; +/********** Probing Configuration: IA64 **********/ +#elif defined(AFS_IA64_LINUX20_ENV) +struct fptr { + void *ip; + unsigned long gp; +}; + +/* no 32-bit support on IA64 for now */ +static probectl *probe_list[] = { + &main_probe +}; + + /********** Probing Configuration: ppc64, sparc64 sys_call_table32 **********/ #elif defined(AFS_PPC64_LINUX20_ENV) || defined(AFS_SPARC64_LINUX20_ENV) @@ -601,6 +645,13 @@ static int sct32_zapped_syscalls[] = { static int sct32_unique_syscalls[] = { #ifdef AFS_PPC64_LINUX20_ENV __NR_mmap2, __NR_fstat64, +#endif +#ifdef AFS_SPARC64_LINUX24_ENV + /* + * On SPARC, we need some additional unique calls to make sure + * we don't match the SunOS-compatibility table. + */ + __NR_sgetmask, __NR_ssetmask, #endif __NR_exit, __NR_mount, __NR_read, __NR_write, __NR_open, __NR_close, __NR_unlink @@ -675,7 +726,11 @@ static probectl *probe_list[] = { /********** Probing Configuration: s390x sys_call_table_emu **********/ -#elif defined(AFS_S390X_LINUX20_ENV) +/* We only actually need to do this on s390x_linux26 and later. + * On earlier versions, the two tables were interleaved and so + * have related base addresses. + */ +#elif defined(AFS_S390X_LINUX26_ENV) /* syscall pairs/triplets to probe */ /* nothing worthwhile is exported, so this is empty */ @@ -718,14 +773,14 @@ static probectl emu_probe = { emu_try, /* array of combinations to try */ /* symbol in section to try scanning */ - (unsigned long)&init_mm, + (unsigned long)&sys_close, /* default base address for scan */ /* base address bits to force to zero */ /* default length for scan */ - (unsigned long)&init_mm, - 0, - 16384, + (unsigned long)&sys_close, + 0xfffff, + 0x20000, /* number and list of unimplemented system calls */ ((sizeof(emu_zapped_syscalls)/sizeof(emu_zapped_syscalls[0])) - 1), @@ -773,17 +828,17 @@ static int check_table(probectl *P, PROBETYPE *ptr) PROBETYPE *x; int i, j; - for (x = ptr, i = 0; i < NR_syscalls; i++, x++) { + for (x = ptr, i = 0; i < _SS(NR_syscalls); i++, x++) { #ifdef OSI_PROBE_DEBUG if (probe_debug & 0x0040) { for (j = 0; j < 4; j++) { - if (P->debug_ignore_NR[j] == i) break; + if (_SS(P->debug_ignore_NR[j]) == _SX(i + P->offset)) break; } if (j < 4) continue; } #endif for (j = 0; j < 8; j++) { - if (probe_ignore_syscalls[j] == i) break; + if (_SS(probe_ignore_syscalls[j]) == _SX(i) + P->offset) break; } if (j < 8) continue; if (*x <= ktxt_lower_bound) { @@ -805,10 +860,12 @@ static int check_table(probectl *P, PROBETYPE *ptr) static void *try(probectl *P, tryctl *T, PROBETYPE *ptr, unsigned long datalen) { +#ifdef OSI_PROBE_KALLSYMS char *mod_name, *sec_name, *sym_name; unsigned long mod_start, mod_end; unsigned long sec_start, sec_end; unsigned long sym_start, sym_end; +#endif unsigned long offset, ip1, ip2, ip3; int ret; @@ -844,14 +901,15 @@ static void *try(probectl *P, tryctl *T, PROBETYPE *ptr, if ((probe_debug & 0x0002) && DEBUG_IN_RANGE(P,ptr)) printk("<7>try 0x%lx\n", (unsigned long)ptr); #endif - if (ptr[T->NR1 - P->offset] != ip1) continue; - if (ptr[T->NR2 - P->offset] != ip2) continue; - if (ip3 && ptr[T->NR3 - P->offset] != ip3) continue; + if (ptr[_SS(T->NR1 - P->offset)] != ip1) continue; + if (ptr[_SS(T->NR2 - P->offset)] != ip2) continue; + if (ip3 && ptr[_SS(T->NR3 - P->offset)] != ip3) continue; #ifdef OSI_PROBE_DEBUG if (probe_debug & 0x0002) printk("<7>try found 0x%lx\n", (unsigned long)ptr); #endif +#ifdef OSI_PROBE_KALLSYMS if (kallsyms_address_to_symbol) { ret = kallsyms_address_to_symbol((unsigned long)ptr, &mod_name, &mod_start, &mod_end, @@ -859,6 +917,7 @@ static void *try(probectl *P, tryctl *T, PROBETYPE *ptr, &sym_name, &sym_start, &sym_end); if (!ret || strcmp(sym_name, P->symbol)) continue; } +#endif /* XXX should we make sure there is only one match? */ return (void *)ptr; } @@ -873,7 +932,7 @@ static int check_harder(probectl *P, PROBETYPE *p) /* Check zapped syscalls */ for (i = 1; i < P->n_zapped_syscalls; i++) { - if (p[P->zapped_syscalls[i]] != p[P->zapped_syscalls[0]]) { + if (p[_SS(P->zapped_syscalls[i])] != p[_SS(P->zapped_syscalls[0])]) { #ifdef OSI_PROBE_DEBUG if ((probe_debug & 0x0020) && DEBUG_IN_RANGE(P,p)) printk("<7>check_harder 0x%lx zapped failed i=%d\n", (unsigned long)p, i); @@ -885,7 +944,8 @@ static int check_harder(probectl *P, PROBETYPE *p) /* Check unique syscalls */ for (i = 0; i < P->n_unique_syscalls; i++) { for (s = 0; s < NR_syscalls; s++) { - if (p[s] == p[P->unique_syscalls[i]] && s != P->unique_syscalls[i]) { + if (p[_SS(s)] == p[_SS(P->unique_syscalls[i])] + && s != P->unique_syscalls[i]) { #ifdef OSI_PROBE_DEBUG if ((probe_debug & 0x0010) && DEBUG_IN_RANGE(P,p)) printk("<7>check_harder 0x%lx unique failed i=%d s=%d\n", (unsigned long)p, i, s); @@ -901,7 +961,7 @@ static int check_harder(probectl *P, PROBETYPE *p) ip1 = (unsigned long)(P->verify_fn); #endif - if (ip1 && p[P->verifyNR - P->offset] != ip1) { + if (ip1 && p[_SS(P->verifyNR - P->offset)] != ip1) { #ifdef OSI_PROBE_DEBUG if ((probe_debug & 0x0010) && DEBUG_IN_RANGE(P,p)) printk("<7>check_harder 0x%lx verify failed\n", (unsigned long)p); @@ -918,10 +978,12 @@ static int check_harder(probectl *P, PROBETYPE *p) static void *try_harder(probectl *P, PROBETYPE *ptr, unsigned long datalen) { +#ifdef OSI_PROBE_KALLSYMS char *mod_name, *sec_name, *sym_name; unsigned long mod_start, mod_end; unsigned long sec_start, sec_end; unsigned long sym_start, sym_end; +#endif unsigned long offset; void *match = 0; int ret; @@ -951,6 +1013,7 @@ static void *try_harder(probectl *P, PROBETYPE *ptr, unsigned long datalen) printk("<7>try_harder found 0x%lx\n", (unsigned long)ptr); #endif +#ifdef OSI_PROBE_KALLSYMS if (kallsyms_address_to_symbol) { ret = kallsyms_address_to_symbol((unsigned long)ptr, &mod_name, &mod_start, &mod_end, @@ -958,6 +1021,7 @@ static void *try_harder(probectl *P, PROBETYPE *ptr, unsigned long datalen) &sym_name, &sym_start, &sym_end); if (!ret || strcmp(sym_name, P->symbol)) continue; } +#endif if (match) { #ifdef OSI_PROBE_DEBUG @@ -995,18 +1059,24 @@ static void *try_harder(probectl *P, PROBETYPE *ptr, unsigned long datalen) #endif static void *do_find_syscall_table(probectl *P, char **method) { +#ifdef OSI_PROBE_KALLSYMS char *mod_name, *sec_name, *sym_name; unsigned long mod_start, mod_end; unsigned long sec_start, sec_end; unsigned long sym_start, sym_end; + unsigned long token; + int ret; +#endif PROBETYPE *B; - unsigned long token, L; + unsigned long L; tryctl *T; void *answer; +#if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV) + void *answer2; +#endif #ifdef OSI_PROBE_DEBUG void *final_answer = 0; #endif - int ret; *method = "not found"; @@ -1014,6 +1084,7 @@ static void *do_find_syscall_table(probectl *P, char **method) check_result(P->weak_answer, "exported"); /* ask the kernel to do the name lookup, if it's willing */ +#ifdef OSI_PROBE_KALLSYMS if (kallsyms_symbol_to_address) { token = 0; sym_start = 0; @@ -1028,6 +1099,7 @@ static void *do_find_syscall_table(probectl *P, char **method) } while (ret); check_result(sym_start, "kallsyms_symbol_to_address"); } +#endif /* Maybe a little birdie told us */ check_result(P->parm_answer, "module parameter"); @@ -1037,6 +1109,7 @@ static void *do_find_syscall_table(probectl *P, char **method) B = (PROBETYPE *)((P->try_base) & ~(P->try_base_mask)); L = P->try_length; /* Now, see if the kernel will tell us something better than the default */ +#ifdef OSI_PROBE_KALLSYMS if (kallsyms_address_to_symbol) { ret = kallsyms_address_to_symbol(P->try_sect_sym, &mod_name, &mod_start, &mod_end, @@ -1047,6 +1120,7 @@ static void *do_find_syscall_table(probectl *P, char **method) L = (sec_end - sec_start) / sizeof(unsigned long); } } +#endif #ifdef OSI_PROBE_DEBUG if (probe_debug & 0x0007) @@ -1062,12 +1136,38 @@ static void *do_find_syscall_table(probectl *P, char **method) for (T = P->trylist; T->name; T++) { answer = try(P, T, B, L); +#if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV) + answer2 = try(P, T, (PROBETYPE *)(2 + (void *)B), L); +#ifdef OSI_PROBE_DEBUG + if (probe_debug & 0x0003) { + printk("<7>osi_probe: %s = 0x%016lx %s (even)\n", + P->symbol, (unsigned long)(answer), T->name); + printk("<7>osi_probe: %s = 0x%016lx %s (odd)\n", + P->symbol, (unsigned long)(answer2), T->name); + } +#endif + if (answer && answer2) answer = 0; + else if (answer2) answer = answer2; +#endif check_result(answer, T->name); } /* XXX more checks here */ answer = try_harder(P, B, L); +#if defined(AFS_S390_LINUX20_ENV) || defined(AFS_S390X_LINUX20_ENV) + answer2 = try_harder(P, (PROBETYPE *)(2 + (void *)B), L); +#ifdef OSI_PROBE_DEBUG + if (probe_debug & 0x0005) { + printk("<7>osi_probe: %s = 0x%016lx pattern scan (even)\n", + P->symbol, (unsigned long)(answer)); + printk("<7>osi_probe: %s = 0x%016lx pattern scan (odd)\n", + P->symbol, (unsigned long)(answer2)); + } +#endif + if (answer && answer2) answer = 0; + else if (answer2) answer = answer2; +#endif check_result(answer, "pattern scan"); #ifdef OSI_PROBE_DEBUG diff --git a/src/afs/LINUX/osi_syscall.c b/src/afs/LINUX/osi_syscall.c index f4ddebf0a..582904814 100644 --- a/src/afs/LINUX/osi_syscall.c +++ b/src/afs/LINUX/osi_syscall.c @@ -49,7 +49,7 @@ RCSID #define SYSCALL2POINTER (void *) #endif -#if defined(AFS_S390X_LINUX24_ENV) +#if defined(AFS_S390X_LINUX24_ENV) && !defined(AFS_LINUX26_ENV) #define _S(x) ((x)<<1) #elif defined(AFS_IA64_LINUX20_ENV) #define _S(x) ((x)-1024) @@ -123,9 +123,12 @@ asmlinkage int afs_syscall32(long syscall, long parm1, long parm2, long parm3, long parm4, long parm5) { - __asm__ __volatile__("srl %o4, 0, %o4\n\t" "mov %o7, %i7\n\t" - "call afs_syscall\n\t" "srl %o5, 0, %o5\n\t" - "ret\n\t" "nop"); + __asm__ __volatile__("srl %o4, 0, %o4\n\t" + "mov %o7, %i7\n\t" + "call afs_syscall\n\t" + "srl %o5, 0, %o5\n\t" + "ret\n\t" + "nop"); } #endif /* AFS_SPARC64_LINUX20_ENV */ @@ -136,21 +139,69 @@ afs_syscall32(long syscall, long parm1, long parm2, long parm3, long parm4, asmlinkage long afs_syscall_stub(int r0, int r1, long r2, long r3, long r4, long gp) { - __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t" "mov r41 = b0\n\t" /* save rp */ - "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 */ - ";;\n" ".L1:\n\t" "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 */ - "br.ret.sptk.many b0\n" ".fptr_afs_syscall:\n\t" - "data8 @fptr(afs_syscall)\n\t" ".skip 8"); + __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t" + "mov r41 = b0\n\t" /* save rp */ + "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 */ + ";;\n" + ".L1:\n\t" + "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 */ + "br.ret.sptk.many b0\n" + ".fptr_afs_syscall:\n\t" + "data8 @fptr(afs_syscall)\n\t" + ".skip 8"); } asmlinkage long afs_xsetgroups_stub(int r0, int r1, long r2, long r3, long r4, long gp) { - __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t" "mov r41 = b0\n\t" /* save rp */ - "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 */ - ";;\n" ".L2:\n\t" "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 */ - "br.ret.sptk.many b0\n" ".fptr_afs_xsetgroups:\n\t" - "data8 @fptr(afs_xsetgroups)\n\t" ".skip 8"); + __asm__ __volatile__("alloc r42 = ar.pfs, 8, 3, 6, 0\n\t" + "mov r41 = b0\n\t" /* save rp */ + "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 */ + ";;\n" + ".L2:\n\t" + "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 */ + "br.ret.sptk.many b0\n" + ".fptr_afs_xsetgroups:\n\t" + "data8 @fptr(afs_xsetgroups)\n\t" + ".skip 8"); } struct fptr { @@ -204,7 +255,7 @@ int osi_syscall_init(void) SYSCALL2POINTER afs_sys_call_table[_S(__NR_setgroups)]; ((struct fptr *)sys_setgroupsp)->gp = kernel_gp; - afs_sys_call_table[__S(_NR_setgroups)] = + afs_sys_call_table[_S(_NR_setgroups)] = POINTER2SYSCALL((struct fptr *)afs_xsetgroups_stub)->ip; } diff --git a/src/afs/afs.h b/src/afs/afs.h index af76a9869..c509db780 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -43,7 +43,7 @@ extern int afs_shuttingdown; #if defined(AFS_HPUX102_ENV) #define AFS_FLOCK k_flock #else -#if defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !defined(AFS_PPC64_LINUX26_ENV) && !defined(AFS_AMD64_LINUX26_ENV) && !defined(AFS_IA64_LINUX26_ENV)) +#if defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !defined(AFS_PPC64_LINUX26_ENV) && !defined(AFS_AMD64_LINUX26_ENV) && !defined(AFS_IA64_LINUX26_ENV) && !defined(AFS_S390X_LINUX26_ENV)) #define AFS_FLOCK flock64 #else #define AFS_FLOCK flock diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 9266fd77a..c165afd38 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -1096,7 +1096,7 @@ struct iparam32 { }; -#if defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) && !defined(AFS_AMD64_LINUX20_ENV)) +#if defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)) static void iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst) { @@ -1139,21 +1139,31 @@ copyin_iparam(caddr_t cmarg, struct iparam *dst) } #endif /* AFS_SUN57_64BIT_ENV */ -#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) && !defined(AFS_AMD64_LINUX20_ENV) +#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) struct iparam32 dst32; #ifdef AFS_SPARC64_LINUX24_ENV if (current->thread.flags & SPARC_FLAG_32BIT) #elif defined(AFS_SPARC64_LINUX20_ENV) if (current->tss.flags & SPARC_FLAG_32BIT) + +#elif defined(AFS_AMD64_LINUX26_ENV) + if (test_thread_flag(TIF_IA32)) #elif defined(AFS_AMD64_LINUX20_ENV) if (current->thread.flags & THREAD_IA32) + +#elif defined(AFS_PPC64_LINUX26_ENV) + if (current->thread_info->flags & _TIF_32BIT) #elif defined(AFS_PPC64_LINUX20_ENV) if (current->thread.flags & PPC_FLAG_32BIT) + +#elif defined(AFS_S390X_LINUX26_ENV) + if (test_thread_flag(TIF_31BIT)) #elif defined(AFS_S390X_LINUX20_ENV) if (current->thread.flags & S390_FLAG_31BIT) + #else -#error Not done for this linux version +#error iparam32 not done for this linux platform #endif { AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code); diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index e7d3c1491..a21de309e 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -195,7 +195,7 @@ static int (*(CpioctlSw[])) () = { #define PSetClientContext 99 /* Special pioctl to setup caller's creds */ int afs_nobody = NFS_NOBODY; -#if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) && !defined(AFS_AMD64_LINUX20_ENV)) +#if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)) static void afs_ioctl32_to_afs_ioctl(const struct afs_ioctl32 *src, struct afs_ioctl *dst) { @@ -260,25 +260,31 @@ copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst) } #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */ -#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) && !defined(AFS_AMD64_LINUX20_ENV) +#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) struct afs_ioctl32 dst32; #ifdef AFS_SPARC64_LINUX24_ENV if (current->thread.flags & SPARC_FLAG_32BIT) #elif defined(AFS_SPARC64_LINUX20_ENV) if (current->tss.flags & SPARC_FLAG_32BIT) + +#elif defined(AFS_AMD64_LINUX26_ENV) + if (test_thread_flag(TIF_IA32)) #elif defined(AFS_AMD64_LINUX20_ENV) if (current->thread.flags & THREAD_IA32) -#elif defined(AFS_PPC64_LINUX20_ENV) -#ifdef AFS_PPC64_LINUX26_ENV + +#elif defined(AFS_PPC64_LINUX26_ENV) if (current->thread_info->flags & _TIF_32BIT) -#else /*Linux 2.6 */ +#elif defined(AFS_PPC64_LINUX20_ENV) if (current->thread.flags & PPC_FLAG_32BIT) -#endif + +#elif defined(AFS_S390X_LINUX26_ENV) + if (test_thread_flag(TIF_31BIT)) #elif defined(AFS_S390X_LINUX20_ENV) if (current->thread.flags & S390_FLAG_31BIT) + #else -#error Not done for this linux type +#error pioctl32 not done for this linux #endif { AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code); diff --git a/src/cf/osconf.m4 b/src/cf/osconf.m4 index 58fd94aa8..d1c930037 100644 --- a/src/cf/osconf.m4 +++ b/src/cf/osconf.m4 @@ -414,21 +414,7 @@ case $AFS_SYSNAME in EXTRA_VLIBOBJS="fstab.o" ;; - ppc_linux22) - INSTALL="install" - KERN_OPTMZ=-O2 - LEX="flex -l" - MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' - MT_LIBS="-lpthread" - PAM_CFLAGS="-O2 -Dlinux -DLINUX_PAM -fPIC" - SHLIB_LDFLAGS="-shared -Xlinker -x" - TXLIBS="-lncurses" - XCFLAGS="-O2 -D_LARGEFILE64_SOURCE" - YACC="bison -y" - SHLIB_LINKER="${MT_CC} -shared" - ;; - - ppc_linux24) + ppc_linux*) KERN_OPTMZ=-O2 LEX="flex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' @@ -503,7 +489,7 @@ case $AFS_SYSNAME in SHLIB_LINKER="${MT_CC} -shared" ;; - s390_linux24) + s390_linux24|s390_linux26) CC="gcc" CCOBJ="gcc" LD="ld" @@ -520,7 +506,7 @@ case $AFS_SYSNAME in SHLIB_LINKER="${MT_CC} -shared" ;; - s390x_linux24) + s390x_linux24|s390x_linux26) CC="gcc" CCOBJ="gcc" LD="ld" diff --git a/src/config/afs_args.h b/src/config/afs_args.h index e28eae5ff..4c2a8f458 100644 --- a/src/config/afs_args.h +++ b/src/config/afs_args.h @@ -191,6 +191,14 @@ struct afsprocdata { long param1; long syscall; }; + +struct afsprocdata32 { + unsigned int param4; + unsigned int param3; + unsigned int param2; + unsigned int param1; + unsigned int syscall; +}; #endif diff --git a/src/config/afs_sysnames.h b/src/config/afs_sysnames.h index bfd8e4515..470ddf04d 100644 --- a/src/config/afs_sysnames.h +++ b/src/config/afs_sysnames.h @@ -154,6 +154,7 @@ #define SYS_NAME_ID_s390x_linux2 1903 #define SYS_NAME_ID_s390x_linux22 1904 #define SYS_NAME_ID_s390x_linux24 1905 +#define SYS_NAME_ID_s390x_linux26 1906 #define SYS_NAME_ID_alpha_linux_2 2000 #define SYS_NAME_ID_alpha_linux_22 2001 diff --git a/src/config/param.s390x_linux26.h b/src/config/param.s390x_linux26.h new file mode 100644 index 000000000..f4cc8931b --- /dev/null +++ b/src/config/param.s390x_linux26.h @@ -0,0 +1,173 @@ +#ifndef UKERNEL +/* This section for kernel libafs compiles only */ + +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + + +#ifndef AFS_PARAM_H +#define AFS_PARAM_H + +/* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel, + * it's a judgment call. If something is obviously s390 specific, use that + * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2" + * in the sysname is the current version of the client. This takes into + * account the perferred OS user space configuration as well as the kernel. + */ + +#define AFS_LINUX20_ENV 1 +#define AFS_LINUX22_ENV 1 +#define AFS_LINUX24_ENV 1 +#define AFS_LINUX26_ENV 1 +#define AFS_S390_LINUX20_ENV 1 +#define AFS_S390_LINUX22_ENV 1 +#define AFS_S390_LINUX24_ENV 1 +#define AFS_S390X_LINUX20_ENV 1 +#define AFS_S390X_LINUX22_ENV 1 +#define AFS_S390X_LINUX24_ENV 1 +#define AFS_S390X_LINUX26_ENV 1 +#define AFS_NONFSTRANS 1 + +#define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ +#define AFS_SYSCALL 137 +#define AFS_64BIT_ENV 1 +#define AFS_64BITPOINTER_ENV 1 +#define AFS_64BIT_CLIENT 1 +#define AFS_64BIT_KERNEL 1 +#define AFS_LINUX_64BIT_KERNEL 1 +#define AFS_64BIT_IOPS_ENV 1 +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ + +#if defined(__KERNEL__) && !defined(KDUMP_KERNEL) +#include + +#include +#ifdef CONFIG_SMP +#ifndef AFS_SMP +#define AFS_SMP 1 +#endif +#endif +/* Using "AFS_SMP" to map to however many #define's are required to get + * MP to compile for Linux + */ +#ifdef AFS_SMP +#ifndef CONFIG_SMP +#define CONFIG_SMP 1 +#endif +#ifndef __SMP__ +#define __SMP__ +#endif +#define AFS_GLOBAL_SUNLOCK +#endif +extern unsigned long __per_cpu_offset[NR_CPUS]; +extern SYSCALLTYPE sys_call_table_emu[] __attribute__((weak)); +#endif /* __KERNEL__ && !DUMP_KERNEL */ + +#include + +#define AFS_USERSPACE_IP_ADDR 1 +#define RXK_LISTENER_ENV 1 +#define AFS_GCPAGS 2 /* Set to Userdisabled, allow sysctl to override */ + +/* Machine / Operating system information */ +#define SYS_NAME "s390x_linux26" +#define SYS_NAME_ID SYS_NAME_ID_s390x_linux26 +#define AFSBIG_ENDIAN 1 +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */ + +#ifdef KERNEL +#ifndef MIN +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#endif +#ifndef MAX +#define MAX(A,B) ((A) > (B) ? (A) : (B)) +#endif +#endif /* KERNEL */ + +#endif /* AFS_PARAM_H */ + +#else /* !defined(UKERNEL) */ + +/* This section for user space compiles only */ + +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#ifndef AFS_PARAM_H +#define AFS_PARAM_H + +/* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel, + * it's a judgment call. If something is obviously s390 specific, use that + * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2" + * in the sysname is the current version of the client. This takes into + * account the perferred OS user space configuration as well as the kernel. + */ + +#define UKERNEL 1 /* user space kernel */ +#define AFS_ENV 1 +#define AFS_USR_LINUX20_ENV 1 +#define AFS_USR_LINUX22_ENV 1 +#define AFS_USR_LINUX24_ENV 1 +#define AFS_USR_LINUX26_ENV 1 +#define AFS_S390X_LINUX20_ENV 1 +#define AFS_S390X_LINUX22_ENV 1 +#define AFS_S390X_LINUX24_ENV 1 +#define AFS_S390X_LINUX26_ENV 1 +#define AFS_NONFSTRANS 1 + +#define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ +#define AFS_SYSCALL 137 +#define AFS_64BIT_ENV 1 +#define AFS_64BIT_CLIENT 1 +#define AFS_64BITPOINTER_ENV 1 +#define AFS_64BIT_IOPS_ENV 1 +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ +#include + +#define AFS_USERSPACE_IP_ADDR 1 +#define RXK_LISTENER_ENV 1 +#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ + + +/* Machine / Operating system information */ +#define SYS_NAME "s390x_linux26" +#define SYS_NAME_ID SYS_NAME_ID_s390x_linux26 +#define AFSBIG_ENDIAN 1 +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */ + +#define afsio_iov uio_iov +#define afsio_iovcnt uio_iovcnt +#define afsio_offset uio_offset +#define afsio_seg uio_segflg +#define afsio_fmode uio_fmode +#define afsio_resid uio_resid +#define AFS_UIOSYS 1 +#define AFS_UIOUSER UIO_USERSPACE +#define AFS_CLBYTES MCLBYTES +#define AFS_MINCHANGE 2 +#define VATTR_NULL usr_vattr_null + +#define AFS_DIRENT +#ifndef CMSERVERPREF +#define CMSERVERPREF +#endif + +#endif /* AFS_PARAM_H */ + +#endif /* !defined(UKERNEL) */ diff --git a/src/libafs/MakefileProto.LINUX.in b/src/libafs/MakefileProto.LINUX.in index e834f7cfb..193570622 100644 --- a/src/libafs/MakefileProto.LINUX.in +++ b/src/libafs/MakefileProto.LINUX.in @@ -66,7 +66,7 @@ DEFINES = $(COMMON_DEFINES) CCFLAGS = $(COMMON_KERN_CFLAGS) -fsigned-char DEFINES = $(COMMON_DEFINES) -D__s390__ - + CCFLAGS = $(COMMON_KERN_CFLAGS) -fsigned-char DEFINES = $(COMMON_DEFINES) -D__s390x__ @@ -160,9 +160,9 @@ ${COMPDIRS} ${INSTDIRS} ${DESTDIRS}: ln -fs ${LINUX_KERNEL_PATH}/arch/um/include/sysdep ln -fs ${LINUX_KERNEL_PATH}/include/asm-x86_64 asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-s390 asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-s390x asm ln -fs ${LINUX_KERNEL_PATH}/include/asm-ppc asm -- 2.39.5