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>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2006-04-05 12:23:49 +01:00
1 parent beac48024f
commit ec74700a6b
1 file changed
+33 -44
+33 -44
View File
@@ -365,57 +365,46 @@ static void hvm_pio_assist(struct cpu_user_regs *regs, ioreq_t *p,
unsigned long old_eax;
int sign = p->df ? -1 : 1;
if (p->pdata_valid || (mmio_opp->flags & OVERLAP)) {
if (mmio_opp->flags & REPZ)
if ( p->pdata_valid || (mmio_opp->flags & OVERLAP) )
{
if ( mmio_opp->flags & REPZ )
regs->ecx -= p->count;
if (p->dir == IOREQ_READ) {
if ( p->dir == IOREQ_READ )
{
regs->edi += sign * p->count * p->size;
if (mmio_opp->flags & OVERLAP) {
/*
* If we are doing in IN and it's overlapping a page boundary,
* we need to copy the data back to user's page with hvm_copy.
* Note that overlap * can only be set with paging enabled, so
* we don't need to worry about * real-mode stuff.
*/
unsigned long addr;
{
/*
* We completely ignore segment registers here -
* it's not a good idea. We also may use upper bits
* in edi when in 16-bit real/protected mode.
* We really need to get the actual address back from
* the arch-dependant HVM portion.
*/
struct vcpu *v = current;
if (hvm_realmode(v))
__hvm_bug(regs);
}
addr = regs->edi;
if ( mmio_opp->flags & OVERLAP )
{
unsigned long addr = regs->edi;
if (hvm_realmode(current))
addr += regs->es << 4;
if (sign > 0)
addr -= p->size;
hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
}
} else
}
else /* p->dir == IOREQ_WRITE */
{
ASSERT(p->dir == IOREQ_WRITE);
regs->esi += sign * p->count * p->size;
} else {
if (p->dir == IOREQ_READ) {
old_eax = regs->eax;
switch (p->size) {
case 1:
regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
break;
case 2:
regs->eax = (old_eax & 0xffff0000) | (p->u.data & 0xffff);
break;
case 4:
regs->eax = (p->u.data & 0xffffffff);
break;
default:
printk("Error: %s unknown port size\n", __FUNCTION__);
domain_crash_synchronous();
}
}
}
else if ( p->dir == IOREQ_READ )
{
old_eax = regs->eax;
switch ( p->size )
{
case 1:
regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
break;
case 2:
regs->eax = (old_eax & 0xffff0000) | (p->u.data & 0xffff);
break;
case 4:
regs->eax = (p->u.data & 0xffffffff);
break;
default:
printk("Error: %s unknown port size\n", __FUNCTION__);
domain_crash_synchronous();
}
}
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.