I fixed some minor detail in Kanoj patch for wrapping the shmctl in alpha
(mainly to make it to compile) and then I checked it works for me.
It seems shmctl is the only syscall that needs wrapping because - despite
the interface breakage of shmget - the "int" was just casted to long
because the syscall interface on alpha passes all parameters throught
64bit registers.
So I suggest to apply this patch to 2.3.35pre6 so shmctl won't break
in 2.3.x with the current Alpha binaries and X will run fine.
diff -urN 2.3.35pre6/arch/alpha/kernel/entry.S a/arch/alpha/kernel/entry.S
--- 2.3.35pre6/arch/alpha/kernel/entry.S Fri Dec 24 02:00:56 1999
+++ a/arch/alpha/kernel/entry.S Wed Dec 29 23:12:52 1999
@@ -985,7 +985,7 @@
.quad osf_utsname
.quad sys_lchown
.quad osf_shmat
- .quad sys_shmctl /* 210 */
+ .quad sys_shmctlold /* 210 */
.quad sys_shmdt
.quad sys_shmget
.quad alpha_ni_syscall
@@ -1150,3 +1150,4 @@
.quad sys_setresgid
.quad sys_getresgid
.quad sys_ni_syscall /* sys_dipc */
+ .quad sys_shmctl
diff -urN 2.3.35pre6/arch/alpha/kernel/osf_sys.c a/arch/alpha/kernel/osf_sys.c
--- 2.3.35pre6/arch/alpha/kernel/osf_sys.c Tue Sep 14 14:33:08 1999
+++ a/arch/alpha/kernel/osf_sys.c Wed Dec 29 23:35:42 1999
@@ -31,6 +31,9 @@
#include <linux/shm.h>
#include <linux/poll.h>
#include <linux/file.h>
+#include <linux/types.h>
+#include <linux/ipc.h>
+#include <linux/shm.h>
#include <asm/fpu.h>
#include <asm/io.h>
@@ -38,6 +41,7 @@
#include <asm/system.h>
#include <asm/sysinfo.h>
#include <asm/hwrpb.h>
+#include <asm/processor.h>
extern int do_mount(kdev_t, const char *, const char *, char *, int, void *);
extern int do_pipe(int *);
@@ -1441,4 +1445,104 @@
return -EFAULT;
return ret;
+}
+
+struct shmid_ds_old {
+ struct ipc_perm shm_perm; /* operation perms */
+ int shm_segsz; /* size of segment (bytes) */
+ __kernel_time_t shm_atime; /* last attach time */
+ __kernel_time_t shm_dtime; /* last detach time */
+ __kernel_time_t shm_ctime; /* last change time */
+ __kernel_ipc_pid_t shm_cpid; /* pid of creator */
+ __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
+ unsigned short shm_nattch; /* no. of current attaches */
+ unsigned short shm_unused; /* compatibility */
+ void *shm_unused2; /* ditto - used by DIPC */
+ void *shm_unused3; /* unused */
+};
+
+struct shminfo_old {
+ int shmmax;
+ int shmmin;
+ int shmmni;
+ int shmseg;
+ int shmall;
+};
+
+asmlinkage long sys_shmctlold(int shmid, int cmd, struct shmid_ds_old *buf)
+{
+ struct shmid_ds arg;
+ long ret;
+ mm_segment_t old_fs;
+
+ if (cmd == IPC_SET) {
+ struct shmid_ds_old tbuf;
+
+ if(copy_from_user (&tbuf, buf, sizeof(*buf)))
+ return -EFAULT;
+ arg.shm_perm = tbuf.shm_perm;
+ arg.shm_segsz = tbuf.shm_segsz;
+ arg.shm_atime = tbuf.shm_atime;
+ arg.shm_dtime = tbuf.shm_dtime;
+ arg.shm_ctime = tbuf.shm_ctime;
+ arg.shm_cpid = tbuf.shm_cpid;
+ arg.shm_lpid = tbuf.shm_lpid;
+ arg.shm_nattch = tbuf.shm_nattch;
+ arg.shm_unused = tbuf.shm_unused;
+ arg.shm_unused2 = tbuf.shm_unused2;
+ arg.shm_unused3 = tbuf.shm_unused3;
+ }
+ old_fs = get_fs ();
+ set_fs (KERNEL_DS);
+ ret = sys_shmctl(shmid, cmd, &arg);
+ set_fs (old_fs);
+ if (ret < 0)
+ return(ret);
+ switch(cmd) {
+ case IPC_INFO:
+ {
+ struct shminfo *tbuf = (struct shminfo *) &arg;
+ struct shminfo_old shminfo_oldst;
+
+ shminfo_oldst.shmmax = (tbuf->shmmax > INT_MAX ?
+ INT_MAX : tbuf->shmmax);
+ shminfo_oldst.shmmin = tbuf->shmmin;
+ shminfo_oldst.shmmni = tbuf->shmmni;
+ shminfo_oldst.shmseg = tbuf->shmseg;
+ shminfo_oldst.shmall = tbuf->shmall;
+ if (copy_to_user(buf, &shminfo_oldst,
+ sizeof(struct shminfo_old)))
+ return -EFAULT;
+ return(ret);
+ }
+ case SHM_INFO:
+ {
+ struct shm_info *tbuf = (struct shm_info *) &arg;
+
+ if (copy_to_user (buf, tbuf, sizeof(struct shm_info)))
+ return -EFAULT;
+ return(ret);
+ }
+ case SHM_STAT:
+ case IPC_STAT:
+ {
+ struct shmid_ds_old tbuf;
+
+ tbuf.shm_perm = arg.shm_perm;
+ tbuf.shm_segsz = arg.shm_segsz;
+ tbuf.shm_atime = arg.shm_atime;
+ tbuf.shm_dtime = arg.shm_dtime;
+ tbuf.shm_ctime = arg.shm_ctime;
+ tbuf.shm_cpid = arg.shm_cpid;
+ tbuf.shm_lpid = arg.shm_lpid;
+ tbuf.shm_nattch = arg.shm_nattch;
+ tbuf.shm_unused = arg.shm_unused;
+ tbuf.shm_unused2 = arg.shm_unused2;
+ tbuf.shm_unused3 = arg.shm_unused3;
+ if (copy_to_user (buf, &tbuf, sizeof(tbuf)))
+ return -EFAULT;
+ return(ret);
+ }
+ }
+ return(ret);
}
In the future libc on alpha may want to use the new shmid_ds struct in
linux/include/linux.h and then to call the new shmctl syscall instead of
the old syscall.
Andrea