All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] x86/vvmx: various fixes
@ 2018-11-14 10:23 Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise() Sergey Dyasli
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

These were found by running nested VMX tests from kvm-unit-tests.

v3:
- Removed 1/8 "x86/vvmx: introduce nvmx_vcpu_preinit()"
- Added 1/8 "x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise()"
- Added R-by and Acked-by to other patches

Sergey Dyasli (8):
  x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise()
  x86/nestedhvm: introduce vvmcx_valid()
  x86/vvmx: add VMX_INSN_INVEPT_INVVPID_INVALID_OP errno
  x86/vvmx: correct vmfail() usage for vmptrld and vmclear
  x86/vvmx: add VMX_INSN_VMPTRLD_WITH_VMXON_PTR errno
  x86/vvmx: refactor nvmx_handle_vmclear()
  x86/vvmx: correctly report vvmcs size
  x86/vvmx: fix I/O and MSR bitmaps mapping

 xen/arch/x86/hvm/hvm.c              |   2 +
 xen/arch/x86/hvm/svm/nestedsvm.c    |   2 +-
 xen/arch/x86/hvm/vmx/vvmx.c         | 201 ++++++++++++++++++----------
 xen/include/asm-x86/hvm/nestedhvm.h |   5 +
 xen/include/asm-x86/hvm/vmx/vmcs.h  |   3 +
 5 files changed, 139 insertions(+), 74 deletions(-)

