http://bugs.winehq.org/show_bug.cgi?id=31279
--- Comment #9 from Anastasius Focht focht@gmx.net 2012-07-22 19:57:43 CDT --- Hello,
--- quote --- Interesting. It looks like the address it's trying to read is before the IDT even starts:
003e:trace:int:emulate_instruction mov idt,xxx (0x7c2f0008, base=0x7c31b000, limit=0x1006) at 0x54287f
Why would that be? There are two others before it:
003e:trace:int:emulate_instruction mov idt,xxx (0x7c2f0008, base=0x7c2f0000, lim it=0x1004) at 0x54287f 003e:trace:int:emulate_instruction mov idt,xxx (0x7c2f0018, base=0x7c2f0000, lim it=0x1004) at 0x542884 --- quote ---
The limits look very strange (invalid). Maybe this is an OSX specific thing, I'm not familiar with that OS. Can you compile and execute this short C program:
--- snip sidt.c --- #include <stdio.h>
struct { unsigned short limit; unsigned int base; } __attribute__ ((packed)) idtr;
int main(int argc, char **argv) { asm ("sidt %0" : "=m" (idtr)); printf("IDTR base at 0x%X\n",(int)idtr.base); printf("IDTR limit 0x%X\n",(int)idtr.limit); return 0; } --- snip sidt.c ---
One thing that comes to my mind is that IDT's are per CPU core. If the IDT addresses are different between cores and the thread is migrated to different cores in between two "sidt" calls then this kind of thing (IDT base change) might happen.
You could try:
$ taskset -c 0 ./sidt $ taskset -c 1 ./sidt $ taskset -c 2 ./sidt $ taskset -c 3 ./sidt
and see if the IDT bases are the same to rule out such kind of problem.
EDIT: You actually had the same idea while I was writing this ;-)
Regards