Re: `io{re,un}map()` build error in s390 under `!CONFIG_HAS_IOMEM`
"Arnd Bergmann" <[email protected]> Tue, 04 Aug 2026 12:36:55 +0200
| Newsgroups | org.kernel.vger.linux-arch,dev.linux.lists.driver-core,org.kernel.vger.linux-s390,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Aug 4, 2026, at 09:13, Heiko Carstens wrote: > On Mon, Aug 03, 2026 at 10:09:08PM +0200, Danilo Krummrich wrote: >> On Mon Aug 3, 2026 at 9:56 PM CEST, Arnd Bergmann wrote: >> > In theory you should be able to use rust code without PCI MMIO >> > support, but I can't see any practical downsides to making rust >> > 'depends on HAS_MMIO' to avoid having to add those #ifdef. >> >> I think the implications should be minor without making Rust depend on >> CONFIG_HAS_IOMEM. >> >> I just sent out a fix [1]; the only annoying part is [2], but we should change >> those doc-tests anyway. For the one in rust/kernel/io.rs we already did in >> driver-core-next. >> >> [1] https://lore.kernel.org/driver-core/[email protected]/ This looks like you still provide the rust version of ioremap(), turning what is supposed to be a link failure into a runtime error. > I'm wondering if it would make sense to make HAS_IOMEM always available > on s390, even though it doesn't make too much sense without PCI. > But at least it would make s390 again a bit less special. I see that with CONFIG_PCI=y, s390 already falls back to generic_ioremap_prot() and just maps any phys_addr_t into the page table as PAGE_KERNEL, regardless of whether this is an MMIO address or not. The simple change below would just extend that behavior to !PCI and make that consistent with CONFIG_PCI=y on machines without actual PCI hardware. Of course any code that might rely on this is now a bug that likely never gets caught at build time. This still relies on implementing the __raw_* helpers as nop to have the same behavior as the PCI=y version, as the generic version would just end up dereferencing the invalid pointers. Arnd diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 84404e6778d5..806782acf6f6 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -173,7 +173,7 @@ config S390 select GENERIC_ENTRY select GENERIC_GETTIMEOFDAY select GENERIC_SMP_IDLE_THREAD - select GENERIC_IOREMAP if PCI + select GENERIC_IOREMAP select GLOB select HAVE_ALIGNED_STRUCT_PAGE select HAVE_ARCH_AUDITSYSCALL @@ -756,9 +756,6 @@ config PCI_NR_FUNCTIONS endif # PCI -config HAS_IOMEM - def_bool PCI - config CHSC_SCH def_tristate m prompt "Support for CHSC subchannels" diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index faddb9aef3b8..fa5a9dd1c47f 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -22,30 +22,16 @@ void *xlate_dev_mem_ptr(phys_addr_t phys); #define kc_unxlate_dev_mem_ptr unxlate_dev_mem_ptr void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); -#define IO_SPACE_LIMIT 0 - -/* - * I/O memory mapping functions. - */ -#define ioremap_prot ioremap_prot -#define iounmap iounmap - #define _PAGE_IOREMAP pgprot_val(PAGE_KERNEL) #define ioremap_wc(addr, size) \ ioremap_prot((addr), (size), pgprot_writecombine(PAGE_KERNEL)) -static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - return NULL; -} - -static inline void ioport_unmap(void __iomem *p) -{ -} - #ifdef CONFIG_PCI +#define ioremap_prot ioremap_prot +#define iounmap iounmap + /* * s390 needs a private implementation of pci_iomap since ioremap with its * offset parameter isn't sufficient. That's because BAR spaces are not @@ -88,6 +74,49 @@ static inline void __iowrite64_copy(void __iomem *to, const void *from, } #define __iowrite64_copy __iowrite64_copy +#else +/* + * ioremap_prot() without PCI behaves like memremap(), + * MMIO accessors do nothing + */ +#define ioremap_prot generic_ioremap_prot +#define iounmap generic_iounmap +static inline u8 __raw_readb(const volatile void __iomem *addr) +{ + return 0xff; +} +#define __raw_readb __raw_readb +static inline u16 __raw_readw(const volatile void __iomem *addr) +{ + return 0xffff; +} +#define __raw_readw __raw_readw +static inline u32 __raw_readl(const volatile void __iomem *addr) +{ + return 0xffffffffu; +} +#define __raw_readl __raw_readl +static inline u64 __raw_readq(const volatile void __iomem *addr) +{ + return 0xffffffffffffffffull; +} +#define __raw_readq __raw_readq +static inline void __raw_writeb(u8 val, volatile void __iomem *addr) +{ +} +#define __raw_writeb __raw_writeb +static inline void __raw_writew(u16 val, volatile void __iomem *addr) +{ +} +#define __raw_writew __raw_writew +static inline void __raw_writel(u32 val, volatile void __iomem *addr) +{ +} +#define __raw_writel __raw_writel +static inline void __raw_writeq(u64 val, volatile void __iomem *addr) +{ +} +#define __raw_writeq __raw_writeq #endif /* CONFIG_PCI */ #include <asm-generic/io.h> diff --git a/init/Kconfig b/init/Kconfig index 5230d4879b1c..2a4e3ecbfddd 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -237,7 +237,6 @@ config INIT_ENV_ARG_LIMIT config COMPILE_TEST bool "Compile also drivers which will not load" - depends on HAS_IOMEM help Some drivers can be compiled on a different platform than they are intended to be run on. Despite they cannot be loaded there (or even