diff mbox series

[Xen-devel,for-next,07/16] xen/arm: Introduce copy_to_guest_phys_flush_dcache

Message ID 20171123183210.12045-8-julien.grall@linaro.org
State Superseded
Headers show
Series xen/arm: Stage-2 handling cleanup | expand

Commit Message

Julien Grall Nov. 23, 2017, 6:32 p.m. UTC
This new function will be used in a follow-up patch to copy data to the guest
using the IPA (aka guest physical address) and then clean the cache.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
---
 xen/arch/arm/guestcopy.c           | 10 ++++++++++
 xen/include/asm-arm/guest_access.h |  6 ++++++
 2 files changed, 16 insertions(+)

Comments

Andrew Cooper Nov. 23, 2017, 6:49 p.m. UTC | #1
On 23/11/17 18:32, Julien Grall wrote:
> This new function will be used in a follow-up patch to copy data to the guest
> using the IPA (aka guest physical address) and then clean the cache.
>
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> ---
>  xen/arch/arm/guestcopy.c           | 10 ++++++++++
>  xen/include/asm-arm/guest_access.h |  6 ++++++
>  2 files changed, 16 insertions(+)
>
> diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c
> index be53bee559..7958663970 100644
> --- a/xen/arch/arm/guestcopy.c
> +++ b/xen/arch/arm/guestcopy.c
> @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to, const void __user *from, unsigned le
>                        COPY_from_guest | COPY_linear);
>  }
>  
> +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
> +                                              paddr_t gpa,
> +                                              void *buf,
> +                                              unsigned int len)
> +{
> +    /* P2M is shared between all vCPUs, so the vCPU used does not matter. */

Be very careful with this line of thinking.  It is only works after
DOMCTL_max_vcpus has succeeded, and before that point, it is a latent
NULL pointer dereference.

Also, what about vcpus configured with alternative views?

~Andrew

> +    return copy_guest(buf, gpa, len, d->vcpu[0],
> +                      COPY_to_guest | COPY_ipa | COPY_flush_dcache);
> +}
> +
>  int access_guest_memory_by_ipa(struct domain *d, paddr_t gpa, void *buf,
>                                 uint32_t size, bool is_write)
>  {
> diff --git a/xen/include/asm-arm/guest_access.h b/xen/include/asm-arm/guest_access.h
> index 6796801cfe..224d2a033b 100644
> --- a/xen/include/asm-arm/guest_access.h
> +++ b/xen/include/asm-arm/guest_access.h
> @@ -11,6 +11,12 @@ unsigned long raw_copy_to_guest_flush_dcache(void *to, const void *from,
>  unsigned long raw_copy_from_guest(void *to, const void *from, unsigned len);
>  unsigned long raw_clear_guest(void *to, unsigned len);
>  
> +/* Copy data to guest physical address, then clean the region. */
> +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
> +                                              paddr_t phys,
> +                                              void *buf,
> +                                              unsigned int len);
> +
>  int access_guest_memory_by_ipa(struct domain *d, paddr_t ipa, void *buf,
>                                 uint32_t size, bool is_write);
>
Julien Grall Nov. 23, 2017, 7:02 p.m. UTC | #2
Hi Andrew,

On 23/11/17 18:49, Andrew Cooper wrote:
> On 23/11/17 18:32, Julien Grall wrote:
>> This new function will be used in a follow-up patch to copy data to the guest
>> using the IPA (aka guest physical address) and then clean the cache.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> ---
>>   xen/arch/arm/guestcopy.c           | 10 ++++++++++
>>   xen/include/asm-arm/guest_access.h |  6 ++++++
>>   2 files changed, 16 insertions(+)
>>
>> diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c
>> index be53bee559..7958663970 100644
>> --- a/xen/arch/arm/guestcopy.c
>> +++ b/xen/arch/arm/guestcopy.c
>> @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to, const void __user *from, unsigned le
>>                         COPY_from_guest | COPY_linear);
>>   }
>>   
>> +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
>> +                                              paddr_t gpa,
>> +                                              void *buf,
>> +                                              unsigned int len)
>> +{
>> +    /* P2M is shared between all vCPUs, so the vCPU used does not matter. */
> 
> Be very careful with this line of thinking.  It is only works after
> DOMCTL_max_vcpus has succeeded, and before that point, it is a latent
> NULL pointer dereference.

I really don't expect that function been used before DOMCT_max_vcpus is 
set. It is only used for hardware emulation or Xen loading image into 
the hardware domain memory. I could add a check d->vcpus to be safe.

> 
> Also, what about vcpus configured with alternative views?

It is not important because the underlying call is get_page_from_gfn 
that does not care about the alternative view (that function take a 
domain in parameter). I can update the comment.

Cheers,
Stefano Stabellini Dec. 6, 2017, 1:26 a.m. UTC | #3
On Thu, 23 Nov 2017, Julien Grall wrote:
> Hi Andrew,

> 

> On 23/11/17 18:49, Andrew Cooper wrote:

> > On 23/11/17 18:32, Julien Grall wrote:

> > > This new function will be used in a follow-up patch to copy data to the

> > > guest

> > > using the IPA (aka guest physical address) and then clean the cache.

> > > 

> > > Signed-off-by: Julien Grall <julien.grall@linaro.org>

> > > ---

> > >   xen/arch/arm/guestcopy.c           | 10 ++++++++++

> > >   xen/include/asm-arm/guest_access.h |  6 ++++++

> > >   2 files changed, 16 insertions(+)

> > > 

> > > diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c

> > > index be53bee559..7958663970 100644

> > > --- a/xen/arch/arm/guestcopy.c

> > > +++ b/xen/arch/arm/guestcopy.c

> > > @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to, const

> > > void __user *from, unsigned le

> > >                         COPY_from_guest | COPY_linear);

