Skip to content

Commit

Permalink
ARM: OMAP: Fix SRAM W+X mapping
Browse files Browse the repository at this point in the history
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 728bbe7 ("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: [email protected]	# v4.12+
Cc: Dave Gerlach <[email protected]>
Reported-by: Pavel Machek <[email protected]>
Signed-off-by: Tony Lindgren <[email protected]>
  • Loading branch information
tmlind committed Mar 21, 2018
1 parent ba68878 commit eb85a35
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
11 changes: 1 addition & 10 deletions arch/arm/plat-omap/include/plat/sram.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
36 changes: 35 additions & 1 deletion arch/arm/plat-omap/sram.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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;

Expand All @@ -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.
Expand All @@ -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;

Expand All @@ -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);
}

0 comments on commit eb85a35

Please sign in to comment.