changeset 4503:8cf697a3acff

6493689 Jvm crash: curthread set by kernel incorrect
author sudheer
date Wed, 20 Jun 2007 03:26:40 -0700
parents 9bc04686066a
children c4dae63a92a0
files usr/src/uts/common/os/lwp.c usr/src/uts/i86pc/ml/locore.s usr/src/uts/i86pc/ml/syscall_asm_amd64.s usr/src/uts/i86pc/os/intr.c usr/src/uts/intel/amd64/ml/mach_offsets.in usr/src/uts/intel/ia32/os/archdep.c usr/src/uts/intel/ia32/os/sundep.c usr/src/uts/intel/ia32/os/sysi86.c usr/src/uts/intel/ia32/syscall/lwp_private.c usr/src/uts/intel/sys/pcb.h
diffstat 10 files changed, 37 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/os/lwp.c	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/common/os/lwp.c	Wed Jun 20 03:26:40 2007 -0700
@@ -1650,9 +1650,8 @@
 
 	/* 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;
--- a/usr/src/uts/i86pc/ml/locore.s	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/i86pc/ml/locore.s	Wed Jun 20 03:26:40 2007 -0700
@@ -1554,11 +1554,11 @@
 #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 @@
 	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
 
--- a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s	Wed Jun 20 03:26:40 2007 -0700
@@ -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 @@
 	.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 @@
 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;		\
--- a/usr/src/uts/i86pc/os/intr.c	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/i86pc/os/intr.c	Wed Jun 20 03:26:40 2007 -0700
@@ -995,7 +995,7 @@
 		/*
 		 * 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 @@
 			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);
--- a/usr/src/uts/intel/amd64/ml/mach_offsets.in	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/intel/amd64/ml/mach_offsets.in	Wed Jun 20 03:26:40 2007 -0700
@@ -135,6 +135,7 @@
 	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
--- a/usr/src/uts/intel/ia32/os/archdep.c	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/intel/ia32/os/archdep.c	Wed Jun 20 03:26:40 2007 -0700
@@ -442,7 +442,7 @@
 	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 @@
 
 	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 @@
 		/*
 		 * 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 @@
 		/*
 		 * 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();
--- a/usr/src/uts/intel/ia32/os/sundep.c	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/intel/ia32/os/sundep.c	Wed Jun 20 03:26:40 2007 -0700
@@ -375,12 +375,12 @@
 	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 @@
  * 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 @@
 	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 @@
 		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 @@
 	 * 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 @@
 
 	pcb->pcb_ds = rp->r_ds;
 	pcb->pcb_es = rp->r_es;
-	pcb->pcb_flags |= RUPDATE_PENDING;
+	pcb->pcb_rupdate = 1;
 
 #elif defined(__i386)
 
--- a/usr/src/uts/intel/ia32/os/sysi86.c	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/intel/ia32/os/sysi86.c	Wed Jun 20 03:26:40 2007 -0700
@@ -571,7 +571,7 @@
 			}
 
 #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 ||
--- a/usr/src/uts/intel/ia32/syscall/lwp_private.c	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/intel/ia32/syscall/lwp_private.c	Wed Jun 20 03:26:40 2007 -0700
@@ -72,12 +72,12 @@
 	 * 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 @@
 	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 @@
 						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 @@
 	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 @@
 						break;
 				}
 			} else {
-				if (pcb->pcb_flags & RUPDATE_PENDING) {
+				if (pcb->pcb_rupdate == 1) {
 					if (pcb->pcb_gs == LWPGS_SEL)
 						break;
 				} else {
--- a/usr/src/uts/intel/sys/pcb.h	Tue Jun 19 22:41:58 2007 -0700
+++ b/usr/src/uts/intel/sys/pcb.h	Wed Jun 20 03:26:40 2007 -0700
@@ -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 @@
 	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 @@
 #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 */