> > >   }

> > >   +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,

> > > +                                              paddr_t gpa,

> > > +                                              void *buf,

> > > +                                              unsigned int len)

> > > +{

> > > +    /* P2M is shared between all vCPUs, so the vCPU used does not matter.

> > > */

> > 

> > Be very careful with this line of thinking.  It is only works after

> > DOMCTL_max_vcpus has succeeded, and before that point, it is a latent

> > NULL pointer dereference.

> 

> I really don't expect that function been used before DOMCT_max_vcpus is set.

> It is only used for hardware emulation or Xen loading image into the hardware

> domain memory. I could add a check d->vcpus to be safe.

> 

> > 

> > Also, what about vcpus configured with alternative views?

> 

> It is not important because the underlying call is get_page_from_gfn that does

> not care about the alternative view (that function take a domain in

> parameter). I can update the comment.

 
Since this is a new function, would it make sense to take a struct
vcpu* as parameter, instead of a struct domain* ?
Julien Grall Dec. 6, 2017, 12:27 p.m. UTC | #4
Hi Stefano,

On 12/06/2017 01:26 AM, Stefano Stabellini wrote:
> On Thu, 23 Nov 2017, Julien Grall wrote:
>> Hi Andrew,
>>
>> On 23/11/17 18:49, Andrew Cooper wrote:
>>> On 23/11/17 18:32, Julien Grall wrote:
>>>> This new function will be used in a follow-up patch to copy data to the
>>>> guest
>>>> using the IPA (aka guest physical address) and then clean the cache.
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>> ---
>>>>    xen/arch/arm/guestcopy.c           | 10 ++++++++++
>>>>    xen/include/asm-arm/guest_access.h |  6 ++++++
>>>>    2 files changed, 16 insertions(+)
>>>>
>>>> diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c
>>>> index be53bee559..7958663970 100644
>>>> --- a/xen/arch/arm/guestcopy.c
>>>> +++ b/xen/arch/arm/guestcopy.c
>>>> @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to, const
>>>> void __user *from, unsigned le
>>>>                          COPY_from_guest | COPY_linear);
>>>>    }
>>>>    +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
>>>> +                                              paddr_t gpa,
>>>> +                                              void *buf,
>>>> +                                              unsigned int len)
>>>> +{
>>>> +    /* P2M is shared between all vCPUs, so the vCPU used does not matter.
>>>> */
>>>
>>> Be very careful with this line of thinking.  It is only works after
>>> DOMCTL_max_vcpus has succeeded, and before that point, it is a latent
>>> NULL pointer dereference.
>>
>> I really don't expect that function been used before DOMCT_max_vcpus is set.
>> It is only used for hardware emulation or Xen loading image into the hardware
>> domain memory. I could add a check d->vcpus to be safe.
>>
>>>
>>> Also, what about vcpus configured with alternative views?
>>
>> It is not important because the underlying call is get_page_from_gfn that does
>> not care about the alternative view (that function take a domain in
>> parameter). I can update the comment.
>   
> Since this is a new function, would it make sense to take a struct
> vcpu* as parameter, instead of a struct domain* ?

Well, I suggested this patch this way because likely everyone will use 
with d->vcpus[0]. And then you would have to wonder why d->vcpus[0] and 
not d->vcpus[1]...

Cheers,
Julien Grall Dec. 8, 2017, 3:34 p.m. UTC | #5
Hi,

On 06/12/17 12:27, Julien Grall wrote:
> On 12/06/2017 01:26 AM, Stefano Stabellini wrote:
>> On Thu, 23 Nov 2017, Julien Grall wrote:
>>> Hi Andrew,
>>>
>>> On 23/11/17 18:49, Andrew Cooper wrote:
>>>> On 23/11/17 18:32, Julien Grall wrote:
>>>>> This new function will be used in a follow-up patch to copy data to 
>>>>> the
>>>>> guest
>>>>> using the IPA (aka guest physical address) and then clean the cache.
>>>>>
>>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>>> ---
>>>>>    xen/arch/arm/guestcopy.c           | 10 ++++++++++
>>>>>    xen/include/asm-arm/guest_access.h |  6 ++++++
>>>>>    2 files changed, 16 insertions(+)
>>>>>
>>>>> diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c
>>>>> index be53bee559..7958663970 100644
>>>>> --- a/xen/arch/arm/guestcopy.c
>>>>> +++ b/xen/arch/arm/guestcopy.c
>>>>> @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to, const
>>>>> void __user *from, unsigned le
>>>>>                          COPY_from_guest | COPY_linear);
>>>>>    }
>>>>>    +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
>>>>> +                                              paddr_t gpa,
>>>>> +                                              void *buf,
>>>>> +                                              unsigned int len)
>>>>> +{
>>>>> +    /* P2M is shared between all vCPUs, so the vCPU used does not 
>>>>> matter.
>>>>> */
>>>>
>>>> Be very careful with this line of thinking.  It is only works after
>>>> DOMCTL_max_vcpus has succeeded, and before that point, it is a latent
>>>> NULL pointer dereference.
>>>
>>> I really don't expect that function been used before DOMCT_max_vcpus 
>>> is set.
>>> It is only used for hardware emulation or Xen loading image into the 
>>> hardware
>>> domain memory. I could add a check d->vcpus to be safe.
>>>
>>>>
>>>> Also, what about vcpus configured with alternative views?
>>>
>>> It is not important because the underlying call is get_page_from_gfn 
>>> that does
>>> not care about the alternative view (that function take a domain in
>>> parameter). I can update the comment.
>> Since this is a new function, would it make sense to take a struct
>> vcpu* as parameter, instead of a struct domain* ?
> 
> Well, I suggested this patch this way because likely everyone will use 
> with d->vcpus[0]. And then you would have to wonder why d->vcpus[0] and 
> not d->vcpus[1]...

Thinking a bit more to this, it might be better/safer to pass either a 
domain or a vCPU to copy_guest. I can see 2 solutions:
	1# Introduce a union that use the same parameter:
		union
		{
			struct
			{
				struct domain *d;
			} ipa;
			struct
			{
				struct vcpu *v;
			} gva;
		}
	  The structure here would be to ensure that it is clear that only 
domain (resp. vcpu) should be used with ipa (resp. gva).

	2# Have 2 parameters, vcpu and domain.

Any opinions?

Cheers,
Stefano Stabellini Dec. 8, 2017, 10:26 p.m. UTC | #6
On Fri, 8 Dec 2017, Julien Grall wrote:
> On 06/12/17 12:27, Julien Grall wrote:

> > On 12/06/2017 01:26 AM, Stefano Stabellini wrote:

> > > On Thu, 23 Nov 2017, Julien Grall wrote:

> > > > Hi Andrew,

> > > > 

> > > > On 23/11/17 18:49, Andrew Cooper wrote:

> > > > > On 23/11/17 18:32, Julien Grall wrote:

> > > > > > This new function will be used in a follow-up patch to copy data to

> > > > > > the

> > > > > > guest

> > > > > > using the IPA (aka guest physical address) and then clean the cache.

> > > > > > 

> > > > > > Signed-off-by: Julien Grall <julien.grall@linaro.org>

> > > > > > ---

> > > > > >    xen/arch/arm/guestcopy.c           | 10 ++++++++++

> > > > > >    xen/include/asm-arm/guest_access.h |  6 ++++++

> > > > > >    2 files changed, 16 insertions(+)

> > > > > > 

> > > > > > diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c

> > > > > > index be53bee559..7958663970 100644

> > > > > > --- a/xen/arch/arm/guestcopy.c

> > > > > > +++ b/xen/arch/arm/guestcopy.c

> > > > > > @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to,

> > > > > > const

> > > > > > void __user *from, unsigned le

> > > > > >                          COPY_from_guest | COPY_linear);

> > > > > >    }

> > > > > >    +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,

> > > > > > +                                              paddr_t gpa,

> > > > > > +                                              void *buf,

> > > > > > +                                              unsigned int len)

> > > > > > +{

> > > > > > +    /* P2M is shared between all vCPUs, so the vCPU used does not

> > > > > > matter.

> > > > > > */

> > > > > 

> > > > > Be very careful with this line of thinking.  It is only works after

> > > > > DOMCTL_max_vcpus has succeeded, and before that point, it is a latent

> > > > > NULL pointer dereference.

> > > > 

> > > > I really don't expect that function been used before DOMCT_max_vcpus is

> > > > set.

> > > > It is only used for hardware emulation or Xen loading image into the

> > > > hardware

> > > > domain memory. I could add a check d->vcpus to be safe.

> > > > 

> > > > > 

> > > > > Also, what about vcpus configured with alternative views?

> > > > 

> > > > It is not important because the underlying call is get_page_from_gfn

> > > > that does

> > > > not care about the alternative view (that function take a domain in

> > > > parameter). I can update the comment.

> > > Since this is a new function, would it make sense to take a struct

> > > vcpu* as parameter, instead of a struct domain* ?

> > 

> > Well, I suggested this patch this way because likely everyone will use with

> > d->vcpus[0]. And then you would have to wonder why d->vcpus[0] and not

> > d->vcpus[1]...

> 

> Thinking a bit more to this, it might be better/safer to pass either a domain

> or a vCPU to copy_guest. I can see 2 solutions:

> 	1# Introduce a union that use the same parameter:

> 		union

> 		{

> 			struct

> 			{

> 				struct domain *d;

> 			} ipa;

> 			struct

> 			{

> 				struct vcpu *v;

> 			} gva;

> 		}

> 	  The structure here would be to ensure that it is clear that only

> domain (resp. vcpu) should be used with ipa (resp. gva).

> 

> 	2# Have 2 parameters, vcpu and domain.

> 

> Any opinions?


I think that would be clearer. You could also add a paddr_t/vaddr_t
correspondingly inside the union maybe.
Julien Grall Dec. 8, 2017, 10:30 p.m. UTC | #7
On 8 Dec 2017 22:26, "Stefano Stabellini" <sstabellini@kernel.org> wrote:

On Fri, 8 Dec 2017, Julien Grall wrote:
> On 06/12/17 12:27, Julien Grall wrote:

> > On 12/06/2017 01:26 AM, Stefano Stabellini wrote:

> > > On Thu, 23 Nov 2017, Julien Grall wrote:

> > > > Hi Andrew,

> > > >

> > > > On 23/11/17 18:49, Andrew Cooper wrote:

> > > > > On 23/11/17 18:32, Julien Grall wrote:

> > > > > > This new function will be used in a follow-up patch to copy

data to
> > > > > > the

> > > > > > guest

> > > > > > using the IPA (aka guest physical address) and then clean the

cache.
> > > > > >

> > > > > > Signed-off-by: Julien Grall <julien.grall@linaro.org>

> > > > > > ---

> > > > > >    xen/arch/arm/guestcopy.c           | 10 ++++++++++

> > > > > >    xen/include/asm-arm/guest_access.h |  6 ++++++

> > > > > >    2 files changed, 16 insertions(+)

> > > > > >

> > > > > > diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c

> > > > > > index be53bee559..7958663970 100644

> > > > > > --- a/xen/arch/arm/guestcopy.c

> > > > > > +++ b/xen/arch/arm/guestcopy.c

> > > > > > @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to,

> > > > > > const

> > > > > > void __user *from, unsigned le

> > > > > >                          COPY_from_guest | COPY_linear);

> > > > > >    }

> > > > > >    +unsigned long copy_to_guest_phys_flush_dcache(struct domain

*d,
> > > > > > +                                              paddr_t gpa,

> > > > > > +                                              void *buf,

> > > > > > +                                              unsigned int len)

> > > > > > +{

> > > > > > +    /* P2M is shared between all vCPUs, so the vCPU used does

not
> > > > > > matter.

> > > > > > */

> > > > >

> > > > > Be very careful with this line of thinking.  It is only works

after
> > > > > DOMCTL_max_vcpus has succeeded, and before that point, it is a

latent
> > > > > NULL pointer dereference.

> > > >

> > > > I really don't expect that function been used before

DOMCT_max_vcpus is
> > > > set.

> > > > It is only used for hardware emulation or Xen loading image into the

> > > > hardware

> > > > domain memory. I could add a check d->vcpus to be safe.

> > > >

> > > > >

> > > > > Also, what about vcpus configured with alternative views?

> > > >

> > > > It is not important because the underlying call is get_page_from_gfn

> > > > that does

> > > > not care about the alternative view (that function take a domain in

> > > > parameter). I can update the comment.

> > > Since this is a new function, would it make sense to take a struct

> > > vcpu* as parameter, instead of a struct domain* ?

> >

> > Well, I suggested this patch this way because likely everyone will use

with
> > d->vcpus[0]. And then you would have to wonder why d->vcpus[0] and not

> > d->vcpus[1]...

>

> Thinking a bit more to this, it might be better/safer to pass either a

domain
> or a vCPU to copy_guest. I can see 2 solutions:

>       1# Introduce a union that use the same parameter:

>               union

>               {

>                       struct

>                       {

>                               struct domain *d;

>                       } ipa;

>                       struct

>                       {

>                               struct vcpu *v;

>                       } gva;

>               }

>         The structure here would be to ensure that it is clear that only

> domain (resp. vcpu) should be used with ipa (resp. gva).

>

>       2# Have 2 parameters, vcpu and domain.

>

> Any opinions?


I think that would be clearer. You could also add a paddr_t/vaddr_t
correspondingly inside the union maybe.


Well, you will have nameclash happening I think.


And vaddr_t and paddr_t are confusing because you don't know which address
you speak about (guest vs hypervisor). At least ipa/gpa, gva are known
naming.

Cheers,
<div dir="auto"><div><br><div class="gmail_extra"><br><div class="gmail_quote">On 8 Dec 2017 22:26, &quot;Stefano Stabellini&quot; &lt;<a href="mailto:sstabellini@kernel.org">sstabellini@kernel.org</a>&gt; wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="elided-text">On Fri, 8 Dec 2017, Julien Grall wrote:<br>
&gt; On 06/12/17 12:27, Julien Grall wrote:<br>
&gt; &gt; On 12/06/2017 01:26 AM, Stefano Stabellini wrote:<br>
&gt; &gt; &gt; On Thu, 23 Nov 2017, Julien Grall wrote:<br>
&gt; &gt; &gt; &gt; Hi Andrew,<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; On 23/11/17 18:49, Andrew Cooper wrote:<br>
&gt; &gt; &gt; &gt; &gt; On 23/11/17 18:32, Julien Grall wrote:<br>
&gt; &gt; &gt; &gt; &gt; &gt; This new function will be used in a follow-up patch to copy data to<br>
&gt; &gt; &gt; &gt; &gt; &gt; the<br>
&gt; &gt; &gt; &gt; &gt; &gt; guest<br>
&gt; &gt; &gt; &gt; &gt; &gt; using the IPA (aka guest physical address) and then clean the cache.<br>
&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; &gt; &gt; Signed-off-by: Julien Grall &lt;<a href="mailto:julien.grall@linaro.org">julien.grall@linaro.org</a>&gt;<br>
&gt; &gt; &gt; &gt; &gt; &gt; ---<br>
&gt; &gt; &gt; &gt; &gt; &gt;    xen/arch/arm/guestcopy.c      <wbr>     | 10 ++++++++++<br>
&gt; &gt; &gt; &gt; &gt; &gt;    xen/include/asm-arm/guest_<wbr>access.h |  6 ++++++<br>
&gt; &gt; &gt; &gt; &gt; &gt;    2 files changed, 16 insertions(+)<br>
&gt; &gt; &gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; &gt; &gt; diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c<br>
&gt; &gt; &gt; &gt; &gt; &gt; index be53bee559..7958663970 100644<br>
&gt; &gt; &gt; &gt; &gt; &gt; --- a/xen/arch/arm/guestcopy.c<br>
&gt; &gt; &gt; &gt; &gt; &gt; +++ b/xen/arch/arm/guestcopy.c<br>
&gt; &gt; &gt; &gt; &gt; &gt; @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to,<br>
&gt; &gt; &gt; &gt; &gt; &gt; const<br>
&gt; &gt; &gt; &gt; &gt; &gt; void __user *from, unsigned le<br>
&gt; &gt; &gt; &gt; &gt; &gt;                          COPY_from_guest | COPY_linear);<br>
&gt; &gt; &gt; &gt; &gt; &gt;    }<br>
&gt; &gt; &gt; &gt; &gt; &gt;    +unsigned long copy_to_guest_phys_flush_<wbr>dcache(struct domain *d,<br>
&gt; &gt; &gt; &gt; &gt; &gt; +                             <wbr>                 paddr_t gpa,<br>
&gt; &gt; &gt; &gt; &gt; &gt; +                             <wbr>                 void *buf,<br>
&gt; &gt; &gt; &gt; &gt; &gt; +                             <wbr>                 unsigned int len)<br>
&gt; &gt; &gt; &gt; &gt; &gt; +{<br>
&gt; &gt; &gt; &gt; &gt; &gt; +    /* P2M is shared between all vCPUs, so the vCPU used does not<br>
&gt; &gt; &gt; &gt; &gt; &gt; matter.<br>
&gt; &gt; &gt; &gt; &gt; &gt; */<br>
&gt; &gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; &gt; Be very careful with this line of thinking.  It is only works after<br>
&gt; &gt; &gt; &gt; &gt; DOMCTL_max_vcpus has succeeded, and before that point, it is a latent<br>
&gt; &gt; &gt; &gt; &gt; NULL pointer dereference.<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; I really don&#39;t expect that function been used before DOMCT_max_vcpus is<br>
&gt; &gt; &gt; &gt; set.<br>
&gt; &gt; &gt; &gt; It is only used for hardware emulation or Xen loading image into the<br>
&gt; &gt; &gt; &gt; hardware<br>
&gt; &gt; &gt; &gt; domain memory. I could add a check d-&gt;vcpus to be safe.<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; &gt; Also, what about vcpus configured with alternative views?<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; It is not important because the underlying call is get_page_from_gfn<br>
&gt; &gt; &gt; &gt; that does<br>
&gt; &gt; &gt; &gt; not care about the alternative view (that function take a domain in<br>
&gt; &gt; &gt; &gt; parameter). I can update the comment.<br>
&gt; &gt; &gt; Since this is a new function, would it make sense to take a struct<br>
&gt; &gt; &gt; vcpu* as parameter, instead of a struct domain* ?<br>
&gt; &gt;<br>
&gt; &gt; Well, I suggested this patch this way because likely everyone will use with<br>
&gt; &gt; d-&gt;vcpus[0]. And then you would have to wonder why d-&gt;vcpus[0] and not<br>
&gt; &gt; d-&gt;vcpus[1]...<br>
&gt;<br>
&gt; Thinking a bit more to this, it might be better/safer to pass either a domain<br>
&gt; or a vCPU to copy_guest. I can see 2 solutions:<br>
&gt;       1# Introduce a union that use the same parameter:<br>
&gt;               union<br>
&gt;               {<br>
&gt;                       struct<br>
&gt;                       {<br>
&gt;                               struct domain *d;<br>
&gt;                       } ipa;<br>
&gt;                       struct<br>
&gt;                       {<br>
&gt;                               struct vcpu *v;<br>
&gt;                       } gva;<br>
&gt;               }<br>
&gt;         The structure here would be to ensure that it is clear that only<br>
&gt; domain (resp. vcpu) should be used with ipa (resp. gva).<br>
&gt;<br>
&gt;       2# Have 2 parameters, vcpu and domain.<br>
&gt;<br>
&gt; Any opinions?<br>
<br>
</div>I think that would be clearer. You could also add a paddr_t/vaddr_t<br>
correspondingly inside the union maybe.</blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">Well, you will have nameclash happening I think.</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">And vaddr_t and paddr_t are confusing because you don&#39;t know which address you speak about (guest vs hypervisor). At least ipa/gpa, gva are known naming.<br></div><div dir="auto"><br></div><div dir="auto">Cheers,</div><div dir="auto"><div class="gmail_extra"><br></div></div></div>
Stefano Stabellini Dec. 8, 2017, 10:43 p.m. UTC | #8
On Fri, 8 Dec 2017, Julien Grall wrote:
> On 8 Dec 2017 22:26, "Stefano Stabellini" <sstabellini@kernel.org> wrote:

>       On Fri, 8 Dec 2017, Julien Grall wrote:

>       > On 06/12/17 12:27, Julien Grall wrote:

>       > > On 12/06/2017 01:26 AM, Stefano Stabellini wrote:

>       > > > On Thu, 23 Nov 2017, Julien Grall wrote:

>       > > > > Hi Andrew,

>       > > > >

>       > > > > On 23/11/17 18:49, Andrew Cooper wrote:

>       > > > > > On 23/11/17 18:32, Julien Grall wrote:

>       > > > > > > This new function will be used in a follow-up patch to copy data to

>       > > > > > > the

>       > > > > > > guest

>       > > > > > > using the IPA (aka guest physical address) and then clean the cache.

>       > > > > > >

>       > > > > > > Signed-off-by: Julien Grall <julien.grall@linaro.org>

>       > > > > > > ---

>       > > > > > >    xen/arch/arm/guestcopy.c           | 10 ++++++++++

>       > > > > > >    xen/include/asm-arm/guest_access.h |  6 ++++++

>       > > > > > >    2 files changed, 16 insertions(+)

>       > > > > > >

>       > > > > > > diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c

>       > > > > > > index be53bee559..7958663970 100644

>       > > > > > > --- a/xen/arch/arm/guestcopy.c

>       > > > > > > +++ b/xen/arch/arm/guestcopy.c

>       > > > > > > @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to,

>       > > > > > > const

>       > > > > > > void __user *from, unsigned le

>       > > > > > >                          COPY_from_guest | COPY_linear);

