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);
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
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)
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];