提交 ca7d58f3 编写于 作者: X Xiao Guangrong 提交者: Avi Kivity

KVM: x86: fix broken read emulation spans a page boundary

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: NXiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Signed-off-by: NAvi Kivity <avi@redhat.com>
上级 9be3be1f
...@@ -4045,13 +4045,12 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, ...@@ -4045,13 +4045,12 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
return 0; return 0;
} }
static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt, static int emulator_read_emulated_onepage(unsigned long addr,
unsigned long addr, void *val,
void *val, unsigned int bytes,
unsigned int bytes, struct x86_exception *exception,
struct x86_exception *exception) struct kvm_vcpu *vcpu)
{ {
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
gpa_t gpa; gpa_t gpa;
int handled, ret; int handled, ret;
...@@ -4071,8 +4070,7 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt, ...@@ -4071,8 +4070,7 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
if (ret) if (ret)
goto mmio; goto mmio;
if (kvm_read_guest_virt(ctxt, addr, val, bytes, exception) if (!kvm_read_guest(vcpu->kvm, gpa, val, bytes))
== X86EMUL_CONTINUE)
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
mmio: mmio:
...@@ -4101,6 +4099,31 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt, ...@@ -4101,6 +4099,31 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
return X86EMUL_IO_NEEDED; 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, int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
const void *val, int bytes) const void *val, int bytes)
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册