OSDN Git Service

Merge tag 'v4.4.214' into 10
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / arch / x86 / kvm / emulate.c
index 6c7847b..ffbdd20 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kvm_host.h>
 #include "kvm_cache_regs.h"
 #include <linux/module.h>
+#include <linux/nospec.h>
 #include <asm/kvm_emulate.h>
 #include <linux/stringify.h>
 #include <asm/debugreg.h>
@@ -5041,16 +5042,28 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
                                ctxt->ad_bytes = def_ad_bytes ^ 6;
                        break;
                case 0x26:      /* ES override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_ES;
+                       break;
                case 0x2e:      /* CS override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_CS;
+                       break;
                case 0x36:      /* SS override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_SS;
+                       break;
                case 0x3e:      /* DS override */
                        has_seg_override = true;
-                       ctxt->seg_override = (ctxt->b >> 3) & 3;
+                       ctxt->seg_override = VCPU_SREG_DS;
                        break;
                case 0x64:      /* FS override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_FS;
+                       break;
                case 0x65:      /* GS override */
                        has_seg_override = true;
-                       ctxt->seg_override = ctxt->b & 7;
+                       ctxt->seg_override = VCPU_SREG_GS;
                        break;
                case 0x40 ... 0x4f: /* REX */
                        if (mode != X86EMUL_MODE_PROT64)
@@ -5134,10 +5147,15 @@ done_prefixes:
                        }
                        break;
                case Escape:
-                       if (ctxt->modrm > 0xbf)
-                               opcode = opcode.u.esc->high[ctxt->modrm - 0xc0];
-                       else
+                       if (ctxt->modrm > 0xbf) {
+                               size_t size = ARRAY_SIZE(opcode.u.esc->high);
+                               u32 index = array_index_nospec(
+                                       ctxt->modrm - 0xc0, size);
+
+                               opcode = opcode.u.esc->high[index];
+                       } else {
                                opcode = opcode.u.esc->op[(ctxt->modrm >> 3) & 7];
+                       }
                        break;
                case InstrDual:
                        if ((ctxt->modrm >> 6) == 3)