diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-10-19 21:47:18 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-10-24 21:54:07 -0400 |
commit | 0909c8c2d547e45ca50e2492b08ec93a37b35237 (patch) | |
tree | 23e66e1dc9a5bd674ba1375b5fccd2cb0d5787a8 /include/asm-powerpc/cputable.h | |
parent | 7aeb732428fc8e2ecae6d432873770c12f04a979 (diff) |
[POWERPC] Support feature fixups in vdso's
This patch reworks the feature fixup mecanism so vdso's can be fixed up.
The main issue was that the construct:
.long label (or .llong on 64 bits)
will not work in the case of a shared library like the vdso. It will
generate an empty placeholder in the fixup table along with a reloc,
which is not something we can deal with in the vdso.
The idea here (thanks Alan Modra !) is to instead use something like:
1:
.long label - 1b
That is, the feature fixup tables no longer contain addresses of bits of
code to patch, but offsets of such code from the fixup table entry
itself. That is properly resolved by ld when building the .so's. I've
modified the fixup mecanism generically to use that method for the rest
of the kernel as well.
Another trick is that the 32 bits vDSO included in the 64 bits kernel
need to have a table in the 64 bits format. However, gas does not
support 32 bits code with a statement of the form:
.llong label - 1b (Or even just .llong label)
That is, it cannot emit the right fixup/relocation for the linker to use
to assign a 32 bits address to an .llong field. Thus, in the specific
case of the 32 bits vdso built as part of the 64 bits kernel, we are
using a modified macro that generates:
.long 0xffffffff
.llong label - 1b
Note that is assumes that the value is negative which is enforced by
the .lds (those offsets are always negative as the .text is always
before the fixup table and gas doesn't support emiting the reloc the
other way around).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc/cputable.h')
-rw-r--r-- | include/asm-powerpc/cputable.h | 31 |
1 files changed, 5 insertions, 26 deletions
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 65faf322ace0..02e52d68cbbe 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h | |||
@@ -92,8 +92,8 @@ extern struct cpu_spec *cur_cpu_spec; | |||
92 | extern unsigned int __start___ftr_fixup, __stop___ftr_fixup; | 92 | extern unsigned int __start___ftr_fixup, __stop___ftr_fixup; |
93 | 93 | ||
94 | extern struct cpu_spec *identify_cpu(unsigned long offset); | 94 | extern struct cpu_spec *identify_cpu(unsigned long offset); |
95 | extern void do_feature_fixups(unsigned long offset, unsigned long value, | 95 | extern void do_feature_fixups(unsigned long value, void *fixup_start, |
96 | void *fixup_start, void *fixup_end); | 96 | void *fixup_end); |
97 | 97 | ||
98 | #endif /* __ASSEMBLY__ */ | 98 | #endif /* __ASSEMBLY__ */ |
99 | 99 | ||
@@ -435,32 +435,11 @@ static inline int cpu_has_feature(unsigned long feature) | |||
435 | #ifdef __ASSEMBLY__ | 435 | #ifdef __ASSEMBLY__ |
436 | 436 | ||
437 | #define BEGIN_FTR_SECTION_NESTED(label) label: | 437 | #define BEGIN_FTR_SECTION_NESTED(label) label: |
438 | #define BEGIN_FTR_SECTION BEGIN_FTR_SECTION_NESTED(98) | 438 | #define BEGIN_FTR_SECTION BEGIN_FTR_SECTION_NESTED(97) |
439 | |||
440 | #ifndef __powerpc64__ | ||
441 | #define END_FTR_SECTION_NESTED(msk, val, label) \ | ||
442 | 99: \ | ||
443 | .section __ftr_fixup,"a"; \ | ||
444 | .align 2; \ | ||
445 | .long msk; \ | ||
446 | .long val; \ | ||
447 | .long label##b; \ | ||
448 | .long 99b; \ | ||
449 | .previous | ||
450 | #else /* __powerpc64__ */ | ||
451 | #define END_FTR_SECTION_NESTED(msk, val, label) \ | 439 | #define END_FTR_SECTION_NESTED(msk, val, label) \ |
452 | 99: \ | 440 | MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup) |
453 | .section __ftr_fixup,"a"; \ | ||
454 | .align 3; \ | ||
455 | .llong msk; \ | ||
456 | .llong val; \ | ||
457 | .llong label##b; \ | ||
458 | .llong 99b; \ | ||
459 | .previous | ||
460 | #endif /* __powerpc64__ */ | ||
461 | |||
462 | #define END_FTR_SECTION(msk, val) \ | 441 | #define END_FTR_SECTION(msk, val) \ |
463 | END_FTR_SECTION_NESTED(msk, val, 98) | 442 | END_FTR_SECTION_NESTED(msk, val, 97) |
464 | 443 | ||
465 | #define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) | 444 | #define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) |
466 | #define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) | 445 | #define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) |