>       > > > > > >    }

>       > > > > > >    +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,

>       > > > > > > +                                              paddr_t gpa,

>       > > > > > > +                                              void *buf,

>       > > > > > > +                                              unsigned int len)

>       > > > > > > +{

>       > > > > > > +    /* P2M is shared between all vCPUs, so the vCPU used does not

>       > > > > > > matter.

>       > > > > > > */

>       > > > > >

>       > > > > > Be very careful with this line of thinking.  It is only works after

>       > > > > > DOMCTL_max_vcpus has succeeded, and before that point, it is a latent

>       > > > > > NULL pointer dereference.

>       > > > >

>       > > > > I really don't expect that function been used before DOMCT_max_vcpus is

>       > > > > set.

>       > > > > It is only used for hardware emulation or Xen loading image into the

>       > > > > hardware

>       > > > > domain memory. I could add a check d->vcpus to be safe.

>       > > > >

>       > > > > >

>       > > > > > Also, what about vcpus configured with alternative views?

>       > > > >

>       > > > > It is not important because the underlying call is get_page_from_gfn

>       > > > > that does

>       > > > > not care about the alternative view (that function take a domain in

>       > > > > parameter). I can update the comment.

>       > > > Since this is a new function, would it make sense to take a struct

>       > > > vcpu* as parameter, instead of a struct domain* ?

>       > >

>       > > Well, I suggested this patch this way because likely everyone will use with

>       > > d->vcpus[0]. And then you would have to wonder why d->vcpus[0] and not

>       > > d->vcpus[1]...

>       >

>       > Thinking a bit more to this, it might be better/safer to pass either a domain

>       > or a vCPU to copy_guest. I can see 2 solutions:

>       >       1# Introduce a union that use the same parameter:

>       >               union

>       >               {

>       >                       struct

>       >                       {

>       >                               struct domain *d;

>       >                       } ipa;

>       >                       struct

>       >                       {

>       >                               struct vcpu *v;

>       >                       } gva;

>       >               }

>       >         The structure here would be to ensure that it is clear that only

>       > domain (resp. vcpu) should be used with ipa (resp. gva).

>       >

>       >       2# Have 2 parameters, vcpu and domain.

>       >

>       > Any opinions?

> 

> I think that would be clearer. You could also add a paddr_t/vaddr_t

> correspondingly inside the union maybe.

> 

> 

> Well, you will have nameclash happening I think.

> 

> 

> And vaddr_t and paddr_t are confusing because you don't know which address you speak about (guest vs hypervisor). At least ipa/gpa, gva are known naming.


That's not what I meant. ipa and gva are good names.

I was suggesting to put an additional address field inside the union to
avoid the issue with paddr_t and vaddr_t discussed elsewhere
(alpine.DEB.2.10.1712081313070.8052@sstabellini-ThinkPad-X260).

I am happy either way, it was just a suggestion.
Julien Grall Dec. 12, 2017, 12:16 a.m. UTC | #9
Hi Stefano,

On 12/08/2017 10:43 PM, Stefano Stabellini wrote:
> On Fri, 8 Dec 2017, Julien Grall wrote:
>> On 8 Dec 2017 22:26, "Stefano Stabellini" <sstabellini@kernel.org> wrote:
>>        On Fri, 8 Dec 2017, Julien Grall wrote:
>>        > On 06/12/17 12:27, Julien Grall wrote:
>>        > > On 12/06/2017 01:26 AM, Stefano Stabellini wrote:
>>        > > > On Thu, 23 Nov 2017, Julien Grall wrote:
>>        > > > > Hi Andrew,
>>        > > > >
>>        > > > > On 23/11/17 18:49, Andrew Cooper wrote:
>>        > > > > > On 23/11/17 18:32, Julien Grall wrote:
>>        > > > > > > This new function will be used in a follow-up patch to copy data to
>>        > > > > > > the
>>        > > > > > > guest
>>        > > > > > > using the IPA (aka guest physical address) and then clean the cache.
>>        > > > > > >
>>        > > > > > > Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>        > > > > > > ---
>>        > > > > > >    xen/arch/arm/guestcopy.c           | 10 ++++++++++
>>        > > > > > >    xen/include/asm-arm/guest_access.h |  6 ++++++
>>        > > > > > >    2 files changed, 16 insertions(+)
>>        > > > > > >
>>        > > > > > > diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c
>>        > > > > > > index be53bee559..7958663970 100644
>>        > > > > > > --- a/xen/arch/arm/guestcopy.c
>>        > > > > > > +++ b/xen/arch/arm/guestcopy.c
>>        > > > > > > @@ -110,6 +110,16 @@ unsigned long raw_copy_from_guest(void *to,
>>        > > > > > > const
>>        > > > > > > void __user *from, unsigned le
>>        > > > > > >                          COPY_from_guest | COPY_linear);
>>        > > > > > >    }
>>        > > > > > >    +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
>>        > > > > > > +                                              paddr_t gpa,
>>        > > > > > > +                                              void *buf,
>>        > > > > > > +                                              unsigned int len)
>>        > > > > > > +{
>>        > > > > > > +    /* P2M is shared between all vCPUs, so the vCPU used does not
>>        > > > > > > matter.
>>        > > > > > > */
>>        > > > > >
>>        > > > > > Be very careful with this line of thinking.  It is only works after
>>        > > > > > DOMCTL_max_vcpus has succeeded, and before that point, it is a latent
>>        > > > > > NULL pointer dereference.
>>        > > > >
>>        > > > > I really don't expect that function been used before DOMCT_max_vcpus is
>>        > > > > set.
>>        > > > > It is only used for hardware emulation or Xen loading image into the
>>        > > > > hardware
>>        > > > > domain memory. I could add a check d->vcpus to be safe.
>>        > > > >
>>        > > > > >
>>        > > > > > Also, what about vcpus configured with alternative views?
>>        > > > >
>>        > > > > It is not important because the underlying call is get_page_from_gfn
>>        > > > > that does
>>        > > > > not care about the alternative view (that function take a domain in
>>        > > > > parameter). I can update the comment.
>>        > > > Since this is a new function, would it make sense to take a struct
>>        > > > vcpu* as parameter, instead of a struct domain* ?
>>        > >
>>        > > Well, I suggested this patch this way because likely everyone will use with
>>        > > d->vcpus[0]. And then you would have to wonder why d->vcpus[0] and not
>>        > > d->vcpus[1]...
>>        >
>>        > Thinking a bit more to this, it might be better/safer to pass either a domain
>>        > or a vCPU to copy_guest. I can see 2 solutions:
>>        >       1# Introduce a union that use the same parameter:
>>        >               union
>>        >               {
>>        >                       struct
>>        >                       {
>>        >                               struct domain *d;
>>        >                       } ipa;
>>        >                       struct
>>        >                       {
>>        >                               struct vcpu *v;
>>        >                       } gva;
>>        >               }
>>        >         The structure here would be to ensure that it is clear that only
>>        > domain (resp. vcpu) should be used with ipa (resp. gva).
>>        >
>>        >       2# Have 2 parameters, vcpu and domain.
>>        >
>>        > Any opinions?
>>
>> I think that would be clearer. You could also add a paddr_t/vaddr_t
>> correspondingly inside the union maybe.
>>
>>
>> Well, you will have nameclash happening I think.
>>
>>
>> And vaddr_t and paddr_t are confusing because you don't know which address you speak about (guest vs hypervisor). At least ipa/gpa, gva are known naming.
> 
> That's not what I meant. ipa and gva are good names.
> 
> I was suggesting to put an additional address field inside the union to
> avoid the issue with paddr_t and vaddr_t discussed elsewhere
> (alpine.DEB.2.10.1712081313070.8052@sstabellini-ThinkPad-X260).
> 
> I am happy either way, it was just a suggestion.

Actually looking at it. It will not be that handy to have the 
paddr_t/vaddr_t inside the union. Mostly because of the common code 
using the address parameter.

I could add another union for the address, but I don't much like it.
As you are happy with either way, I will use uint64_t.

Cheers,
Stefano Stabellini Dec. 12, 2017, 12:28 a.m. UTC | #10
On Tue, 12 Dec 2017, Julien Grall wrote:
> Hi Stefano,

> 

> On 12/08/2017 10:43 PM, Stefano Stabellini wrote:

> > On Fri, 8 Dec 2017, Julien Grall wrote:

> > > On 8 Dec 2017 22:26, "Stefano Stabellini" <sstabellini@kernel.org> wrote:

> > >        On Fri, 8 Dec 2017, Julien Grall wrote:

> > >        > On 06/12/17 12:27, Julien Grall wrote:

> > >        > > On 12/06/2017 01:26 AM, Stefano Stabellini wrote:

> > >        > > > On Thu, 23 Nov 2017, Julien Grall wrote:

> > >        > > > > Hi Andrew,

> > >        > > > >

> > >        > > > > On 23/11/17 18:49, Andrew Cooper wrote:

> > >        > > > > > On 23/11/17 18:32, Julien Grall wrote:

> > >        > > > > > > This new function will be used in a follow-up patch to

> > > copy data to

> > >        > > > > > > the

> > >        > > > > > > guest

> > >        > > > > > > using the IPA (aka guest physical address) and then

> > > clean the cache.

> > >        > > > > > >

> > >        > > > > > > Signed-off-by: Julien Grall <julien.grall@linaro.org>

> > >        > > > > > > ---

> > >        > > > > > >    xen/arch/arm/guestcopy.c           | 10 ++++++++++

> > >        > > > > > >    xen/include/asm-arm/guest_access.h |  6 ++++++

> > >        > > > > > >    2 files changed, 16 insertions(+)

> > >        > > > > > >

> > >        > > > > > > diff --git a/xen/arch/arm/guestcopy.c

> > > b/xen/arch/arm/guestcopy.c

> > >        > > > > > > index be53bee559..7958663970 100644

> > >        > > > > > > --- a/xen/arch/arm/guestcopy.c

> > >        > > > > > > +++ b/xen/arch/arm/guestcopy.c

> > >        > > > > > > @@ -110,6 +110,16 @@ unsigned long

> > > raw_copy_from_guest(void *to,

> > >        > > > > > > const

> > >        > > > > > > void __user *from, unsigned le

> > >        > > > > > >                          COPY_from_guest |

> > > COPY_linear);

> > >        > > > > > >    }

> > >        > > > > > >    +unsigned long

> > > copy_to_guest_phys_flush_dcache(struct domain *d,

> > >        > > > > > > +                                              paddr_t

> > > gpa,

> > >        > > > > > > +                                              void

> > > *buf,

> > >        > > > > > > +                                              unsigned

> > > int len)

> > >        > > > > > > +{

> > >        > > > > > > +    /* P2M is shared between all vCPUs, so the vCPU

> > > used does not

> > >        > > > > > > matter.

> > >        > > > > > > */

> > >        > > > > >

> > >        > > > > > Be very careful with this line of thinking.  It is only

> > > works after

> > >        > > > > > DOMCTL_max_vcpus has succeeded, and before that point, it

> > > is a latent

> > >        > > > > > NULL pointer dereference.

> > >        > > > >

> > >        > > > > I really don't expect that function been used before

> > > DOMCT_max_vcpus is

> > >        > > > > set.

> > >        > > > > It is only used for hardware emulation or Xen loading image

> > > into the

> > >        > > > > hardware

> > >        > > > > domain memory. I could add a check d->vcpus to be safe.

> > >        > > > >

> > >        > > > > >

> > >        > > > > > Also, what about vcpus configured with alternative views?

> > >        > > > >

> > >        > > > > It is not important because the underlying call is

> > > get_page_from_gfn

> > >        > > > > that does

> > >        > > > > not care about the alternative view (that function take a

> > > domain in

> > >        > > > > parameter). I can update the comment.

> > >        > > > Since this is a new function, would it make sense to take a

> > > struct

> > >        > > > vcpu* as parameter, instead of a struct domain* ?

> > >        > >

> > >        > > Well, I suggested this patch this way because likely everyone

> > > will use with

> > >        > > d->vcpus[0]. And then you would have to wonder why d->vcpus[0]

> > > and not

> > >        > > d->vcpus[1]...

> > >        >

> > >        > Thinking a bit more to this, it might be better/safer to pass

> > > either a domain

> > >        > or a vCPU to copy_guest. I can see 2 solutions:

> > >        >       1# Introduce a union that use the same parameter:

> > >        >               union

> > >        >               {

> > >        >                       struct

> > >        >                       {

> > >        >                               struct domain *d;

> > >        >                       } ipa;

> > >        >                       struct

> > >        >                       {

> > >        >                               struct vcpu *v;

> > >        >                       } gva;

> > >        >               }

> > >        >         The structure here would be to ensure that it is clear

> > > that only

> > >        > domain (resp. vcpu) should be used with ipa (resp. gva).

> > >        >

> > >        >       2# Have 2 parameters, vcpu and domain.

> > >        >

> > >        > Any opinions?

> > > 

> > > I think that would be clearer. You could also add a paddr_t/vaddr_t

> > > correspondingly inside the union maybe.

> > > 

> > > 

> > > Well, you will have nameclash happening I think.

> > > 

> > > 

> > > And vaddr_t and paddr_t are confusing because you don't know which address

> > > you speak about (guest vs hypervisor). At least ipa/gpa, gva are known

> > > naming.

> > 

> > That's not what I meant. ipa and gva are good names.

> > 

> > I was suggesting to put an additional address field inside the union to

> > avoid the issue with paddr_t and vaddr_t discussed elsewhere

> > (alpine.DEB.2.10.1712081313070.8052@sstabellini-ThinkPad-X260).

> > 

> > I am happy either way, it was just a suggestion.

> 

> Actually looking at it. It will not be that handy to have the paddr_t/vaddr_t

> inside the union. Mostly because of the common code using the address

> parameter.

> 

> I could add another union for the address, but I don't much like it.

> As you are happy with either way, I will use uint64_t.

 
Sounds good
diff mbox series

Patch

diff --git a/xen/arch/arm/guestcopy.c b/xen/arch/arm/guestcopy.c
index be53bee559..7958663970 100644
--- a/xen/arch/arm/guestcopy.c
+++ b/xen/arch/arm/guestcopy.c
@@ -110,6 +110,16 @@  unsigned long raw_copy_from_guest(void *to, const void __user *from, unsigned le
                       COPY_from_guest | COPY_linear);
 }
 
+unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
+                                              paddr_t gpa,
+                                              void *buf,
+                                              unsigned int len)
+{
+    /* P2M is shared between all vCPUs, so the vCPU used does not matter. */
+    return copy_guest(buf, gpa, len, d->vcpu[0],
+                      COPY_to_guest | COPY_ipa | COPY_flush_dcache);
+}
+
 int access_guest_memory_by_ipa(struct domain *d, paddr_t gpa, void *buf,
                                uint32_t size, bool is_write)
 {
diff --git a/xen/include/asm-arm/guest_access.h b/xen/include/asm-arm/guest_access.h
index 6796801cfe..224d2a033b 100644
--- a/xen/include/asm-arm/guest_access.h
+++ b/xen/include/asm-arm/guest_access.h
@@ -11,6 +11,12 @@  unsigned long raw_copy_to_guest_flush_dcache(void *to, const void *from,
 unsigned long raw_copy_from_guest(void *to, const void *from, unsigned len);
 unsigned long raw_clear_guest(void *to, unsigned len);
 
+/* Copy data to guest physical address, then clean the region. */
+unsigned long copy_to_guest_phys_flush_dcache(struct domain *d,
+                                              paddr_t phys,
+                                              void *buf,
+                                              unsigned int len);
+
 int access_guest_memory_by_ipa(struct domain *d, paddr_t ipa, void *buf,
                                uint32_t size, bool is_write);