public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] IA64 trap code 16 bytes atomic copy on montecito
@ 2006-10-31  5:55 bibo,mao
  2006-10-31  6:18 ` Keith Owens
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: bibo,mao @ 2006-10-31  5:55 UTC (permalink / raw)
  To: linux-ia64

hi,
  On IA64 kprobe can not insert trap code on slot 1 because
opcode of slot 1 crosses over two consecutive 8-bytes. On
montecito machine 16 bytes atomic operation is avaiable,
This patch implements 16 bytes atomic copy on montecito
machine, so that kprobe can probe any slot on montecito
machine.
  Any comments is welcome.

Signed-off-by: bibo, mao <bibo.mao@intel.com>
  
thanks
bibo,mao 

 arch/ia64/kernel/jprobes.S |   38 +++++++++++++++++++++++++++
 arch/ia64/kernel/kprobes.c |   16 ++++++++++++----
 include/asm-ia64/kprobes.h |    1 +
 3 files changed, 51 insertions(+), 4 deletions(-)
-------------------------------------------------------------

diff -Nruap -X 2.6.19-rc2.org/Documentation/dontdiff 2.6.19-rc2.org/arch/ia64/kernel/jprobes.S 2.6.19-rc2/arch/ia64/kernel/jprobes.S
--- 2.6.19-rc2.org/arch/ia64/kernel/jprobes.S	2006-03-27 14:41:20.000000000 +0800
+++ 2.6.19-rc2/arch/ia64/kernel/jprobes.S	2006-10-31 12:29:14.000000000 +0800
@@ -87,3 +87,41 @@ GLOBAL_ENTRY(flush_register_stack)
 	br.ret.sptk.many rp
 END(flush_register_stack)
 
+/* this function uses st16/ld16 to atomically copy one bundle
+ * to code area, it requires src address and dest address is
+ * not in UC/UCE/WC area. Currently kernel physical memory
+ * identified map is cachable and WB, so there is no such check.
+ *  input0: represents whether this cpu supports atomic
+ *	    st16/ld16 instruction
+ *  input1: destionation address of bundle copy
+ *  input2: source address of bundle copy
+ *  return: -1 failed, 0 succeed  
+ */
+GLOBAL_ENTRY(kprobe_update_inst_bundle)
+	alloc loc0=ar.pfs,3,1,0,0
+
+	and r15\x15,r34
+	and r14\x15,r33
+	mov r8=-1
+	;;
+	cmp.eq p9,p8=0,r15
+	cmp.eq p7,p6=0,r14
+(p6) 	br.ret.dptk.many b0
+	;;
+	cmp4.eq p7,p6=0,r32
+(p8)	br.ret.dpnt.many b0
+	;;
+(p7)	ld8  r14=[r34],8
+	mov  r8=r0
+(p6)	ld16 r14=[r34]
+	;;
+(p7)	st8  [r33]=r14,8
+(p6)	st16 [r33]=r14
+	;;
+(p7)	ld8  r14=[r34]
+	;;
+(p7)	st8 [r33]=r14
+	nop.i 0x0
+	br.ret.sptk.many b0
+	;;	
+END(kprobe_update_inst_bundle)
diff -Nruap -X 2.6.19-rc2.org/Documentation/dontdiff 2.6.19-rc2.org/arch/ia64/kernel/kprobes.c 2.6.19-rc2/arch/ia64/kernel/kprobes.c
--- 2.6.19-rc2.org/arch/ia64/kernel/kprobes.c	2006-10-27 16:39:29.000000000 +0800
+++ 2.6.19-rc2/arch/ia64/kernel/kprobes.c	2006-10-31 13:59:52.000000000 +0800
@@ -39,6 +39,8 @@ extern void jprobe_inst_return(void);
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+#define ITANIUM_CPUID4_BIT_AO	2
+#define ITANIUM_CPUID4_AO	(0x1UL << ITANIUM_CPUID4_BIT_AO)
 
 enum instruction_type {A, I, M, F, B, L, X, u};
 static enum instruction_type bundle_encoding[32][3] = {
@@ -284,6 +286,8 @@ static int __kprobes in_ivt_functions(un
 static int __kprobes valid_kprobe_addr(int template, int slot,
 				       unsigned long addr)
 {
+	int atomic;
+
 	if ((slot > 2) || ((bundle_encoding[template][1] = L) && slot > 1)) {
 		printk(KERN_WARNING "Attempting to insert unaligned kprobe "
 				"at 0x%lx\n", addr);
@@ -296,7 +300,8 @@ static int __kprobes valid_kprobe_addr(i
 		return -EINVAL;
 	}
 
-	if (slot = 1 && bundle_encoding[template][1] != L) {
+	atomic = local_cpu_data->features & ITANIUM_CPUID4_AO;
+	if (slot = 1 && !atomic && bundle_encoding[template][1] != L) {
 		printk(KERN_WARNING "Inserting kprobes on slot #1 "
 		       "is not supported\n");
 		return -EINVAL;
@@ -460,10 +465,12 @@ void __kprobes arch_arm_kprobe(struct kp
 {
 	unsigned long addr = (unsigned long)p->addr;
 	unsigned long arm_addr = addr & ~0xFULL;
+	int atomic;
 
+	atomic = local_cpu_data->features & ITANIUM_CPUID4_AO;
 	flush_icache_range((unsigned long)p->ainsn.insn,
 			(unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t));
-	memcpy((char *)arm_addr, &p->opcode, sizeof(kprobe_opcode_t));
+	kprobe_update_inst_bundle(atomic, (void *)arm_addr, (void *)&p->opcode);
 	flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
 }
 
@@ -471,10 +478,11 @@ void __kprobes arch_disarm_kprobe(struct
 {
 	unsigned long addr = (unsigned long)p->addr;
 	unsigned long arm_addr = addr & ~0xFULL;
+	int atomic;
 
+	atomic = local_cpu_data->features & ITANIUM_CPUID4_AO;
 	/* p->ainsn.insn contains the original unaltered kprobe_opcode_t */
-	memcpy((char *) arm_addr, (char *) p->ainsn.insn,
-					 sizeof(kprobe_opcode_t));
+	kprobe_update_inst_bundle(atomic, (void *)arm_addr, (void *) p->ainsn.insn);
 	flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
 }
 
diff -Nruap -X 2.6.19-rc2.org/Documentation/dontdiff 2.6.19-rc2.org/include/asm-ia64/kprobes.h 2.6.19-rc2/include/asm-ia64/kprobes.h
--- 2.6.19-rc2.org/include/asm-ia64/kprobes.h	2006-10-27 16:39:34.000000000 +0800
+++ 2.6.19-rc2/include/asm-ia64/kprobes.h	2006-10-31 12:29:36.000000000 +0800
@@ -127,5 +127,6 @@ static inline void jprobe_return(void)
 extern void invalidate_stacked_regs(void);
 extern void flush_register_stack(void);
 extern void arch_remove_kprobe(struct kprobe *p);
+extern int kprobe_update_inst_bundle(int atomic, void *desc, void *src);
 
 #endif				/* _ASM_KPROBES_H */

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-10-31 12:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-31  5:55 [PATCH] IA64 trap code 16 bytes atomic copy on montecito bibo,mao
2006-10-31  6:18 ` Keith Owens
2006-10-31  7:53 ` Chen, Kenneth W
2006-10-31  8:09 ` Chen, Kenneth W
2006-10-31  8:19 ` bibo,mao
2006-10-31  8:40 ` Chen, Kenneth W
2006-10-31 12:48 ` bibo,mao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox