Skip to contentSkip to conversation

Clean up mtrr compat ioctl code

PATCH New Brian Gerst 1 participant 1 message Oct 12, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Clean up mtrr compat ioctl code

Handle 32-bit mtrr ioctls in the mtrr driver instead of the ia32 compatability layer.

Subject: [PATCH] Clean up mtrr compat ioctl code

Handle 32-bit mtrr ioctls in the mtrr driver instead of the ia32 compatability layer.

---

 arch/i386/kernel/cpu/mtrr/if.c |  119 +++++++++++++++++++++++++---------------
 arch/x86_64/ia32/ia32_ioctl.c  |   96 --------------------------------
 include/asm-x86_64/mtrr.h      |   33 +++++++++++
 3 files changed, 107 insertions(+), 141 deletions(-)

applies-to: c6f31816e5a5afc84e920c6c3f5702327dd990de 0af3f4ccc5931bdc4301c6987134d9c172947c5a

arch/i386/kernel/cpu/mtrr/if.c +74 -45
index 1923e0a..cf39e20 100644
@@ -149,60 +149,89 @@ mtrr_write(struct file *file, const char
 	return -EINVAL;
 }
 
-static int
-mtrr_ioctl(struct inode *inode, struct file *file,
-	   unsigned int cmd, unsigned long __arg)
+static long
+mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
 {
-	int err;
+	int err = 0;
 	mtrr_type type;
 	struct mtrr_sentry sentry;
 	struct mtrr_gentry gentry;
 	void __user *arg = (void __user *) __arg;
 
 	switch (cmd) {
+	case MTRRIOC_ADD_ENTRY:
+	case MTRRIOC_SET_ENTRY:
+	case MTRRIOC_DEL_ENTRY:
+	case MTRRIOC_KILL_ENTRY:
+	case MTRRIOC_ADD_PAGE_ENTRY:
+	case MTRRIOC_SET_PAGE_ENTRY:
+	case MTRRIOC_DEL_PAGE_ENTRY:
+	case MTRRIOC_KILL_PAGE_ENTRY:
+		if (copy_from_user(&sentry, arg, sizeof sentry))
+			return -EFAULT;
+		break;
+	case MTRRIOC_GET_ENTRY:
+	case MTRRIOC_GET_PAGE_ENTRY:
+		if (copy_from_user(&gentry, arg, sizeof gentry))
+			return -EFAULT;
+		break;
+#ifdef CONFIG_COMPAT
+	case MTRRIOC32_ADD_ENTRY:
+	case MTRRIOC32_SET_ENTRY:
+	case MTRRIOC32_DEL_ENTRY:
+	case MTRRIOC32_KILL_ENTRY:
+	case MTRRIOC32_ADD_PAGE_ENTRY:
+	case MTRRIOC32_SET_PAGE_ENTRY:
+	case MTRRIOC32_DEL_PAGE_ENTRY:
+	case MTRRIOC32_KILL_PAGE_ENTRY: {
+		struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
+		err = get_user(sentry.base, &s32->base);
+		err |= get_user(sentry.size, &s32->size);
+		err |= get_user(sentry.type, &s32->type);
+		if (err)
+			return err;
+		break;
+	}
+	case MTRRIOC32_GET_ENTRY:
+	case MTRRIOC32_GET_PAGE_ENTRY: {
+		struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+		err = get_user(gentry.regnum, &g32->regnum);
+		err |= get_user(gentry.base, &g32->base);
+		err |= get_user(gentry.size, &g32->size);
+		err |= get_user(gentry.type, &g32->type);
+		if (err)
+			return err;
+		break;
+	}
+#endif
+	}
+
+	switch (cmd) {
 	default:
 		return -ENOTTY;
 	case MTRRIOC_ADD_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err =
 		    mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
 				  file, 0);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_SET_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err = mtrr_add(sentry.base, sentry.size, sentry.type, 0);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_DEL_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err = mtrr_file_del(sentry.base, sentry.size, file, 0);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_KILL_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err = mtrr_del(-1, sentry.base, sentry.size);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_GET_ENTRY:
-		if (copy_from_user(&gentry, arg, sizeof gentry))
-			return -EFAULT;
 		if (gentry.regnum >= num_var_ranges)
 			return -EINVAL;
 		mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
@@ -217,60 +246,59 @@ mtrr_ioctl(struct inode *inode, struct f
 			gentry.type = type;
 		}
 
-		if (copy_to_user(arg, &gentry, sizeof gentry))
-			return -EFAULT;
 		break;
 	case MTRRIOC_ADD_PAGE_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err =
 		    mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
 				  file, 1);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_SET_PAGE_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_DEL_PAGE_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err = mtrr_file_del(sentry.base, sentry.size, file, 1);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_KILL_PAGE_ENTRY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if (copy_from_user(&sentry, arg, sizeof sentry))
