diff options
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_misc.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/disp/thread.c | 30 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/spa_misc.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/os/kcpc.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/os/schedctl.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/proc.h | 5 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/vmm/vmm.c | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/cpc_subr.c | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/fpu.c | 29 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/sundep.c | 21 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/sysi86.c | 16 | ||||
-rw-r--r-- | usr/src/uts/sun4u/os/cpc_subr.c | 3 | ||||
-rw-r--r-- | usr/src/uts/sun4v/os/cpc_subr.c | 3 |
13 files changed, 87 insertions, 42 deletions
diff --git a/usr/src/uts/common/brand/lx/os/lx_misc.c b/usr/src/uts/common/brand/lx/os/lx_misc.c index 726c3c7915..8d48d2ea59 100644 --- a/usr/src/uts/common/brand/lx/os/lx_misc.c +++ b/usr/src/uts/common/brand/lx/os/lx_misc.c @@ -121,7 +121,7 @@ lx_exec() lwpd->br_ntv_stack_current = 0; installctx(lwptot(lwp), lwp, lx_save, lx_restore, NULL, NULL, lx_save, - NULL); + NULL, NULL); /* * clear out the tls array @@ -499,7 +499,7 @@ lx_initlwp(klwp_t *lwp, void *lwpbd) lwpd->br_lpid = NULL; installctx(lwptot(lwp), lwp, lx_save, lx_restore, NULL, NULL, - lx_save, NULL); + lx_save, NULL, NULL); /* * Install branded system call hooks for this LWP: diff --git a/usr/src/uts/common/disp/thread.c b/usr/src/uts/common/disp/thread.c index bf1f121b67..c9e0216dbe 100644 --- a/usr/src/uts/common/disp/thread.c +++ b/usr/src/uts/common/disp/thread.c @@ -21,7 +21,7 @@ /* * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2019 Joyent, Inc. + * Copyright 2021 Joyent, Inc. */ #include <sys/types.h> @@ -1025,7 +1025,28 @@ reapq_add(kthread_t *t) } /* + * Provide an allocation function for callers of installctx() that, for + * reasons of incomplete context-op initialization, must call installctx() + * in a kpreempt_disable() block. The caller, therefore, must call this + * without being in such a block. + */ +struct ctxop * +installctx_preallocate(void) +{ + /* + * NOTE: We could ASSERT/VERIFY that we are not in a place where + * a KM_SLEEP allocation could block indefinitely. + * + * ASSERT(curthread->t_preempt == 0); + */ + + return (kmem_alloc(sizeof (struct ctxop), KM_SLEEP)); +} + +/* * Install thread context ops for the current thread. + * The caller can pass in a preallocated struct ctxop, eliminating the need + * for the requirement of entering with kernel preemption still enabled. */ void installctx( @@ -1036,11 +1057,12 @@ installctx( void (*fork)(void *, void *), void (*lwp_create)(void *, void *), void (*exit)(void *), - void (*free)(void *, int)) + void (*free)(void *, int), + struct ctxop *ctx) { - struct ctxop *ctx; + if (ctx == NULL) + ctx = kmem_alloc(sizeof (struct ctxop), KM_SLEEP); - ctx = kmem_alloc(sizeof (struct ctxop), KM_SLEEP); ctx->save_op = save; ctx->restore_op = restore; ctx->fork_op = fork; diff --git a/usr/src/uts/common/fs/zfs/spa_misc.c b/usr/src/uts/common/fs/zfs/spa_misc.c index dd44829a43..af87d4611c 100644 --- a/usr/src/uts/common/fs/zfs/spa_misc.c +++ b/usr/src/uts/common/fs/zfs/spa_misc.c @@ -322,7 +322,8 @@ int zfs_deadman_enabled = -1; * the FPU state? This is currently off by default due to stability issues in * the kernel FPU routines; e.g., see bug 13717. */ -int zfs_fpu_enabled = 0; +/* XXX SmartOS now includes fixes for 13902 and 13915, so re-enable it. */ +int zfs_fpu_enabled = 1; #endif /* diff --git a/usr/src/uts/common/os/kcpc.c b/usr/src/uts/common/os/kcpc.c index 977d243400..33486aaff3 100644 --- a/usr/src/uts/common/os/kcpc.c +++ b/usr/src/uts/common/os/kcpc.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2021 Joyent, Inc. */ #include <sys/param.h> @@ -318,7 +319,7 @@ kcpc_bind_thread(kcpc_set_t *set, kthread_t *t, int *subcode) * Add a device context to the subject thread. */ installctx(t, ctx, kcpc_save, kcpc_restore, NULL, - kcpc_lwp_create, NULL, kcpc_free); + kcpc_lwp_create, NULL, kcpc_free, NULL); /* * Ask the backend to program the hardware. @@ -1424,7 +1425,7 @@ kcpc_lwp_create(kthread_t *t, kthread_t *ct) } installctx(ct, cctx, kcpc_save, kcpc_restore, - NULL, kcpc_lwp_create, NULL, kcpc_free); + NULL, kcpc_lwp_create, NULL, kcpc_free, NULL); } /* diff --git a/usr/src/uts/common/os/schedctl.c b/usr/src/uts/common/os/schedctl.c index 18b396a765..34f72995a2 100644 --- a/usr/src/uts/common/os/schedctl.c +++ b/usr/src/uts/common/os/schedctl.c @@ -22,7 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2016 Joyent, Inc. + * Copyright 2021 Joyent, Inc. */ #include <sys/types.h> @@ -113,7 +113,7 @@ schedctl(void) bzero(ssp, sizeof (*ssp)); installctx(t, ssp, schedctl_save, schedctl_restore, - schedctl_fork, NULL, NULL, NULL); + schedctl_fork, NULL, NULL, NULL, NULL); thread_lock(t); /* protect against ts_tick and ts_update */ t->t_schedctl = ssp; diff --git a/usr/src/uts/common/sys/proc.h b/usr/src/uts/common/sys/proc.h index bb6f62f83f..90007bda1b 100644 --- a/usr/src/uts/common/sys/proc.h +++ b/usr/src/uts/common/sys/proc.h @@ -21,7 +21,7 @@ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2021 Joyent, Inc. * Copyright 2020 Oxide Computer Company */ @@ -720,8 +720,9 @@ extern void thread_free(kthread_t *); extern void thread_rele(kthread_t *); extern void thread_join(kt_did_t); extern int reaper(void); +extern struct ctxop *installctx_preallocate(void); extern void installctx(kthread_t *, void *, void (*)(), void (*)(), - void (*)(), void (*)(), void (*)(), void (*)()); + void (*)(), void (*)(), void (*)(), void (*)(), struct ctxop *); extern int removectx(kthread_t *, void *, void (*)(), void (*)(), void (*)(), void (*)(), void (*)(), void (*)()); extern void savectx(kthread_t *); diff --git a/usr/src/uts/i86pc/io/vmm/vmm.c b/usr/src/uts/i86pc/io/vmm/vmm.c index fd37a2a171..c15a1118d8 100644 --- a/usr/src/uts/i86pc/io/vmm/vmm.c +++ b/usr/src/uts/i86pc/io/vmm/vmm.c @@ -2223,7 +2223,7 @@ vm_run(struct vm *vm, int vcpuid, const struct vm_entry *entry) vtc.vtc_vcpuid = vcpuid; vtc.vtc_status = 0; installctx(curthread, &vtc, vmm_savectx, vmm_restorectx, NULL, NULL, - NULL, vmm_freectx); + NULL, vmm_freectx, NULL); error = vm_entry_actions(vm, vcpuid, entry, vme); if (error != 0) { 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. diff --git a/usr/src/uts/sun4u/os/cpc_subr.c b/usr/src/uts/sun4u/os/cpc_subr.c index 5d4b6862d8..5efa580e71 100644 --- a/usr/src/uts/sun4u/os/cpc_subr.c +++ b/usr/src/uts/sun4u/os/cpc_subr.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2021 Joyent, Inc. */ /* @@ -95,7 +96,7 @@ kcpc_hw_startup_cpu(ushort_t cpflags) return; installctx(t, cp, kcpc_idle_save, kcpc_idle_restore, NULL, NULL, - NULL, NULL); + NULL, NULL, NULL); } /* diff --git a/usr/src/uts/sun4v/os/cpc_subr.c b/usr/src/uts/sun4v/os/cpc_subr.c index f545120f64..558549e9b3 100644 --- a/usr/src/uts/sun4v/os/cpc_subr.c +++ b/usr/src/uts/sun4v/os/cpc_subr.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2021 Joyent, Inc. */ /* @@ -94,7 +95,7 @@ kcpc_hw_startup_cpu(ushort_t cpflags) return; installctx(t, cp, kcpc_idle_save, kcpc_idle_restore, NULL, NULL, - NULL, NULL); + NULL, NULL, NULL); } /* |