diff mbox series

MIPS: Add support for CONFIG_DEBUG_VIRTUAL

Message ID 20210319192440.2019371-1-f.fainelli@gmail.com (mailing list archive)
State Superseded
Headers show
Series MIPS: Add support for CONFIG_DEBUG_VIRTUAL | expand

Commit Message

Florian Fainelli March 19, 2021, 7:24 p.m. UTC
Provide hooks to intercept bad usages of virt_to_phys() and
__pa_symbol() throughout the kernel. To make this possible, we need to
rename the current implement of virt_to_phys() into
__virt_to_phys_nodebug() and wrap it around depending on
CONFIG_DEBUG_VIRTUAL.

A similar thing is needed for __pa_symbol() which is now aliased to
__phys_addr_symbol() whose implementation is either the direct return of
RELOC_HIDE or goes through the debug version.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 arch/mips/Kconfig            |  1 +
 arch/mips/include/asm/io.h   | 14 ++++++++-
 arch/mips/include/asm/page.h |  9 +++++-
 arch/mips/mm/Makefile        |  2 ++
 arch/mips/mm/physaddr.c      | 55 ++++++++++++++++++++++++++++++++++++
 5 files changed, 79 insertions(+), 2 deletions(-)
 create mode 100644 arch/mips/mm/physaddr.c

Comments

kernel test robot March 20, 2021, 12:50 a.m. UTC | #1
Hi Florian,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.12-rc3 next-20210319]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Florian-Fainelli/MIPS-Add-support-for-CONFIG_DEBUG_VIRTUAL/20210320-032733
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 8b12a62a4e3ed4ae99c715034f557eb391d6b196
config: mips-randconfig-s032-20210318 (attached as .config)
compiler: mipsel-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-277-gc089cd2d-dirty
        # https://github.com/0day-ci/linux/commit/1c409697fd2f3f5639d1900cfd811d4d72a2314a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Florian-Fainelli/MIPS-Add-support-for-CONFIG_DEBUG_VIRTUAL/20210320-032733
        git checkout 1c409697fd2f3f5639d1900cfd811d4d72a2314a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
   command-line: note: in included file:
   builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_ACQUIRE redefined
   builtin:0:0: sparse: this was the original definition
   builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_SEQ_CST redefined
   builtin:0:0: sparse: this was the original definition
   builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_ACQ_REL redefined
   builtin:0:0: sparse: this was the original definition
   builtin:1:9: sparse: sparse: preprocessor token __ATOMIC_RELEASE redefined
   builtin:0:0: sparse: this was the original definition
>> arch/mips/kernel/vdso.c:161:54: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile *x @@     got void [noderef] __iomem * @@
   arch/mips/kernel/vdso.c:161:54: sparse:     expected void const volatile *x
   arch/mips/kernel/vdso.c:161:54: sparse:     got void [noderef] __iomem *

vim +161 arch/mips/kernel/vdso.c

