summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2018-08-02 12:53:50 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2018-08-02 12:53:50 -0400
commit000447dc0d892a41d1f7c9989885cde9cb95a86f (patch)
tree90c39aed07e2d29f96ce21d7cbf10c75a1f86602
parentc145b880adcfb776561e3fe5417c805a35878864 (diff)
downloadlongterm-queue-4.12-000447dc0d892a41d1f7c9989885cde9cb95a86f.tar.gz
x86: drop insn commit; breaks build
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--queue/series1
-rw-r--r--queue/x86-insn-eval-Add-utility-functions-to-get-segment-s.patch463
2 files changed, 0 insertions, 464 deletions
diff --git a/queue/series b/queue/series
index 42f9a28..c0ba19c 100644
--- a/queue/series
+++ b/queue/series
@@ -50,7 +50,6 @@ bpf-s390x-do-not-reload-skb-pointers-in-non-skb-cont.patch
bpf-ppc64-do-not-reload-skb-pointers-in-non-skb-cont.patch
bpf-sparc-fix-usage-of-wrong-reg-for-load_skb_regs-a.patch
bpf-fix-incorrect-sign-extension-in-check_alu_op.patch
-x86-insn-eval-Add-utility-functions-to-get-segment-s.patch
ACPI-APEI-ERST-Fix-missing-error-handling-in-erst_re.patch
acpi-nfit-fix-health-event-notification.patch
crypto-mcryptd-protect-the-per-CPU-queue-with-a-lock.patch
diff --git a/queue/x86-insn-eval-Add-utility-functions-to-get-segment-s.patch b/queue/x86-insn-eval-Add-utility-functions-to-get-segment-s.patch
deleted file mode 100644
index 2fe51ef..0000000
--- a/queue/x86-insn-eval-Add-utility-functions-to-get-segment-s.patch
+++ /dev/null
@@ -1,463 +0,0 @@
-From c3719f8bb7ae0249b00882e9f8a9b3989d4f367c Mon Sep 17 00:00:00 2001
-From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
-Date: Fri, 27 Oct 2017 13:25:40 -0700
-Subject: [PATCH] x86/insn-eval: Add utility functions to get segment selector
-
-commit 32d0b95300db03c2b23b2ea2c94769a4a138e79d upstream.
-
-When computing a linear address and segmentation is used, we need to know
-the base address of the segment involved in the computation. In most of
-the cases, the segment base address will be zero as in USER_DS/USER32_DS.
-However, it may be possible that a user space program defines its own
-segments via a local descriptor table. In such a case, the segment base
-address may not be zero. Thus, the segment base address is needed to
-calculate correctly the linear address.
-
-If running in protected mode, the segment selector to be used when
-computing a linear address is determined by either any of segment override
-prefixes in the instruction or inferred from the registers involved in the
-computation of the effective address; in that order. Also, there are cases
-when the segment override prefixes shall be ignored (i.e., code segments
-are always selected by the CS segment register; string instructions always
-use the ES segment register when using rDI register as operand). In long
-mode, segment registers are ignored, except for FS and GS. In these two
-cases, base addresses are obtained from the respective MSRs.
-
-For clarity, this process can be split into four steps (and an equal
-number of functions): determine if segment prefixes overrides can be used;
-parse the segment override prefixes, and use them if found; if not found
-or cannot be used, use the default segment registers associated with the
-operand registers. Once the segment register to use has been identified,
-read its value to obtain the segment selector.
-
-The method to obtain the segment selector depends on several factors. In
-32-bit builds, segment selectors are saved into a pt_regs structure
-when switching to kernel mode. The same is also true for virtual-8086
-mode. In 64-bit builds, segmentation is mostly ignored, except when
-running a program in 32-bit legacy mode. In this case, CS and SS can be
-obtained from pt_regs. DS, ES, FS and GS can be read directly from
-the respective segment registers.
-
-In order to identify the segment registers, a new set of #defines is
-introduced. It also includes two special identifiers. One of them
-indicates when the default segment register associated with instruction
-operands shall be used. Another one indicates that the contents of the
-segment register shall be ignored; this identifier is used when in long
-mode.
-
-Improvements-by: Borislav Petkov <bp@suse.de>
-Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Reviewed-by: Borislav Petkov <bp@suse.de>
-Cc: "Michael S. Tsirkin" <mst@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: ricardo.neri@intel.com
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
-Cc: Huang Rui <ray.huang@amd.com>
-Cc: Qiaowei Ren <qiaowei.ren@intel.com>
-Cc: Shuah Khan <shuah@kernel.org>
-Cc: Kees Cook <keescook@chromium.org>
-Cc: Jonathan Corbet <corbet@lwn.net>
-Cc: Jiri Slaby <jslaby@suse.cz>
-Cc: Dmitry Vyukov <dvyukov@google.com>
-Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
-Cc: Chris Metcalf <cmetcalf@mellanox.com>
-Cc: Brian Gerst <brgerst@gmail.com>
-Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
-Cc: Andy Lutomirski <luto@kernel.org>
-Cc: Colin Ian King <colin.king@canonical.com>
-Cc: Chen Yucong <slaoub@gmail.com>
-Cc: Adam Buchbinder <adam.buchbinder@gmail.com>
-Cc: Vlastimil Babka <vbabka@suse.cz>
-Cc: Lorenzo Stoakes <lstoakes@gmail.com>
-Cc: Masami Hiramatsu <mhiramat@kernel.org>
-Cc: Paolo Bonzini <pbonzini@redhat.com>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Cc: Thomas Garnier <thgarnie@google.com>
-Link: https://lkml.kernel.org/r/1509135945-13762-14-git-send-email-ricardo.neri-calderon@linux.intel.com
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-
-diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
-index 02aff0867211..1c78580e58be 100644
---- a/arch/x86/include/asm/inat.h
-+++ b/arch/x86/include/asm/inat.h
-@@ -97,6 +97,16 @@
- #define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)
- #define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS)
-
-+/* Identifiers for segment registers */
-+#define INAT_SEG_REG_IGNORE 0
-+#define INAT_SEG_REG_DEFAULT 1
-+#define INAT_SEG_REG_CS 2
-+#define INAT_SEG_REG_SS 3
-+#define INAT_SEG_REG_DS 4
-+#define INAT_SEG_REG_ES 5
-+#define INAT_SEG_REG_FS 6
-+#define INAT_SEG_REG_GS 7
-+
- /* Attribute search APIs */
- extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
- extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
-diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
-index 405ffeb1c382..e5ef85a37102 100644
---- a/arch/x86/lib/insn-eval.c
-+++ b/arch/x86/lib/insn-eval.c
-@@ -9,6 +9,7 @@
- #include <asm/inat.h>
- #include <asm/insn.h>
- #include <asm/insn-eval.h>
-+#include <asm/vm86.h>
-
- #undef pr_fmt
- #define pr_fmt(fmt) "insn: " fmt
-@@ -19,6 +20,345 @@ enum reg_type {
- REG_TYPE_BASE,
- };
-
-+/**
-+ * get_seg_reg_override_idx() - obtain segment register override index
-+ * @insn: Valid instruction with segment override prefixes
-+ *
-+ * Inspect the instruction prefixes in @insn and find segment overrides, if any.
-+ *
-+ * Returns:
-+ *
-+ * A constant identifying the segment register to use, among CS, SS, DS,
-+ * ES, FS, or GS. INAT_SEG_REG_DEFAULT is returned if no segment override
-+ * prefixes were found.
-+ *
-+ * -EINVAL in case of error.
-+ */
-+static int get_seg_reg_override_idx(struct insn *insn)
-+{
-+ int idx = INAT_SEG_REG_DEFAULT;
-+ int num_overrides = 0, i;
-+
-+ insn_get_prefixes(insn);
-+
-+ /* Look for any segment override prefixes. */
-+ for (i = 0; i < insn->prefixes.nbytes; i++) {
-+ insn_attr_t attr;
-+
-+ attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]);
-+ switch (attr) {
-+ case INAT_MAKE_PREFIX(INAT_PFX_CS):
-+ idx = INAT_SEG_REG_CS;
-+ num_overrides++;
-+ break;
-+ case INAT_MAKE_PREFIX(INAT_PFX_SS):
-+ idx = INAT_SEG_REG_SS;
-+ num_overrides++;
-+ break;
-+ case INAT_MAKE_PREFIX(INAT_PFX_DS):
-+ idx = INAT_SEG_REG_DS;
-+ num_overrides++;
-+ break;
-+ case INAT_MAKE_PREFIX(INAT_PFX_ES):
-+ idx = INAT_SEG_REG_ES;
-+ num_overrides++;
-+ break;
-+ case INAT_MAKE_PREFIX(INAT_PFX_FS):
-+ idx = INAT_SEG_REG_FS;
-+ num_overrides++;
-+ break;
-+ case INAT_MAKE_PREFIX(INAT_PFX_GS):
-+ idx = INAT_SEG_REG_GS;
-+ num_overrides++;
-+ break;
-+ /* No default action needed. */
-+ }
-+ }
-+
-+ /* More than one segment override prefix leads to undefined behavior. */
-+ if (num_overrides > 1)
-+ return -EINVAL;
-+
-+ return idx;
-+}
-+
-+/**
-+ * check_seg_overrides() - check if segment override prefixes are allowed
-+ * @insn: Valid instruction with segment override prefixes
-+ * @regoff: Operand offset, in pt_regs, for which the check is performed
-+ *
-+ * For a particular register used in register-indirect addressing, determine if
-+ * segment override prefixes can be used. Specifically, no overrides are allowed
-+ * for rDI if used with a string instruction.
-+ *
-+ * Returns:
-+ *
-+ * True if segment override prefixes can be used with the register indicated
-+ * in @regoff. False if otherwise.
-+ */
-+static bool check_seg_overrides(struct insn *insn, int regoff)
-+{
-+ if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn))
-+ return false;
-+
-+ return true;
-+}
-+
-+/**
-+ * resolve_default_seg() - resolve default segment register index for an operand
-+ * @insn: Instruction with opcode and address size. Must be valid.
-+ * @regs: Register values as seen when entering kernel mode
-+ * @off: Operand offset, in pt_regs, for which resolution is needed
-+ *
-+ * Resolve the default segment register index associated with the instruction
-+ * operand register indicated by @off. Such index is resolved based on defaults
-+ * described in the Intel Software Development Manual.
-+ *
-+ * Returns:
-+ *
-+ * If in protected mode, a constant identifying the segment register to use,
-+ * among CS, SS, ES or DS. If in long mode, INAT_SEG_REG_IGNORE.
-+ *
-+ * -EINVAL in case of error.
-+ */
-+static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off)
-+{
-+ if (user_64bit_mode(regs))
-+ return INAT_SEG_REG_IGNORE;
-+ /*
-+ * Resolve the default segment register as described in Section 3.7.4
-+ * of the Intel Software Development Manual Vol. 1:
-+ *
-+ * + DS for all references involving r[ABCD]X, and rSI.
-+ * + If used in a string instruction, ES for rDI. Otherwise, DS.
-+ * + AX, CX and DX are not valid register operands in 16-bit address
-+ * encodings but are valid for 32-bit and 64-bit encodings.
-+ * + -EDOM is reserved to identify for cases in which no register
-+ * is used (i.e., displacement-only addressing). Use DS.
-+ * + SS for rSP or rBP.
-+ * + CS for rIP.
-+ */
-+
-+ switch (off) {
-+ case offsetof(struct pt_regs, ax):
-+ case offsetof(struct pt_regs, cx):
-+ case offsetof(struct pt_regs, dx):
-+ /* Need insn to verify address size. */
-+ if (insn->addr_bytes == 2)
-+ return -EINVAL;
-+
-+ case -EDOM:
-+ case offsetof(struct pt_regs, bx):
-+ case offsetof(struct pt_regs, si):
-+ return INAT_SEG_REG_DS;
-+
-+ case offsetof(struct pt_regs, di):
-+ if (is_string_insn(insn))
-+ return INAT_SEG_REG_ES;
-+ return INAT_SEG_REG_DS;
-+
-+ case offsetof(struct pt_regs, bp):
-+ case offsetof(struct pt_regs, sp):
-+ return INAT_SEG_REG_SS;
-+
-+ case offsetof(struct pt_regs, ip):
-+ return INAT_SEG_REG_CS;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+/**
-+ * resolve_seg_reg() - obtain segment register index
-+ * @insn: Instruction with operands
-+ * @regs: Register values as seen when entering kernel mode
-+ * @regoff: Operand offset, in pt_regs, used to deterimine segment register
-+ *
-+ * Determine the segment register associated with the operands and, if
-+ * applicable, prefixes and the instruction pointed by @insn.
-+ *
-+ * The segment register associated to an operand used in register-indirect
-+ * addressing depends on:
-+ *
-+ * a) Whether running in long mode (in such a case segments are ignored, except
-+ * if FS or GS are used).
-+ *
-+ * b) Whether segment override prefixes can be used. Certain instructions and
-+ * registers do not allow override prefixes.
-+ *
-+ * c) Whether segment overrides prefixes are found in the instruction prefixes.
-+ *
-+ * d) If there are not segment override prefixes or they cannot be used, the
-+ * default segment register associated with the operand register is used.
-+ *
-+ * The function checks first if segment override prefixes can be used with the
-+ * operand indicated by @regoff. If allowed, obtain such overridden segment
-+ * register index. Lastly, if not prefixes were found or cannot be used, resolve
-+ * the segment register index to use based on the defaults described in the
-+ * Intel documentation. In long mode, all segment register indexes will be
-+ * ignored, except if overrides were found for FS or GS. All these operations
-+ * are done using helper functions.
-+ *
-+ * The operand register, @regoff, is represented as the offset from the base of
-+ * pt_regs.
-+ *
-+ * As stated, the main use of this function is to determine the segment register
-+ * index based on the instruction, its operands and prefixes. Hence, @insn
-+ * must be valid. However, if @regoff indicates rIP, we don't need to inspect
-+ * @insn at all as in this case CS is used in all cases. This case is checked
-+ * before proceeding further.
-+ *
-+ * Please note that this function does not return the value in the segment
-+ * register (i.e., the segment selector) but our defined index. The segment
-+ * selector needs to be obtained using get_segment_selector() and passing the
-+ * segment register index resolved by this function.
-+ *
-+ * Returns:
-+ *
-+ * An index identifying the segment register to use, among CS, SS, DS,
-+ * ES, FS, or GS. INAT_SEG_REG_IGNORE is returned if running in long mode.
-+ *
-+ * -EINVAL in case of error.
-+ */
-+static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)
-+{
-+ int idx;
-+
-+ /*
-+ * In the unlikely event of having to resolve the segment register
-+ * index for rIP, do it first. Segment override prefixes should not
-+ * be used. Hence, it is not necessary to inspect the instruction,
-+ * which may be invalid at this point.
-+ */
-+ if (regoff == offsetof(struct pt_regs, ip)) {
-+ if (user_64bit_mode(regs))
-+ return INAT_SEG_REG_IGNORE;
-+ else
-+ return INAT_SEG_REG_CS;
-+ }
-+
-+ if (!insn)
-+ return -EINVAL;
-+
-+ if (!check_seg_overrides(insn, regoff))
-+ return resolve_default_seg(insn, regs, regoff);
-+
-+ idx = get_seg_reg_override_idx(insn);
-+ if (idx < 0)
-+ return idx;
-+
-+ if (idx == INAT_SEG_REG_DEFAULT)
-+ return resolve_default_seg(insn, regs, regoff);
-+
-+ /*
-+ * In long mode, segment override prefixes are ignored, except for
-+ * overrides for FS and GS.
-+ */
-+ if (user_64bit_mode(regs)) {
-+ if (idx != INAT_SEG_REG_FS &&
-+ idx != INAT_SEG_REG_GS)
-+ idx = INAT_SEG_REG_IGNORE;
-+ }
-+
-+ return idx;
-+}
-+
-+/**
-+ * get_segment_selector() - obtain segment selector
-+ * @regs: Register values as seen when entering kernel mode
-+ * @seg_reg_idx: Segment register index to use
-+ *
-+ * Obtain the segment selector from any of the CS, SS, DS, ES, FS, GS segment
-+ * registers. In CONFIG_X86_32, the segment is obtained from either pt_regs or
-+ * kernel_vm86_regs as applicable. In CONFIG_X86_64, CS and SS are obtained
-+ * from pt_regs. DS, ES, FS and GS are obtained by reading the actual CPU
-+ * registers. This done for only for completeness as in CONFIG_X86_64 segment
-+ * registers are ignored.
-+ *
-+ * Returns:
-+ *
-+ * Value of the segment selector, including null when running in
-+ * long mode.
-+ *
-+ * -EINVAL on error.
-+ */
-+static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
-+{
-+#ifdef CONFIG_X86_64
-+ unsigned short sel;
-+
-+ switch (seg_reg_idx) {
-+ case INAT_SEG_REG_IGNORE:
-+ return 0;
-+ case INAT_SEG_REG_CS:
-+ return (unsigned short)(regs->cs & 0xffff);
-+ case INAT_SEG_REG_SS:
-+ return (unsigned short)(regs->ss & 0xffff);
-+ case INAT_SEG_REG_DS:
-+ savesegment(ds, sel);
-+ return sel;
-+ case INAT_SEG_REG_ES:
-+ savesegment(es, sel);
-+ return sel;
-+ case INAT_SEG_REG_FS:
-+ savesegment(fs, sel);
-+ return sel;
-+ case INAT_SEG_REG_GS:
-+ savesegment(gs, sel);
-+ return sel;
-+ default:
-+ return -EINVAL;
-+ }
-+#else /* CONFIG_X86_32 */
-+ struct kernel_vm86_regs *vm86regs = (struct kernel_vm86_regs *)regs;
-+
-+ if (v8086_mode(regs)) {
-+ switch (seg_reg_idx) {
-+ case INAT_SEG_REG_CS:
-+ return (unsigned short)(regs->cs & 0xffff);
-+ case INAT_SEG_REG_SS:
-+ return (unsigned short)(regs->ss & 0xffff);
-+ case INAT_SEG_REG_DS:
-+ return vm86regs->ds;
-+ case INAT_SEG_REG_ES:
-+ return vm86regs->es;
-+ case INAT_SEG_REG_FS:
-+ return vm86regs->fs;
-+ case INAT_SEG_REG_GS:
-+ return vm86regs->gs;
-+ case INAT_SEG_REG_IGNORE:
-+ /* fall through */
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ switch (seg_reg_idx) {
-+ case INAT_SEG_REG_CS:
-+ return (unsigned short)(regs->cs & 0xffff);
-+ case INAT_SEG_REG_SS:
-+ return (unsigned short)(regs->ss & 0xffff);
-+ case INAT_SEG_REG_DS:
-+ return (unsigned short)(regs->ds & 0xffff);
-+ case INAT_SEG_REG_ES:
-+ return (unsigned short)(regs->es & 0xffff);
-+ case INAT_SEG_REG_FS:
-+ return (unsigned short)(regs->fs & 0xffff);
-+ case INAT_SEG_REG_GS:
-+ /*
-+ * GS may or may not be in regs as per CONFIG_X86_32_LAZY_GS.
-+ * The macro below takes care of both cases.
-+ */
-+ return get_user_gs(regs);
-+ case INAT_SEG_REG_IGNORE:
-+ /* fall through */
-+ default:
-+ return -EINVAL;
-+ }
-+#endif /* CONFIG_X86_64 */
-+}
-+
- static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
- enum reg_type type)
- {
---
-2.15.0
-