ia64/xen-unstable

changeset 16297:2a5461071ca4

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@virtualiron.com>
Signed-off-by: Ben Guthro <bguthro@virtualiron.com>
author Keir Fraser <keir@xensource.com>
date Thu Nov 01 09:48:14 2007 +0000 (2007-11-01)
parents ba1b6f9d33f5
children adefbadab27c
files xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/stdvga.c xen/include/public/hvm/ioreq.h
line diff
     1.1 --- a/xen/arch/x86/hvm/intercept.c	Thu Nov 01 09:37:47 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/intercept.c	Thu Nov 01 09:48:14 2007 +0000
     1.3 @@ -157,19 +157,26 @@ int hvm_buffered_io_send(ioreq_t *p)
     1.4      struct hvm_ioreq_page *iorp = &v->domain->arch.hvm_domain.buf_ioreq;
     1.5      buffered_iopage_t *pg = iorp->va;
     1.6      buf_ioreq_t bp;
     1.7 -    /* Timeoffset sends 64b data, but no address.  Use two consecutive slots. */
     1.8 +    /* Timeoffset sends 64b data, but no address. Use two consecutive slots. */
     1.9      int qw = 0;
    1.10  
    1.11      /* Ensure buffered_iopage fits in a page */
    1.12      BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE);
    1.13  
    1.14      /* Return 0 for the cases we can't deal with. */
    1.15 -    if (p->addr > 0xffffful || p->data_is_ptr || p->df || p->count != 1)
    1.16 +    if ( (p->addr > 0xffffful) || p->data_is_ptr || p->df || (p->count != 1) )
    1.17 +    {
    1.18 +        gdprintk(XENLOG_DEBUG, "slow ioreq.  type:%d size:%ld addr:0x%08lx "
    1.19 +                 "dir:%d ptr:%d df:%d count:%ld\n",
    1.20 +                 p->type, p->size, p->addr, !!p->dir,
    1.21 +                 !!p->data_is_ptr, !!p->df, p->count);
    1.22          return 0;
    1.23 +    }
    1.24  
    1.25      bp.type = p->type;
    1.26      bp.dir  = p->dir;
    1.27 -    switch (p->size) {
    1.28 +    switch ( p->size )
    1.29 +    {
    1.30      case 1:
    1.31          bp.size = 0;
    1.32          break;
    1.33 @@ -182,8 +189,6 @@ int hvm_buffered_io_send(ioreq_t *p)
    1.34      case 8:
    1.35          bp.size = 3;
    1.36          qw = 1;
    1.37 -        gdprintk(XENLOG_INFO, "quadword ioreq type:%d data:%"PRIx64"\n",
    1.38 -                 p->type, p->data);
    1.39          break;
    1.40      default:
    1.41          gdprintk(XENLOG_WARNING, "unexpected ioreq size:%"PRId64"\n", p->size);
    1.42 @@ -191,11 +196,12 @@ int hvm_buffered_io_send(ioreq_t *p)
    1.43      }
    1.44      
    1.45      bp.data = p->data;
    1.46 -    bp.addr = qw ? ((p->data >> 16) & 0xfffful) : (p->addr & 0xffffful);
    1.47 +    bp.addr = p->addr;
    1.48      
    1.49      spin_lock(&iorp->lock);
    1.50  
    1.51 -    if ( (pg->write_pointer - pg->read_pointer) >= IOREQ_BUFFER_SLOT_NUM - (qw ? 1 : 0))
    1.52 +    if ( (pg->write_pointer - pg->read_pointer) >=
    1.53 +         (IOREQ_BUFFER_SLOT_NUM - qw) )
    1.54      {
    1.55          /* The queue is full: send the iopacket through the normal path. */
    1.56          spin_unlock(&iorp->lock);
    1.57 @@ -205,9 +211,9 @@ int hvm_buffered_io_send(ioreq_t *p)
    1.58      memcpy(&pg->buf_ioreq[pg->write_pointer % IOREQ_BUFFER_SLOT_NUM],
    1.59             &bp, sizeof(bp));
    1.60      
    1.61 -    if (qw) {
    1.62 +    if ( qw )
    1.63 +    {
    1.64          bp.data = p->data >> 32;
    1.65 -        bp.addr = (p->data >> 48) & 0xfffful;
    1.66          memcpy(&pg->buf_ioreq[(pg->write_pointer+1) % IOREQ_BUFFER_SLOT_NUM],
    1.67                 &bp, sizeof(bp));
    1.68      }
    1.69 @@ -215,7 +221,7 @@ int hvm_buffered_io_send(ioreq_t *p)
    1.70      /* Make the ioreq_t visible /before/ write_pointer. */
    1.71      wmb();
    1.72      pg->write_pointer += qw ? 2 : 1;
    1.73 -    
    1.74 +
    1.75      spin_unlock(&iorp->lock);
    1.76      
    1.77      return 1;
     2.1 --- a/xen/arch/x86/hvm/stdvga.c	Thu Nov 01 09:37:47 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/stdvga.c	Thu Nov 01 09:48:14 2007 +0000
     2.3 @@ -296,6 +296,8 @@ int stdvga_intercept_pio(ioreq_t *p)
     2.4      {
     2.5          if ( p->size != 1 )
     2.6              gdprintk(XENLOG_WARNING, "unexpected io size:%d\n", (int)p->size);
     2.7 +        if ( p->data_is_ptr )
     2.8 +            gdprintk(XENLOG_WARNING, "unexpected data_is_ptr\n");
     2.9          if ( !((p->addr == 0x3c5) && (s->sr_index >= sizeof(sr_mask))) &&
    2.10               !((p->addr == 0x3cf) && (s->gr_index >= sizeof(gr_mask))) )
    2.11          {
    2.12 @@ -643,6 +645,10 @@ int stdvga_intercept_mmio(ioreq_t *p)
    2.13              s->cache = 0;
    2.14          }
    2.15      }
    2.16 +    else
    2.17 +    {
    2.18 +        buf = (p->dir == IOREQ_WRITE);
    2.19 +    }
    2.20  
    2.21      rc = (buf && hvm_buffered_io_send(p));
    2.22  
     3.1 --- a/xen/include/public/hvm/ioreq.h	Thu Nov 01 09:37:47 2007 +0000
     3.2 +++ b/xen/include/public/hvm/ioreq.h	Thu Nov 01 09:48:14 2007 +0000
     3.3 @@ -80,9 +80,9 @@ typedef struct shared_iopage shared_iopa
     3.4  struct buf_ioreq {
     3.5      uint8_t  type;   /*  I/O type                    */
     3.6      uint8_t  dir:1;  /*  1=read, 0=write             */
     3.7 -    uint8_t  size:2; /*  0=>1, 1=>2, 3=>8. If 8 then use two contig buf_ioreqs */
     3.8 -    uint16_t data;   /*  (low order) data            */
     3.9 -    uint32_t addr;   /*  physical address or high-order data */
    3.10 +    uint8_t  size:2; /*  0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */
    3.11 +    uint32_t addr:20;/*  physical address            */
    3.12 +    uint32_t data;   /*  data                        */
    3.13  };
    3.14  typedef struct buf_ioreq buf_ioreq_t;
    3.15