Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull LoongArch fixes from Huacai Chen:
"Fix a lot of build warnings for LTO-enabled objtool check, increase
COMMAND_LINE_SIZE up to 4096, rename a missing GCC_PLUGIN_STACKLEAK to
KSTACK_ERASE, and fix some bugs about arch timer, module loading, LBT
and KVM"

* tag 'loongarch-fixes-6.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
LoongArch: KVM: Add address alignment check in pch_pic register access
LoongArch: KVM: Use kvm_get_vcpu_by_id() instead of kvm_get_vcpu()
LoongArch: KVM: Fix stack protector issue in send_ipi_data()
LoongArch: KVM: Make function kvm_own_lbt() robust
LoongArch: Rename GCC_PLUGIN_STACKLEAK to KSTACK_ERASE
LoongArch: Save LBT before FPU in setup_sigcontext()
LoongArch: Optimize module load time by optimizing PLT/GOT counting
LoongArch: Add cpuhotplug hooks to fix high cpu usage of vCPU threads
LoongArch: Increase COMMAND_LINE_SIZE up to 4096
LoongArch: Pass annotate-tablejump option if LTO is enabled
objtool/LoongArch: Get table size correctly if LTO is enabled

+110 -33
+6
arch/loongarch/Makefile
··· 102 102 103 103 ifdef CONFIG_OBJTOOL 104 104 ifdef CONFIG_CC_HAS_ANNOTATE_TABLEJUMP 105 + # The annotate-tablejump option can not be passed to LLVM backend when LTO is enabled. 106 + # Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' also needs to 107 + # be passed via '-mllvm' to ld.lld. 105 108 KBUILD_CFLAGS += -mannotate-tablejump 109 + ifdef CONFIG_LTO_CLANG 110 + KBUILD_LDFLAGS += -mllvm --loongarch-annotate-tablejump 111 + endif 106 112 else 107 113 KBUILD_CFLAGS += -fno-jump-tables # keep compatibility with older compilers 108 114 endif
+1 -1
arch/loongarch/include/asm/stackframe.h
··· 58 58 .endm 59 59 60 60 .macro STACKLEAK_ERASE 61 - #ifdef CONFIG_GCC_PLUGIN_STACKLEAK 61 + #ifdef CONFIG_KSTACK_ERASE 62 62 bl stackleak_erase_on_task_stack 63 63 #endif 64 64 .endm
+8
arch/loongarch/include/uapi/asm/setup.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + 3 + #ifndef _UAPI_ASM_LOONGARCH_SETUP_H 4 + #define _UAPI_ASM_LOONGARCH_SETUP_H 5 + 6 + #define COMMAND_LINE_SIZE 4096 7 + 8 + #endif /* _UAPI_ASM_LOONGARCH_SETUP_H */
+19 -19
arch/loongarch/kernel/module-sections.c
··· 8 8 #include <linux/module.h> 9 9 #include <linux/moduleloader.h> 10 10 #include <linux/ftrace.h> 11 + #include <linux/sort.h> 11 12 12 13 Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val) 13 14 { ··· 62 61 return (Elf_Addr)&plt[nr]; 63 62 } 64 63 65 - static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y) 64 + #define cmp_3way(a, b) ((a) < (b) ? -1 : (a) > (b)) 65 + 66 + static int compare_rela(const void *x, const void *y) 66 67 { 67 - return x->r_info == y->r_info && x->r_addend == y->r_addend; 68 - } 68 + int ret; 69 + const Elf_Rela *rela_x = x, *rela_y = y; 69 70 70 - static bool duplicate_rela(const Elf_Rela *rela, int idx) 71 - { 72 - int i; 71 + ret = cmp_3way(rela_x->r_info, rela_y->r_info); 72 + if (ret == 0) 73 + ret = cmp_3way(rela_x->r_addend, rela_y->r_addend); 73 74 74 - for (i = 0; i < idx; i++) { 75 - if (is_rela_equal(&rela[i], &rela[idx])) 76 - return true; 77 - } 78 - 79 - return false; 75 + return ret; 80 76 } 81 77 82 78 static void count_max_entries(Elf_Rela *relas, int num, 83 79 unsigned int *plts, unsigned int *gots) 84 80 { 85 - unsigned int i, type; 81 + unsigned int i; 82 + 83 + sort(relas, num, sizeof(Elf_Rela), compare_rela, NULL); 86 84 87 85 for (i = 0; i < num; i++) { 88 - type = ELF_R_TYPE(relas[i].r_info); 89 - switch (type) { 86 + if (i && !compare_rela(&relas[i-1], &relas[i])) 87 + continue; 88 + 89 + switch (ELF_R_TYPE(relas[i].r_info)) { 90 90 case R_LARCH_SOP_PUSH_PLT_PCREL: 91 91 case R_LARCH_B26: 92 - if (!duplicate_rela(relas, i)) 93 - (*plts)++; 92 + (*plts)++; 94 93 break; 95 94 case R_LARCH_GOT_PC_HI20: 96 - if (!duplicate_rela(relas, i)) 97 - (*gots)++; 95 + (*gots)++; 98 96 break; 99 97 default: 100 98 break; /* Do nothing. */
+5 -5
arch/loongarch/kernel/signal.c
··· 677 677 for (i = 1; i < 32; i++) 678 678 err |= __put_user(regs->regs[i], &sc->sc_regs[i]); 679 679 680 + #ifdef CONFIG_CPU_HAS_LBT 681 + if (extctx->lbt.addr) 682 + err |= protected_save_lbt_context(extctx); 683 + #endif 684 + 680 685 if (extctx->lasx.addr) 681 686 err |= protected_save_lasx_context(extctx); 682 687 else if (extctx->lsx.addr) 683 688 err |= protected_save_lsx_context(extctx); 684 689 else if (extctx->fpu.addr) 685 690 err |= protected_save_fpu_context(extctx); 686 - 687 - #ifdef CONFIG_CPU_HAS_LBT 688 - if (extctx->lbt.addr) 689 - err |= protected_save_lbt_context(extctx); 690 - #endif 691 691 692 692 /* Set the "end" magic */ 693 693 info = (struct sctx_info *)extctx->end.addr;
+22
arch/loongarch/kernel/time.c
··· 5 5 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 6 6 */ 7 7 #include <linux/clockchips.h> 8 + #include <linux/cpuhotplug.h> 8 9 #include <linux/delay.h> 9 10 #include <linux/export.h> 10 11 #include <linux/init.h> ··· 103 102 return 0; 104 103 } 105 104 105 + static int arch_timer_starting(unsigned int cpu) 106 + { 107 + set_csr_ecfg(ECFGF_TIMER); 108 + 109 + return 0; 110 + } 111 + 112 + static int arch_timer_dying(unsigned int cpu) 113 + { 114 + constant_set_state_shutdown(this_cpu_ptr(&constant_clockevent_device)); 115 + 116 + /* Clear Timer Interrupt */ 117 + write_csr_tintclear(CSR_TINTCLR_TI); 118 + 119 + return 0; 120 + } 121 + 106 122 static unsigned long get_loops_per_jiffy(void) 107 123 { 108 124 unsigned long lpj = (unsigned long)const_clock_freq; ··· 189 171 190 172 lpj_fine = get_loops_per_jiffy(); 191 173 pr_info("Constant clock event device register\n"); 174 + 175 + cpuhp_setup_state(CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING, 176 + "clockevents/loongarch/timer:starting", 177 + arch_timer_starting, arch_timer_dying); 192 178 193 179 return 0; 194 180 }
+6 -1
arch/loongarch/kvm/intc/eiointc.c
··· 45 45 } 46 46 47 47 cpu = s->sw_coremap[irq]; 48 - vcpu = kvm_get_vcpu(s->kvm, cpu); 48 + vcpu = kvm_get_vcpu_by_id(s->kvm, cpu); 49 + if (unlikely(vcpu == NULL)) { 50 + kvm_err("%s: invalid target cpu: %d\n", __func__, cpu); 51 + return; 52 + } 53 + 49 54 if (level) { 50 55 /* if not enable return false */ 51 56 if (!test_bit(irq, (unsigned long *)s->enable.reg_u32))
+4 -4
arch/loongarch/kvm/intc/ipi.c
··· 99 99 static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) 100 100 { 101 101 int i, idx, ret; 102 - uint32_t val = 0, mask = 0; 102 + uint64_t val = 0, mask = 0; 103 103 104 104 /* 105 105 * Bit 27-30 is mask for byte writing. ··· 108 108 if ((data >> 27) & 0xf) { 109 109 /* Read the old val */ 110 110 idx = srcu_read_lock(&vcpu->kvm->srcu); 111 - ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); 111 + ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, 4, &val); 112 112 srcu_read_unlock(&vcpu->kvm->srcu, idx); 113 113 if (unlikely(ret)) { 114 114 kvm_err("%s: : read data from addr %llx failed\n", __func__, addr); ··· 124 124 } 125 125 val |= ((uint32_t)(data >> 32) & ~mask); 126 126 idx = srcu_read_lock(&vcpu->kvm->srcu); 127 - ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); 127 + ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, 4, &val); 128 128 srcu_read_unlock(&vcpu->kvm->srcu, idx); 129 129 if (unlikely(ret)) 130 130 kvm_err("%s: : write data to addr %llx failed\n", __func__, addr); ··· 298 298 cpu = (attr->attr >> 16) & 0x3ff; 299 299 addr = attr->attr & 0xff; 300 300 301 - vcpu = kvm_get_vcpu(dev->kvm, cpu); 301 + vcpu = kvm_get_vcpu_by_id(dev->kvm, cpu); 302 302 if (unlikely(vcpu == NULL)) { 303 303 kvm_err("%s: invalid target cpu: %d\n", __func__, cpu); 304 304 return -EINVAL;
+10
arch/loongarch/kvm/intc/pch_pic.c
··· 195 195 return -EINVAL; 196 196 } 197 197 198 + if (addr & (len - 1)) { 199 + kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len); 200 + return -EINVAL; 201 + } 202 + 198 203 /* statistics of pch pic reading */ 199 204 vcpu->stat.pch_pic_read_exits++; 200 205 ret = loongarch_pch_pic_read(s, addr, len, val); ··· 304 299 305 300 if (!s) { 306 301 kvm_err("%s: pch pic irqchip not valid!\n", __func__); 302 + return -EINVAL; 303 + } 304 + 305 + if (addr & (len - 1)) { 306 + kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len); 307 307 return -EINVAL; 308 308 } 309 309
+5 -3
arch/loongarch/kvm/vcpu.c
··· 1283 1283 return -EINVAL; 1284 1284 1285 1285 preempt_disable(); 1286 - set_csr_euen(CSR_EUEN_LBTEN); 1287 - _restore_lbt(&vcpu->arch.lbt); 1288 - vcpu->arch.aux_inuse |= KVM_LARCH_LBT; 1286 + if (!(vcpu->arch.aux_inuse & KVM_LARCH_LBT)) { 1287 + set_csr_euen(CSR_EUEN_LBTEN); 1288 + _restore_lbt(&vcpu->arch.lbt); 1289 + vcpu->arch.aux_inuse |= KVM_LARCH_LBT; 1290 + } 1289 1291 preempt_enable(); 1290 1292 1291 1293 return 0;
+1
include/linux/cpuhotplug.h
··· 168 168 CPUHP_AP_QCOM_TIMER_STARTING, 169 169 CPUHP_AP_TEGRA_TIMER_STARTING, 170 170 CPUHP_AP_ARMADA_TIMER_STARTING, 171 + CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING, 171 172 CPUHP_AP_MIPS_GIC_TIMER_STARTING, 172 173 CPUHP_AP_ARC_TIMER_STARTING, 173 174 CPUHP_AP_REALTEK_TIMER_STARTING,
+23
tools/objtool/arch/loongarch/special.c
··· 27 27 struct table_info *next_table; 28 28 unsigned long tmp_insn_offset; 29 29 unsigned long tmp_rodata_offset; 30 + bool is_valid_list = false; 30 31 31 32 rsec = find_section_by_name(file->elf, ".rela.discard.tablejump_annotate"); 32 33 if (!rsec) ··· 36 35 INIT_LIST_HEAD(&table_list); 37 36 38 37 for_each_reloc(rsec, reloc) { 38 + if (reloc->sym->sec->rodata) 39 + continue; 40 + 41 + if (strcmp(insn->sec->name, reloc->sym->sec->name)) 42 + continue; 43 + 39 44 orig_table = malloc(sizeof(struct table_info)); 40 45 if (!orig_table) { 41 46 WARN("malloc failed"); ··· 56 49 57 50 if (reloc_idx(reloc) + 1 == sec_num_entries(rsec)) 58 51 break; 52 + 53 + if (strcmp(insn->sec->name, (reloc + 1)->sym->sec->name)) { 54 + list_for_each_entry(orig_table, &table_list, jump_info) { 55 + if (orig_table->insn_offset == insn->offset) { 56 + is_valid_list = true; 57 + break; 58 + } 59 + } 60 + 61 + if (!is_valid_list) { 62 + list_del_init(&table_list); 63 + continue; 64 + } 65 + 66 + break; 67 + } 59 68 } 60 69 61 70 list_for_each_entry(orig_table, &table_list, jump_info) {