[vbox-dev] GDT entries syncing between qemu mode & raw mode bug

lin zuojian manjian2006 at gmail.com
Thu Dec 24 03:23:17 UTC 2015


Hi friends,
    When I turn off the vt of my machine, my linux occasionally meets
    a coredump, which eip points to the following something like this:
    movl %ecx, %gs:0
    And that's the tls of linux conventions controlled by gdt.
    And the wired thing is that when a gdb attached into the
    will-coredump process, and enter 'continue', the process that should
    trigger coredump continues to run normally.
    I guess this is a syncing bug between raw mode and qemu mode, So I
    add patch like following:
diff --git a/src/recompiler/VBoxRecompiler.c b/src/recompiler/VBoxRecompiler.c
index d74eeb0..fdba032 100644
--- a/src/recompiler/VBoxRecompiler.c
+++ b/src/recompiler/VBoxRecompiler.c
@@ -2063,6 +2063,7 @@ void remR3RecordCall(CPUX86State *env)
 #endif
 }
 
+#define DEEP_SYNC_SEGMENT_REG /* add by linsh for VT */
 
 /**
  * Syncs the internal REM state with the VM.
@@ -2089,7 +2090,14 @@ REMR3DECL(int)  REMR3State(PVM pVM, PVMCPU pVCpu)
     uint8_t                 u8TrapNo;
     uint32_t                uCpl;
     int                     rc;
+#ifdef DEEP_SYNC_SEGMENT_REG /* add by linsh for VT */
 
+	VBOXGDTR	GDTR;
+	RTGCPTR 	GCPtrGDT;
+	unsigned	iGDT;
+	unsigned	cGDTs;
+
+#endif
     STAM_PROFILE_START(&pVM->rem.s.StatsState, a);
     Log2(("REMR3State:\n"));
 
@@ -2406,7 +2414,52 @@ REMR3DECL(int)  REMR3State(PVM pVM, PVMCPU pVCpu)
     SYNC_IN_SREG(&pVM->rem.s.Env, GS, &pVM->rem.s.Env.segs[R_GS], &pCtx->gs);
     /** @todo need to find a way to communicate potential GDT/LDT changes and thread switches. The selector might
      * be the same but not the base/limit. */
+#ifdef DEEP_SYNC_SEGMENT_REG /* add by linsh for VT */
 
+/*
+*Check for the base address of the SegmentCache
+*/
+#define DEEP_SYNC_SEG_REG(a_pRemSReg,a_SReg,a_pVBoxSReg,a_pGDTE,a_Sel) \
+	    do \
+        { \
+        	if (a_Sel == (((a_pVBoxSReg)->Sel) >> 3)/* && (a_Sel == 6 || a_Sel == 7) */) \
+        	{ \
+				if ((a_pRemSReg)->base != X86DESC_BASE(a_pGDTE) ) \
+				{ \
+					Log2(("REMR3State: " #a_SReg " base had changed from %08x to %08x!\n", \
+					(a_pRemSReg)->base, X86DESC_BASE(a_pGDTE))); \
+					(a_pRemSReg)->base  = X86DESC_BASE(a_pGDTE); \
+					(a_pRemSReg)->limit = X86DESC_LIMIT_G(a_pGDTE); \
+				} \
+        	} \
+        } while (0)
+
+	/* Get the GDTR */
+	CPUMGetGuestGDTR(pVCpu, &GDTR);
+	if (GDTR.cbGdt < sizeof(X86DESC))
+	{
+		Log2(("REMR3State: No GDT entries...\n"));
+		return VINF_SUCCESS;
+	}
+
+	GCPtrGDT = GDTR.pGdt;
+	cGDTs = ((unsigned)GDTR.cbGdt + 1) / sizeof(X86DESC);
+
+	for (iGDT = 0; iGDT < cGDTs; iGDT++, GCPtrGDT += sizeof(X86DESC))
+	{
+		X86DESC GDTE;
+		int rc = PGMPhysSimpleReadGCPtr(pVCpu, &GDTE, GCPtrGDT, sizeof(GDTE));
+		if (RT_SUCCESS(rc))
+		{
+			if (GDTE.Gen.u1Present)
+			{
+				Log2(("REMR3State: iGDT:%d,base:%08x,limit:%08x\n",iGDT,X86DESC_BASE(&GDTE),X86DESC_LIMIT_G(&GDTE))); 
+				DEEP_SYNC_SEG_REG(&pVM->rem.s.Env.segs[R_GS], GS, &pCtx->gs, &GDTE, iGDT );
+			}
+		}
+	}
+	
+#endif

    The coredump never ever happend again.
--
Lin Zuojian



More information about the vbox-dev mailing list