From: tip-bot for Ricardo Neri <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: jslaby@suse.cz, tglx@linutronix.de, corbet@lwn.net,
brgerst@gmail.com, thgarnie@google.com, colin.king@canonical.com,
mst@redhat.com, akpm@linux-foundation.org,
adrian.hunter@intel.com, luto@kernel.org, cmetcalf@mellanox.com,
pbonzini@redhat.com, vbabka@suse.cz, dave.hansen@linux.intel.com,
dvyukov@google.com, acme@redhat.com, keescook@chromium.org,
slaoub@gmail.com, hpa@zytor.com, paul.gortmaker@windriver.com,
ray.huang@amd.com, ravi.v.shankar@intel.com,
peterz@infradead.org, ricardo.neri-calderon@linux.intel.com,
mhiramat@kernel.org, bp@suse.de, qiaowei.ren@intel.com,
linux-kernel@vger.kernel.org, lstoakes@gmail.com,
mingo@kernel.org, adam.buchbinder@gmail.com, shuah@kernel.org
Subject: [tip:x86/mpx] x86/insn-eval: Add utility functions to get segment descriptor base address and limit
Date: Wed, 1 Nov 2017 14:00:53 -0700 [thread overview]
Message-ID: <tip-bd5a410a5de3a6893eaacc749e706b85506dc908@git.kernel.org> (raw)
In-Reply-To: <1509135945-13762-16-git-send-email-ricardo.neri-calderon@linux.intel.com>
Commit-ID: bd5a410a5de3a6893eaacc749e706b85506dc908
Gitweb: https://git.kernel.org/tip/bd5a410a5de3a6893eaacc749e706b85506dc908
Author: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
AuthorDate: Fri, 27 Oct 2017 13:25:42 -0700
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 1 Nov 2017 21:50:12 +0100
x86/insn-eval: Add utility functions to get segment descriptor base address and limit
With segmentation, the base address of the segment is needed to compute a
linear address. This base address is obtained from the applicable segment
descriptor. Such segment descriptor is referenced from a segment selector.
These new functions obtain the segment base and limit of the segment
selector indicated by segment register index given as argument. This index
is any of the INAT_SEG_REG_* family of #define's.
The logic to obtain the segment selector is wrapped in the function
get_segment_selector() with the inputs described above. Once the selector
is known, the base address is determined. In protected mode, the selector
is used to obtain the segment descriptor and then its base address. In
long mode, the segment base address is zero except when FS or GS are used.
In virtual-8086 mode, the base address is computed as the value of the
segment selector shifted 4 positions to the left.
In protected mode, segment limits are enforced. Thus, a function to
determine the limit of the segment is added. Segment limits are not
enforced in long or virtual-8086. For the latter, addresses are limited
to 20 bits; address size will be handled when computing the linear
address.
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-16-git-send-email-ricardo.neri-calderon@linux.intel.com
---
arch/x86/include/asm/insn-eval.h | 1 +
arch/x86/lib/insn-eval.c | 114 +++++++++++++++++++++++++++++++++++++++
2 files changed, 115 insertions(+)
diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h
index 7e8c963..25d6e44 100644
--- a/arch/x86/include/asm/insn-eval.h
+++ b/arch/x86/include/asm/insn-eval.h
@@ -13,5 +13,6 @@
void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs);
int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs);
+unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx);
#endif /* _ASM_X86_INSN_EVAL_H */
diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
index d85e840..89d5c89 100644
--- a/arch/x86/lib/insn-eval.c
+++ b/arch/x86/lib/insn-eval.c
@@ -526,6 +526,120 @@ static struct desc_struct *get_desc(unsigned short sel)
}
/**
+ * insn_get_seg_base() - Obtain base address of segment descriptor.
+ * @regs: Register values as seen when entering kernel mode
+ * @seg_reg_idx: Index of the segment register pointing to seg descriptor
+ *
+ * Obtain the base address of the segment as indicated by the segment descriptor
+ * pointed by the segment selector. The segment selector is obtained from the
+ * input segment register index @seg_reg_idx.
+ *
+ * Returns:
+ *
+ * In protected mode, base address of the segment. Zero in long mode,
+ * except when FS or GS are used. In virtual-8086 mode, the segment
+ * selector shifted 4 bits to the right.
+ *
+ * -1L in case of error.
+ */
+unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx)
+{
+ struct desc_struct *desc;
+ short sel;
+
+ sel = get_segment_selector(regs, seg_reg_idx);
+ if (sel < 0)
+ return -1L;
+
+ if (v8086_mode(regs))
+ /*
+ * Base is simply the segment selector shifted 4
+ * bits to the right.
+ */
+ return (unsigned long)(sel << 4);
+
+ if (user_64bit_mode(regs)) {
+ /*
+ * Only FS or GS will have a base address, the rest of
+ * the segments' bases are forced to 0.
+ */
+ unsigned long base;
+
+ if (seg_reg_idx == INAT_SEG_REG_FS)
+ rdmsrl(MSR_FS_BASE, base);
+ else if (seg_reg_idx == INAT_SEG_REG_GS)
+ /*
+ * swapgs was called at the kernel entry point. Thus,
+ * MSR_KERNEL_GS_BASE will have the user-space GS base.
+ */
+ rdmsrl(MSR_KERNEL_GS_BASE, base);
+ else
+ base = 0;
+ return base;
+ }
+
+ /* In protected mode the segment selector cannot be null. */
+ if (!sel)
+ return -1L;
+
+ desc = get_desc(sel);
+ if (!desc)
+ return -1L;
+
+ return get_desc_base(desc);
+}
+
+/**
+ * get_seg_limit() - Obtain the limit of a segment descriptor
+ * @regs: Register values as seen when entering kernel mode
+ * @seg_reg_idx: Index of the segment register pointing to seg descriptor
+ *
+ * Obtain the limit of the segment as indicated by the segment descriptor
+ * pointed by the segment selector. The segment selector is obtained from the
+ * input segment register index @seg_reg_idx.
+ *
+ * Returns:
+ *
+ * In protected mode, the limit of the segment descriptor in bytes.
+ * In long mode and virtual-8086 mode, segment limits are not enforced. Thus,
+ * limit is returned as -1L to imply a limit-less segment.
+ *
+ * Zero is returned on error.
+ */
+static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx)
+{
+ struct desc_struct *desc;
+ unsigned long limit;
+ short sel;
+
+ sel = get_segment_selector(regs, seg_reg_idx);
+ if (sel < 0)
+ return 0;
+
+ if (user_64bit_mode(regs) || v8086_mode(regs))
+ return -1L;
+
+ if (!sel)
+ return 0;
+
+ desc = get_desc(sel);
+ if (!desc)
+ return 0;
+
+ /*
+ * If the granularity bit is set, the limit is given in multiples
+ * of 4096. This also means that the 12 least significant bits are
+ * not tested when checking the segment limits. In practice,
+ * this means that the segment ends in (limit << 12) + 0xfff.
+ */
+ limit = get_desc_limit(desc);
+ if (desc->g)
+ limit = (limit << 12) + 0xfff;
+
+ return limit;
+}
+
+/**
* insn_get_modrm_rm_off() - Obtain register in r/m part of the ModRM byte
* @insn: Instruction containing the ModRM byte
* @regs: Register values as seen when entering kernel mode
next prev parent reply other threads:[~2017-11-01 21:07 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-27 20:25 [PATCH v10 00/18] x86: Add address resolution code for UMIP and MPX Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 01/18] x86/mm: Relocate page fault error codes to traps.h Ricardo Neri
2017-11-01 20:55 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 02/18] x86/boot: Relocate definition of the initial state of CR0 Ricardo Neri
2017-11-01 20:55 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 03/18] ptrace,x86: Make user_64bit_mode() available to 32-bit builds Ricardo Neri
2017-11-01 20:55 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 04/18] uprobes/x86: Use existing definitions for segment override prefixes Ricardo Neri
2017-11-01 20:56 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 05/18] x86/mpx: Simplify handling of errors when computing linear addresses Ricardo Neri
2017-11-01 20:56 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 06/18] x86/mpx: Use signed variables to compute effective addresses Ricardo Neri
2017-11-01 20:57 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 07/18] x86/mpx: Do not use SIB.index if its value is 100b and ModRM.mod is not 11b Ricardo Neri
2017-11-01 20:57 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 08/18] x86/mpx: Do not use SIB.base if its value is 101b and ModRM.mod = 0 Ricardo Neri
2017-11-01 20:57 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 09/18] x86/mpx, x86/insn: Relocate insn util functions to a new insn-eval file Ricardo Neri
2017-11-01 20:58 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 10/18] x86/insn-eval: Do not BUG on invalid register type Ricardo Neri
2017-11-01 20:58 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 11/18] x86/insn-eval: Add a utility function to get register offsets Ricardo Neri
2017-11-01 20:59 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 12/18] x86/insn-eval: Add utility function to identify string instructions Ricardo Neri
2017-11-01 20:59 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 13/18] x86/insn-eval: Add utility functions to get segment selector Ricardo Neri
2017-11-01 21:00 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-11-09 11:12 ` [PATCH v10 13/18] " Arnd Bergmann
2017-11-09 13:50 ` Ingo Molnar
2017-10-27 20:25 ` [PATCH v10 14/18] x86/insn-eval: Add utility function to get segment descriptor Ricardo Neri
2017-11-01 21:00 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-12-05 17:48 ` Peter Zijlstra
2017-12-05 18:14 ` Borislav Petkov
2017-12-05 18:38 ` Peter Zijlstra
2017-12-05 21:29 ` Borislav Petkov
2017-12-07 7:23 ` Ricardo Neri
2017-12-07 8:03 ` Borislav Petkov
2017-12-07 7:26 ` Ricardo Neri
2017-12-07 8:01 ` Borislav Petkov
2017-10-27 20:25 ` [PATCH v10 15/18] x86/insn-eval: Add utility functions to get segment descriptor base address and limit Ricardo Neri
2017-11-01 21:00 ` tip-bot for Ricardo Neri [this message]
2017-10-27 20:25 ` [PATCH v10 16/18] x86/insn-eval: Add function to get default params of code segment Ricardo Neri
2017-11-01 21:01 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 17/18] x86/insn-eval: Indicate a 32-bit displacement if ModRM.mod is 0 and ModRM.rm is 101b Ricardo Neri
2017-11-01 21:01 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
2017-10-27 20:25 ` [PATCH v10 18/18] x86/insn-eval: Incorporate segment base in linear address computation Ricardo Neri
2017-11-01 17:56 ` Borislav Petkov
2017-11-01 19:08 ` Ricardo Neri
2017-11-01 21:02 ` [tip:x86/mpx] " tip-bot for Ricardo Neri
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-bd5a410a5de3a6893eaacc749e706b85506dc908@git.kernel.org \
--to=tipbot@zytor.com \
--cc=acme@redhat.com \
--cc=adam.buchbinder@gmail.com \
--cc=adrian.hunter@intel.com \
--cc=akpm@linux-foundation.org \
--cc=bp@suse.de \
--cc=brgerst@gmail.com \
--cc=cmetcalf@mellanox.com \
--cc=colin.king@canonical.com \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=dvyukov@google.com \
--cc=hpa@zytor.com \
--cc=jslaby@suse.cz \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=lstoakes@gmail.com \
--cc=luto@kernel.org \
--cc=mhiramat@kernel.org \
--cc=mingo@kernel.org \
--cc=mst@redhat.com \
--cc=paul.gortmaker@windriver.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=qiaowei.ren@intel.com \
--cc=ravi.v.shankar@intel.com \
--cc=ray.huang@amd.com \
--cc=ricardo.neri-calderon@linux.intel.com \
--cc=shuah@kernel.org \
--cc=slaoub@gmail.com \
--cc=tglx@linutronix.de \
--cc=thgarnie@google.com \
--cc=vbabka@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox