From: Niklas Schnelle <schnelle@linux.ibm.com> To: Arnd Bergmann <arnd@arndb.de>, Vineet Gupta <vgupta@synopsys.com>, "David S. Miller" <davem@davemloft.net> Cc: Nathan Chancellor <nathan@kernel.org>, Nick Desaulniers <ndesaulniers@google.com>, clang-built-linux@googlegroups.com, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, linux-snps-arc@lists.infradead.org, sparclinux@vger.kernel.org Subject: [PATCH v6 3/3] asm-generic/io.h: warn in inb() and friends with undefined PCI_IOBASE Date: Mon, 10 May 2021 16:52:34 +0200 [thread overview] Message-ID: <20210510145234.594814-4-schnelle@linux.ibm.com> (raw) In-Reply-To: <20210510145234.594814-1-schnelle@linux.ibm.com> When PCI_IOBASE is not defined, it is set to 0 such that it is ignored in calls to the readX/writeX primitives. This triggers clang's -Wnull-pointer-arithmetic warning and will result in illegal accesses on platforms that do not support I/O ports. Make things explicit and silence the warning by letting inb() and friends fail with WARN_ONCE() and a 0xff... return in case PCI_IOBASE is not defined. Link: https://lore.kernel.org/lkml/20210421111759.2059976-1-schnelle@linux.ibm.com/ Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> --- v5 -> v6: - Added memset to insb()/insw()/insl() in WARN_ONCE() case to prevent access to uninitalized memory v4 -> v5: - Added Link to commit message (Arnd) v3 -> v4: - Changed the subject to better reflect the actual change - Added asm/bug.h so WARN_ONCE() is always available v2 -> v3: - Added ifdefs to ioport_map() and __pci_ioport_map() since apparently at least test configs enable CONFIG_HAS_IOPORT_MAP even on architectures which leave PCI_IOBASE unset (kernel test robot for nds32 and ARC). v1 -> v2: - Instead of working around the warning with a uintptr_t PCI_IOBASE make inb() and friends explicitly WARN_ONCE() and return 0xff... (Arnd) include/asm-generic/io.h | 68 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index e93375c710b9..4a3af97a832d 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -8,6 +8,7 @@ #define __ASM_GENERIC_IO_H #include <asm/page.h> /* I/O is all done through memory accesses */ +#include <linux/bug.h> #include <linux/string.h> /* for memset() and memcpy() */ #include <linux/types.h> @@ -440,10 +441,6 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer, #endif #endif /* CONFIG_64BIT */ -#ifndef PCI_IOBASE -#define PCI_IOBASE ((void __iomem *)0) -#endif - #ifndef IO_SPACE_LIMIT #define IO_SPACE_LIMIT 0xffff #endif @@ -458,12 +455,17 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer, #define _inb _inb static inline u8 _inb(unsigned long addr) { +#ifdef PCI_IOBASE u8 val; __io_pbr(); val = __raw_readb(PCI_IOBASE + addr); __io_par(val); return val; +#else + WARN_ONCE(1, "No I/O port support\n"); + return ~0; +#endif } #endif @@ -471,12 +473,17 @@ static inline u8 _inb(unsigned long addr) #define _inw _inw static inline u16 _inw(unsigned long addr) { +#ifdef PCI_IOBASE u16 val; __io_pbr(); val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); __io_par(val); return val; +#else + WARN_ONCE(1, "No I/O port support\n"); + return ~0; +#endif } #endif @@ -484,12 +491,17 @@ static inline u16 _inw(unsigned long addr) #define _inl _inl static inline u32 _inl(unsigned long addr) { +#ifdef PCI_IOBASE u32 val; __io_pbr(); val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); __io_par(val); return val; +#else + WARN_ONCE(1, "No I/O port support\n"); + return ~0; +#endif } #endif @@ -497,9 +509,13 @@ static inline u32 _inl(unsigned long addr) #define _outb _outb static inline void _outb(u8 value, unsigned long addr) { +#ifdef PCI_IOBASE __io_pbw(); __raw_writeb(value, PCI_IOBASE + addr); __io_paw(); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -507,9 +523,13 @@ static inline void _outb(u8 value, unsigned long addr) #define _outw _outw static inline void _outw(u16 value, unsigned long addr) { +#ifdef PCI_IOBASE __io_pbw(); __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); __io_paw(); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -517,9 +537,13 @@ static inline void _outw(u16 value, unsigned long addr) #define _outl _outl static inline void _outl(u32 value, unsigned long addr) { +#ifdef PCI_IOBASE __io_pbw(); __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); __io_paw(); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -606,7 +630,12 @@ static inline void outl_p(u32 value, unsigned long addr) #define insb insb static inline void insb(unsigned long addr, void *buffer, unsigned int count) { +#ifdef PCI_IOBASE readsb(PCI_IOBASE + addr, buffer, count); +#else + memset(buffer, 0xff, count); + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -614,7 +643,12 @@ static inline void insb(unsigned long addr, void *buffer, unsigned int count) #define insw insw static inline void insw(unsigned long addr, void *buffer, unsigned int count) { +#ifdef PCI_IOBASE readsw(PCI_IOBASE + addr, buffer, count); +#else + memset(buffer, 0xff, count); + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -622,7 +656,12 @@ static inline void insw(unsigned long addr, void *buffer, unsigned int count) #define insl insl static inline void insl(unsigned long addr, void *buffer, unsigned int count) { +#ifdef PCI_IOBASE readsl(PCI_IOBASE + addr, buffer, count); +#else + memset(buffer, 0xff, count); + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -631,7 +670,11 @@ static inline void insl(unsigned long addr, void *buffer, unsigned int count) static inline void outsb(unsigned long addr, const void *buffer, unsigned int count) { +#ifdef PCI_IOBASE writesb(PCI_IOBASE + addr, buffer, count); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -640,7 +683,11 @@ static inline void outsb(unsigned long addr, const void *buffer, static inline void outsw(unsigned long addr, const void *buffer, unsigned int count) { +#ifdef PCI_IOBASE writesw(PCI_IOBASE + addr, buffer, count); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -649,7 +696,11 @@ static inline void outsw(unsigned long addr, const void *buffer, static inline void outsl(unsigned long addr, const void *buffer, unsigned int count) { +#ifdef PCI_IOBASE writesl(PCI_IOBASE + addr, buffer, count); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -1020,18 +1071,27 @@ static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size) #define ioport_map ioport_map static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) { +#ifdef PCI_IOBASE port &= IO_SPACE_LIMIT; return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port; +#else + WARN_ONCE(1, "No I/O port support\n"); + return NULL; +#endif } #define __pci_ioport_unmap __pci_ioport_unmap static inline void __pci_ioport_unmap(void __iomem *p) { +#ifdef PCI_IOBASE uintptr_t start = (uintptr_t) PCI_IOBASE; uintptr_t addr = (uintptr_t) p; if (addr >= start && addr < start + IO_SPACE_LIMIT) return; iounmap(p); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Niklas Schnelle <schnelle@linux.ibm.com> To: Arnd Bergmann <arnd@arndb.de>, Vineet Gupta <vgupta@synopsys.com>, "David S. Miller" <davem@davemloft.net> Cc: Nathan Chancellor <nathan@kernel.org>, Nick Desaulniers <ndesaulniers@google.com>, clang-built-linux@googlegroups.com, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, linux-snps-arc@lists.infradead.org, sparclinux@vger.kernel.org Subject: [PATCH v6 3/3] asm-generic/io.h: warn in inb() and friends with undefined PCI_IOBASE Date: Mon, 10 May 2021 16:52:34 +0200 [thread overview] Message-ID: <20210510145234.594814-4-schnelle@linux.ibm.com> (raw) In-Reply-To: <20210510145234.594814-1-schnelle@linux.ibm.com> When PCI_IOBASE is not defined, it is set to 0 such that it is ignored in calls to the readX/writeX primitives. This triggers clang's -Wnull-pointer-arithmetic warning and will result in illegal accesses on platforms that do not support I/O ports. Make things explicit and silence the warning by letting inb() and friends fail with WARN_ONCE() and a 0xff... return in case PCI_IOBASE is not defined. Link: https://lore.kernel.org/lkml/20210421111759.2059976-1-schnelle@linux.ibm.com/ Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> --- v5 -> v6: - Added memset to insb()/insw()/insl() in WARN_ONCE() case to prevent access to uninitalized memory v4 -> v5: - Added Link to commit message (Arnd) v3 -> v4: - Changed the subject to better reflect the actual change - Added asm/bug.h so WARN_ONCE() is always available v2 -> v3: - Added ifdefs to ioport_map() and __pci_ioport_map() since apparently at least test configs enable CONFIG_HAS_IOPORT_MAP even on architectures which leave PCI_IOBASE unset (kernel test robot for nds32 and ARC). v1 -> v2: - Instead of working around the warning with a uintptr_t PCI_IOBASE make inb() and friends explicitly WARN_ONCE() and return 0xff... (Arnd) include/asm-generic/io.h | 68 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index e93375c710b9..4a3af97a832d 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -8,6 +8,7 @@ #define __ASM_GENERIC_IO_H #include <asm/page.h> /* I/O is all done through memory accesses */ +#include <linux/bug.h> #include <linux/string.h> /* for memset() and memcpy() */ #include <linux/types.h> @@ -440,10 +441,6 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer, #endif #endif /* CONFIG_64BIT */ -#ifndef PCI_IOBASE -#define PCI_IOBASE ((void __iomem *)0) -#endif - #ifndef IO_SPACE_LIMIT #define IO_SPACE_LIMIT 0xffff #endif @@ -458,12 +455,17 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer, #define _inb _inb static inline u8 _inb(unsigned long addr) { +#ifdef PCI_IOBASE u8 val; __io_pbr(); val = __raw_readb(PCI_IOBASE + addr); __io_par(val); return val; +#else + WARN_ONCE(1, "No I/O port support\n"); + return ~0; +#endif } #endif @@ -471,12 +473,17 @@ static inline u8 _inb(unsigned long addr) #define _inw _inw static inline u16 _inw(unsigned long addr) { +#ifdef PCI_IOBASE u16 val; __io_pbr(); val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); __io_par(val); return val; +#else + WARN_ONCE(1, "No I/O port support\n"); + return ~0; +#endif } #endif @@ -484,12 +491,17 @@ static inline u16 _inw(unsigned long addr) #define _inl _inl static inline u32 _inl(unsigned long addr) { +#ifdef PCI_IOBASE u32 val; __io_pbr(); val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); __io_par(val); return val; +#else + WARN_ONCE(1, "No I/O port support\n"); + return ~0; +#endif } #endif @@ -497,9 +509,13 @@ static inline u32 _inl(unsigned long addr) #define _outb _outb static inline void _outb(u8 value, unsigned long addr) { +#ifdef PCI_IOBASE __io_pbw(); __raw_writeb(value, PCI_IOBASE + addr); __io_paw(); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -507,9 +523,13 @@ static inline void _outb(u8 value, unsigned long addr) #define _outw _outw static inline void _outw(u16 value, unsigned long addr) { +#ifdef PCI_IOBASE __io_pbw(); __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); __io_paw(); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -517,9 +537,13 @@ static inline void _outw(u16 value, unsigned long addr) #define _outl _outl static inline void _outl(u32 value, unsigned long addr) { +#ifdef PCI_IOBASE __io_pbw(); __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); __io_paw(); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -606,7 +630,12 @@ static inline void outl_p(u32 value, unsigned long addr) #define insb insb static inline void insb(unsigned long addr, void *buffer, unsigned int count) { +#ifdef PCI_IOBASE readsb(PCI_IOBASE + addr, buffer, count); +#else + memset(buffer, 0xff, count); + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -614,7 +643,12 @@ static inline void insb(unsigned long addr, void *buffer, unsigned int count) #define insw insw static inline void insw(unsigned long addr, void *buffer, unsigned int count) { +#ifdef PCI_IOBASE readsw(PCI_IOBASE + addr, buffer, count); +#else + memset(buffer, 0xff, count); + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -622,7 +656,12 @@ static inline void insw(unsigned long addr, void *buffer, unsigned int count) #define insl insl static inline void insl(unsigned long addr, void *buffer, unsigned int count) { +#ifdef PCI_IOBASE readsl(PCI_IOBASE + addr, buffer, count); +#else + memset(buffer, 0xff, count); + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -631,7 +670,11 @@ static inline void insl(unsigned long addr, void *buffer, unsigned int count) static inline void outsb(unsigned long addr, const void *buffer, unsigned int count) { +#ifdef PCI_IOBASE writesb(PCI_IOBASE + addr, buffer, count); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -640,7 +683,11 @@ static inline void outsb(unsigned long addr, const void *buffer, static inline void outsw(unsigned long addr, const void *buffer, unsigned int count) { +#ifdef PCI_IOBASE writesw(PCI_IOBASE + addr, buffer, count); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -649,7 +696,11 @@ static inline void outsw(unsigned long addr, const void *buffer, static inline void outsl(unsigned long addr, const void *buffer, unsigned int count) { +#ifdef PCI_IOBASE writesl(PCI_IOBASE + addr, buffer, count); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif @@ -1020,18 +1071,27 @@ static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size) #define ioport_map ioport_map static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) { +#ifdef PCI_IOBASE port &= IO_SPACE_LIMIT; return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port; +#else + WARN_ONCE(1, "No I/O port support\n"); + return NULL; +#endif } #define __pci_ioport_unmap __pci_ioport_unmap static inline void __pci_ioport_unmap(void __iomem *p) { +#ifdef PCI_IOBASE uintptr_t start = (uintptr_t) PCI_IOBASE; uintptr_t addr = (uintptr_t) p; if (addr >= start && addr < start + IO_SPACE_LIMIT) return; iounmap(p); +#else + WARN_ONCE(1, "No I/O port support\n"); +#endif } #endif -- 2.25.1 _______________________________________________ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
next prev parent reply other threads:[~2021-05-10 14:54 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-05-10 14:52 [PATCH v6 0/3] asm-generic/io.h: Silence -Wnull-pointer-arithmetic warning on PCI_IOBASE Niklas Schnelle 2021-05-10 14:52 ` Niklas Schnelle 2021-05-10 14:52 ` [PATCH v6 1/3] sparc: explicitly set PCI_IOBASE to 0 Niklas Schnelle 2021-05-10 14:52 ` Niklas Schnelle 2021-05-10 14:52 ` [PATCH v6 2/3] risc-v: Use generic io.h helpers for nommu Niklas Schnelle 2021-05-10 14:52 ` Niklas Schnelle 2021-05-10 14:52 ` Niklas Schnelle [this message] 2021-05-10 14:52 ` [PATCH v6 3/3] asm-generic/io.h: warn in inb() and friends with undefined PCI_IOBASE Niklas Schnelle
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210510145234.594814-4-schnelle@linux.ibm.com \ --to=schnelle@linux.ibm.com \ --cc=arnd@arndb.de \ --cc=clang-built-linux@googlegroups.com \ --cc=davem@davemloft.net \ --cc=linux-arch@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-s390@vger.kernel.org \ --cc=linux-snps-arc@lists.infradead.org \ --cc=nathan@kernel.org \ --cc=ndesaulniers@google.com \ --cc=sparclinux@vger.kernel.org \ --cc=vgupta@synopsys.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.