-			return -EFAULT;
 		err = mtrr_del_page(-1, sentry.base, sentry.size);
-		if (err < 0)
-			return err;
 		break;
 	case MTRRIOC_GET_PAGE_ENTRY:
-		if (copy_from_user(&gentry, arg, sizeof gentry))
-			return -EFAULT;
 		if (gentry.regnum >= num_var_ranges)
 			return -EINVAL;
 		mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
 		gentry.type = type;
+		break;
+	}
+
+	if (err)
+		return err;
 
+	switch(cmd) {
+	case MTRRIOC_GET_ENTRY:
+	case MTRRIOC_GET_PAGE_ENTRY:
 		if (copy_to_user(arg, &gentry, sizeof gentry))
-			return -EFAULT;
+			err = -EFAULT;
+		break;
+#ifdef CONFIG_COMPAT
+	case MTRRIOC32_GET_ENTRY:
+	case MTRRIOC32_GET_PAGE_ENTRY: {
+		struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+		err = put_user(gentry.base, &g32->base);
+		err |= put_user(gentry.size, &g32->size);
+		err |= put_user(gentry.regnum, &g32->regnum);
+		err |= put_user(gentry.type, &g32->type);
 		break;
 	}
-	return 0;
+#endif
+	}
+	return err;
 }
 
 static int
@@ -310,7 +338,8 @@ static struct file_operations mtrr_fops 
 	.read    = seq_read,
 	.llseek  = seq_lseek,
 	.write   = mtrr_write,
-	.ioctl   = mtrr_ioctl,
+	.unlocked_ioctl = mtrr_ioctl,
+	.compat_ioctl = mtrr_ioctl,
 	.release = mtrr_close,
 };
 
arch/x86_64/ia32/ia32_ioctl.c +0 -96

114 lines not on this page · raw message

include/asm-x86_64/mtrr.h +33 -0
index c5959d6..66ac1c0 100644
@@ -25,6 +25,7 @@
 
 #include <linux/config.h>
 #include <linux/ioctl.h>
+#include <linux/compat.h>
 
 #define	MTRR_IOCTL_BASE	'M'
 
@@ -105,4 +106,36 @@ static __inline__ int mtrr_del_page (int
 
 #endif
 
+#ifdef CONFIG_COMPAT
+
+struct mtrr_sentry32
+{
+    compat_ulong_t base;    /*  Base address     */
+    compat_uint_t size;    /*  Size of region   */
+    compat_uint_t type;     /*  Type of region   */
+};
+
+struct mtrr_gentry32
+{
+    compat_ulong_t regnum;   /*  Register number  */
+    compat_uint_t base;    /*  Base address     */
+    compat_uint_t size;    /*  Size of region   */
+    compat_uint_t type;     /*  Type of region   */
+};
+
+#define MTRR_IOCTL_BASE 'M'
+
+#define MTRRIOC32_ADD_ENTRY        _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
+#define MTRRIOC32_SET_ENTRY        _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
+#define MTRRIOC32_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
+#define MTRRIOC32_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
+#define MTRRIOC32_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
+#define MTRRIOC32_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
+
+#endif /* CONFIG_COMPAT */
+
 #endif  /*  _LINUX_MTRR_H  */

---
0.99.8.GIT