[PATCH] NVMe: compat SG_IO ioctl
Verma, Vishal L
vishal.l.verma at intel.com
Tue Oct 8 14:29:11 EDT 2013
On 9/27/13 3:09 PM, "Keith Busch" <keith.busch at intel.com> wrote:
>I hear some people have (and use!) 32-bit versions of sg3-utils on
>64-bit OSes. This is pretty much a straight copy from fs/compat_ioctl.c.
>
>Signed-off-by: Keith Busch <keith.busch at intel.com>
>---
> drivers/block/nvme-core.c | 14 +++++-
> drivers/block/nvme-scsi.c | 111
>+++++++++++++++++++++++++++++++++++++++++++++
> include/linux/nvme.h | 1 +
> 3 files changed, 125 insertions(+), 1 deletion(-)
<snip>
>
>+
>+int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg)
>+{
>+ sg_io_hdr32_t __user *sgio32 = (sg_io_hdr32_t __user *)arg;
>+ sg_io_hdr_t __user *sgio;
>+ u16 iovec_count;
>+ u32 data;
>+ void __user *dxferp;
>+ unsigned char __user *cmdp;
>+ unsigned char __user *sbp;
>+ unsigned char __user *new;
>+ unsigned char __user *top;
>+
>+ if (get_user(iovec_count, &sgio32->iovec_count))
>+ return -EFAULT;
>+
>+ top = compat_alloc_user_space(0);
>+ new = compat_alloc_user_space(sizeof(sg_io_hdr_t) +
>+ (iovec_count * sizeof(sg_iovec_t)));
>+ if (new > top)
>+ return -EINVAL;
>+
>+ sgio = (sg_io_hdr_t __user *)new;
>+ if (copy_in_user(&sgio->interface_id, &sgio32->interface_id,
>+ (2 * sizeof(int)) +
>+ (2 * sizeof(unsigned char)) +
>+ (1 * sizeof(unsigned short)) +
>+ (1 * sizeof(unsigned int))))
>+ return -EFAULT;
>+ if (get_user(data, &sgio32->dxferp))
>+ return -EFAULT;
>+
>+ dxferp = compat_ptr(data);
>+ if (iovec_count && sg_build_iovec(sgio, dxferp, iovec_count))
>+ return -EFAULT;
>+ else if (put_user(dxferp, &sgio->dxferp))
>+ return -EFAULT;
>+
>+ if (get_user(data, &sgio32->cmdp))
>+ return -EFAULT;
>+
>+ cmdp = compat_ptr(data);
>+ if (get_user(data, &sgio32->sbp))
>+ return -EFAULT;
>+
>+ sbp = compat_ptr(data);
>+ if (put_user(cmdp, &sgio->cmdp) || put_user(sbp, &sgio->sbp))
>+ return -EFAULT;
>+ if (copy_in_user(&sgio->timeout, &sgio32->timeout, 3 * sizeof(int)))
>+ return -EFAULT;
>+ if (get_user(data, &sgio32->usr_ptr))
>+ return -EFAULT;
>+ if (put_user(compat_ptr(data), &sgio->usr_ptr))
>+ return -EFAULT;
>+
>+ return nvme_sg_io(ns, sgio);
This should copy status and sbp/sb_len_wr from sgio back into sgio32
before returning.
>+}
>+
> int nvme_sg_get_version_num(int __user *ip)
> {
> return put_user(sg_version_num, ip);
>diff --git a/include/linux/nvme.h b/include/linux/nvme.h
>index 26ebcf4..6867de6 100644
>--- a/include/linux/nvme.h
>+++ b/include/linux/nvme.h
>@@ -165,6 +165,7 @@ int nvme_set_features(struct nvme_dev *dev, unsigned
>fid, unsigned dword11,
> struct sg_io_hdr;
>
> int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr);
>+int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg);
> int nvme_sg_get_version_num(int __user *ip);
>
> #endif /* _LINUX_NVME_H */
>--
>1.7.10.4
>
Thanks,
-Vishal
>
>_______________________________________________
>Linux-nvme mailing list
>Linux-nvme at lists.infradead.org
>http://merlin.infradead.org/mailman/listinfo/linux-nvme
>
More information about the Linux-nvme
mailing list