* [PATCH] kprobe invalidate icache of jump buffer
@ 2006-06-29 9:29 bibo, mao
2006-06-29 12:52 ` Jes Sorensen
0 siblings, 1 reply; 2+ messages in thread
From: bibo, mao @ 2006-06-29 9:29 UTC (permalink / raw)
To: linux-ia64
Hi,
Kprobe inserts breakpoint instruction in probepoint and then jump to jmp buffer,
the jump buffer icache must be consistent with dcache. Here is the patch invalidates
jump buffer icache area.
Without this patch, in some machines there will be fault when jumping to jmp buffer
where icache content is inconsistent with dcache.
This patch has been tested in my IA32, x86_64 and IA64 box, but is not tested in SPARC64
and powerpc architecture. It is based on kernel 2.6.17 version.
Signed-off-by: bibo,mao <bibo.mao@intel.com>
Thanks
bibo,mao
diff -Nruap 2.6.17.org/arch/i386/kernel/kprobes.c 2.6.17.mbo/arch/i386/kernel/kprobes.c
--- 2.6.17.org/arch/i386/kernel/kprobes.c 2006-06-29 03:50:15.000000000 +0800
+++ 2.6.17.mbo/arch/i386/kernel/kprobes.c 2006-06-29 08:41:49.000000000 +0800
@@ -114,6 +114,9 @@ int __kprobes arch_prepare_kprobe(struct
} else {
p->ainsn.boostable = -1;
}
+ flush_icache_range((unsigned long)p->ainsn.insn,
+ (unsigned long)p->ainsn.insn + MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+
return 0;
}
@@ -131,6 +134,12 @@ void __kprobes arch_disarm_kprobe(struct
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}
+void __kprobes kprobe_flush_icache(struct kprobe *p)
+{
+ flush_icache_range((unsigned long) p->ainsn.insn,
+ (unsigned long) p->ainsn.insn + MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+}
+
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
mutex_lock(&kprobe_mutex);
diff -Nruap 2.6.17.org/arch/ia64/kernel/kprobes.c 2.6.17.mbo/arch/ia64/kernel/kprobes.c
--- 2.6.17.org/arch/ia64/kernel/kprobes.c 2006-06-29 03:50:15.000000000 +0800
+++ 2.6.17.mbo/arch/ia64/kernel/kprobes.c 2006-06-29 07:36:51.000000000 +0800
@@ -445,29 +445,39 @@ int __kprobes arch_prepare_kprobe(struct
return -EINVAL;
prepare_break_inst(template, slot, major_opcode, kprobe_inst, p);
+ addr = (unsigned long)&p->opcode.bundle & ~0xFULL;
+ flush_icache_range(addr, addr + sizeof(bundle_t));
return 0;
}
void __kprobes arch_arm_kprobe(struct kprobe *p)
{
- unsigned long addr = (unsigned long)p->addr;
- unsigned long arm_addr = addr & ~0xFULL;
+ unsigned long arm_addr;
+ arm_addr = (unsigned long)p->addr & ~0xFULL;
memcpy((char *)arm_addr, &p->ainsn.insn.bundle, sizeof(bundle_t));
flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
}
void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
- unsigned long addr = (unsigned long)p->addr;
- unsigned long arm_addr = addr & ~0xFULL;
+ unsigned long arm_addr;
+ arm_addr = (unsigned long)p->addr & ~0xFULL;
/* p->opcode contains the original unaltered bundle */
memcpy((char *) arm_addr, (char *) &p->opcode.bundle, sizeof(bundle_t));
flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
}
+void __kprobes kprobe_flush_icache(struct kprobe *p)
+{
+ unsigned long arm_addr;
+
+ arm_addr = (unsigned long)&p->opcode.bundle & ~0xFULL;
+ flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
+}
+
/*
* We are resuming execution after a single step fault, so the pt_regs
* structure reflects the register state after we executed the instruction
diff -Nruap 2.6.17.org/arch/powerpc/kernel/kprobes.c 2.6.17.mbo/arch/powerpc/kernel/kprobes.c
--- 2.6.17.org/arch/powerpc/kernel/kprobes.c 2006-06-29 03:50:15.000000000 +0800
+++ 2.6.17.mbo/arch/powerpc/kernel/kprobes.c 2006-06-29 08:17:31.000000000 +0800
@@ -63,6 +63,8 @@ int __kprobes arch_prepare_kprobe(struct
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
p->opcode = *p->addr;
}
+ flush_icache_range((unsigned long)p->ainsn.insn,
+ (unsigned long)p->ainsn.insn + MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
return ret;
}
@@ -81,6 +83,12 @@ void __kprobes arch_disarm_kprobe(struct
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}
+void __kprobes kprobe_flush_icache(struct kprobe *p)
+{
+ flush_icache_range((unsigned long)p->ainsn.insn,
+ (unsigned long)p->ainsn.insn + MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+}
+
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
mutex_lock(&kprobe_mutex);
diff -Nruap 2.6.17.org/arch/sparc64/kernel/kprobes.c 2.6.17.mbo/arch/sparc64/kernel/kprobes.c
--- 2.6.17.org/arch/sparc64/kernel/kprobes.c 2006-06-29 03:50:15.000000000 +0800
+++ 2.6.17.mbo/arch/sparc64/kernel/kprobes.c 2006-06-29 08:13:52.000000000 +0800
@@ -48,6 +48,8 @@ int __kprobes arch_prepare_kprobe(struct
p->ainsn.insn[0] = *p->addr;
p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
p->opcode = *p->addr;
+ flushi(&p->ainsn.insn[0]);
+ flushi(&p->ainsn.insn[1]);
return 0;
}
@@ -63,6 +65,12 @@ void __kprobes arch_disarm_kprobe(struct
flushi(p->addr);
}
+void __kprobe kprobe_flush_icache(struct kprobe *p)
+{
+ flushi(&p->ainsn.insn[0]);
+ flushi(&p->ainsn.insn[1]);
+}
+
static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
{
kcb->prev_kprobe.kp = kprobe_running();
diff -Nruap 2.6.17.org/arch/x86_64/kernel/kprobes.c 2.6.17.mbo/arch/x86_64/kernel/kprobes.c
--- 2.6.17.org/arch/x86_64/kernel/kprobes.c 2006-06-29 03:50:15.000000000 +0800
+++ 2.6.17.mbo/arch/x86_64/kernel/kprobes.c 2006-06-29 08:36:50.000000000 +0800
@@ -76,6 +76,8 @@ int __kprobes arch_prepare_kprobe(struct
return -ENOMEM;
}
arch_copy_kprobe(p);
+ flush_icache_range((unsigned long) p->ainsn.insn,
+ (unsigned long) p->ainsn.insn + MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
return 0;
}
@@ -185,7 +187,7 @@ static s32 __kprobes *is_riprel(u8 *insn
static void __kprobes arch_copy_kprobe(struct kprobe *p)
{
s32 *ripdisp;
- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
+ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
ripdisp = is_riprel(p->ainsn.insn);
if (ripdisp) {
/*
@@ -222,6 +224,12 @@ void __kprobes arch_disarm_kprobe(struct
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}
+void __kprobes kprobe_flush_icache(struct kprobe *p)
+{
+ flush_icache_range((unsigned long) p->ainsn.insn,
+ (unsigned long) p->ainsn.insn + MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+}
+
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
mutex_lock(&kprobe_mutex);
diff -Nruap 2.6.17.org/include/linux/kprobes.h 2.6.17.mbo/include/linux/kprobes.h
--- 2.6.17.org/include/linux/kprobes.h 2006-06-29 03:50:19.000000000 +0800
+++ 2.6.17.mbo/include/linux/kprobes.h 2006-06-29 08:20:12.000000000 +0800
@@ -157,6 +157,7 @@ extern struct mutex kprobe_mutex;
extern int arch_prepare_kprobe(struct kprobe *p);
extern void arch_arm_kprobe(struct kprobe *p);
extern void arch_disarm_kprobe(struct kprobe *p);
+extern void kprobe_flush_icache(struct kprobe *p);
extern int arch_init_kprobes(void);
extern void show_registers(struct pt_regs *regs);
extern kprobe_opcode_t *get_insn_slot(void);
diff -Nruap 2.6.17.org/kernel/kprobes.c 2.6.17.mbo/kernel/kprobes.c
--- 2.6.17.org/kernel/kprobes.c 2006-06-29 03:50:19.000000000 +0800
+++ 2.6.17.mbo/kernel/kprobes.c 2006-06-29 07:18:28.000000000 +0800
@@ -419,6 +419,7 @@ static int __kprobes register_aggr_kprob
return -ENOMEM;
add_aggr_kprobe(ap, old_p);
copy_kprobe(ap, p);
+ kprobe_flush_icache(ap);
ret = add_new_kprobe(ap, p);
}
return ret;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] kprobe invalidate icache of jump buffer
2006-06-29 9:29 [PATCH] kprobe invalidate icache of jump buffer bibo, mao
@ 2006-06-29 12:52 ` Jes Sorensen
0 siblings, 0 replies; 2+ messages in thread
From: Jes Sorensen @ 2006-06-29 12:52 UTC (permalink / raw)
To: linux-ia64
>>>>> "Mao" = bibo, mao <bibo.mao@intel.com> writes:
Mao> Hi, Kprobe inserts breakpoint instruction in probepoint and then
Mao> jump to jmp buffer, the jump buffer icache must be consistent
Mao> with dcache. Here is the patch invalidates jump buffer icache
Mao> area. Without this patch, in some machines there will be fault
Mao> when jumping to jmp buffer where icache content is inconsistent
Mao> with dcache.
Mao> This patch has been tested in my IA32, x86_64 and IA64 box, but
Mao> is not tested in SPARC64 and powerpc architecture. It is based on
Mao> kernel 2.6.17 version. Signed-off-by: bibo,mao
Mao> <bibo.mao@intel.com> Thanks bibo,mao diff -Nruap
Your patch seems to have been mangled by your mail client. Please also
make it comply with Documentation/CodingStyle
Cheers,
Jes
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2006-06-29 12:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-29 9:29 [PATCH] kprobe invalidate icache of jump buffer bibo, mao
2006-06-29 12:52 ` Jes Sorensen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox