Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb85a355 authored by Tony Lindgren's avatar Tony Lindgren
Browse files

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 728bbe75 ("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: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent ba688783
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -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);
+35 −1
Original line number Diff line number Diff line
@@ -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);
}