return X86EMUL_RETRY;
}
+ /* Maintain a ref on the mfn to ensure liveness. Put the gfn
+ * to avoid potential deadlock wrt event channel lock, later. */
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ if ( !get_page(mfn_to_page(mfn_x(ram_mfn)),
+ curr->domain) )
+ {
+ put_gfn(curr->domain, ram_gfn);
+ return X86EMUL_RETRY;
+ }
+ put_gfn(curr->domain, ram_gfn);
+
/*
* Weird-sized accesses have undefined behaviour: we discard writes
* and read all-ones.
ASSERT(p_data != NULL); /* cannot happen with a REP prefix */
if ( dir == IOREQ_READ )
memset(p_data, ~0, size);
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_UNHANDLEABLE;
}
unsigned int bytes = vio->mmio_large_write_bytes;
if ( (addr >= pa) && ((addr + size) <= (pa + bytes)) )
{
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_OKAY;
}
}
{
memcpy(p_data, &vio->mmio_large_read[addr - pa],
size);
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_OKAY;
}
}
vio->io_state = HVMIO_none;
if ( p_data == NULL )
{
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_UNHANDLEABLE;
}
goto finish_access;
(addr == (vio->mmio_large_write_pa +
vio->mmio_large_write_bytes)) )
{
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_RETRY;
}
default:
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_UNHANDLEABLE;
}
{
gdprintk(XENLOG_WARNING, "WARNING: io already pending (%d)?\n",
p->state);
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_UNHANDLEABLE;
}
if ( rc != X86EMUL_OKAY )
{
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return rc;
}
}
}
- put_gfn(curr->domain, ram_gfn);
+ if ( mfn_valid(mfn_x(ram_mfn)) )
+ put_page(mfn_to_page(mfn_x(ram_mfn)));
return X86EMUL_OKAY;
}