public inbox for linux-kernel@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox