summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsudheer <none@none>2007-06-20 03:26:40 -0700
committersudheer <none@none>2007-06-20 03:26:40 -0700
commit7712e92cf4ce9bcf161748b8648b7537d95ffb16 (patch)
tree693a36eaf4f168e1d227f90d06e259cd5071c049
parent34b3058f17535674a5b5c68e924617f6076dd640 (diff)
downloadillumos-gate-7712e92cf4ce9bcf161748b8648b7537d95ffb16.tar.gz
6493689 Jvm crash: curthread set by kernel incorrect
-rw-r--r--usr/src/uts/common/os/lwp.c5
-rw-r--r--usr/src/uts/i86pc/ml/locore.s6
-rw-r--r--usr/src/uts/i86pc/ml/syscall_asm_amd64.s15
-rw-r--r--usr/src/uts/i86pc/os/intr.c4
-rw-r--r--usr/src/uts/intel/amd64/ml/mach_offsets.in1
-rw-r--r--usr/src/uts/intel/ia32/os/archdep.c8
-rw-r--r--usr/src/uts/intel/ia32/os/sundep.c14
-rw-r--r--usr/src/uts/intel/ia32/os/sysi86.c2
-rw-r--r--usr/src/uts/intel/ia32/syscall/lwp_private.c12
-rw-r--r--usr/src/uts/intel/sys/pcb.h9
10 files changed, 37 insertions, 39 deletions
diff --git a/usr/src/uts/common/os/lwp.c b/usr/src/uts/common/os/lwp.c
index 60eee244dd..a925f979a4 100644
--- a/usr/src/uts/common/os/lwp.c
+++ b/usr/src/uts/common/os/lwp.c
@@ -1650,9 +1650,8 @@ forklwp(klwp_t *lwp, proc_t *cp, id_t lwpid)
/* fix up child's lwp */
-#if defined(__i386) || defined(__amd64)
- clwp->lwp_pcb.pcb_flags = clwp->lwp_pcb.pcb_flags & RUPDATE_PENDING;
-#elif defined(__sparc)
+ clwp->lwp_pcb.pcb_flags = 0;
+#if defined(__sparc)
clwp->lwp_pcb.pcb_step = STEP_NONE;
#endif
clwp->lwp_cursig = 0;
diff --git a/usr/src/uts/i86pc/ml/locore.s b/usr/src/uts/i86pc/ml/locore.s
index c3da3b99bc..3605e10fff 100644
--- a/usr/src/uts/i86pc/ml/locore.s
+++ b/usr/src/uts/i86pc/ml/locore.s
@@ -1554,11 +1554,11 @@ _lwp_rtt:
#if defined(DEBUG)
/*
* If we were to run lwp_savectx at this point -without-
- * RUPDATE_PENDING being set, we'd end up sampling the hardware
+ * pcb_rupdate being set to 1, we'd end up sampling the hardware
* state left by the previous running lwp, rather than setting
* the values requested by the lwp creator. Bad.
*/
- testl $RUPDATE_PENDING, PCB_FLAGS(%r14)
+ testb $0x1, PCB_RUPDATE(%r14)
jne 1f
leaq _no_pending_updates(%rip), %rdi
movl $__LINE__, %esi
@@ -1566,7 +1566,7 @@ _lwp_rtt:
xorl %eax, %eax
call panic
_no_pending_updates:
- .string "locore.s:%d lwp_rtt(lwp %p) but no RUPDATE_PENDING"
+ .string "locore.s:%d lwp_rtt(lwp %p) but pcb_rupdate != 1"
1:
#endif
diff --git a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
index 537aeda633..51a1d8cb54 100644
--- a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
+++ b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
@@ -174,8 +174,8 @@
/*
* Check to see if a simple (direct) return is possible i.e.
*
- * if ((t->t_post_sys_ast | syscalltrace |
- * (lwp->lwp_pcb.pcb_flags & RUPDATE_PENDING)) != 0)
+ * if (t->t_post_sys_ast | syscalltrace |
+ * lwp->lwp_pcb.pcb_rupdate == 1)
* do full version ;
*
* Preconditions:
@@ -187,8 +187,7 @@
*/
#define CHECK_POSTSYS_NE(t, ltmp, rtmp) \
movq T_LWP(t), ltmp; \
- movl PCB_FLAGS(ltmp), rtmp; \
- andl $RUPDATE_PENDING, rtmp; \
+ movzbl PCB_RUPDATE(ltmp), rtmp; \
ORL_SYSCALLTRACE(rtmp); \
orl T_POST_SYS_AST(t), rtmp; \
cmpl $0, rtmp
@@ -226,7 +225,7 @@
* Postconditions (if assertion is true):
* -none-
*
- * ASSERT((lwp->lwp_pcb.pcb_flags & RUPDATE_PENDING) == 0);
+ * ASSERT(lwp->lwp_pcb.pcb_rupdate == 0);
*
* If this is false, it meant that we returned to userland without
* updating the segment registers as we were supposed to.
@@ -234,7 +233,7 @@
* Note that we must ensure no interrupts or other traps intervene
* between entering privileged mode and performing the assertion,
* otherwise we may perform a context switch on the thread, which
- * will end up setting the RUPDATE_PENDING bit again.
+ * will end up setting pcb_rupdate to 1 again.
*/
#if defined(DEBUG)
@@ -247,7 +246,7 @@ __codesel_msg:
.string "syscall_asm_amd64.s:%d rp->r_cs [%ld] != %ld"
__no_rupdate_msg:
- .string "syscall_asm_amd64.s:%d lwp %p, pcb_flags & RUPDATE_PENDING != 0"
+ .string "syscall_asm_amd64.s:%d lwp %p, pcb_rupdate != 0"
#endif /* !__lint */
@@ -265,7 +264,7 @@ __no_rupdate_msg:
7:
#define ASSERT_NO_RUPDATE_PENDING(lwp) \
- testl $RUPDATE_PENDING, PCB_FLAGS(lwp); \
+ testb $0x1, PCB_RUPDATE(lwp); \
je 8f; \
movq lwp, %rdx; \
leaq __no_rupdate_msg(%rip), %rdi; \
diff --git a/usr/src/uts/i86pc/os/intr.c b/usr/src/uts/i86pc/os/intr.c
index ea15df6828..22672330f7 100644
--- a/usr/src/uts/i86pc/os/intr.c
+++ b/usr/src/uts/i86pc/os/intr.c
@@ -995,7 +995,7 @@ loop:
/*
* We are done if segment registers do not need updating.
*/
- if ((tp->t_lwp->lwp_pcb.pcb_flags & RUPDATE_PENDING) == 0)
+ if (tp->t_lwp->lwp_pcb.pcb_rupdate == 0)
return (1);
if (update_sregs(rp, tp->t_lwp)) {
@@ -1013,7 +1013,7 @@ loop:
tp->t_sig_check = 1;
cli();
}
- tp->t_lwp->lwp_pcb.pcb_flags &= ~RUPDATE_PENDING;
+ tp->t_lwp->lwp_pcb.pcb_rupdate = 0;
#endif /* __amd64 */
return (1);
diff --git a/usr/src/uts/intel/amd64/ml/mach_offsets.in b/usr/src/uts/intel/amd64/ml/mach_offsets.in
index 018b9ef813..8921f58c36 100644
--- a/usr/src/uts/intel/amd64/ml/mach_offsets.in
+++ b/usr/src/uts/intel/amd64/ml/mach_offsets.in
@@ -135,6 +135,7 @@ _klwp
lwp_pcb.pcb_flags PCB_FLAGS
lwp_pcb.pcb_fpu.fpu_regs LWP_FPU_REGS
lwp_pcb.pcb_fpu.fpu_flags LWP_FPU_FLAGS
+ lwp_pcb.pcb_rupdate PCB_RUPDATE
pcb PCBSIZE
pcb_drstat
diff --git a/usr/src/uts/intel/ia32/os/archdep.c b/usr/src/uts/intel/ia32/os/archdep.c
index 317cd9b77d..2681aeae1a 100644
--- a/usr/src/uts/intel/ia32/os/archdep.c
+++ b/usr/src/uts/intel/ia32/os/archdep.c
@@ -442,7 +442,7 @@ getgregs(klwp_t *lwp, gregset_t grp)
grp[REG_GSBASE] = pcb->pcb_gsbase;
if (thisthread)
kpreempt_disable();
- if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_rupdate == 1) {
grp[REG_DS] = pcb->pcb_ds;
grp[REG_ES] = pcb->pcb_es;
grp[REG_FS] = pcb->pcb_fs;
@@ -478,7 +478,7 @@ getgregs32(klwp_t *lwp, gregset32_t grp)
if (thisthread)
kpreempt_disable();
- if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_rupdate == 1) {
grp[GS] = (uint16_t)pcb->pcb_gs;
grp[FS] = (uint16_t)pcb->pcb_fs;
grp[DS] = (uint16_t)pcb->pcb_ds;
@@ -712,7 +712,7 @@ setgregs(klwp_t *lwp, gregset_t grp)
/*
* Ensure that we go out via update_sregs
*/
- pcb->pcb_flags |= RUPDATE_PENDING;
+ pcb->pcb_rupdate = 1;
lwptot(lwp)->t_post_sys = 1;
if (thisthread)
kpreempt_enable();
@@ -757,7 +757,7 @@ setgregs(klwp_t *lwp, gregset_t grp)
/*
* Ensure that we go out via update_sregs
*/
- pcb->pcb_flags |= RUPDATE_PENDING;
+ pcb->pcb_rupdate = 1;
lwptot(lwp)->t_post_sys = 1;
if (thisthread)
kpreempt_enable();
diff --git a/usr/src/uts/intel/ia32/os/sundep.c b/usr/src/uts/intel/ia32/os/sundep.c
index 8b4455576d..0f16acc954 100644
--- a/usr/src/uts/intel/ia32/os/sundep.c
+++ b/usr/src/uts/intel/ia32/os/sundep.c
@@ -375,12 +375,12 @@ lwp_forkregs(klwp_t *lwp, klwp_t *clwp)
struct pcb *pcb = &clwp->lwp_pcb;
struct regs *rp = lwptoregs(lwp);
- if ((pcb->pcb_flags & RUPDATE_PENDING) == 0) {
+ if (pcb->pcb_rupdate == 0) {
pcb->pcb_ds = rp->r_ds;
pcb->pcb_es = rp->r_es;
pcb->pcb_fs = rp->r_fs;
pcb->pcb_gs = rp->r_gs;
- pcb->pcb_flags |= RUPDATE_PENDING;
+ pcb->pcb_rupdate = 1;
lwptot(clwp)->t_post_sys = 1;
}
ASSERT(lwptot(clwp)->t_post_sys);
@@ -416,7 +416,7 @@ lwp_pcb_exit(void)
* as a segment-not-present trap.
*
* Here we save the current values from the lwp regs into the pcb
- * and set the RUPDATE_PENDING bit to tell the rest of the kernel
+ * and set pcb->pcb_rupdate to 1 to tell the rest of the kernel
* that the pcb copy of the segment registers is the current one.
* This ensures the lwp's next trip to user land via update_sregs.
* Finally we set t_post_sys to ensure that no system call fast-path's
@@ -447,7 +447,7 @@ lwp_segregs_save(klwp_t *lwp)
ASSERT(VALID_LWP_DESC(&pcb->pcb_fsdesc));
ASSERT(VALID_LWP_DESC(&pcb->pcb_gsdesc));
- if ((pcb->pcb_flags & RUPDATE_PENDING) == 0) {
+ if (pcb->pcb_rupdate == 0) {
rp = lwptoregs(lwp);
/*
@@ -461,7 +461,7 @@ lwp_segregs_save(klwp_t *lwp)
pcb->pcb_es = rp->r_es;
pcb->pcb_fs = rp->r_fs;
pcb->pcb_gs = rp->r_gs;
- pcb->pcb_flags |= RUPDATE_PENDING;
+ pcb->pcb_rupdate = 1;
lwp->lwp_thread->t_post_sys = 1;
}
#endif /* __amd64 */
@@ -696,7 +696,7 @@ lwp_installctx(klwp_t *lwp)
* On the amd64 kernel, the context handlers are responsible for
* virtualizing %ds, %es, %fs, and %gs to the lwp. The register
* values are only ever changed via sys_rtt when the
- * RUPDATE_PENDING bit is set. Only sys_rtt gets to clear the bit.
+ * pcb->pcb_rupdate == 1. Only sys_rtt gets to clear the bit.
*
* On the i386 kernel, the context handlers are responsible for
* virtualizing %gs/%fs to the lwp by updating the per-cpu GDTs
@@ -827,7 +827,7 @@ setregs(uarg_t *args)
pcb->pcb_ds = rp->r_ds;
pcb->pcb_es = rp->r_es;
- pcb->pcb_flags |= RUPDATE_PENDING;
+ pcb->pcb_rupdate = 1;
#elif defined(__i386)
diff --git a/usr/src/uts/intel/ia32/os/sysi86.c b/usr/src/uts/intel/ia32/os/sysi86.c
index be4eedcb9c..fd4c369dec 100644
--- a/usr/src/uts/intel/ia32/os/sysi86.c
+++ b/usr/src/uts/intel/ia32/os/sysi86.c
@@ -571,7 +571,7 @@ setdscr(struct ssd *ssd)
}
#if defined(__amd64)
- if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_rupdate == 1) {
if (ssd->sel == pcb->pcb_ds ||
ssd->sel == pcb->pcb_es ||
ssd->sel == pcb->pcb_fs ||
diff --git a/usr/src/uts/intel/ia32/syscall/lwp_private.c b/usr/src/uts/intel/ia32/syscall/lwp_private.c
index da9985a5a2..7991499615 100644
--- a/usr/src/uts/intel/ia32/syscall/lwp_private.c
+++ b/usr/src/uts/intel/ia32/syscall/lwp_private.c
@@ -72,12 +72,12 @@ lwp_setprivate(klwp_t *lwp, int which, uintptr_t base)
* of zero for %fs and %gs to use the 64-bit fs_base and gs_base
* respectively.
*/
- if ((pcb->pcb_flags & RUPDATE_PENDING) == 0) {
+ if (pcb->pcb_rupdate == 0) {
pcb->pcb_ds = rp->r_ds;
pcb->pcb_es = rp->r_es;
pcb->pcb_fs = rp->r_fs;
pcb->pcb_gs = rp->r_gs;
- pcb->pcb_flags |= RUPDATE_PENDING;
+ pcb->pcb_rupdate = 1;
t->t_post_sys = 1;
}
ASSERT(t->t_post_sys);
@@ -167,7 +167,7 @@ lwp_getprivate(klwp_t *lwp, int which, uintptr_t base)
case _LWP_FSBASE:
if ((sbase = pcb->pcb_fsbase) != 0) {
if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
- if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_rupdate == 1) {
if (pcb->pcb_fs == 0)
break;
} else {
@@ -175,7 +175,7 @@ lwp_getprivate(klwp_t *lwp, int which, uintptr_t base)
break;
}
} else {
- if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_rupdate == 1) {
if (pcb->pcb_fs == LWPFS_SEL)
break;
} else {
@@ -189,7 +189,7 @@ lwp_getprivate(klwp_t *lwp, int which, uintptr_t base)
case _LWP_GSBASE:
if ((sbase = pcb->pcb_gsbase) != 0) {
if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
- if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_rupdate == 1) {
if (pcb->pcb_gs == 0)
break;
} else {
@@ -197,7 +197,7 @@ lwp_getprivate(klwp_t *lwp, int which, uintptr_t base)
break;
}
} else {
- if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_rupdate == 1) {
if (pcb->pcb_gs == LWPGS_SEL)
break;
} else {
diff --git a/usr/src/uts/intel/sys/pcb.h b/usr/src/uts/intel/sys/pcb.h
index 54ac91a787..63325e4cc2 100644
--- a/usr/src/uts/intel/sys/pcb.h
+++ b/usr/src/uts/intel/sys/pcb.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,6 +47,7 @@ typedef struct pcb {
greg_t pcb_drstat; /* status debug register (%dr6) */
unsigned char pcb_instr; /* /proc: instruction at stop */
#if defined(__amd64)
+ unsigned char pcb_rupdate; /* new register values in pcb -> regs */
uintptr_t pcb_fsbase;
uintptr_t pcb_gsbase;
selector_t pcb_ds;
@@ -67,7 +67,6 @@ typedef struct pcb {
#define NORMAL_STEP 0x10 /* normal debugger-requested single-step */
#define WATCH_STEP 0x20 /* single-stepping in watchpoint emulation */
#define CPC_OVERFLOW 0x40 /* performance counters overflowed */
-#define RUPDATE_PENDING 0x80 /* new register values in the pcb -> regs */
#define REQUEST_STEP 0x100 /* request pending to single-step this lwp */
#define REQUEST_NOSTEP 0x200 /* request pending to disable single-step */