The strange problem about this is that my interrupt handling is known to work. If I place an "int 3" before the wrmsr, my kernel dumps the register states to the screen. EDX:EAX and ECX match what I would expect for the wrmsr instruction. If I place the "int 3" after the wrmsr instruction, the triple fault occurs. There is plenty of stack space (ie. it is not a kmode stack overflow triple fault).
Furthermore, it works fine under Bochs and on a Pentium 3 processor. The actual system call also works fine. It does not work on all the Pentium 4 computers that I have at home, but I cannot find any documentation in the Intel manuals about changes in MSR functionality. Interrupts are disabled and it is ring 0 code.
Also, according to the documentation, a #GP is generated if the MSR number is out of range or if reserved bits are set. I know that it is not GPF'ing since I successfully receive a GPF if I intentionally choose an invalid MSR address.
The register states reported by the int3 instruction are absolutely identical on both a working machine and a nonworking machine:
Code: Select all
IoDumpContext() : ISR 0x03, code 0x00000000
EAX=0x803007FE ECX=0x00000176 EDX=0x00000000 EBX=0x00003A10 ESP=0x80006FBC
EBP=0x80006FEC ESI=0x00003A10 EDI=0x00000000 EIP=0x80302EBC EFL=0x00000046
CR0=0x80000011 CR1=0x00000000 CR2=0x00000000 CR3=0x00100000 CR4=0x00000000
CS=0x0008 DS=0x0010 ES=0x0010 FS=0x0010 GS=0x0010 SS=0x0010
Code: Select all
; void WriteMSR(unsigned int msr, unsigned int lowval)
_WriteMSR@8:
mov ecx, dword ptr [esp+4]
mov eax, dword ptr [esp+8]
xor edx, edx
wrmsr
ret 8
Thanks in advance.