]> xenbits.xensource.com Git - xen.git/commitdiff
x86, hvm: I/O emulation handlers return X86EMUL_* return codes.
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 15 Apr 2008 12:28:02 +0000 (13:28 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 15 Apr 2008 12:28:02 +0000 (13:28 +0100)
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
13 files changed:
xen/arch/x86/hvm/emulate.c
xen/arch/x86/hvm/hpet.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/i8254.c
xen/arch/x86/hvm/intercept.c
xen/arch/x86/hvm/io.c
xen/arch/x86/hvm/pmtimer.c
xen/arch/x86/hvm/rtc.c
xen/arch/x86/hvm/stdvga.c
xen/arch/x86/hvm/vioapic.c
xen/arch/x86/hvm/vlapic.c
xen/arch/x86/hvm/vpic.c
xen/include/asm-x86/hvm/io.h

index 46aebf951b3453a822b7e162f3919284b5a9ed32..036583d90ce458a298d56401b9a676046d424f4f 100644 (file)
 #include <asm/hvm/support.h>
 
 static int hvmemul_do_io(
-    int is_mmio, paddr_t addr, unsigned long count, int size,
+    int is_mmio, paddr_t addr, unsigned long *reps, int size,
     paddr_t value, int dir, int df, int value_is_ptr, unsigned long *val)
 {
     struct vcpu *curr = current;
     vcpu_iodata_t *vio = get_ioreq(curr);
     ioreq_t *p = &vio->vp_ioreq;
+    int rc;
 
     switch ( curr->arch.hvm_vcpu.io_state )
     {
@@ -56,40 +57,58 @@ static int hvmemul_do_io(
     p->type = is_mmio ? IOREQ_TYPE_COPY : IOREQ_TYPE_PIO;
     p->size = size;
     p->addr = addr;
-    p->count = count;
+    p->count = *reps;
     p->df = df;
     p->data = value;
     p->io_count++;
 
-    if ( is_mmio
-         ? (hvm_mmio_intercept(p) || hvm_buffered_io_intercept(p))
-         : hvm_portio_intercept(p) )
+    if ( is_mmio )
+    {
+        rc = hvm_mmio_intercept(p);
+        if ( rc == X86EMUL_UNHANDLEABLE )
+            rc = hvm_buffered_io_intercept(p);
+    }
+    else
+    {
+        rc = hvm_portio_intercept(p);
+    }
+
+    switch ( rc )
     {
+    case X86EMUL_OKAY:
+        *reps = p->count;
         p->state = STATE_IORESP_READY;
         hvm_io_assist();
         if ( val != NULL )
             *val = curr->arch.hvm_vcpu.io_data;
         curr->arch.hvm_vcpu.io_state = HVMIO_none;
-        return X86EMUL_OKAY;
+        break;
+    case X86EMUL_UNHANDLEABLE:
+        hvm_send_assist_req(curr);
+        rc = (val != NULL) ? X86EMUL_RETRY : X86EMUL_OKAY;
+        break;
+    case X86EMUL_RETRY:
+        break;
+    default:
+        BUG();
     }
 
-    hvm_send_assist_req(curr);
-    return (val != NULL) ? X86EMUL_RETRY : X86EMUL_OKAY;
+    return rc;
 }
 
 static int hvmemul_do_pio(
-    unsigned long port, unsigned long count, int size,
+    unsigned long port, unsigned long *reps, int size,
     paddr_t value, int dir, int df, int value_is_ptr, unsigned long *val)
 {
-    return hvmemul_do_io(0, port, count, size, value,
+    return hvmemul_do_io(0, port, reps, size, value,
                          dir, df, value_is_ptr, val);
 }
 
 static int hvmemul_do_mmio(
-    paddr_t gpa, unsigned long count, int size,
+    paddr_t gpa, unsigned long *reps, int size,
     paddr_t value, int dir, int df, int value_is_ptr, unsigned long *val)
 {
-    return hvmemul_do_io(1, gpa, count, size, value,
+    return hvmemul_do_io(1, gpa, reps, size, value,
                          dir, df, value_is_ptr, val);
 }
 
@@ -209,7 +228,7 @@ static int __hvmemul_read(
     struct hvm_emulate_ctxt *hvmemul_ctxt)
 {
     struct vcpu *curr = current;
-    unsigned long addr;
+    unsigned long addr, reps = 1;
     uint32_t pfec = PFEC_page_present;
     paddr_t gpa;
     int rc;
@@ -229,7 +248,8 @@ static int __hvmemul_read(
             return X86EMUL_UNHANDLEABLE;
         gpa = (((paddr_t)curr->arch.hvm_vcpu.mmio_gpfn << PAGE_SHIFT) | off);
         if ( (off + bytes) <= PAGE_SIZE )
-            return hvmemul_do_mmio(gpa, 1, bytes, 0, IOREQ_READ, 0, 0, val);
+            return hvmemul_do_mmio(gpa, &reps, bytes, 0,
+                                   IOREQ_READ, 0, 0, val);
     }
 
     if ( (seg != x86_seg_none) &&
@@ -254,7 +274,7 @@ static int __hvmemul_read(
         if ( rc != X86EMUL_OKAY )
             return rc;
 
-        return hvmemul_do_mmio(gpa, 1, bytes, 0, IOREQ_READ, 0, 0, val);
+        return hvmemul_do_mmio(gpa, &reps, bytes, 0, IOREQ_READ, 0, 0, val);
     }
 
     return X86EMUL_OKAY;
@@ -305,7 +325,7 @@ static int hvmemul_write(
     struct hvm_emulate_ctxt *hvmemul_ctxt =
         container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
     struct vcpu *curr = current;
-    unsigned long addr;
+    unsigned long addr, reps = 1;
     uint32_t pfec = PFEC_page_present | PFEC_write_access;
     paddr_t gpa;
     int rc;
@@ -321,8 +341,8 @@ static int hvmemul_write(
         unsigned int off = addr & (PAGE_SIZE - 1);
         gpa = (((paddr_t)curr->arch.hvm_vcpu.mmio_gpfn << PAGE_SHIFT) | off);
         if ( (off + bytes) <= PAGE_SIZE )
-            return hvmemul_do_mmio(gpa, 1, bytes, val, IOREQ_WRITE,
-                                   0, 0, NULL);
+            return hvmemul_do_mmio(gpa, &reps, bytes, val,
+                                   IOREQ_WRITE, 0, 0, NULL);
     }
 
     if ( (seg != x86_seg_none) &&
@@ -342,7 +362,8 @@ static int hvmemul_write(
         if ( rc != X86EMUL_OKAY )
             return rc;
 
-        return hvmemul_do_mmio(gpa, 1, bytes, val, IOREQ_WRITE, 0, 0, NULL);
+        return hvmemul_do_mmio(gpa, &reps, bytes, val,
+                               IOREQ_WRITE, 0, 0, NULL);
     }
 
     return X86EMUL_OKAY;
@@ -389,7 +410,7 @@ static int hvmemul_rep_ins(
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    return hvmemul_do_pio(src_port, *reps, bytes_per_rep, gpa, IOREQ_READ,
+    return hvmemul_do_pio(src_port, reps, bytes_per_rep, gpa, IOREQ_READ,
                           !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1, NULL);
 }
 
@@ -422,7 +443,7 @@ static int hvmemul_rep_outs(
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    return hvmemul_do_pio(dst_port, *reps, bytes_per_rep, gpa, IOREQ_WRITE,
+    return hvmemul_do_pio(dst_port, reps, bytes_per_rep, gpa, IOREQ_WRITE,
                           !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1, NULL);
 }
 
@@ -472,14 +493,14 @@ static int hvmemul_rep_movs(
     (void)gfn_to_mfn_current(sgpa >> PAGE_SHIFT, &p2mt);
     if ( !p2m_is_ram(p2mt) )
         return hvmemul_do_mmio(
-            sgpa, *reps, bytes_per_rep, dgpa, IOREQ_READ,
+            sgpa, reps, bytes_per_rep, dgpa, IOREQ_READ,
             !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1, NULL);
 
     (void)gfn_to_mfn_current(dgpa >> PAGE_SHIFT, &p2mt);
     if ( p2m_is_ram(p2mt) )
         return X86EMUL_UNHANDLEABLE;
     return hvmemul_do_mmio(
-        dgpa, *reps, bytes_per_rep, sgpa, IOREQ_WRITE,
+        dgpa, reps, bytes_per_rep, sgpa, IOREQ_WRITE,
         !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1, NULL);
 }
 
@@ -516,7 +537,8 @@ static int hvmemul_read_io(
     unsigned long *val,
     struct x86_emulate_ctxt *ctxt)
 {
-    return hvmemul_do_pio(port, 1, bytes, 0, IOREQ_READ, 0, 0, val);
+    unsigned long reps = 1;
+    return hvmemul_do_pio(port, &reps, bytes, 0, IOREQ_READ, 0, 0, val);
 }
 
 static int hvmemul_write_io(
@@ -525,7 +547,8 @@ static int hvmemul_write_io(
     unsigned long val,
     struct x86_emulate_ctxt *ctxt)
 {
-    return hvmemul_do_pio(port, 1, bytes, val, IOREQ_WRITE, 0, 0, NULL);
+    unsigned long reps = 1;
+    return hvmemul_do_pio(port, &reps, bytes, val, IOREQ_WRITE, 0, 0, NULL);
 }
 
 static int hvmemul_read_cr(
index 49ca998d37edce30d50cf8a46a0ff76e06983684..03dfbf3bd823648e802c74aa96d6a1e514bfdffa 100644 (file)
@@ -150,8 +150,9 @@ static inline uint64_t hpet_read_maincounter(HPETState *h)
         return h->hpet.mc64;
 }
 
-static unsigned long hpet_read(
-    struct vcpu *v, unsigned long addr, unsigned long length)
+static int hpet_read(
+    struct vcpu *v, unsigned long addr, unsigned long length,
+    unsigned long *pval)
 {
     HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
     unsigned long result;
@@ -160,7 +161,10 @@ static unsigned long hpet_read(
     addr &= HPET_MMAP_SIZE-1;
 
     if ( hpet_check_access_length(addr, length) != 0 )
-        return ~0UL;
+    {
+        result = ~0ul;
+        goto out;
+    }
 
     spin_lock(&h->lock);
 
@@ -174,7 +178,9 @@ static unsigned long hpet_read(
 
     spin_unlock(&h->lock);
 
-    return result;
+ out:
+    *pval = result;
+    return X86EMUL_OKAY;
 }
 
 static void hpet_stop_timer(HPETState *h, unsigned int tn)
@@ -234,7 +240,7 @@ static inline uint64_t hpet_fixup_reg(
     return new;
 }
 
-static void hpet_write(
+static int hpet_write(
     struct vcpu *v, unsigned long addr,
     unsigned long length, unsigned long val)
 {
@@ -245,7 +251,7 @@ static void hpet_write(
     addr &= HPET_MMAP_SIZE-1;
 
     if ( hpet_check_access_length(addr, length) != 0 )
-        return;
+        goto out;
 
     spin_lock(&h->lock);
 
@@ -349,6 +355,9 @@ static void hpet_write(
     }
 
     spin_unlock(&h->lock);
+
+ out:
+    return X86EMUL_OKAY;
 }
 
 static int hpet_range(struct vcpu *v, unsigned long addr)
index 37307103469b740fcfc19743efc22208967d092c..74c8d43e41265adf73b870888af8bb7797759c04 100644 (file)
@@ -277,7 +277,7 @@ static int hvm_print_line(
     }
     spin_unlock(&hd->pbuf_lock);
 
-    return 1;
+    return X86EMUL_OKAY;
 }
 
 int hvm_domain_initialise(struct domain *d)
index 3cfd9dd47e2ba7d06c1f499870f6c033e464fbe6..493b7317b9ec8c5fb1cabecc65d72d88352976c6 100644 (file)
@@ -487,7 +487,7 @@ static int handle_pit_io(
     if ( bytes != 1 )
     {
         gdprintk(XENLOG_WARNING, "PIT bad access\n");
-        return 1;
+        return X86EMUL_OKAY;
     }
 
     if ( dir == IOREQ_WRITE )
@@ -502,7 +502,7 @@ static int handle_pit_io(
             gdprintk(XENLOG_WARNING, "PIT: read A1:A0=3!\n");
     }
 
-    return 1;
+    return X86EMUL_OKAY;
 }
 
 static void speaker_ioport_write(
@@ -526,11 +526,7 @@ static int handle_speaker_io(
 {
     struct PITState *vpit = vcpu_vpit(current);
 
-    if ( bytes != 1 )
-    {
-        gdprintk(XENLOG_WARNING, "PIT_SPEAKER bad access\n");
-        return 1;
-    }
+    BUG_ON(bytes != 1);
 
     spin_lock(&vpit->lock);
 
@@ -541,7 +537,7 @@ static int handle_speaker_io(
 
     spin_unlock(&vpit->lock);
 
-    return 1;
+    return X86EMUL_OKAY;
 }
 
 int pv_pit_handler(int port, int data, int write)
index 8084214d1fb60c433d1c3ce7fa6ea5368d560fa4..0e110e00dcbe6c833635f51415bec269b7baa4af 100644 (file)
@@ -45,53 +45,63 @@ static struct hvm_mmio_handler *hvm_mmio_handlers[HVM_MMIO_HANDLER_NR] =
     &vioapic_mmio_handler
 };
 
-static inline void hvm_mmio_access(struct vcpu *v,
-                                   ioreq_t *p,
-                                   hvm_mmio_read_t read_handler,
-                                   hvm_mmio_write_t write_handler)
+static int hvm_mmio_access(struct vcpu *v,
+                           ioreq_t *p,
+                           hvm_mmio_read_t read_handler,
+                           hvm_mmio_write_t write_handler)
 {
     unsigned long data;
+    int rc = X86EMUL_OKAY, i, sign = p->df ? -1 : 1;
 
     if ( !p->data_is_ptr )
     {
         if ( p->dir == IOREQ_READ )
-            p->data = read_handler(v, p->addr, p->size);
-        else    /* p->dir == IOREQ_WRITE */
-            write_handler(v, p->addr, p->size, p->data);
+        {
+            rc = read_handler(v, p->addr, p->size, &data);
+            p->data = data;
+        }
+        else /* p->dir == IOREQ_WRITE */
+            rc = write_handler(v, p->addr, p->size, p->data);
+        return rc;
     }
-    else
-    {
-        int i, sign = (p->df) ? -1 : 1;
 
-        if ( p->dir == IOREQ_READ )
+    if ( p->dir == IOREQ_READ )
+    {
+        for ( i = 0; i < p->count; i++ )
         {
-            for ( i = 0; i < p->count; i++ )
-            {
-                data = read_handler(
-                    v,
-                    p->addr + (sign * i * p->size),
-                    p->size);
-                (void)hvm_copy_to_guest_phys(
-                    p->data + (sign * i * p->size),
-                    &data,
-                    p->size);
-            }
+            rc = read_handler(
+                v,
+                p->addr + (sign * i * p->size),
+                p->size, &data);
+            if ( rc != X86EMUL_OKAY )
+                break;
+            (void)hvm_copy_to_guest_phys(
+                p->data + (sign * i * p->size),
+                &data,
+                p->size);
         }
-        else
+    }
+    else
+    {
+        for ( i = 0; i < p->count; i++ )
         {
-            for ( i = 0; i < p->count; i++ )
-            {
-                (void)hvm_copy_from_guest_phys(
-                    &data,
-                    p->data + (sign * i * p->size),
-                    p->size);
-                write_handler(
-                    v,
-                    p->addr + (sign * i * p->size),
-                    p->size, data);
-            }
+            (void)hvm_copy_from_guest_phys(
+                &data,
+                p->data + (sign * i * p->size),
+                p->size);
+            rc = write_handler(
+                v,
+                p->addr + (sign * i * p->size),
+                p->size, data);
+            if ( rc != X86EMUL_OKAY )
+                break;
         }
     }
+
+    if ( (p->count = i) != 0 )
+        rc = X86EMUL_OKAY;
+
+    return rc;
 }
 
 int hvm_mmio_intercept(ioreq_t *p)
@@ -100,60 +110,62 @@ int hvm_mmio_intercept(ioreq_t *p)
     int i;
 
     for ( i = 0; i < HVM_MMIO_HANDLER_NR; i++ )
-    {
         if ( hvm_mmio_handlers[i]->check_handler(v, p->addr) )
-        {
-            hvm_mmio_access(v, p,
-                            hvm_mmio_handlers[i]->read_handler,
-                            hvm_mmio_handlers[i]->write_handler);
-            return 1;
-        }
-    }
+            return hvm_mmio_access(
+                v, p,
+                hvm_mmio_handlers[i]->read_handler,
+                hvm_mmio_handlers[i]->write_handler);
 
-    return 0;
+    return X86EMUL_UNHANDLEABLE;
 }
 
 static int process_portio_intercept(portio_action_t action, ioreq_t *p)
 {
-    int rc = 1, i, sign = p->df ? -1 : 1;
+    int rc = X86EMUL_OKAY, i, sign = p->df ? -1 : 1;
     uint32_t data;
 
-    if ( p->dir == IOREQ_READ )
+    if ( !p->data_is_ptr )
     {
-        if ( !p->data_is_ptr )
+        if ( p->dir == IOREQ_READ )
         {
             rc = action(IOREQ_READ, p->addr, p->size, &data);
             p->data = data;
         }
         else
         {
-            for ( i = 0; i < p->count; i++ )
-            {
-                rc = action(IOREQ_READ, p->addr, p->size, &data);
-                (void)hvm_copy_to_guest_phys(p->data + sign*i*p->size,
-                                             &data, p->size);
-            }
+            data = p->data;
+            rc = action(IOREQ_WRITE, p->addr, p->size, &data);
         }
+        return rc;
     }
-    else /* p->dir == IOREQ_WRITE */
+
+    if ( p->dir == IOREQ_READ )
     {
-        if ( !p->data_is_ptr )
+        for ( i = 0; i < p->count; i++ )
         {
-            data = p->data;
-            rc = action(IOREQ_WRITE, p->addr, p->size, &data);
+            rc = action(IOREQ_READ, p->addr, p->size, &data);
+            if ( rc != X86EMUL_OKAY )
+                break;
+            (void)hvm_copy_to_guest_phys(p->data + sign*i*p->size,
+                                         &data, p->size);
         }
-        else
+    }
+    else /* p->dir == IOREQ_WRITE */
+    {
+        for ( i = 0; i < p->count; i++ )
         {
-            for ( i = 0; i < p->count; i++ )
-            {
-                data = 0;
-                (void)hvm_copy_from_guest_phys(&data, p->data + sign*i*p->size,
-                                               p->size);
-                rc = action(IOREQ_WRITE, p->addr, p->size, &data);
-            }
+            data = 0;
+            (void)hvm_copy_from_guest_phys(&data, p->data + sign*i*p->size,
+                                           p->size);
+            rc = action(IOREQ_WRITE, p->addr, p->size, &data);
+            if ( rc != X86EMUL_OKAY )
+                break;
         }
     }
 
+    if ( (p->count = i) != 0 )
+        rc = X86EMUL_OKAY;
+
     return rc;
 }
 
@@ -170,7 +182,7 @@ int hvm_io_intercept(ioreq_t *p, int type)
     unsigned long addr, size;
 
     if ( (type == HVM_PORTIO) && (dpci_ioport_intercept(p)) )
-        return 1;
+        return X86EMUL_OKAY;
 
     for ( i = 0; i < handler->num_slot; i++ )
     {
@@ -188,10 +200,10 @@ int hvm_io_intercept(ioreq_t *p, int type)
         }
     }
 
-    return 0;
+    return X86EMUL_UNHANDLEABLE;
 }
 
-int register_io_handler(
+void register_io_handler(
     struct domain *d, unsigned long addr, unsigned long size,
     void *action, int type)
 {
@@ -207,9 +219,8 @@ int register_io_handler(
     else
         handler->hdl_list[num].action.mmio = action;
     handler->num_slot++;
-
-    return 1;
 }
+
 /*
  * Local variables:
  * mode: C
index 9ff2958ca73a07ed4c14c960062b02ce4e63766c..6a8e0885c0757828035b74f5b3652dd8f9b79a56 100644 (file)
@@ -246,74 +246,59 @@ void hvm_io_assist(void)
 
 void dpci_ioport_read(uint32_t mport, ioreq_t *p)
 {
-    uint64_t i;
-    uint64_t z_data;
-    uint64_t length = (p->count * p->size);
+    int i, sign = p->df ? -1 : 1;
+    uint32_t data = 0;
 
-    for ( i = 0; i < length; i += p->size )
+    for ( i = 0; i < p->count; i++ )
     {
-        z_data = ~0ULL;
-        
         switch ( p->size )
         {
         case 1:
-            z_data = (uint64_t)inb(mport);
+            data = inb(mport);
             break;
         case 2:
-            z_data = (uint64_t)inw(mport);
+            data = inw(mport);
             break;
         case 4:
-            z_data = (uint64_t)inl(mport);
+            data = inl(mport);
             break;
         default:
-            gdprintk(XENLOG_ERR, "Error: unable to handle size: %"
-                     PRId64 "\n", p->size);
-            return;
+            BUG();
         }
 
-        p->data = z_data;
-        if ( p->data_is_ptr &&
-             hvm_copy_to_guest_phys(p->data + i, (void *)&z_data,
-                                    (int)p->size) )
-        {
-            gdprintk(XENLOG_ERR, "Error: couldn't copy to hvm phys\n");
-            return;
-        }
+        if ( p->data_is_ptr )
+            (void)hvm_copy_to_guest_phys(
+                p->data + (sign * i * p->size), &data, p->size);
+        else
+            p->data = data;
     }
 }
 
 void dpci_ioport_write(uint32_t mport, ioreq_t *p)
 {
-    uint64_t i;
-    uint64_t z_data = 0;
-    uint64_t length = (p->count * p->size);
+    int i, sign = p->df ? -1 : 1;
+    uint32_t data;
 
-    for ( i = 0; i < length; i += p->size )
+    for ( i = 0; i < p->count; i++ )
     {
-        z_data = p->data;
-        if ( p->data_is_ptr &&
-             hvm_copy_from_guest_phys((void *)&z_data,
-                                      p->data + i, (int)p->size) )
-        {
-            gdprintk(XENLOG_ERR, "Error: couldn't copy from hvm phys\n");
-            return;
-        }
+        data = p->data;
+        if ( p->data_is_ptr )
+            (void)hvm_copy_from_guest_phys(
+                &data, p->data + (sign * i & p->size), p->size);
 
         switch ( p->size )
         {
         case 1:
-            outb((uint8_t) z_data, mport);
+            outb(data, mport);
             break;
         case 2:
-            outw((uint16_t) z_data, mport);
+            outw(data, mport);
             break;
         case 4:
-            outl((uint32_t) z_data, mport);
+            outl(data, mport);
             break;
         default:
-            gdprintk(XENLOG_ERR, "Error: unable to handle size: %"
-                     PRId64 "\n", p->size);
-            break;
+            BUG();
         }
     }
 }
index 8d3fff8f446bc523cd9fe79cbf0d1c06e7227aaa..4924a8068767f4c0273fa166941f3de73b6802e7 100644 (file)
@@ -169,7 +169,7 @@ static int handle_evt_io(
 
     spin_unlock(&s->lock);
 
-    return 1;
+    return X86EMUL_OKAY;
 }
 
 
@@ -183,7 +183,7 @@ static int handle_pmt_io(
     if ( bytes != 4 )
     {
         gdprintk(XENLOG_WARNING, "HVM_PMT bad access\n");
-        return 1;
+        return X86EMUL_OKAY;
     }
     
     if ( dir == IOREQ_READ )
@@ -192,10 +192,10 @@ static int handle_pmt_io(
         pmt_update_time(s);
         *val = s->pm.tmr_val;
         spin_unlock(&s->lock);
-        return 1;
+        return X86EMUL_OKAY;
     }
 
-    return 0;
+    return X86EMUL_UNHANDLEABLE;
 }
 
 static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
index b9e4b4a2412d0b0d2efa8012d7cc794144ceb7ee..e196c728663ec62f76ff1343847b2b7d054f10db 100644 (file)
@@ -403,21 +403,21 @@ static int handle_rtc_io(
     if ( bytes != 1 )
     {
         gdprintk(XENLOG_WARNING, "HVM_RTC bas access\n");
-        return 1;
+        return X86EMUL_OKAY;
     }
     
     if ( dir == IOREQ_WRITE )
     {
         if ( rtc_ioport_write(vrtc, port, (uint8_t)*val) )
-            return 1;
+            return X86EMUL_OKAY;
     }
     else if ( vrtc->hw.cmos_index < RTC_CMOS_SIZE )
     {
         *val = rtc_ioport_read(vrtc, port);
-        return 1;
+        return X86EMUL_OKAY;
     }
 
-    return 0;
+    return X86EMUL_UNHANDLEABLE;
 }
 
 void rtc_migrate_timers(struct vcpu *v)
index 514444cc34279fe7cbe1a8139c318428d7fda4de..25b16bddacbb560fca67215f3fc56219d432d814 100644 (file)
@@ -167,19 +167,19 @@ static void stdvga_out(uint32_t port, uint32_t bytes, uint32_t val)
     }
 }
 
-int stdvga_intercept_pio(
+static int stdvga_intercept_pio(
     int dir, uint32_t port, uint32_t bytes, uint32_t *val)
 {
     struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
 
-    if ( dir == IOREQ_READ )
-        return 0;
-
-    spin_lock(&s->lock);
-    stdvga_out(port, bytes, *val);
-    spin_unlock(&s->lock);
+    if ( dir == IOREQ_WRITE )
+    {
+        spin_lock(&s->lock);
+        stdvga_out(port, bytes, *val);
+        spin_unlock(&s->lock);
+    }
 
-    return 0; /* propagate to external ioemu */
+    return X86EMUL_UNHANDLEABLE; /* propagate to external ioemu */
 }
 
 #define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
@@ -459,7 +459,7 @@ static int mmio_move(struct hvm_hw_stdvga *s, ioreq_t *p)
     return 1;
 }
 
-int stdvga_intercept_mmio(ioreq_t *p)
+static int stdvga_intercept_mmio(ioreq_t *p)
 {
     struct domain *d = current->domain;
     struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
@@ -468,7 +468,7 @@ int stdvga_intercept_mmio(ioreq_t *p)
     if ( p->size > 8 )
     {
         gdprintk(XENLOG_WARNING, "invalid mmio size %d\n", (int)p->size);
-        return 0;
+        return X86EMUL_UNHANDLEABLE;
     }
 
     spin_lock(&s->lock);
@@ -499,7 +499,7 @@ int stdvga_intercept_mmio(ioreq_t *p)
 
     spin_unlock(&s->lock);
 
-    return rc;
+    return rc ? X86EMUL_OKAY : X86EMUL_UNHANDLEABLE;
 }
 
 void stdvga_init(struct domain *d)
index fbdfe0c931da215fdb19ed24f8ceb8815b5a62e5..8ebaa260cf8e3b6bfe6806771f0ad091f3894886 100644 (file)
@@ -88,9 +88,9 @@ static unsigned long vioapic_read_indirect(struct hvm_hw_vioapic *vioapic,
     return result;
 }
 
-static unsigned long vioapic_read(struct vcpu *v,
-                                  unsigned long addr,
-                                  unsigned long length)
+static int vioapic_read(
+    struct vcpu *v, unsigned long addr,
+    unsigned long length, unsigned long *pval)
 {
     struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
     uint32_t result;
@@ -114,11 +114,13 @@ static unsigned long vioapic_read(struct vcpu *v,
         break;
     }
 
-    return result;
+    *pval = result;
+    return X86EMUL_OKAY;
 }
 
 static void vioapic_write_redirent(
-    struct hvm_hw_vioapic *vioapic, unsigned int idx, int top_word, uint32_t val)
+    struct hvm_hw_vioapic *vioapic, unsigned int idx,
+    int top_word, uint32_t val)
 {
     struct domain *d = vioapic_domain(vioapic);
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
@@ -196,10 +198,9 @@ static void vioapic_write_indirect(
     }
 }
 
-static void vioapic_write(struct vcpu *v,
-                          unsigned long addr,
-                          unsigned long length,
-                          unsigned long val)
+static int vioapic_write(
+    struct vcpu *v, unsigned long addr,
+    unsigned long length, unsigned long val)
 {
     struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
 
@@ -224,6 +225,8 @@ static void vioapic_write(struct vcpu *v,
     default:
         break;
     }
+
+    return X86EMUL_OKAY;
 }
 
 static int vioapic_range(struct vcpu *v, unsigned long addr)
index d66e3c26cf4b26dd2693fefcd7ab1b218343255b..424ee4dd5d7e224d0de4b93b47ce5323fa192e57 100644 (file)
@@ -466,17 +466,18 @@ static void vlapic_read_aligned(
     }
 }
 
-static unsigned long vlapic_read(struct vcpu *v, unsigned long address,
-                                 unsigned long len)
+static int vlapic_read(
+    struct vcpu *v, unsigned long address,
+    unsigned long len, unsigned long *pval)
 {
     unsigned int alignment;
     unsigned int tmp;
-    unsigned long result;
+    unsigned long result = 0;
     struct vlapic *vlapic = vcpu_vlapic(v);
     unsigned int offset = address - vlapic_base_address(vlapic);
 
     if ( offset > (APIC_TDCR + 0x3) )
-        return 0;
+        goto out;
 
     alignment = offset & 0x3;
 
@@ -508,14 +509,16 @@ static unsigned long vlapic_read(struct vcpu *v, unsigned long address,
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "offset 0x%x with length 0x%lx, "
                 "and the result is 0x%lx", offset, len, result);
 
-    return result;
+ out:
+    *pval = result;
+    return X86EMUL_OKAY;
 
  unaligned_exit_and_crash:
     gdprintk(XENLOG_ERR, "Unaligned LAPIC read len=0x%lx at offset=0x%x.\n",
              len, offset);
  exit_and_crash:
     domain_crash(v->domain);
-    return 0;
+    return X86EMUL_OKAY;
 }
 
 void vlapic_pt_cb(struct vcpu *v, void *data)
@@ -523,8 +526,8 @@ void vlapic_pt_cb(struct vcpu *v, void *data)
     *(s_time_t *)data = hvm_get_guest_time(v);
 }
 
-static void vlapic_write(struct vcpu *v, unsigned long address,
-                         unsigned long len, unsigned long val)
+static int vlapic_write(struct vcpu *v, unsigned long address,
+                        unsigned long len, unsigned long val)
 {
     struct vlapic *vlapic = vcpu_vlapic(v);
     unsigned int offset = address - vlapic_base_address(vlapic);
@@ -541,13 +544,13 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
     val = (uint32_t)val;
     if ( len != 4 )
     {
-        unsigned int tmp;
+        unsigned long tmp;
         unsigned char alignment;
 
         gdprintk(XENLOG_INFO, "Notice: Local APIC write with len = %lx\n",len);
 
         alignment = offset & 0x3;
-        tmp = vlapic_read(v, offset & ~0x3, 4);
+        (void)vlapic_read(v, offset & ~0x3, 4, &tmp);
 
         switch ( len )
         {
@@ -670,13 +673,14 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
         break;
     }
 
-    return;
+    return X86EMUL_OKAY;
 
  unaligned_exit_and_crash:
     gdprintk(XENLOG_ERR, "Unaligned LAPIC write len=0x%lx at offset=0x%x.\n",
              len, offset);
  exit_and_crash:
     domain_crash(v->domain);
+    return X86EMUL_OKAY;
 }
 
 static int vlapic_range(struct vcpu *v, unsigned long addr)
index f7bc2eb34f970735728ce56b74a5e64c8a8eefed..a3d6f2d9caeeb6ab0da2fbb64017ae5cd6e44f17 100644 (file)
@@ -319,7 +319,7 @@ static int vpic_intercept_pic_io(
     if ( bytes != 1 )
     {
         gdprintk(XENLOG_WARNING, "PIC_IO bad access size %d\n", bytes);
-        return 1;
+        return X86EMUL_OKAY;
     }
 
     vpic = &current->domain->arch.hvm_domain.vpic[port >> 7];
@@ -329,7 +329,7 @@ static int vpic_intercept_pic_io(
     else
         *val = (uint8_t)vpic_ioport_read(vpic, port);
 
-    return 1;
+    return X86EMUL_OKAY;
 }
 
 static int vpic_intercept_elcr_io(
@@ -338,11 +338,7 @@ static int vpic_intercept_elcr_io(
     struct hvm_hw_vpic *vpic;
     uint32_t data;
 
-    if ( bytes != 1 )
-    {
-        gdprintk(XENLOG_WARNING, "PIC_IO bad access size %d\n", bytes);
-        return 1;
-    }
+    BUG_ON(bytes != 1);
 
     vpic = &current->domain->arch.hvm_domain.vpic[port & 1];
 
@@ -360,7 +356,7 @@ static int vpic_intercept_elcr_io(
         *val = vpic->elcr & vpic_elcr_mask(vpic);
     }
 
-    return 1;
+    return X86EMUL_OKAY;
 }
 
 static int vpic_save(struct domain *d, hvm_domain_context_t *h)
index 9ef4f645a104970019a68e3e13f39b845f96e9aa..249fd2bcc388d91c58413cb8eddd017dfdca2ee6 100644 (file)
 #define HVM_PORTIO                  0
 #define HVM_BUFFERED_IO             2
 
-typedef unsigned long (*hvm_mmio_read_t)(struct vcpu *v,
-                                         unsigned long addr,
-                                         unsigned long length);
-typedef void (*hvm_mmio_write_t)(struct vcpu *v,
+typedef int (*hvm_mmio_read_t)(struct vcpu *v,
                                unsigned long addr,
                                unsigned long length,
-                               unsigned long val);
+                               unsigned long *val);
+typedef int (*hvm_mmio_write_t)(struct vcpu *v,
+                                unsigned long addr,
+                                unsigned long length,
+                                unsigned long val);
 typedef int (*hvm_mmio_check_t)(struct vcpu *v, unsigned long addr);
 
 typedef int (*portio_action_t)(
@@ -64,7 +65,7 @@ struct hvm_mmio_handler {
 };
 
 int hvm_io_intercept(ioreq_t *p, int type);
-int register_io_handler(
+void register_io_handler(
     struct domain *d, unsigned long addr, unsigned long size,
     void *action, int type);
 
@@ -81,18 +82,18 @@ static inline int hvm_buffered_io_intercept(ioreq_t *p)
 int hvm_mmio_intercept(ioreq_t *p);
 int hvm_buffered_io_send(ioreq_t *p);
 
-static inline int register_portio_handler(
+static inline void register_portio_handler(
     struct domain *d, unsigned long addr,
     unsigned long size, portio_action_t action)
 {
-    return register_io_handler(d, addr, size, action, HVM_PORTIO);
+    register_io_handler(d, addr, size, action, HVM_PORTIO);
 }
 
-static inline int register_buffered_io_handler(
+static inline void register_buffered_io_handler(
     struct domain *d, unsigned long addr,
     unsigned long size, mmio_action_t action)
 {
-    return register_io_handler(d, addr, size, action, HVM_BUFFERED_IO);
+    register_io_handler(d, addr, size, action, HVM_BUFFERED_IO);
 }
 
 void send_timeoffset_req(unsigned long timeoff);