diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2008-06-27 13:58:02 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-10-15 04:13:57 -0400 |
commit | 5fdbf9765b7ba6a45100851154768de703d51e76 (patch) | |
tree | ec34ec9357575dc4190e5228a6eabfd5f81b66a5 /arch/x86/kvm/x86_emulate.c | |
parent | ca60dfbb69afb549e33527cbf676e4daf8febfb5 (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.c | 19 |
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 | ||
1773 | done: | 1774 | done: |
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; |