xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
@ 2013-07-04 19:36 suravee.suthikulpanit
  2013-07-04 19:42 ` Andrew Cooper
  0 siblings, 1 reply; 7+ messages in thread
From: suravee.suthikulpanit @ 2013-07-04 19:36 UTC (permalink / raw)
  To: xen-devel, JBeulich, chegger; +Cc: Suravee Suthikulpanit

From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>

Fix assertion in __virt_to_maddr when starting nested SVM guest
in debug mode. Investigation has shown that svm_vmsave/svm_vmload
make use of __pa() with invalid address.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 xen/arch/x86/hvm/svm/svm.c        |    4 ++--
 xen/include/asm-x86/hvm/svm/svm.h |   14 ++++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index acd2d49..944569a 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1809,7 +1809,7 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb,
         goto inject;
     }
 
-    svm_vmload(nv->nv_vvmcx);
+    nestedsvm_vmload(nv->nv_vvmcxaddr);
     /* State in L1 VMCB is stale now */
     v->arch.hvm_svm.vmcb_in_sync = 0;
 
@@ -1845,7 +1845,7 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb,
         goto inject;
     }
 
-    svm_vmsave(nv->nv_vvmcx);
+    nestedsvm_vmsave(nv->nv_vvmcxaddr);
 
     __update_guest_eip(regs, inst_len);
     return;
diff --git a/xen/include/asm-x86/hvm/svm/svm.h b/xen/include/asm-x86/hvm/svm/svm.h
index 64e7e25..909e8a1 100644
--- a/xen/include/asm-x86/hvm/svm/svm.h
+++ b/xen/include/asm-x86/hvm/svm/svm.h
@@ -55,6 +55,20 @@ static inline void svm_vmsave(void *vmcb)
         : : "a" (__pa(vmcb)) : "memory" );
 }
 
+static inline void nestedsvm_vmload(uint64_t vmcb)
+{
+    asm volatile (
+        ".byte 0x0f,0x01,0xda" /* vmload */
+        : : "a" (vmcb) : "memory" );
+}
+
+static inline void nestedsvm_vmsave(uint64_t vmcb)
+{
+    asm volatile (
+        ".byte 0x0f,0x01,0xdb" /* vmsave */
+        : : "a" (vmcb) : "memory" );
+}
+
 static inline void svm_invlpga(unsigned long vaddr, uint32_t asid)
 {
     asm volatile (
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
  2013-07-04 19:36 [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr suravee.suthikulpanit
@ 2013-07-04 19:42 ` Andrew Cooper
  2013-07-04 21:48   ` Tim Deegan
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew Cooper @ 2013-07-04 19:42 UTC (permalink / raw)
  To: suravee.suthikulpanit; +Cc: chegger, JBeulich, xen-devel

On 04/07/13 20:36, suravee.suthikulpanit@amd.com wrote:
> From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
>
> Fix assertion in __virt_to_maddr when starting nested SVM guest
> in debug mode. Investigation has shown that svm_vmsave/svm_vmload
> make use of __pa() with invalid address.
>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  xen/arch/x86/hvm/svm/svm.c        |    4 ++--
>  xen/include/asm-x86/hvm/svm/svm.h |   14 ++++++++++++++
>  2 files changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
> index acd2d49..944569a 100644
> --- a/xen/arch/x86/hvm/svm/svm.c
> +++ b/xen/arch/x86/hvm/svm/svm.c
> @@ -1809,7 +1809,7 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb,
>          goto inject;
>      }
>  
> -    svm_vmload(nv->nv_vvmcx);
> +    nestedsvm_vmload(nv->nv_vvmcxaddr);
>      /* State in L1 VMCB is stale now */
>      v->arch.hvm_svm.vmcb_in_sync = 0;
>  
> @@ -1845,7 +1845,7 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb,
>          goto inject;
>      }
>  
> -    svm_vmsave(nv->nv_vvmcx);
> +    nestedsvm_vmsave(nv->nv_vvmcxaddr);
>  
>      __update_guest_eip(regs, inst_len);
>      return;
> diff --git a/xen/include/asm-x86/hvm/svm/svm.h b/xen/include/asm-x86/hvm/svm/svm.h
> index 64e7e25..909e8a1 100644
> --- a/xen/include/asm-x86/hvm/svm/svm.h
> +++ b/xen/include/asm-x86/hvm/svm/svm.h
> @@ -55,6 +55,20 @@ static inline void svm_vmsave(void *vmcb)
>          : : "a" (__pa(vmcb)) : "memory" );
>  }
>  
> +static inline void nestedsvm_vmload(uint64_t vmcb)

unsigned long if this is actually an address.

But more importantly, if virt_to_maddr() fails an assertion because the
virtual address is not a persistent mapping, what is going to happen
when the virtual mapping (potentially) changes while the vvmcx is in use?

~Andrew

> +{
> +    asm volatile (
> +        ".byte 0x0f,0x01,0xda" /* vmload */
> +        : : "a" (vmcb) : "memory" );
> +}
> +
> +static inline void nestedsvm_vmsave(uint64_t vmcb)
> +{
> +    asm volatile (
> +        ".byte 0x0f,0x01,0xdb" /* vmsave */
> +        : : "a" (vmcb) : "memory" );
> +}
> +
>  static inline void svm_invlpga(unsigned long vaddr, uint32_t asid)
>  {
>      asm volatile (

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
  2013-07-04 19:42 ` Andrew Cooper
