Commit 77c2002e authored by Izik Eidus's avatar Izik Eidus Committed by Avi Kivity

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: default avatarIzik Eidus <ieidus@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 53f658b3
...@@ -609,10 +609,6 @@ void kvm_inject_nmi(struct kvm_vcpu *vcpu); ...@@ -609,10 +609,6 @@ void kvm_inject_nmi(struct kvm_vcpu *vcpu);
void fx_init(struct kvm_vcpu *vcpu); void fx_init(struct kvm_vcpu *vcpu);
int emulator_read_std(unsigned long addr,
void *val,
unsigned int bytes,
struct kvm_vcpu *vcpu);
int emulator_write_emulated(unsigned long addr, int emulator_write_emulated(unsigned long addr,
const void *val, const void *val,
unsigned int bytes, unsigned int bytes,
......
...@@ -1976,10 +1976,8 @@ static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, ...@@ -1976,10 +1976,8 @@ static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
return dev; return dev;
} }
int emulator_read_std(unsigned long addr, int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
void *val, struct kvm_vcpu *vcpu)
unsigned int bytes,
struct kvm_vcpu *vcpu)
{ {
void *data = val; void *data = val;
int r = X86EMUL_CONTINUE; int r = X86EMUL_CONTINUE;
...@@ -1987,27 +1985,57 @@ int emulator_read_std(unsigned long addr, ...@@ -1987,27 +1985,57 @@ int emulator_read_std(unsigned long addr,
while (bytes) { while (bytes) {
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
unsigned offset = addr & (PAGE_SIZE-1); unsigned offset = addr & (PAGE_SIZE-1);
unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset); unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret; int ret;
if (gpa == UNMAPPED_GVA) { if (gpa == UNMAPPED_GVA) {
r = X86EMUL_PROPAGATE_FAULT; r = X86EMUL_PROPAGATE_FAULT;
goto out; goto out;
} }
ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy); ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
if (ret < 0) { if (ret < 0) {
r = X86EMUL_UNHANDLEABLE; r = X86EMUL_UNHANDLEABLE;
goto out; goto out;
} }
bytes -= tocopy; bytes -= toread;
data += tocopy; data += toread;
addr += tocopy; addr += toread;
} }
out: out:
return r; return r;
} }
EXPORT_SYMBOL_GPL(emulator_read_std);
int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
struct kvm_vcpu *vcpu)
{
void *data = val;
int r = X86EMUL_CONTINUE;
while (bytes) {
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
unsigned offset = addr & (PAGE_SIZE-1);
unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
if (gpa == UNMAPPED_GVA) {
r = X86EMUL_PROPAGATE_FAULT;
goto out;
}
ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite);
if (ret < 0) {
r = X86EMUL_UNHANDLEABLE;
goto out;
}
bytes -= towrite;
data += towrite;
addr += towrite;
}
out:
return r;
}
static int emulator_read_emulated(unsigned long addr, static int emulator_read_emulated(unsigned long addr,
void *val, void *val,
...@@ -2029,8 +2057,8 @@ static int emulator_read_emulated(unsigned long addr, ...@@ -2029,8 +2057,8 @@ static int emulator_read_emulated(unsigned long addr,
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
goto mmio; goto mmio;
if (emulator_read_std(addr, val, bytes, vcpu) if (kvm_read_guest_virt(addr, val, bytes, vcpu)
== X86EMUL_CONTINUE) == X86EMUL_CONTINUE)
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
if (gpa == UNMAPPED_GVA) if (gpa == UNMAPPED_GVA)
return X86EMUL_PROPAGATE_FAULT; return X86EMUL_PROPAGATE_FAULT;
...@@ -2233,7 +2261,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) ...@@ -2233,7 +2261,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu); kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu);
printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); 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,7 +2269,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
static struct x86_emulate_ops emulate_ops = { static struct x86_emulate_ops emulate_ops = {
.read_std = emulator_read_std, .read_std = kvm_read_guest_virt,
.read_emulated = emulator_read_emulated, .read_emulated = emulator_read_emulated,
.write_emulated = emulator_write_emulated, .write_emulated = emulator_write_emulated,
.cmpxchg_emulated = emulator_cmpxchg_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment