[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86, hvm: Fix stdvga and buffered-io code.



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.