sparc64-linux-and-setgroups32-cleanup-20020422
authorChaskiel M Grundman <cg2v@andrew.cmu.edu>
Tue, 23 Apr 2002 04:26:36 +0000 (04:26 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 23 Apr 2002 04:26:36 +0000 (04:26 +0000)
update setgroups32 for 2.4 and make sparc64 linux2.4 work again

src/afs/LINUX/osi_alloc.c
src/afs/LINUX/osi_groups.c
src/afs/afs_call.c

index 154fce5..b0b9389 100644 (file)
@@ -187,9 +187,15 @@ hash_verify(size_t index, unsigned key, void *data)
     int memtype;
 
     memtype = MEMTYPE(lmp->chunk);
+#ifdef AFS_SPARC64_LINUX24_ENV
+    if ((memtype == KM_TYPE) && (!VALID_PAGE(virt_to_page(lmp->chunk)))) {
+       printf("osi_linux_verify_alloced_memory: address 0x%x outside range, index=%d, key=%d\n", lmp->chunk, index, key);
+    }
+#else
     if ((memtype == KM_TYPE) && (AFS_LINUX_MAP_NR(lmp->chunk) > max_mapnr)) {
        printf("osi_linux_verify_alloced_memory: address 0x%x outside range, index=%d, key=%d\n", lmp->chunk, index, key);
     }
+#endif
     
     if (memtype != KM_TYPE && memtype != VM_TYPE) {
        printf("osi_linux_verify_alloced_memory: unknown type %d at 0x%x, index=%d\n",    memtype, lmp->chunk, index);
index bd6f695..922fddf 100644 (file)
@@ -162,39 +162,68 @@ asmlinkage int afs_xsetgroups32(int gidsetsize, gid_t *grouplist)
     return code;
 }
 #endif
+
 #if defined(AFS_SPARC64_LINUX20_ENV)
+/* Intercept the uid16 system call as used by 32bit programs. */
+extern int (*sys32_setgroupsp)(int gidsetsize, __kernel_gid_t32 *grouplist);
 asmlinkage int afs32_xsetgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
 {
-    gid_t gl[NGROUPS];
-    int ret, i;
-    mm_segment_t old_fs = get_fs ();
-
-    if ((unsigned) gidsetsize > NGROUPS)
-       return -EINVAL;
-    for (i = 0; i < gidsetsize; i++, grouplist++)
-       if (__get_user (gl[i], grouplist))
-           return -EFAULT;
-    set_fs (KERNEL_DS);
-    ret = afs_xsetgroups(gidsetsize, gl);
-    set_fs (old_fs);
-    return ret;
+    int code;
+    cred_t *cr = crref();
+    afs_uint32 junk;
+    int old_pag;
+
+    lock_kernel();
+    old_pag = PagInCred(cr);
+    crfree(cr);
+    unlock_kernel();
+
+    code = (*sys32_setgroupsp)(gidsetsize, grouplist);
+    if (code) {
+       return code;
+    }
+
+    lock_kernel();
+    cr = crref();
+    if (old_pag != NOPAG && PagInCred(cr) == NOPAG) {
+       /* re-install old pag if there's room. */
+       code = setpag(&cr, old_pag, &junk, 0);
+    }
+    crfree(cr);
+    unlock_kernel();
+
+    return code;
 }
 #ifdef AFS_LINUX24_ENV
+/* Intercept the uid32 system call as used by 32bit programs. */
+extern int (*sys32_setgroups32p)(int gidsetsize, __kernel_gid_t32 *grouplist);
 asmlinkage int afs32_xsetgroups32(int gidsetsize, __kernel_gid_t32 *grouplist)
 {
-    gid_t gl[NGROUPS];
-    int ret, i;
-    mm_segment_t old_fs = get_fs ();
-
-    if ((unsigned) gidsetsize > NGROUPS)
-       return -EINVAL;
-    for (i = 0; i < gidsetsize; i++, grouplist++)
-       if (__get_user (gl[i], grouplist))
-           return -EFAULT;
-    set_fs (KERNEL_DS);
-    ret = afs_xsetgroups32(gidsetsize, gl);
-    set_fs (old_fs);
-    return ret;
+    int code;
+    cred_t *cr = crref();
+    afs_uint32 junk;
+    int old_pag;
+
+    lock_kernel();
+    old_pag = PagInCred(cr);
+    crfree(cr);
+    unlock_kernel();
+
+    code = (*sys32_setgroups32p)(gidsetsize, grouplist);
+    if (code) {
+       return code;
+    }
+
+    lock_kernel();
+    cr = crref();
+    if (old_pag != NOPAG && PagInCred(cr) == NOPAG) {
+       /* re-install old pag if there's room. */
+       code = setpag(&cr, old_pag, &junk, 0);
+    }
+    crfree(cr);
+    unlock_kernel();
+
+    return code;
 }
 #endif
 #endif
index 06db6f3..664b848 100644 (file)
@@ -985,6 +985,9 @@ asmlinkage int afs_syscall(long syscall, long parm1, long parm2, long parm3,
     long linux_ret=0;
     long *retval = &linux_ret;
     long eparm[4]; /* matches AFSCALL_ICL in fstrace.c */
+#ifdef AFS_SPARC64_LINUX24_ENV
+    afs_int32 eparm32[4];
+#endif
     /* eparm is also used by AFSCALL_CALL in afsd.c */
 #else
 #if defined(UKERNEL)
@@ -1047,6 +1050,25 @@ Afs_syscall ()
     uap->parm2 = parm2;
     uap->parm3 = parm3;
     if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) {
+#ifdef AFS_SPARC64_LINUX24_ENV
+/* from arch/sparc64/kernel/sys_sparc32.c */
+#define AA(__x)                                \
+({     unsigned long __ret;            \
+       __asm__ ("srl   %0, 0, %0"      \
+                : "=r" (__ret)         \
+                : "0" (__x));          \
+       __ret;                          \
+})
+
+
+       if (current->thread.flags & SPARC_FLAG_32BIT) {
+       AFS_COPYIN((char*)parm4, (char*)eparm32, sizeof(eparm32), code);
+       eparm[0]=AA(eparm32[0]);
+       eparm[1]=AA(eparm32[1]);
+       eparm[2]=AA(eparm32[2]);
+#undef AA
+} else
+#endif
        AFS_COPYIN((char*)parm4, (char*)eparm, sizeof(eparm), code);
        uap->parm4 = eparm[0];
        uap->parm5 = eparm[1];