diff options
author | Izik Eidus <ieidus@redhat.com> | 2008-12-28 18:42:19 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 05:02:54 -0400 |
commit | 77c2002e7c6f019f59a6f3cc5f8b16b41748dbe1 (patch) | |
tree | 9d2d483b0624f09625f6b9ab6e2bc547f1cee4d3 /arch/x86 | |
parent | 53f658b3c33616a4997ee254311b335e59063289 (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>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 56 |
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 | ||
610 | void fx_init(struct kvm_vcpu *vcpu); | 610 | void fx_init(struct kvm_vcpu *vcpu); |
611 | 611 | ||
612 | int emulator_read_std(unsigned long addr, | ||
613 | void *val, | ||
614 | unsigned int bytes, | ||
615 | struct kvm_vcpu *vcpu); | ||
616 | int emulator_write_emulated(unsigned long addr, | 612 | int 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 | ||
1979 | int emulator_read_std(unsigned long addr, | 1979 | int 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 | } |
2007 | out: | 2005 | out: |
2008 | return r; | 2006 | return r; |
2009 | } | 2007 | } |
2010 | EXPORT_SYMBOL_GPL(emulator_read_std); | 2008 | |
2009 | int 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 | } | ||
2035 | out: | ||
2036 | return r; | ||
2037 | } | ||
2038 | |||
2011 | 2039 | ||
2012 | static int emulator_read_emulated(unsigned long addr, | 2040 | static 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) | |||
2241 | EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); | 2269 | EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); |
2242 | 2270 | ||
2243 | static struct x86_emulate_ops emulate_ops = { | 2271 | static 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, |