Michael Ellerman <m...@ellerman.id.au> writes: > Oliver O'Halloran <ooh...@gmail.com> writes: > >> When the kernel is compiled to use 64bit ABIv2 the _GLOBAL() macro does not >> include a global entry point. A function's global entry point is used when >> the >> function is called from a different TOC context and in the kernel this >> typically means a call from a module into the vmlinux (or vis-a-vis). >> >> There are a few exported ASM functions declared with _GLOBAL() and calling >> them from a module will module will likely crash the kernel since any TOC >> relative load will yield garbage. >> >> To fix this use _GLOBAL_TOC() for exported asm functions rather than >> _GLOBAL() >> and some documentation about when to use each. > > I wonder if we should just change _GLOBAL() to include the global entry > point. Persisting with _GLOBAL_TOC() seems like it's just going to be a > game of whack-a-mole.
Turns out that doesn't work well at all. We have *a lot* of places that use _GLOBAL() to make a symbol global, but which aren't functions entry points, eg: .align 7 _GLOBAL(ret_from_except) ld r11,_TRAP(r1) andi. r0,r11,1 bne ret_from_except_lite REST_NVGPRS(r1) _GLOBAL(ret_from_except_lite) ... Because ret_from_except wants to fallthrough there, we can't have _GLOBAL() insert instructions at ret_from_except_lite. So for now we'll merge a version of this fix. In the medium term we should change all our asm functions to use FUNC_START(), so it's clear they are functions, and then FUNC_START() should add the global entry point. We can then have a hard rule that anything EXPORT_SYMBOL'ed should use FUNC_START(). cheers