Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86/alternative: Refactor INT3 call emulation selftest

The INT3 call emulation selftest is a bit fragile as it relies on the
compiler not inserting any extra instructions before the
int3_selftest_ip() definition.

Also, the int3_selftest_ip() symbol overlaps with the int3_selftest
symbol(), which can confuse objtool.

Fix those issues by slightly reworking the functionality and moving
int3_selftest_ip() to a separate asm function. While at it, improve the
naming.

Acked-by: Petr Mladek <pmladek@suse.com>
Tested-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

+28 -23
+28 -23
arch/x86/kernel/alternative.c
··· 2244 2244 * See entry_{32,64}.S for more details. 2245 2245 */ 2246 2246 2247 - /* 2248 - * We define the int3_magic() function in assembly to control the calling 2249 - * convention such that we can 'call' it from assembly. 2250 - */ 2251 - 2252 - extern void int3_magic(unsigned int *ptr); /* defined in asm */ 2247 + extern void int3_selftest_asm(unsigned int *ptr); 2253 2248 2254 2249 asm ( 2255 2250 " .pushsection .init.text, \"ax\", @progbits\n" 2256 - " .type int3_magic, @function\n" 2257 - "int3_magic:\n" 2251 + " .type int3_selftest_asm, @function\n" 2252 + "int3_selftest_asm:\n" 2258 2253 ANNOTATE_NOENDBR 2259 - " movl $1, (%" _ASM_ARG1 ")\n" 2254 + /* 2255 + * INT3 padded with NOP to CALL_INSN_SIZE. The INT3 triggers an 2256 + * exception, then the int3_exception_nb notifier emulates a call to 2257 + * int3_selftest_callee(). 2258 + */ 2259 + " int3; nop; nop; nop; nop\n" 2260 2260 ASM_RET 2261 - " .size int3_magic, .-int3_magic\n" 2261 + " .size int3_selftest_asm, . - int3_selftest_asm\n" 2262 + " .popsection\n" 2263 + ); 2264 + 2265 + extern void int3_selftest_callee(unsigned int *ptr); 2266 + 2267 + asm ( 2268 + " .pushsection .init.text, \"ax\", @progbits\n" 2269 + " .type int3_selftest_callee, @function\n" 2270 + "int3_selftest_callee:\n" 2271 + ANNOTATE_NOENDBR 2272 + " movl $0x1234, (%" _ASM_ARG1 ")\n" 2273 + ASM_RET 2274 + " .size int3_selftest_callee, . - int3_selftest_callee\n" 2262 2275 " .popsection\n" 2263 2276 ); 2264 2277 ··· 2280 2267 static int __init 2281 2268 int3_exception_notify(struct notifier_block *self, unsigned long val, void *data) 2282 2269 { 2283 - unsigned long selftest = (unsigned long)&int3_selftest_ip; 2270 + unsigned long selftest = (unsigned long)&int3_selftest_asm; 2284 2271 struct die_args *args = data; 2285 2272 struct pt_regs *regs = args->regs; 2286 2273 ··· 2295 2282 if (regs->ip - INT3_INSN_SIZE != selftest) 2296 2283 return NOTIFY_DONE; 2297 2284 2298 - int3_emulate_call(regs, (unsigned long)&int3_magic); 2285 + int3_emulate_call(regs, (unsigned long)&int3_selftest_callee); 2299 2286 return NOTIFY_STOP; 2300 2287 } 2301 2288 ··· 2311 2298 BUG_ON(register_die_notifier(&int3_exception_nb)); 2312 2299 2313 2300 /* 2314 - * Basically: int3_magic(&val); but really complicated :-) 2315 - * 2316 - * INT3 padded with NOP to CALL_INSN_SIZE. The int3_exception_nb 2317 - * notifier above will emulate CALL for us. 2301 + * Basically: int3_selftest_callee(&val); but really complicated :-) 2318 2302 */ 2319 - asm volatile ("int3_selftest_ip:\n\t" 2320 - ANNOTATE_NOENDBR 2321 - " int3; nop; nop; nop; nop\n\t" 2322 - : ASM_CALL_CONSTRAINT 2323 - : __ASM_SEL_RAW(a, D) (&val) 2324 - : "memory"); 2303 + int3_selftest_asm(&val); 2325 2304 2326 - BUG_ON(val != 1); 2305 + BUG_ON(val != 0x1234); 2327 2306 2328 2307 unregister_die_notifier(&int3_exception_nb); 2329 2308 }