[parisc-linux-cvs] Added 64-bit wrappers for msgctl(), semctl(), msgrcv(), msgsnd().
bame@riverrock.org
bame@riverrock.org
Mon, 26 Feb 2001 17:55:18 -0700
These wrappers involved making some changes to header files used by
narrow kernel but in ways don't invalidate the ABI.
Index: arch/parisc/kernel/syscall.S
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/syscall.S,v
retrieving revision 1.56
diff -u -r1.56 syscall.S
--- syscall.S 2001/02/23 05:08:19 1.56
+++ syscall.S 2001/02/27 00:46:45
@@ -541,19 +541,15 @@
/* *sockopt() might work... */
ENTRY_SAME(setsockopt)
ENTRY_SAME(getsockopt)
- /* struct msghdr contains pointers... */
ENTRY_DIFF(sendmsg)
ENTRY_DIFF(recvmsg)
ENTRY_SAME(semop) /* 185 */
ENTRY_SAME(semget)
- /* needs a more careful review */
- ENTRY_UHOH(semctl)
- /* struct msgbuf contains a long */
- ENTRY_UHOH(msgsnd)
- ENTRY_UHOH(msgrcv)
+ ENTRY_DIFF(semctl)
+ ENTRY_DIFF(msgsnd)
+ ENTRY_DIFF(msgrcv)
ENTRY_SAME(msgget) /* 190 */
- /* struct msqid_ds contains pointers */
- ENTRY_UHOH(msgctl)
+ ENTRY_DIFF(msgctl)
ENTRY_SAME(shmat_wrapper)
ENTRY_SAME(shmdt)
ENTRY_SAME(shmget)
Index: arch/parisc64/kernel/sys_parisc32.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc64/kernel/sys_parisc32.c,v
retrieving revision 1.16
diff -u -r1.16 sys_parisc32.c
--- sys_parisc32.c 2001/02/08 06:20:15 1.16
+++ sys_parisc32.c 2001/02/27 00:46:46
@@ -2464,3 +2464,170 @@
out_nofds:
return ret;
}
+
+struct msgbuf32 {
+ int mtype;
+ char mtext[1];
+};
+
+asmlinkage long sys32_msgsnd(int msqid,
+ struct msgbuf32 *umsgp32,
+ size_t msgsz, int msgflg)
+{
+ struct msgbuf *mb;
+ struct msgbuf32 mb32;
+ int err;
+
+ if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL)
+ return ENOMEM;
+
+ err = get_user(mb32.mtype, &umsgp32->mtype);
+ mb->mtype = mb32.mtype;
+ err |= copy_from_user(mb->mtext, &umsgp32->mtext, msgsz);
+
+ if (err == 0) {
+ KERNEL_SYSCALL(err, sys_msgsnd, msqid, mb, msgsz, msgflg);
+ }
+
+ kfree(mb);
+ return err;
+}
+
+asmlinkage long sys32_msgrcv(int msqid,
+ struct msgbuf32 *umsgp32,
+ size_t msgsz, long msgtyp, int msgflg)
+{
+ struct msgbuf *mb;
+ struct msgbuf32 mb32;
+ int err;
+
+ if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL)
+ return ENOMEM;
+
+ KERNEL_SYSCALL(err, sys_msgrcv, msqid, mb, msgsz, msgtyp, msgflg);
+
+ if (err >= 0) {
+ mb32.mtype = mb->mtype;
+ err = put_user(mb32.mtype, &umsgp32->mtype);
+ err |= copy_to_user(&umsgp32->mtext, mb->mtext, err);
+ }
+
+ kfree(mb);
+ return err;
+}
+
+/* XXX FIXME Probably the msgctl() is not required */
+extern int ipc_parse_version (int *cmd);
+
+asmlinkage long sys32_msgctl (int msqid, int cmd, void *buf)
+{
+ int err = -EINVAL;
+
+ switch (cmd) {
+
+ case IPC_INFO:
+ case MSG_INFO:
+ /* struct msginfo needs no translation -- fall through */
+ case IPC_RMID:
+ err = sys_msgctl (msqid, cmd, buf);
+ break;
+
+ case IPC_SET:
+ /* Don't support the older stuff */
+ if (ipc_parse_version(&cmd) != IPC_64) {
+ printk("msgctl() does not support libc5 IPC_SET\n");
+ return ENOSYS;
+ }
+ /* padded values (time_t's) aren't used, so this is safe */
+ err = sys_msgctl(msqid, cmd, buf);
+ break;
+
+ case IPC_STAT:
+ case MSG_STAT:
+ /* Don't support the older stuff */
+ if (ipc_parse_version(&cmd) != IPC_64) {
+ printk("msgctl() does not support libc5 IPC_STAT\n");
+ return ENOSYS;
+ }
+ err = sys_msgctl(msqid, cmd, buf);
+ break;
+
+ }
+
+ return err;
+}
+
+struct shmid64_ds32 {
+ struct ipc64_perm shm_perm; /* operation perms */
+ unsigned int __pad1;
+ __kernel_time_t32 shm_atime; /* last attach time */
+ unsigned int __pad2;
+ __kernel_time_t32 shm_dtime; /* last detach time */
+ unsigned int __pad3;
+ __kernel_time_t32 shm_ctime; /* last change time */
+ __kernel_size_t32 shm_segsz; /* size of segment (bytes) */
+ __kernel_pid_t shm_cpid; /* pid of creator */
+ __kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned int shm_nattch; /* no. of current attaches */
+ unsigned int __unused1;
+ unsigned int __unused2;
+};
+
+asmlinkage long sys32_semctl(int semid, int semnum, int cmd, union semun arg)
+{
+ int err = EINVAL;
+ struct shmid64_ds s64;
+ union semun u;
+ int version = ipc_parse_version(&cmd);
+
+
+ switch (cmd) {
+ case IPC_SET:
+ if (version != IPC_64) {
+ printk("semctl(IPC_STAT(cmd=0x%x)) does not support libc5-style cmds\n", cmd);
+ return ENOSYS;
+ }
+ /* FALL THROUGH */
+ case IPC_INFO:
+ case SEM_INFO:
+ case IPC_RMID:
+ case GETVAL:
+ case GETPID:
+ case GETNCNT:
+ case GETZCNT:
+ case GETALL:
+ case SETVAL:
+ case SETALL:
+ err = sys_semctl (semid, semnum, cmd, arg);
+ break;
+
+ case IPC_STAT:
+ case SEM_STAT:
+ if (version != IPC_64) {
+ printk("semctl(IPC_STAT(cmd=0x%x)) does not support libc5-style cmds\n", cmd);
+ return ENOSYS;
+ }
+ u.buf = &s64;
+ KERNEL_SYSCALL(err, sys_semctl, semid, semnum, cmd, u);
+ if (err == 0) {
+ struct shmid64_ds32 s32;
+ memcpy(&s32.shm_perm, &s64.shm_perm, sizeof s32.shm_perm);
+ s32.shm_segsz = s64.shm_segsz;
+ s32.shm_atime = s64.shm_atime;
+ s32.shm_dtime = s64.shm_dtime;
+ s32.shm_ctime = s64.shm_ctime;
+ s32.shm_cpid = s64.shm_cpid;
+ s32.shm_lpid = s64.shm_lpid;
+ s32.shm_nattch = s64.shm_nattch;
+ return copy_to_user((struct shmid64_ds32 *)arg.buf, &s32, sizeof s32);
+ }
+ break;
+
+ default:
+ printk("semctl(cmd=%d) undefined cmd\n", cmd);
+ err = ENOSYS;
+ break;
+ }
+
+ return err;
+}
Index: include/asm-parisc/ipcbuf.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/ipcbuf.h,v
retrieving revision 1.2
diff -u -r1.2 ipcbuf.h
--- ipcbuf.h 2000/02/26 18:50:00 1.2
+++ ipcbuf.h 2001/02/27 00:46:46
@@ -2,10 +2,21 @@
#define __PARISC_IPCBUF_H__
/*
- * The ipc64_perm structure for PA-RISC is identical to kern_ipc_perm
- * as we have always had 32-bit UIDs and GIDs in the kernel.
+ * The ipc64_perm structure for PA-RISC is almost identical to
+ * kern_ipc_perm as we have always had 32-bit UIDs and GIDs in the kernel.
+ * 'seq' has been changed from long to int so that it's the same size
+ * on 64-bit kernels as on 32-bit ones.
*/
-#define ipc64_perm kern_ipc_perm
+struct ipc64_perm
+{
+ key_t key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ mode_t mode;
+ unsigned int seq;
+};
#endif /* __PARISC_IPCBUF_H__ */
Index: include/asm-parisc/msgbuf.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/msgbuf.h,v
retrieving revision 1.2
diff -u -r1.2 msgbuf.h
--- msgbuf.h 2000/10/25 17:25:59 1.2
+++ msgbuf.h 2001/02/27 00:46:46
@@ -13,11 +13,17 @@
struct msqid64_ds {
struct ipc64_perm msg_perm;
+#ifndef __LP64__
unsigned int __pad1;
+#endif
__kernel_time_t msg_stime; /* last msgsnd time */
+#ifndef __LP64__
unsigned int __pad2;
+#endif
__kernel_time_t msg_rtime; /* last msgrcv time */
+#ifndef __LP64__
unsigned int __pad3;
+#endif
__kernel_time_t msg_ctime; /* last change time */
unsigned int msg_cbytes; /* current number of bytes on queue */
unsigned int msg_qnum; /* number of messages in queue */
Index: include/asm-parisc/sembuf.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/sembuf.h,v
retrieving revision 1.2
diff -u -r1.2 sembuf.h
--- sembuf.h 2000/10/25 22:35:14 1.2
+++ sembuf.h 2001/02/27 00:46:46
@@ -13,9 +13,13 @@
struct semid64_ds {
struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+#ifndef __LP64__
unsigned int __pad1;
+#endif
__kernel_time_t sem_otime; /* last semop time */
+#ifndef __LP64__
unsigned int __pad2;
+#endif
__kernel_time_t sem_ctime; /* last change time */
unsigned int sem_nsems; /* no. of semaphores in array */
unsigned int __unused1;
Index: include/asm-parisc/shmbuf.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/shmbuf.h,v
retrieving revision 1.2
diff -u -r1.2 shmbuf.h
--- shmbuf.h 2000/10/25 22:38:00 1.2
+++ shmbuf.h 2001/02/27 00:46:46
@@ -13,11 +13,17 @@
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
+#ifndef __LP64__
unsigned int __pad1;
+#endif
__kernel_time_t shm_atime; /* last attach time */
+#ifndef __LP64__
unsigned int __pad2;
+#endif
__kernel_time_t shm_dtime; /* last detach time */
+#ifndef __LP64__
unsigned int __pad3;
+#endif
__kernel_time_t shm_ctime; /* last change time */
size_t shm_segsz; /* size of segment (bytes) */
__kernel_pid_t shm_cpid; /* pid of creator */
@@ -28,11 +34,10 @@
};
#ifdef __LP64__
-#warning shminfo64 is an undocumented struct
/* The 'unsigned int' (formerly 'unsigned long') data types below will
* ensure that a 32-bit app calling shmctl(*,IPC_INFO,*) will work on
* a wide kernel, but if some of these values are meant to contain pointers
- * they may need to be 'long long' instead. -PB
+ * they may need to be 'long long' instead. -PB XXX FIXME
*/
#endif
struct shminfo64 {