Shadow Pagingによるオーバヘッドが大きいためにストールしているように見えるのではないかと考え、Shadow Paging の PTE を無効化した時のみ TLB をフラッシュするようにしてオーバヘッドの削減を試みましたが(r40)、ストールする状況は改善しませんでした。
ストール後、QEMUのコンソールからNMIを発生させてみた。
CPU0 panic : Fatal interrupt in VMM: 0x02 NMI CR0: 0x80000019 CR2: 0x7F98D3A5E4D0 CR3: 0x17D4F000 CR4: 0x00000020 RSP on interrupt: 0x4031FCA8 Stack information: +00 Error code / RIP : 0x4010F502 +32 RSP / SS : 0x00000058 +08 RIP / CS : 0x00000050 +40 SS / : 0x00000000 +16 CS / RFLAGS : 0x00007046 +48 / : 0x00000001 +24 RFLAGS / RSP : 0x4031FCD0 +56 / : 0x4031FD70 RAX: 0x00000000 RCX: 0x00000000 RDX: 0x17C00000 RBX: 0x00000000 RSP: 0x4031FC50 RBP: 0x4031FE00 RSI: 0x00000000 RDI: 0x003DC1F8 R8: 0x4031FD68 R9: 0x00000001 R10: 0x00000000 R11: 0x00000046 R12: 0x00000000 R13: 0x00000000 R14: 0x4031FD10 R15: 0x00000000 ES: 0x0058 CS: 0x0050 SS: 0x0058 DS: 0x0058 FS: 0x0058 GS: 0x0080 VMM state of CPU0---- -------------------------- RAX 00000031 RCX 00000000 RDX 00000000 RBX 40144690 RSP 4031F8F0 RBP 4031FB40 RSI 00000001 RDI 00000000 R8 4011E940 R9 00000000 R10 00000000 R11 00000000 R12 4031FBF0 R13 4031FB50 R14 4031FD10 R15 00000000 CR0 80000019 CR2 7F98D3A5E4D0 CR3 17D4F000 CR4 00000020 RFLAGS 00003002 GDTR 402ECD80+000000FF IDTR 401A0540+00001000 backtrace: 0x4031f8e8: 0x4011cc97 0x4031fb48: 0x4011d478 0x4031fba8: 0x40112e40 0x4031fbc8: 0x40112f43 0x4031fbe8: 0x401174d7 0x4031fe08: 0x40127a4c 0x4031ff98: 0x40118369 0x4031ffc8: 0x4012616d 0x4031fff8: 0x0 ------------------------------------------------ Guest state of CPU0 ---------------------------- RAX FFFFFFFF81311F90 RCX 64599A1600 RDX 00000000 RBX FFFF880015A61530 RSP FFFF880001803E90 RBP FFFF880001815780 RSI FFFF880015A61530 RDI FFFF880001815780 R8 000027EE R9 000027EE R10 00000000 R11 00000046 R12 00000000 R13 FFFF880015A61530 R14 FFFF880001810108 R15 FFFF880001803F48 CR0 8005003B CR2 7F98D3A5E4D0 CR3 15A7C000 CR4 000006F0 ACR ES 00010000 CS 0000A09B SS 0000C093 DS 00010000 FS 00010000 GS 00010000 LIMIT ES FFFFFFFFFFFFFFFF CS FFFFFFFFFFFFFFFF SS FFFFFFFFFFFFFFFF DS FFFFFFFFFFFFFFFF FS FFFFFFFFFFFFFFFF GS FFFFFFFFFFFFFFFF BASE ES 00000000 CS 00000000 SS 00000000 DS 00000000 FS 7F6771E72700 GS FFFF880001800000 SEL ES 00000000 CS 00000010 SS 00000018 DS 00000000 FS 00000000 GS 00000000 RIP FFFFFFFF8103FCDF RFLAGS 00000046 GDTR FFFF880001804000+0000007F IDTR FFFFFFFF815F0000+00000FFF EFER 00001D01 VMCB 0x40326000 (phys 17F26000) EXITCODE: 78=0x4E (VMEXIT_EXCP14) EXITINFO1 00000010 EXITINFO2 FFFFFFFF8103FCDF EXITINTINFO 000000EF ------------------------------------------------ Sending NMI to other CPUs The first panic occured on CPU0 : Fatal interrupt in VMM: 0x02 NMI Starting shell.
ベースとした BitVisor 1.0.1 で試したところ、Guest Linux の起動に成功しました。
切り分けのため、HPETエミュレータとRTCエミュレータを無効化してみたが、改善せず。
Index: vmm/io/ioapic_emu.c =================================================================== --- vmm/io/ioapic_emu.c (リビジョン 66) +++ vmm/io/ioapic_emu.c (作業コピー) @@ -274,9 +274,9 @@ spinlock_unlock(&ioapic->lock); - if (updated_gsi != INVALID_GSI) { - hpet_ioapic_updated(updated_gsi); - } + /* if (updated_gsi != INVALID_GSI) { */ + /* hpet_ioapic_updated(updated_gsi); */ + /* } */ return ret; } Index: vmm/io/Makefile =================================================================== --- vmm/io/Makefile (リビジョン 66) +++ vmm/io/Makefile (作業コピー) @@ -7,17 +7,18 @@ TARGET = io.o OBJS-1 = \ - hpet.o \ ioapic_emu.o \ pci_acpi.o \ pci_assign.o \ pci_core.o \ pci_init.o \ - rtc.o \ pic_emu.o \ pic_hook.o \ pit_emu.o \ +# hpet.o \ +# rtc.o \ + OBJS-$(CONFIG_TTY_SERIAL) += serial_emu.o OBJS-$(CONFIG_VTD_IOMMU) += vtd_dmar.o vtd.o
外部割り込み処理のデバッグメッセージを有効化してみたところ、 コンソールに「udev46: starting version 164」と出力された後、ベクタ 239 の APIC 割り込みが連続して発生していました。
Index: vmm/core/extint.c =================================================================== --- vmm/core/extint.c (リビジョン 66) +++ vmm/core/extint.c (作業コピー) @@ -38,7 +38,7 @@ #include "current.h" #include "panic.h" -#define EXTINT_DEBUG 1 +#define EXTINT_DEBUG 2 #ifdef EXTINT_DEBUG #define EXTINT_DBG(level, ...) \ do {
Linuxのソースコードを調査したところ、ベクタ 239 (0xef) は、ローカルタイマ割り込みのようだ。 ストールとの関連はなさそう。
/* * Local APIC timer IRQ vector is on a different priority level, * to work around the 'lost local interrupt if more than 2 IRQ * sources per level' errata. */ #define LOCAL_TIMER_VECTOR 0xef
make config で TTY_SERIAL を無効化してみたが、同じ場所でストール。
make configでACPI_DSDTと、DISABLE_SLEEP を無効化しても、ストールした。
make config で I/O のホック(仮想化)の有無を指定可能にして(r68)、I/O のホックを無効化して起動を試みたが、同じ場所でストールした。 I/O のホックが原因ではない可能性が高い。
以下のブートオプションを Guest Linux に付与してみたが、同じタイミングでストールした。
参考URL
http://ubuntuforums.org/showthread.php?t=1572287
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/638434
udevtimeout=3をGuest Linuxのブートオプションに付与しても改善せず。
udevdebugをGuest Linuxのブートオプションに付与しても、コンソールに出力されるメッセージは増えなかった。(VMMなしでも同様)
udev.log-priority=info udev.children-max=1を指定したら、メッセージが出力され、かつ、処理が直列に実行されてメッセージを読みやすくなった。
「'/sbin/modprobe' (stderr) 'FATAL: Module acpi:LMXSYSTEM: not found」というようなacpi関連のメッセージが複数出力されてていたため、acpi=offを指定して起動を試みた。
一時間近く待ったところ、INITの起動まで進んだ。 単に処理が重すぎ、udevがストールしたように見えている可能性がある。
次のパッチを適用して確かめると、udev開始後、VINTRによるinterceptが発生することが多いことが分かった。
Index: vmm/core/svm_main.c =================================================================== --- vmm/core/svm_main.c (リビジョン 68) +++ vmm/core/svm_main.c (作業コピー) @@ -360,12 +360,14 @@ * extint_check_interrupt will be inject the pending * interrupt or keep it. */ + printf("INTR\n"); break; case VMEXIT_VINTR: /* * extint_check_interrupt will be inject the pending * interrupt. */ + printf("VINTR\n"); break; case VMEXIT_NMI: panic("NMI recieved while executing guest software."); @@ -383,7 +385,8 @@ call_cpu_interpreter(); break; default: - panic ("unsupported exitcode"); + panic ("unsupported exitcode 0x%llx", + current->u.svm.vi.vmcb->exitcode); } } Index: vmm/core/svm.c =================================================================== --- vmm/core/svm.c (リビジョン 68) +++ vmm/core/svm.c (作業コピー) @@ -113,10 +113,11 @@ { if (pending) { current->u.svm.vi.vmcb->v_irq = 1; - current->u.svm.vi.vmcb->v_ign_tpr = 1; + /* current->u.svm.vi.vmcb->v_ign_tpr = 1; */ current->u.svm.vi.vmcb->intercept_vintr = 1; } else { current->u.svm.vi.vmcb->v_irq = 0; + /* current->u.svm.vi.vmcb->v_ign_tpr = 0; */ current->u.svm.vi.vmcb->intercept_vintr = 0; } }
BitVisor の SPT3 を r71 で復活させてみたところ、1回目のudevの起動に成功しました。 そのため、Shadow Page Tableの処理が重すぎてudevの処理が先に進まなかった可能性があります。
しかし、その後、2回目のudevの起動でストールし、さらに、割り込みロストなどのI/Oエラーが発生しました。
また、SPT3を有効、EPTを無効にして、実機で起動したところ、Linuxの起動中にストールしました。 SPT3を無効、EPTを無効にした状態では正常に起動するため、SPT3に問題(マージ方法に問題)があるかもしれません。
SPT3を有効にして、Guest Linuxに acpi=off を指定したところ、Guest Linux の起動に成功し、login できました。
おそらく、acpi=off にすると Linux が認識するデバイスが減るため、udev の処理が短時間で終わるようになり、タイムアウトしなくなると思います。
closeします。
QEMU上でTinyVisorを動かすと、Guest Linuxがudevの起動中にストールしました。
障害発生リビジョン: trunkのr38
関連チケット: #28637