SSE, General protection fault

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
de
Posts: 12
Joined: Tue Apr 29, 2008 2:27 pm

SSE, General protection fault

Post 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
Laksen
Member
Member
Posts: 140
Joined: Fri Nov 09, 2007 3:30 am
Location: Aalborg, Denmark

Post by Laksen »

Do you save the FPU stack and related floating point registers in your ISR?

If not your stack may be screwing up
de
Posts: 12
Joined: Tue Apr 29, 2008 2:27 pm

Post 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?
Cognition
Member
Member
Posts: 191
Joined: Tue Apr 15, 2008 6:37 pm
Location: Gotham, Batmanistan

Post 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.
Laksen
Member
Member
Posts: 140
Joined: Fri Nov 09, 2007 3:30 am
Location: Aalborg, Denmark

Post by Laksen »

How are your control registers set up?
de
Posts: 12
Joined: Tue Apr 29, 2008 2:27 pm

Post 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?
User avatar
Zenith
Member
Member
Posts: 224
Joined: Tue Apr 10, 2007 4:42 pm

Post 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?
"Sufficiently advanced stupidity is indistinguishable from malice."
de
Posts: 12
Joined: Tue Apr 29, 2008 2:27 pm

Post 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.
Cognition
Member
Member
Posts: 191
Joined: Tue Apr 15, 2008 6:37 pm
Location: Gotham, Batmanistan

Post 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.
de
Posts: 12
Joined: Tue Apr 29, 2008 2:27 pm

Post 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.
stlw
Member
Member
Posts: 357
Joined: Fri Apr 04, 2008 6:43 am
Contact:

Post 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
de
Posts: 12
Joined: Tue Apr 29, 2008 2:27 pm

Post 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) ?
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

(except vmWare which doesn't work on Vista)
Huh? I use vmware on Vista without any problems...
de
Posts: 12
Joined: Tue Apr 29, 2008 2:27 pm

Post by de »

I wasn't clear enough. vmWare doesn't work on Vista x64. At least not on any of my 3 computers...
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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).
Post Reply