summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/ia32
diff options
context:
space:
mode:
authorDan McDonald <danmcd@joyent.com>2021-07-01 13:27:16 -0400
committerGitHub <noreply@github.com>2021-07-01 13:27:16 -0400
commit1fef3b89560b821bfc30ca13f87ed2c0d876ee17 (patch)
treeac9d8ca9247cf806d445001c5f382ff4eb4d5ce3 /usr/src/uts/intel/ia32
parent0402a6962cad4cc9a83682bb49b6496264a913c3 (diff)
downloadillumos-joyent-release-20210701.tar.gz
OS-8288 Pull in 13902 and 13915 early (#370)release-20210701
Portions contributed by: Jerry Jelinek <gjelinek@gmail.com>
Diffstat (limited to 'usr/src/uts/intel/ia32')
-rw-r--r--usr/src/uts/intel/ia32/os/cpc_subr.c4
-rw-r--r--usr/src/uts/intel/ia32/os/fpu.c29
-rw-r--r--usr/src/uts/intel/ia32/os/sundep.c21
-rw-r--r--usr/src/uts/intel/ia32/os/sysi86.c16
4 files changed, 44 insertions, 26 deletions
diff --git a/usr/src/uts/intel/ia32/os/cpc_subr.c b/usr/src/uts/intel/ia32/os/cpc_subr.c
index a74dfd77bc..71e1ebaeee 100644
--- a/usr/src/uts/intel/ia32/os/cpc_subr.c
+++ b/usr/src/uts/intel/ia32/os/cpc_subr.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2019 Joyent, Inc.
+ * Copyright 2021 Joyent, Inc.
*/
/*
@@ -169,7 +169,7 @@ kcpc_hw_init(cpu_t *cp)
return;
installctx(t, cp, kcpc_idle_save, kcpc_idle_restore,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
void
diff --git a/usr/src/uts/intel/ia32/os/fpu.c b/usr/src/uts/intel/ia32/os/fpu.c
index d648e0552f..9a02806b66 100644
--- a/usr/src/uts/intel/ia32/os/fpu.c
+++ b/usr/src/uts/intel/ia32/os/fpu.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2020 Joyent, Inc.
+ * Copyright 2021 Joyent, Inc.
* Copyright 2021 RackTop Systems, Inc.
*/
@@ -670,7 +670,7 @@ fp_new_lwp(kthread_id_t t, kthread_id_t ct)
*/
installctx(ct, cfp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp,
- fp_new_lwp, NULL, fp_free);
+ fp_new_lwp, NULL, fp_free, NULL);
}
/*
@@ -796,6 +796,7 @@ void
fp_exec(void)
{
struct fpu_ctx *fp = &ttolwp(curthread)->lwp_pcb.pcb_fpu;
+ struct ctxop *ctx = installctx_preallocate();
if (fp_save_mech == FP_XSAVE) {
fp->fpu_xsave_mask = XFEATURE_FP_ALL;
@@ -807,7 +808,7 @@ fp_exec(void)
*/
kpreempt_disable();
installctx(curthread, fp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp,
- fp_new_lwp, NULL, fp_free);
+ fp_new_lwp, NULL, fp_free, ctx);
fpinit();
fp->fpu_flags = FPU_EN;
kpreempt_enable();
@@ -836,7 +837,7 @@ fp_seed(void)
}
installctx(curthread, fp, fpsave_ctxt, fprestore_ctxt, fp_new_lwp,
- fp_new_lwp, NULL, fp_free);
+ fp_new_lwp, NULL, fp_free, NULL);
fpinit();
/*
@@ -1318,6 +1319,7 @@ void
kernel_fpu_begin(kfpu_state_t *kfpu, uint_t flags)
{
klwp_t *pl = curthread->t_lwp;
+ struct ctxop *ctx;
if ((curthread->t_flag & T_KFPU) != 0) {
panic("curthread attempting to nest kernel FPU states");
@@ -1380,23 +1382,25 @@ kernel_fpu_begin(kfpu_state_t *kfpu, uint_t flags)
* FPU or another code path) so FPU_VALID could be set. This is handled
* by fp_save, as is the FPU_EN check.
*/
+ ctx = installctx_preallocate();
+ kpreempt_disable();
if (pl != NULL) {
- kpreempt_disable();
if ((flags & KFPU_USE_LWP) == 0)
fp_save(&pl->lwp_pcb.pcb_fpu);
pl->lwp_pcb.pcb_fpu.fpu_flags |= FPU_KERNEL;
- kpreempt_enable();
}
/*
- * Set the context operations for kernel FPU usage. Note that this
- * cannot be done with pre-emption and interrupts disabled, since
- * installctx does a sleeping allocation. We haven't finished
- * initializing our kernel FPU state yet, but in the rare case that we
- * happen to save/restore before that, no harm is done.
+ * Set the context operations for kernel FPU usage. Note that this is
+ * done with a preallocated buffer and under kpreempt_disable because
+ * without a preallocated buffer, installctx does a sleeping
+ * allocation. We haven't finished initializing our kernel FPU state
+ * yet, and in the rare case that we happen to save/restore just as
+ * installctx() exits its own kpreempt_enable() internal call, we
+ * guard against restoring an uninitialized buffer (0xbaddcafe).
*/
installctx(curthread, kfpu, kernel_fpu_ctx_save, kernel_fpu_ctx_restore,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, ctx);
curthread->t_flag |= T_KFPU;
@@ -1420,6 +1424,7 @@ kernel_fpu_begin(kfpu_state_t *kfpu, uint_t flags)
/* initialize the kfpu state */
kernel_fpu_ctx_restore(kfpu);
}
+ kpreempt_enable();
}
void
diff --git a/usr/src/uts/intel/ia32/os/sundep.c b/usr/src/uts/intel/ia32/os/sundep.c
index 34e0a03d68..8a5562f4ad 100644
--- a/usr/src/uts/intel/ia32/os/sundep.c
+++ b/usr/src/uts/intel/ia32/os/sundep.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2019 Joyent, Inc.
+ * Copyright 2021 Joyent, Inc.
*/
/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
@@ -763,7 +763,7 @@ lwp_attach_brand_hdlrs(klwp_t *lwp)
brand_interpositioning_disable, NULL) == 0);
installctx(t, NULL, brand_interpositioning_disable,
brand_interpositioning_enable, NULL, NULL,
- brand_interpositioning_disable, NULL);
+ brand_interpositioning_disable, NULL, NULL);
if (t == curthread) {
kpreempt_disable();
@@ -829,6 +829,7 @@ lwp_installctx(klwp_t *lwp)
#else
void (*restop)(klwp_t *) = lwp_segregs_restore;
#endif
+ struct ctxop *ctx;
/*
* Install the basic lwp context handlers on each lwp.
@@ -844,10 +845,14 @@ lwp_installctx(klwp_t *lwp)
*/
ASSERT(removectx(t, lwp, lwp_segregs_save, restop,
NULL, NULL, NULL, NULL) == 0);
- if (thisthread)
+ if (thisthread) {
+ ctx = installctx_preallocate();
kpreempt_disable();
+ } else {
+ ctx = NULL;
+ }
installctx(t, lwp, lwp_segregs_save, restop,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, ctx);
if (thisthread) {
/*
* Since we're the right thread, set the values in the GDT
@@ -874,10 +879,14 @@ lwp_installctx(klwp_t *lwp)
ASSERT(removectx(t, kstktop,
sep_save, sep_restore, NULL, NULL, NULL, NULL) == 0);
- if (thisthread)
+ if (thisthread) {
+ ctx = installctx_preallocate();
kpreempt_disable();
+ } else {
+ ctx = NULL;
+ }
installctx(t, kstktop,
- sep_save, sep_restore, NULL, NULL, NULL, NULL);
+ sep_save, sep_restore, NULL, NULL, NULL, NULL, ctx);
if (thisthread) {
/*
* We're the right thread, so set the stack pointer
diff --git a/usr/src/uts/intel/ia32/os/sysi86.c b/usr/src/uts/intel/ia32/os/sysi86.c
index bdb66e3e1f..03796bc9e9 100644
--- a/usr/src/uts/intel/ia32/os/sysi86.c
+++ b/usr/src/uts/intel/ia32/os/sysi86.c
@@ -20,12 +20,12 @@
*/
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2018 Joyent, Inc.
+ * Copyright 2021 Joyent, Inc.
*/
/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
-/* All Rights Reserved */
+/* All Rights Reserved */
/* Copyright (c) 1987, 1988 Microsoft Corporation */
/* All Rights Reserved */
@@ -93,6 +93,9 @@ sysi86(short cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
*/
case SI86V86:
if (arg1 == V86SC_IOPL) {
+#if defined(__xpv)
+ struct ctxop *ctx;
+#endif
struct regs *rp = lwptoregs(ttolwp(curthread));
greg_t oldpl = rp->r_ps & PS_IOPL;
greg_t newpl = arg2 & PS_IOPL;
@@ -105,10 +108,11 @@ sysi86(short cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
secpolicy_sys_config(CRED(), B_FALSE)) != 0)
return (set_errno(error));
#if defined(__xpv)
+ ctx = installctx_preallocate();
kpreempt_disable();
installctx(curthread, NULL, xen_disable_user_iopl,
xen_enable_user_iopl, NULL, NULL,
- xen_disable_user_iopl, NULL);
+ xen_disable_user_iopl, NULL, ctx);
xen_enable_user_iopl();
kpreempt_enable();
#else
@@ -398,14 +402,14 @@ ldt_savectx(proc_t *p)
* selectors when context switching away from a process that
* has a private ldt. Consider the following example:
*
- * Wine creats a ldt descriptor and points a segment register
- * to it.
+ * Wine creats a ldt descriptor and points a segment register
+ * to it.
*
* We then context switch away from wine lwp to kernel
* thread and hit breakpoint in kernel with kmdb
*
* When we continue and resume from kmdb we will #gp
- * fault since kmdb will have saved the stale ldt selector
+ * fault since kmdb will have saved the stale ldt selector
* from wine and will try to restore it but we are no longer in
* the context of the wine process and do not have our
* ldtr register pointing to the private ldt.