-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise()
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  2018-11-14 13:46   ` Jan Beulich
  2018-11-15  1:35   ` Tian, Kevin
  2018-11-14 10:23 ` [PATCH v3 2/8] x86/nestedhvm: introduce vvmcx_valid() Sergey Dyasli
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

This allows to safely use nestedhvm functions that rely on the values
inside struct nestedvcpu independently of the nested virtualisation
(HVM_PARAM_NESTEDHVM) status of a domain.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
---
v3:
- new patch
---
 xen/arch/x86/hvm/hvm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 5d263c4090..c0a3db5858 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1516,6 +1516,8 @@ int hvm_vcpu_initialise(struct vcpu *v)
     if ( rc != 0 )
         goto fail4;
 
+    vcpu_nestedhvm(v).nv_vvmcxaddr = INVALID_PADDR;
+
     if ( nestedhvm_enabled(d)
          && (rc = nestedhvm_vcpu_initialise(v)) < 0 ) /* teardown: nestedhvm_vcpu_destroy */
         goto fail5;
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 2/8] x86/nestedhvm: introduce vvmcx_valid()
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise() Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 3/8] x86/vvmx: add VMX_INSN_INVEPT_INVVPID_INVALID_OP errno Sergey Dyasli
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima, Boris Ostrovsky, Brian Woods,
	Suravee Suthikulpanit

As a convenient helper function and refactor the code to use it.

No functional change.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
CC: Boris Ostrovsky <boris.ostrovsky@oracle.com>
CC: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
CC: Brian Woods <brian.woods@amd.com>

v3:
- Added R-by

v2:
- Use the new helper in nestedsvm.c
---
 xen/arch/x86/hvm/svm/nestedsvm.c    |  2 +-
 xen/arch/x86/hvm/vmx/vvmx.c         | 17 ++++++++---------
 xen/include/asm-x86/hvm/nestedhvm.h |  5 +++++
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index 088b3fd562..9660202210 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -68,7 +68,7 @@ int nestedsvm_vmcb_map(struct vcpu *v, uint64_t vmcbaddr)
     struct nestedvcpu *nv = &vcpu_nestedhvm(v);
 
     if (nv->nv_vvmcx != NULL && nv->nv_vvmcxaddr != vmcbaddr) {
-        ASSERT(nv->nv_vvmcxaddr != INVALID_PADDR);
+        ASSERT(vvmcx_valid(v));
         hvm_unmap_guest_frame(nv->nv_vvmcx, 1);
         nv->nv_vvmcx = NULL;
         nv->nv_vvmcxaddr = INVALID_PADDR;
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index dfd08e2d0a..071ee61d19 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -479,8 +479,7 @@ static void vmfail(struct cpu_user_regs *regs, enum vmx_insn_errno errno)
     if ( errno == VMX_INSN_SUCCEED )
         return;
 
-    if ( vcpu_nestedhvm(current).nv_vvmcxaddr != INVALID_PADDR &&
-         errno != VMX_INSN_FAIL_INVALID )
+    if ( vvmcx_valid(current) && errno != VMX_INSN_FAIL_INVALID )
         vmfail_valid(regs, errno);
     else
         vmfail_invalid(regs);
@@ -763,7 +762,7 @@ static void nvmx_purge_vvmcs(struct vcpu *v)
     int i;
 
     __clear_current_vvmcs(v);
-    if ( nvcpu->nv_vvmcxaddr != INVALID_PADDR )
+    if ( vvmcx_valid(v) )
         hvm_unmap_guest_frame(nvcpu->nv_vvmcx, 1);
     nvcpu->nv_vvmcx = NULL;
     nvcpu->nv_vvmcxaddr = INVALID_PADDR;
@@ -1554,7 +1553,7 @@ static int nvmx_vmresume(struct vcpu *v, struct cpu_user_regs *regs)
     struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
 
     /* check VMCS is valid and IO BITMAP is set */
-    if ( (nvcpu->nv_vvmcxaddr != INVALID_PADDR) &&
+    if ( vvmcx_valid(v) &&
             ((nvmx->iobitmap[0] && nvmx->iobitmap[1]) ||
             !(__n2_exec_control(v) & CPU_BASED_ACTIVATE_IO_BITMAP) ) )
         nvcpu->nv_vmentry_pending = 1;
@@ -1571,7 +1570,7 @@ static int nvmx_handle_vmresume(struct cpu_user_regs *regs)
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
     unsigned long intr_shadow;
 
-    if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR )
+    if ( !vvmcx_valid(v) )
     {
         vmfail_invalid(regs);
         return X86EMUL_OKAY;        
@@ -1602,7 +1601,7 @@ static int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)
     unsigned long intr_shadow;
     int rc;
 
-    if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR )
+    if ( !vvmcx_valid(v) )
     {
         vmfail_invalid(regs);
         return X86EMUL_OKAY;
@@ -1655,7 +1654,7 @@ static int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
     if ( nvcpu->nv_vvmcxaddr != gpa )
         nvmx_purge_vvmcs(v);
 
-    if ( nvcpu->nv_vvmcxaddr == INVALID_PADDR )
+    if ( !vvmcx_valid(v) )
     {
         bool_t writable;
         void *vvmcx = hvm_map_guest_frame_rw(paddr_to_pfn(gpa), 1, &writable);
@@ -1794,7 +1793,7 @@ static int nvmx_handle_vmread(struct cpu_user_regs *regs)
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR )
+    if ( !vvmcx_valid(v) )
     {
         vmfail_invalid(regs);
         return X86EMUL_OKAY;
@@ -1836,7 +1835,7 @@ static int nvmx_handle_vmwrite(struct cpu_user_regs *regs)
     if ( decode_vmx_inst(regs, &decode, &operand) != X86EMUL_OKAY )
         return X86EMUL_EXCEPTION;
 
-    if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR )
+    if ( !vvmcx_valid(v) )
     {
         vmfail_invalid(regs);
         return X86EMUL_OKAY;
diff --git a/xen/include/asm-x86/hvm/nestedhvm.h b/xen/include/asm-x86/hvm/nestedhvm.h
index 9d1c2742b5..e09fa9d47d 100644
--- a/xen/include/asm-x86/hvm/nestedhvm.h
+++ b/xen/include/asm-x86/hvm/nestedhvm.h
@@ -92,4 +92,9 @@ static inline void nestedhvm_set_cr(struct vcpu *v, unsigned int cr,
         v->arch.hvm.nvcpu.guest_cr[cr] = value;
 }
 
+static inline bool vvmcx_valid(const struct vcpu *v)
+{
+    return vcpu_nestedhvm(v).nv_vvmcxaddr != INVALID_PADDR;
+}
+
 #endif /* _HVM_NESTEDHVM_H */
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 3/8] x86/vvmx: add VMX_INSN_INVEPT_INVVPID_INVALID_OP errno
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise() Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 2/8] x86/nestedhvm: introduce vvmcx_valid() Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 4/8] x86/vvmx: correct vmfail() usage for vmptrld and vmclear Sergey Dyasli
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

And use it in nvmx_handle_invept() and nvmx_handle_invvpid().

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
---
v3:
- Added Acked-by

v2:
- new patch
---
 xen/arch/x86/hvm/vmx/vvmx.c        | 4 ++--
 xen/include/asm-x86/hvm/vmx/vmcs.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index 071ee61d19..a9b92a5b95 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -1891,7 +1891,7 @@ static int nvmx_handle_invept(struct cpu_user_regs *regs)
         __invept(INVEPT_ALL_CONTEXT, 0);
         break;
     default:
-        vmfail_invalid(regs);
+        vmfail(regs, VMX_INSN_INVEPT_INVVPID_INVALID_OP);
         return X86EMUL_OKAY;
     }
     vmsucceed(regs);
@@ -1916,7 +1916,7 @@ static int nvmx_handle_invvpid(struct cpu_user_regs *regs)
         hvm_asid_flush_vcpu_asid(&vcpu_nestedhvm(current).nv_n2asid);
         break;
     default:
-        vmfail_invalid(regs);
+        vmfail(regs, VMX_INSN_INVEPT_INVVPID_INVALID_OP);
         return X86EMUL_OKAY;
     }
 
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 76dd04a72d..6d0ae56fc1 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -538,6 +538,7 @@ enum vmx_insn_errno
     VMX_INSN_UNSUPPORTED_VMCS_COMPONENT    = 12,
     VMX_INSN_VMXON_IN_VMX_ROOT             = 15,
     VMX_INSN_VMENTRY_BLOCKED_BY_MOV_SS     = 26,
+    VMX_INSN_INVEPT_INVVPID_INVALID_OP     = 28,
     VMX_INSN_FAIL_INVALID                  = ~0,
 };
 
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 4/8] x86/vvmx: correct vmfail() usage for vmptrld and vmclear
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
                   ` (2 preceding siblings ...)
  2018-11-14 10:23 ` [PATCH v3 3/8] x86/vvmx: add VMX_INSN_INVEPT_INVVPID_INVALID_OP errno Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 5/8] x86/vvmx: add VMX_INSN_VMPTRLD_WITH_VMXON_PTR errno Sergey Dyasli
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

Calling vmfail_valid() is correct only if vvmcx is valid. Modify
functions to use vmfail() instead which performs the necessary check.

While at it, add ASSERTs into vmfail_valid/invalid() to quickly catch
an incorrect usage in the future.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
---
v3:
- Added Acked-by

v2:
- Added ASSERTs
---
 xen/arch/x86/hvm/vmx/vvmx.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index a9b92a5b95..206a4a44fb 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -463,14 +463,19 @@ static void vmfail_valid(struct cpu_user_regs *regs, enum vmx_insn_errno errno)
     struct vcpu *v = current;
     unsigned int eflags = regs->eflags;
 
+    ASSERT(vvmcx_valid(v));
+
     regs->eflags = (eflags & ~X86_EFLAGS_ARITH_MASK) | X86_EFLAGS_ZF;
     set_vvmcs(v, VM_INSTRUCTION_ERROR, errno);
 }
 
 static void vmfail_invalid(struct cpu_user_regs *regs)
 {
+    struct vcpu *v = current;
     unsigned int eflags = regs->eflags;
 
+    ASSERT(!vvmcx_valid(v));
+
     regs->eflags = (eflags & ~X86_EFLAGS_ARITH_MASK) | X86_EFLAGS_CF;
 }
 
@@ -1690,7 +1695,7 @@ static int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
              !map_io_bitmap_all(v) ||
              !_map_msr_bitmap(v) )
         {
-            vmfail_valid(regs, VMX_INSN_VMPTRLD_INVALID_PHYADDR);
+            vmfail(regs, VMX_INSN_VMPTRLD_INVALID_PHYADDR);
             goto out;
         }
     }
@@ -1774,7 +1779,7 @@ static int nvmx_handle_vmclear(struct cpu_user_regs *regs)
     if ( rc == VMSUCCEED )
         vmsucceed(regs);
     else if ( rc == VMFAIL_VALID )
-        vmfail_valid(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR);
+        vmfail(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR);
     else
         vmfail_invalid(regs);
 
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 5/8] x86/vvmx: add VMX_INSN_VMPTRLD_WITH_VMXON_PTR errno
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
                   ` (3 preceding siblings ...)
  2018-11-14 10:23 ` [PATCH v3 4/8] x86/vvmx: correct vmfail() usage for vmptrld and vmclear Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 6/8] x86/vvmx: refactor nvmx_handle_vmclear() Sergey Dyasli
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

And make nvmx_handle_vmptrld() return the new errno in case the provided
address is the same as vmxon region address.

While at it, correct the return value for not-4KB-aligned case.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
---
v3:
- no changes

v2:
- Added Acked-by
---
 xen/arch/x86/hvm/vmx/vvmx.c        | 10 ++++++++--
 xen/include/asm-x86/hvm/vmx/vmcs.h |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index 206a4a44fb..4391cd314a 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -1650,9 +1650,15 @@ static int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    if ( gpa == vcpu_2_nvmx(v).vmxon_region_pa || gpa & 0xfff )
+    if ( gpa & 0xfff )
     {
-        vmfail_invalid(regs);
+        vmfail(regs, VMX_INSN_VMPTRLD_INVALID_PHYADDR);
+        goto out;
+    }
+
+    if ( gpa == vcpu_2_nvmx(v).vmxon_region_pa )
+    {
+        vmfail(regs, VMX_INSN_VMPTRLD_WITH_VMXON_PTR);
         goto out;
     }
 
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 6d0ae56fc1..eae4e5397e 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -534,6 +534,7 @@ enum vmx_insn_errno
     VMX_INSN_INVALID_CONTROL_STATE         = 7,
     VMX_INSN_INVALID_HOST_STATE            = 8,
     VMX_INSN_VMPTRLD_INVALID_PHYADDR       = 9,
+    VMX_INSN_VMPTRLD_WITH_VMXON_PTR        = 10,
     VMX_INSN_VMPTRLD_INCORRECT_VMCS_ID     = 11,
     VMX_INSN_UNSUPPORTED_VMCS_COMPONENT    = 12,
     VMX_INSN_VMXON_IN_VMX_ROOT             = 15,
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 6/8] x86/vvmx: refactor nvmx_handle_vmclear()
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
                   ` (4 preceding siblings ...)
  2018-11-14 10:23 ` [PATCH v3 5/8] x86/vvmx: add VMX_INSN_VMPTRLD_WITH_VMXON_PTR errno Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 7/8] x86/vvmx: correctly report vvmcs size Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 8/8] x86/vvmx: fix I/O and MSR bitmaps mapping Sergey Dyasli
  7 siblings, 0 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

1. Add VMX_INSN_VMCLEAR_WITH_VMXON_PTR errno and add the appropriate
   check to the function.

2. Correct the return value for not-4KB-aligned case and for invalid
   physaddr (when hvm_map_guest_frame_rw() fails).

3. Remove enum vmx_ops_result and use vmfail/vmsucceed() calls directly.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
---
v3:
- Added Acked-by

v2:
- Removal of enum vmx_ops_result and refactoring
---
 xen/arch/x86/hvm/vmx/vvmx.c        | 52 +++++++++++++++++-------------
 xen/include/asm-x86/hvm/vmx/vmcs.h |  1 +
 2 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index 4391cd314a..1cb4af5113 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -207,12 +207,6 @@ struct vmx_inst_decoded {
     unsigned int reg2;
 };
 
-enum vmx_ops_result {
-    VMSUCCEED,
-    VMFAIL_VALID,
-    VMFAIL_INVALID,
-};
-
 #define CASE_SET_REG(REG, reg)      \
     case VMX_REG_ ## REG: regs->reg = value; break
 #define CASE_GET_REG(REG, reg)      \
@@ -1754,16 +1748,26 @@ static int nvmx_handle_vmclear(struct cpu_user_regs *regs)
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    BUILD_BUG_ON(X86EMUL_OKAY != VMSUCCEED); /* rc = VMSUCCEED; */
+    if ( gpa == vcpu_2_nvmx(v).vmxon_region_pa )
+    {
+        vmfail(regs, VMX_INSN_VMCLEAR_WITH_VMXON_PTR);
+        goto out;
+    }
+
     if ( gpa & 0xfff )
-        rc = VMFAIL_INVALID;
-    else if ( gpa == nvcpu->nv_vvmcxaddr )
+    {
+        vmfail(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR);
+        goto out;
+    }
+
+    if ( gpa == nvcpu->nv_vvmcxaddr )
     {
         if ( cpu_has_vmx_vmcs_shadowing )
             nvmx_clear_vmcs_pointer(v, nvcpu->nv_vvmcx);
         clear_vvmcs_launched(&nvmx->launched_list,
                              PFN_DOWN(v->arch.hvm.vmx.vmcs_shadow_maddr));
         nvmx_purge_vvmcs(v);
+        vmsucceed(regs);
     }
     else 
     {
@@ -1771,24 +1775,26 @@ static int nvmx_handle_vmclear(struct cpu_user_regs *regs)
         bool_t writable;
 
         vvmcs = hvm_map_guest_frame_rw(paddr_to_pfn(gpa), 0, &writable);
-        if ( vvmcs ) 
+
+        if ( !vvmcs )
         {
-            if ( writable )
-                clear_vvmcs_launched(&nvmx->launched_list,
-                                     mfn_x(domain_page_map_to_mfn(vvmcs)));
-            else
-                rc = VMFAIL_VALID;
-            hvm_unmap_guest_frame(vvmcs, 0);
+            vmfail(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR);
+            goto out;
         }
-    }
 
-    if ( rc == VMSUCCEED )
-        vmsucceed(regs);
-    else if ( rc == VMFAIL_VALID )
-        vmfail(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR);
-    else
-        vmfail_invalid(regs);
+        if ( writable )
+        {
+            clear_vvmcs_launched(&nvmx->launched_list,
+                                 mfn_x(domain_page_map_to_mfn(vvmcs)));
+            vmsucceed(regs);
+        }
+        else
+            vmfail(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR);
 
+        hvm_unmap_guest_frame(vvmcs, 0);
+    }
+
+out:
     return X86EMUL_OKAY;
 }
 
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index eae4e5397e..b3e800138e 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -529,6 +529,7 @@ enum vmx_insn_errno
 {
     VMX_INSN_SUCCEED                       = 0,
     VMX_INSN_VMCLEAR_INVALID_PHYADDR       = 2,
+    VMX_INSN_VMCLEAR_WITH_VMXON_PTR        = 3,
     VMX_INSN_VMLAUNCH_NONCLEAR_VMCS        = 4,
     VMX_INSN_VMRESUME_NONLAUNCHED_VMCS     = 5,
     VMX_INSN_INVALID_CONTROL_STATE         = 7,
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 7/8] x86/vvmx: correctly report vvmcs size
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
                   ` (5 preceding siblings ...)
  2018-11-14 10:23 ` [PATCH v3 6/8] x86/vvmx: refactor nvmx_handle_vmclear() Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  2018-11-14 10:23 ` [PATCH v3 8/8] x86/vvmx: fix I/O and MSR bitmaps mapping Sergey Dyasli
  7 siblings, 0 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

The size of Xen's virtual vmcs region is 4096 bytes (see comment about
Virtual VMCS layout in include/asm-x86/hvm/vmx/vvmx.h). Correctly report
it to the guest in case when VMCS shadowing is not available instead of
providing H/W value (which is usually smaller).

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
---
v3:
- Added Acked-by

v2:
- slight commit message change
---
 xen/arch/x86/hvm/vmx/vvmx.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index 1cb4af5113..610236e3f2 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -2091,6 +2091,14 @@ int nvmx_msr_read_intercept(unsigned int msr, u64 *msr_content)
         data = (host_data & (~0ul << 32)) |
                (vmcs->vmcs_revision_id & 0x7fffffff);
         unmap_domain_page(vmcs);
+
+        if ( !cpu_has_vmx_vmcs_shadowing )
+        {
+            /* Report vmcs_region_size as 4096 */
+            data &= ~VMX_BASIC_VMCS_SIZE_MASK;
+            data |= 1ULL << 44;
+        }
+
         break;
     }
     case MSR_IA32_VMX_PINBASED_CTLS:
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH v3 8/8] x86/vvmx: fix I/O and MSR bitmaps mapping
  2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
                   ` (6 preceding siblings ...)
  2018-11-14 10:23 ` [PATCH v3 7/8] x86/vvmx: correctly report vvmcs size Sergey Dyasli
@ 2018-11-14 10:23 ` Sergey Dyasli
  7 siblings, 0 replies; 11+ messages in thread
From: Sergey Dyasli @ 2018-11-14 10:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Sergey Dyasli, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima

Currently Xen tries to map bitmaps during emulation of vmptrld and
vmwrite. This is wrong: a guest can store arbitrary values in those
fields.

Make bitmaps mapping happen only during a nested vmentry and only if
the appropriate execution controls are turned on by L1 hypervisor.

For performance reasons, Xen maps bitmaps only:

    1. During the first nested vmentry
    2. After L1 has changed an appropriate vmcs field
    3. After nvmx_purge_vvmcs() was previously called

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
---
v3:
- Added Acked-by

v2:
- slight commit message change
---
 xen/arch/x86/hvm/vmx/vvmx.c | 105 +++++++++++++++++++++++-------------
 1 file changed, 68 insertions(+), 37 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index 610236e3f2..88021af0e1 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -707,6 +707,17 @@ static void __clear_current_vvmcs(struct vcpu *v)
         __vmpclear(nvcpu->nv_n2vmcx_pa);
 }
 
+static void unmap_msr_bitmap(struct vcpu *v)
+{
+    struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
+
+    if ( nvmx->msrbitmap )
+    {
+        hvm_unmap_guest_frame(nvmx->msrbitmap, 1);
+        nvmx->msrbitmap = NULL;
+    }
+}
+
 /*
  * Refreshes the MSR bitmap mapping for the current nested vcpu.  Returns true
  * for a successful mapping, and returns false for MSR_BITMAP parameter errors
@@ -717,12 +728,7 @@ static bool __must_check _map_msr_bitmap(struct vcpu *v)
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
     uint64_t gpa;
 
-    if ( nvmx->msrbitmap )
-    {
-        hvm_unmap_guest_frame(nvmx->msrbitmap, 1);
-        nvmx->msrbitmap = NULL;
-    }
-
+    unmap_msr_bitmap(v);
     gpa = get_vvmcs(v, MSR_BITMAP);
 
     if ( !IS_ALIGNED(gpa, PAGE_SIZE) )
@@ -733,6 +739,17 @@ static bool __must_check _map_msr_bitmap(struct vcpu *v)
     return nvmx->msrbitmap != NULL;
 }
 
+static void unmap_io_bitmap(struct vcpu *v, unsigned int idx)
+{
+    struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
+
+    if ( nvmx->iobitmap[idx] )
+    {
+        hvm_unmap_guest_frame(nvmx->iobitmap[idx], 1);
+        nvmx->iobitmap[idx] = NULL;
+    }
+}
+
 static bool_t __must_check _map_io_bitmap(struct vcpu *v, u64 vmcs_reg)
 {
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
@@ -740,8 +757,7 @@ static bool_t __must_check _map_io_bitmap(struct vcpu *v, u64 vmcs_reg)
     int index;
 
     index = vmcs_reg == IO_BITMAP_A ? 0 : 1;
-    if (nvmx->iobitmap[index])
-        hvm_unmap_guest_frame(nvmx->iobitmap[index], 1);
+    unmap_io_bitmap(v, index);
     gpa = get_vvmcs(v, vmcs_reg);
     nvmx->iobitmap[index] = hvm_map_guest_frame_ro(gpa >> PAGE_SHIFT, 1);
 
@@ -756,7 +772,6 @@ static inline bool_t __must_check map_io_bitmap_all(struct vcpu *v)
 
 static void nvmx_purge_vvmcs(struct vcpu *v)
 {
-    struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
     struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
     int i;
 
@@ -766,16 +781,11 @@ static void nvmx_purge_vvmcs(struct vcpu *v)
     nvcpu->nv_vvmcx = NULL;
     nvcpu->nv_vvmcxaddr = INVALID_PADDR;
     v->arch.hvm.vmx.vmcs_shadow_maddr = 0;
-    for (i=0; i<2; i++) {
-        if ( nvmx->iobitmap[i] ) {
-            hvm_unmap_guest_frame(nvmx->iobitmap[i], 1);
-            nvmx->iobitmap[i] = NULL;
-        }
-    }
-    if ( nvmx->msrbitmap ) {
-        hvm_unmap_guest_frame(nvmx->msrbitmap, 1);
-        nvmx->msrbitmap = NULL;
-    }
+
+    for ( i = 0; i < 2; i++ )
+        unmap_io_bitmap(v, i);
+
+    unmap_msr_bitmap(v);
 }
 
 u64 nvmx_get_tsc_offset(struct vcpu *v)
@@ -1546,20 +1556,34 @@ static void clear_vvmcs_launched(struct list_head *launched_list,
     }
 }
 
-static int nvmx_vmresume(struct vcpu *v, struct cpu_user_regs *regs)
+static enum vmx_insn_errno nvmx_vmresume(struct vcpu *v)
 {
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
     struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+    unsigned int exec_ctrl;
 
-    /* check VMCS is valid and IO BITMAP is set */
-    if ( vvmcx_valid(v) &&
-            ((nvmx->iobitmap[0] && nvmx->iobitmap[1]) ||
-            !(__n2_exec_control(v) & CPU_BASED_ACTIVATE_IO_BITMAP) ) )
-        nvcpu->nv_vmentry_pending = 1;
-    else
-        vmfail_invalid(regs);
+    ASSERT(vvmcx_valid(v));
+    exec_ctrl = __n2_exec_control(v);
 
-    return X86EMUL_OKAY;
+    if ( exec_ctrl & CPU_BASED_ACTIVATE_IO_BITMAP )
+    {
+        if ( (nvmx->iobitmap[0] == NULL || nvmx->iobitmap[1] == NULL) &&
+             !map_io_bitmap_all(v) )
+            goto invalid_control_state;
+    }
+
+    if ( exec_ctrl & CPU_BASED_ACTIVATE_MSR_BITMAP )
+    {
+        if ( nvmx->msrbitmap == NULL && !_map_msr_bitmap(v) )
+            goto invalid_control_state;
+    }
+
+    nvcpu->nv_vmentry_pending = 1;
+
+    return VMX_INSN_SUCCEED;
+
+invalid_control_state:
+    return VMX_INSN_INVALID_CONTROL_STATE;
 }
 
 static int nvmx_handle_vmresume(struct cpu_user_regs *regs)
@@ -1568,6 +1592,7 @@ static int nvmx_handle_vmresume(struct cpu_user_regs *regs)
     struct vcpu *v = current;
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
     unsigned long intr_shadow;
+    int rc;
 
     if ( !vvmcx_valid(v) )
     {
@@ -1589,7 +1614,12 @@ static int nvmx_handle_vmresume(struct cpu_user_regs *regs)
         vmfail_valid(regs, VMX_INSN_VMRESUME_NONLAUNCHED_VMCS);
         return X86EMUL_OKAY;
     }
-    return nvmx_vmresume(v,regs);
+
+    rc = nvmx_vmresume(v);
+    if ( rc )
+        vmfail_valid(regs, rc);
+
+    return X86EMUL_OKAY;
 }
 
 static int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)
@@ -1621,13 +1651,16 @@ static int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)
         return X86EMUL_OKAY;
     }
     else {
-        rc = nvmx_vmresume(v,regs);
-        if ( rc == X86EMUL_OKAY )
+        rc = nvmx_vmresume(v);
+        if ( rc )
+            vmfail_valid(regs, rc);
+        else
         {
             if ( set_vvmcs_launched(&nvmx->launched_list,
                                     PFN_DOWN(v->arch.hvm.vmx.vmcs_shadow_maddr)) < 0 )
                 return X86EMUL_UNHANDLEABLE;
         }
+        rc = X86EMUL_OKAY;
     }
     return rc;
 }
@@ -1691,9 +1724,7 @@ static int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
                 vvmcx = NULL;
             }
         }
-        if ( !vvmcx ||
-             !map_io_bitmap_all(v) ||
-             !_map_msr_bitmap(v) )
+        else
         {
             vmfail(regs, VMX_INSN_VMPTRLD_INVALID_PHYADDR);
             goto out;
@@ -1869,13 +1900,13 @@ static int nvmx_handle_vmwrite(struct cpu_user_regs *regs)
     switch ( vmcs_encoding & ~VMCS_HIGH(0) )
     {
     case IO_BITMAP_A:
-        okay = _map_io_bitmap(v, IO_BITMAP_A);
+        unmap_io_bitmap(v, 0);
         break;
     case IO_BITMAP_B:
-        okay = _map_io_bitmap(v, IO_BITMAP_B);
+        unmap_io_bitmap(v, 1);
         break;
     case MSR_BITMAP:
-        okay = _map_msr_bitmap(v);
+        unmap_msr_bitmap(v);
         break;
     }
 
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise()
  2018-11-14 10:23 ` [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise() Sergey Dyasli
@ 2018-11-14 13:46   ` Jan Beulich
  2018-11-15  1:35   ` Tian, Kevin
  1 sibling, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2018-11-14 13:46 UTC (permalink / raw)
  To: Sergey Dyasli; +Cc: Andrew Cooper, Kevin Tian, Wei Liu, Jun Nakajima, xen-devel

>>> On 14.11.18 at 11:23, <sergey.dyasli@citrix.com> wrote:
> This allows to safely use nestedhvm functions that rely on the values
> inside struct nestedvcpu independently of the nested virtualisation
> (HVM_PARAM_NESTEDHVM) status of a domain.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>

> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise()
  2018-11-14 10:23 ` [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise() Sergey Dyasli
  2018-11-14 13:46   ` Jan Beulich
@ 2018-11-15  1:35   ` Tian, Kevin
  1 sibling, 0 replies; 11+ messages in thread
From: Tian, Kevin @ 2018-11-15  1:35 UTC (permalink / raw)
  To: Sergey Dyasli, xen-devel
  Cc: Andrew Cooper, Wei Liu, Nakajima, Jun, Jan Beulich

> From: Sergey Dyasli [mailto:sergey.dyasli@citrix.com]
> Sent: Wednesday, November 14, 2018 6:23 PM
> 
> This allows to safely use nestedhvm functions that rely on the values
> inside struct nestedvcpu independently of the nested virtualisation
> (HVM_PARAM_NESTEDHVM) status of a domain.
> 
> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>

Reviewed-by: Kevin Tian <kevin.tian@intel.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

end of thread, other threads:[~2018-11-15  1:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-14 10:23 [PATCH v3 0/8] x86/vvmx: various fixes Sergey Dyasli
2018-11-14 10:23 ` [PATCH v3 1/8] x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise() Sergey Dyasli
2018-11-14 13:46   ` Jan Beulich
2018-11-15  1:35   ` Tian, Kevin
2018-11-14 10:23 ` [PATCH v3 2/8] x86/nestedhvm: introduce vvmcx_valid() Sergey Dyasli
2018-11-14 10:23 ` [PATCH v3 3/8] x86/vvmx: add VMX_INSN_INVEPT_INVVPID_INVALID_OP errno Sergey Dyasli
2018-11-14 10:23 ` [PATCH v3 4/8] x86/vvmx: correct vmfail() usage for vmptrld and vmclear Sergey Dyasli
2018-11-14 10:23 ` [PATCH v3 5/8] x86/vvmx: add VMX_INSN_VMPTRLD_WITH_VMXON_PTR errno Sergey Dyasli
2018-11-14 10:23 ` [PATCH v3 6/8] x86/vvmx: refactor nvmx_handle_vmclear() Sergey Dyasli
2018-11-14 10:23 ` [PATCH v3 7/8] x86/vvmx: correctly report vvmcs size Sergey Dyasli
2018-11-14 10:23 ` [PATCH v3 8/8] x86/vvmx: fix I/O and MSR bitmaps mapping Sergey Dyasli

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.