Commit 6e2a3064 authored by Ricardo Neri's avatar Ricardo Neri Committed by Ingo Molnar

x86/umip: Identify the STR and SLDT instructions

The STR and SLDT instructions are not emulated by the UMIP code, thus
there's no functionality in the decoder to identify them.

However, a subsequent commit will introduce a warning about the use
of all the instructions that UMIP protect/changes, not only those that
are emulated.

A first step for that is to add the ability to decode/identify them.

Plus, now that STR and SLDT are identified, we need to explicitly avoid
their emulation (i.e., not rely on successful identification). Group
together all the cases that we do not want to emulate: STR, SLDT and user
long mode processes.
Signed-off-by: default avatarRicardo Neri <ricardo.neri-calderon@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi V. Shankar <ravi.v.shankar@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: ricardo.neri@intel.com
Link: http://lkml.kernel.org/r/1510640985-18412-4-git-send-email-ricardo.neri-calderon@linux.intel.com
[ Rewrote the changelog, fixed ugly col80 artifact. ]
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 770c7755
...@@ -78,7 +78,9 @@ ...@@ -78,7 +78,9 @@
#define UMIP_INST_SGDT 0 /* 0F 01 /0 */ #define UMIP_INST_SGDT 0 /* 0F 01 /0 */
#define UMIP_INST_SIDT 1 /* 0F 01 /1 */ #define UMIP_INST_SIDT 1 /* 0F 01 /1 */
#define UMIP_INST_SMSW 3 /* 0F 01 /4 */ #define UMIP_INST_SMSW 2 /* 0F 01 /4 */
#define UMIP_INST_SLDT 3 /* 0F 00 /0 */
#define UMIP_INST_STR 4 /* 0F 00 /1 */
/** /**
* identify_insn() - Identify a UMIP-protected instruction * identify_insn() - Identify a UMIP-protected instruction
...@@ -118,10 +120,16 @@ static int identify_insn(struct insn *insn) ...@@ -118,10 +120,16 @@ static int identify_insn(struct insn *insn)
default: default:
return -EINVAL; return -EINVAL;
} }
} else if (insn->opcode.bytes[1] == 0x0) {
if (X86_MODRM_REG(insn->modrm.value) == 0)
return UMIP_INST_SLDT;
else if (X86_MODRM_REG(insn->modrm.value) == 1)
return UMIP_INST_STR;
else
return -EINVAL;
} else {
return -EINVAL;
} }
/* SLDT AND STR are not emulated */
return -EINVAL;
} }
/** /**
...@@ -267,10 +275,6 @@ bool fixup_umip_exception(struct pt_regs *regs) ...@@ -267,10 +275,6 @@ bool fixup_umip_exception(struct pt_regs *regs)
if (!regs) if (!regs)
return false; return false;
/* Do not emulate 64-bit processes. */
if (user_64bit_mode(regs))
return false;
/* /*
* If not in user-space long mode, a custom code segment could be in * If not in user-space long mode, a custom code segment could be in
* use. This is true in protected mode (if the process defined a local * use. This is true in protected mode (if the process defined a local
...@@ -322,6 +326,10 @@ bool fixup_umip_exception(struct pt_regs *regs) ...@@ -322,6 +326,10 @@ bool fixup_umip_exception(struct pt_regs *regs)
if (umip_inst < 0) if (umip_inst < 0)
return false; return false;
/* Do not emulate SLDT, STR or user long mode processes. */
if (umip_inst == UMIP_INST_STR || umip_inst == UMIP_INST_SLDT || user_64bit_mode(regs))
return false;
if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size)) if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size))
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment