mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 15:12:13 +02:00
LoongArch fixes for v7.1-rc5
-----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmoQFmAWHGNoZW5odWFj YWlAa2VybmVsLm9yZwAKCRAChivD8uImevFED/9pCspo7HFPyYlEBeEoPfKvkLRr XyJzaVpCyqfbnfnsLyUGnu+rtQfX1hLxRqeMUjPGx0AE8M59KD9KkQ0H2ZdTVz80 3ytI0oVBVCzmm1QdbtxRHPGd1kvJcUH/Z2hQFQhSPDoq8wiLbjj36kpGy3YQEdjb o7880THpa47OemgHwAKqCUOyXnsfjPj5nISimuIZg3XfFn9svsvuk3nsktYWdcJ3 UiH9BDSVbIqHj7xzSCrvgil8fcaBHYbXNBjWezubmc0V21PKWf063XNqO9xKzkGQ uzcb0l0B9qImm0brxczIlDfoLc3wzOj67jrvUF5xhU4DZiNBci039RNfW8+7l1pQ GhrWBxf+sWuhW/vqiv65bHys4Af5P1FX2848i4ZxW+m2gfuxw5T43Mf6R1v05Acy 0NZ3Y0zZt+rw8VpTF0I7egjshLFix5fq4mdfECKBB24fCsr8svNFuNYT8JPtqw3S Hk6wN5RVHy5cbc4wnq3zUQna7iWO+bE+rngnyv29BS/1nIfAhbOUqIrNrB0lvs5S UK6IQVmW84Zx18KvWie4tzyAXWJglCOM1V8f1QejOrNGPPZI9+RDtYw8TONFrFdz SFfL6fulS6X5tSCo9e8V7NzeWLIvIGEjxVP2bVeVBrY4fVvmjromm/msVqrYhj3Z 8UYQqCuduiGQErmH3g== =cYtz -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
95e6d3ba05
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -123,11 +123,7 @@ void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
|
|||
{
|
||||
unsigned long start_pfn = start >> PAGE_SHIFT;
|
||||
unsigned long nr_pages = size >> PAGE_SHIFT;
|
||||
struct page *page = pfn_to_page(start_pfn);
|
||||
|
||||
/* With altmap the first mapped page is offset from @start */
|
||||
if (altmap)
|
||||
page += vmem_altmap_offset(altmap);
|
||||
__remove_pages(start_pfn, nr_pages, altmap);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ efi_status_t efi_parse_options(char const *cmdline)
|
|||
efi_noinitrd = true;
|
||||
} else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
|
||||
efi_no5lvl = true;
|
||||
} else if (IS_ENABLED(CONFIG_LOONGARCH) &&
|
||||
IS_ENABLED(CONFIG_HIBERNATION) &&
|
||||
!strcmp(param, "resume") && val) {
|
||||
efi_nokaslr = true; /* LoongArch can't KASLR for hibernation */
|
||||
} else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
|
||||
!strcmp(param, "mem_encrypt") && val) {
|
||||
if (parse_option_str(val, "on"))
|
||||
|
|
|
|||
|
|
@ -23,6 +23,22 @@ void efi_cache_sync_image(unsigned long image_base, unsigned long alloc_size)
|
|||
asm volatile ("ibar 0" ::: "memory");
|
||||
}
|
||||
|
||||
unsigned long efi_get_kimg_kaslr_address(void)
|
||||
{
|
||||
unsigned int random_offset = 0;
|
||||
|
||||
#ifdef CONFIG_RANDOMIZE_BASE
|
||||
if (!efi_nokaslr) {
|
||||
efi_get_random_bytes(sizeof(random_offset), (u8 *)&random_offset);
|
||||
random_offset ^= (random_get_entropy() << 16);
|
||||
random_offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1);
|
||||
random_offset = ALIGN(random_offset + SZ_64K, SZ_64K);
|
||||
}
|
||||
#endif
|
||||
|
||||
return PHYSADDR(VMLINUX_LOAD_ADDRESS) + random_offset;
|
||||
}
|
||||
|
||||
struct exit_boot_struct {
|
||||
efi_memory_desc_t *runtime_map;
|
||||
int runtime_entry_count;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user