Re: RFC: outb 0x80 in inb_p, outb_p harmful on some modern AMD64 with MCP51 laptops

David P. Reed
2007-12-07T14:50:47Z

Andi Kleen wrote:
>> Changing the delay instruction sequence from the outb to short jumps
>> might be the safe thing.
> I don't think that makes sense to do on anything modern. The trouble
> is that the jumps will effectively execute near "infinitely fast" on any
> modern CPU compared to the bus. But the delay really needs to be something
> that is about IO port speed.
This all presumes that you need any delay at all. From back in the
early days (when I was writing DOS and BIOS code on 80286 class
machines) the /only/ reason this was a problem was using really slow
acting, non-buffered chips compared to the processor clock (8259?). If
you think about it, if there is a sequence such as outb->device,
inb<-device, the only reason for a delay would be that the device failed
to process the out command, /and/ the device had no "done" flag. The
other "slow" problem would be an out->device, out->device at a rate
higher than the device could handle because it had a one-level buffer
that ignored input that came too fast after the previous, but didn't
stall the bus to protect the device. Modern machines just are not
designed that way - a few of the early PC compatibles were.

My machine in question, for example, needs no waiting within CMOS_READs
at all. And I doubt any other chip/device needs waiting that isn't
already provided by the bus. the i/o to port 80 is very, very odd in
this context. Actually, modern machines have potentially more serious
problems with i/o ops to non-existent addresses, which may cause real
bus wierdness.

So that's why I suggested the short-jump answer - it fixes the problem
on the ancient machines, but doesn't do anything on the modern ones,
where there should be no problem.

One patch that makes immediate sense is to use the "virtualization"
hooks for the CMOS_READ/WRITE ops that is there in the 32-bit code to
allow substitution of a workable sequence for the RTC, which is where I
experience the problem on my machine. This doesn't fix any lurking
issues with the _p APIs, since they are not virtualized. I'd suggest
the safest possible route that would fix my machine would be either an
early_quirk, a boot parameter, or both that would then control the
virtualization hook logic.

That patch would fix my machine's current issues, and would not harm any
machines that need the 0x80 delay.

But I know it leaves a lurking issue for another day - for all the other
inb_p and outb_p code in the kernel drivers. A grep suggests that they
are used only in somewhat less modern drivers - perhaps for legacy
machines. I don't think any such drivers are used on any of my machines.