KVM: x86: accessors for guest registers
As suggested by Avi, introduce accessors to read/write guest registers. This simplifies the ->cache_regs/->decache_regs interface, and improves register caching which is important for VMX, where the cost of vmcs_read/vmcs_write is significant. [avi: fix warnings] Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:

committed by
Avi Kivity

parent
ca60dfbb69
commit
5fdbf9765b
@@ -26,6 +26,7 @@
|
||||
#define DPRINTF(_f, _a ...) printf(_f , ## _a)
|
||||
#else
|
||||
#include <linux/kvm_host.h>
|
||||
#include "kvm_cache_regs.h"
|
||||
#define DPRINTF(x...) do {} while (0)
|
||||
#endif
|
||||
#include <linux/module.h>
|
||||
@@ -839,7 +840,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
||||
/* Shadow copy of register state. Committed on successful emulation. */
|
||||
|
||||
memset(c, 0, sizeof(struct decode_cache));
|
||||
c->eip = ctxt->vcpu->arch.rip;
|
||||
c->eip = kvm_rip_read(ctxt->vcpu);
|
||||
ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
|
||||
memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
|
||||
|
||||
@@ -1267,7 +1268,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
||||
if (c->rep_prefix && (c->d & String)) {
|
||||
/* All REP prefixes have the same first termination condition */
|
||||
if (c->regs[VCPU_REGS_RCX] == 0) {
|
||||
ctxt->vcpu->arch.rip = c->eip;
|
||||
kvm_rip_write(ctxt->vcpu, c->eip);
|
||||
goto done;
|
||||
}
|
||||
/* The second termination condition only applies for REPE
|
||||
@@ -1281,17 +1282,17 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
|
||||
(c->b == 0xae) || (c->b == 0xaf)) {
|
||||
if ((c->rep_prefix == REPE_PREFIX) &&
|
||||
((ctxt->eflags & EFLG_ZF) == 0)) {
|
||||
ctxt->vcpu->arch.rip = c->eip;
|
||||
kvm_rip_write(ctxt->vcpu, c->eip);
|
||||
goto done;
|
||||
}
|
||||
if ((c->rep_prefix == REPNE_PREFIX) &&
|
||||
((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) {
|
||||
ctxt->vcpu->arch.rip = c->eip;
|
||||
kvm_rip_write(ctxt->vcpu, c->eip);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
c->regs[VCPU_REGS_RCX]--;
|
||||
c->eip = ctxt->vcpu->arch.rip;
|
||||
c->eip = kvm_rip_read(ctxt->vcpu);
|
||||
}
|
||||
|
||||
if (c->src.type == OP_MEM) {
|
||||
@@ -1768,7 +1769,7 @@ writeback:
|
||||
|
||||
/* Commit shadow register state. */
|
||||
memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);
|
||||
ctxt->vcpu->arch.rip = c->eip;
|
||||
kvm_rip_write(ctxt->vcpu, c->eip);
|
||||
|
||||
done:
|
||||
if (rc == X86EMUL_UNHANDLEABLE) {
|
||||
@@ -1793,7 +1794,7 @@ twobyte_insn:
|
||||
goto done;
|
||||
|
||||
/* Let the processor re-execute the fixed hypercall */
|
||||
c->eip = ctxt->vcpu->arch.rip;
|
||||
c->eip = kvm_rip_read(ctxt->vcpu);
|
||||
/* Disable writeback. */
|
||||
c->dst.type = OP_NONE;
|
||||
break;
|
||||
@@ -1889,7 +1890,7 @@ twobyte_insn:
|
||||
rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data);
|
||||
if (rc) {
|
||||
kvm_inject_gp(ctxt->vcpu, 0);
|
||||
c->eip = ctxt->vcpu->arch.rip;
|
||||
c->eip = kvm_rip_read(ctxt->vcpu);
|
||||
}
|
||||
rc = X86EMUL_CONTINUE;
|
||||
c->dst.type = OP_NONE;
|
||||
@@ -1899,7 +1900,7 @@ twobyte_insn:
|
||||
rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
|
||||
if (rc) {
|
||||
kvm_inject_gp(ctxt->vcpu, 0);
|
||||
c->eip = ctxt->vcpu->arch.rip;
|
||||
c->eip = kvm_rip_read(ctxt->vcpu);
|
||||
} else {
|
||||
c->regs[VCPU_REGS_RAX] = (u32)msr_data;
|
||||
c->regs[VCPU_REGS_RDX] = msr_data >> 32;
|
||||
|
Reference in New Issue
Block a user