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,
next prev parent 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.