提交 b0fcd903 编写于 作者: A Avi Kivity

KVM: Correctly handle writes crossing a page boundary

Writes that are contiguous in virtual memory may not be contiguous in
physical memory; so split writes that straddle a page boundary.

Thanks to Aurelien for reporting the bug, patient testing, and a fix
to this very patch.
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>
Signed-off-by: NAvi Kivity <avi@qumranet.com>
上级 0de085bb
...@@ -1078,10 +1078,10 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, ...@@ -1078,10 +1078,10 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
return 1; return 1;
} }
static int emulator_write_emulated(unsigned long addr, static int emulator_write_emulated_onepage(unsigned long addr,
const void *val, const void *val,
unsigned int bytes, unsigned int bytes,
struct x86_emulate_ctxt *ctxt) struct x86_emulate_ctxt *ctxt)
{ {
struct kvm_vcpu *vcpu = ctxt->vcpu; struct kvm_vcpu *vcpu = ctxt->vcpu;
struct kvm_io_device *mmio_dev; struct kvm_io_device *mmio_dev;
...@@ -1113,6 +1113,26 @@ static int emulator_write_emulated(unsigned long addr, ...@@ -1113,6 +1113,26 @@ static int emulator_write_emulated(unsigned long addr,
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
} }
static int emulator_write_emulated(unsigned long addr,
const void *val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
/* Crossing a page boundary? */
if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
int rc, now;
now = -addr & ~PAGE_MASK;
rc = emulator_write_emulated_onepage(addr, val, now, ctxt);
if (rc != X86EMUL_CONTINUE)
return rc;
addr += now;
val += now;
bytes -= now;
}
return emulator_write_emulated_onepage(addr, val, bytes, ctxt);
}
static int emulator_cmpxchg_emulated(unsigned long addr, static int emulator_cmpxchg_emulated(unsigned long addr,
const void *old, const void *old,
const void *new, const void *new,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册