aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIzik Eidus <ieidus@redhat.com>2008-12-28 18:42:19 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:02:54 -0400
commit77c2002e7c6f019f59a6f3cc5f8b16b41748dbe1 (patch)
tree9d2d483b0624f09625f6b9ab6e2bc547f1cee4d3
parent53f658b3c33616a4997ee254311b335e59063289 (diff)
KVM: introduce kvm_read_guest_virt, kvm_write_guest_virt
This commit change the name of emulator_read_std into kvm_read_guest_virt, and add new function name kvm_write_guest_virt that allow writing into a guest virtual address. Signed-off-by: Izik Eidus <ieidus@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_host.h4
-rw-r--r--arch/x86/kvm/x86.c56
2 files changed, 42 insertions, 18 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9efc446b5ac6..b74576aec19a 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -609,10 +609,6 @@ void kvm_inject_nmi(struct kvm_vcpu *vcpu);
609 609
610void fx_init(struct kvm_vcpu *vcpu); 610void fx_init(struct kvm_vcpu *vcpu);
611 611
612int emulator_read_std(unsigned long addr,
613 void *val,
614 unsigned int bytes,
615 struct kvm_vcpu *vcpu);
616int emulator_write_emulated(unsigned long addr, 612int emulator_write_emulated(unsigned long addr,
617 const void *val, 613 const void *val,
618 unsigned int bytes, 614 unsigned int bytes,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3b2acfd72d7f..67f91764e99b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1976,10 +1976,8 @@ static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
1976 return dev; 1976 return dev;
1977} 1977}
1978 1978
1979int emulator_read_std(unsigned long addr, 1979int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
1980 void *val, 1980 struct kvm_vcpu *vcpu)
1981 unsigned int bytes,
1982 struct kvm_vcpu *vcpu)
1983{ 1981{
1984 void *data = val; 1982 void *data = val;
1985 int r = X86EMUL_CONTINUE; 1983 int r = X86EMUL_CONTINUE;
@@ -1987,27 +1985,57 @@ int emulator_read_std(unsigned long addr,
1987 while (bytes) { 1985 while (bytes) {
1988 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); 1986 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
1989 unsigned offset = addr & (PAGE_SIZE-1); 1987 unsigned offset = addr & (PAGE_SIZE-1);
1990 unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset); 1988 unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
1991 int ret; 1989 int ret;
1992 1990
1993 if (gpa == UNMAPPED_GVA) { 1991 if (gpa == UNMAPPED_GVA) {
1994 r = X86EMUL_PROPAGATE_FAULT; 1992 r = X86EMUL_PROPAGATE_FAULT;
1995 goto out; 1993 goto out;
1996 } 1994 }
1997 ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy); 1995 ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
1998 if (ret < 0) { 1996 if (ret < 0) {
1999 r = X86EMUL_UNHANDLEABLE; 1997 r = X86EMUL_UNHANDLEABLE;
2000 goto out; 1998 goto out;
2001 } 1999 }
2002 2000
2003 bytes -= tocopy; 2001 bytes -= toread;
2004 data += tocopy; 2002 data += toread;
2005 addr += tocopy; 2003 addr += toread;
2006 } 2004 }
2007out: 2005out:
2008 return r; 2006 return r;
2009} 2007}
2010EXPORT_SYMBOL_GPL(emulator_read_std); 2008
2009int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
2010 struct kvm_vcpu *vcpu)
2011{
2012 void *data = val;
2013 int r = X86EMUL_CONTINUE;
2014
2015 while (bytes) {
2016 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
2017 unsigned offset = addr & (PAGE_SIZE-1);
2018 unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
2019 int ret;
2020
2021 if (gpa == UNMAPPED_GVA) {
2022 r = X86EMUL_PROPAGATE_FAULT;
2023 goto out;
2024 }
2025 ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite);
2026 if (ret < 0) {
2027 r = X86EMUL_UNHANDLEABLE;
2028 goto out;
2029 }
2030
2031 bytes -= towrite;
2032 data += towrite;
2033 addr += towrite;
2034 }
2035out:
2036 return r;
2037}
2038
2011 2039
2012static int emulator_read_emulated(unsigned long addr, 2040static int emulator_read_emulated(unsigned long addr,
2013 void *val, 2041 void *val,
@@ -2029,8 +2057,8 @@ static int emulator_read_emulated(unsigned long addr,
2029 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) 2057 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
2030 goto mmio; 2058 goto mmio;
2031 2059
2032 if (emulator_read_std(addr, val, bytes, vcpu) 2060 if (kvm_read_guest_virt(addr, val, bytes, vcpu)
2033 == X86EMUL_CONTINUE) 2061 == X86EMUL_CONTINUE)
2034 return X86EMUL_CONTINUE; 2062 return X86EMUL_CONTINUE;
2035 if (gpa == UNMAPPED_GVA) 2063 if (gpa == UNMAPPED_GVA)
2036 return X86EMUL_PROPAGATE_FAULT; 2064 return X86EMUL_PROPAGATE_FAULT;
@@ -2233,7 +2261,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
2233 2261
2234 rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); 2262 rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
2235 2263
2236 emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu); 2264 kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu);
2237 2265
2238 printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", 2266 printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
2239 context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); 2267 context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
@@ -2241,7 +2269,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
2241EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); 2269EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
2242 2270
2243static struct x86_emulate_ops emulate_ops = { 2271static struct x86_emulate_ops emulate_ops = {
2244 .read_std = emulator_read_std, 2272 .read_std = kvm_read_guest_virt,
2245 .read_emulated = emulator_read_emulated, 2273 .read_emulated = emulator_read_emulated,
2246 .write_emulated = emulator_write_emulated, 2274 .write_emulated = emulator_write_emulated,
2247 .cmpxchg_emulated = emulator_cmpxchg_emulated, 2275 .cmpxchg_emulated = emulator_cmpxchg_emulated,