unified-osi-probe-2-20050216
authorJeffrey Hutzelman <jhutz@cs.cmu.edu>
Wed, 16 Feb 2005 22:47:35 +0000 (22:47 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 16 Feb 2005 22:47:35 +0000 (22:47 +0000)
FIXES 17548

update osi_probe

src/afs/LINUX/osi_module.c
src/afs/LINUX/osi_probe.c
src/afs/LINUX/osi_syscall.c
src/afs/afs.h
src/afs/afs_call.c
src/afs/afs_pioctl.c
src/cf/osconf.m4
src/config/afs_args.h
src/config/afs_sysnames.h
src/config/param.s390x_linux26.h [new file with mode: 0644]
src/libafs/MakefileProto.LINUX.in

index f021681..6cfe801 100644 (file)
@@ -477,14 +477,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);
+    }
 }
 
 
index fc9c394..83f3a19 100644 (file)
 #include <asm/ia32_unistd.h>
 #endif
 
-#ifdef HAVE_KERNEL_LINUX_SYSCALL_H
-#include <linux/syscall.h>
-#endif
-
 /* number of syscalls */
 /* NB: on MIPS we care about the 4xxx range */
 #ifndef NR_syscalls
 #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.
 #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)
 
@@ -602,6 +646,13 @@ 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
index f4ddebf..5829048 100644 (file)
@@ -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;
     }
 
index af76a98..c509db7 100644 (file)
@@ -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
index 9266fd7..c165afd 100644 (file)
@@ -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);
index e7d3c14..a21de30 100644 (file)
@@ -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);
index 58fd94a..d1c9300 100644 (file)
@@ -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"
index cd86d43..b2dce5d 100644 (file)
@@ -197,6 +197,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
 
index bfd8e45..470ddf0 100644 (file)
 #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 (file)
index 0000000..f4cc893
--- /dev/null
@@ -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 <linux/threads.h>
+
+#include <linux/config.h>
+#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 <afs/afs_sysnames.h>
+
+#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 <afs/afs_sysnames.h>
+
+#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) */
index e834f7c..1935706 100644 (file)
@@ -66,7 +66,7 @@ DEFINES = $(COMMON_DEFINES)
 CCFLAGS = $(COMMON_KERN_CFLAGS) -fsigned-char
 DEFINES = $(COMMON_DEFINES) -D__s390__ 
 
-<s390x_linux22 s390x_linux24>
+<s390x_linux22 s390x_linux24 s390x_linux26>
 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
 <amd64_linux24 amd64_linux26>
        ln -fs ${LINUX_KERNEL_PATH}/include/asm-x86_64 asm
-<s390_linux22 s390_linux24 s390_linux26>
+<s390_linux22 s390_linux24 s390_linux26 s390x_linux26>
        ln -fs ${LINUX_KERNEL_PATH}/include/asm-s390 asm
-<s390x_linux22 s390x_linux24 s390x_linux26>
+<s390x_linux22 s390x_linux24>
        ln -fs ${LINUX_KERNEL_PATH}/include/asm-s390x asm
 <ppc_linux22 ppc_linux24 ppc_linux26>
        ln -fs ${LINUX_KERNEL_PATH}/include/asm-ppc asm