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

BHyVeビルドめも24

BHyVe DragonFlyBSD

φ(・ω・ )かきかき
ipiまわりはFreeBSDとDragonFlyで結構違うっぽいのでゆっくりと。
まずは簡単なやつだけ直しておいたのでこっからが本番ですね~

--------------------------------------------------------------
>>> Kernel build for BHYVE started on Tue Jul 24 21:26:35 JST 2012
--------------------------------------------------------------
===> BHYVE
cd /usr/src/sys/config;  PATH=/usr/obj/usr/src/ctools_x86_64_x86_64/usr/sbin:/usr/obj/usr/src/ctools_x86_64_x86_64/usr/bin:/usr/obj/usr/src/ctools_x86_64_x86_64/bin:/usr/obj/usr/src/ctools_x86_64_x86_64/usr/games:/usr/obj/usr/src/btools_x86_64/usr/sbin:/usr/obj/usr/src/btools_x86_64/usr/bin:/usr/obj/usr/src/btools_x86_64/bin:/usr/obj/usr/src/btools_x86_64/usr/games:/usr/pkg/bin  config  -d /usr/obj/usr/src/sys/BHYVE  /usr/src/sys/config/BHYVE
Kernel build directory is /usr/obj/usr/src/sys/BHYVE
cd /usr/obj/usr/src/sys/BHYVE;  MAKEOBJDIRPREFIX=/usr/obj/usr/src/world_x86_64  OBJTREE=/usr/obj  MACHINE_ARCH=x86_64  MACHINE=x86_64  MACHINE_PLATFORM=pc64  OBJFORMAT_PATH=/usr/obj/usr/src/ctools_x86_64_x86_64  HOST_CCVER=gcc44  CCVER=gcc44  BINUTILSVER=binutils221  DESTDIR=/usr/obj/usr/src/world_x86_64  INSTALL="sh /usr/src/tools/install.sh"  PATH=/usr/obj/usr/src/ctools_x86_64_x86_64/usr/sbin:/usr/obj/usr/src/ctools_x86_64_x86_64/usr/bin:/usr/obj/usr/src/ctools_x86_64_x86_64/bin:/usr/obj/usr/src/ctools_x86_64_x86_64/usr/games:/usr/obj/usr/src/btools_x86_64/usr/sbin:/usr/obj/usr/src/btools_x86_64/usr/bin:/usr/obj/usr/src/btools_x86_64/bin:/usr/obj/usr/src/btools_x86_64/usr/games:/usr/pkg/bin make KERNEL=kernel all
cc -c -O -pipe  -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wold-style-definition -std=c99 -Wold-style-declaration -g -nostdinc -I. -Iinclude -I/usr/src/sys -I/usr/src/sys/../include -I/usr/obj/usr/src/sys/BHYVE -I"/usr/src/sys/dev/acpica5" -I"/usr/src/sys/contrib/dev/acpica-unix/include" -I/usr/src/sys/dev/netif/ath/hal -I/usr/src/sys/dev/netif/ath/hal/ath_hal  -D_KERNEL -include opt_global.h  -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common -ffreestanding -mpreferred-stack-boundary=4 -fno-stack-protector -mcmodel=kernel -mno-red-zone -mfpmath=387 -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-sse4a  -mno-sse5 -mno-abm -mno-aes -mno-avx -mno-pclmul -mno-popcnt -msoft-float -fno-asynchronous-unwind-tables -fno-omit-frame-pointer  /usr/src/sys/platform/pc64/vmm/vmm_ipi.c -Werror
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:51: error: 'IPI_AST' undeclared here (not in a function)
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:53: error: 'APIC_SPURIOUS_INT' undeclared here (not in a function)
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c: In function 'vmm_ipi_init':
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:72: error: 'APIC_IPI_INTS' undeclared (first use in this function)
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:72: error: (Each undeclared identifier is reported only once
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:72: error: for each function it appears in.)
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:73: error: 'idt' undeclared (first use in this function)
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:78: error: too few arguments to function 'setidt'
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c: In function 'vmm_ipi_cleanup':
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:93: error: too few arguments to function 'setidt'
cc1: warnings being treated as errors
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c: In function 'vm_interrupt_hostcpu':
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:102: error: implicit declaration of function 'ipi_cpu'
/usr/src/sys/platform/pc64/vmm/vmm_ipi.c:102: error: nested extern declaration of 'ipi_cpu'
*** Error code 1

