ARM: OMAP: Fix SRAM W+X mapping

We are still using custom SRAM code for some SoCs and are not marking
the PM code mapped to SRAM as read-only and executable after we're
done. With CONFIG_DEBUG_WX=y, we will get "Found insecure W+X mapping
at address" warning.

Let's fix this issue the same way as commit 728bbe75c8 ("misc: sram:
Introduce support code for protect-exec sram type") is doing for
drivers/misc/sram-exec.c.

On omap3, we need to restore SRAM when returning from off mode after
idle, so init time configuration is not enough.

And as we no longer have users for omap_sram_push_address() we can
make it static while at it.

Note that eventually we should be using sram-exec.c for all SoCs.

Cc: stable@vger.kernel.org	# v4.12+
Cc: Dave Gerlach <d-gerlach@ti.com>
Reported-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Tony Lindgren <tony@atomide.com>
This commit is contained in:
Tony Lindgren 2018-03-21 08:16:29 -07:00
parent ba68878361
commit eb85a355c3
2 changed files with 36 additions and 11 deletions

View File

@ -5,13 +5,4 @@ void omap_map_sram(unsigned long start, unsigned long size,
unsigned long skip, int cached);
void omap_sram_reset(void);
extern void *omap_sram_push_address(unsigned long size);
/* Macro to push a function to the internal SRAM, using the fncpy API */
#define omap_sram_push(funcp, size) ({ \
typeof(&(funcp)) _res = NULL; \
void *_sram_address = omap_sram_push_address(size); \
if (_sram_address) \
_res = fncpy(_sram_address, &(funcp), size); \
_res; \
})
extern void *omap_sram_push(void *funcp, unsigned long size);

View File

@ -23,6 +23,7 @@
#include <asm/fncpy.h>
#include <asm/tlb.h>
#include <asm/cacheflush.h>
#include <asm/set_memory.h>
#include <asm/mach/map.h>
@ -42,7 +43,7 @@ static void __iomem *omap_sram_ceil;
* Note that fncpy requires the returned address to be aligned
* to an 8-byte boundary.
*/
void *omap_sram_push_address(unsigned long size)
static void *omap_sram_push_address(unsigned long size)
{
unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
@ -60,6 +61,30 @@ void *omap_sram_push_address(unsigned long size)
return (void *)omap_sram_ceil;
}
void *omap_sram_push(void *funcp, unsigned long size)
{
void *sram;
unsigned long base;
int pages;
void *dst = NULL;
sram = omap_sram_push_address(size);
if (!sram)
return NULL;
base = (unsigned long)sram & PAGE_MASK;
pages = PAGE_ALIGN(size) / PAGE_SIZE;
set_memory_rw(base, pages);
dst = fncpy(sram, funcp, size);
set_memory_ro(base, pages);
set_memory_x(base, pages);
return dst;
}
/*
* The SRAM context is lost during off-idle and stack
* needs to be reset.
@ -75,6 +100,9 @@ void omap_sram_reset(void)
void __init omap_map_sram(unsigned long start, unsigned long size,
unsigned long skip, int cached)
{
unsigned long base;
int pages;
if (size == 0)
return;
@ -95,4 +123,10 @@ void __init omap_map_sram(unsigned long start, unsigned long size,
*/
memset_io(omap_sram_base + omap_sram_skip, 0,
omap_sram_size - omap_sram_skip);
base = (unsigned long)omap_sram_base;
pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
set_memory_ro(base, pages);
set_memory_x(base, pages);
}