# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1193910494 0
# Node ID 2a5461071ca4c9eb0a389d55ce511f73f8a9f29c
# Parent ba1b6f9d33f58ab6064fe6a5d6eddf5ddfbed295
x86, hvm: Fix stdvga and buffered-io code.
Corrected a bug in the stdvga code where it did not properly handle 32
bit operations. The buf_ioreq_t can now store 32 bits of data.
Signed-off-by: Robert Phillips <rphillips@xxxxxxxxxxxxxxx>
Signed-off-by: Ben Guthro <bguthro@xxxxxxxxxxxxxxx>
---
xen/arch/x86/hvm/intercept.c | 26 ++++++++++++++++----------
xen/arch/x86/hvm/stdvga.c | 6 ++++++
xen/include/public/hvm/ioreq.h | 6 +++---
3 files changed, 25 insertions(+), 13 deletions(-)
diff -r ba1b6f9d33f5 -r 2a5461071ca4 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Thu Nov 01 09:37:47 2007 +0000
+++ b/xen/arch/x86/hvm/intercept.c Thu Nov 01 09:48:14 2007 +0000
@@ -157,19 +157,26 @@ int hvm_buffered_io_send(ioreq_t *p)
struct hvm_ioreq_page *iorp = &v->domain->arch.hvm_domain.buf_ioreq;
buffered_iopage_t *pg = iorp->va;
buf_ioreq_t bp;
- /* Timeoffset sends 64b data, but no address. Use two consecutive slots.
*/
+ /* Timeoffset sends 64b data, but no address. Use two consecutive slots. */
int qw = 0;
/* Ensure buffered_iopage fits in a page */
BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE);
/* Return 0 for the cases we can't deal with. */
- if (p->addr > 0xffffful || p->data_is_ptr || p->df || p->count != 1)
+ if ( (p->addr > 0xffffful) || p->data_is_ptr || p->df || (p->count != 1) )
+ {
+ gdprintk(XENLOG_DEBUG, "slow ioreq. type:%d size:%ld addr:0x%08lx "
+ "dir:%d ptr:%d df:%d count:%ld\n",
+ p->type, p->size, p->addr, !!p->dir,
+ !!p->data_is_ptr, !!p->df, p->count);
return 0;
+ }
bp.type = p->type;
bp.dir = p->dir;
- switch (p->size) {
+ switch ( p->size )
+ {
case 1:
bp.size = 0;
break;
@@ -182,8 +189,6 @@ int hvm_buffered_io_send(ioreq_t *p)
case 8:
bp.size = 3;
qw = 1;
- gdprintk(XENLOG_INFO, "quadword ioreq type:%d data:%"PRIx64"\n",
- p->type, p->data);
break;
default:
gdprintk(XENLOG_WARNING, "unexpected ioreq size:%"PRId64"\n", p->size);
@@ -191,11 +196,12 @@ int hvm_buffered_io_send(ioreq_t *p)
}
bp.data = p->data;
- bp.addr = qw ? ((p->data >> 16) & 0xfffful) : (p->addr & 0xffffful);
+ bp.addr = p->addr;
spin_lock(&iorp->lock);
- if ( (pg->write_pointer - pg->read_pointer) >= IOREQ_BUFFER_SLOT_NUM - (qw
? 1 : 0))
+ if ( (pg->write_pointer - pg->read_pointer) >=
+ (IOREQ_BUFFER_SLOT_NUM - qw) )
{
/* The queue is full: send the iopacket through the normal path. */
spin_unlock(&iorp->lock);
@@ -205,9 +211,9 @@ int hvm_buffered_io_send(ioreq_t *p)
memcpy(&pg->buf_ioreq[pg->write_pointer % IOREQ_BUFFER_SLOT_NUM],
&bp, sizeof(bp));
- if (qw) {
+ if ( qw )
+ {
bp.data = p->data >> 32;
- bp.addr = (p->data >> 48) & 0xfffful;
memcpy(&pg->buf_ioreq[(pg->write_pointer+1) % IOREQ_BUFFER_SLOT_NUM],
&bp, sizeof(bp));
}
@@ -215,7 +221,7 @@ int hvm_buffered_io_send(ioreq_t *p)
/* Make the ioreq_t visible /before/ write_pointer. */
wmb();
pg->write_pointer += qw ? 2 : 1;
-
+
spin_unlock(&iorp->lock);
return 1;
diff -r ba1b6f9d33f5 -r 2a5461071ca4 xen/arch/x86/hvm/stdvga.c
--- a/xen/arch/x86/hvm/stdvga.c Thu Nov 01 09:37:47 2007 +0000
+++ b/xen/arch/x86/hvm/stdvga.c Thu Nov 01 09:48:14 2007 +0000
@@ -296,6 +296,8 @@ int stdvga_intercept_pio(ioreq_t *p)
{
if ( p->size != 1 )
gdprintk(XENLOG_WARNING, "unexpected io size:%d\n", (int)p->size);
+ if ( p->data_is_ptr )
+ gdprintk(XENLOG_WARNING, "unexpected data_is_ptr\n");
if ( !((p->addr == 0x3c5) && (s->sr_index >= sizeof(sr_mask))) &&
!((p->addr == 0x3cf) && (s->gr_index >= sizeof(gr_mask))) )
{
@@ -643,6 +645,10 @@ int stdvga_intercept_mmio(ioreq_t *p)
s->cache = 0;
}
}
+ else
+ {
+ buf = (p->dir == IOREQ_WRITE);
+ }
rc = (buf && hvm_buffered_io_send(p));
diff -r ba1b6f9d33f5 -r 2a5461071ca4 xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h Thu Nov 01 09:37:47 2007 +0000
+++ b/xen/include/public/hvm/ioreq.h Thu Nov 01 09:48:14 2007 +0000
@@ -80,9 +80,9 @@ struct buf_ioreq {
struct buf_ioreq {
uint8_t type; /* I/O type */
uint8_t dir:1; /* 1=read, 0=write */
- uint8_t size:2; /* 0=>1, 1=>2, 3=>8. If 8 then use two contig buf_ioreqs
*/
- uint16_t data; /* (low order) data */
- uint32_t addr; /* physical address or high-order data */
+ uint8_t size:2; /* 0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */
+ uint32_t addr:20;/* physical address */
+ uint32_t data; /* data */
};
typedef struct buf_ioreq buf_ioreq_t;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|