From: David Vrabel <david.vrabel@citrix.com>
To: Andres Lagar-Cavilla <andreslc@gridcentric.ca>
Cc: xen-devel@lists.xensource.com,
David Vrabel <david.vrabel@citrix.com>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: Re: [PATCH 2/2] xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl
Date: Fri, 31 Aug 2012 14:08:50 +0100 [thread overview]
Message-ID: <5040B762.3060402@citrix.com> (raw)
In-Reply-To: <DDCE284F-9506-4EF4-88BB-CF6A04D98A2F@gridcentric.ca>
On 30/08/12 19:32, Andres Lagar-Cavilla wrote:
> Second repost of my version, heavily based on David's.
Doing another allocation that may be larger than a page (and its
associated additional error paths) seems to me to be a hammer to crack
the (admittedly bit wonky) casting nut.
That said, it's up to Konrad which version he prefers.
There are also some minor improvements you could make if you respin this
patch.
> Complementary to this patch, on the xen tree I intend to add
> PRIVCMD_MMAPBATCH_*_ERROR into the libxc header files, and remove
> XEN_DOMCTL_PFINFO_PAGEDTAB from domctl.h
Yes, a good idea. There's no correspondence between the ioctl's error
reporting values and the DOMCTL_PFINFO flags.
> commit 3f40e8d79b7e032527ee207a97499ddbc81ca12b
> Author: Andres Lagar-Cavilla <andres@lagarcavilla.org>
> Date: Thu Aug 30 12:23:33 2012 -0400
>
> xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl
>
> 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.
>
> Also expand PRIVCMD_MMAPBATCH to return appropriate error-encoding top nibble
> in the mfn array.
>
> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
> Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
[...]
> -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);
> + int *err_array;
int *err_array = NULL;
and you could avoid the additional jump label as kfree(NULL) is safe.
> struct mmap_batch_state state;
>
> if (!xen_initial_domain())
> return -EPERM;
>
> - if (copy_from_user(&m, udata, sizeof(m)))
> - return -EFAULT;
> + switch (version) {
> + case 1:
> + if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch)))
> + return -EFAULT;
> + /* Returns per-frame error in m.arr. */
> + m.err = NULL;
> + if (!access_ok(VERIFY_WRITE, m.arr, m.num * sizeof(*m.arr)))
> + return -EFAULT;
> + break;
> + case 2:
> + if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch_v2)))
> + return -EFAULT;
> + /* Returns per-frame error code in m.err. */
> + if (!access_ok(VERIFY_WRITE, m.err, m.num * (sizeof(*m.err))))
> + return -EFAULT;
> + break;
> + default:
> + return -EINVAL;
> + }
>
> 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);
> + ret = gather_array(&pagelist, m.num, sizeof(xen_pfn_t), m.arr);
>
> if (ret || list_empty(&pagelist))
> - goto out;
> + goto out_no_err_array;
> +
> + err_array = kmalloc_array(m.num, sizeof(int), GFP_KERNEL);
kcalloc() (see below).
> + if (err_array == NULL)
> + {
Style: if (err_array == NULL) {
> + if (state.global_error) {
> + int efault;
> +
> + if (state.global_error == -ENOENT)
> + ret = -ENOENT;
> +
> + /* Write back errors in second pass. */
> + state.user_mfn = (xen_pfn_t *)m.arr;
> + state.user_err = m.err;
> + state.err = err_array;
> + efault = traverse_pages(m.num, sizeof(xen_pfn_t),
> + &pagelist, mmap_return_errors, &state);
> + if (efault)
> + ret = efault;
> + } else if (m.err)
> + ret = __clear_user(m.err, m.num * sizeof(*m.err));
Since you have an array of errors already there's no need to iterate
through all the MFNs again for V2. A simple copy_to_user() is
sufficient provided err_array was zeroed with kcalloc().
if (m.err)
ret = __copy_to_user(m.err, err_array, m.num * sizeof(*m.err));
else {
/* Write back errors in second pass. */
state.user_mfn = (xen_pfn_t *)m.arr;
state.user_err = m.err;
state.err = err_array;
ret = traverse_pages(m.num, sizeof(xen_pfn_t),
&pagelist, mmap_return_errors, &state);
}
if (ret == 0 && state.global_error == -ENOENT)
ret = -ENOENT;
David
next prev parent reply other threads:[~2012-08-31 13:08 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-30 12:58 [PATCHv3 0/2] xen/privcmd: support for paged-out frames David Vrabel
2012-08-30 12:58 ` [PATCH 1/2] xen/mm: return more precise error from xen_remap_domain_range() David Vrabel
2012-08-30 15:07 ` Andres Lagar-Cavilla
2012-08-30 12:58 ` [PATCH 2/2] xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl David Vrabel
2012-08-30 16:41 ` Andres Lagar-Cavilla
2012-08-30 17:04 ` David Vrabel
2012-08-30 18:29 ` Andres Lagar-Cavilla
2012-08-31 7:02 ` Ian Campbell
2012-08-30 18:32 ` Andres Lagar-Cavilla
2012-08-31 13:08 ` David Vrabel [this message]
2012-08-31 13:13 ` Andres Lagar-Cavilla
2012-09-05 16:17 ` Konrad Rzeszutek Wilk
2012-08-31 13:59 ` Andres Lagar-Cavilla
2012-09-05 16:21 ` Konrad Rzeszutek Wilk
2012-09-05 17:09 ` Andres Lagar-Cavilla
2012-09-05 17:40 ` Konrad Rzeszutek Wilk
2012-09-06 13:41 ` Andres Lagar-Cavilla
2012-09-06 16:20 ` Konrad Rzeszutek Wilk
2012-08-30 20:05 ` [PATCHv3 0/2] xen/privcmd: support for paged-out frames Konrad Rzeszutek Wilk
2012-08-30 20:12 ` Andres Lagar-Cavilla
2012-09-05 18:57 ` Konrad Rzeszutek Wilk
2012-09-05 19:51 ` Andres Lagar-Cavilla
2012-09-05 20:05 ` Konrad Rzeszutek Wilk
-- strict thread matches above, loose matches on Subject: below --
2012-08-29 13:15 [PATCHv2 " David Vrabel
2012-08-29 13:15 ` [PATCH 2/2] xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl David Vrabel
2012-08-29 16:14 ` Andres Lagar-Cavilla
2012-08-29 16:36 ` David Vrabel
2012-08-29 18:10 ` 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=5040B762.3060402@citrix.com \
--to=david.vrabel@citrix.com \
--cc=andreslc@gridcentric.ca \
--cc=konrad.wilk@oracle.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).