From: Naveen N. Rao <hidden> Date: 2017-09-13 21:20:57
1. This is only used in kprobes.c, so make it static.
2. Remove the un-necessary (ret == 0) comparison in the else clause.
Signed-off-by: Naveen N. Rao <redacted>
---
arch/powerpc/kernel/kprobes.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Naveen N. Rao <hidden> Date: 2017-09-13 21:21:01
Currently, we disable instruction emulation if emulate_step() fails for
any reason. However, such failures could be transient and specific to a
particular run. Instead, only disable instruction emulation if we have
never been able to emulate this. If we had emulated this instruction
successfully at least once, then we single step only this probe hit and
continue to try emulating the instruction in subsequent probe hits.
Signed-off-by: Naveen N. Rao <redacted>
---
arch/powerpc/kernel/kprobes.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
On Thu, 14 Sep 2017 02:50:33 +0530
"Naveen N. Rao" [off-list ref] wrote:
Currently, we disable instruction emulation if emulate_step() fails for
any reason. However, such failures could be transient and specific to a
particular run. Instead, only disable instruction emulation if we have
never been able to emulate this. If we had emulated this instruction
successfully at least once, then we single step only this probe hit and
continue to try emulating the instruction in subsequent probe hits.
Hmm, would this mean that the instruction is emulatable or not depends
on context? What kind of situation is considerable?
Thank you,
From: Naveen N. Rao <hidden> Date: 2017-09-14 06:38:18
On 2017/09/13 04:53PM, Masami Hiramatsu wrote:
On Thu, 14 Sep 2017 02:50:33 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Currently, we disable instruction emulation if emulate_step() fails for
any reason. However, such failures could be transient and specific to a
particular run. Instead, only disable instruction emulation if we have
never been able to emulate this. If we had emulated this instruction
successfully at least once, then we single step only this probe hit and
continue to try emulating the instruction in subsequent probe hits.
Hmm, would this mean that the instruction is emulatable or not depends
on context? What kind of situation is considerable?
Yes, as an example, a load/store instruction can cause exceptions
depending on the address. In some of those cases, we will have to single
step the instruction, but we will be able to emulate in most scenarios.
Thanks for the review!
- Naveen
On Thu, 14 Sep 2017 12:08:07 +0530
"Naveen N. Rao" [off-list ref] wrote:
On 2017/09/13 04:53PM, Masami Hiramatsu wrote:
quoted
On Thu, 14 Sep 2017 02:50:33 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Currently, we disable instruction emulation if emulate_step() fails for
any reason. However, such failures could be transient and specific to a
particular run. Instead, only disable instruction emulation if we have
never been able to emulate this. If we had emulated this instruction
successfully at least once, then we single step only this probe hit and
continue to try emulating the instruction in subsequent probe hits.
Hmm, would this mean that the instruction is emulatable or not depends
on context? What kind of situation is considerable?
Yes, as an example, a load/store instruction can cause exceptions
depending on the address. In some of those cases, we will have to single
step the instruction, but we will be able to emulate in most scenarios.
OK, I got it.
Could you add this example as comment in the code so that readers can
easily understand?
Thank you,
From: Naveen N. Rao <hidden> Date: 2017-09-14 10:03:20
On 2017/09/14 02:45AM, Masami Hiramatsu wrote:
On Thu, 14 Sep 2017 12:08:07 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
On 2017/09/13 04:53PM, Masami Hiramatsu wrote:
quoted
On Thu, 14 Sep 2017 02:50:33 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Currently, we disable instruction emulation if emulate_step() fails for
any reason. However, such failures could be transient and specific to a
particular run. Instead, only disable instruction emulation if we have
never been able to emulate this. If we had emulated this instruction
successfully at least once, then we single step only this probe hit and
continue to try emulating the instruction in subsequent probe hits.
Hmm, would this mean that the instruction is emulatable or not depends
on context? What kind of situation is considerable?
Yes, as an example, a load/store instruction can cause exceptions
depending on the address. In some of those cases, we will have to single
step the instruction, but we will be able to emulate in most scenarios.
OK, I got it.
Could you add this example as comment in the code so that readers can
easily understand?
From: Naveen N. Rao <hidden> Date: 2017-09-13 21:21:05
Kamalesh pointed out that we are getting the below call traces with
livepatched functions when we enable CONFIG_PREEMPT:
[ 495.470721] BUG: using __this_cpu_read() in preemptible [00000000] code: cat/8394
[ 495.471167] caller is is_current_kprobe_addr+0x30/0x90
[ 495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G K 4.13.0-rc7-nnr+ #95
[ 495.471173] Call Trace:
[ 495.471178] [c00000008fd9b960] [c0000000009f039c] dump_stack+0xec/0x160 (unreliable)
[ 495.471184] [c00000008fd9b9a0] [c00000000059169c] check_preemption_disabled+0x15c/0x170
[ 495.471187] [c00000008fd9ba30] [c000000000046460] is_current_kprobe_addr+0x30/0x90
[ 495.471191] [c00000008fd9ba60] [c00000000004e9a0] ftrace_call+0x1c/0xb8
[ 495.471195] [c00000008fd9bc30] [c000000000376fd8] seq_read+0x238/0x5c0
[ 495.471199] [c00000008fd9bcd0] [c0000000003cfd78] proc_reg_read+0x88/0xd0
[ 495.471203] [c00000008fd9bd00] [c00000000033e5d4] __vfs_read+0x44/0x1b0
[ 495.471206] [c00000008fd9bd90] [c0000000003402ec] vfs_read+0xbc/0x1b0
[ 495.471210] [c00000008fd9bde0] [c000000000342138] SyS_read+0x68/0x110
[ 495.471214] [c00000008fd9be30] [c00000000000bc6c] system_call+0x58/0x6c
Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
jprobes") introduced a helper is_current_kprobe_addr() to help determine
if the current function has been livepatched or if it has a jprobe
installed, both of which modify the NIP.
In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
before calling into setjmp_pre_handler() which returns without disabling
pre-emption. This is done to ensure that the jprobe handler won't
disappear beneath us if the jprobe is unregistered between the
setjmp_pre_handler() and the subsequent longjmp_break_handler() called
from the jprobe handler. Due to this, we can use __this_cpu_read() in
is_current_kprobe_addr() with the pre-emption check as we know that
pre-emption will be disabled.
However, if this function has been livepatched, we are still doing this
check and when we do so, pre-emption won't necessarily be disabled. This
results in the call trace shown above.
Fix this by only invoking is_current_kprobe_addr() when pre-emption is
disabled. And since we now guard this within a pre-emption check, we can
instead use raw_cpu_read() to get the current_kprobe value skipping the
check done by __this_cpu_read().
Fixes: c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for jprobes")
Reported-by: Kamalesh Babulal <redacted>
Signed-off-by: Naveen N. Rao <redacted>
---
arch/powerpc/kernel/kprobes.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
On Thu, 14 Sep 2017 02:50:34 +0530
"Naveen N. Rao" [off-list ref] wrote:
Kamalesh pointed out that we are getting the below call traces with
livepatched functions when we enable CONFIG_PREEMPT:
[ 495.470721] BUG: using __this_cpu_read() in preemptible [00000000] code: cat/8394
[ 495.471167] caller is is_current_kprobe_addr+0x30/0x90
[ 495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G K 4.13.0-rc7-nnr+ #95
[ 495.471173] Call Trace:
[ 495.471178] [c00000008fd9b960] [c0000000009f039c] dump_stack+0xec/0x160 (unreliable)
[ 495.471184] [c00000008fd9b9a0] [c00000000059169c] check_preemption_disabled+0x15c/0x170
[ 495.471187] [c00000008fd9ba30] [c000000000046460] is_current_kprobe_addr+0x30/0x90
[ 495.471191] [c00000008fd9ba60] [c00000000004e9a0] ftrace_call+0x1c/0xb8
[ 495.471195] [c00000008fd9bc30] [c000000000376fd8] seq_read+0x238/0x5c0
[ 495.471199] [c00000008fd9bcd0] [c0000000003cfd78] proc_reg_read+0x88/0xd0
[ 495.471203] [c00000008fd9bd00] [c00000000033e5d4] __vfs_read+0x44/0x1b0
[ 495.471206] [c00000008fd9bd90] [c0000000003402ec] vfs_read+0xbc/0x1b0
[ 495.471210] [c00000008fd9bde0] [c000000000342138] SyS_read+0x68/0x110
[ 495.471214] [c00000008fd9be30] [c00000000000bc6c] system_call+0x58/0x6c
Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
jprobes") introduced a helper is_current_kprobe_addr() to help determine
if the current function has been livepatched or if it has a jprobe
installed, both of which modify the NIP.
In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
before calling into setjmp_pre_handler() which returns without disabling
pre-emption. This is done to ensure that the jprobe han dler won't
disappear beneath us if the jprobe is unregistered between the
setjmp_pre_handler() and the subsequent longjmp_break_handler() called
from the jprobe handler. Due to this, we can use __this_cpu_read() in
is_current_kprobe_addr() with the pre-emption check as we know that
pre-emption will be disabled.
However, if this function has been livepatched, we are still doing this
check and when we do so, pre-emption won't necessarily be disabled. This
results in the call trace shown above.
Fix this by only invoking is_current_kprobe_addr() when pre-emption is
disabled. And since we now guard this within a pre-emption check, we can
instead use raw_cpu_read() to get the current_kprobe value skipping the
check done by __this_cpu_read().
Hmm, can you disable preempt temporary at this function and read it?
Thank you,
From: Naveen N. Rao <hidden> Date: 2017-09-14 06:47:32
On 2017/09/13 05:36PM, Masami Hiramatsu wrote:
On Thu, 14 Sep 2017 02:50:34 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Kamalesh pointed out that we are getting the below call traces with
livepatched functions when we enable CONFIG_PREEMPT:
[ 495.470721] BUG: using __this_cpu_read() in preemptible [00000000] code: cat/8394
[ 495.471167] caller is is_current_kprobe_addr+0x30/0x90
[ 495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G K 4.13.0-rc7-nnr+ #95
[ 495.471173] Call Trace:
[ 495.471178] [c00000008fd9b960] [c0000000009f039c] dump_stack+0xec/0x160 (unreliable)
[ 495.471184] [c00000008fd9b9a0] [c00000000059169c] check_preemption_disabled+0x15c/0x170
[ 495.471187] [c00000008fd9ba30] [c000000000046460] is_current_kprobe_addr+0x30/0x90
[ 495.471191] [c00000008fd9ba60] [c00000000004e9a0] ftrace_call+0x1c/0xb8
[ 495.471195] [c00000008fd9bc30] [c000000000376fd8] seq_read+0x238/0x5c0
[ 495.471199] [c00000008fd9bcd0] [c0000000003cfd78] proc_reg_read+0x88/0xd0
[ 495.471203] [c00000008fd9bd00] [c00000000033e5d4] __vfs_read+0x44/0x1b0
[ 495.471206] [c00000008fd9bd90] [c0000000003402ec] vfs_read+0xbc/0x1b0
[ 495.471210] [c00000008fd9bde0] [c000000000342138] SyS_read+0x68/0x110
[ 495.471214] [c00000008fd9be30] [c00000000000bc6c] system_call+0x58/0x6c
Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
jprobes") introduced a helper is_current_kprobe_addr() to help determine
if the current function has been livepatched or if it has a jprobe
installed, both of which modify the NIP.
In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
before calling into setjmp_pre_handler() which returns without disabling
pre-emption. This is done to ensure that the jprobe han dler won't
disappear beneath us if the jprobe is unregistered between the
setjmp_pre_handler() and the subsequent longjmp_break_handler() called
from the jprobe handler. Due to this, we can use __this_cpu_read() in
is_current_kprobe_addr() with the pre-emption check as we know that
pre-emption will be disabled.
However, if this function has been livepatched, we are still doing this
check and when we do so, pre-emption won't necessarily be disabled. This
results in the call trace shown above.
Fix this by only invoking is_current_kprobe_addr() when pre-emption is
disabled. And since we now guard this within a pre-emption check, we can
instead use raw_cpu_read() to get the current_kprobe value skipping the
check done by __this_cpu_read().
Hmm, can you disable preempt temporary at this function and read it?
Yes, but I felt this approach is more optimal specifically for live
patching. We don't normally expect preemption to be disabled while
handling a livepatched function, so the simple 'if (!preemptible())'
check helps us bypass looking at current_kprobe.
The check also ensures we can use raw_cpu_read() safely in other
scenarios. Do you see any other concerns with this approach?
Thanks,
Naveen
On Thu, 14 Sep 2017 12:17:20 +0530
"Naveen N. Rao" [off-list ref] wrote:
On 2017/09/13 05:36PM, Masami Hiramatsu wrote:
quoted
On Thu, 14 Sep 2017 02:50:34 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Kamalesh pointed out that we are getting the below call traces with
livepatched functions when we enable CONFIG_PREEMPT:
[ 495.470721] BUG: using __this_cpu_read() in preemptible [00000000] code: cat/8394
[ 495.471167] caller is is_current_kprobe_addr+0x30/0x90
[ 495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G K 4.13.0-rc7-nnr+ #95
[ 495.471173] Call Trace:
[ 495.471178] [c00000008fd9b960] [c0000000009f039c] dump_stack+0xec/0x160 (unreliable)
[ 495.471184] [c00000008fd9b9a0] [c00000000059169c] check_preemption_disabled+0x15c/0x170
[ 495.471187] [c00000008fd9ba30] [c000000000046460] is_current_kprobe_addr+0x30/0x90
[ 495.471191] [c00000008fd9ba60] [c00000000004e9a0] ftrace_call+0x1c/0xb8
[ 495.471195] [c00000008fd9bc30] [c000000000376fd8] seq_read+0x238/0x5c0
[ 495.471199] [c00000008fd9bcd0] [c0000000003cfd78] proc_reg_read+0x88/0xd0
[ 495.471203] [c00000008fd9bd00] [c00000000033e5d4] __vfs_read+0x44/0x1b0
[ 495.471206] [c00000008fd9bd90] [c0000000003402ec] vfs_read+0xbc/0x1b0
[ 495.471210] [c00000008fd9bde0] [c000000000342138] SyS_read+0x68/0x110
[ 495.471214] [c00000008fd9be30] [c00000000000bc6c] system_call+0x58/0x6c
Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
jprobes") introduced a helper is_current_kprobe_addr() to help determine
if the current function has been livepatched or if it has a jprobe
installed, both of which modify the NIP.
In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
before calling into setjmp_pre_handler() which returns without disabling
pre-emption. This is done to ensure that the jprobe han dler won't
disappear beneath us if the jprobe is unregistered between the
setjmp_pre_handler() and the subsequent longjmp_break_handler() called
from the jprobe handler. Due to this, we can use __this_cpu_read() in
is_current_kprobe_addr() with the pre-emption check as we know that
pre-emption will be disabled.
However, if this function has been livepatched, we are still doing this
check and when we do so, pre-emption won't necessarily be disabled. This
results in the call trace shown above.
Fix this by only invoking is_current_kprobe_addr() when pre-emption is
disabled. And since we now guard this within a pre-emption check, we can
instead use raw_cpu_read() to get the current_kprobe value skipping the
check done by __this_cpu_read().
Hmm, can you disable preempt temporary at this function and read it?
Yes, but I felt this approach is more optimal specifically for live
patching. We don't normally expect preemption to be disabled while
handling a livepatched function, so the simple 'if (!preemptible())'
check helps us bypass looking at current_kprobe.
Ah, I see. this is for checking "jprobes", since kprobes/kretprobes
usually already done there.
The check also ensures we can use raw_cpu_read() safely in other
scenarios. Do you see any other concerns with this approach?
Yes, there are 2 reasons.
At first, if user's custom kprobe pre-handler changes NIP for their
custom handwriting livepatching, such handler will enable preemption
before return. We don't prohibit it. I think this function can not
detect it.
And also, the function "name" is very confusing :)
Especially, since this symbol is exported, if you are checking jprobes
context, it should be renamed, at least it starts with "__" so that
show it as local use.
Thank you,
From: Naveen N. Rao <hidden> Date: 2017-09-16 11:25:49
On 2017/09/14 03:10AM, Masami Hiramatsu wrote:
On Thu, 14 Sep 2017 12:17:20 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
On 2017/09/13 05:36PM, Masami Hiramatsu wrote:
quoted
On Thu, 14 Sep 2017 02:50:34 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Kamalesh pointed out that we are getting the below call traces with
livepatched functions when we enable CONFIG_PREEMPT:
[ 495.470721] BUG: using __this_cpu_read() in preemptible [00000000] code: cat/8394
[ 495.471167] caller is is_current_kprobe_addr+0x30/0x90
[ 495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G K 4.13.0-rc7-nnr+ #95
[ 495.471173] Call Trace:
[ 495.471178] [c00000008fd9b960] [c0000000009f039c] dump_stack+0xec/0x160 (unreliable)
[ 495.471184] [c00000008fd9b9a0] [c00000000059169c] check_preemption_disabled+0x15c/0x170
[ 495.471187] [c00000008fd9ba30] [c000000000046460] is_current_kprobe_addr+0x30/0x90
[ 495.471191] [c00000008fd9ba60] [c00000000004e9a0] ftrace_call+0x1c/0xb8
[ 495.471195] [c00000008fd9bc30] [c000000000376fd8] seq_read+0x238/0x5c0
[ 495.471199] [c00000008fd9bcd0] [c0000000003cfd78] proc_reg_read+0x88/0xd0
[ 495.471203] [c00000008fd9bd00] [c00000000033e5d4] __vfs_read+0x44/0x1b0
[ 495.471206] [c00000008fd9bd90] [c0000000003402ec] vfs_read+0xbc/0x1b0
[ 495.471210] [c00000008fd9bde0] [c000000000342138] SyS_read+0x68/0x110
[ 495.471214] [c00000008fd9be30] [c00000000000bc6c] system_call+0x58/0x6c
Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
jprobes") introduced a helper is_current_kprobe_addr() to help determine
if the current function has been livepatched or if it has a jprobe
installed, both of which modify the NIP.
In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
before calling into setjmp_pre_handler() which returns without disabling
pre-emption. This is done to ensure that the jprobe han dler won't
disappear beneath us if the jprobe is unregistered between the
setjmp_pre_handler() and the subsequent longjmp_break_handler() called
from the jprobe handler. Due to this, we can use __this_cpu_read() in
is_current_kprobe_addr() with the pre-emption check as we know that
pre-emption will be disabled.
However, if this function has been livepatched, we are still doing this
check and when we do so, pre-emption won't necessarily be disabled. This
results in the call trace shown above.
Fix this by only invoking is_current_kprobe_addr() when pre-emption is
disabled. And since we now guard this within a pre-emption check, we can
instead use raw_cpu_read() to get the current_kprobe value skipping the
check done by __this_cpu_read().
Hmm, can you disable preempt temporary at this function and read it?
Yes, but I felt this approach is more optimal specifically for live
patching. We don't normally expect preemption to be disabled while
handling a livepatched function, so the simple 'if (!preemptible())'
check helps us bypass looking at current_kprobe.
Ah, I see. this is for checking "jprobes", since kprobes/kretprobes
usually already done there.
Correct.
quoted
The check also ensures we can use raw_cpu_read() safely in other
scenarios. Do you see any other concerns with this approach?
Yes, there are 2 reasons.
At first, if user's custom kprobe pre-handler changes NIP for their
custom handwriting livepatching, such handler will enable preemption
before return. We don't prohibit it. I think this function can not
detect it.
I thought about this quite a bit since we won't have a way to identify
if the ftrace handler was a kprobe or a livepatch in such cases.
Subsequently, I've concluded that this will _not_ be a problem for us.
Here's why:
- The primary reason is_current_kprobe_addr() was added was to detect
jprobes. Jprobes is special since the alternate function does not do a
normal return, but uses jprobe_return()/trap to return from the
function. In this case, if we don't detect this, we end up needlessly
consuming the livepatch stack (the stack frames won't ever be
"popped").
- If a kprobe handler were to modify nip, it would likely reset
current_kprobe and re-enable pre-emption before returning. We won't be
able to detect this scenario. We will end up going through the
livepatch_handler(), allocating a stack, branching into the new nip,
return back from there and de-allocate the stack before going back.
This will be a bit in-efficient, but will work properly.
- Finally, if a custom kprobe handler were to simulate jprobes, it
cannot disable pre-emption or reset current_kprobe, since both are
needed for proper functioning.
As such, I think the current approach works fine for us.
And also, the function "name" is very confusing :)
Especially, since this symbol is exported, if you are checking jprobes
context, it should be renamed, at least it starts with "__" so that
show it as local use.
Agreed. I think I will make suitable updates to specifically call out
jprobes here.
Thanks for the review!
- Naveen
On Thursday 14 September 2017 02:50 AM, Naveen N. Rao wrote:
Kamalesh pointed out that we are getting the below call traces with
livepatched functions when we enable CONFIG_PREEMPT:
[ 495.470721] BUG: using __this_cpu_read() in preemptible [00000000] code: cat/8394
[ 495.471167] caller is is_current_kprobe_addr+0x30/0x90
[ 495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G K 4.13.0-rc7-nnr+ #95
[ 495.471173] Call Trace:
[ 495.471178] [c00000008fd9b960] [c0000000009f039c] dump_stack+0xec/0x160 (unreliable)
[ 495.471184] [c00000008fd9b9a0] [c00000000059169c] check_preemption_disabled+0x15c/0x170
[ 495.471187] [c00000008fd9ba30] [c000000000046460] is_current_kprobe_addr+0x30/0x90
[ 495.471191] [c00000008fd9ba60] [c00000000004e9a0] ftrace_call+0x1c/0xb8
[ 495.471195] [c00000008fd9bc30] [c000000000376fd8] seq_read+0x238/0x5c0
[ 495.471199] [c00000008fd9bcd0] [c0000000003cfd78] proc_reg_read+0x88/0xd0
[ 495.471203] [c00000008fd9bd00] [c00000000033e5d4] __vfs_read+0x44/0x1b0
[ 495.471206] [c00000008fd9bd90] [c0000000003402ec] vfs_read+0xbc/0x1b0
[ 495.471210] [c00000008fd9bde0] [c000000000342138] SyS_read+0x68/0x110
[ 495.471214] [c00000008fd9be30] [c00000000000bc6c] system_call+0x58/0x6c
Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
jprobes") introduced a helper is_current_kprobe_addr() to help determine
if the current function has been livepatched or if it has a jprobe
installed, both of which modify the NIP.
In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
before calling into setjmp_pre_handler() which returns without disabling
pre-emption. This is done to ensure that the jprobe handler won't
disappear beneath us if the jprobe is unregistered between the
setjmp_pre_handler() and the subsequent longjmp_break_handler() called
from the jprobe handler. Due to this, we can use __this_cpu_read() in
is_current_kprobe_addr() with the pre-emption check as we know that
pre-emption will be disabled.
However, if this function has been livepatched, we are still doing this
check and when we do so, pre-emption won't necessarily be disabled. This
results in the call trace shown above.
Fix this by only invoking is_current_kprobe_addr() when pre-emption is
disabled. And since we now guard this within a pre-emption check, we can
instead use raw_cpu_read() to get the current_kprobe value skipping the
check done by __this_cpu_read().
Fixes: c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for jprobes")
Reported-by: Kamalesh Babulal <redacted>
Signed-off-by: Naveen N. Rao <redacted>
Thanks, the call traces are not seen anymore with the patch.
Tested-by: Kamalesh Babulal <redacted>
@@ -65,6 +65,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,/* Disable irq for emulating a breakpoint and avoiding preempt */local_irq_save(flags);hard_irq_disable();+preempt_disable();p=get_kprobe((kprobe_opcode_t*)nip);if(unlikely(!p)||kprobe_disabled(p))
@@ -86,12 +87,18 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,kcb->kprobe_status=KPROBE_HIT_ACTIVE;if(!p->pre_handler||!p->pre_handler(p,regs))__skip_singlestep(p,regs,kcb,orig_nip);-/*-*Ifpre_handlerreturns!0,itsetsregs->nipand-*resetscurrentkprobe.-*/+else{+/*+*Ifpre_handlerreturns!0,itsetsregs->nipand+*resetscurrentkprobe.Inthiscase,westillneed+*torestoreirq,butnotpreemption.+*/+local_irq_restore(flags);+return;+}}end:+preempt_enable_no_resched();local_irq_restore(flags);}NOKPROBE_SYMBOL(kprobe_ftrace_handler);
@@ -65,6 +65,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,/* Disable irq for emulating a breakpoint and avoiding preempt */local_irq_save(flags);hard_irq_disable();+preempt_disable();p=get_kprobe((kprobe_opcode_t*)nip);if(unlikely(!p)||kprobe_disabled(p))
@@ -86,12 +87,18 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,kcb->kprobe_status=KPROBE_HIT_ACTIVE;if(!p->pre_handler||!p->pre_handler(p,regs))__skip_singlestep(p,regs,kcb,orig_nip);-/*-*Ifpre_handlerreturns!0,itsetsregs->nipand-*resetscurrentkprobe.-*/+else{+/*+*Ifpre_handlerreturns!0,itsetsregs->nipand+*resetscurrentkprobe.Inthiscase,westillneed+*torestoreirq,butnotpreemption.+*/+local_irq_restore(flags);+return;+}}end:+preempt_enable_no_resched();local_irq_restore(flags);}NOKPROBE_SYMBOL(kprobe_ftrace_handler);
Indeed, I will send a patch for that.
On a related note, I've been looking into why we have !PREEMPT for
CONFIG_OPTPROBES. It looks like the primary reason is x86 having to deal
with replacing multiple instructions. However, that isn't true with arm
and powerpc. So, does it make sense to move 'depends on !PREEMPT' to the
x86 code? Are there other scenarios where it might cause issues for
arm/powerpc?
Thanks!
- Naveen
Indeed, I will send a patch for that.
On a related note, I've been looking into why we have !PREEMPT for
CONFIG_OPTPROBES. It looks like the primary reason is x86 having to deal
with replacing multiple instructions. However, that isn't true with arm
and powerpc. So, does it make sense to move 'depends on !PREEMPT' to the
x86 code? Are there other scenarios where it might cause issues for
arm/powerpc?
Indeed! Whuat I expected was to replace several instructions in RISC processors
for jumping far site (like load & jump), but you chose different approach.
So there is no reason to prehibit that.
Thanks!
--
Masami Hiramatsu [off-list ref]
From: Naveen N. Rao <hidden> Date: 2017-09-13 21:21:11
Fix a circa 2005 FIXME by implementing a check to ensure that we
actually got into the jprobe break handler() due to the trap in
jprobe_return().
Signed-off-by: Naveen N. Rao <redacted>
---
This is v2 of the patch posted previously (*) to change the WARN() to a
pr_debug() as suggested by Masami.
(*) https://patchwork.ozlabs.org/patch/762670/
- Naveen
arch/powerpc/kernel/kprobes.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
@@ -648,24 +648,22 @@ NOKPROBE_SYMBOL(setjmp_pre_handler);void__usedjprobe_return(void){-asmvolatile("trap":::"memory");+asmvolatile("jprobe_return_trap:\n"+"trap\n"+:::"memory");}NOKPROBE_SYMBOL(jprobe_return);-staticvoid__usedjprobe_return_end(void)-{-}-NOKPROBE_SYMBOL(jprobe_return_end);-intlongjmp_break_handler(structkprobe*p,structpt_regs*regs){structkprobe_ctlblk*kcb=get_kprobe_ctlblk();-/*-*FIXME-weshouldideallybevalidatingthatwegothere'cos-*ofthe"trap"injprobe_return()above,beforerestoringthe-*savedregs...-*/+if(regs->nip!=ppc_kallsyms_lookup_name("jprobe_return_trap")){+pr_debug("longjmp_break_handler NIP (0x%lx) does not match jprobe_return_trap (0x%lx)\n",+regs->nip,ppc_kallsyms_lookup_name("jprobe_return_trap"));+return0;+}+memcpy(regs,&kcb->jprobe_saved_regs,sizeof(structpt_regs));/* It's OK to start function graph tracing again */unpause_graph_tracing();
On Thu, 14 Sep 2017 02:50:36 +0530
"Naveen N. Rao" [off-list ref] wrote:
Fix a circa 2005 FIXME by implementing a check to ensure that we
actually got into the jprobe break handler() due to the trap in
jprobe_return().
Looks good to me.
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Thanks!
quoted hunk
Signed-off-by: Naveen N. Rao <redacted>
---
This is v2 of the patch posted previously (*) to change the WARN() to a
pr_debug() as suggested by Masami.
(*) https://patchwork.ozlabs.org/patch/762670/
- Naveen
arch/powerpc/kernel/kprobes.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
@@ -648,24 +648,22 @@ NOKPROBE_SYMBOL(setjmp_pre_handler);void__usedjprobe_return(void){-asmvolatile("trap":::"memory");+asmvolatile("jprobe_return_trap:\n"+"trap\n"+:::"memory");}NOKPROBE_SYMBOL(jprobe_return);-staticvoid__usedjprobe_return_end(void)-{-}-NOKPROBE_SYMBOL(jprobe_return_end);-intlongjmp_break_handler(structkprobe*p,structpt_regs*regs){structkprobe_ctlblk*kcb=get_kprobe_ctlblk();-/*-*FIXME-weshouldideallybevalidatingthatwegothere'cos-*ofthe"trap"injprobe_return()above,beforerestoringthe-*savedregs...-*/+if(regs->nip!=ppc_kallsyms_lookup_name("jprobe_return_trap")){+pr_debug("longjmp_break_handler NIP (0x%lx) does not match jprobe_return_trap (0x%lx)\n",+regs->nip,ppc_kallsyms_lookup_name("jprobe_return_trap"));+return0;+}+memcpy(regs,&kcb->jprobe_saved_regs,sizeof(structpt_regs));/* It's OK to start function graph tracing again */unpause_graph_tracing();
On Thu, 14 Sep 2017 02:50:32 +0530
"Naveen N. Rao" [off-list ref] wrote:
1. This is only used in kprobes.c, so make it static.
2. Remove the un-necessary (ret == 0) comparison in the else clause.
Signed-off-by: Naveen N. Rao <redacted>
On Thursday 14 September 2017 02:50 AM, Naveen N. Rao wrote:
1. This is only used in kprobes.c, so make it static.
2. Remove the un-necessary (ret == 0) comparison in the else clause.
Signed-off-by: Naveen N. Rao <redacted>