1

tl;dr

Are Linux kernel functions outw() and inw() atomic when accessing ISA/LPC on x86 on a multicore system, given that at a HW level it must consist of four separate 8-bit transactions?

As an equivalent question, since outw() and inw() functions are wrappers for inline assembly instructions of the same name, are these instructions guaranteed to be atomic when accessing LPC/ISA on a multicore x86?

Background

I am currently writing a Linux driver for a device that expects 32-bit accesses, but in interfaced to the LPC bus (which appears as an ISA bus to the OS). An FPGA maps the four separate 8-bit LPC transactions to a single 32-bit transaction.

I can see that for x86, the kernel defines outw and outl for x86, which degenerate into inline assembly instructions of the same name.

Are these functions/instructions defined to be atomic, even on a multicore system? In particular, I am thinking of a possible race condition if only (for example) two of the four bytes are accessed before another core runs the interrupt starts a new (pseudo) 32-bit transaction. LDD3 doesn't say much other than acknowledging the existence of the functions, and the kernel documentation is similarly unhelpful in this regard.

In the meantime, I have implemented as four separate inb() transactions, wrapped in a spinlock. (It doesn't matter if other drivers insert transactions in between because the FPGA translator will not include those addresses when building the 32-bit transaction).

(As an aside, I have tested outw() and inw() and they do indeed perform a multi-byte access on my platform - Intel Atom Bay Trail - but the question on the possible race condition remains).

Damien
  • 785
  • 3
  • 8
  • 18
  • Even if you do use a spinlock, why not use a single 32-bit IN instruction? I'm pretty sure it's not going to be slower than 4 separate INB instructions. Good question about atomicity, though. I'm not sure. – Peter Cordes Oct 01 '16 at 10:35
  • @PeterCordes, thanks. It's a good suggestion, though the question of atomicity still stands. – Damien Oct 04 '16 at 00:00
  • All `mov %(addr), rX` instructions on x86 are atomic. The actual issue is out-of-order and write-combine when you get your IO messed up. – 0andriy Oct 07 '16 at 14:01

0 Answers0