Commit a2d063ac216c1618bfc2b4d40b7176adffa63511

Authored by Steven Rostedt
Committed by Ingo Molnar
1 parent c16dbd54a3

extable, core_kernel_data(): Make sure all archs define _sdata

A new utility function (core_kernel_data()) is used to determine if a
passed in address is part of core kernel data or not. It may or may not
return true for RO data, but this utility must work for RW data.

Thus both _sdata and _edata must be defined and continuous,
without .init sections that may later be freed and replaced by
volatile memory (memory that can be freed).

This utility function is used to determine if data is safe from
ever being freed. Thus it should return true for all RW global
data that is not in a module or has been allocated, or false
otherwise.

Also change core_kernel_data() back to the more precise _sdata condition
and document the function.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Hirokazu Takata <takata@linux-m32r.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Helge Deller <deller@gmx.de>
Cc: JamesE.J.Bottomley <jejb@parisc-linux.org>
Link: http://lkml.kernel.org/r/1305855298.1465.19.camel@gandalf.stny.rr.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
----
 arch/alpha/kernel/vmlinux.lds.S   |    1 +
 arch/m32r/kernel/vmlinux.lds.S    |    1 +
 arch/m68k/kernel/vmlinux-std.lds  |    2 ++
 arch/m68k/kernel/vmlinux-sun3.lds |    1 +
 arch/mips/kernel/vmlinux.lds.S    |    1 +
 arch/parisc/kernel/vmlinux.lds.S  |    3 +++
 kernel/extable.c                  |   12 +++++++++++-
 7 files changed, 20 insertions(+), 1 deletion(-)

Showing 7 changed files with 20 additions and 1 deletions Side-by-side Diff

arch/alpha/kernel/vmlinux.lds.S
... ... @@ -46,6 +46,7 @@
46 46 __init_end = .;
47 47 /* Freed after init ends here */
48 48  
  49 + _sdata = .; /* Start of rw data section */
49 50 _data = .;
50 51 RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
51 52  
arch/m32r/kernel/vmlinux.lds.S
... ... @@ -44,6 +44,7 @@
44 44 EXCEPTION_TABLE(16)
45 45 NOTES
46 46  
  47 + _sdata = .; /* Start of data section */
47 48 RODATA
48 49 RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
49 50 _edata = .; /* End of data section */
arch/m68k/kernel/vmlinux-std.lds
... ... @@ -25,6 +25,8 @@
25 25  
26 26 EXCEPTION_TABLE(16)
27 27  
  28 + _sdata = .; /* Start of data section */
  29 +
28 30 RODATA
29 31  
30 32 RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
arch/m68k/kernel/vmlinux-sun3.lds
... ... @@ -25,6 +25,7 @@
25 25 _etext = .; /* End of text section */
26 26  
27 27 EXCEPTION_TABLE(16) :data
  28 + _sdata = .; /* Start of rw data section */
28 29 RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) :data
29 30 /* End of data goes *here* so that freeing init code works properly. */
30 31 _edata = .;
arch/mips/kernel/vmlinux.lds.S
... ... @@ -65,6 +65,7 @@
65 65 NOTES :text :note
66 66 .dummy : { *(.dummy) } :text
67 67  
  68 + _sdata = .; /* Start of data section */
68 69 RODATA
69 70  
70 71 /* writeable */
arch/parisc/kernel/vmlinux.lds.S
... ... @@ -69,6 +69,9 @@
69 69 /* End of text section */
70 70 _etext = .;
71 71  
  72 + /* Start of data section */
  73 + _sdata = .;
  74 +
72 75 RODATA
73 76  
74 77 /* writeable */
... ... @@ -72,9 +72,19 @@
72 72 return 0;
73 73 }
74 74  
  75 +/**
  76 + * core_kernel_data - tell if addr points to kernel data
  77 + * @addr: address to test
  78 + *
  79 + * Returns true if @addr passed in is from the core kernel data
  80 + * section.
  81 + *
  82 + * Note: On some archs it may return true for core RODATA, and false
  83 + * for others. But will always be true for core RW data.
  84 + */
75 85 int core_kernel_data(unsigned long addr)
76 86 {
77   - if (addr >= (unsigned long)_stext &&
  87 + if (addr >= (unsigned long)_sdata &&
78 88 addr < (unsigned long)_edata)
79 89 return 1;
80 90 return 0;