Stop in /usr/obj/usr/src/sys/BHYVE.
*** Error code 1

Stop in /usr/src.
*** Error code 1

Stop in /usr/src.

基本的にはマクロの定義、関数の引数が合ってない、関数がない、そんな変数はないというパターンです。
マクロに関してはFreeBSDならapicvar.hで定義されているんですが、dfbsdだと実質1行しかapicvar.hはありません\(^o^)/
一番古いgitの歴史でもこの辺のマクロいない感じだったので別の方法を取っているんでしょうね。

次に、idtがいないとかsetidtの引数違うしってところはfbsdから見てみますと、変数idtの実体の宣言がamd64/amd64/machdep.c?に。

996 static struct gate_descriptor idt0[NIDT];
997 struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */
998 

ここでNIDTは256となっていて、まあ割り込みテーブルの大きさですね。itd0の"0"はbspのことなのかな?そうだとすると変数idtはbspのidtを指すんだよねーと思ったりします。

そしてsetidt()はこれです。特別なことはしてないですよね。はじめて読む486の割り込みの章でidt設定しているところを思い出したとかそんな程度です。

 1132 void
 1133 setidt(idx, func, typ, dpl, ist)
 1134         int idx;
 1135         inthand_t *func;
 1136         int typ;
 1137         int dpl;
 1138         int ist;
 1139 {
 1140         struct gate_descriptor *ip;
 1141 
 1142         ip = idt + idx;
 1143         ip->gd_looffset = (uintptr_t)func;
 1144         ip->gd_selector = GSEL(GCODE_SEL, SEL_KPL);
 1145         ip->gd_ist = ist;
 1146         ip->gd_xx = 0;
 1147         ip->gd_type = typ;
 1148         ip->gd_dpl = dpl;
 1149         ip->gd_p = 1;
 1150         ip->gd_hioffset = ((uintptr_t)func)>>16 ;
 1151 }

では、dfbsdを見てみますと、こちらはidtではなくてidt_arrという名前の変数を使うようになっています。大体想像付くと思いますがidtの配列でfbsdと違って1cpu(core)につき1つのidtがペアになる感じです。ソースはsys/platform/pc64/x86_64/machdep.cです。

struct user_segment_descriptor gdt[NGDT * MAXCPU];	/* global descriptor table */
struct gate_descriptor idt_arr[MAXCPU][NIDT];

そしてsetidt()はというとこんな感じになります。

void
setidt(int idx, inthand_t *func, int typ, int dpl, int ist, int cpu)
{
	struct gate_descriptor *ip;

	KASSERT(cpu >= 0 && cpu < ncpus, ("invalid cpu %d\n", cpu));

	ip = &idt_arr[cpu][idx];
	ip->gd_looffset = (uintptr_t)func;
	ip->gd_selector = GSEL(GCODE_SEL, SEL_KPL);
	ip->gd_ist = ist;
	ip->gd_xx = 0;
	ip->gd_type = typ;
	ip->gd_dpl = dpl;
	ip->gd_p = 1;
	ip->gd_hioffset = ((uintptr_t)func)>>16 ;
}

fbsdとの違いは、どのcpuのidtに値をセットするかを選べるところですね。ちなみにsetidt_global()というのもあって、これは全cpuに対して処理をするというところがsetidt()との違いになってます。

このcpuを選べるというところがまあコンパイルエラーの原因になっていて、vmm_ipi.cのvmm_ipi_init()の以下のところで引数が1個足りないためコンパイルエラーになるわけですね。

setidt(ipinum, IDTVEC(justreturn), SDT_SYSIGT,
			       SEL_KPL, 0);

ここで悩むのはどのcpuのidtにデータをセットしたら良いのかってところです。fbsdは常に固定されたidtが使われる気配ですけどdfbsdはidtをcpu数分持ってますからね。そうするとカレントcpu(mycpuid)を使うかなってところに落ち着くのですが。