From: Wei Liu <wei.liu2@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
Wei Liu <wei.liu2@citrix.com>, Jan Beulich <JBeulich@suse.com>
Subject: [PATCH v4 01/27] x86: factor out common PV emulation code
Date: Thu, 8 Jun 2017 18:11:37 +0100 [thread overview]
Message-ID: <20170608171203.20416-2-wei.liu2@citrix.com> (raw)
In-Reply-To: <20170608171203.20416-1-wei.liu2@citrix.com>
We're going to split PV emulation code into several files. This patch
extracts the functions needed by them into a dedicated file.
The functions are now prefixed with "pv_emul_" and exported via a
local header file.
While at it, change bool_t to bool.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
xen/arch/x86/pv/Makefile | 1 +
xen/arch/x86/pv/emulate.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++
xen/arch/x86/pv/emulate.h | 10 +++++
xen/arch/x86/traps.c | 95 ++++++++-------------------------------------
4 files changed, 126 insertions(+), 78 deletions(-)
create mode 100644 xen/arch/x86/pv/emulate.c
create mode 100644 xen/arch/x86/pv/emulate.h
diff --git a/xen/arch/x86/pv/Makefile b/xen/arch/x86/pv/Makefile
index 489a9f59cb..564202cbb7 100644
--- a/xen/arch/x86/pv/Makefile
+++ b/xen/arch/x86/pv/Makefile
@@ -3,3 +3,4 @@ obj-y += traps.o
obj-bin-y += dom0_build.init.o
obj-y += domain.o
+obj-y += emulate.o
diff --git a/xen/arch/x86/pv/emulate.c b/xen/arch/x86/pv/emulate.c
new file mode 100644
index 0000000000..5750c7699b
--- /dev/null
+++ b/xen/arch/x86/pv/emulate.c
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * arch/x86/pv/emulate.c
+ *
+ * Common PV emulation code
+ *
+ * Modifications to Linux original are copyright (c) 2002-2004, K A Fraser
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/guest_access.h>
+
+#include <asm/debugreg.h>
+
+#include "emulate.h"
+
+int pv_emul_read_descriptor(unsigned int sel, const struct vcpu *v,
+ unsigned long *base, unsigned long *limit,
+ unsigned int *ar, bool insn_fetch)
+{
+ struct desc_struct desc;
+
+ if ( sel < 4)
+ desc.b = desc.a = 0;
+ else if ( __get_user(desc,
+ (const struct desc_struct *)(!(sel & 4)
+ ? GDT_VIRT_START(v)
+ : LDT_VIRT_START(v))
+ + (sel >> 3)) )
+ return 0;
+ if ( !insn_fetch )
+ desc.b &= ~_SEGMENT_L;
+
+ *ar = desc.b & 0x00f0ff00;
+ if ( !(desc.b & _SEGMENT_L) )
+ {
+ *base = ((desc.a >> 16) + ((desc.b & 0xff) << 16) +
+ (desc.b & 0xff000000));
+ *limit = (desc.a & 0xffff) | (desc.b & 0x000f0000);
+ if ( desc.b & _SEGMENT_G )
+ *limit = ((*limit + 1) << 12) - 1;
+#ifndef NDEBUG
+ if ( sel > 3 )
+ {
+ unsigned int a, l;
+ unsigned char valid;
+
+ asm volatile (
+ "larl %2,%0 ; setz %1"
+ : "=r" (a), "=qm" (valid) : "rm" (sel));
+ BUG_ON(valid && ((a & 0x00f0ff00) != *ar));
+ asm volatile (
+ "lsll %2,%0 ; setz %1"
+ : "=r" (l), "=qm" (valid) : "rm" (sel));
+ BUG_ON(valid && (l != *limit));
+ }
+#endif
+ }
+ else
+ {
+ *base = 0UL;
+ *limit = ~0UL;
+ }
+
+ return 1;
+}
+
+void pv_emul_instruction_done(struct cpu_user_regs *regs, unsigned long rip)
+{
+ regs->rip = rip;
+ regs->eflags &= ~X86_EFLAGS_RF;
+ if ( regs->eflags & X86_EFLAGS_TF )
+ {
+ current->arch.debugreg[6] |= DR_STEP | DR_STATUS_RESERVED_ONE;
+ pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
+ }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/pv/emulate.h b/xen/arch/x86/pv/emulate.h
new file mode 100644
index 0000000000..b2b1192d48
--- /dev/null
+++ b/xen/arch/x86/pv/emulate.h
@@ -0,0 +1,10 @@
+#ifndef __PV_EMULATE_H__
+#define __PV_EMULATE_H__
+
+int pv_emul_read_descriptor(unsigned int sel, const struct vcpu *v,
+ unsigned long *base, unsigned long *limit,
+ unsigned int *ar, bool insn_fetch);
+
+void pv_emul_instruction_done(struct cpu_user_regs *regs, unsigned long rip);
+
+#endif /* __PV_EMULATE_H__ */
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 52e740f11f..dcc48f9860 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -78,6 +78,8 @@
#include <asm/cpuid.h>
#include <xsm/xsm.h>
+#include "pv/emulate.h"
+
/*
* opt_nmi: one of 'ignore', 'dom0', or 'fatal'.
* fatal: Xen prints diagnostic message and then hangs.
@@ -694,17 +696,6 @@ void pv_inject_event(const struct x86_event *event)
}
}
-static void instruction_done(struct cpu_user_regs *regs, unsigned long rip)
-{
- regs->rip = rip;
- regs->eflags &= ~X86_EFLAGS_RF;
- if ( regs->eflags & X86_EFLAGS_TF )
- {
- current->arch.debugreg[6] |= DR_STEP | DR_STATUS_RESERVED_ONE;
- pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
- }
-}
-
static unsigned int check_guest_io_breakpoint(struct vcpu *v,
unsigned int port, unsigned int len)
{
@@ -1027,7 +1018,7 @@ static int emulate_invalid_rdtscp(struct cpu_user_regs *regs)
return 0;
eip += sizeof(opcode);
pv_soft_rdtsc(v, regs, 1);
- instruction_done(regs, eip);
+ pv_emul_instruction_done(regs, eip);
return EXCRET_fault_fixed;
}
@@ -1075,7 +1066,7 @@ static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
regs->rcx = res.c;
regs->rdx = res.d;
- instruction_done(regs, eip);
+ pv_emul_instruction_done(regs, eip);
trace_trap_one_addr(TRC_PV_FORCED_INVALID_OP, regs->rip);
@@ -1623,60 +1614,6 @@ long do_fpu_taskswitch(int set)
return 0;
}
-static int read_descriptor(unsigned int sel,
- const struct vcpu *v,
- unsigned long *base,
- unsigned long *limit,
- unsigned int *ar,
- bool_t insn_fetch)
-{
- struct desc_struct desc;
-
- if ( sel < 4)
- desc.b = desc.a = 0;
- else if ( __get_user(desc,
- (const struct desc_struct *)(!(sel & 4)
- ? GDT_VIRT_START(v)
- : LDT_VIRT_START(v))
- + (sel >> 3)) )
- return 0;
- if ( !insn_fetch )
- desc.b &= ~_SEGMENT_L;
-
- *ar = desc.b & 0x00f0ff00;
- if ( !(desc.b & _SEGMENT_L) )
- {
- *base = ((desc.a >> 16) + ((desc.b & 0xff) << 16) +
- (desc.b & 0xff000000));
- *limit = (desc.a & 0xffff) | (desc.b & 0x000f0000);
- if ( desc.b & _SEGMENT_G )
- *limit = ((*limit + 1) << 12) - 1;
-#ifndef NDEBUG
- if ( sel > 3 )
- {
- unsigned int a, l;
- unsigned char valid;
-
- asm volatile (
- "larl %2,%0 ; setz %1"
- : "=r" (a), "=qm" (valid) : "rm" (sel));
- BUG_ON(valid && ((a & 0x00f0ff00) != *ar));
- asm volatile (
- "lsll %2,%0 ; setz %1"
- : "=r" (l), "=qm" (valid) : "rm" (sel));
- BUG_ON(valid && (l != *limit));
- }
-#endif
- }
- else
- {
- *base = 0UL;
- *limit = ~0UL;
- }
-
- return 1;
-}
-
static int read_gate_descriptor(unsigned int gate_sel,
const struct vcpu *v,
unsigned int *sel,
@@ -1841,7 +1778,8 @@ static int priv_op_read_segment(enum x86_segment seg,
default: return X86EMUL_UNHANDLEABLE;
}
- if ( !read_descriptor(sel, current, ®->base, &limit, &ar, 0) )
+ if ( !pv_emul_read_descriptor(sel, current, ®->base,
+ &limit, &ar, 0) )
return X86EMUL_UNHANDLEABLE;
reg->limit = limit;
@@ -2987,8 +2925,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
int rc;
unsigned int eflags, ar;
- if ( !read_descriptor(regs->cs, curr, &ctxt.cs.base, &ctxt.cs.limit,
- &ar, 1) ||
+ if ( !pv_emul_read_descriptor(regs->cs, curr, &ctxt.cs.base,
+ &ctxt.cs.limit, &ar, 1) ||
!(ar & _SEGMENT_S) ||
!(ar & _SEGMENT_P) ||
!(ar & _SEGMENT_CODE) )
@@ -3110,7 +3048,7 @@ static int gate_op_read(
unsigned int ar;
ASSERT(!goc->insn_fetch);
- if ( !read_descriptor(sel, current, &addr, &limit, &ar, 0) ||
+ if ( !pv_emul_read_descriptor(sel, current, &addr, &limit, &ar, 0) ||
!(ar & _SEGMENT_S) ||
!(ar & _SEGMENT_P) ||
((ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR)) )
@@ -3170,8 +3108,8 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
* Decode instruction (and perhaps operand) to determine RPL,
* whether this is a jump or a call, and the call return offset.
*/
- if ( !read_descriptor(regs->cs, v, &ctxt.cs.base, &ctxt.cs.limit,
- &ar, 0) ||
+ if ( !pv_emul_read_descriptor(regs->cs, v, &ctxt.cs.base, &ctxt.cs.limit,
+ &ar, 0) ||
!(ar & _SEGMENT_S) ||
!(ar & _SEGMENT_P) ||
!(ar & _SEGMENT_CODE) )
@@ -3243,7 +3181,7 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
return;
}
- if ( !read_descriptor(sel, v, &base, &limit, &ar, 0) ||
+ if ( !pv_emul_read_descriptor(sel, v, &base, &limit, &ar, 0) ||
!(ar & _SEGMENT_S) ||
!(ar & _SEGMENT_CODE) ||
(!jump || (ar & _SEGMENT_EC) ?
@@ -3293,7 +3231,7 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
esp = v->arch.pv_vcpu.kernel_sp;
ss = v->arch.pv_vcpu.kernel_ss;
if ( (ss & 3) != (sel & 3) ||
- !read_descriptor(ss, v, &base, &limit, &ar, 0) ||
+ !pv_emul_read_descriptor(ss, v, &base, &limit, &ar, 0) ||
((ar >> 13) & 3) != (sel & 3) ||
!(ar & _SEGMENT_S) ||
(ar & _SEGMENT_CODE) ||
@@ -3320,7 +3258,8 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
{
const unsigned int *ustkp;
- if ( !read_descriptor(regs->ss, v, &base, &limit, &ar, 0) ||
+ if ( !pv_emul_read_descriptor(regs->ss, v, &base,
+ &limit, &ar, 0) ||
((ar >> 13) & 3) != (regs->cs & 3) ||
!(ar & _SEGMENT_S) ||
(ar & _SEGMENT_CODE) ||
@@ -3354,7 +3293,7 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
sel |= (regs->cs & 3);
esp = regs->rsp;
ss = regs->ss;
- if ( !read_descriptor(ss, v, &base, &limit, &ar, 0) ||
+ if ( !pv_emul_read_descriptor(ss, v, &base, &limit, &ar, 0) ||
((ar >> 13) & 3) != (sel & 3) )
{
pv_inject_hw_exception(TRAP_gp_fault, regs->error_code);
@@ -3382,7 +3321,7 @@ static void emulate_gate_op(struct cpu_user_regs *regs)
sel |= (regs->cs & 3);
regs->cs = sel;
- instruction_done(regs, off);
+ pv_emul_instruction_done(regs, off);
}
void do_general_protection(struct cpu_user_regs *regs)
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-06-08 17:12 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-08 17:11 [PATCH v4 00/27] x86: refactor trap handling code Wei Liu
2017-06-08 17:11 ` Wei Liu [this message]
2017-06-20 16:00 ` [PATCH v4 01/27] x86: factor out common PV emulation code Jan Beulich
2017-06-08 17:11 ` [PATCH v4 02/27] x86: move PV privileged instruction " Wei Liu
2017-06-20 16:03 ` Jan Beulich
2017-06-08 17:11 ` [PATCH v4 03/27] x86: move PV gate op " Wei Liu
2017-06-20 16:05 ` Jan Beulich
2017-06-08 17:11 ` [PATCH v4 04/27] x86: move PV invalid " Wei Liu
2017-06-20 16:21 ` Jan Beulich
2017-06-20 16:25 ` Wei Liu
2017-06-21 6:15 ` Jan Beulich
2017-06-21 8:57 ` Wei Liu
2017-06-21 9:09 ` Jan Beulich
2017-06-21 9:14 ` Wei Liu
2017-06-21 9:26 ` Jan Beulich
2017-06-21 9:29 ` Wei Liu
2017-06-08 17:11 ` [PATCH v4 05/27] x86/traps: remove now unused inclusion of emulate.h Wei Liu
2017-06-20 16:21 ` Jan Beulich
2017-06-08 17:11 ` [PATCH v4 06/27] x86: clean up PV emulation code Wei Liu
2017-06-23 10:56 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 07/27] x86: move do_set_trap_table to pv/traps.c Wei Liu
2017-06-23 11:00 ` Andrew Cooper
2017-06-23 13:59 ` Wei Liu
2017-06-23 13:59 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 08/27] x86: move some misc PV hypercalls to misc-hypercalls.c Wei Liu
2017-06-23 11:02 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 09/27] x86/traps: move pv_inject_event to pv/traps.c Wei Liu
2017-06-23 11:04 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 10/27] x86/traps: move set_guest_{machine, nmi}_trapbounce Wei Liu
2017-06-23 11:05 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 11/27] x86:/traps: move {un, }register_guest_nmi_callback Wei Liu
2017-06-23 11:38 ` Andrew Cooper
2017-06-23 12:19 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 12/27] x86/traps: move guest_has_trap_callback to pv/traps.c Wei Liu
2017-06-23 12:01 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 13/27] x86: move toggle_guest_mode to pv/domain.c Wei Liu
2017-06-23 12:10 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 14/27] x86: move do_iret to pv/iret.c Wei Liu
2017-06-23 12:12 ` Andrew Cooper
2017-06-23 14:17 ` Wei Liu
2017-06-23 14:17 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 15/27] x86: move callback_op code to pv/callback.c Wei Liu
2017-06-08 17:11 ` [PATCH v4 16/27] x86/traps: factor out pv_trap_init Wei Liu
2017-06-23 12:31 ` Andrew Cooper
2017-06-23 13:55 ` Wei Liu
2017-06-08 17:11 ` [PATCH v4 17/27] x86/traps: move some PV specific functions and struct to pv/traps.c Wei Liu
2017-06-23 12:36 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 18/27] x86/traps: move init_int80_direct_trap " Wei Liu
2017-06-23 12:37 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 19/27] x86: move hypercall_page_initialise_ring3_kernel to pv/hypercall.c Wei Liu
2017-06-23 12:41 ` Andrew Cooper
2017-06-23 14:49 ` Wei Liu
2017-06-23 14:53 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 20/27] x86: move hypercall_page_initialise_ring1_kernel Wei Liu
2017-06-23 12:41 ` Andrew Cooper
2017-06-23 13:56 ` Wei Liu
2017-06-23 13:56 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 21/27] x86: move compat_set_trap_table along side the non-compat variant Wei Liu
2017-06-23 12:43 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 22/27] x86: move compat_iret along side its " Wei Liu
2017-06-23 12:44 ` Andrew Cooper
2017-06-08 17:11 ` [PATCH v4 23/27] x86: move the compat callback ops next to the " Wei Liu
2017-06-23 13:40 ` Jan Beulich
2017-06-08 17:12 ` [PATCH v4 24/27] x86: move compat_show_guest_statck near its " Wei Liu
2017-06-23 12:47 ` Andrew Cooper
2017-06-08 17:12 ` [PATCH v4 25/27] x86: remove the now empty x86_64/compat/traps.c Wei Liu
2017-06-23 12:47 ` Andrew Cooper
2017-06-08 17:12 ` [PATCH v4 26/27] x86: fix coding a style issue in asm-x86/traps.h Wei Liu
2017-06-23 12:48 ` Andrew Cooper
2017-06-08 17:12 ` [PATCH v4 27/27] x86: clean up traps.c Wei Liu
2017-06-23 12:50 ` Andrew Cooper
2017-06-23 13:45 ` Jan Beulich
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=20170608171203.20416-2-wei.liu2@citrix.com \
--to=wei.liu2@citrix.com \
--cc=JBeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/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;
as well as URLs for NNTP newsgroup(s).