mbox series

[RFC,00/32] Kconfig: Introduce HAS_IOPORT and LEGACY_PCI options

Message ID 20211227164317.4146918-1-schnelle@linux.ibm.com
Headers show
Series Kconfig: Introduce HAS_IOPORT and LEGACY_PCI options | expand

Message

Niklas Schnelle Dec. 27, 2021, 4:42 p.m. UTC
Hello Kernel Hackers,

Some platforms such as s390 do not support legacy PCI devices nor PCI I/O
spaces. On such platforms I/O space accessors like inb()/outb() are merely
stubs that can never actually work. The way these stubs are implemented in
asm-generic/io.h leads to compiler warnings because any use will
essentially lead to a NULL pointer access. In a previous patch we tried
handling this case by generating a run-time warning on access. This
approach however was rejected by Linus in tha mail below with the argument
that this really should be a compile-time check and, though a much more
invasive change, we believe that is indeed the right approach.

https://lore.kernel.org/lkml/CAHk-=wg80je=K7madF4e7WrRNp37e3qh6y10Svhdc7O8SZ_-8g@mail.gmail.com/

This patch series aims to do exactly that by introducing a HAS_IOPORT
config option akin to the existing HAS_IOMEM. When this is unset
inb()/outb() and friends may not be defined. Now since I/O port access is
not only used in legacy PCI devices or with legacy I/O spaces for backwards
compatible PCI Express devices, but also for  example in ACPI we also
introduce another config option LEGACY_PCI to specifically disable the
compilation of drivers for legacy PCI devices and legacy I/O space uses
while keeping I/O port accessors for non-legacy uses. This allows modern
systems which do not need legacy PCI support to skip building drivers for
legacy devices while keeping e.g.  ACPI support.

This series builts heavily on an original patch for demonstating the
concept by Arnd Bergmann and was created in collaboration with him as
discussed in the follow up to his original patch here:

https://lore.kernel.org/lkml/CAK8P3a0MNbx-iuzW_-=0ab6-TTZzwV-PT_6gAC1Gp5PgYyHcrA@mail.gmail.com/

It rebases his patch on v5.16-rc7, adds the missing arch selects for
HAS_IOPORT, fixes a few trivial findings from the original patch discussion
and splits the patch into more manageable patches. One other thing that
came up during the discussion is the idea of adding a separate
HARDCODED_IOPORTS config option for drivers which use hardcoded I/O port
numbers, this is not currently implemented but could still be added if we
find enough drivers that should not be compiled on platforms where
HAS_IOPORT is set but these hardcoded I/O ports will not work. According to
the above discussion John Garry is looking into this but I wanted to get
the discussion going on this proposal.

The series is split up into multiple patches as follows:

- Patch 01: Adds the LEGACY_PCI config and selects it for all remaining
  drivers for legacy PCI devices.

- Patch 02: Adds the HAS_IOPORT config option and selects it for those
  architectures supporting the I/O space access. It is currently not
  selected for s390, nds32, um, h8300, nios2, openrisc, hexagon, csky, and
  xtensa

- Patches 03-26: Add HAS_IOPORT dependencies on a per subsystem basis.
  These dependencies are either Kconfig "depends on" or ifdefs where I/O
  port access is an alternative path or required e.g. for a sysfs file.

- Patches 27-31: Handle HAS_IOPORT dependencies for some special cases such
  as sysfs files, PCI quirks and in USB code.

- Patch 32: Removes the inb()/outb() etc. definitions in asm-generic/io.h
  when HAS_IOPORT is not selected e.g. on s390.

I performed the following testing:

- On s390 this series on top of v5.16-rc7 builds with allyesconfig i.e. the
  HAS_IOPORT=n case. It also builds with defconfig and the resulting kernel
  appears fully functional including tests with PCI devices.

- On x86_64 with a config based on Arch Linux' standard config and
  LEGACY_PCI=n it builds and I've been running kernels with this
  configuration for over a week without issue on my Ryzen 3990X based
  workstation (initially based on v5.16-rc6). I also tested LEGACY_PCI=y
  though I do not have any legacy PCI devices, I did confirm though that
  the additional modules are built as expected.

