Commit 95e6d3ba authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'loongarch-fixes-7.1-2' of...

Merge tag 'loongarch-fixes-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson

Pull LoongArch fixes from Huacai Chen:
 "Rework KASLR to avoid initrd overlap, remove some unused code to avoid
  a build warning, fix some bugs in kprobes and KVM"

* tag 'loongarch-fixes-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  LoongArch: KVM: Move some variable declarations to paravirt.h
  LoongArch: kprobes: Fix handling of fatal unrecoverable recursions
  LoongArch: kprobes: Use larch_insn_text_copy() to patch instructions
  LoongArch: Remove unused code to avoid build warning
  LoongArch: Avoid initrd overlap during kernel relocation
  LoongArch: Skip relocation-time KASLR if already applied
  efi/loongarch: Randomize kernel preferred address for KASLR
parents c8561c73 4a09f4a2
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ static inline unsigned long efi_get_kimg_min_align(void)
	return SZ_2M;
}

#define EFI_KIMG_PREFERRED_ADDRESS	PHYSADDR(VMLINUX_LOAD_ADDRESS)
unsigned long efi_get_kimg_kaslr_address(void);

#define EFI_KIMG_PREFERRED_ADDRESS efi_get_kimg_kaslr_address()

#endif /* _ASM_LOONGARCH_EFI_H */
+6 −0
Original line number Diff line number Diff line
@@ -4,6 +4,12 @@

#ifdef CONFIG_PARAVIRT

#include <linux/jump_label.h>

DECLARE_STATIC_KEY_FALSE(virt_preempt_key);
DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key);
DECLARE_PER_CPU(struct kvm_steal_time, steal_time);

int __init pv_ipi_init(void);
int __init pv_time_init(void);
int __init pv_spinlock_init(void);
+1 −4
Original line number Diff line number Diff line
@@ -3,12 +3,9 @@
#define _ASM_LOONGARCH_QSPINLOCK_H

#include <asm/kvm_para.h>
#include <linux/jump_label.h>
#include <asm/paravirt.h>

#ifdef CONFIG_PARAVIRT
DECLARE_STATIC_KEY_FALSE(virt_preempt_key);
DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key);
DECLARE_PER_CPU(struct kvm_steal_time, steal_time);

#define virt_spin_lock virt_spin_lock

+8 −6
Original line number Diff line number Diff line
@@ -60,16 +60,18 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
/* Install breakpoint in text */
void arch_arm_kprobe(struct kprobe *p)
{
	*p->addr = KPROBE_BP_INSN;
	flush_insn_slot(p);
	u32 insn = KPROBE_BP_INSN;

	larch_insn_text_copy(p->addr, &insn, LOONGARCH_INSN_SIZE);
}
NOKPROBE_SYMBOL(arch_arm_kprobe);

/* Remove breakpoint from text */
void arch_disarm_kprobe(struct kprobe *p)
{
	*p->addr = p->opcode;
	flush_insn_slot(p);
	u32 insn = p->opcode;

	larch_insn_text_copy(p->addr, &insn, LOONGARCH_INSN_SIZE);
}
NOKPROBE_SYMBOL(arch_disarm_kprobe);

@@ -184,16 +186,16 @@ static bool reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
			   struct kprobe_ctlblk *kcb)
{
	switch (kcb->kprobe_status) {
	case KPROBE_HIT_SS:
	case KPROBE_HIT_SSDONE:
	case KPROBE_HIT_ACTIVE:
		kprobes_inc_nmissed_count(p);
		setup_singlestep(p, regs, kcb, 1);
		break;
	case KPROBE_HIT_SS:
	case KPROBE_REENTER:
		pr_warn("Failed to recover from reentered kprobes.\n");
		dump_kprobe(p);
		WARN_ON_ONCE(1);
		BUG();
		break;
	default:
		WARN_ON(1);
+50 −0
Original line number Diff line number Diff line
@@ -134,11 +134,23 @@ early_param("nokaslr", nokaslr);

#define KASLR_DISABLED_MESSAGE "KASLR is disabled by %s in %s cmdline.\n"

/*
 * Note: strictly-defined KASLR means the kernel's final runtime address
 * has a random offset from the kernel's load address, which is implemented
 * in relocate.c; broadly-defined KALSR means the kernel's final runtime
 * address has a random offset from the kernel's link address (a.k.a.
 * VMLINUX_LOAD_ADDRESS), which also include the efistlub implementation,
 * kexec_file implementation and QEMU direct kernel boot. kaslr_disabled()
 * return true only means strictly-defined KASLR is disabled.
 */
static inline __init bool kaslr_disabled(void)
{
	char *str;
	const char *builtin_cmdline = CONFIG_CMDLINE;

	if (kaslr_offset())
		return true; /* KASLR is performed during early boot. */

	str = strstr(builtin_cmdline, "nokaslr");
	if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' ')) {
		pr_info(KASLR_DISABLED_MESSAGE, "\'nokaslr\'", "built-in");
@@ -210,14 +222,52 @@ static inline void __init *determine_relocation_address(void)
	return RELOCATED_KASLR(destination);
}

static unsigned long __init determine_initrd_address(unsigned long *size)
{
	unsigned long start = 0;
	unsigned long key_length;
	char *p, *endp, *key = "initrd=";

	key_length = strlen(key);
	p = strstr(boot_command_line, key);

	if (!p) {
		key = "initrdmem=";
		key_length = strlen(key);
		p = strstr(boot_command_line, key);
	}

	if (p == boot_command_line || (p > boot_command_line && *(p - 1) == ' ')) {
		p += key_length;
		start = memparse(p, &endp);
		if (*endp == ',')
			*size = memparse(endp + 1, NULL);
	}

	return start;
}

static inline int __init relocation_addr_valid(void *location_new)
{
	unsigned long kernel_start, kernel_size;
	unsigned long initrd_start, initrd_size = 0;

	if ((unsigned long)location_new & 0x00000ffff)
		return 0; /* Inappropriately aligned new location */

	if ((unsigned long)location_new < (unsigned long)_end)
		return 0; /* New location overlaps original kernel */

	initrd_start = determine_initrd_address(&initrd_size);
	if (initrd_start && initrd_size) {
		kernel_start = PHYSADDR(location_new);
		kernel_size = (unsigned long)_end - (unsigned long)_text;

		if (kernel_start < (initrd_start + initrd_size) &&
			initrd_start < (kernel_start + kernel_size))
			return 0; /* initrd/initramfs overlaps kernel */
	}

	return 1;
}
#endif
Loading