From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: David Vrabel <david.vrabel@citrix.com>
Cc: Andres Lagar-Cavilla <andres@gridcentric.ca>,
xen-devel@lists.xensource.com, Keir Fraser <keir@xen.org>
Subject: Re: [PATCH 3/3] xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl
Date: Thu, 23 Aug 2012 15:40:00 -0400 [thread overview]
Message-ID: <20120823194000.GA11652@phenom.dumpdata.com> (raw)
In-Reply-To: <1345742026-10569-4-git-send-email-david.vrabel@citrix.com>
On Thu, Aug 23, 2012 at 06:13:46PM +0100, David Vrabel wrote:
> From: David Vrabel <david.vrabel@citrix.com>
>
> PRIVCMD_MMAPBATCH_V2 extends PRIVCMD_MMAPBATCH with an additional
> field for reporting the error code for every frame that could not be
> mapped. libxc prefers PRIVCMD_MMAPBATCH_V2 over PRIVCMD_MMAPBATCH.
>
> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
> ---
> drivers/xen/privcmd.c | 54 +++++++++++++++++++++++++++++++++++++++----------
> include/xen/privcmd.h | 10 +++++++++
> 2 files changed, 53 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
> index f8c1b6d..4f97160 100644
> --- a/drivers/xen/privcmd.c
> +++ b/drivers/xen/privcmd.c
> @@ -248,7 +248,8 @@ struct mmap_batch_state {
> struct vm_area_struct *vma;
> int err;
>
> - xen_pfn_t __user *user;
> + xen_pfn_t __user *user_mfn;
> + int __user *user_err;
> };
>
> static int mmap_batch_fn(void *data, void *state)
> @@ -275,34 +276,58 @@ static int mmap_return_errors(void *data, void *state)
> {
> xen_pfn_t *mfnp = data;
> struct mmap_batch_state *st = state;
> + int ret = 0;
>
> - return put_user(*mfnp, st->user++);
> + if (st->user_err) {
> + if ((*mfnp & 0xf0000000U) == 0xf0000000U)
> + ret = -ENOENT;
> + else if ((*mfnp & 0xf0000000U) == 0x80000000U)
> + ret = -EINVAL;
Yikes. Any way those 0xf000.. and 0x8000 can at least be #defined
> + else
> + ret = 0;
> + return __put_user(ret, st->user_err);
> + } else
> + return __put_user(*mfnp, st->user_mfn++);
> }
>
> static struct vm_operations_struct privcmd_vm_ops;
>
> -static long privcmd_ioctl_mmap_batch(void __user *udata)
> +static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
> {
> int ret;
> - struct privcmd_mmapbatch m;
> + struct privcmd_mmapbatch_v2 m;
> struct mm_struct *mm = current->mm;
> struct vm_area_struct *vma;
> unsigned long nr_pages;
> LIST_HEAD(pagelist);
> struct mmap_batch_state state;
>
> + printk("%s(%d)\n", __func__, version);
> +
Hehe.
> if (!xen_initial_domain())
> return -EPERM;
>
> - if (copy_from_user(&m, udata, sizeof(m)))
> - return -EFAULT;
> + if (version == 1) {
> + if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch)))
> + return -EFAULT;
> + if (!access_ok(VERIFY_WRITE, m.arr, m.num * sizeof(*m.arr)))
> + return -EFAULT;
That is new..
> + m.err = NULL;
> + } else {
Not elseif (version == 2) ?
.. what if version 3 comes around?
> + if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch_v2)))
> + return -EFAULT;
> + if (!access_ok(VERIFY_READ, m.arr, m.num * sizeof(*m.arr)))
> + return -EFAULT;
> + if (!access_ok(VERIFY_WRITE, m.err, m.num * (sizeof(*m.err))))
> + return -EFAULT;
I think the VERIFY_WRITE can cover both versions?
> + }
>
> nr_pages = m.num;
> if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
> return -EINVAL;
>
> ret = gather_array(&pagelist, m.num, sizeof(xen_pfn_t),
> - m.arr);
> + (xen_pfn_t *)m.arr);
>
> if (ret || list_empty(&pagelist))
> goto out;
> @@ -331,10 +356,11 @@ static long privcmd_ioctl_mmap_batch(void __user *udata)
> up_write(&mm->mmap_sem);
>
> if (state.err > 0) {
> - state.user = m.arr;
> + state.user_mfn = (xen_pfn_t *)m.arr;
> + state.user_err = m.err;
> ret = traverse_pages(m.num, sizeof(xen_pfn_t),
> - &pagelist,
> - mmap_return_errors, &state);
> + &pagelist,
> + mmap_return_errors, &state);
> }
>
> out:
> @@ -359,7 +385,13 @@ static long privcmd_ioctl(struct file *file,
> break;
>
> case IOCTL_PRIVCMD_MMAPBATCH:
> - ret = privcmd_ioctl_mmap_batch(udata);
> + ret = privcmd_ioctl_mmap_batch(udata, 1);
> + printk("%s() batch ret = %d\n", __func__, ret);
Pfff...
> + break;
> +
> + case IOCTL_PRIVCMD_MMAPBATCH_V2:
> + ret = privcmd_ioctl_mmap_batch(udata, 2);
> + printk("%s() batch ret = %d\n", __func__, ret);
> break;
>
> default:
> diff --git a/include/xen/privcmd.h b/include/xen/privcmd.h
> index 17857fb..9fa27c4 100644
> --- a/include/xen/privcmd.h
> +++ b/include/xen/privcmd.h
> @@ -62,6 +62,14 @@ struct privcmd_mmapbatch {
> xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */
> };
>
> +struct privcmd_mmapbatch_v2 {
> + unsigned int num; /* number of pages to populate */
unsigend int? Not 'u32'?
> + domid_t dom; /* target domain */
> + __u64 addr; /* virtual address */
> + const xen_pfn_t __user *arr; /* array of mfns */
> + int __user *err; /* array of error codes */
int? Not a specific type?
> +};
> +
> /*
> * @cmd: IOCTL_PRIVCMD_HYPERCALL
> * @arg: &privcmd_hypercall_t
> @@ -73,5 +81,7 @@ struct privcmd_mmapbatch {
> _IOC(_IOC_NONE, 'P', 2, sizeof(struct privcmd_mmap))
> #define IOCTL_PRIVCMD_MMAPBATCH \
> _IOC(_IOC_NONE, 'P', 3, sizeof(struct privcmd_mmapbatch))
> +#define IOCTL_PRIVCMD_MMAPBATCH_V2 \
> + _IOC(_IOC_NONE, 'P', 4, sizeof(struct privcmd_mmapbatch_v2))
>
> #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
> --
> 1.7.2.5
next prev parent reply other threads:[~2012-08-23 19:40 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-23 17:13 [RFC PATCH 0/3] xen/privcmd: support for paged-out frames David Vrabel
2012-08-23 17:13 ` [PATCH 1/3] xen/mm: return more precise error from xen_remap_domain_range() David Vrabel
2012-08-23 17:13 ` [PATCH 2/3] xen/privcmd: report paged-out frames in PRIVCMD_MMAPBATCH ioctl David Vrabel
2012-08-24 1:34 ` Andres Lagar-Cavilla
2012-08-24 18:01 ` Bastian Blank
2012-08-23 17:13 ` [PATCH 3/3] xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl David Vrabel
2012-08-23 19:40 ` Konrad Rzeszutek Wilk [this message]
2012-08-24 11:14 ` David Vrabel
2012-08-24 11:41 ` Konrad Rzeszutek Wilk
2012-08-24 11:50 ` Ian Campbell
2012-08-24 12:00 ` David Vrabel
2012-08-24 12:14 ` Ian Campbell
2012-08-24 1:35 ` Andres Lagar-Cavilla
2012-08-24 1:32 ` [RFC PATCH 0/3] xen/privcmd: support for paged-out frames Andres Lagar-Cavilla
2012-08-24 11:58 ` David Vrabel
2012-08-24 12:14 ` Ian Campbell
2012-08-24 15:06 ` Andres Lagar-Cavilla
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=20120823194000.GA11652@phenom.dumpdata.com \
--to=konrad.wilk@oracle.com \
--cc=andres@gridcentric.ca \
--cc=david.vrabel@citrix.com \
--cc=keir@xen.org \
--cc=xen-devel@lists.xensource.com \
/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.