All of lore.kernel.org
 help / color / mirror / Atom feed
From: Corey Minyard <minyard@acm.org>
To: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: akpm@osdl.org, linux-kernel@vger.kernel.org, jordan_hargrave@dell.com
Subject: Re: [PATCH] Add 32-bit ioctl translations for 64-bit platforms
Date: Fri, 20 May 2005 08:57:18 -0500	[thread overview]
Message-ID: <428DECBE.8040902@acm.org> (raw)
In-Reply-To: <20050520143337.38b6b5a6.sfr@canb.auug.org.au>

[-- Attachment #1: Type: text/plain, Size: 545 bytes --]

Stephen Rothwell wrote:

>Hi Cory,
>
>On Thu, 19 May 2005 18:33:21 -0500 Corey Minyard <minyard@acm.org> wrote:
>  
>
>>+struct ipmi_msg32
>>+{
>>+	uint8_t	      netfn;
>>+	uint8_t	      cmd;
>>+	uint16_t      data_len;
>>+	compat_uptr_t data;
>>+};
>>    
>>
>
>Why are you using unint8_t etc when we have perfectly good kernel types u8
>etc?
>  
>
I would say "Why does the kernel have its own types when there are 
perfectly good types from the C standard?"  However, it's no big deal to 
me, here's a version with the kernel types.

-Corey


[-- Attachment #2: ipmi-32-bit-compat.patch --]
[-- Type: text/x-patch, Size: 5422 bytes --]

This contains the patch for supporting 32-bit compatible
ioctls on x86_64 systems. The current x86_64 driver
will not work with 32-bit applications.

Signed-off-by: Jordan Hargave <jordan_hargrave@dell.com>
Signed-off-by: Corey Minyard <minyard@acm.org>

Index: linux-2.6.12-rc4/drivers/char/ipmi/ipmi_devintf.c
===================================================================
--- linux-2.6.12-rc4.orig/drivers/char/ipmi/ipmi_devintf.c
+++ linux-2.6.12-rc4/drivers/char/ipmi/ipmi_devintf.c
@@ -45,6 +45,7 @@
 #include <asm/semaphore.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/compat.h>
 
 #define IPMI_DEVINTF_VERSION "v33"
 
@@ -500,10 +501,184 @@
 	return rv;
 }
 
+#ifdef CONFIG_COMPAT
+/* 
+ * The following code contains code for supporting 32-bit compatible
+ * ioctls on 64-bit kernels.  This allows running 32-bit apps on the
+ * 64-bit kernel
+ */
+#define IPMICTL_SEND_COMMAND32	       _IOR(IPMI_IOC_MAGIC, 13,	 struct ipmi_req32)
+#define IPMICTL_SEND_COMMAND_SETTIME32 _IOR(IPMI_IOC_MAGIC, 21,	 struct ipmi_req_settime32)
+#define IPMICTL_RECEIVE_MSG32	       _IOWR(IPMI_IOC_MAGIC, 12, struct ipmi_recv32)
+#define IPMICTL_RECEIVE_MSG_TRUNC32    _IOWR(IPMI_IOC_MAGIC, 11, struct ipmi_recv32)
+
+struct ipmi_msg32
+{
+	u8	      netfn;
+	u8	      cmd;
+	u16	      data_len;
+	compat_uptr_t data;
+};
+
+struct ipmi_req32
+{
+	compat_uptr_t addr;
+	u32	      addr_len;
+	s32	      msgid;
+
+	struct ipmi_msg32 msg;
+};
+
+struct ipmi_recv32
+{
+	s32	      recv_type;
+	compat_uptr_t addr;
+	u32	      addr_len;
+	u32	      msgid;
+
+	struct ipmi_msg32 msg;
+};
+
+struct ipmi_req_settime32
+{
+	struct ipmi_req32  req;
+	s32		   retries;
+	u32		   retry_time_ms;
+};
+
+/*
+ * Define some helper functions for copying IPMI data
+ */
+static void ipmi_copymsg64(struct ipmi_msg *p64, struct ipmi_msg32 *p32)
+{
+	p64->netfn    = p32->netfn;
+	p64->cmd      = p32->cmd;
+	p64->data_len = p32->data_len;
+	p64->data     = (char __user *)(u64)p32->data;
+}
+static void ipmi_copymsg32(struct ipmi_msg32 *p32, struct ipmi_msg *p64)
+{
+	p32->netfn    = p64->netfn;
+	p32->cmd      = p64->cmd;
+	p32->data_len = p64->data_len;
+}
+static void ipmi_copyreq64(struct ipmi_req *p64, struct ipmi_req32 *p32)
+{
+	p64->addr     = (char __user *)(u64)p32->addr;
+	p64->addr_len = p32->addr_len;
+	p64->msgid    = p32->msgid;
+	ipmi_copymsg64(&p64->msg, &p32->msg);
+}
+static void ipmi_copyrecv64(struct ipmi_recv *p64, struct ipmi_recv32 *p32)
+{
+	p64->recv_type = p32->recv_type;
+	p64->addr      = (char __user *)(u64)p32->addr;
+	p64->addr_len  = p32->addr_len;
+	p64->msgid     = p32->msgid;
+	ipmi_copymsg64(&p64->msg, &p32->msg);
+}
+static void ipmi_copyrecv32(struct ipmi_recv32 *p32, struct ipmi_recv *p64)
+{
+	p32->recv_type = p64->recv_type;
+	p32->addr_len  = p64->addr_len;
+	p32->msgid     = p64->msgid;
+	ipmi_copymsg32(&p32->msg, &p64->msg);
+}
+
+/*
+ * Handle 32-bit ioctls on 64-bit kernel
+ */
+static long ipmi_ioctl32(struct file *filep, unsigned int cmd,
+			 unsigned long arg)
+{
+	int rc;
+
+	switch(cmd) {
+	case IPMICTL_SEND_COMMAND32:
+	{
+		struct ipmi_req	  *preq64, req64;
+		struct ipmi_req32  req32;
+      
+		/*
+		 * Copy in the 32-bit ioctl structure from userspace,
+		 * move fields to 64-bit ioctl structure, copy back to
+		 * userspace and issue 64-bit ioctl
+		 */
+		if (copy_from_user(&req32, compat_ptr(arg), sizeof(req32)))
+			return -EFAULT;
+
+		ipmi_copyreq64(&req64, &req32);
+
+		preq64 = compat_alloc_user_space(sizeof(req64));
+		if (copy_to_user(preq64, &req64, sizeof(req64)))
+			return -EFAULT;
+
+		return ipmi_ioctl(filep->f_dentry->d_inode, filep,
+				  IPMICTL_SEND_COMMAND, (long) preq64);
+	}
+	case IPMICTL_SEND_COMMAND_SETTIME32:
+	{
+		struct ipmi_req_settime	 *preq64, req64;
+		struct ipmi_req_settime32 req32;
+
+		if (copy_from_user(&req32, compat_ptr(arg), sizeof(req32)))
+			return -EFAULT;
+
+		ipmi_copyreq64(&req64.req, &req32.req); 
+		req64.retries = req32.retries;
+		req64.retry_time_ms = req32.retry_time_ms;
+
+		preq64 = compat_alloc_user_space(sizeof(req64));
+		if (copy_to_user(preq64, &req64, sizeof(req64)))
+			return -EFAULT;
+
+		return ipmi_ioctl(filep->f_dentry->d_inode, filep,
+				  IPMICTL_SEND_COMMAND_SETTIME, (long) preq64);
+	}
+	case IPMICTL_RECEIVE_MSG32:
+	case IPMICTL_RECEIVE_MSG_TRUNC32:
+	{
+		struct ipmi_recv   *precv64, recv64;
+		struct ipmi_recv32  recv32;
+
+		if (copy_from_user(&recv32, compat_ptr(arg), sizeof(recv32)))
+			return -EFAULT;
+
+		ipmi_copyrecv64(&recv64, &recv32);
+
+		precv64 = compat_alloc_user_space(sizeof(recv64));
+		if (copy_to_user(precv64, &recv64, sizeof(recv64)))
+			return -EFAULT;
+
+		rc = ipmi_ioctl(filep->f_dentry->d_inode, filep, 
+				((cmd == IPMICTL_RECEIVE_MSG32)
+				 ? IPMICTL_RECEIVE_MSG
+				 : IPMICTL_RECEIVE_MSG_TRUNC),
+				(long) precv64);
+		if (rc != 0)
+			return rc;
+
+		if (copy_from_user(&recv64, precv64, sizeof(recv64))) 
+			return -EFAULT;
+
+		ipmi_copyrecv32(&recv32, &recv64);
+		if (copy_to_user(compat_ptr(arg), &recv32, sizeof(recv32)))
+			return -EFAULT;
+
+		return rc;
+	}
+	default:
+		return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg);
+	}
+}
+#endif
 
 static struct file_operations ipmi_fops = {
 	.owner		= THIS_MODULE,
 	.ioctl		= ipmi_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl   = ipmi_ioctl32,
+#endif
 	.open		= ipmi_open,
 	.release	= ipmi_release,
 	.fasync		= ipmi_fasync,

  reply	other threads:[~2005-05-20 14:01 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-19 23:33 [PATCH] Add 32-bit ioctl translations for 64-bit platforms Corey Minyard
2005-05-20  4:33 ` Stephen Rothwell
2005-05-20 13:57   ` Corey Minyard [this message]
2005-05-20 21:22   ` Corey Minyard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=428DECBE.8040902@acm.org \
    --to=minyard@acm.org \
    --cc=akpm@osdl.org \
    --cc=jordan_hargrave@dell.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sfr@canb.auug.org.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.