aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@cn.fujitsu.com>2011-07-13 02:31:08 -0400
committerAvi Kivity <avi@redhat.com>2011-09-25 12:17:17 -0400
commitca7d58f375c650cf36900cb1da1ca2cc99b13393 (patch)
treedf36edae4b8426061119b876fcbd3f0d0eb2251a /arch/x86/kvm/x86.c
parent9be3be1f153e90ea4e1e5b6ed1d72a73d44318d1 (diff)
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: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 84a28ea45fa4..1453248723eb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4045,13 +4045,12 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
4045 return 0; 4045 return 0;
4046} 4046}
4047 4047
4048static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt, 4048static int emulator_read_emulated_onepage(unsigned long addr,
4049 unsigned long addr, 4049 void *val,
4050 void *val, 4050 unsigned int bytes,
4051 unsigned int bytes, 4051 struct x86_exception *exception,
4052 struct x86_exception *exception) 4052 struct kvm_vcpu *vcpu)
4053{ 4053{
4054 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
4055 gpa_t gpa; 4054 gpa_t gpa;
4056 int handled, ret; 4055 int handled, ret;
4057 4056
@@ -4071,8 +4070,7 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
4071 if (ret) 4070 if (ret)
4072 goto mmio; 4071 goto mmio;
4073 4072
4074 if (kvm_read_guest_virt(ctxt, addr, val, bytes, exception) 4073 if (!kvm_read_guest(vcpu->kvm, gpa, val, bytes))
4075 == X86EMUL_CONTINUE)
4076 return X86EMUL_CONTINUE; 4074 return X86EMUL_CONTINUE;
4077 4075
4078mmio: 4076mmio:
@@ -4101,6 +4099,31 @@ mmio:
4101 return X86EMUL_IO_NEEDED; 4099 return X86EMUL_IO_NEEDED;
4102} 4100}
4103 4101
4102static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
4103 unsigned long addr,
4104 void *val,
4105 unsigned int bytes,
4106 struct x86_exception *exception)
4107{
4108 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
4109
4110 /* Crossing a page boundary? */
4111 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
4112 int rc, now;
4113
4114 now = -addr & ~PAGE_MASK;
4115 rc = emulator_read_emulated_onepage(addr, val, now, exception,
4116 vcpu);
4117 if (rc != X86EMUL_CONTINUE)
4118 return rc;
4119 addr += now;
4120 val += now;
4121 bytes -= now;
4122 }
4123 return emulator_read_emulated_onepage(addr, val, bytes, exception,
4124 vcpu);
4125}
4126
4104int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, 4127int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
4105 const void *val, int bytes) 4128 const void *val, int bytes)
4106{ 4129{