Implement ->proc_ioctl_buf() so procfs copies the arguments in before
it pins the entry and back out after unpinning it. The native and the
32-bit commands encode their arguments and share one table.
mtrr_ioctl() reads and fills procfs' copy, also in the 32-bit layouts.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 arch/x86/kernel/cpu/mtrr/if.c | 79 +++++++++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 33 deletions(-)

diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index 038e2dc38797..9c33c0428dfe 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -149,7 +149,7 @@ mtrr_write(struct file *file, char *buf, size_t len, loff_t 
* ppos)
 }
 
 static long
-mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
+mtrr_ioctl(struct file *file, unsigned int cmd, void *arg)
 {
        int err = 0;
        mtrr_type type;
@@ -157,7 +157,6 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned 
long __arg)
        unsigned long size;
        struct mtrr_sentry sentry;
        struct mtrr_gentry gentry;
-       void __user *arg = (void __user *) __arg;
 
        memset(&gentry, 0, sizeof(gentry));
 
@@ -170,13 +169,11 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned 
long __arg)
        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;
+               memcpy(&sentry, arg, sizeof(sentry));
                break;
        case MTRRIOC_GET_ENTRY:
        case MTRRIOC_GET_PAGE_ENTRY:
-               if (copy_from_user(&gentry, arg, sizeof(gentry)))
-                       return -EFAULT;
+               memcpy(&gentry, arg, sizeof(gentry));
                break;
 #ifdef CONFIG_COMPAT
        case MTRRIOC32_ADD_ENTRY:
@@ -187,27 +184,21 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned 
long __arg)
        case MTRRIOC32_SET_PAGE_ENTRY:
        case MTRRIOC32_DEL_PAGE_ENTRY:
        case MTRRIOC32_KILL_PAGE_ENTRY: {
-               struct mtrr_sentry32 __user *s32;
+               struct mtrr_sentry32 *s32 = arg;
 
-               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;
+               sentry.base = s32->base;
+               sentry.size = s32->size;
+               sentry.type = s32->type;
                break;
        }
        case MTRRIOC32_GET_ENTRY:
        case MTRRIOC32_GET_PAGE_ENTRY: {
-               struct mtrr_gentry32 __user *g32;
+               struct mtrr_gentry32 *g32 = arg;
 
-               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;
+               gentry.regnum = g32->regnum;
+               gentry.base = g32->base;
+               gentry.size = g32->size;
+               gentry.type = g32->type;
                break;
        }
 #endif
@@ -312,19 +303,17 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned 
long __arg)
        switch (cmd) {
        case MTRRIOC_GET_ENTRY:
        case MTRRIOC_GET_PAGE_ENTRY:
-               if (copy_to_user(arg, &gentry, sizeof(gentry)))
-                       err = -EFAULT;
+               memcpy(arg, &gentry, sizeof(gentry));
                break;
 #ifdef CONFIG_COMPAT
        case MTRRIOC32_GET_ENTRY:
        case MTRRIOC32_GET_PAGE_ENTRY: {
-               struct mtrr_gentry32 __user *g32;
+               struct mtrr_gentry32 *g32 = arg;
 
-               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);
+               g32->base = gentry.base;
+               g32->size = gentry.size;
+               g32->regnum = gentry.regnum;
+               g32->type = gentry.type;
                break;
        }
 #endif
@@ -393,14 +382,38 @@ static int mtrr_open(struct inode *inode, struct file 
*file)
        return 0;
 }
 
+static const struct proc_ioctl_arg mtrr_ioctl_args[] = {
+       PROC_IOCTL_IOC(MTRRIOC_ADD_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_SET_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_DEL_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_GET_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_KILL_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_ADD_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_SET_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_DEL_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_GET_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC_KILL_PAGE_ENTRY),
+#ifdef CONFIG_COMPAT
+       PROC_IOCTL_IOC(MTRRIOC32_ADD_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_SET_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_DEL_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_GET_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_KILL_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_ADD_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_SET_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_DEL_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_GET_PAGE_ENTRY),
+       PROC_IOCTL_IOC(MTRRIOC32_KILL_PAGE_ENTRY),
+#endif
+};
+
 static const struct proc_ops mtrr_proc_ops = {
        .proc_show              = mtrr_seq_show,
        .proc_open              = mtrr_open,
        .proc_write_buf         = mtrr_write,
-       .proc_ioctl             = mtrr_ioctl,
-#ifdef CONFIG_COMPAT
-       .proc_compat_ioctl      = mtrr_ioctl,
-#endif
+       .proc_ioctl_buf         = mtrr_ioctl,
+       .proc_ioctl_args        = mtrr_ioctl_args,
+       .proc_nr_ioctl_args     = ARRAY_SIZE(mtrr_ioctl_args),
        .proc_release           = mtrr_close,
 };
 

-- 
2.53.0


Reply via email to