VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

According to the 80286 documentation, the LOCK prefix faults (#GP?) when IOPL<CPL, just like other privileged IOPL-based instructions.
But afaik, it's needed to perform locking for semaphores and mutexes on multiple CPU configurations? Thus a user-mode process needs to be able to use it?
Did it change with CPU generations or is it incorrectly documented for the 286?

https://www.scs.stanford.edu/05au-cs240c/lab/i386/s15_07.htm
Documents that it is sensitive, but the LOCK prefix documentation doesn't mention it's relation to IOPL? Or is it a 286 vs 386+ difference? What about NEC Vx0/186 and 808x processors? They probably allow it in any case.
Then what about the 286? Does it prevent LOCK (#GP fault) when used with IOPL<CPL?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 1, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

I think this must have changed between 286 and 386 (though I haven't tested it on a 286). The 386 documentation says that that LOCK is IOPL-sensitive in v86 mode, though. I can't see any mechanism for this in the microcode so it must be handled by random logic, unless the documentation is wrong (which is possible - the documentation for the LOCK instruction itself doesn't mention the possibility of a #GP for IOPL<3 in V86 mode). I suppose on a 286 (or a 386 in V86 mode) the idea is that the OS is supposed to catch the #GP and simulate the effect of the locked instruction. But that is going to be very slow when ideally a "LOCK XCHG" should be fast. I suppose that is why it was changed with the 386 for protected mode applications. 8086 applications rarely used LOCK so the #GP there perhaps doesn't matter.

LOCK does actually work fine on 8086/8088, though, and does something potentially useful even on instructions where it would be disallowed on the 386, as long as those instructions do more than one bus access. On the 8086/8088, LOCK just prevents any other bus accesses between the bus accesses of an instruction (so if you're doing an "OUT DX,AX" on an 8088, you won't get a DRAM refresh cycle between the first and second bytes of the output, for example).