Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0fcd903 authored by Avi Kivity's avatar Avi Kivity
Browse files

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: default avatarAurelien Jarno <aurelien@aurel32.net>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 0de085bb
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -1078,7 +1078,7 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
	return 1;
}

static int emulator_write_emulated(unsigned long addr,
static int emulator_write_emulated_onepage(unsigned long addr,
					   const void *val,
					   unsigned int bytes,
					   struct x86_emulate_ctxt *ctxt)
@@ -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,