[Bug 31279] Age of Empires II SafeDisc v1.x driver crashes in IDT check (INT1/3 hooks)

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Jul 22 20:39:13 CDT 2012


http://bugs.winehq.org/show_bug.cgi?id=31279

--- Comment #10 from Charles Davis <cdavis at mymail.mines.edu> 2012-07-22 20:39:13 CDT ---
(In reply to comment #9)
> 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  ---
Sure enough, every time I run this program, I get a different result.

That last digit in the limit is strange, but it doesn't seem to be a problem in
practice. I haven't had any IDT-related panics :). I suspect it's got something
to do with the number of the CPU that owns that particular IDT. So far I've
seen 1000h, 1002h, 1004h, and 1006h. I have four physical cores, so that makes
sense.
> 
> 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.
Unfortunately, I just remembered that it's not generally possible to force a
thread onto one particular CPU on Mac OS. (So, there's no 'taskset' command. I
believe that's a Linux-ism anyway.) The best one can do on Mac OS is put your
threads in an "affinity group", whereby your threads are tagged with a number;
then the scheduler runs the threads on whatever CPUs are closest to each other
in terms of memory locality (at least, that's how it's supposed to work). (This
of course makes it impossible to sanely implement Windows-style thread affinity
handling on Mac OS, which kinda makes me mad. Maybe I should start using
Linux...)

By the way, in case you're wondering, using the affinity tag API is no help. I
still see four different base/limit combinations.

This also means that forcing the NTOSKRNL thread onto a particular CPU is out.
> 
> EDIT: You actually had the same idea while I was writing this ;-)
> 
> Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list