Skip to content

Commit

Permalink
KVM: x86: fix broken read emulation spans a page boundary
Browse files Browse the repository at this point in the history
If the range spans a page boundary, the mmio access can be broke, fix it as
write emulation.

And we already get the guest physical address, so use it to read guest data
directly to avoid walking guest page table again

Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
  • Loading branch information
Xiao Guangrong authored and Avi Kivity committed Sep 25, 2011
1 parent 9be3be1 commit ca7d58f
Showing 1 changed file with 31 additions and 8 deletions.
39 changes: 31 additions & 8 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -4045,13 +4045,12 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
return 0;
}

static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
unsigned long addr,
void *val,
unsigned int bytes,
struct x86_exception *exception)
static int emulator_read_emulated_onepage(unsigned long addr,
void *val,
unsigned int bytes,
struct x86_exception *exception,
struct kvm_vcpu *vcpu)
{
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
gpa_t gpa;
int handled, ret;

Expand All @@ -4071,8 +4070,7 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
if (ret)
goto mmio;

if (kvm_read_guest_virt(ctxt, addr, val, bytes, exception)
== X86EMUL_CONTINUE)
if (!kvm_read_guest(vcpu->kvm, gpa, val, bytes))
return X86EMUL_CONTINUE;

mmio:
Expand Down Expand Up @@ -4101,6 +4099,31 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
return X86EMUL_IO_NEEDED;
}

static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
unsigned long addr,
void *val,
unsigned int bytes,
struct x86_exception *exception)
{
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);

/* Crossing a page boundary? */
if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
int rc, now;

now = -addr & ~PAGE_MASK;
rc = emulator_read_emulated_onepage(addr, val, now, exception,
vcpu);
if (rc != X86EMUL_CONTINUE)
return rc;
addr += now;
val += now;
bytes -= now;
}
return emulator_read_emulated_onepage(addr, val, bytes, exception,
vcpu);
}

int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
const void *val, int bytes)
{
Expand Down

0 comments on commit ca7d58f

Please sign in to comment.