diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2b6c24e572d..a81486790ba 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -104,6 +104,7 @@ | |||
104 | 104 | ||
105 | struct opcode { | 105 | struct opcode { |
106 | u32 flags; | 106 | u32 flags; |
107 | u8 intercept; | ||
107 | union { | 108 | union { |
108 | int (*execute)(struct x86_emulate_ctxt *ctxt); | 109 | int (*execute)(struct x86_emulate_ctxt *ctxt); |
109 | struct opcode *group; | 110 | struct opcode *group; |
@@ -2423,10 +2424,13 @@ static int em_movdqu(struct x86_emulate_ctxt *ctxt) | |||
2423 | } | 2424 | } |
2424 | 2425 | ||
2425 | #define D(_y) { .flags = (_y) } | 2426 | #define D(_y) { .flags = (_y) } |
2427 | #define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i } | ||
2426 | #define N D(0) | 2428 | #define N D(0) |
2427 | #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) } | 2429 | #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) } |
2428 | #define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) } | 2430 | #define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) } |
2429 | #define I(_f, _e) { .flags = (_f), .u.execute = (_e) } | 2431 | #define I(_f, _e) { .flags = (_f), .u.execute = (_e) } |
2432 | #define II(_f, _e, _i) \ | ||
2433 | { .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i } | ||
2430 | #define GP(_f, _g) { .flags = ((_f) | Prefix), .u.gprefix = (_g) } | 2434 | #define GP(_f, _g) { .flags = ((_f) | Prefix), .u.gprefix = (_g) } |
2431 | 2435 | ||
2432 | #define D2bv(_f) D((_f) | ByteOp), D(_f) | 2436 | #define D2bv(_f) D((_f) | ByteOp), D(_f) |
@@ -2867,6 +2871,7 @@ done_prefixes: | |||
2867 | } | 2871 | } |
2868 | 2872 | ||
2869 | c->execute = opcode.u.execute; | 2873 | c->execute = opcode.u.execute; |
2874 | c->intercept = opcode.intercept; | ||
2870 | 2875 | ||
2871 | /* Unrecognised? */ | 2876 | /* Unrecognised? */ |
2872 | if (c->d == 0 || (c->d & Undefined)) | 2877 | if (c->d == 0 || (c->d & Undefined)) |
@@ -3116,12 +3121,26 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
3116 | goto done; | 3121 | goto done; |
3117 | } | 3122 | } |
3118 | 3123 | ||
3124 | if (unlikely(ctxt->guest_mode) && c->intercept) { | ||
3125 | rc = ops->intercept(ctxt, c->intercept, | ||
3126 | X86_ICPT_PRE_EXCEPT); | ||
3127 | if (rc != X86EMUL_CONTINUE) | ||
3128 | goto done; | ||
3129 | } | ||
3130 | |||
3119 | /* Privileged instruction can be executed only in CPL=0 */ | 3131 | /* Privileged instruction can be executed only in CPL=0 */ |
3120 | if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) { | 3132 | if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) { |
3121 | rc = emulate_gp(ctxt, 0); | 3133 | rc = emulate_gp(ctxt, 0); |
3122 | goto done; | 3134 | goto done; |
3123 | } | 3135 | } |
3124 | 3136 | ||
3137 | if (unlikely(ctxt->guest_mode) && c->intercept) { | ||
3138 | rc = ops->intercept(ctxt, c->intercept, | ||
3139 | X86_ICPT_POST_EXCEPT); | ||
3140 | if (rc != X86EMUL_CONTINUE) | ||
3141 | goto done; | ||
3142 | } | ||
3143 | |||
3125 | if (c->rep_prefix && (c->d & String)) { | 3144 | if (c->rep_prefix && (c->d & String)) { |
3126 | /* All REP prefixes have the same first termination condition */ | 3145 | /* All REP prefixes have the same first termination condition */ |
3127 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { | 3146 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { |
@@ -3160,6 +3179,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
3160 | 3179 | ||
3161 | special_insn: | 3180 | special_insn: |
3162 | 3181 | ||
3182 | if (unlikely(ctxt->guest_mode) && c->intercept) { | ||
3183 | rc = ops->intercept(ctxt, c->intercept, | ||
3184 | X86_ICPT_POST_MEMACCESS); | ||
3185 | if (rc != X86EMUL_CONTINUE) | ||
3186 | goto done; | ||
3187 | } | ||
3188 | |||
3163 | if (c->execute) { | 3189 | if (c->execute) { |
3164 | rc = c->execute(ctxt); | 3190 | rc = c->execute(ctxt); |
3165 | if (rc != X86EMUL_CONTINUE) | 3191 | if (rc != X86EMUL_CONTINUE) |