Skip to contentSkip to conversation

xen: cleanup hvm io

PATCH New Christoph Egger 1 participant 1 message Oct 25, 2011

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 xen: cleanup hvm io

Move HVM io fields into a structure.
On MMIO instruction failure print out some more bytes.

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
xen/arch/x86/hvm/emulate.c +36 -34
diff -r 0f95fb74e19d xen/arch/x86/hvm/emulate.c
@@ -56,6 +56,7 @@ static int hvmemul_do_io(
     paddr_t value = ram_gpa;
     int value_is_ptr = (p_data == NULL);
     struct vcpu *curr = current;
+    struct hvm_vcpu_io *vio;
     ioreq_t *p = get_ioreq(curr);
     unsigned long ram_gfn = paddr_to_pfn(ram_gpa);
     p2m_type_t p2mt;
@@ -91,43 +92,45 @@ static int hvmemul_do_io(
         p_data = NULL;
     }
 
+    vio = &curr->arch.hvm_vcpu.hvm_io;
+
     if ( is_mmio && !value_is_ptr )
     {
         /* Part of a multi-cycle read or write? */
         if ( dir == IOREQ_WRITE )
         {
-            paddr_t pa = curr->arch.hvm_vcpu.mmio_large_write_pa;
-            unsigned int bytes = curr->arch.hvm_vcpu.mmio_large_write_bytes;
+            paddr_t pa = vio->mmio_large_write_pa;
+            unsigned int bytes = vio->mmio_large_write_bytes;
             if ( (addr >= pa) && ((addr + size) <= (pa + bytes)) )
                 return X86EMUL_OKAY;
         }
         else
         {
-            paddr_t pa = curr->arch.hvm_vcpu.mmio_large_read_pa;
-            unsigned int bytes = curr->arch.hvm_vcpu.mmio_large_read_bytes;
+            paddr_t pa = vio->mmio_large_read_pa;
+            unsigned int bytes = vio->mmio_large_read_bytes;
             if ( (addr >= pa) && ((addr + size) <= (pa + bytes)) )
             {
-                memcpy(p_data, &curr->arch.hvm_vcpu.mmio_large_read[addr - pa],
+                memcpy(p_data, &vio->mmio_large_read[addr - pa],
                        size);
                 return X86EMUL_OKAY;
             }
         }
     }
 
-    switch ( curr->arch.hvm_vcpu.io_state )
+    switch ( vio->io_state )
     {
     case HVMIO_none:
         break;
     case HVMIO_completed:
-        curr->arch.hvm_vcpu.io_state = HVMIO_none;
+        vio->io_state = HVMIO_none;
         if ( p_data == NULL )
             return X86EMUL_UNHANDLEABLE;
         goto finish_access;
     case HVMIO_dispatched:
         /* May have to wait for previous cycle of a multi-write to complete. */
         if ( is_mmio && !value_is_ptr && (dir == IOREQ_WRITE) &&
-             (addr == (curr->arch.hvm_vcpu.mmio_large_write_pa +
-                       curr->arch.hvm_vcpu.mmio_large_write_bytes)) )
+             (addr == (vio->mmio_large_write_pa +
+                       vio->mmio_large_write_bytes)) )
             return X86EMUL_RETRY;
     default:
         return X86EMUL_UNHANDLEABLE;
@@ -140,9 +143,9 @@ static int hvmemul_do_io(
         return X86EMUL_UNHANDLEABLE;
     }
 
-    curr->arch.hvm_vcpu.io_state =
+    vio->io_state =
         (p_data == NULL) ? HVMIO_dispatched : HVMIO_awaiting_completion;
-    curr->arch.hvm_vcpu.io_size = size;
+    vio->io_size = size;
 
     p->dir = dir;
     p->data_is_ptr = value_is_ptr;
@@ -173,12 +176,12 @@ static int hvmemul_do_io(
         *reps = p->count;
         p->state = STATE_IORESP_READY;
         hvm_io_assist();
-        curr->arch.hvm_vcpu.io_state = HVMIO_none;
+        vio->io_state = HVMIO_none;
         break;
     case X86EMUL_UNHANDLEABLE:
         rc = X86EMUL_RETRY;
         if ( !hvm_send_assist_req(curr) )
-            curr->arch.hvm_vcpu.io_state = HVMIO_none;
+            vio->io_state = HVMIO_none;
         else if ( p_data == NULL )
             rc = X86EMUL_OKAY;
         break;
@@ -191,33 +194,32 @@ static int hvmemul_do_io(
 
  finish_access:
     if ( p_data != NULL )
-        memcpy(p_data, &curr->arch.hvm_vcpu.io_data, size);
+        memcpy(p_data, &vio->io_data, size);
 
     if ( is_mmio && !value_is_ptr )
     {
         /* Part of a multi-cycle read or write? */
         if ( dir == IOREQ_WRITE )
         {
-            paddr_t pa = curr->arch.hvm_vcpu.mmio_large_write_pa;
-            unsigned int bytes = curr->arch.hvm_vcpu.mmio_large_write_bytes;
+            paddr_t pa = vio->mmio_large_write_pa;
+            unsigned int bytes = vio->mmio_large_write_bytes;
             if ( bytes == 0 )
-                pa = curr->arch.hvm_vcpu.mmio_large_write_pa = addr;
+                pa = vio->mmio_large_write_pa = addr;
             if ( addr == (pa + bytes) )
-                curr->arch.hvm_vcpu.mmio_large_write_bytes += size;
+                vio->mmio_large_write_bytes += size;
         }
         else
         {
-            paddr_t pa = curr->arch.hvm_vcpu.mmio_large_read_pa;
-            unsigned int bytes = curr->arch.hvm_vcpu.mmio_large_read_bytes;
+            paddr_t pa = vio->mmio_large_read_pa;
+            unsigned int bytes = vio->mmio_large_read_bytes;
             if ( bytes == 0 )
-                pa = curr->arch.hvm_vcpu.mmio_large_read_pa = addr;
+                pa = vio->mmio_large_read_pa = addr;
             if ( (addr == (pa + bytes)) &&
                  ((bytes + size) <
-                  sizeof(curr->arch.hvm_vcpu.mmio_large_read)) )
+                  sizeof(vio->mmio_large_read)) )
             {
-                memcpy(&curr->arch.hvm_vcpu.mmio_large_read[addr - pa],
-                       p_data, size);
-                curr->arch.hvm_vcpu.mmio_large_read_bytes += size;
+                memcpy(&vio->mmio_large_read[addr - pa], p_data, size);
+                vio->mmio_large_read_bytes += size;
             }
         }
     }
@@ -401,6 +403,7 @@ static int __hvmemul_read(
     struct vcpu *curr = current;
     unsigned long addr, reps = 1;
     uint32_t pfec = PFEC_page_present;
+    struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
     paddr_t gpa;
     int rc;
 
@@ -409,13 +412,12 @@ static int __hvmemul_read(
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    if ( unlikely(curr->arch.hvm_vcpu.mmio_gva == (addr & PAGE_MASK)) &&
-         curr->arch.hvm_vcpu.mmio_gva )
+    if ( unlikely(vio->mmio_gva == (addr & PAGE_MASK)) && vio->mmio_gva )
     {
         unsigned int off = addr & (PAGE_SIZE - 1);
         if ( access_type == hvm_access_insn_fetch )
             return X86EMUL_UNHANDLEABLE;
-        gpa = (((paddr_t)curr->arch.hvm_vcpu.mmio_gpfn << PAGE_SHIFT) | off);
+        gpa = (((paddr_t)vio->mmio_gpfn << PAGE_SHIFT) | off);
         if ( (off + bytes) <= PAGE_SIZE )
             return hvmemul_do_mmio(gpa, &reps, bytes, 0,
                                    IOREQ_READ, 0, p_data);
@@ -500,6 +502,7 @@ static int hvmemul_write(
     struct vcpu *curr = current;
     unsigned long addr, reps = 1;
     uint32_t pfec = PFEC_page_present | PFEC_write_access;
+    struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
     paddr_t gpa;
     int rc;
 
@@ -508,11 +511,10 @@ static int hvmemul_write(
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    if ( unlikely(curr->arch.hvm_vcpu.mmio_gva == (addr & PAGE_MASK)) &&
-         curr->arch.hvm_vcpu.mmio_gva )
+    if ( unlikely(vio->mmio_gva == (addr & PAGE_MASK)) && vio->mmio_gva )
     {
         unsigned int off = addr & (PAGE_SIZE - 1);
-        gpa = (((paddr_t)curr->arch.hvm_vcpu.mmio_gpfn << PAGE_SHIFT) | off);
+        gpa = (((paddr_t)vio->mmio_gpfn << PAGE_SHIFT) | off);
         if ( (off + bytes) <= PAGE_SIZE )
             return hvmemul_do_mmio(gpa, &reps, bytes, 0,
                                    IOREQ_WRITE, 0, p_data);
@@ -530,7 +532,7 @@ static int hvmemul_write(
         return X86EMUL_EXCEPTION;
     case HVMCOPY_unhandleable:
         return X86EMUL_UNHANDLEABLE;
-    case  HVMCOPY_bad_gfn_to_mfn:
+    case HVMCOPY_bad_gfn_to_mfn:
         rc = hvmemul_linear_to_phys(
             addr, &gpa, bytes, &reps, pfec, hvmemul_ctxt);
         if ( rc != X86EMUL_OKAY )
@@ -1011,6 +1013,7 @@ int hvm_emulate_one(
     struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs;
     struct vcpu *curr = current;
     uint32_t new_intr_shadow, pfec = PFEC_page_present;
+    struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
     unsigned long addr;
     int rc;
 
@@ -1048,8 +1051,7 @@ int hvm_emulate_one(
     rc = x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops);
 
     if ( rc != X86EMUL_RETRY )
-        curr->arch.hvm_vcpu.mmio_large_read_bytes =
-            curr->arch.hvm_vcpu.mmio_large_write_bytes = 0;
+        vio->mmio_large_read_bytes = vio->mmio_large_write_bytes = 0;
 
     if ( rc != X86EMUL_OKAY )
         return rc;
xen/arch/x86/hvm/io.c +23 -18

109 lines not on this page · raw message

xen/arch/x86/hvm/svm/nestedsvm.c +1 -1
diff -r 0f95fb74e19d xen/arch/x86/hvm/svm/nestedsvm.c
@@ -1168,7 +1168,7 @@ enum hvm_intblk nsvm_intr_blocked(struct
          * Delay the injection because this would result in delivering
          * an interrupt *within* the execution of an instruction.
          */
-        if ( v->arch.hvm_vcpu.io_state != HVMIO_none )
+        if ( v->arch.hvm_vcpu.hvm_io.io_state != HVMIO_none )
             return hvm_intblk_shadow;
     }
 
xen/arch/x86/hvm/vmx/realmode.c +4 -3
diff -r 0f95fb74e19d xen/arch/x86/hvm/vmx/realmode.c
@@ -172,6 +172,7 @@ void vmx_realmode(struct cpu_user_regs *
     struct vcpu *curr = current;
     struct hvm_emulate_ctxt hvmemul_ctxt;
     struct segment_register *sreg;
+    struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
     unsigned long intr_info;
     unsigned int emulations = 0;
 
@@ -182,7 +183,7 @@ void vmx_realmode(struct cpu_user_regs *
 
     hvm_emulate_prepare(&hvmemul_ctxt, regs);
 
-    if ( curr->arch.hvm_vcpu.io_state == HVMIO_completed )
+    if ( vio->io_state == HVMIO_completed )
         realmode_emulate_one(&hvmemul_ctxt);
 
     /* Only deliver interrupts into emulated real mode. */
@@ -196,7 +197,7 @@ void vmx_realmode(struct cpu_user_regs *
     curr->arch.hvm_vmx.vmx_emulate = 1;
     while ( curr->arch.hvm_vmx.vmx_emulate &&
             !softirq_pending(smp_processor_id()) &&
-            (curr->arch.hvm_vcpu.io_state == HVMIO_none) )
+            (vio->io_state == HVMIO_none) )
     {
         /*
          * Check for pending interrupts only every 16 instructions, because
@@ -221,7 +222,7 @@ void vmx_realmode(struct cpu_user_regs *
     }
 
     /* Need to emulate next time if we've started an IO operation */
-    if ( curr->arch.hvm_vcpu.io_state != HVMIO_none )
+    if ( vio->io_state != HVMIO_none )
         curr->arch.hvm_vmx.vmx_emulate = 1;
 
     if ( !curr->arch.hvm_vmx.vmx_emulate && !curr->arch.hvm_vmx.vmx_realmode )
xen/include/asm-x86/hvm/vcpu.h +25 -21

62 lines not on this page · raw message

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel