Re: [PATCH 1/1] tty: serial: handle HAS_IOPORT dependencies

From: Maciej W. Rozycki
Date: Fri Oct 04 2024 - 12:24:17 EST


On Fri, 4 Oct 2024, Arnd Bergmann wrote:

> > It can be worse than that. Part of my confusion with the defxx driver
> > trying to do port I/O with my POWER9 system came from the mapping actually
> > resulting in non-NULL invalid pointers, dereferencing which caused a flood
> > of obscure messages produced to the system console by the system firmware:
> >
> > LPC[000]: Got SYNC no-response error. Error address reg: 0xd0010014
> > IPMI: dropping non severe PEL event
> > LPC[000]: Got SYNC no-response error. Error address reg: 0xd0010014
> > IPMI: dropping non severe PEL event
> > LPC[000]: Got SYNC no-response error. Error address reg: 0xd0010014
> > IPMI: dropping non severe PEL event
> > LPC[000]: Got SYNC no-response error. Error address reg: 0xd0010014
> > IPMI: dropping non severe PEL event
> > [...]
> >
> > from which it was all but obvious that they were caused by an attempt to
> > use PCI port I/O with a system lacking support for it.
>
> Ah, that's too bad. I think this is a result of the patch that
> Michael did to shut up the NULL pointer warning we get, see
> be140f1732b5 ("powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA
> not 0 for CONFIG_PCI=n"). I really wish we could have finished
> Niklas' series earlier to avoid this.

That was back in 2020 (5.9.0), so long before be140f1732b5, and it's a
production system, so I don't want to fiddle with it beyond necessity:

$ uptime
16:53:27 up 466 days, 9:49, 5 users, load average: 0.14, 0.12, 0.09
$

Essentially defxx has this code (not changed much since, except that
`dfx_use_mmio' is now always true for PCI):

if (!dfx_use_mmio)
region = request_region(bar_start[0], bar_len[0],
bdev->driver->name);
if (!region) {
dfx_register_res_err(print_name, dfx_use_mmio,
bar_start[0], bar_len[0]);
err = -EBUSY;
goto err_out_disable;
}
/* ... */
if (dfx_use_mmio) {
/* ... */
} else {
bp->base.port = bar_start[0];
dev->base_addr = bar_start[0];
}

so whatever came out of BAR[1]:

pci 0031:02:04.0: [1011:000f] type 00 class 0x020200
pci 0031:02:04.0: reg 0x10: [mem 0x620c080020000-0x620c08002007f]
pci 0031:02:04.0: reg 0x14: [io 0x0000-0x007f]
pci 0031:02:04.0: reg 0x18: [mem 0x620c080030000-0x620c08003ffff]
pci 0031:02:04.0: BAR0 [mem size 0x00000080]: requesting alignment to 0x10000

was supplied to `inl'/`outl' and wreaked havoc.

First of all I think `request_region', etc. ought to fail in the first
place with non-port-I/O systems: why does a request for a resource that
cannot be satisfied succeed? It would have already solved the issue with
defxx, making the driver gracefully fail to register the device. I don't
know if this has been fixed since.

Second, rather than relying on a magic mapping in the physical space
causing a bus error (unless you are absolutely sure it is going to work in
100% cases), I think it would make sense to make port I/O accessors call
BUG_ON(no_port_io) explicitly for platforms where it is only known at run
time whether PCI/e port I/O is available or not. Port I/O is the opposite
of performance already, so a couple of extra instructions will be lost in
the latency and at least POWER has conditional traps, so there'd be no
branch penalty.

> > Well, virtually all non-x86 systems continue supporting PCI/e port I/O
> > via a suitably decoded CPU-side MMIO window, so I think coming across one
> > that doesn't can still be a nasty surprise even in 2024. For instance
> > I've been happily using a PC parallel port PCIe option card, one of the
> > very few interfaces if not the only one remaining that have not ever seen
> > an MMIO variant, with my RISC-V hardware, newer than said POWER9 system.
> >
> > So far it's been the s390 and a couple of POWER system implementations
> > that have support for PCI/e port I/O removed. Have I missed anything?
>
> I meant PCIe cards with I/O space here, not host bridges. I know you
> have a lot of them, but what I've heard from Arm platform maintainers
> is that they tend to struggle finding any PCIe cards to test their
> hsot bridge drivers on, and I expect that a lot of them are actually
> broken because they have never been tested and just copied the
> implementation badly from some other driver.

I would expect serial ports to be the most common PCIe options still
using port I/O. Sadly OxSemi was acquired and their line of devices,
which support MMIO, cancelled at one point and my observations seem to
indicate that what is still manufactured uses port I/O (correct me if I'm
wrong please). Last time I checked OxSemi-based option cards were still
available though, but one may have to check with the supplier as to
whether they have been configured for MMIO or port I/O, as they're not
dual-mapped.

> I think the only new PCIe devices you can find today that still use
> I/O space are ones with compatibility registers for IBM PC style
> hardware (vga, uart, parport), but most users would never have used
> one of those and instead use the native register interface of their
> GPU (on non-x86), USB-serial and no parport. Other devices that
> needed I/O space never worked on PCIe anyway because of the lack
> of ISA style DMA.

I think serial port options are the most likely devices still in use,
given that UARTs continue being widely used in industrial applications.
Depending on application a USB serial adapter may or may not be suitable
to interface those.

> There are also a lot of Arm systems that have no I/O space support at
> all, such as the Apple M2 I'm using at the moment.

Thanks for letting me know. Is it AArch64 only that has no port I/O
support in the PCIe root complex nowadays, or is it 32-bit ARM as well?

Maciej