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

cpuidle, xenpv: Make more PARAVIRT_XXL noinstr clean

objtool found a few cases where this code called out into instrumented
code:

vmlinux.o: warning: objtool: acpi_idle_enter_s2idle+0xde: call to wbinvd() leaves .noinstr.text section
vmlinux.o: warning: objtool: default_idle+0x4: call to arch_safe_halt() leaves .noinstr.text section
vmlinux.o: warning: objtool: xen_safe_halt+0xa: call to HYPERVISOR_sched_op.constprop.0() leaves .noinstr.text section

Solve this by:

- marking arch_safe_halt(), wbinvd(), native_wbinvd() and
HYPERVISOR_sched_op() as __always_inline().

- Explicitly uninlining xen_safe_halt() and pv_native_wbinvd() [they were
already uninlined by the compiler on use as function pointers] and
annotating them as 'noinstr'.

- Annotating pv_native_safe_halt() as 'noinstr'.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Tested-by: Tony Lindgren <tony@atomide.com>
Tested-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
Reviewed-by: Juergen Gross <jgross@suse.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/r/20230112195541.171918174@infradead.org

authored by

Peter Zijlstra and committed by
Ingo Molnar
10a09940 c3982c1a

+21 -9
+4 -2
arch/x86/include/asm/paravirt.h
··· 168 168 PVOP_VCALL1(cpu.write_cr4, x); 169 169 } 170 170 171 - static inline void arch_safe_halt(void) 171 + static __always_inline void arch_safe_halt(void) 172 172 { 173 173 PVOP_VCALL0(irq.safe_halt); 174 174 } ··· 178 178 PVOP_VCALL0(irq.halt); 179 179 } 180 180 181 - static inline void wbinvd(void) 181 + extern noinstr void pv_native_wbinvd(void); 182 + 183 + static __always_inline void wbinvd(void) 182 184 { 183 185 PVOP_ALT_VCALL0(cpu.wbinvd, "wbinvd", ALT_NOT(X86_FEATURE_XENPV)); 184 186 }
+2 -2
arch/x86/include/asm/special_insns.h
··· 115 115 } 116 116 #endif 117 117 118 - static inline void native_wbinvd(void) 118 + static __always_inline void native_wbinvd(void) 119 119 { 120 120 asm volatile("wbinvd": : :"memory"); 121 121 } ··· 179 179 native_write_cr4(x); 180 180 } 181 181 182 - static inline void wbinvd(void) 182 + static __always_inline void wbinvd(void) 183 183 { 184 184 native_wbinvd(); 185 185 }
+1 -1
arch/x86/include/asm/xen/hypercall.h
··· 382 382 } 383 383 #endif 384 384 385 - static inline int 385 + static __always_inline int 386 386 HYPERVISOR_sched_op(int cmd, void *arg) 387 387 { 388 388 return _hypercall2(int, sched_op, cmd, arg);
+12 -2
arch/x86/kernel/paravirt.c
··· 216 216 native_set_debugreg(regno, val); 217 217 } 218 218 219 + noinstr void pv_native_wbinvd(void) 220 + { 221 + native_wbinvd(); 222 + } 223 + 219 224 static noinstr void pv_native_irq_enable(void) 220 225 { 221 226 native_irq_enable(); ··· 229 224 static noinstr void pv_native_irq_disable(void) 230 225 { 231 226 native_irq_disable(); 227 + } 228 + 229 + static noinstr void pv_native_safe_halt(void) 230 + { 231 + native_safe_halt(); 232 232 } 233 233 #endif 234 234 ··· 266 256 .cpu.read_cr0 = native_read_cr0, 267 257 .cpu.write_cr0 = native_write_cr0, 268 258 .cpu.write_cr4 = native_write_cr4, 269 - .cpu.wbinvd = native_wbinvd, 259 + .cpu.wbinvd = pv_native_wbinvd, 270 260 .cpu.read_msr = native_read_msr, 271 261 .cpu.write_msr = native_write_msr, 272 262 .cpu.read_msr_safe = native_read_msr_safe, ··· 300 290 .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), 301 291 .irq.irq_disable = __PV_IS_CALLEE_SAVE(pv_native_irq_disable), 302 292 .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), 303 - .irq.safe_halt = native_safe_halt, 293 + .irq.safe_halt = pv_native_safe_halt, 304 294 .irq.halt = native_halt, 305 295 #endif /* CONFIG_PARAVIRT_XXL */ 306 296
+1 -1
arch/x86/xen/enlighten_pv.c
··· 1068 1068 1069 1069 .write_cr4 = xen_write_cr4, 1070 1070 1071 - .wbinvd = native_wbinvd, 1071 + .wbinvd = pv_native_wbinvd, 1072 1072 1073 1073 .read_msr = xen_read_msr, 1074 1074 .write_msr = xen_write_msr,
+1 -1
arch/x86/xen/irq.c
··· 24 24 (void)HYPERVISOR_xen_version(0, NULL); 25 25 } 26 26 27 - static void xen_safe_halt(void) 27 + static noinstr void xen_safe_halt(void) 28 28 { 29 29 /* Blocking includes an implicit local_irq_enable(). */ 30 30 if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)