Skip to content

Commit

Permalink
m68k/atari: ARAnyM - Fix NatFeat module support
Browse files Browse the repository at this point in the history
commit e8184e1 upstream.

As pointed out by Andreas Schwab, pointers passed to ARAnyM NatFeat calls
should be physical addresses, not virtual addresses.

Fortunately on Atari, physical and virtual kernel addresses are the same,
as long as normal kernel memory is concerned, so this usually worked fine
without conversion.

But for modules, pointers to literal strings are located in vmalloc()ed
memory. Depending on the version of ARAnyM, this causes the nf_get_id()
call to just fail, or worse, crash ARAnyM itself with e.g.

    Gotcha! Illegal memory access. Atari PC = $968c

This is a big issue for distro kernels, who want to have all drivers as
loadable modules in an initrd.

Add a wrapper for nf_get_id() that copies the literal to the stack to
work around this issue.

Reported-by: Thorsten Glaser <tg@debian.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Geert Uytterhoeven authored and Greg Kroah-Hartman committed Aug 20, 2013
1 parent aa1f7bc commit dadf2af
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions arch/m68k/emu/natfeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
#include <asm/machdep.h>
#include <asm/natfeat.h>

extern long nf_get_id2(const char *feature_name);

asm("\n"
" .global nf_get_id,nf_call\n"
"nf_get_id:\n"
" .global nf_get_id2,nf_call\n"
"nf_get_id2:\n"
" .short 0x7300\n"
" rts\n"
"nf_call:\n"
Expand All @@ -29,12 +31,25 @@ asm("\n"
"1: moveq.l #0,%d0\n"
" rts\n"
" .section __ex_table,\"a\"\n"
" .long nf_get_id,1b\n"
" .long nf_get_id2,1b\n"
" .long nf_call,1b\n"
" .previous");
EXPORT_SYMBOL_GPL(nf_get_id);
EXPORT_SYMBOL_GPL(nf_call);

long nf_get_id(const char *feature_name)
{
/* feature_name may be in vmalloc()ed memory, so make a copy */
char name_copy[32];
size_t n;

n = strlcpy(name_copy, feature_name, sizeof(name_copy));
if (n >= sizeof(name_copy))
return 0;

return nf_get_id2(name_copy);
}
EXPORT_SYMBOL_GPL(nf_get_id);

void nfprint(const char *fmt, ...)
{
static char buf[256];
Expand Down

0 comments on commit dadf2af

Please sign in to comment.