Hi,
I recently realized that on x86 virtual machines, memory operations on VGA memory mapped IO with the LOCK prefix are not atomic. An example instruction is the XCHG instruction operating on memory address 0xb8000.
Here is the information about my environment:
I have written a system-level software to demonstrate this bug. The software is attached to this post as "c.vmdk" in "c.zip". To run my code:
The expected behavior is to see the following from serial port:
... counts: count0 count1 count2 count0-count1+count2 counts: 1 0 1 0 counts: 2 1 1 0 counts: 3 1 2 0 counts: 4 2 2 0 counts: 5 2 3 0 counts: 6 3 3 0 counts: 7 3 4 0 counts: 8 4 4 0 counts: 9 5 4 0 counts: 10 5 5 0 counts: 11 5 6 0 counts: 12 6 6 0 counts: 13 7 6 0 ... (does not stop, right most column is always 0)
However, VMware's output stops at some point, and the last column may become negative. For example:
... counts: count0 count1 count2 count0-count1+count2 counts: 1 1 0 0 counts: 2 2 0 0 counts: 3 3 0 0 counts: 4 4 0 0 counts: 5 5 1 -1 ... (no more outputs)
My code is available in https://github.com/lxylxy123456/uberxmhf/blob/b5935eaf8aab38ce1933da1c1be22dcf1b992eaf/xmhf/src/xmhf... line 5 - 89
My code performs the following experiment repeatedly on 3 CPUs:
Ideally, after each experiment there should always be count1 + count2 = count0. However, in VMware, there may be count1 + count2 > count0. This because CPU 0 writes 0x12345678 to ptr once, but CPU 1 and CPU 2 both get 0x12345678 in XCHG. Note that according to Intel's specification, XCHG instruction always implements the locking protocol.
The correct behavior can be reproduced on:
The incorrect behavior can be reproduced on:
Thank you!
Did you also try on Workstation 16.2.5?
Hi RDPetruska, thank you for the prompt reply.
VMware workstation player 16.2.5 build-20904516 have the same bug.
VMware workstation player 17.0.0 build-20800274 have the same bug.
