This patchset drop the approach of creating new stub type for livepatch
symbols and offloads the issue of handling local function becoming global
to kpatch tool via gcc-plugin.
In function restore_r2(), a check for sibling call is added and also
improves the error message on unexpected op-code.
v4:
- Drop creation of stubs for livepatch symbols and offload solution
to kpatch tool.
- Introduce check for sibling call, when restoring r2 after branch. (Josh)
- Improve error message in restore_r2(). (Josh)
v3:
- Defined FUNC_DESC_OFFSET to calculate func_desc offset from
struct ppc64le_klp_stub_entry.
- Replaced BUG_ON() with WARN_ON() in klp_stub_for_addr().
- Major commit message re-write.
v2:
- Changed klp_stub construction to re-use livepatch_handler and
additional patch code required for klp_stub, instead of duplicating it.
- Minor comments and commit body edit.
Josh Poimboeuf (2):
powerpc/modules: Don't try to restore r2 after a sibling call
powerpc/modules: Improve restore_r2() error message
Kamalesh Babulal (1):
kernel/modules: Add REL24 relocation support of livepatch symbols
arch/powerpc/kernel/module_64.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--
2.9.3
Livepatch re-uses module loader function apply_relocate_add() to write
relocations, instead of managing them by arch-dependent
klp_write_module_reloc() function.
apply_relocate_add() doesn't understand livepatch symbols (marked with
SHN_LIVEPATCH symbol section index) and assumes them to be local symbols
by default for R_PPC64_REL24 relocation type. It fails with an error,
when trying to calculate offset with local_entry_offset():
module_64: kpatch_meminfo: REL24 -1152921504897399800 out of range!
Whereas livepatch symbols are essentially SHN_UNDEF, should be
called via stub used for global calls. This issue can be fixed by
teaching apply_relocate_add() to handle both SHN_UNDEF/SHN_LIVEPATCH
symbols via the same stub. This patch extends SHN_UNDEF code to handle
livepatch symbols too.
Signed-off-by: Kamalesh Babulal <redacted>
CC: Balbir Singh <bsingharora@gmail.com>
Cc: Naveen N. Rao <redacted>
Cc: Josh Poimboeuf <redacted>
Cc: Jessica Yu <jeyu@kernel.org>
Cc: Ananth N Mavinakayanahalli <redacted>
Cc: Aravinda Prasad <redacted>
Cc: Torsten Duwe <redacted>
---
arch/powerpc/kernel/module_64.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
@@ -613,7 +613,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,caseR_PPC_REL24:/* FIXME: Handle weak symbols here --RR */-if(sym->st_shndx==SHN_UNDEF){+if(sym->st_shndx==SHN_UNDEF||+sym->st_shndx==SHN_LIVEPATCH){/* External: go via stub */value=stub_for_addr(sechdrs,value,me);if(!value)
From: Josh Poimboeuf <redacted>
Print the function address associated with the restore_r2() error to
make it easier to debug the problem.
Also clarify the wording a bit.
Before:
module_64: patch_foo: Expect noop after relocate, got 3c820000
After:
module_64: patch_foo: Expected noop after call, got 7c630034 at netdev_has_upper_dev+0x54/0xb0 [patch_foo]
Signed-off-by: Josh Poimboeuf <redacted>
Signed-off-by: Kamalesh Babulal <redacted>
---
arch/powerpc/kernel/module_64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Josh Poimboeuf <redacted>
When attempting to load a livepatch module, I got the following error:
module_64: patch_module: Expect noop after relocate, got 3c820000
The error was triggered by the following code in
unregister_netdevice_queue():
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
Signed-off-by: Josh Poimboeuf <redacted>
Signed-off-by: Kamalesh Babulal <redacted>
---
arch/powerpc/kernel/module_64.c | 4 ++++
1 file changed, 4 insertions(+)
@@ -489,6 +489,10 @@ static int restore_r2(u32 *instruction, struct module *me)if(is_early_mcount_callsite(instruction-1))return1;+/* Sibling calls don't return, so they don't need to restore r2 */+if(instruction[-1]==PPC_INST_BRANCH)+return1;+if(*instruction!=PPC_INST_NOP){pr_err("%s: Expect noop after relocate, got %08x\n",me->name,*instruction);
From: Naveen N. Rao <hidden> Date: 2017-11-14 10:29:39
Kamalesh Babulal wrote:
quoted hunk
From: Josh Poimboeuf <redacted>
=20
When attempting to load a livepatch module, I got the following error:
=20
module_64: patch_module: Expect noop after relocate, got 3c820000
=20
The error was triggered by the following code in
unregister_netdevice_queue():
=20
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
=20
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
=20
Signed-off-by: Josh Poimboeuf <redacted>
Signed-off-by: Kamalesh Babulal <redacted>
---
arch/powerpc/kernel/module_64.c | 4 ++++
1 file changed, 4 insertions(+)
=20
@@ -489,6 +489,10 @@ static int restore_r2(u32 *instruction, struct modul=
e *me)
if (is_early_mcount_callsite(instruction - 1))
return 1;
=20
+ /* Sibling calls don't return, so they don't need to restore r2 */
+ if (instruction[-1] =3D=3D PPC_INST_BRANCH)
+ return 1;
+
This looks quite fragile, unless we know for sure that gcc will _always_
emit this instruction form for sibling calls with relocations.
As an alternative, does it make sense to do the following check instead?
if ((instr_is_branch_iform(insn) || instr_is_branch_bform(insn))
&& !(insn & 0x1))
- Naveen
=
On Tue, Nov 14, 2017 at 03:59:21PM +0530, Naveen N. Rao wrote:
Kamalesh Babulal wrote:
quoted
From: Josh Poimboeuf <redacted>
When attempting to load a livepatch module, I got the following error:
module_64: patch_module: Expect noop after relocate, got 3c820000
The error was triggered by the following code in
unregister_netdevice_queue():
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
Signed-off-by: Josh Poimboeuf <redacted>
Signed-off-by: Kamalesh Babulal <redacted>
---
arch/powerpc/kernel/module_64.c | 4 ++++
1 file changed, 4 insertions(+)
@@ -489,6 +489,10 @@ static int restore_r2(u32 *instruction, struct module *me)if(is_early_mcount_callsite(instruction-1))return1;+/* Sibling calls don't return, so they don't need to restore r2 */+if(instruction[-1]==PPC_INST_BRANCH)+return1;+
This looks quite fragile, unless we know for sure that gcc will _always_
emit this instruction form for sibling calls with relocations.
As an alternative, does it make sense to do the following check instead?
if ((instr_is_branch_iform(insn) || instr_is_branch_bform(insn))
&& !(insn & 0x1))
Yes, good point. How about something like this?
(completely untested because I don't have access to a box at the moment)
@@ -33,6 +33,7 @@ int patch_branch(unsigned int *addr, unsigned long target, int flags);intpatch_instruction(unsignedint*addr,unsignedintinstr);intinstr_is_relative_branch(unsignedintinstr);+intinstr_is_link_branch(unsignedintinstr);intinstr_is_branch_to_addr(constunsignedint*instr,unsignedlongaddr);unsignedlongbranch_target(constunsignedint*instr);unsignedinttranslate_branch(constunsignedint*dest,
@@ -487,11 +487,13 @@ static bool is_early_mcount_callsite(u32 *instruction)restorer2.*/staticintrestore_r2(u32*instruction,structmodule*me){-if(is_early_mcount_callsite(instruction-1))+u32*prev_insn=instruction-1;++if(is_early_mcount_callsite(prev_insn))return1;/* Sibling calls don't return, so they don't need to restore r2 */-if(instruction[-1]==PPC_INST_BRANCH)+if(!instr_is_link_branch(*prev_insn))return1;if(*instruction!=PPC_INST_NOP){
@@ -304,6 +304,12 @@ int instr_is_relative_branch(unsigned int instr)returninstr_is_branch_iform(instr)||instr_is_branch_bform(instr);}+intinstr_is_link_branch(unsignedintinstr)+{+return(instr_is_branch_iform(instr)||instr_is_branch_bform(instr))&&+(instr&BRANCH_SET_LINK);+}+staticunsignedlongbranch_iform_target(constunsignedint*instr){signedlongimm;
On Tuesday 14 November 2017 09:23 PM, Josh Poimboeuf wrote:
On Tue, Nov 14, 2017 at 03:59:21PM +0530, Naveen N. Rao wrote:
quoted
Kamalesh Babulal wrote:
quoted
From: Josh Poimboeuf <redacted>
When attempting to load a livepatch module, I got the following error:
module_64: patch_module: Expect noop after relocate, got 3c820000
The error was triggered by the following code in
unregister_netdevice_queue():
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
Signed-off-by: Josh Poimboeuf <redacted>
Signed-off-by: Kamalesh Babulal <redacted>
---
arch/powerpc/kernel/module_64.c | 4 ++++
1 file changed, 4 insertions(+)
@@ -489,6 +489,10 @@ static int restore_r2(u32 *instruction, struct module *me)if(is_early_mcount_callsite(instruction-1))return1;+/* Sibling calls don't return, so they don't need to restore r2 */+if(instruction[-1]==PPC_INST_BRANCH)+return1;+
This looks quite fragile, unless we know for sure that gcc will _always_
emit this instruction form for sibling calls with relocations.
As an alternative, does it make sense to do the following check instead?
if ((instr_is_branch_iform(insn) || instr_is_branch_bform(insn))
&& !(insn & 0x1))
Yes, good point. How about something like this?
(completely untested because I don't have access to a box at the moment)
@@ -33,6 +33,7 @@ int patch_branch(unsigned int *addr, unsigned long target, int flags);intpatch_instruction(unsignedint*addr,unsignedintinstr);intinstr_is_relative_branch(unsignedintinstr);+intinstr_is_link_branch(unsignedintinstr);intinstr_is_branch_to_addr(constunsignedint*instr,unsignedlongaddr);unsignedlongbranch_target(constunsignedint*instr);unsignedinttranslate_branch(constunsignedint*dest,
@@ -487,11 +487,13 @@ static bool is_early_mcount_callsite(u32 *instruction)restorer2.*/staticintrestore_r2(u32*instruction,structmodule*me){-if(is_early_mcount_callsite(instruction-1))+u32*prev_insn=instruction-1;++if(is_early_mcount_callsite(prev_insn))return1;/* Sibling calls don't return, so they don't need to restore r2 */-if(instruction[-1]==PPC_INST_BRANCH)+if(!instr_is_link_branch(*prev_insn))return1;if(*instruction!=PPC_INST_NOP){
@@ -304,6 +304,12 @@ int instr_is_relative_branch(unsigned int instr)returninstr_is_branch_iform(instr)||instr_is_branch_bform(instr);}+intinstr_is_link_branch(unsignedintinstr)+{+return(instr_is_branch_iform(instr)||instr_is_branch_bform(instr))&&+(instr&BRANCH_SET_LINK);+}+staticunsignedlongbranch_iform_target(constunsignedint*instr){signedlongimm;
From: Naveen N. Rao <hidden> Date: 2017-11-15 09:28:55
Josh Poimboeuf wrote:
On Tue, Nov 14, 2017 at 03:59:21PM +0530, Naveen N. Rao wrote:
quoted
Kamalesh Babulal wrote:
quoted
From: Josh Poimboeuf <redacted>
=20
When attempting to load a livepatch module, I got the following error:
=20
module_64: patch_module: Expect noop after relocate, got 3c820000
=20
The error was triggered by the following code in
unregister_netdevice_queue():
=20
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c=
quoted
quoted
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
=20
GCC didn't insert a nop after the branch to net_set_todo() because it'=
s
quoted
quoted
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
=20
Signed-off-by: Josh Poimboeuf <redacted>
Signed-off-by: Kamalesh Babulal <redacted>
---
arch/powerpc/kernel/module_64.c | 4 ++++
1 file changed, 4 insertions(+)
=20
@@ -489,6 +489,10 @@ static int restore_r2(u32 *instruction, struct mo=
dule *me)
quoted
quoted
if (is_early_mcount_callsite(instruction - 1))
return 1;
=20
+ /* Sibling calls don't return, so they don't need to restore r2 */
+ if (instruction[-1] =3D=3D PPC_INST_BRANCH)
+ return 1;
+
=20
This looks quite fragile, unless we know for sure that gcc will _always_
emit this instruction form for sibling calls with relocations.
=20
As an alternative, does it make sense to do the following check instead?
if ((instr_is_branch_iform(insn) || instr_is_branch_bform(insn))
&& !(insn & 0x1))
=20
Yes, good point. How about something like this?
That looks good to me (with a very minor nit below).
Acked-by: Naveen N. Rao <redacted>
quoted hunk
=20
(completely untested because I don't have access to a box at the moment)
=20
=20
@@ -33,6 +33,7 @@ int patch_branch(unsigned int *addr, unsigned long targ=
et, int flags);
int patch_instruction(unsigned int *addr, unsigned int instr);
=20
int instr_is_relative_branch(unsigned int instr);
+int instr_is_link_branch(unsigned int instr);
int instr_is_branch_to_addr(const unsigned int *instr, unsigned long add=
r);
quoted hunk
unsigned long branch_target(const unsigned int *instr);
unsigned int translate_branch(const unsigned int *dest,
Nitpicking here, but since we're not considering the other branch forms,
perhaps this can be renamed to instr_is_link_relative_branch() (or maybe=20
instr_is_relative_branch_link()), just so we're clear :)
- Naveen
static unsigned long branch_iform_target(const unsigned int *instr)
{
signed long imm;
--
To unsubscribe from this list: send the line "unsubscribe live-patching" =
Nitpicking here, but since we're not considering the other branch forms,
perhaps this can be renamed to instr_is_link_relative_branch() (or maybe
instr_is_relative_branch_link()), just so we're clear :)
My understanding is that the absolute/relative bit isn't a "form", but
rather a bit that can be set for either the b-form (conditional) or the
i-form (unconditional). And the above function isn't checking the
absolute bit, so it isn't necessarily a relative branch. Or did I miss
something?
--
Josh
From: Naveen N. Rao <hidden> Date: 2017-11-16 13:09:23
Josh Poimboeuf wrote:
On Wed, Nov 15, 2017 at 02:58:33PM +0530, Naveen N. Rao wrote:
quoted
quoted
+int instr_is_link_branch(unsigned int instr)
+{
+ return (instr_is_branch_iform(instr) || instr_is_branch_bform(instr)=
) &&
quoted
quoted
+ (instr & BRANCH_SET_LINK);
+}
+
=20
Nitpicking here, but since we're not considering the other branch forms,
perhaps this can be renamed to instr_is_link_relative_branch() (or maybe
instr_is_relative_branch_link()), just so we're clear :)
=20
My understanding is that the absolute/relative bit isn't a "form", but
rather a bit that can be set for either the b-form (conditional) or the
i-form (unconditional). And the above function isn't checking the
absolute bit, so it isn't necessarily a relative branch. Or did I miss
something?
Ah, good point. I was coming from the fact that we are only considering=20
the i-form and b-form branches and not the lr/ctr/tar based branches,=20
which are always absolute branches, but can also set the link register.
Thinking about this more, aren't we only interested in relative branches
here (for relocations), so can we actually filter out the absolute=20
branches? Something like this?
int instr_is_relative_branch_link(unsigned int instr)
{
return ((instr_is_branch_iform(instr) || instr_is_branch_bform(instr)) &&
!(instr & BRANCH_ABSOLUTE) && (instr & BRANCH_SET_LINK));
}
- Naveen
=
Nitpicking here, but since we're not considering the other branch forms,
perhaps this can be renamed to instr_is_link_relative_branch() (or maybe
instr_is_relative_branch_link()), just so we're clear :)
My understanding is that the absolute/relative bit isn't a "form", but
rather a bit that can be set for either the b-form (conditional) or the
i-form (unconditional). And the above function isn't checking the
absolute bit, so it isn't necessarily a relative branch. Or did I miss
something?
Ah, good point. I was coming from the fact that we are only considering the
i-form and b-form branches and not the lr/ctr/tar based branches, which are
always absolute branches, but can also set the link register.
Hm, RISC is more complicated than I realized ;-)
Thinking about this more, aren't we only interested in relative branches
here (for relocations), so can we actually filter out the absolute branches?
Something like this?
int instr_is_relative_branch_link(unsigned int instr)
{
return ((instr_is_branch_iform(instr) || instr_is_branch_bform(instr)) &&
!(instr & BRANCH_ABSOLUTE) && (instr & BRANCH_SET_LINK));
Yeah, makes sense to me. Here's another try (also untested). If this
looks ok, Kamalesh would you mind testing again?
----8<----
From: Josh Poimboeuf <redacted>
Subject: [PATCH v4.2] powerpc/modules: Don't try to restore r2 after a sibling call
When attempting to load a livepatch module, I got the following error:
module_64: patch_module: Expect noop after relocate, got 3c820000
The error was triggered by the following code in
unregister_netdevice_queue():
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
Signed-off-by: Josh Poimboeuf <redacted>
---
arch/powerpc/include/asm/code-patching.h | 1 +
arch/powerpc/kernel/module_64.c | 12 +++++++++++-
arch/powerpc/lib/code-patching.c | 5 +++++
3 files changed, 17 insertions(+), 1 deletion(-)
@@ -33,6 +33,7 @@ int patch_branch(unsigned int *addr, unsigned long target, int flags);intpatch_instruction(unsignedint*addr,unsignedintinstr);intinstr_is_relative_branch(unsignedintinstr);+intinstr_is_relative_link_branch(unsignedintinstr);intinstr_is_branch_to_addr(constunsignedint*instr,unsignedlongaddr);unsignedlongbranch_target(constunsignedint*instr);unsignedinttranslate_branch(constunsignedint*dest,
@@ -304,6 +304,11 @@ int instr_is_relative_branch(unsigned int instr)returninstr_is_branch_iform(instr)||instr_is_branch_bform(instr);}+intinstr_is_relative_link_branch(unsignedintinstr)+{+returninstr_is_relative_branch(instr)&&(instr&BRANCH_SET_LINK);+}+staticunsignedlongbranch_iform_target(constunsignedint*instr){signedlongimm;
Nitpicking here, but since we're not considering the other branch forms,
perhaps this can be renamed to instr_is_link_relative_branch() (or maybe
instr_is_relative_branch_link()), just so we're clear :)
My understanding is that the absolute/relative bit isn't a "form", but
rather a bit that can be set for either the b-form (conditional) or the
i-form (unconditional). And the above function isn't checking the
absolute bit, so it isn't necessarily a relative branch. Or did I miss
something?
Ah, good point. I was coming from the fact that we are only considering the
i-form and b-form branches and not the lr/ctr/tar based branches, which are
always absolute branches, but can also set the link register.
Hm, RISC is more complicated than I realized ;-)
quoted
Thinking about this more, aren't we only interested in relative branches
here (for relocations), so can we actually filter out the absolute branches?
Something like this?
int instr_is_relative_branch_link(unsigned int instr)
{
return ((instr_is_branch_iform(instr) || instr_is_branch_bform(instr)) &&
!(instr & BRANCH_ABSOLUTE) && (instr & BRANCH_SET_LINK));
Yeah, makes sense to me. Here's another try (also untested). If this
looks ok, Kamalesh would you mind testing again?
----8<----
From: Josh Poimboeuf <redacted>
Subject: [PATCH v4.2] powerpc/modules: Don't try to restore r2 after a sibling call
When attempting to load a livepatch module, I got the following error:
module_64: patch_module: Expect noop after relocate, got 3c820000
The error was triggered by the following code in
unregister_netdevice_queue():
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
Signed-off-by: Josh Poimboeuf <redacted>
@@ -33,6 +33,7 @@ int patch_branch(unsigned int *addr, unsigned long target, int flags);intpatch_instruction(unsignedint*addr,unsignedintinstr);intinstr_is_relative_branch(unsignedintinstr);+intinstr_is_relative_link_branch(unsignedintinstr);intinstr_is_branch_to_addr(constunsignedint*instr,unsignedlongaddr);unsignedlongbranch_target(constunsignedint*instr);unsignedinttranslate_branch(constunsignedint*dest,
@@ -304,6 +304,11 @@ int instr_is_relative_branch(unsigned int instr)returninstr_is_branch_iform(instr)||instr_is_branch_bform(instr);}+intinstr_is_relative_link_branch(unsignedintinstr)+{+returninstr_is_relative_branch(instr)&&(instr&BRANCH_SET_LINK);+}+staticunsignedlongbranch_iform_target(constunsignedint*instr){signedlongimm;
Yeah, makes sense to me. Here's another try (also untested). If this
looks ok, Kamalesh would you mind testing again?
Thanks. That looks good to me.
Acked-by: Naveen N. Rao <redacted>
quoted
----8<----
From: Josh Poimboeuf <redacted>
Subject: [PATCH v4.2] powerpc/modules: Don't try to restore r2 after a s=
ibling call
quoted
When attempting to load a livepatch module, I got the following error:
module_64: patch_module: Expect noop after relocate, got 3c820000
The error was triggered by the following code in
unregister_netdevice_queue():
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
Signed-off-by: Josh Poimboeuf <redacted>
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2017-12-06 04:32:09
Kamalesh Babulal [off-list ref] writes:
From: Josh Poimboeuf <redacted>
Print the function address associated with the restore_r2() error to
make it easier to debug the problem.
Also clarify the wording a bit.
Before:
module_64: patch_foo: Expect noop after relocate, got 3c820000
After:
module_64: patch_foo: Expected noop after call, got 7c630034 at netdev_has_upper_dev+0x54/0xb0 [patch_foo]
I renamed noop to nop, as that's the name of the instruction.
cheers
From: Michael Ellerman <hidden> Date: 2017-12-12 11:39:36
On Tue, 2017-11-14 at 09:29:10 UTC, Kamalesh Babulal wrote:
From: Josh Poimboeuf <redacted>
Print the function address associated with the restore_r2() error to
make it easier to debug the problem.
Also clarify the wording a bit.
Before:
module_64: patch_foo: Expect noop after relocate, got 3c820000
After:
module_64: patch_foo: Expected noop after call, got 7c630034 at netdev_has_upper_dev+0x54/0xb0 [patch_foo]
Signed-off-by: Josh Poimboeuf <redacted>
Signed-off-by: Kamalesh Babulal <redacted>
From: Michael Ellerman <hidden> Date: 2017-12-12 11:39:38
On Tue, 2017-11-14 at 09:29:08 UTC, Kamalesh Babulal wrote:
Livepatch re-uses module loader function apply_relocate_add() to write
relocations, instead of managing them by arch-dependent
klp_write_module_reloc() function.
apply_relocate_add() doesn't understand livepatch symbols (marked with
SHN_LIVEPATCH symbol section index) and assumes them to be local symbols
by default for R_PPC64_REL24 relocation type. It fails with an error,
when trying to calculate offset with local_entry_offset():
module_64: kpatch_meminfo: REL24 -1152921504897399800 out of range!
Whereas livepatch symbols are essentially SHN_UNDEF, should be
called via stub used for global calls. This issue can be fixed by
teaching apply_relocate_add() to handle both SHN_UNDEF/SHN_LIVEPATCH
symbols via the same stub. This patch extends SHN_UNDEF code to handle
livepatch symbols too.
Signed-off-by: Kamalesh Babulal <redacted>
CC: Balbir Singh <bsingharora@gmail.com>
Cc: Naveen N. Rao <redacted>
Cc: Josh Poimboeuf <redacted>
Cc: Jessica Yu <jeyu@kernel.org>
Cc: Ananth N Mavinakayanahalli <redacted>
Cc: Aravinda Prasad <redacted>
Cc: Torsten Duwe <redacted>
From: Michael Ellerman <hidden> Date: 2017-12-12 11:39:42
On Thu, 2017-11-16 at 17:45:37 UTC, Josh Poimboeuf wrote:
From: Josh Poimboeuf <redacted>
Subject: [PATCH v4.2] powerpc/modules: Don't try to restore r2 after a sibling call
When attempting to load a livepatch module, I got the following error:
module_64: patch_module: Expect noop after relocate, got 3c820000
The error was triggered by the following code in
unregister_netdevice_queue():
14c: 00 00 00 48 b 14c <unregister_netdevice_queue+0x14c>
14c: R_PPC64_REL24 net_set_todo
150: 00 00 82 3c addis r4,r2,0
GCC didn't insert a nop after the branch to net_set_todo() because it's
a sibling call, so it never returns. The nop isn't needed after the
branch in that case.
Signed-off-by: Josh Poimboeuf <redacted>
Acked-by: Naveen N. Rao <redacted>