Centos-kernel-stream-9/arch/x86/kernel/callthunks.c

378 lines
8.5 KiB
C
Raw Normal View History

x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
// SPDX-License-Identifier: GPL-2.0-only
#define pr_fmt(fmt) "callthunks: " fmt
#include <linux/debugfs.h>
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
#include <linux/kallsyms.h>
#include <linux/memory.h>
#include <linux/moduleloader.h>
#include <linux/static_call.h>
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
#include <asm/alternative.h>
#include <asm/asm-offsets.h>
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
#include <asm/cpu.h>
#include <asm/ftrace.h>
#include <asm/insn.h>
#include <asm/kexec.h>
#include <asm/nospec-branch.h>
#include <asm/paravirt.h>
#include <asm/sections.h>
#include <asm/switch_to.h>
#include <asm/sync_core.h>
#include <asm/text-patching.h>
#include <asm/xen/hypercall.h>
static int __initdata_or_module debug_callthunks;
#define prdbg(fmt, args...) \
do { \
if (debug_callthunks) \
printk(KERN_DEBUG pr_fmt(fmt), ##args); \
} while(0)
static int __init debug_thunks(char *str)
{
debug_callthunks = 1;
return 1;
}
__setup("debug-callthunks", debug_thunks);
#ifdef CONFIG_CALL_THUNKS_DEBUG
DEFINE_PER_CPU(u64, __x86_call_count);
DEFINE_PER_CPU(u64, __x86_ret_count);
DEFINE_PER_CPU(u64, __x86_stuffs_count);
DEFINE_PER_CPU(u64, __x86_ctxsw_count);
EXPORT_SYMBOL_GPL(__x86_ctxsw_count);
EXPORT_SYMBOL_GPL(__x86_call_count);
#endif
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
extern s32 __call_sites[], __call_sites_end[];
struct core_text {
unsigned long base;
unsigned long end;
const char *name;
};
static bool thunks_initialized __ro_after_init;
static const struct core_text builtin_coretext = {
.base = (unsigned long)_text,
.end = (unsigned long)_etext,
.name = "builtin",
};
asm (
".pushsection .rodata \n"
".global skl_call_thunk_template \n"
"skl_call_thunk_template: \n"
__stringify(INCREMENT_CALL_DEPTH)" \n"
".global skl_call_thunk_tail \n"
"skl_call_thunk_tail: \n"
".popsection \n"
);
extern u8 skl_call_thunk_template[];
extern u8 skl_call_thunk_tail[];
#define SKL_TMPL_SIZE \
((unsigned int)(skl_call_thunk_tail - skl_call_thunk_template))
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
extern void error_entry(void);
extern void xen_error_entry(void);
extern void paranoid_entry(void);
static inline bool within_coretext(const struct core_text *ct, void *addr)
{
unsigned long p = (unsigned long)addr;
return ct->base <= p && p < ct->end;
}
static inline bool within_module_coretext(void *addr)
{
bool ret = false;
#ifdef CONFIG_MODULES
struct module *mod;
preempt_disable();
mod = __module_address((unsigned long)addr);
if (mod && within_module_core((unsigned long)addr, mod))
ret = true;
preempt_enable();
#endif
return ret;
}
static bool is_coretext(const struct core_text *ct, void *addr)
{
if (ct && within_coretext(ct, addr))
return true;
if (within_coretext(&builtin_coretext, addr))
return true;
return within_module_coretext(addr);
}
static bool skip_addr(void *dest)
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
{
if (dest == error_entry)
return true;
if (dest == paranoid_entry)
return true;
if (dest == xen_error_entry)
return true;
/* Does FILL_RSB... */
if (dest == __switch_to_asm)
return true;
/* Accounts directly */
if (dest == ret_from_fork)
return true;
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_AMD_MEM_ENCRYPT)
if (dest == soft_restart_cpu)
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
return true;
#endif
#ifdef CONFIG_FUNCTION_TRACER
if (dest == __fentry__)
return true;
#endif
#ifdef CONFIG_KEXEC_CORE
if (dest >= (void *)relocate_kernel &&
dest < (void*)relocate_kernel + KEXEC_CONTROL_CODE_MAX_SIZE)
return true;
#endif
return false;
}
static __init_or_module void *call_get_dest(void *addr)
{
struct insn insn;
void *dest;
int ret;
ret = insn_decode_kernel(&insn, addr);
if (ret)
return ERR_PTR(ret);
/* Patched out call? */
if (insn.opcode.bytes[0] != CALL_INSN_OPCODE)
return NULL;
dest = addr + insn.length + insn.immediate.value;
if (skip_addr(dest))
return NULL;
return dest;
}
static const u8 nops[] = {
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
};
static void *patch_dest(void *dest, bool direct)
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
{
unsigned int tsize = SKL_TMPL_SIZE;
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
u8 *pad = dest - tsize;
/* Already patched? */
if (!bcmp(pad, skl_call_thunk_template, tsize))
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
return pad;
/* Ensure there are nops */
if (bcmp(pad, nops, tsize)) {
pr_warn_once("Invalid padding area for %pS\n", dest);
return NULL;
}
if (direct)
memcpy(pad, skl_call_thunk_template, tsize);
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
else
text_poke_copy_locked(pad, skl_call_thunk_template, tsize, true);
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
return pad;
}
static __init_or_module void patch_call(void *addr, const struct core_text *ct)
{
void *pad, *dest;
u8 bytes[8];
if (!within_coretext(ct, addr))
return;
dest = call_get_dest(addr);
if (!dest || WARN_ON_ONCE(IS_ERR(dest)))
return;
if (!is_coretext(ct, dest))
return;
pad = patch_dest(dest, within_coretext(ct, dest));
if (!pad)
return;
prdbg("Patch call at: %pS %px to %pS %px -> %px \n", addr, addr,
dest, dest, pad);
__text_gen_insn(bytes, CALL_INSN_OPCODE, addr, pad, CALL_INSN_SIZE);
text_poke_early(addr, bytes, CALL_INSN_SIZE);
}
static __init_or_module void
patch_call_sites(s32 *start, s32 *end, const struct core_text *ct)
{
s32 *s;
for (s = start; s < end; s++)
patch_call((void *)s + *s, ct);
}
static __init_or_module void
patch_paravirt_call_sites(struct paravirt_patch_site *start,
struct paravirt_patch_site *end,
const struct core_text *ct)
{
struct paravirt_patch_site *p;
for (p = start; p < end; p++)
patch_call((void *)&p->instr_offset + p->instr_offset, ct);
x86/callthunks: Add call patching for call depth tracking Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2190342 Conflicts: A fuzz in the arch/x86/kernel/Makefile hunk due to missing upstream commit 3c516f89e17e5 ("x86: Add support for CONFIG_CFI_CLANG"). commit e81dc127ef69887c72735a3e3868930e2bf313ed Author: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 15 Sep 2022 13:11:23 +0200 x86/callthunks: Add call patching for call depth tracking Mitigating the Intel SKL RSB underflow issue in software requires to track the call depth. That is every CALL and every RET need to be intercepted and additional code injected. The existing retbleed mitigations already include means of redirecting RET to __x86_return_thunk; this can be re-purposed and RET can be redirected to another function doing RET accounting. CALL accounting will use the function padding introduced in prior patches. For each CALL instruction, the destination symbol's padding is rewritten to do the accounting and the CALL instruction is adjusted to call into the padding. This ensures only affected CPUs pay the overhead of this accounting. Unaffected CPUs will leave the padding unused and have their 'JMP __x86_return_thunk' replaced with an actual 'RET' instruction. Objtool has been modified to supply a .call_sites section that lists all the 'CALL' instructions. Additionally the paravirt instruction sites are iterated since they will have been patched from an indirect call to direct calls (or direct instructions in which case it'll be ignored). Module handling and the actual thunk code for SKL will be added in subsequent steps. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220915111147.470877038@infradead.org Signed-off-by: Waiman Long <longman@redhat.com>
2023-07-01 00:28:55 +00:00
}
static __init_or_module void
callthunks_setup(struct callthunk_sites *cs, const struct core_text *ct)
{
prdbg("Patching call sites %s\n", ct->name);
patch_call_sites(cs->call_start, cs->call_end, ct);
patch_paravirt_call_sites(cs->pv_start, cs->pv_end, ct);
prdbg("Patching call sites done%s\n", ct->name);
}
void __init callthunks_patch_builtin_calls(void)
{
struct callthunk_sites cs = {
.call_start = __call_sites,
.call_end = __call_sites_end,
.pv_start = __parainstructions,
.pv_end = __parainstructions_end
};
if (!cpu_feature_enabled(X86_FEATURE_CALL_DEPTH))
return;
pr_info("Setting up call depth tracking\n");
mutex_lock(&text_mutex);
callthunks_setup(&cs, &builtin_coretext);
thunks_initialized = true;
mutex_unlock(&text_mutex);
}
void *callthunks_translate_call_dest(void *dest)
{
void *target;
lockdep_assert_held(&text_mutex);
if (!thunks_initialized || skip_addr(dest))
return dest;
if (!is_coretext(NULL, dest))
return dest;
target = patch_dest(dest, false);
return target ? : dest;
}
#ifdef CONFIG_BPF_JIT
bool is_callthunk(void *addr)
{
unsigned int tmpl_size = SKL_TMPL_SIZE;
void *tmpl = skl_call_thunk_template;
unsigned long dest;
dest = roundup((unsigned long)addr, CONFIG_FUNCTION_ALIGNMENT);
if (!thunks_initialized || skip_addr((void *)dest))
return false;
return !bcmp((void *)(dest - tmpl_size), tmpl, tmpl_size);
}
int x86_call_depth_emit_accounting(u8 **pprog, void *func)
{
unsigned int tmpl_size = SKL_TMPL_SIZE;
void *tmpl = skl_call_thunk_template;
if (!thunks_initialized)
return 0;
/* Is function call target a thunk? */
if (func && is_callthunk(func))
return 0;
memcpy(*pprog, tmpl, tmpl_size);
*pprog += tmpl_size;
return tmpl_size;
}
#endif
#ifdef CONFIG_MODULES
void noinline callthunks_patch_module_calls(struct callthunk_sites *cs,
struct module *mod)
{
struct core_text ct = {
module: replace module_layout with module_memory JIRA: https://issues.redhat.com/browse/RHEL-28063 Conflict: Remove PPC's module_32.c hunk since not supported in RHEL. commit ac3b43283923440900b4f36ca5f9f0b1ca43b70e Author: Song Liu <song@kernel.org> Date: Mon Feb 6 16:28:02 2023 -0800 module: replace module_layout with module_memory module_layout manages different types of memory (text, data, rodata, etc.) in one allocation, which is problematic for some reasons: 1. It is hard to enable CONFIG_STRICT_MODULE_RWX. 2. It is hard to use huge pages in modules (and not break strict rwx). 3. Many archs uses module_layout for arch-specific data, but it is not obvious how these data are used (are they RO, RX, or RW?) Improve the scenario by replacing 2 (or 3) module_layout per module with up to 7 module_memory per module: MOD_TEXT, MOD_DATA, MOD_RODATA, MOD_RO_AFTER_INIT, MOD_INIT_TEXT, MOD_INIT_DATA, MOD_INIT_RODATA, and allocating them separately. This adds slightly more entries to mod_tree (from up to 3 entries per module, to up to 7 entries per module). However, this at most adds a small constant overhead to __module_address(), which is expected to be fast. Various archs use module_layout for different data. These data are put into different module_memory based on their location in module_layout. IOW, data that used to go with text is allocated with MOD_MEM_TYPE_TEXT; data that used to go with data is allocated with MOD_MEM_TYPE_DATA, etc. module_memory simplifies quite some of the module code. For example, ARCH_WANTS_MODULES_DATA_IN_VMALLOC is a lot cleaner, as it just uses a different allocator for the data. kernel/module/strict_rwx.c is also much cleaner with module_memory. Signed-off-by: Song Liu <song@kernel.org> Cc: Luis Chamberlain <mcgrof@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Guenter Roeck <linux@roeck-us.net> Cc: Christophe Leroy <christophe.leroy@csgroup.eu> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Signed-off-by: Luis Chamberlain <mcgrof@kernel.org> Signed-off-by: Donald Dutile <ddutile@redhat.com>
2024-05-09 05:53:58 +00:00
.base = (unsigned long)mod->mem[MOD_TEXT].base,
.end = (unsigned long)mod->mem[MOD_TEXT].base + mod->mem[MOD_TEXT].size,
.name = mod->name,
};
if (!thunks_initialized)
return;
mutex_lock(&text_mutex);
callthunks_setup(cs, &ct);
mutex_unlock(&text_mutex);
}
#endif /* CONFIG_MODULES */
#if defined(CONFIG_CALL_THUNKS_DEBUG) && defined(CONFIG_DEBUG_FS)
static int callthunks_debug_show(struct seq_file *m, void *p)
{
unsigned long cpu = (unsigned long)m->private;
seq_printf(m, "C: %16llu R: %16llu S: %16llu X: %16llu\n,",
per_cpu(__x86_call_count, cpu),
per_cpu(__x86_ret_count, cpu),
per_cpu(__x86_stuffs_count, cpu),
per_cpu(__x86_ctxsw_count, cpu));
return 0;
}
static int callthunks_debug_open(struct inode *inode, struct file *file)
{
return single_open(file, callthunks_debug_show, inode->i_private);
}
static const struct file_operations dfs_ops = {
.open = callthunks_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __init callthunks_debugfs_init(void)
{
struct dentry *dir;
unsigned long cpu;
dir = debugfs_create_dir("callthunks", NULL);
for_each_possible_cpu(cpu) {
void *arg = (void *)cpu;
char name [10];
sprintf(name, "cpu%lu", cpu);
debugfs_create_file(name, 0644, dir, arg, &dfs_ops);
}
return 0;
}
__initcall(callthunks_debugfs_init);
#endif