aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-04-15 13:28:02 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-04-15 13:28:02 +0100
commit6742db6e6819687ab311199bfe76476947ed75ed (patch)
tree3736ca574aebcce589b9769d62aeb96bc19b0176 /xen/arch
parentef3c86eb818614eb5a4bdd7c0c82b1e1346dd60e (diff)
downloadxen-6742db6e6819687ab311199bfe76476947ed75ed.tar.gz
xen-6742db6e6819687ab311199bfe76476947ed75ed.tar.bz2
xen-6742db6e6819687ab311199bfe76476947ed75ed.zip
x86, hvm: I/O emulation handlers return X86EMUL_* return codes.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch')
-rw-r--r--xen/arch/x86/hvm/emulate.c73
-rw-r--r--xen/arch/x86/hvm/hpet.c21
-rw-r--r--xen/arch/x86/hvm/hvm.c2
-rw-r--r--xen/arch/x86/hvm/i8254.c12
-rw-r--r--xen/arch/x86/hvm/intercept.c149
-rw-r--r--xen/arch/x86/hvm/io.c61
-rw-r--r--xen/arch/x86/hvm/pmtimer.c8
-rw-r--r--xen/arch/x86/hvm/rtc.c8
-rw-r--r--xen/arch/x86/hvm/stdvga.c22
-rw-r--r--xen/arch/x86/hvm/vioapic.c21
-rw-r--r--xen/arch/x86/hvm/vlapic.c26
-rw-r--r--xen/arch/x86/hvm/vpic.c12
12 files changed, 221 insertions, 194 deletions
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 46aebf951b..036583d90c 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -20,12 +20,13 @@
#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(
diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c
index 49ca998d37..03dfbf3bd8 100644
--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -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)
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 3730710346..74c8d43e41 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -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)
diff --git a/xen/arch/x86/hvm/i8254.c b/xen/arch/x86/hvm/i8254.c
index 3cfd9dd47e..493b7317b9 100644
--- a/xen/arch/x86/hvm/i8254.c
+++ b/xen/arch/x86/hvm/i8254.c
@@ -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)
diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c
index 8084214d1f..0e110e00dc 100644
--- a/xen/arch/x86/hvm/intercept.c
+++ b/xen/arch/x86/hvm/intercept.c
@@ -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
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 9ff2958ca7..6a8e0885c0 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -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();
}
}
}
diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c
index 8d3fff8f44..4924a80687 100644
--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -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)
diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c
index b9e4b4a241..e196c72866 100644
--- a/xen/arch/x86/hvm/rtc.c
+++ b/xen/arch/x86/hvm/rtc.c
@@ -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)
diff --git a/xen/arch/x86/hvm/stdvga.c b/xen/arch/x86/hvm/stdvga.c
index 514444cc34..25b16bddac 100644
--- a/xen/arch/x86/hvm/stdvga.c
+++ b/xen/arch/x86/hvm/stdvga.c
@@ -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)
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index fbdfe0c931..8ebaa260cf 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -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)
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index d66e3c26cf..424ee4dd5d 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -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)
diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c
index f7bc2eb34f..a3d6f2d9ca 100644
--- a/xen/arch/x86/hvm/vpic.c
+++ b/xen/arch/x86/hvm/vpic.c
@@ -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)