mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 21:54:11 +08:00
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: Aurelien Jarno <aurelien@aurel32.net> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
0de085bb47
commit
b0fcd903e6
@ -1078,10 +1078,10 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int emulator_write_emulated(unsigned long addr,
|
||||
const void *val,
|
||||
unsigned int bytes,
|
||||
struct x86_emulate_ctxt *ctxt)
|
||||
static int emulator_write_emulated_onepage(unsigned long addr,
|
||||
const void *val,
|
||||
unsigned int bytes,
|
||||
struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
||||
struct kvm_io_device *mmio_dev;
|
||||
@ -1113,6 +1113,26 @@ static int emulator_write_emulated(unsigned long addr,
|
||||
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,
|
||||
const void *old,
|
||||
const void *new,
|
||||
|
Loading…
Reference in New Issue
Block a user