aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2008-06-27 13:58:02 -0400
committerAvi Kivity <avi@qumranet.com>2008-10-15 04:13:57 -0400
commit5fdbf9765b7ba6a45100851154768de703d51e76 (patch)
treeec34ec9357575dc4190e5228a6eabfd5f81b66a5 /arch/x86/kvm/x86_emulate.c
parentca60dfbb69afb549e33527cbf676e4daf8febfb5 (diff)
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>
Diffstat (limited to 'arch/x86/kvm/x86_emulate.c')
-rw-r--r--arch/x86/kvm/x86_emulate.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index f2f90468f8b1..d5da7f14d536 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -26,6 +26,7 @@
26#define DPRINTF(_f, _a ...) printf(_f , ## _a) 26#define DPRINTF(_f, _a ...) printf(_f , ## _a)
27#else 27#else
28#include <linux/kvm_host.h> 28#include <linux/kvm_host.h>
29#include "kvm_cache_regs.h"
29#define DPRINTF(x...) do {} while (0) 30#define DPRINTF(x...) do {} while (0)
30#endif 31#endif
31#include <linux/module.h> 32#include <linux/module.h>
@@ -839,7 +840,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
839 /* Shadow copy of register state. Committed on successful emulation. */ 840 /* Shadow copy of register state. Committed on successful emulation. */
840 841
841 memset(c, 0, sizeof(struct decode_cache)); 842 memset(c, 0, sizeof(struct decode_cache));
842 c->eip = ctxt->vcpu->arch.rip; 843 c->eip = kvm_rip_read(ctxt->vcpu);
843 ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); 844 ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
844 memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); 845 memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
845 846
@@ -1267,7 +1268,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1267 if (c->rep_prefix && (c->d & String)) { 1268 if (c->rep_prefix && (c->d & String)) {
1268 /* All REP prefixes have the same first termination condition */ 1269 /* All REP prefixes have the same first termination condition */
1269 if (c->regs[VCPU_REGS_RCX] == 0) { 1270 if (c->regs[VCPU_REGS_RCX] == 0) {
1270 ctxt->vcpu->arch.rip = c->eip; 1271 kvm_rip_write(ctxt->vcpu, c->eip);
1271 goto done; 1272 goto done;
1272 } 1273 }
1273 /* The second termination condition only applies for REPE 1274 /* 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)
1281 (c->b == 0xae) || (c->b == 0xaf)) { 1282 (c->b == 0xae) || (c->b == 0xaf)) {
1282 if ((c->rep_prefix == REPE_PREFIX) && 1283 if ((c->rep_prefix == REPE_PREFIX) &&
1283 ((ctxt->eflags & EFLG_ZF) == 0)) { 1284 ((ctxt->eflags & EFLG_ZF) == 0)) {
1284 ctxt->vcpu->arch.rip = c->eip; 1285 kvm_rip_write(ctxt->vcpu, c->eip);
1285 goto done; 1286 goto done;
1286 } 1287 }
1287 if ((c->rep_prefix == REPNE_PREFIX) && 1288 if ((c->rep_prefix == REPNE_PREFIX) &&
1288 ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) { 1289 ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) {
1289 ctxt->vcpu->arch.rip = c->eip; 1290 kvm_rip_write(ctxt->vcpu, c->eip);
1290 goto done; 1291 goto done;
1291 } 1292 }
1292 } 1293 }
1293 c->regs[VCPU_REGS_RCX]--; 1294 c->regs[VCPU_REGS_RCX]--;
1294 c->eip = ctxt->vcpu->arch.rip; 1295 c->eip = kvm_rip_read(ctxt->vcpu);
1295 } 1296 }
1296 1297
1297 if (c->src.type == OP_MEM) { 1298 if (c->src.type == OP_MEM) {
@@ -1768,7 +1769,7 @@ writeback:
1768 1769
1769 /* Commit shadow register state. */ 1770 /* Commit shadow register state. */
1770 memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); 1771 memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);
1771 ctxt->vcpu->arch.rip = c->eip; 1772 kvm_rip_write(ctxt->vcpu, c->eip);
1772 1773
1773done: 1774done:
1774 if (rc == X86EMUL_UNHANDLEABLE) { 1775 if (rc == X86EMUL_UNHANDLEABLE) {
@@ -1793,7 +1794,7 @@ twobyte_insn:
1793 goto done; 1794 goto done;
1794 1795
1795 /* Let the processor re-execute the fixed hypercall */ 1796 /* Let the processor re-execute the fixed hypercall */
1796 c->eip = ctxt->vcpu->arch.rip; 1797 c->eip = kvm_rip_read(ctxt->vcpu);
1797 /* Disable writeback. */ 1798 /* Disable writeback. */
1798 c->dst.type = OP_NONE; 1799 c->dst.type = OP_NONE;
1799 break; 1800 break;
@@ -1889,7 +1890,7 @@ twobyte_insn:
1889 rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data); 1890 rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data);
1890 if (rc) { 1891 if (rc) {
1891 kvm_inject_gp(ctxt->vcpu, 0); 1892 kvm_inject_gp(ctxt->vcpu, 0);
1892 c->eip = ctxt->vcpu->arch.rip; 1893 c->eip = kvm_rip_read(ctxt->vcpu);
1893 } 1894 }
1894 rc = X86EMUL_CONTINUE; 1895 rc = X86EMUL_CONTINUE;
1895 c->dst.type = OP_NONE; 1896 c->dst.type = OP_NONE;
@@ -1899,7 +1900,7 @@ twobyte_insn:
1899 rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data); 1900 rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
1900 if (rc) { 1901 if (rc) {
1901 kvm_inject_gp(ctxt->vcpu, 0); 1902 kvm_inject_gp(ctxt->vcpu, 0);
1902 c->eip = ctxt->vcpu->arch.rip; 1903 c->eip = kvm_rip_read(ctxt->vcpu);
1903 } else { 1904 } else {
1904 c->regs[VCPU_REGS_RAX] = (u32)msr_data; 1905 c->regs[VCPU_REGS_RAX] = (u32)msr_data;
1905 c->regs[VCPU_REGS_RDX] = msr_data >> 32; 1906 c->regs[VCPU_REGS_RDX] = msr_data >> 32;