xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] nested SVM: adjust guest handling of structure mappings
@ 2013-11-11  8:33 Jan Beulich
  2013-11-11 11:07 ` [PATCH v2] " Jan Beulich
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Beulich @ 2013-11-11  8:33 UTC (permalink / raw)
  To: xen-devel; +Cc: Boris Ostrovsky, Christoph Egger, suravee.suthikulpanit

[-- Attachment #1: Type: text/plain, Size: 3717 bytes --]

For one, nestedsvm_vmcb_map() error checking must not consist of using
assertions: Global (permanent) mappings can fail, and hence failure
needs to be dealt with properly. And non-global (transient) mappings
can't fail anyway.

And then the I/O port access bitmap handling was broken: It checked
only to first of the accessed ports rather than each of them.

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

--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -360,7 +360,6 @@ static int nsvm_vmrun_permissionmap(stru
     svm->ns_iomap_pa = ns_vmcb->_iopm_base_pa;
 
     ns_viomap = hvm_map_guest_frame_ro(svm->ns_iomap_pa >> PAGE_SHIFT, 0);
-    ASSERT(ns_viomap != NULL);
     ioport_80 = test_bit(0x80, ns_viomap);
     ioport_ed = test_bit(0xed, ns_viomap);
     hvm_unmap_guest_frame(ns_viomap, 0);
@@ -866,40 +865,45 @@ nsvm_vmcb_guest_intercepts_msr(unsigned 
 static int
 nsvm_vmcb_guest_intercepts_ioio(paddr_t iopm_pa, uint64_t exitinfo1)
 {
-    unsigned long iopm_gfn = iopm_pa >> PAGE_SHIFT;
-    unsigned long *io_bitmap = NULL;
+    unsigned long gfn = iopm_pa >> PAGE_SHIFT;
+    unsigned long *io_bitmap;
     ioio_info_t ioinfo;
     uint16_t port;
+    unsigned int size;
     bool_t enabled;
-    unsigned long gfn = 0; /* gcc ... */
 
     ioinfo.bytes = exitinfo1;
     port = ioinfo.fields.port;
+    size = ioinfo.fields.sz32 ? 4 : ioinfo.fields.sz16 ? 2 : 1;
 
-    switch (port) {
-    case 0 ... 32767: /* first 4KB page */
-        gfn = iopm_gfn;
+    switch ( port )
+    {
+    case 0 ... 8 * PAGE_SIZE - 1: /* first 4KB page */
         break;
-    case 32768 ... 65535: /* second 4KB page */
-        port -= 32768;
-        gfn = iopm_gfn + 1;
+    case 8 * PAGE_SIZE ... 2 * 8 * PAGE_SIZE - 1: /* second 4KB page */
+        port -= 8 * PAGE_SIZE;
+        ++gfn;
         break;
     default:
         BUG();
         break;
     }
 
-    io_bitmap = hvm_map_guest_frame_ro(gfn, 0);
-    if (io_bitmap == NULL) {
-        gdprintk(XENLOG_ERR,
-            "IOIO intercept: mapping of permission map failed\n");
-        return NESTEDHVM_VMEXIT_ERROR;
+    for ( io_bitmap = hvm_map_guest_frame_ro(gfn, 0); ; )
+    {
+        enabled = test_bit(port, io_bitmap);
+        if ( !enabled || !--size )
+            break;
+        if ( unlikely(++port == 8 * PAGE_SIZE) )
+        {
+            hvm_unmap_guest_frame(io_bitmap, 0);
+            io_bitmap = hvm_map_guest_frame_ro(++gfn, 0);
+            port -= 8 * PAGE_SIZE;
+        }
     }
-
-    enabled = test_bit(port, io_bitmap);
     hvm_unmap_guest_frame(io_bitmap, 0);
 
-    if (!enabled)
+    if ( !enabled )
         return NESTEDHVM_VMEXIT_HOST;
 
     return NESTEDHVM_VMEXIT_INJECT;
@@ -966,8 +970,8 @@ nsvm_vmcb_guest_intercepts_exitcode(stru
     switch (exitcode) {
     case VMEXIT_MSR:
         ASSERT(regs != NULL);
-        nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr);
-        ASSERT(nv->nv_vvmcx != NULL);
+        if ( !nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr) )
+            break;
         ns_vmcb = nv->nv_vvmcx;
         vmexits = nsvm_vmcb_guest_intercepts_msr(svm->ns_cached_msrpm,
             regs->ecx, ns_vmcb->exitinfo1 != 0);
@@ -975,8 +979,8 @@ nsvm_vmcb_guest_intercepts_exitcode(stru
             return 0;
         break;
     case VMEXIT_IOIO:
-        nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr);
-        ASSERT(nv->nv_vvmcx != NULL);
+        if ( !nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr) )
+            break;
         ns_vmcb = nv->nv_vvmcx;
         vmexits = nsvm_vmcb_guest_intercepts_ioio(ns_vmcb->_iopm_base_pa,
             ns_vmcb->exitinfo1);




[-- Attachment #2: nSVM-map-errors.patch --]
[-- Type: text/plain, Size: 3770 bytes --]

nested SVM: adjust guest handling of structure mappings

For one, nestedsvm_vmcb_map() error checking must not consist of using
assertions: Global (permanent) mappings can fail, and hence failure
needs to be dealt with properly. And non-global (transient) mappings
can't fail anyway.

And then the I/O port access bitmap handling was broken: It checked
only to first of the accessed ports rather than each of them.

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

--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -360,7 +360,6 @@ static int nsvm_vmrun_permissionmap(stru
     svm->ns_iomap_pa = ns_vmcb->_iopm_base_pa;
 
     ns_viomap = hvm_map_guest_frame_ro(svm->ns_iomap_pa >> PAGE_SHIFT, 0);
-    ASSERT(ns_viomap != NULL);
     ioport_80 = test_bit(0x80, ns_viomap);
     ioport_ed = test_bit(0xed, ns_viomap);
     hvm_unmap_guest_frame(ns_viomap, 0);
@@ -866,40 +865,45 @@ nsvm_vmcb_guest_intercepts_msr(unsigned 
 static int
 nsvm_vmcb_guest_intercepts_ioio(paddr_t iopm_pa, uint64_t exitinfo1)
 {
-    unsigned long iopm_gfn = iopm_pa >> PAGE_SHIFT;
-    unsigned long *io_bitmap = NULL;
+    unsigned long gfn = iopm_pa >> PAGE_SHIFT;
+    unsigned long *io_bitmap;
     ioio_info_t ioinfo;
     uint16_t port;
+    unsigned int size;
     bool_t enabled;
-    unsigned long gfn = 0; /* gcc ... */
 
     ioinfo.bytes = exitinfo1;
     port = ioinfo.fields.port;
+    size = ioinfo.fields.sz32 ? 4 : ioinfo.fields.sz16 ? 2 : 1;
 
-    switch (port) {
-    case 0 ... 32767: /* first 4KB page */
-        gfn = iopm_gfn;
+    switch ( port )
+    {
+    case 0 ... 8 * PAGE_SIZE - 1: /* first 4KB page */
         break;
-    case 32768 ... 65535: /* second 4KB page */
-        port -= 32768;
-        gfn = iopm_gfn + 1;
+    case 8 * PAGE_SIZE ... 2 * 8 * PAGE_SIZE - 1: /* second 4KB page */
+        port -= 8 * PAGE_SIZE;
+        ++gfn;
         break;
     default:
         BUG();
         break;
     }
 
-    io_bitmap = hvm_map_guest_frame_ro(gfn, 0);
-    if (io_bitmap == NULL) {
-        gdprintk(XENLOG_ERR,
-            "IOIO intercept: mapping of permission map failed\n");
-        return NESTEDHVM_VMEXIT_ERROR;
+    for ( io_bitmap = hvm_map_guest_frame_ro(gfn, 0); ; )
+    {
+        enabled = test_bit(port, io_bitmap);
+        if ( !enabled || !--size )
+            break;
+        if ( unlikely(++port == 8 * PAGE_SIZE) )
+        {
+            hvm_unmap_guest_frame(io_bitmap, 0);
+            io_bitmap = hvm_map_guest_frame_ro(++gfn, 0);
+            port -= 8 * PAGE_SIZE;
+        }
     }
-
-    enabled = test_bit(port, io_bitmap);
     hvm_unmap_guest_frame(io_bitmap, 0);
 
-    if (!enabled)
+    if ( !enabled )
         return NESTEDHVM_VMEXIT_HOST;
 
     return NESTEDHVM_VMEXIT_INJECT;
@@ -966,8 +970,8 @@ nsvm_vmcb_guest_intercepts_exitcode(stru
     switch (exitcode) {
     case VMEXIT_MSR:
         ASSERT(regs != NULL);
-        nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr);
-        ASSERT(nv->nv_vvmcx != NULL);
+        if ( !nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr) )
+            break;
         ns_vmcb = nv->nv_vvmcx;
         vmexits = nsvm_vmcb_guest_intercepts_msr(svm->ns_cached_msrpm,
             regs->ecx, ns_vmcb->exitinfo1 != 0);
@@ -975,8 +979,8 @@ nsvm_vmcb_guest_intercepts_exitcode(stru
             return 0;
         break;
     case VMEXIT_IOIO:
-        nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr);
-        ASSERT(nv->nv_vvmcx != NULL);
+        if ( !nestedsvm_vmcb_map(v, nv->nv_vvmcxaddr) )
+            break;
         ns_vmcb = nv->nv_vvmcx;
         vmexits = nsvm_vmcb_guest_intercepts_ioio(ns_vmcb->_iopm_base_pa,
             ns_vmcb->exitinfo1);

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

end of thread, other threads:[~2013-11-12  3:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-11  8:33 [PATCH] nested SVM: adjust guest handling of structure mappings Jan Beulich
2013-11-11 11:07 ` [PATCH v2] " Jan Beulich
2013-11-11 11:25   ` Andrew Cooper
2013-11-11 12:29     ` Jan Beulich
2013-11-11 12:53     ` [PATCH v3] " Jan Beulich
2013-11-11 13:16       ` Andrew Cooper
2013-11-11 13:35         ` Jan Beulich
2013-11-11 14:40           ` Andrew Cooper
2013-11-11 13:22       ` Egger, Christoph
2013-11-12  3:57       ` Suravee Suthikulpanit

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