aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/cpuid.c18
-rw-r--r--arch/x86/kvm/emulate.c53
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)
222static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, 222static 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
2966static 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
2964static int em_cr_write(struct x86_emulate_ctxt *ctxt) 3004static 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
3895static const struct gprefix three_byte_0f_38_f0 = { 3935static 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
3899static const struct gprefix three_byte_0f_38_f1 = { 3939static 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 = {
3907static const struct opcode opcode_map_0f_38[256] = { 3947static 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