[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86/HVM: don't leak PFEC_implict to guests



commit b706e1c6af274fc1914884b3da5af27221f1e818
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri Apr 7 12:08:34 2017 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Apr 7 12:08:34 2017 +0200

    x86/HVM: don't leak PFEC_implict to guests
    
    Doing so may not only confuse them, but will - on VMX - lead to
    VMRESUME failures. Add respective ASSERT()s where the fields get set
    to guard against future similar issues (or - in the restore case -
    fail the operation). In that latter code at once convert the mis-used
    gdprintk() to dprintk(), as the vCPU of interest is not "current".
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
    Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c     |  2 +-
 xen/arch/x86/hvm/svm/svm.c | 24 ++++++++++++++++++------
 xen/arch/x86/hvm/vmx/vmx.c | 23 +++++++++++++++++------
 3 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 4dfdb83..8c423f8 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3126,7 +3126,7 @@ static enum hvm_copy_result __hvm_copy(
                 if ( pfinfo )
                 {
                     pfinfo->linear = addr;
-                    pfinfo->ec = pfec;
+                    pfinfo->ec = pfec & ~PFEC_implicit;
                 }
                 return HVMCOPY_bad_gva_to_gfn;
             }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 1ffe5c3..2f0b542 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -269,13 +269,23 @@ static int svm_vmcb_restore(struct vcpu *v, struct 
hvm_hw_cpu *c)
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
 
-    if ( c->pending_valid &&
-         ((c->pending_type == 1) || (c->pending_type > 6) ||
-          (c->pending_reserved != 0)) )
+    if ( c->pending_valid )
     {
-        gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n",
-                 c->pending_event);
-        return -EINVAL;
+       if ( (c->pending_type == 1) || (c->pending_type > 6) ||
+            (c->pending_reserved != 0) )
+        {
+            dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32"\n",
+                    v, c->pending_event);
+            return -EINVAL;
+        }
+
+        if ( c->pending_error_valid &&
+             c->error_code != (uint16_t)c->error_code )
+        {
+            dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32"\n",
+                    v, c->error_code);
+            return -EINVAL;
+        }
     }
 
     if ( !paging_mode_hap(v->domain) )
@@ -1421,6 +1431,8 @@ static void svm_inject_event(const struct x86_event 
*event)
         vmcb->nextrip = (uint32_t)vmcb->nextrip;
     }
 
+    ASSERT(!eventinj.fields.ev ||
+           eventinj.fields.errorcode == (uint16_t)eventinj.fields.errorcode);
     vmcb->eventinj = eventinj;
 
     if ( _event.vector == TRAP_page_fault )
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index b6526c9..36d2aaa 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -731,13 +731,23 @@ static int vmx_vmcs_restore(struct vcpu *v, struct 
hvm_hw_cpu *c)
 {
     int rc;
 
-    if ( c->pending_valid &&
-         ((c->pending_type == 1) || (c->pending_type > 6) ||
-          (c->pending_reserved != 0)) )
+    if ( c->pending_valid )
     {
-        gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n",
-                 c->pending_event);
-        return -EINVAL;
+        if ( (c->pending_type == 1) || (c->pending_type > 6) ||
+             (c->pending_reserved != 0) )
+        {
+            dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32"\n",
+                    v, c->pending_event);
+            return -EINVAL;
+        }
+
+        if ( c->pending_error_valid &&
+             c->error_code != (uint16_t)c->error_code )
+        {
+            dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32"\n",
+                    v, c->error_code);
+            return -EINVAL;
+        }
     }
 
     rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3);
@@ -1660,6 +1670,7 @@ static void __vmx_inject_exception(int trap, int type, 
int error_code)
                   MASK_INSR(trap, INTR_INFO_VECTOR_MASK);
     if ( error_code != X86_EVENT_NO_EC )
     {
+        ASSERT(error_code == (uint16_t)error_code);
         __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
         intr_fields |= INTR_INFO_DELIVER_CODE_MASK;
     }
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.