|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/2] xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl
On Aug 29, 2012, at 12:36 PM, David Vrabel wrote:
> On 29/08/12 17:14, Andres Lagar-Cavilla wrote:
>>
>> On Aug 29, 2012, at 9:15 AM, David Vrabel wrote:
>>
>>> From: David Vrabel <david.vrabel@xxxxxxxxxx>
>>>
>>> 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.
> [...]
>>> diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
>>> index ccee0f1..ddd32cf 100644
>>> --- a/drivers/xen/privcmd.c
>>> +++ b/drivers/xen/privcmd.c
>>> @@ -248,18 +248,23 @@ 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)
>>> {
>>> xen_pfn_t *mfnp = data;
>>> + int *err = data;
>> Am I missing something or is there an aliasing here? Both mfnp and err point
>> to data?
>
> There is deliberate aliasing here. We use the mfn array to save the
> error codes for later processing.
May I suggest a comment to clarify this here? Are xen_pfn_t and int the same
size in both bitnesses? The very fact that I raise the question is an argument
against this black-magic aliasing. Imho.
A explicit union for each slot in the *data, or passing both arrays to the
callback looks better to me.
>
>>> struct mmap_batch_state *st = state;
>>> + int ret;
>>>
>>> - if (xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
>>> - st->vma->vm_page_prot, st->domain) < 0) {
>>> - *mfnp |= 0xf0000000U;
>>> - st->err++;
>>> + ret = xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
>>> + st->vma->vm_page_prot, st->domain);
>>> + if (ret < 0) {
>>> + *err = ret;
>>> + if (st->err == 0 || st->err == -ENOENT)
>>> + st->err = ret;
>> This will unset -ENOENT if a frame after an ENOENT error fails differently.
>
> I thought that was what the original implementation did but it seems it
> does not
I think the best way to do this is:
if ((ret == -ENOENT) && (st->err == 0))
st->err = -ENOENT;
Then st->err is -ENOENT if at least there was one individual -ENOENT or zero
otherwise. Which is the expectation of libxc (barring an EFAULT or some other
higher-level whole-operation error).
Andres
> .
>
>>> @@ -325,12 +359,16 @@ static long privcmd_ioctl_mmap_batch(void __user
>>> *udata)
>>>
>>> up_write(&mm->mmap_sem);
>>>
>>> - if (state.err > 0) {
>>> - state.user = m.arr;
>>> + if (state.err) {
>>> + 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);
>
>> The callback now maps data to err (instead of mfnp … but I see no
>> change to the gather_array other than a cast …am I missing something?
>
> The kernel mfn and the err array are aliased.
>
> I could have made gather_array() allow the kernel array to have larger
> elements than the user array but that looked like too much work.
>
> David
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |