xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
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

  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).