diff options
-rw-r--r-- | arch/x86/kvm/cpuid.c | 18 | ||||
-rw-r--r-- | arch/x86/kvm/emulate.c | 53 |
2 files changed, 66 insertions, 5 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 78a4439bfdc5..86d5756dda07 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
@@ -222,6 +222,22 @@ static bool supported_xcr0_bit(unsigned bit) | |||
222 | static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, | 222 | static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, |
223 | u32 func, u32 index, int *nent, int maxnent) | 223 | u32 func, u32 index, int *nent, int maxnent) |
224 | { | 224 | { |
225 | switch (func) { | ||
226 | case 0: | ||
227 | entry->eax = 1; /* only one leaf currently */ | ||
228 | ++*nent; | ||
229 | break; | ||
230 | case 1: | ||
231 | entry->ecx = F(MOVBE); | ||
232 | ++*nent; | ||
233 | break; | ||
234 | default: | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | entry->function = func; | ||
239 | entry->index = index; | ||
240 | |||
225 | return 0; | 241 | return 0; |
226 | } | 242 | } |
227 | 243 | ||
@@ -593,7 +609,7 @@ int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, | |||
593 | return -EINVAL; | 609 | return -EINVAL; |
594 | 610 | ||
595 | r = -ENOMEM; | 611 | r = -ENOMEM; |
596 | cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); | 612 | cpuid_entries = vzalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); |
597 | if (!cpuid_entries) | 613 | if (!cpuid_entries) |
598 | goto out; | 614 | goto out; |
599 | 615 | ||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 6c5cfe962b28..8e2a07bd8eac 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2961,6 +2961,46 @@ static int em_mov(struct x86_emulate_ctxt *ctxt) | |||
2961 | return X86EMUL_CONTINUE; | 2961 | return X86EMUL_CONTINUE; |
2962 | } | 2962 | } |
2963 | 2963 | ||
2964 | #define FFL(x) bit(X86_FEATURE_##x) | ||
2965 | |||
2966 | static int em_movbe(struct x86_emulate_ctxt *ctxt) | ||
2967 | { | ||
2968 | u32 ebx, ecx, edx, eax = 1; | ||
2969 | u16 tmp; | ||
2970 | |||
2971 | /* | ||
2972 | * Check MOVBE is set in the guest-visible CPUID leaf. | ||
2973 | */ | ||
2974 | ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); | ||
2975 | if (!(ecx & FFL(MOVBE))) | ||
2976 | return emulate_ud(ctxt); | ||
2977 | |||
2978 | switch (ctxt->op_bytes) { | ||
2979 | case 2: | ||
2980 | /* | ||
2981 | * From MOVBE definition: "...When the operand size is 16 bits, | ||
2982 | * the upper word of the destination register remains unchanged | ||
2983 | * ..." | ||
2984 | * | ||
2985 | * Both casting ->valptr and ->val to u16 breaks strict aliasing | ||
2986 | * rules so we have to do the operation almost per hand. | ||
2987 | */ | ||
2988 | tmp = (u16)ctxt->src.val; | ||
2989 | ctxt->dst.val &= ~0xffffUL; | ||
2990 | ctxt->dst.val |= (unsigned long)swab16(tmp); | ||
2991 | break; | ||
2992 | case 4: | ||
2993 | ctxt->dst.val = swab32((u32)ctxt->src.val); | ||
2994 | break; | ||
2995 | case 8: | ||
2996 | ctxt->dst.val = swab64(ctxt->src.val); | ||
2997 | break; | ||
2998 | default: | ||
2999 | return X86EMUL_PROPAGATE_FAULT; | ||
3000 | } | ||
3001 | return X86EMUL_CONTINUE; | ||
3002 | } | ||
3003 | |||
2964 | static int em_cr_write(struct x86_emulate_ctxt *ctxt) | 3004 | static int em_cr_write(struct x86_emulate_ctxt *ctxt) |
2965 | { | 3005 | { |
2966 | if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) | 3006 | if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) |
@@ -3893,11 +3933,11 @@ static const struct opcode twobyte_table[256] = { | |||
3893 | }; | 3933 | }; |
3894 | 3934 | ||
3895 | static const struct gprefix three_byte_0f_38_f0 = { | 3935 | static const struct gprefix three_byte_0f_38_f0 = { |
3896 | N, N, N, N | 3936 | I(DstReg | SrcMem | Mov, em_movbe), N, N, N |
3897 | }; | 3937 | }; |
3898 | 3938 | ||
3899 | static const struct gprefix three_byte_0f_38_f1 = { | 3939 | static const struct gprefix three_byte_0f_38_f1 = { |
3900 | N, N, N, N | 3940 | I(DstMem | SrcReg | Mov, em_movbe), N, N, N |
3901 | }; | 3941 | }; |
3902 | 3942 | ||
3903 | /* | 3943 | /* |
@@ -3907,8 +3947,13 @@ static const struct gprefix three_byte_0f_38_f1 = { | |||
3907 | static const struct opcode opcode_map_0f_38[256] = { | 3947 | static const struct opcode opcode_map_0f_38[256] = { |
3908 | /* 0x00 - 0x7f */ | 3948 | /* 0x00 - 0x7f */ |
3909 | X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), | 3949 | X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), |
3910 | /* 0x80 - 0xff */ | 3950 | /* 0x80 - 0xef */ |
3911 | X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N) | 3951 | X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), |
3952 | /* 0xf0 - 0xf1 */ | ||
3953 | GP(EmulateOnUD | ModRM | Prefix, &three_byte_0f_38_f0), | ||
3954 | GP(EmulateOnUD | ModRM | Prefix, &three_byte_0f_38_f1), | ||
3955 | /* 0xf2 - 0xff */ | ||
3956 | N, N, X4(N), X8(N) | ||
3912 | }; | 3957 | }; |
3913 | 3958 | ||
3914 | #undef D | 3959 | #undef D |