Skip to content

Commit

Permalink
KVM: introduce kvm_read_guest_virt, kvm_write_guest_virt
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Izik Eidus authored and Avi Kivity committed Mar 24, 2009
1 parent 53f658b commit 77c2002
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 18 deletions.
4 changes: 0 additions & 4 deletions arch/x86/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -609,10 +609,6 @@ void kvm_inject_nmi(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,
const void *val,
unsigned int bytes,
Expand Down
56 changes: 42 additions & 14 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -1976,38 +1976,66 @@ static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
return dev;
}

int emulator_read_std(unsigned long addr,
void *val,
unsigned int bytes,
struct kvm_vcpu *vcpu)
int kvm_read_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 tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;

if (gpa == UNMAPPED_GVA) {
r = X86EMUL_PROPAGATE_FAULT;
goto out;
}
ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy);
ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
if (ret < 0) {
r = X86EMUL_UNHANDLEABLE;
goto out;
}

bytes -= tocopy;
data += tocopy;
addr += tocopy;
bytes -= toread;
data += toread;
addr += toread;
}
out:
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,
void *val,
Expand All @@ -2029,8 +2057,8 @@ static int emulator_read_emulated(unsigned long addr,
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
goto mmio;

if (emulator_read_std(addr, val, bytes, vcpu)
== X86EMUL_CONTINUE)
if (kvm_read_guest_virt(addr, val, bytes, vcpu)
== X86EMUL_CONTINUE)
return X86EMUL_CONTINUE;
if (gpa == UNMAPPED_GVA)
return X86EMUL_PROPAGATE_FAULT;
Expand Down Expand Up @@ -2233,15 +2261,15 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)

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",
context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
}
EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);

static struct x86_emulate_ops emulate_ops = {
.read_std = emulator_read_std,
.read_std = kvm_read_guest_virt,
.read_emulated = emulator_read_emulated,
.write_emulated = emulator_write_emulated,
.cmpxchg_emulated = emulator_cmpxchg_emulated,
Expand Down

0 comments on commit 77c2002

Please sign in to comment.