X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=include%2Fwrapper%2Fibt.h;fp=include%2Fwrapper%2Fibt.h;h=e089a8f6b3054d0f7f009e54434d13d45c3e2adc;hb=92e2c5feecb39cdd4796da89f2b684e395403040;hp=0000000000000000000000000000000000000000;hpb=dfdb34fd8576fba33510491aef5cd5f6f67b56b8;p=lttng-modules.git diff --git a/include/wrapper/ibt.h b/include/wrapper/ibt.h new file mode 100644 index 00000000..e089a8f6 --- /dev/null +++ b/include/wrapper/ibt.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: (GPL-2.0-only) + * + * wrapper/ibt.h + * + * Copyright (C) 2024 Mathieu Desnoyers + */ + +#ifndef _LTTNG_WRAPPER_IBT_H +#define _LTTNG_WRAPPER_IBT_H + +struct irq_ibt_state { + u64 msr; + unsigned long flags; +}; + +/* + * Save (disable) and restore interrupts around MSR bit change and indirect + * function call to make sure this thread is not migrated to another CPU which + * would not have the MSR bit cleared. + */ + +#ifdef CONFIG_X86_KERNEL_IBT +# include +# include +static inline __attribute__((always_inline)) +struct irq_ibt_state wrapper_irq_ibt_save(void) +{ + struct irq_ibt_state state = { 0, 0 }; + u64 msr; + + if (!cpu_feature_enabled(X86_FEATURE_IBT)) + goto end; + local_irq_save(state.flags); + rdmsrl(MSR_IA32_S_CET, msr); + wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN); + state.msr = msr; +end: + return state; +} + +static inline __attribute__((always_inline)) +void wrapper_irq_ibt_restore(struct irq_ibt_state state) +{ + u64 msr; + + if (!cpu_feature_enabled(X86_FEATURE_IBT)) + return; + rdmsrl(MSR_IA32_S_CET, msr); + msr &= ~CET_ENDBR_EN; + msr |= (state.msr & CET_ENDBR_EN); + wrmsrl(MSR_IA32_S_CET, msr); + local_irq_restore(state.flags); +} +#else +static inline struct irq_ibt_state wrapper_irq_ibt_save(void) { struct irq_ibt_state state = { 0, 0 }; return state; } +static inline void wrapper_irq_ibt_restore(struct irq_ibt_state state) { } +#endif + +#endif /* _LTTNG_WRAPPER_IBT_H */