aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/kernel/kprobes.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 5d5344681555..51bc08bd0466 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -120,6 +120,41 @@ static void update_kprobe_inst_flag(uint template, uint slot, uint major_opcode
120} 120}
121 121
122/* 122/*
123 * In this function we check to see if the instruction
124 * (qp) cmpx.crel.ctype p1,p2=r2,r3
125 * on which we are inserting kprobe is cmp instruction
126 * with ctype as unc.
127 */
128static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode,
129unsigned long kprobe_inst)
130{
131 cmp_inst_t cmp_inst;
132 uint ctype_unc = 0;
133
134 if (!((bundle_encoding[template][slot] == I) ||
135 (bundle_encoding[template][slot] == M)))
136 goto out;
137
138 if (!((major_opcode == 0xC) || (major_opcode == 0xD) ||
139 (major_opcode == 0xE)))
140 goto out;
141
142 cmp_inst.l = kprobe_inst;
143 if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
144 /* Integere compare - Register Register (A6 type)*/
145 if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
146 &&(cmp_inst.f.c == 1))
147 ctype_unc = 1;
148 } else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
149 /* Integere compare - Immediate Register (A8 type)*/
150 if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
151 ctype_unc = 1;
152 }
153out:
154 return ctype_unc;
155}
156
157/*
123 * In this function we override the bundle with 158 * In this function we override the bundle with
124 * the break instruction at the given slot. 159 * the break instruction at the given slot.
125 */ 160 */
@@ -131,9 +166,13 @@ static void prepare_break_inst(uint template, uint slot, uint major_opcode,
131 166
132 /* 167 /*
133 * Copy the original kprobe_inst qualifying predicate(qp) 168 * Copy the original kprobe_inst qualifying predicate(qp)
134 * to the break instruction 169 * to the break instruction iff !is_cmp_ctype_unc_inst
170 * because for cmp instruction with ctype equal to unc,
171 * which is a special instruction always needs to be
172 * executed regradless of qp
135 */ 173 */
136 break_inst |= (0x3f & kprobe_inst); 174 if (!is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst))
175 break_inst |= (0x3f & kprobe_inst);
137 176
138 switch (slot) { 177 switch (slot) {
139 case 0: 178 case 0: