ia64/xen-unstable

changeset 9590:02e8dd5e4c57

Fix a regression in hvm_pio_assist() when booting Windows
on VT-x. Clean up the function also.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Apr 05 12:23:49 2006 +0100 (2006-04-05)
parents ce7746d47f18
children bb316b4df46f
files xen/arch/x86/hvm/io.c
line diff
     1.1 --- a/xen/arch/x86/hvm/io.c	Wed Apr 05 10:54:29 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/io.c	Wed Apr 05 12:23:49 2006 +0100
     1.3 @@ -365,57 +365,46 @@ static void hvm_pio_assist(struct cpu_us
     1.4      unsigned long old_eax;
     1.5      int sign = p->df ? -1 : 1;
     1.6  
     1.7 -    if (p->pdata_valid || (mmio_opp->flags & OVERLAP)) {
     1.8 -        if (mmio_opp->flags & REPZ)
     1.9 +    if ( p->pdata_valid || (mmio_opp->flags & OVERLAP) )
    1.10 +    {
    1.11 +        if ( mmio_opp->flags & REPZ )
    1.12              regs->ecx -= p->count;
    1.13 -        if (p->dir == IOREQ_READ) {
    1.14 +        if ( p->dir == IOREQ_READ )
    1.15 +        {
    1.16              regs->edi += sign * p->count * p->size;
    1.17 -
    1.18 -            if (mmio_opp->flags & OVERLAP) {
    1.19 -                /* 
    1.20 -                 * If we are doing in IN and it's overlapping a page boundary, 
    1.21 -                 * we need to copy the data back to user's page with hvm_copy. 
    1.22 -                 * Note that overlap * can only be set with paging enabled, so 
    1.23 -                 * we don't need to worry about * real-mode stuff.  
    1.24 -                 */
    1.25 -                unsigned long addr;
    1.26 -                {
    1.27 -                    /* 
    1.28 -		     * We completely ignore segment registers here - 
    1.29 -                     * it's not a good idea. We also may use upper bits
    1.30 -                     * in edi when in 16-bit real/protected mode.
    1.31 -                     * We really need to get the actual address back from
    1.32 -                     * the arch-dependant HVM portion.
    1.33 -                     */
    1.34 -                    struct vcpu *v = current;
    1.35 -                    if (hvm_realmode(v))
    1.36 -                        __hvm_bug(regs);
    1.37 -                }
    1.38 -                addr = regs->edi;
    1.39 +            if ( mmio_opp->flags & OVERLAP )
    1.40 +            {
    1.41 +                unsigned long addr = regs->edi;
    1.42 +                if (hvm_realmode(current))
    1.43 +                    addr += regs->es << 4;
    1.44                  if (sign > 0)
    1.45                      addr -= p->size;
    1.46                  hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
    1.47              }
    1.48 -        } else
    1.49 +        }
    1.50 +        else /* p->dir == IOREQ_WRITE */
    1.51 +        {
    1.52 +            ASSERT(p->dir == IOREQ_WRITE);
    1.53              regs->esi += sign * p->count * p->size;
    1.54 -
    1.55 -    } else {
    1.56 -        if (p->dir == IOREQ_READ) {
    1.57 -            old_eax = regs->eax;
    1.58 -            switch (p->size) {
    1.59 -            case 1:
    1.60 -                regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
    1.61 -                break;
    1.62 -            case 2:
    1.63 -                regs->eax = (old_eax & 0xffff0000) | (p->u.data & 0xffff);
    1.64 -                break;
    1.65 -            case 4:
    1.66 -                regs->eax = (p->u.data & 0xffffffff);
    1.67 -                break;
    1.68 -            default:
    1.69 -                printk("Error: %s unknown port size\n", __FUNCTION__);
    1.70 -                domain_crash_synchronous();
    1.71 -            }
    1.72 +        }
    1.73 +    }
    1.74 +    else if ( p->dir == IOREQ_READ )
    1.75 +    {
    1.76 +        old_eax = regs->eax;
    1.77 +        switch ( p->size )
    1.78 +        {
    1.79 +        case 1:
    1.80 +            regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
    1.81 +            break;
    1.82 +        case 2:
    1.83 +            regs->eax = (old_eax & 0xffff0000) | (p->u.data & 0xffff);
    1.84 +            break;
    1.85 +        case 4:
    1.86 +            regs->eax = (p->u.data & 0xffffffff);
    1.87 +            break;
    1.88 +        default:
    1.89 +            printk("Error: %s unknown port size\n", __FUNCTION__);
    1.90 +            domain_crash_synchronous();
    1.91          }
    1.92      }
    1.93  }