* [PATCH] MIPS: Add support for CONFIG_DEBUG_VIRTUAL
@ 2017-03-28 17:57 Florian Fainelli
2017-08-23 17:29 ` Florian Fainelli
0 siblings, 1 reply; 4+ messages in thread
From: Florian Fainelli @ 2017-03-28 17:57 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, david.daney, paul.burton, james.hogan, Florian Fainelli
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 | 40 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 arch/mips/mm/physaddr.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2afb41c52ba0..724457b5a7eb 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -70,6 +70,7 @@ config MIPS
select HAVE_EXIT_THREAD
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_ARCH_HARDENED_USERCOPY
+ select ARCH_HAS_DEBUG_VIRTUAL
menu "Machine selection"
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index ecabc00c1e66..016e12161c9d 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -116,11 +116,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 5f987598054f..bf8bd7d77fce 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -205,9 +205,16 @@ static inline unsigned long ___pa(unsigned long x)
* 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 b4cc8811a664..0a1d241c50fb 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -29,3 +29,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..6123a9b3b3c0
--- /dev/null
+++ b/arch/mips/mm/physaddr.c
@@ -0,0 +1,40 @@
+#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)
+{
+ if (x >= PAGE_OFFSET && x < (unsigned long)high_memory)
+ 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);
--
2.9.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] MIPS: Add support for CONFIG_DEBUG_VIRTUAL
2017-03-28 17:57 [PATCH] MIPS: Add support for CONFIG_DEBUG_VIRTUAL Florian Fainelli
@ 2017-08-23 17:29 ` Florian Fainelli
0 siblings, 0 replies; 4+ messages in thread
From: Florian Fainelli @ 2017-08-23 17:29 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: david.daney, paul.burton, james.hogan
On 03/28/2017 10:57 AM, Florian Fainelli wrote:
> 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.
Ping? This may not longer apply cleanly against arch/mips/Kconfig, but
the conflicts should be trivial to resolve.
Thanks.
>
> 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 | 40 ++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 64 insertions(+), 2 deletions(-)
> create mode 100644 arch/mips/mm/physaddr.c
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 2afb41c52ba0..724457b5a7eb 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -70,6 +70,7 @@ config MIPS
> select HAVE_EXIT_THREAD
> select HAVE_REGS_AND_STACK_ACCESS_API
> select HAVE_ARCH_HARDENED_USERCOPY
> + select ARCH_HAS_DEBUG_VIRTUAL
>
> menu "Machine selection"
>
> diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
> index ecabc00c1e66..016e12161c9d 100644
> --- a/arch/mips/include/asm/io.h
> +++ b/arch/mips/include/asm/io.h
> @@ -116,11 +116,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 5f987598054f..bf8bd7d77fce 100644
> --- a/arch/mips/include/asm/page.h
> +++ b/arch/mips/include/asm/page.h
> @@ -205,9 +205,16 @@ static inline unsigned long ___pa(unsigned long x)
> * 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 b4cc8811a664..0a1d241c50fb 100644
> --- a/arch/mips/mm/Makefile
> +++ b/arch/mips/mm/Makefile
> @@ -29,3 +29,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..6123a9b3b3c0
> --- /dev/null
> +++ b/arch/mips/mm/physaddr.c
> @@ -0,0 +1,40 @@
> +#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)
> +{
> + if (x >= PAGE_OFFSET && x < (unsigned long)high_memory)
> + 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);
>
--
Florian
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] MIPS: Add support for CONFIG_DEBUG_VIRTUAL
2021-03-19 19:24 Florian Fainelli
@ 2021-03-20 0:50 ` kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-03-20 0:50 UTC (permalink / raw)
To: Florian Fainelli, linux-mips
Cc: kbuild-all, Florian Fainelli, Thomas Bogendoerfer, Randy Dunlap,
Jiaxun Yang, Vlastimil Babka, Jinyang He, Kees Cook,
Geert Uytterhoeven, Anshuman Khandual
[-- Attachment #1: Type: text/plain, Size: 8578 bytes --]
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
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25452 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] MIPS: Add support for CONFIG_DEBUG_VIRTUAL
@ 2021-03-19 19:24 Florian Fainelli
2021-03-20 0:50 ` kernel test robot
0 siblings, 1 reply; 4+ messages in thread
From: Florian Fainelli @ 2021-03-19 19:24 UTC (permalink / raw)
To: linux-mips
Cc: Florian Fainelli, Thomas Bogendoerfer, Randy Dunlap, Jiaxun Yang,
Vlastimil Babka, Jinyang He, Kees Cook, Geert Uytterhoeven,
Anshuman Khandual, Liangliang Huang, open list
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
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);
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-03-20 0:52 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-28 17:57 [PATCH] MIPS: Add support for CONFIG_DEBUG_VIRTUAL Florian Fainelli
2017-08-23 17:29 ` Florian Fainelli
2021-03-19 19:24 Florian Fainelli
2021-03-20 0:50 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).