diff options
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/emulate.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 799000d8bf8b..4cd3313b4131 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2921,6 +2921,40 @@ static int em_btc(struct x86_emulate_ctxt *ctxt) | |||
2921 | return X86EMUL_CONTINUE; | 2921 | return X86EMUL_CONTINUE; |
2922 | } | 2922 | } |
2923 | 2923 | ||
2924 | static int em_bsf(struct x86_emulate_ctxt *ctxt) | ||
2925 | { | ||
2926 | u8 zf; | ||
2927 | |||
2928 | __asm__ ("bsf %2, %0; setz %1" | ||
2929 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
2930 | : "r"(ctxt->src.val)); | ||
2931 | |||
2932 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
2933 | if (zf) { | ||
2934 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
2935 | /* Disable writeback. */ | ||
2936 | ctxt->dst.type = OP_NONE; | ||
2937 | } | ||
2938 | return X86EMUL_CONTINUE; | ||
2939 | } | ||
2940 | |||
2941 | static int em_bsr(struct x86_emulate_ctxt *ctxt) | ||
2942 | { | ||
2943 | u8 zf; | ||
2944 | |||
2945 | __asm__ ("bsr %2, %0; setz %1" | ||
2946 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
2947 | : "r"(ctxt->src.val)); | ||
2948 | |||
2949 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
2950 | if (zf) { | ||
2951 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
2952 | /* Disable writeback. */ | ||
2953 | ctxt->dst.type = OP_NONE; | ||
2954 | } | ||
2955 | return X86EMUL_CONTINUE; | ||
2956 | } | ||
2957 | |||
2924 | static bool valid_cr(int nr) | 2958 | static bool valid_cr(int nr) |
2925 | { | 2959 | { |
2926 | switch (nr) { | 2960 | switch (nr) { |
@@ -3428,7 +3462,7 @@ static struct opcode twobyte_table[256] = { | |||
3428 | N, N, | 3462 | N, N, |
3429 | G(BitOp, group8), | 3463 | G(BitOp, group8), |
3430 | I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc), | 3464 | I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc), |
3431 | D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), | 3465 | I(DstReg | SrcMem | ModRM, em_bsf), I(DstReg | SrcMem | ModRM, em_bsr), |
3432 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), | 3466 | D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), |
3433 | /* 0xC0 - 0xCF */ | 3467 | /* 0xC0 - 0xCF */ |
3434 | D2bv(DstMem | SrcReg | ModRM | Lock), | 3468 | D2bv(DstMem | SrcReg | ModRM | Lock), |
@@ -4176,30 +4210,6 @@ twobyte_insn: | |||
4176 | ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val | 4210 | ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val |
4177 | : (u16) ctxt->src.val; | 4211 | : (u16) ctxt->src.val; |
4178 | break; | 4212 | break; |
4179 | case 0xbc: { /* bsf */ | ||
4180 | u8 zf; | ||
4181 | __asm__ ("bsf %2, %0; setz %1" | ||
4182 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
4183 | : "r"(ctxt->src.val)); | ||
4184 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
4185 | if (zf) { | ||
4186 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
4187 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ | ||
4188 | } | ||
4189 | break; | ||
4190 | } | ||
4191 | case 0xbd: { /* bsr */ | ||
4192 | u8 zf; | ||
4193 | __asm__ ("bsr %2, %0; setz %1" | ||
4194 | : "=r"(ctxt->dst.val), "=q"(zf) | ||
4195 | : "r"(ctxt->src.val)); | ||
4196 | ctxt->eflags &= ~X86_EFLAGS_ZF; | ||
4197 | if (zf) { | ||
4198 | ctxt->eflags |= X86_EFLAGS_ZF; | ||
4199 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ | ||
4200 | } | ||
4201 | break; | ||
4202 | } | ||
4203 | case 0xbe ... 0xbf: /* movsx */ | 4213 | case 0xbe ... 0xbf: /* movsx */ |
4204 | ctxt->dst.bytes = ctxt->op_bytes; | 4214 | ctxt->dst.bytes = ctxt->op_bytes; |
4205 | ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val : | 4215 | ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val : |