diff options
author | Wei Yongjun <yjwei@cn.fujitsu.com> | 2010-08-04 03:38:18 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:00 -0400 |
commit | 36089fed70337f4d96a5c3aa7fadc4095b707f73 (patch) | |
tree | 72f8450214eaa8769ec75df3c0dddce8d3bc2f0e /arch/x86/kvm/emulate.c | |
parent | 06cb704611caf40e531a3835809283f14f5307d5 (diff) |
KVM: x86 emulator: disable writeback when decode dest operand
This patch change to disable writeback when decode dest
operand if the dest type is ImplicitOps or not specified.
Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 23 |
1 files changed, 6 insertions, 17 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 6c1e4d6c12cd..e0216eb8b574 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2627,9 +2627,6 @@ done_prefixes: | |||
2627 | 2627 | ||
2628 | /* Decode and fetch the destination operand: register or memory. */ | 2628 | /* Decode and fetch the destination operand: register or memory. */ |
2629 | switch (c->d & DstMask) { | 2629 | switch (c->d & DstMask) { |
2630 | case ImplicitOps: | ||
2631 | /* Special instructions do their own operand decoding. */ | ||
2632 | return 0; | ||
2633 | case DstReg: | 2630 | case DstReg: |
2634 | decode_register_operand(&c->dst, c, | 2631 | decode_register_operand(&c->dst, c, |
2635 | c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); | 2632 | c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); |
@@ -2664,6 +2661,11 @@ done_prefixes: | |||
2664 | c->regs[VCPU_REGS_RDI]); | 2661 | c->regs[VCPU_REGS_RDI]); |
2665 | c->dst.val = 0; | 2662 | c->dst.val = 0; |
2666 | break; | 2663 | break; |
2664 | case ImplicitOps: | ||
2665 | /* Special instructions do their own operand decoding. */ | ||
2666 | default: | ||
2667 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
2668 | return 0; | ||
2667 | } | 2669 | } |
2668 | 2670 | ||
2669 | done: | 2671 | done: |
@@ -3115,7 +3117,6 @@ special_insn: | |||
3115 | case 0xf5: /* cmc */ | 3117 | case 0xf5: /* cmc */ |
3116 | /* complement carry flag from eflags reg */ | 3118 | /* complement carry flag from eflags reg */ |
3117 | ctxt->eflags ^= EFLG_CF; | 3119 | ctxt->eflags ^= EFLG_CF; |
3118 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
3119 | break; | 3120 | break; |
3120 | case 0xf6 ... 0xf7: /* Grp3 */ | 3121 | case 0xf6 ... 0xf7: /* Grp3 */ |
3121 | if (!emulate_grp3(ctxt, ops)) | 3122 | if (!emulate_grp3(ctxt, ops)) |
@@ -3123,16 +3124,13 @@ special_insn: | |||
3123 | break; | 3124 | break; |
3124 | case 0xf8: /* clc */ | 3125 | case 0xf8: /* clc */ |
3125 | ctxt->eflags &= ~EFLG_CF; | 3126 | ctxt->eflags &= ~EFLG_CF; |
3126 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
3127 | break; | 3127 | break; |
3128 | case 0xfa: /* cli */ | 3128 | case 0xfa: /* cli */ |
3129 | if (emulator_bad_iopl(ctxt, ops)) { | 3129 | if (emulator_bad_iopl(ctxt, ops)) { |
3130 | emulate_gp(ctxt, 0); | 3130 | emulate_gp(ctxt, 0); |
3131 | goto done; | 3131 | goto done; |
3132 | } else { | 3132 | } else |
3133 | ctxt->eflags &= ~X86_EFLAGS_IF; | 3133 | ctxt->eflags &= ~X86_EFLAGS_IF; |
3134 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
3135 | } | ||
3136 | break; | 3134 | break; |
3137 | case 0xfb: /* sti */ | 3135 | case 0xfb: /* sti */ |
3138 | if (emulator_bad_iopl(ctxt, ops)) { | 3136 | if (emulator_bad_iopl(ctxt, ops)) { |
@@ -3141,16 +3139,13 @@ special_insn: | |||
3141 | } else { | 3139 | } else { |
3142 | ctxt->interruptibility = KVM_X86_SHADOW_INT_STI; | 3140 | ctxt->interruptibility = KVM_X86_SHADOW_INT_STI; |
3143 | ctxt->eflags |= X86_EFLAGS_IF; | 3141 | ctxt->eflags |= X86_EFLAGS_IF; |
3144 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
3145 | } | 3142 | } |
3146 | break; | 3143 | break; |
3147 | case 0xfc: /* cld */ | 3144 | case 0xfc: /* cld */ |
3148 | ctxt->eflags &= ~EFLG_DF; | 3145 | ctxt->eflags &= ~EFLG_DF; |
3149 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
3150 | break; | 3146 | break; |
3151 | case 0xfd: /* std */ | 3147 | case 0xfd: /* std */ |
3152 | ctxt->eflags |= EFLG_DF; | 3148 | ctxt->eflags |= EFLG_DF; |
3153 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
3154 | break; | 3149 | break; |
3155 | case 0xfe: /* Grp4 */ | 3150 | case 0xfe: /* Grp4 */ |
3156 | grp45: | 3151 | grp45: |
@@ -3287,16 +3282,13 @@ twobyte_insn: | |||
3287 | break; | 3282 | break; |
3288 | case 0x06: | 3283 | case 0x06: |
3289 | emulate_clts(ctxt->vcpu); | 3284 | emulate_clts(ctxt->vcpu); |
3290 | c->dst.type = OP_NONE; | ||
3291 | break; | 3285 | break; |
3292 | case 0x09: /* wbinvd */ | 3286 | case 0x09: /* wbinvd */ |
3293 | kvm_emulate_wbinvd(ctxt->vcpu); | 3287 | kvm_emulate_wbinvd(ctxt->vcpu); |
3294 | c->dst.type = OP_NONE; | ||
3295 | break; | 3288 | break; |
3296 | case 0x08: /* invd */ | 3289 | case 0x08: /* invd */ |
3297 | case 0x0d: /* GrpP (prefetch) */ | 3290 | case 0x0d: /* GrpP (prefetch) */ |
3298 | case 0x18: /* Grp16 (prefetch/nop) */ | 3291 | case 0x18: /* Grp16 (prefetch/nop) */ |
3299 | c->dst.type = OP_NONE; | ||
3300 | break; | 3292 | break; |
3301 | case 0x20: /* mov cr, reg */ | 3293 | case 0x20: /* mov cr, reg */ |
3302 | switch (c->modrm_reg) { | 3294 | switch (c->modrm_reg) { |
@@ -3349,7 +3341,6 @@ twobyte_insn: | |||
3349 | goto done; | 3341 | goto done; |
3350 | } | 3342 | } |
3351 | rc = X86EMUL_CONTINUE; | 3343 | rc = X86EMUL_CONTINUE; |
3352 | c->dst.type = OP_NONE; | ||
3353 | break; | 3344 | break; |
3354 | case 0x32: | 3345 | case 0x32: |
3355 | /* rdmsr */ | 3346 | /* rdmsr */ |
@@ -3361,7 +3352,6 @@ twobyte_insn: | |||
3361 | c->regs[VCPU_REGS_RDX] = msr_data >> 32; | 3352 | c->regs[VCPU_REGS_RDX] = msr_data >> 32; |
3362 | } | 3353 | } |
3363 | rc = X86EMUL_CONTINUE; | 3354 | rc = X86EMUL_CONTINUE; |
3364 | c->dst.type = OP_NONE; | ||
3365 | break; | 3355 | break; |
3366 | case 0x34: /* sysenter */ | 3356 | case 0x34: /* sysenter */ |
3367 | rc = emulate_sysenter(ctxt, ops); | 3357 | rc = emulate_sysenter(ctxt, ops); |
@@ -3385,7 +3375,6 @@ twobyte_insn: | |||
3385 | case 0x80 ... 0x8f: /* jnz rel, etc*/ | 3375 | case 0x80 ... 0x8f: /* jnz rel, etc*/ |
3386 | if (test_cc(c->b, ctxt->eflags)) | 3376 | if (test_cc(c->b, ctxt->eflags)) |
3387 | jmp_rel(c, c->src.val); | 3377 | jmp_rel(c, c->src.val); |
3388 | c->dst.type = OP_NONE; | ||
3389 | break; | 3378 | break; |
3390 | case 0xa0: /* push fs */ | 3379 | case 0xa0: /* push fs */ |
3391 | emulate_push_sreg(ctxt, ops, VCPU_SREG_FS); | 3380 | emulate_push_sreg(ctxt, ops, VCPU_SREG_FS); |