diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/kernel/kprobes.c | 43 |
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 | */ | ||
128 | static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode, | ||
129 | unsigned 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 | } | ||
153 | out: | ||
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: |