ea7e0480a4b695 Paul Burton       2018-09-25   88  
c52d0d30aef84a David Daney       2010-02-18   89  int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
c52d0d30aef84a David Daney       2010-02-18   90  {
ebb5e78cc63417 Alex Smith        2015-10-21   91  	struct mips_vdso_image *image = current->thread.abi->vdso;
c52d0d30aef84a David Daney       2010-02-18   92  	struct mm_struct *mm = current->mm;
00578cd864d45a Paul Burton       2017-08-12   93  	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn;
ebb5e78cc63417 Alex Smith        2015-10-21   94  	struct vm_area_struct *vma;
ebb5e78cc63417 Alex Smith        2015-10-21   95  	int ret;
c52d0d30aef84a David Daney       2010-02-18   96  
d8ed45c5dcd455 Michel Lespinasse 2020-06-08   97  	if (mmap_write_lock_killable(mm))
69048176078add Michal Hocko      2016-05-23   98  		return -EINTR;
c52d0d30aef84a David Daney       2010-02-18   99  
aebdc6ff3b2e79 Yousong Zhou      2020-03-24  100  	if (IS_ENABLED(CONFIG_MIPS_FP_SUPPORT)) {
432c6bacbd0c16 Paul Burton       2016-07-08  101  		/* Map delay slot emulation page */
432c6bacbd0c16 Paul Burton       2016-07-08  102  		base = mmap_region(NULL, STACK_TOP, PAGE_SIZE,
adcc81f148d733 Paul Burton       2018-12-20  103  				VM_READ | VM_EXEC |
432c6bacbd0c16 Paul Burton       2016-07-08  104  				VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
897ab3e0c49e24 Mike Rapoport     2017-02-24  105  				0, NULL);
432c6bacbd0c16 Paul Burton       2016-07-08  106  		if (IS_ERR_VALUE(base)) {
432c6bacbd0c16 Paul Burton       2016-07-08  107  			ret = base;
432c6bacbd0c16 Paul Burton       2016-07-08  108  			goto out;
432c6bacbd0c16 Paul Burton       2016-07-08  109  		}
aebdc6ff3b2e79 Yousong Zhou      2020-03-24  110  	}
432c6bacbd0c16 Paul Burton       2016-07-08  111  
a7f4df4e21dd8a Alex Smith        2015-10-21  112  	/*
a7f4df4e21dd8a Alex Smith        2015-10-21  113  	 * Determine total area size. This includes the VDSO data itself, the
a7f4df4e21dd8a Alex Smith        2015-10-21  114  	 * data page, and the GIC user page if present. Always create a mapping
a7f4df4e21dd8a Alex Smith        2015-10-21  115  	 * for the GIC user area if the GIC is present regardless of whether it
a7f4df4e21dd8a Alex Smith        2015-10-21  116  	 * is the current clocksource, in case it comes into use later on. We
a7f4df4e21dd8a Alex Smith        2015-10-21  117  	 * only map a page even though the total area is 64K, as we only need
a7f4df4e21dd8a Alex Smith        2015-10-21  118  	 * the counter registers at the start.
a7f4df4e21dd8a Alex Smith        2015-10-21  119  	 */
00578cd864d45a Paul Burton       2017-08-12  120  	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
a7f4df4e21dd8a Alex Smith        2015-10-21  121  	vvar_size = gic_size + PAGE_SIZE;
a7f4df4e21dd8a Alex Smith        2015-10-21  122  	size = vvar_size + image->size;
a7f4df4e21dd8a Alex Smith        2015-10-21  123  
0f02cfbc3d9e41 Paul Burton       2018-08-30  124  	/*
0f02cfbc3d9e41 Paul Burton       2018-08-30  125  	 * Find a region that's large enough for us to perform the
0f02cfbc3d9e41 Paul Burton       2018-08-30  126  	 * colour-matching alignment below.
0f02cfbc3d9e41 Paul Burton       2018-08-30  127  	 */
0f02cfbc3d9e41 Paul Burton       2018-08-30  128  	if (cpu_has_dc_aliases)
0f02cfbc3d9e41 Paul Burton       2018-08-30  129  		size += shm_align_mask + 1;
0f02cfbc3d9e41 Paul Burton       2018-08-30  130  
ea7e0480a4b695 Paul Burton       2018-09-25  131  	base = get_unmapped_area(NULL, vdso_base(), size, 0, 0);
ebb5e78cc63417 Alex Smith        2015-10-21  132  	if (IS_ERR_VALUE(base)) {
ebb5e78cc63417 Alex Smith        2015-10-21  133  		ret = base;
ebb5e78cc63417 Alex Smith        2015-10-21  134  		goto out;
ebb5e78cc63417 Alex Smith        2015-10-21  135  	}
ebb5e78cc63417 Alex Smith        2015-10-21  136  
0f02cfbc3d9e41 Paul Burton       2018-08-30  137  	/*
0f02cfbc3d9e41 Paul Burton       2018-08-30  138  	 * If we suffer from dcache aliasing, ensure that the VDSO data page
0f02cfbc3d9e41 Paul Burton       2018-08-30  139  	 * mapping is coloured the same as the kernel's mapping of that memory.
0f02cfbc3d9e41 Paul Burton       2018-08-30  140  	 * This ensures that when the kernel updates the VDSO data userland
0f02cfbc3d9e41 Paul Burton       2018-08-30  141  	 * will observe it without requiring cache invalidations.
0f02cfbc3d9e41 Paul Burton       2018-08-30  142  	 */
0f02cfbc3d9e41 Paul Burton       2018-08-30  143  	if (cpu_has_dc_aliases) {
0f02cfbc3d9e41 Paul Burton       2018-08-30  144  		base = __ALIGN_MASK(base, shm_align_mask);
24640f233b4660 Vincenzo Frascino 2019-06-21  145  		base += ((unsigned long)vdso_data - gic_size) & shm_align_mask;
0f02cfbc3d9e41 Paul Burton       2018-08-30  146  	}
0f02cfbc3d9e41 Paul Burton       2018-08-30  147  
a7f4df4e21dd8a Alex Smith        2015-10-21  148  	data_addr = base + gic_size;
a7f4df4e21dd8a Alex Smith        2015-10-21  149  	vdso_addr = data_addr + PAGE_SIZE;
c52d0d30aef84a David Daney       2010-02-18  150  
a7f4df4e21dd8a Alex Smith        2015-10-21  151  	vma = _install_special_mapping(mm, base, vvar_size,
ebb5e78cc63417 Alex Smith        2015-10-21  152  				       VM_READ | VM_MAYREAD,
ebb5e78cc63417 Alex Smith        2015-10-21  153  				       &vdso_vvar_mapping);
ebb5e78cc63417 Alex Smith        2015-10-21  154  	if (IS_ERR(vma)) {
ebb5e78cc63417 Alex Smith        2015-10-21  155  		ret = PTR_ERR(vma);
ebb5e78cc63417 Alex Smith        2015-10-21  156  		goto out;
c52d0d30aef84a David Daney       2010-02-18  157  	}
c52d0d30aef84a David Daney       2010-02-18  158  
a7f4df4e21dd8a Alex Smith        2015-10-21  159  	/* Map GIC user page. */
a7f4df4e21dd8a Alex Smith        2015-10-21  160  	if (gic_size) {
00578cd864d45a Paul Burton       2017-08-12 @161  		gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT;

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d89efba3d8a4..0904d6351808 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -4,6 +4,7 @@  config MIPS
 	default y
 	select ARCH_32BIT_OFF_T if !64BIT
 	select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
+	select ARCH_HAS_DEBUG_VIRTUAL if !64BIT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI)
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 78537aa23500..2c138450ad3b 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -100,11 +100,23 @@  static inline void set_io_port_base(unsigned long base)
  *     almost all conceivable cases a device driver should not be using
  *     this function
  */
-static inline unsigned long virt_to_phys(volatile const void *address)
+static inline unsigned long __virt_to_phys_nodebug(volatile const void *address)
 {
 	return __pa(address);
 }
 
+#ifdef CONFIG_DEBUG_VIRTUAL
+extern phys_addr_t __virt_to_phys(volatile const void *x);
+#else
+#define __virt_to_phys(x)	__virt_to_phys_nodebug(x)
+#endif
+
+#define virt_to_phys virt_to_phys
+static inline phys_addr_t virt_to_phys(const volatile void *x)
+{
+	return __virt_to_phys(x);
+}
+
 /*
  *     phys_to_virt    -       map physical address to virtual
  *     @address: address to remap
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 65acab9c41f9..195ff4e9771f 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -210,9 +210,16 @@  static inline unsigned long ___pa(unsigned long x)
  * also affect MIPS so we keep this one until GCC 3.x has been retired
  * before we can apply https://patchwork.linux-mips.org/patch/1541/
  */
+#define __pa_symbol_nodebug(x)	__pa(RELOC_HIDE((unsigned long)(x), 0))
+
+#ifdef CONFIG_DEBUG_VIRTUAL
+extern phys_addr_t __phys_addr_symbol(unsigned long x);
+#else
+#define __phys_addr_symbol(x)	__pa_symbol_nodebug(x)
+#endif
 
 #ifndef __pa_symbol
-#define __pa_symbol(x)	__pa(RELOC_HIDE((unsigned long)(x), 0))
+#define __pa_symbol(x)		__phys_addr_symbol((unsigned long)(x))
 #endif
 
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 865926a37775..fa1f729e0700 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -40,3 +40,5 @@  obj-$(CONFIG_R5000_CPU_SCACHE)	+= sc-r5k.o
 obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
 obj-$(CONFIG_MIPS_CPU_SCACHE)	+= sc-mips.o
 obj-$(CONFIG_SCACHE_DEBUGFS)	+= sc-debugfs.o
+
+obj-$(CONFIG_DEBUG_VIRTUAL)	+= physaddr.o
diff --git a/arch/mips/mm/physaddr.c b/arch/mips/mm/physaddr.c
new file mode 100644
index 000000000000..008b524a96b2
--- /dev/null
+++ b/arch/mips/mm/physaddr.c
@@ -0,0 +1,55 @@ 
+#include <linux/bug.h>
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/mmdebug.h>
+#include <linux/mm.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+
+static inline bool __debug_virt_addr_valid(unsigned long x)
+{
+	/* high_memory does not get immediately defined, and there
+	 * are early callers of __pa() against PAGE_OFFSET
+	 */
+	if (!high_memory && x >= PAGE_OFFSET)
+		return true;
+
+	if (high_memory && x >= PAGE_OFFSET && x < (unsigned long)high_memory)
+		return true;
+
+	/*
+	 * MAX_DMA_ADDRESS is a virtual address that may not correspond to an
+	 * actual physical address. Enough code relies on
+	 * virt_to_phys(MAX_DMA_ADDRESS) that we just need to work around it
+	 * and always return true.
+	 */
+	if (x == MAX_DMA_ADDRESS)
+		return true;
+
+	return false;
+}
+
+phys_addr_t __virt_to_phys(volatile const void *x)
+{
+	WARN(!__debug_virt_addr_valid((unsigned long)x),
+	     "virt_to_phys used for non-linear address: %pK (%pS)\n",
+	     x, x);
+
+	return __virt_to_phys_nodebug(x);
+}
+EXPORT_SYMBOL(__virt_to_phys);
+
+phys_addr_t __phys_addr_symbol(unsigned long x)
+{
+	/* This is bounds checking against the kernel image only.
+	 * __pa_symbol should only be used on kernel symbol addresses.
+	 */
+	VIRTUAL_BUG_ON(x < (unsigned long)_text ||
+		       x > (unsigned long)_end);
+
+	return __pa_symbol_nodebug(x);
+}
+EXPORT_SYMBOL(__phys_addr_symbol);