Page 1 of 2

SSE, General protection fault

Posted: Tue Apr 29, 2008 2:45 pm
by de
My code crashes when I run it under Virtual PC 2007 (It works fine with Bochs and QEMU). I didn't write this code, instead it's a function from FreePascal. I added the faulting instruction just to make sure it accesses an aligned address. If I change the instructions to movups it doesn't cause a GPF.

AFAIK, the address 0xb80a0 is aligned to a 16-byte-boundary. Otherwise it wouldn't have "0" at it's end, right?

AFAIK, the only difference between movaps and movups is that movaps needs data aligned on a 16-byte-boundary.


Do you have any ideas why this might crash?

Code:

Code: Select all

...
40001cbf:	f7 d8                	neg    %eax
40001cc1:	3d 00 80 ff ff       	cmp    $0xffff8000,%eax
40001cc6:	0f 8c bf 00 00 00    	jl     40001d8b <SYSTEM_ALIGNEDFWDMOVESSE_3$formal$formal$SMALLINT+0xdb>
40001ccc:	f7 c6 0f 00 00 00    	test   $0xf,%esi
40001cd2:	75 5f                	jne    40001d33 <SYSTEM_ALIGNEDFWDMOVESSE_3$formal$formal$SMALLINT+0x83>
40001cd4:	0f 28 05 a0 80 0b 00 	movaps 0xb80a0,%xmm0                              ;<--- fault
40001cdb:	0f 28 04 c6          	movaps (%esi,%eax,8),%xmm0
...
Exception-details:

Code: Select all

Exception 13
Error: 0
CR2: $EFFFE8A7
Thread: 2
Exception address: $0000001B:$40001CD4
   eax=$FFFFFE20       ebx=$00000000       ecx=$00000F00       edx=$000B8F00
   esi=$000B8FA0       edi=$005660E0       ebp=$FF9FFFDE       esp=$FF9FFFBA
eflags=%00000000000000010000001001000110

Thanks,
Simon

Posted: Tue Apr 29, 2008 4:17 pm
by Laksen
Do you save the FPU stack and related floating point registers in your ISR?

If not your stack may be screwing up

Posted: Tue Apr 29, 2008 5:18 pm
by de
No interrupts fired when the code ran.

Besides my ISR uses FXSAVE and FXRSTOR to save FPU,MMX,...-state. And movaps has nothing to do with the stack, right?

Posted: Tue Apr 29, 2008 9:03 pm
by Cognition
Any idea why you're getting a CR2 value there? That usually means a pagefault. If you don't have your IDT properly set that could cause it, but it wouldn't explain the gpf error firing in the first place. I'm the addressing syntax looks a bit odd in the source you've pasted as well, I dunno if that's from objdump simplifying a few things or what. But I'd expect it to look like ($0xB80a0) vs just the number.

Posted: Wed Apr 30, 2008 12:25 am
by Laksen
How are your control registers set up?

Posted: Wed Apr 30, 2008 2:55 am
by de
Values show up as $0x1234, addresses as 0x1234. To make it easier to read, here's the same code in Intel-FPC-asm-syntax:

Code: Select all

  ...
  test    esi,15              {Check if Both Source/Dest Aligned}
  jnz     @SmallUnaligned
@SmallAligned:                {Both Source and Dest 16-Byte Aligned}
@SmallAlignedLoop:
  movaps  xmm0,[$b80a0]                               {<---- Fault}
  movaps  xmm0,[esi+8*eax]
  movaps  xmm1,[esi+8*eax+16]
  movaps  xmm2,[esi+8*eax+32]
  ...
I output the value of CR2 everytime, wether it was a pagefault or not. Basically I was just too lazy to put an "if" there. Those are the values of the other control registers:

Code: Select all

cr0=%10000000000000000000000000010001
cr3=%00000111101000110000000000000000
cr4=%00000000000000000000011010010000
CR0 has "protection enable", "paging" and "extension type" set. CR4 has "page size extension", "page global enable", "OSFXSR (OS supports FXSAVE and FXRSTOR)" and "OSXMMEXCPT (Throw SSE exceptions)" set. My reference was Intel's SDM, Volume 3: System Programming, Page 53.

Note that movups works... Does that make sense to you?

Posted: Wed Apr 30, 2008 7:10 am
by Zenith
That's pretty weird...

Does only that specific instruction trigger a fault, or do the following 'movaps' trigger one too? Also, (I'm not sure about this) doesn't CR2 only get loaded on a Page Fault?

Posted: Wed Apr 30, 2008 7:28 am
by de
The first movaps triggers the exception. I can comment the first 5 out - then the 6th one will fail.


CR2 gets loaded on a page fault, right. My OS does demand-paging. That's why CR2 isn't empty. Accessing the specified address with non-sse instructions works. Therefore I don't think it's related to page-faults.

Posted: Wed Apr 30, 2008 9:15 am
by Cognition
I'd give it a shot with another aligned instruction, maybe movntdqa or movdqa if virtual pc supports it. See if you get the same kind of results. If it's just that single instruction then I'd say it's a bug. The fact that it's running on two other emulators is very suspect.

Posted: Wed Apr 30, 2008 9:26 am
by de
Yeah, great idea. I'll try that.

That it runs under bochs is no wonder. Bochs doesn't check the alignment when executing this instruction.

Posted: Wed Apr 30, 2008 3:44 pm
by stlw
de wrote:Yeah, great idea. I'll try that.

That it runs under bochs is no wonder. Bochs doesn't check the alignment when executing this instruction.
Bochs does check the alignment for SSE instruction, QEMU doesn't.
But it depends by which Bochs version you are using.
My guess is that your segment base is not 16 byte aligned so althrough effective address of the instruction is 16 byte aligned - instruction will still #GP.

MOVAPS should #GP fault always when linear address (seg_base+ea) is not aligned to 16-byte boundary.

Bochs had a bug and checked only effective address which is mostly correct, I don't remember when already, but recently it was fixed to check linear address.

Stanislav

Posted: Wed Apr 30, 2008 4:46 pm
by de
These are the results of trying other, related instructions:

From memory to register
movapd faults
movaps faults

movdqa works
movdqu works
movups works
movupd works

From register to memory
movaps faults
movapd faults
movdqa faults

movdqu works
movups works
movupd works


stlw, you're right. I checked old bochs source files by mistake. The current version checks alignment. I ran this on 2.3.6, the most recent version. When trying to execute "movaps xmm0,[$b80a1]" Bochs gives me the GPF.

All the segment bases are 0. I just re-checked that using my source and with the bochs debugger.




Could anyone test "movaps xmm0,[$b80a0]" under his/her os and VPC ? Maybe this would give some insights what's going on here...



Btw: My OS doesn't run under VirtualBox because of PCI issues. But I'm working on it... Are there other programs I could test my OS under (except vmWare which doesn't work on Vista) ?

Posted: Wed Apr 30, 2008 4:55 pm
by pcmattman
(except vmWare which doesn't work on Vista)
Huh? I use vmware on Vista without any problems...

Posted: Wed Apr 30, 2008 4:57 pm
by de
I wasn't clear enough. vmWare doesn't work on Vista x64. At least not on any of my 3 computers...

Posted: Wed Apr 30, 2008 4:58 pm
by pcmattman
Ah, that makes sense then. I think x64 is supported in either the newest release or the newest beta (though that's from memory).