[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 {