Commit 87fa732d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86-core-2023-08-30-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 core updates from Thomas Gleixner:

 - Prevent kprobes on compiler generated CFI checking code.

   The compiler generates an instruction sequence for indirect call
   checks. If this sequence is modified with a kprobe, then the check
   fails. So the instructions must be protected against probing.

 - A few minor cleanups for the SMP code

* tag 'x86-core-2023-08-30-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/kprobes: Prohibit probing on compiler generated CFI checking code
  x86/smpboot: Change smp_store_boot_cpu_info() to static
  x86/smp: Remove a non-existent function declaration
  x86/smpboot: Remove a stray comment about CPU hotplug
parents 98559227 b6541376
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -132,11 +132,8 @@ void smp_kick_mwait_play_dead(void);
void native_smp_send_reschedule(int cpu);
void native_send_call_func_ipi(const struct cpumask *mask);
void native_send_call_func_single_ipi(int cpu);
void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle);

bool smp_park_other_cpus_in_init(void);

void smp_store_boot_cpu_info(void);
void smp_store_cpu_info(int id);

asmlinkage __visible void smp_reboot_interrupt(void);
+34 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <linux/vmalloc.h>
#include <linux/pgtable.h>
#include <linux/set_memory.h>
#include <linux/cfi.h>

#include <asm/text-patching.h>
#include <asm/cacheflush.h>
@@ -293,7 +294,40 @@ static int can_probe(unsigned long paddr)
#endif
		addr += insn.length;
	}
	if (IS_ENABLED(CONFIG_CFI_CLANG)) {
		/*
		 * The compiler generates the following instruction sequence
		 * for indirect call checks and cfi.c decodes this;
		 *
		 *   movl    -<id>, %r10d       ; 6 bytes
		 *   addl    -4(%reg), %r10d    ; 4 bytes
		 *   je      .Ltmp1             ; 2 bytes
		 *   ud2                        ; <- regs->ip
		 *   .Ltmp1:
		 *
		 * Also, these movl and addl are used for showing expected
		 * type. So those must not be touched.
		 */
		__addr = recover_probed_instruction(buf, addr);
		if (!__addr)
			return 0;

		if (insn_decode_kernel(&insn, (void *)__addr) < 0)
			return 0;

		if (insn.opcode.value == 0xBA)
			offset = 12;
		else if (insn.opcode.value == 0x3)
			offset = 6;
		else
			goto out;

		/* This movl/addl is used for decoding CFI. */
		if (is_cfi_trap(addr + offset))
			return 0;
	}

out:
	return (addr == paddr);
}

+2 −4
Original line number Diff line number Diff line
@@ -414,7 +414,7 @@ int topology_update_die_map(unsigned int die, unsigned int cpu)
	return 0;
}

void __init smp_store_boot_cpu_info(void)
static void __init smp_store_boot_cpu_info(void)
{
	int id = 0; /* CPU 0 */
	struct cpuinfo_x86 *c = &cpu_data(id);
@@ -1601,9 +1601,7 @@ void play_dead_common(void)
	idle_task_exit();

	cpuhp_ap_report_dead();
	/*
	 * With physical CPU hotplug, we should halt the cpu
	 */

	local_irq_disable();
}

+3 −1
Original line number Diff line number Diff line
@@ -19,11 +19,13 @@ static inline enum bug_trap_type report_cfi_failure_noaddr(struct pt_regs *regs,
{
	return report_cfi_failure(regs, addr, NULL, 0);
}
#endif /* CONFIG_CFI_CLANG */

#ifdef CONFIG_ARCH_USES_CFI_TRAPS
bool is_cfi_trap(unsigned long addr);
#else
static inline bool is_cfi_trap(unsigned long addr) { return false; }
#endif
#endif /* CONFIG_CFI_CLANG */

#ifdef CONFIG_MODULES
#ifdef CONFIG_ARCH_USES_CFI_TRAPS