@ 2013-07-04 21:48   ` Tim Deegan
  2013-07-05  7:47     ` Egger, Christoph
  2013-07-05  7:53     ` Jan Beulich
  0 siblings, 2 replies; 7+ messages in thread
From: Tim Deegan @ 2013-07-04 21:48 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: chegger, JBeulich, suravee.suthikulpanit, xen-devel

At 20:42 +0100 on 04 Jul (1372970576), Andrew Cooper wrote:
> On 04/07/13 20:36, suravee.suthikulpanit@amd.com wrote:
> > From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> >
> > Fix assertion in __virt_to_maddr when starting nested SVM guest
> > in debug mode. Investigation has shown that svm_vmsave/svm_vmload
> > make use of __pa() with invalid address.
> >
> > Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> > ---
> >  xen/arch/x86/hvm/svm/svm.c        |    4 ++--
> >  xen/include/asm-x86/hvm/svm/svm.h |   14 ++++++++++++++
> >  2 files changed, 16 insertions(+), 2 deletions(-)
> >
> > diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
> > index acd2d49..944569a 100644
> > --- a/xen/arch/x86/hvm/svm/svm.c
> > +++ b/xen/arch/x86/hvm/svm/svm.c
> > @@ -1809,7 +1809,7 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb,
> >          goto inject;
> >      }
> >  
> > -    svm_vmload(nv->nv_vvmcx);
> > +    nestedsvm_vmload(nv->nv_vvmcxaddr);
> >      /* State in L1 VMCB is stale now */
> >      v->arch.hvm_svm.vmcb_in_sync = 0;
> >  
> > @@ -1845,7 +1845,7 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb,
> >          goto inject;
> >      }
> >  
> > -    svm_vmsave(nv->nv_vvmcx);
> > +    nestedsvm_vmsave(nv->nv_vvmcxaddr);
> >  
> >      __update_guest_eip(regs, inst_len);
> >      return;
> > diff --git a/xen/include/asm-x86/hvm/svm/svm.h b/xen/include/asm-x86/hvm/svm/svm.h
> > index 64e7e25..909e8a1 100644
> > --- a/xen/include/asm-x86/hvm/svm/svm.h
> > +++ b/xen/include/asm-x86/hvm/svm/svm.h
> > @@ -55,6 +55,20 @@ static inline void svm_vmsave(void *vmcb)
> >          : : "a" (__pa(vmcb)) : "memory" );
> >  }
> >  
> > +static inline void nestedsvm_vmload(uint64_t vmcb)
> 
> unsigned long if this is actually an address.

IIUC this is a physical address, so paddr_t is the correct type.  Also,
it might be nicer to call these svm_vm{save,load}_by_paddr() or similar
to make it clear what they do.

> But more importantly, if virt_to_maddr() fails an assertion because the
> virtual address is not a persistent mapping, what is going to happen
> when the virtual mapping (potentially) changes while the vvmcx is in use?

I think the virtual mapping is ok from that point of view -- it's mapped
with map_domain_page_global().  I worry that we might run out of mapping
slots if we keep a lot of these permanent mappings around, though.

Cheers,

Tim

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
  2013-07-04 21:48   ` Tim Deegan
@ 2013-07-05  7:47     ` Egger, Christoph
  2013-07-05  7:54       ` Jan Beulich
  2013-07-05  7:53     ` Jan Beulich
  1 sibling, 1 reply; 7+ messages in thread
From: Egger, Christoph @ 2013-07-05  7:47 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Andrew Cooper, JBeulich, suravee.suthikulpanit, xen-devel

On 04.07.13 23:48, Tim Deegan wrote:
> At 20:42 +0100 on 04 Jul (1372970576), Andrew Cooper wrote:
>> On 04/07/13 20:36, suravee.suthikulpanit@amd.com wrote:
>>> From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
>>>
>>> Fix assertion in __virt_to_maddr when starting nested SVM guest
>>> in debug mode. Investigation has shown that svm_vmsave/svm_vmload
>>> make use of __pa() with invalid address.
>>>
>>> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
>>> ---
>>>  xen/arch/x86/hvm/svm/svm.c        |    4 ++--
>>>  xen/include/asm-x86/hvm/svm/svm.h |   14 ++++++++++++++
>>>  2 files changed, 16 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
>>> index acd2d49..944569a 100644
>>> --- a/xen/arch/x86/hvm/svm/svm.c
>>> +++ b/xen/arch/x86/hvm/svm/svm.c
>>> @@ -1809,7 +1809,7 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb,
>>>          goto inject;
>>>      }
>>>  
>>> -    svm_vmload(nv->nv_vvmcx);
>>> +    nestedsvm_vmload(nv->nv_vvmcxaddr);
>>>      /* State in L1 VMCB is stale now */
>>>      v->arch.hvm_svm.vmcb_in_sync = 0;
>>>  
>>> @@ -1845,7 +1845,7 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb,
>>>          goto inject;
>>>      }
>>>  
>>> -    svm_vmsave(nv->nv_vvmcx);
>>> +    nestedsvm_vmsave(nv->nv_vvmcxaddr);
>>>  
>>>      __update_guest_eip(regs, inst_len);
>>>      return;
>>> diff --git a/xen/include/asm-x86/hvm/svm/svm.h b/xen/include/asm-x86/hvm/svm/svm.h
>>> index 64e7e25..909e8a1 100644
>>> --- a/xen/include/asm-x86/hvm/svm/svm.h
>>> +++ b/xen/include/asm-x86/hvm/svm/svm.h
>>> @@ -55,6 +55,20 @@ static inline void svm_vmsave(void *vmcb)
>>>          : : "a" (__pa(vmcb)) : "memory" );
>>>  }
>>>  
>>> +static inline void nestedsvm_vmload(uint64_t vmcb)
>>
>> unsigned long if this is actually an address.
> 
> IIUC this is a physical address, so paddr_t is the correct type.

Right.

> Also, it might be nicer to call these svm_vm{save,load}_by_paddr() or similar
> to make it clear what they do.

I agree.

But why did the assertion never trigger when called from elsewhere
in svm_vm{load,save}?

>> But more importantly, if virt_to_maddr() fails an assertion because the
>> virtual address is not a persistent mapping, what is going to happen
>> when the virtual mapping (potentially) changes while the vvmcx is in use?
> 
> I think the virtual mapping is ok from that point of view -- it's mapped
> with map_domain_page_global().  I worry that we might run out of mapping
> slots if we keep a lot of these permanent mappings around, though.

The number of mappings = number of guest hypervisors * number of virtual
cpus per guest hypervisor

number of guest hypervisors = number of domains excluding all domains
where nestedhvm is not used even when turned on

Christoph

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
  2013-07-04 21:48   ` Tim Deegan
  2013-07-05  7:47     ` Egger, Christoph
@ 2013-07-05  7:53     ` Jan Beulich
  2013-07-05 21:38       ` Suravee Suthikulanit
  1 sibling, 1 reply; 7+ messages in thread
From: Jan Beulich @ 2013-07-05  7:53 UTC (permalink / raw)
  To: suravee.suthikulpanit, Tim Deegan; +Cc: Andrew Cooper, chegger, xen-devel

>>> On 04.07.13 at 23:48, Tim Deegan <tim@xen.org> wrote:
> At 20:42 +0100 on 04 Jul (1372970576), Andrew Cooper wrote:
>> On 04/07/13 20:36, suravee.suthikulpanit@amd.com wrote:
>> > +static inline void nestedsvm_vmload(uint64_t vmcb)
>> 
>> unsigned long if this is actually an address.
> 
> IIUC this is a physical address, so paddr_t is the correct type.  Also,
> it might be nicer to call these svm_vm{save,load}_by_paddr() or similar
> to make it clear what they do.

So would I think. And the existing functions then could simply
wrap the new ones.

However, looking at the call sites of svm_vmexit_do_vm(), I don't
think this is a host physical address in all cases: At least the uses
from svm_vmexit_do_vm*() in svm.c suggest that these are GPAs,
and hence can't be passed to vmload/vmsave without translation.

>> But more importantly, if virt_to_maddr() fails an assertion because the
>> virtual address is not a persistent mapping, what is going to happen
>> when the virtual mapping (potentially) changes while the vvmcx is in use?
> 
> I think the virtual mapping is ok from that point of view -- it's mapped
> with map_domain_page_global().

And anyway, the virtual mapping isn't being used in the resulting
code.

> I worry that we might run out of mapping
> slots if we keep a lot of these permanent mappings around, though.

Afaict there's a single such mapping per vCPU, so not that much to
worry about I think.

Jan

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
  2013-07-05  7:47     ` Egger, Christoph
@ 2013-07-05  7:54       ` Jan Beulich
  0 siblings, 0 replies; 7+ messages in thread
From: Jan Beulich @ 2013-07-05  7:54 UTC (permalink / raw)
  To: Christoph Egger
  Cc: Andrew Cooper, Tim Deegan, suravee.suthikulpanit, xen-devel

>>> On 05.07.13 at 09:47, "Egger, Christoph" <chegger@amazon.de> wrote:
> But why did the assertion never trigger when called from elsewhere
> in svm_vm{load,save}?

Because ordinary VMCBs get allocated from the Xen heap.

Jan

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
  2013-07-05  7:53     ` Jan Beulich
@ 2013-07-05 21:38       ` Suravee Suthikulanit
  0 siblings, 0 replies; 7+ messages in thread
From: Suravee Suthikulanit @ 2013-07-05 21:38 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Andrew Cooper, chegger, Tim Deegan, xen-devel

On 7/5/2013 2:53 AM, Jan Beulich wrote:
>>>> On 04.07.13 at 23:48, Tim Deegan <tim@xen.org> wrote:
>> At 20:42 +0100 on 04 Jul (1372970576), Andrew Cooper wrote:
>>> On 04/07/13 20:36, suravee.suthikulpanit@amd.com wrote:
>>>> +static inline void nestedsvm_vmload(uint64_t vmcb)
>>> unsigned long if this is actually an address.
>> IIUC this is a physical address, so paddr_t is the correct type.  Also,
>> it might be nicer to call these svm_vm{save,load}_by_paddr() or similar
>> to make it clear what they do.
> So would I think. And the existing functions then could simply
> wrap the new ones.
>
> However, looking at the call sites of svm_vmexit_do_vm(), I don't
> think this is a host physical address in all cases: At least the uses
> from svm_vmexit_do_vm*() in svm.c suggest that these are GPAs,
> and hence can't be passed to vmload/vmsave without translation.
>
>>> But more importantly, if virt_to_maddr() fails an assertion because the
>>> virtual address is not a persistent mapping, what is going to happen
>>> when the virtual mapping (potentially) changes while the vvmcx is in use?
>> I think the virtual mapping is ok from that point of view -- it's mapped
>> with map_domain_page_global().
> And anyway, the virtual mapping isn't being used in the resulting
> code.
>
>> I worry that we might run out of mapping
>> slots if we keep a lot of these permanent mappings around, though.
> Afaict there's a single such mapping per vCPU, so not that much to
> worry about I think.
>
> Jan
>
>
Thank you all for comments. I am sending out V2 in a separate thread.

Suravee

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-07-05 21:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-04 19:36 [PATCH 1/1] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr suravee.suthikulpanit
2013-07-04 19:42 ` Andrew Cooper
2013-07-04 21:48   ` Tim Deegan
2013-07-05  7:47     ` Egger, Christoph
2013-07-05  7:54       ` Jan Beulich
2013-07-05  7:53     ` Jan Beulich
2013-07-05 21:38       ` Suravee Suthikulanit

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