Triple Fault on Accesses to the VGA Memory [solved]

Discussions related to using VirtualBox on Windows hosts.
Post Reply
yellowriver81
Posts: 3
Joined: 22. Jul 2021, 03:36

Triple Fault on Accesses to the VGA Memory [solved]

Post by yellowriver81 »

Hi,

I hope this is right place to ask this question: I am working on developing a small kernel as a personal project. I have been using the Bochs PC emulator so far to test my kernel, and it has been working fine. However, when I run it on VirtualBox (6.1.2, booting from floppy), I sometimes get a triple fault after jumping into my kernel. I would say it happens around 50% of the time. Looking at the EIP for the triple fault, it is always on a read or write to the VGA video memory. I have attached the log from one run where it triple faulted after printing 5 characters. I have verified that the VGA memory has been properly mapped in virtual memory (it is within the first 4 MB, which I have mapped to itself). What could be going on here? Is there any way to see what exceptions were raised leading up to the triple fault? Or, better, is there a way to run with a debugger attached?

Thanks a lot in advance.

*Edit: The image seems to work every time without any issues on VMWare as well.
Attachments
VBox.7z
(33.09 KiB) Downloaded 8 times
Last edited by yellowriver81 on 22. Jul 2021, 23:27, edited 1 time in total.
fth0
Volunteer
Posts: 5668
Joined: 14. Feb 2019, 03:06
Primary OS: Mac OS X other
VBox Version: PUEL
Guest OSses: Linux, Windows 10, ...
Location: Germany

Re: Triple Fault on Accesses to the VGA Memory

Post by fth0 »

VBox.log file wrote:
00:00:05.928155 !!
00:00:05.928155 !! {cpumguest, verbose}
00:00:05.928156 !!
00:00:05.928163 Guest CPUM (VCPU 0) state: 
00:00:05.928168 eax=000b8008 ebx=c0004000 ecx=00000000 edx=00000f67 esi=ffff1000 edi=00080000
00:00:05.928171 eip=c0000f42 esp=fffffe70 ebp=fffffe98 iopl=0      rf nv up ei pl zr na po nc
00:00:05.928173 cs={0008 base=0000000000000000 limit=ffffffff flags=0000c09b} dr0=00000000 dr1=00000000
00:00:05.928176 ds={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr2=00000000 dr3=00000000
00:00:05.928177 es={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr4=00000000 dr5=00000000
00:00:05.928179 fs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr6=ffff0ff0 dr7=00000400
00:00:05.928181 gs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr0=80000011 cr2=00000000
00:00:05.928182 ss={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr3=00080000 cr4=00000000
00:00:05.928184 gdtr=0000000000008e5b:0017  idtr=0000000000000000:ffff  eflags=00210206
[...]
00:00:05.928303 !!
00:00:05.928303 !! {cpumguestinstr, verbose}
00:00:05.928304 !!
00:00:05.928339 
00:00:05.928339 CPUM0: 0008:c0000f42 e8 c3 00 00 00          call 0c000100ah
00:00:05.928340 
[...]
00:00:05.930156 !!
00:00:05.930157 !! {exits}
00:00:05.930157 !!
00:00:05.930160 CPU[0]: VM-exit history:
00:00:05.930160    Exit No.:     TSC timestamp / delta    RIP (Flat/*)      Exit    Name
00:00:05.930166       16035: 0x00007122cd3166b7/+0        00000000c0000f42  0x01002 VMX_EXIT_TRIPLE_FAULT - 2 - Triple fault.
00:00:05.930172       16034: 0x00007122cd275ad6/-658401   00000000c0000f42  0x01001 VMX_EXIT_EXT_INT - 1 - External interrupt.
00:00:05.930177       16033: 0x00007122cd273df7/-7391     00000000c0000f3f  0x40005 MMIO access
00:00:05.930181       16032: 0x00007122cd272581/-6262     00000000c0000f3f  0x40005 MMIO access
00:00:05.930185       16031: 0x00007122cd270e30/-5969     00000000c0000f3f  0x40005 MMIO access
Some excerpts from the VBox.log file you may be interested in.
yellowriver81 wrote:VirtualBox (6.1.2, booting from floppy)
It may not be important, but why are you using such an old VirtualBox version (6.1.2 is from Jan. 2020, 6.1.24 is current)?
yellowriver81 wrote:Looking at the EIP for the triple fault, it is always on a read or write to the VGA video memory.
This time it's a call instruction, going to another memory page, but no paging error is reported.
yellowriver81 wrote:Is there any way to see what exceptions were raised leading up to the triple fault?
The VM-exit history may give some hints. Are the EIP/RIP addresses as expected?
yellowriver81 wrote:Or, better, is there a way to run with a debugger attached?
Yes, see 12.1.4. The Built-In VM Debugger for instructions.
yellowriver81
Posts: 3
Joined: 22. Jul 2021, 03:36

Re: Triple Fault on Accesses to the VGA Memory

Post by yellowriver81 »

Thank you for your response! I was using version 6.1.2 because it was what I had last installed and haven't upgraded since. I have now updated to 6.1.24 but am getting the same behavior. Based on my understanding, EIP should point to the next instruction to be fetched, is that correct? According to this, the faulting instruction should be the one immediately before the call. In this case, the listing is

Code: Select all

0xc0000f3c: mov eax, [ebp - 0xc]
0xc0000f3f: mov [eax], dx           <- currently executing instruction (I believe?)
0xc0000f42: call 0xc000100a       <- EIP reported in log
In another scenario, the stopping point is as illustrated below:

Code: Select all

0xc0000fa7: movzx eax, word ptr [ecx]
0xc0000faa: mov [edx], ax          <- currently executing instruction (I believe?)
0xc0000fad: add [ebp - 4], 1       <- EIP reported in log
In all scenarios the instruction preceding the reported EIP causes the triple fault and Guru Meditation. And in all of these cases, it is always a read or write from the VGA text memory region beginning at

Code: Select all

0xb8000
.
fth0
Volunteer
Posts: 5668
Joined: 14. Feb 2019, 03:06
Primary OS: Mac OS X other
VBox Version: PUEL
Guest OSses: Linux, Windows 10, ...
Location: Germany

Re: Triple Fault on Accesses to the VGA Memory

Post by fth0 »

yellowriver81 wrote:Based on my understanding, EIP should point to the next instruction to be fetched, is that correct? According to this, the faulting instruction should be the one immediately before the call.
Let's meet in the middle. ;) I'll put up a theory:

While the preceding mov instruction was executed, an interrupt was triggered. The vCPU finished executing the mov (compare {vgatext} and EAX/EDX), the interrupt led to a VM-exit and was allowed by the hypervisor. vCPU0 had interrupts enabled (EFLAGS.IF=1), but the interrupt table (IDTR) was not set up appropriately, leading to a double- and triple-fault inside the guest OS.
yellowriver81
Posts: 3
Joined: 22. Jul 2021, 03:36

Re: Triple Fault on Accesses to the VGA Memory

Post by yellowriver81 »

You are right! For some strange reason, even though I had cleared the interrupt flag before entering protected mode, it got set again. But in any case, disabling interrupts again once I had entered protected mode prevents the triple fault and Guru Meditation.

Appreciate your help! Your explanation was very clear.
Post Reply