I'm posting this just so people might benefit. I replaced the exchange with a read of the old value plus a write of the new value.
The memory address was obtained through MmMapIoSpace. It was mapped to the local Apic registers on the current processor. The InterlockedExchange translated into an XCHG instruction, which has locking behavior.
After doing this in my driver, eventually the system crashed with a BAD PTE code.
Curiously, if I loaded the driver, ran the user app once and then unloaded the driver, I could do this indefinitely. But if I kept the driver resident, then after the second or third time, usually, I got the crash.
If anyone has an explanation for this, I'd be curious. But otherwise, this should be a caution to avoid locking instructions with mapped addresses of this sort.