読者です 読者をやめる 読者になる 読者になる

BHyVeデバッグめも1

BHyVe DragonFlyBSD

φ(^∇^ ) メモナノラ
コンパイルエラーの修正は終わったのでデバッグめもに変わりましたw

昨日のカーネルパニックの原因はsys/kern/kern_slaballoc.cのここで落ちているだろうという予測をしました。

    if (ptr == NULL)
	panic("trying to free NULL pointer");

理由ですが、kfreeenv()の呼び出し元のvmm_is_pptdevでkgetenv()で取得したポインタをあとでkfreeenv()で開放しているのですが、
今のカーネルだとkgetenv("pptdevs");はNULLを返すはずなので(なにも設定してないし)whileブロックは実行されてないはずなんですよね。

boolean_t
vmm_is_pptdev(int bus, int slot, int func)
{
	int found, b, s, f, n;
	char *val, *cp, *cp2;

	/*
	 * setenv pptdevs "1/2/3 4/5/6 7/8/9 10/11/12"
	 */
	found = 0;
	cp = val = kgetenv("pptdevs");
	while (cp != NULL && *cp != '\0') {
		if ((cp2 = strchr(cp, ' ')) != NULL)
			*cp2 = '\0';

		n = ksscanf(cp, "%d/%d/%d", &b, &s, &f);
		if (n == 3 && bus == b && slot == s && func == f) {
			found = 1;
			break;
		}

		if (cp2 != NULL)
			*cp2++ = ' ';

		cp = cp2;
	}
	kfreeenv(val);
	return (found);
}

そうすると怪しいのはkfreeevn()となってこれはkfree()を呼び出していて、先のNULLチェックの場所に行き着くのですね。

    if (ptr == NULL)
	panic("trying to free NULL pointer");

FreeBSDの場合、開放しようとしたポインタがNULLなら単にreturnするだけですが、dfbsdはpanic()を呼ぶのでそこでカーネルパニックが発生するという感じです。
ということで単純な一行パッチを当てます!

diff --git a/sys/platform/pc64/vmm/vmm.c b/sys/platform/pc64/vmm/vmm.c
index 46d2e69..366b826 100644
--- a/sys/platform/pc64/vmm/vmm.c
+++ b/sys/platform/pc64/vmm/vmm.c
@@ -658,7 +658,8 @@ vmm_is_pptdev(int bus, int slot, int func)
 
 		cp = cp2;
 	}
-	kfreeenv(val);
+	if (val)
+		kfreeenv(val);
 	return (found);
 }

そしたら見事に起動しましたよ!
f:id:masami256:20120728021603p:plain
まぁ、見てのとおり「vmx_init: processor does not support VMX operation」と出てます。これはテスト環境がkvmなのでしょうがないんですけどね。