- For ARM64 I cross-compiled based on the current Arch Linux ARM generic
  kernel config and LEGACY_PCI=n and have been running a v5.16-rc6 based
  version of this patch on my Raspberry Pi 4 (DT not UEFI) and checked that
  the PCI based USB still works.

For easy consumption a branch on top of v5.16-rc7 is also available from my
Github here https://github.com/niklas88/linux/tree/has_ioport_rfc_v1

Thanks,
Niklas Schnelle

Niklas Schnelle (32):
  Kconfig: introduce and depend on LEGACY_PCI
  Kconfig: introduce HAS_IOPORT option and select it as necessary
  ACPI: Kconfig: add HAS_IOPORT dependencies
  parport: PC style parport depends on HAS_IOPORT
  char: impi, tpm: depend on HAS_IOPORT
  speakup: Kconfig: add HAS_IOPORT dependencies
  Input: gameport: add ISA and HAS_IOPORT dependencies
  comedi: Kconfig: add HAS_IOPORT dependencies
  sound: Kconfig: add HAS_IOPORT dependencies
  i2c: Kconfig: add HAS_IOPORT dependencies
  Input: Kconfig: add HAS_IOPORT dependencies
  iio: adc: Kconfig: add HAS_IOPORT dependencies
  hwmon: Kconfig: add HAS_IOPORT dependencies
  leds: Kconfig: add HAS_IOPORT dependencies
  media: Kconfig: add HAS_IOPORT dependencies
  misc: handle HAS_IOPORT dependencies
  net: Kconfig: add HAS_IOPORT dependencies
  pcmcia: Kconfig: add HAS_IOPORT dependencies
  platform: Kconfig: add HAS_IOPORT dependencies
  pnp: Kconfig: add HAS_IOPORT dependencies
  power: Kconfig: add HAS_IOPORT dependencies
  video: handle HAS_IOPORT dependencies
  rtc: Kconfig: add HAS_IOPORT dependencies
  scsi: Kconfig: add HAS_IOPORT dependencies
  watchdog: Kconfig: add HAS_IOPORT dependencies
  drm: handle HAS_IOPORT dependencies
  PCI/sysfs: make I/O resource depend on HAS_IOPORT
  PCI: make quirk using inw() depend on HAS_IOPORT
  firmware: dmi-sysfs: handle HAS_IOPORT dependencies
  /dev/port: don't compile file operations without CONFIG_DEVPORT
  usb: handle HAS_IOPORT dependencies
  asm-generic/io.h: drop inb() etc for HAS_IOPORT=n

 arch/alpha/Kconfig                           |   1 +
 arch/arc/Kconfig                             |   1 +
 arch/arm/Kconfig                             |   1 +
 arch/arm64/Kconfig                           |   1 +
 arch/ia64/Kconfig                            |   1 +
 arch/m68k/Kconfig                            |   1 +
 arch/microblaze/Kconfig                      |   1 +
 arch/mips/Kconfig                            |   1 +
 arch/parisc/Kconfig                          |   1 +
 arch/powerpc/Kconfig                         |   1 +
 arch/riscv/Kconfig                           |   1 +
 arch/sh/Kconfig                              |   1 +
 arch/sparc/Kconfig                           |   1 +
 arch/x86/Kconfig                             |   1 +
 drivers/accessibility/speakup/Kconfig        |   1 +
 drivers/acpi/Kconfig                         |   1 +
 drivers/ata/Kconfig                          |  34 ++---
 drivers/ata/ata_generic.c                    |   3 +-
 drivers/ata/libata-sff.c                     |   2 +
 drivers/bus/Kconfig                          |   2 +-
 drivers/char/Kconfig                         |   3 +-
 drivers/char/ipmi/Makefile                   |  11 +-
 drivers/char/ipmi/ipmi_si_intf.c             |   3 +-
 drivers/char/ipmi/ipmi_si_pci.c              |   3 +
 drivers/char/mem.c                           |   6 +-
 drivers/char/tpm/Kconfig                     |   1 +
 drivers/char/tpm/tpm_infineon.c              |  14 +-
 drivers/char/tpm/tpm_tis_core.c              |  19 ++-
 drivers/comedi/Kconfig                       |  53 ++++++++
 drivers/firmware/dmi-sysfs.c                 |   4 +
 drivers/gpio/Kconfig                         |   2 +-
 drivers/gpu/drm/qxl/Kconfig                  |   1 +
 drivers/gpu/drm/tiny/Kconfig                 |   1 +
 drivers/gpu/drm/tiny/cirrus.c                |   2 +
 drivers/hwmon/Kconfig                        |  21 ++-
 drivers/i2c/busses/Kconfig                   |  29 +++--
 drivers/iio/adc/Kconfig                      |   2 +-
 drivers/input/gameport/Kconfig               |   6 +-
 drivers/input/serio/Kconfig                  |   2 +
 drivers/input/touchscreen/Kconfig            |   1 +
 drivers/isdn/hardware/mISDN/Kconfig          |  14 +-
 drivers/leds/Kconfig                         |   2 +-
 drivers/media/cec/platform/Kconfig           |   2 +-
 drivers/media/pci/dm1105/Kconfig             |   2 +-
 drivers/media/radio/Kconfig                  |  15 ++-
 drivers/media/rc/Kconfig                     |   6 +
 drivers/message/fusion/Kconfig               |   8 +-
 drivers/misc/altera-stapl/Makefile           |   3 +-
 drivers/misc/altera-stapl/altera.c           |   6 +-
 drivers/net/Kconfig                          |   2 +-
 drivers/net/arcnet/Kconfig                   |   2 +-
 drivers/net/can/cc770/Kconfig                |   1 +
 drivers/net/can/sja1000/Kconfig              |   1 +
 drivers/net/ethernet/8390/Kconfig            |   2 +-
 drivers/net/ethernet/amd/Kconfig             |   2 +-
 drivers/net/ethernet/intel/Kconfig           |   4 +-
 drivers/net/ethernet/sis/Kconfig             |   6 +-
 drivers/net/ethernet/ti/Kconfig              |   4 +-
 drivers/net/ethernet/via/Kconfig             |   5 +-
 drivers/net/fddi/Kconfig                     |   4 +-
 drivers/net/hamradio/Kconfig                 |   6 +-
 drivers/net/wan/Kconfig                      |   2 +-
 drivers/net/wireless/atmel/Kconfig           |   4 +-
 drivers/net/wireless/intersil/hostap/Kconfig |   4 +-
 drivers/parport/Kconfig                      |   2 +-
 drivers/pci/Kconfig                          |  11 ++
 drivers/pci/pci-sysfs.c                      |  16 +++
 drivers/pci/quirks.c                         |   2 +
 drivers/pcmcia/Kconfig                       |   2 +-
 drivers/platform/chrome/Kconfig              |   1 +
 drivers/platform/chrome/wilco_ec/Kconfig     |   1 +
 drivers/pnp/isapnp/Kconfig                   |   2 +-
 drivers/power/reset/Kconfig                  |   1 +
 drivers/rtc/Kconfig                          |   4 +-
 drivers/scsi/Kconfig                         |  21 +--
 drivers/scsi/aic7xxx/Kconfig.aic79xx         |   2 +-
 drivers/scsi/aic7xxx/Kconfig.aic7xxx         |   2 +-
 drivers/scsi/aic94xx/Kconfig                 |   2 +-
 drivers/scsi/megaraid/Kconfig.megaraid       |   2 +-
 drivers/scsi/mvsas/Kconfig                   |   2 +-
 drivers/scsi/qla2xxx/Kconfig                 |   2 +-
 drivers/spi/Kconfig                          |   1 +
 drivers/staging/sm750fb/Kconfig              |   2 +-
 drivers/staging/vt6655/Kconfig               |   2 +-
 drivers/tty/Kconfig                          |   2 +-
 drivers/tty/serial/Kconfig                   |   2 +-
 drivers/usb/core/hcd-pci.c                   |   3 +-
 drivers/usb/host/Kconfig                     |   4 +-
 drivers/usb/host/pci-quirks.c                | 127 ++++++++++---------
 drivers/usb/host/pci-quirks.h                |  33 +++--
 drivers/usb/host/uhci-hcd.c                  |   2 +-
 drivers/usb/host/uhci-hcd.h                  |  77 +++++++----
 drivers/video/fbdev/Kconfig                  |  23 ++--
 drivers/watchdog/Kconfig                     |   6 +-
 include/asm-generic/io.h                     |   5 +
 include/linux/gameport.h                     |   9 +-
 include/linux/parport.h                      |   2 +-
 include/video/vga.h                          |   8 ++
 lib/Kconfig                                  |   4 +
 lib/Kconfig.kgdb                             |   1 +
 sound/drivers/Kconfig                        |   3 +
 sound/pci/Kconfig                            |  43 +++++--
 102 files changed, 532 insertions(+), 250 deletions(-)

Comments

John Garry Jan. 6, 2022, 5:45 p.m. UTC | #1
Hi Niklas,

On 27/12/2021 16:42, Niklas Schnelle wrote:
> I performed the following testing:
> 
> - On s390 this series on top of v5.16-rc7 builds with allyesconfig i.e. the
>    HAS_IOPORT=n case.

Are you sure that allyesconfig gives HAS_IOPORT=n? Indeed I see no 
mechanism is always disallow HAS_IOPORT for s390 (which I think we would 
want).

> It also builds with defconfig and the resulting kernel
>    appears fully functional including tests with PCI devices.

Thanks,
Johnw
Niklas Schnelle Jan. 7, 2022, 7:21 a.m. UTC | #2
On Thu, 2022-01-06 at 17:45 +0000, John Garry wrote:
> Hi Niklas,
> 
> On 27/12/2021 16:42, Niklas Schnelle wrote:
> > I performed the following testing:
> > 
> > - On s390 this series on top of v5.16-rc7 builds with allyesconfig i.e. the
> >    HAS_IOPORT=n case.
> 
> Are you sure that allyesconfig gives HAS_IOPORT=n? Indeed I see no 
> mechanism is always disallow HAS_IOPORT for s390 (which I think we would 
> want).
> 
> > It also builds with defconfig and the resulting kernel
> >    appears fully functional including tests with PCI devices.
> 
> Thanks,
> Johnw
> 

I checked again by adding

config HAS_IOPORT
       def_bool n

in arch/s390/Kconfig and that doesn't seem to make a difference,
allyesconfig builds all the same. Also checked for CONFIG_HAS_IOPORT in
my .config and that isn't listed with or without the above addition.

I think this is because without a help text there is no "config
question" and thus nothing that allyesconfig would set to yes. I do
agree though that it's better to be explicit and add the above to those
Kconfigs that don't support HAS_IOPORT.
Thanks,
Niklas
John Garry Jan. 7, 2022, 4:57 p.m. UTC | #3
On 07/01/2022 07:21, Niklas Schnelle wrote:
> I checked again by adding
> 
> config HAS_IOPORT
>         def_bool n
> 
> in arch/s390/Kconfig and that doesn't seem to make a difference,
> allyesconfig builds all the same. Also checked for CONFIG_HAS_IOPORT in
> my .config and that isn't listed with or without the above addition.

Strange, as I build your branch and I see it:

HEAD is now at 9f421b6580ed asm-generic/io.h: drop inb() etc for 
HAS_IOPORT=n
john@localhost:~/kernel-dev5> export ARCH=s390
john@localhost:~/kernel-dev5> export 
CROSS_COMPILE=/usr/bin/s390x-suse-linux-
john@localhost:~/kernel-dev5> make allyesconfig
#
# configuration written to .config
#
john@localhost:~/kernel-dev5> more .config | grep HAS_IOPORT
CONFIG_HAS_IOPORT=y

> 
> I think this is because without a help text there is no "config
> question" and thus nothing that allyesconfig would set to yes. I do
> agree though that it's better to be explicit and add the above to those
> Kconfigs that don't support HAS_IOPORT.

So maybe something like:
config HAS_IOPORT
	def_bool ISA || LEGACY_PCI
	depends on !S390

Otherwise you can build inb et al from asm-generic/io.h and get the 
original compile error about arithmetic on NULL pointer, right?

But I assume that there is a more elegant way of doing this...

Thanks,
John