mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
LoongArch fixes for v6.17-rc3
-----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAminBwoWHGNoZW5odWFj YWlAa2VybmVsLm9yZwAKCRAChivD8uImemVYD/44F6KMPz2nUnS+5kIDs6Dpe4VI Lqz+QinoA4ZT/poY0Ui78UEz/XqHxKmcSnIg20wHVMtZ7XuWWuqj4VHzroa83okB YOyYdKg8oiRJR3LSi28uPIqJjQ/UPGLtKsjuO+UJS6fgKwRYVFShGgg6V7LIXSYe gbkeOFcom+VMCV2PE4xxhmvfCYvG3CbisUk7YqTYFbUe8Iic0xNTDZIRT+IImL0Z sRq2PMGOmKNV4HU4FfixXkCyppRxX/QLLYPFap1koWk0lwreB8gVXcSNTt4HhI/R 9hzySdJmTdn9HlWBvBn1LD24HBFs6zqliRftw8SwTZovw1garUFbpMqc8S7hE58L QMpV5h8BanUvoJo2X2iLvEsDycdvVPIE7voU+9JCMXyPrLy3KTbVehMY2lHY5YXu CMPL4nGvq1SXunrfUlxttgmVvuKKqeJ0Wp9NQ2hjOvVz2hmObRe5nugK0yBREV7b 0GeZ1M2N8hdmMNQ39BC7P53s3XzpV258BrXbUOSzct6nITeIHzzNj69O0+jKFN7d RKh6Qi0XxDuocNckmrmLPk5Wh0u/OPB3D1WHyndMmPgfVCGTxF7XLqmDTJnpdDiL JO0IUdBB59SbecjFLZs4QXVrNIocw8TzK0HNCAFjaeEeJABCDVFoo98CrJ+wT3pG dAcwd9Gpal6hb+l0Bg== =dUol -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
1c656b1efd
|
|
@ -102,7 +102,13 @@ KBUILD_CFLAGS += $(call cc-option,-mthin-add-sub) $(call cc-option,-Wa$(comma)
|
|||
|
||||
ifdef CONFIG_OBJTOOL
|
||||
ifdef CONFIG_CC_HAS_ANNOTATE_TABLEJUMP
|
||||
# The annotate-tablejump option can not be passed to LLVM backend when LTO is enabled.
|
||||
# Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' also needs to
|
||||
# be passed via '-mllvm' to ld.lld.
|
||||
KBUILD_CFLAGS += -mannotate-tablejump
|
||||
ifdef CONFIG_LTO_CLANG
|
||||
KBUILD_LDFLAGS += -mllvm --loongarch-annotate-tablejump
|
||||
endif
|
||||
else
|
||||
KBUILD_CFLAGS += -fno-jump-tables # keep compatibility with older compilers
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
.endm
|
||||
|
||||
.macro STACKLEAK_ERASE
|
||||
#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
|
||||
#ifdef CONFIG_KSTACK_ERASE
|
||||
bl stackleak_erase_on_task_stack
|
||||
#endif
|
||||
.endm
|
||||
|
|
|
|||
8
arch/loongarch/include/uapi/asm/setup.h
Normal file
8
arch/loongarch/include/uapi/asm/setup.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
|
||||
#ifndef _UAPI_ASM_LOONGARCH_SETUP_H
|
||||
#define _UAPI_ASM_LOONGARCH_SETUP_H
|
||||
|
||||
#define COMMAND_LINE_SIZE 4096
|
||||
|
||||
#endif /* _UAPI_ASM_LOONGARCH_SETUP_H */
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val)
|
||||
{
|
||||
|
|
@ -61,39 +62,38 @@ Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr v
|
|||
return (Elf_Addr)&plt[nr];
|
||||
}
|
||||
|
||||
static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y)
|
||||
#define cmp_3way(a, b) ((a) < (b) ? -1 : (a) > (b))
|
||||
|
||||
static int compare_rela(const void *x, const void *y)
|
||||
{
|
||||
return x->r_info == y->r_info && x->r_addend == y->r_addend;
|
||||
}
|
||||
int ret;
|
||||
const Elf_Rela *rela_x = x, *rela_y = y;
|
||||
|
||||
static bool duplicate_rela(const Elf_Rela *rela, int idx)
|
||||
{
|
||||
int i;
|
||||
ret = cmp_3way(rela_x->r_info, rela_y->r_info);
|
||||
if (ret == 0)
|
||||
ret = cmp_3way(rela_x->r_addend, rela_y->r_addend);
|
||||
|
||||
for (i = 0; i < idx; i++) {
|
||||
if (is_rela_equal(&rela[i], &rela[idx]))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void count_max_entries(Elf_Rela *relas, int num,
|
||||
unsigned int *plts, unsigned int *gots)
|
||||
{
|
||||
unsigned int i, type;
|
||||
unsigned int i;
|
||||
|
||||
sort(relas, num, sizeof(Elf_Rela), compare_rela, NULL);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
type = ELF_R_TYPE(relas[i].r_info);
|
||||
switch (type) {
|
||||
if (i && !compare_rela(&relas[i-1], &relas[i]))
|
||||
continue;
|
||||
|
||||
switch (ELF_R_TYPE(relas[i].r_info)) {
|
||||
case R_LARCH_SOP_PUSH_PLT_PCREL:
|
||||
case R_LARCH_B26:
|
||||
if (!duplicate_rela(relas, i))
|
||||
(*plts)++;
|
||||
(*plts)++;
|
||||
break;
|
||||
case R_LARCH_GOT_PC_HI20:
|
||||
if (!duplicate_rela(relas, i))
|
||||
(*gots)++;
|
||||
(*gots)++;
|
||||
break;
|
||||
default:
|
||||
break; /* Do nothing. */
|
||||
|
|
|
|||
|
|
@ -677,6 +677,11 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
|||
for (i = 1; i < 32; i++)
|
||||
err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
if (extctx->lbt.addr)
|
||||
err |= protected_save_lbt_context(extctx);
|
||||
#endif
|
||||
|
||||
if (extctx->lasx.addr)
|
||||
err |= protected_save_lasx_context(extctx);
|
||||
else if (extctx->lsx.addr)
|
||||
|
|
@ -684,11 +689,6 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
|||
else if (extctx->fpu.addr)
|
||||
err |= protected_save_fpu_context(extctx);
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
if (extctx->lbt.addr)
|
||||
err |= protected_save_lbt_context(extctx);
|
||||
#endif
|
||||
|
||||
/* Set the "end" magic */
|
||||
info = (struct sctx_info *)extctx->end.addr;
|
||||
err |= __put_user(0, &info->magic);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -102,6 +103,23 @@ static int constant_timer_next_event(unsigned long delta, struct clock_event_dev
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int arch_timer_starting(unsigned int cpu)
|
||||
{
|
||||
set_csr_ecfg(ECFGF_TIMER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_timer_dying(unsigned int cpu)
|
||||
{
|
||||
constant_set_state_shutdown(this_cpu_ptr(&constant_clockevent_device));
|
||||
|
||||
/* Clear Timer Interrupt */
|
||||
write_csr_tintclear(CSR_TINTCLR_TI);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long get_loops_per_jiffy(void)
|
||||
{
|
||||
unsigned long lpj = (unsigned long)const_clock_freq;
|
||||
|
|
@ -172,6 +190,10 @@ int constant_clockevent_init(void)
|
|||
lpj_fine = get_loops_per_jiffy();
|
||||
pr_info("Constant clock event device register\n");
|
||||
|
||||
cpuhp_setup_state(CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING,
|
||||
"clockevents/loongarch/timer:starting",
|
||||
arch_timer_starting, arch_timer_dying);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,12 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
|
|||
}
|
||||
|
||||
cpu = s->sw_coremap[irq];
|
||||
vcpu = kvm_get_vcpu(s->kvm, cpu);
|
||||
vcpu = kvm_get_vcpu_by_id(s->kvm, cpu);
|
||||
if (unlikely(vcpu == NULL)) {
|
||||
kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
if (level) {
|
||||
/* if not enable return false */
|
||||
if (!test_bit(irq, (unsigned long *)s->enable.reg_u32))
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ static void write_mailbox(struct kvm_vcpu *vcpu, int offset, uint64_t data, int
|
|||
static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
|
||||
{
|
||||
int i, idx, ret;
|
||||
uint32_t val = 0, mask = 0;
|
||||
uint64_t val = 0, mask = 0;
|
||||
|
||||
/*
|
||||
* Bit 27-30 is mask for byte writing.
|
||||
|
|
@ -108,7 +108,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
|
|||
if ((data >> 27) & 0xf) {
|
||||
/* Read the old val */
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val);
|
||||
ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
if (unlikely(ret)) {
|
||||
kvm_err("%s: : read data from addr %llx failed\n", __func__, addr);
|
||||
|
|
@ -124,7 +124,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
|
|||
}
|
||||
val |= ((uint32_t)(data >> 32) & ~mask);
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val);
|
||||
ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
if (unlikely(ret))
|
||||
kvm_err("%s: : write data to addr %llx failed\n", __func__, addr);
|
||||
|
|
@ -298,7 +298,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,
|
|||
cpu = (attr->attr >> 16) & 0x3ff;
|
||||
addr = attr->attr & 0xff;
|
||||
|
||||
vcpu = kvm_get_vcpu(dev->kvm, cpu);
|
||||
vcpu = kvm_get_vcpu_by_id(dev->kvm, cpu);
|
||||
if (unlikely(vcpu == NULL)) {
|
||||
kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -195,6 +195,11 @@ static int kvm_pch_pic_read(struct kvm_vcpu *vcpu,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (addr & (len - 1)) {
|
||||
kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* statistics of pch pic reading */
|
||||
vcpu->stat.pch_pic_read_exits++;
|
||||
ret = loongarch_pch_pic_read(s, addr, len, val);
|
||||
|
|
@ -302,6 +307,11 @@ static int kvm_pch_pic_write(struct kvm_vcpu *vcpu,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (addr & (len - 1)) {
|
||||
kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* statistics of pch pic writing */
|
||||
vcpu->stat.pch_pic_write_exits++;
|
||||
ret = loongarch_pch_pic_write(s, addr, len, val);
|
||||
|
|
|
|||
|
|
@ -1283,9 +1283,11 @@ int kvm_own_lbt(struct kvm_vcpu *vcpu)
|
|||
return -EINVAL;
|
||||
|
||||
preempt_disable();
|
||||
set_csr_euen(CSR_EUEN_LBTEN);
|
||||
_restore_lbt(&vcpu->arch.lbt);
|
||||
vcpu->arch.aux_inuse |= KVM_LARCH_LBT;
|
||||
if (!(vcpu->arch.aux_inuse & KVM_LARCH_LBT)) {
|
||||
set_csr_euen(CSR_EUEN_LBTEN);
|
||||
_restore_lbt(&vcpu->arch.lbt);
|
||||
vcpu->arch.aux_inuse |= KVM_LARCH_LBT;
|
||||
}
|
||||
preempt_enable();
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ enum cpuhp_state {
|
|||
CPUHP_AP_QCOM_TIMER_STARTING,
|
||||
CPUHP_AP_TEGRA_TIMER_STARTING,
|
||||
CPUHP_AP_ARMADA_TIMER_STARTING,
|
||||
CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING,
|
||||
CPUHP_AP_MIPS_GIC_TIMER_STARTING,
|
||||
CPUHP_AP_ARC_TIMER_STARTING,
|
||||
CPUHP_AP_REALTEK_TIMER_STARTING,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,
|
|||
struct table_info *next_table;
|
||||
unsigned long tmp_insn_offset;
|
||||
unsigned long tmp_rodata_offset;
|
||||
bool is_valid_list = false;
|
||||
|
||||
rsec = find_section_by_name(file->elf, ".rela.discard.tablejump_annotate");
|
||||
if (!rsec)
|
||||
|
|
@ -35,6 +36,12 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,
|
|||
INIT_LIST_HEAD(&table_list);
|
||||
|
||||
for_each_reloc(rsec, reloc) {
|
||||
if (reloc->sym->sec->rodata)
|
||||
continue;
|
||||
|
||||
if (strcmp(insn->sec->name, reloc->sym->sec->name))
|
||||
continue;
|
||||
|
||||
orig_table = malloc(sizeof(struct table_info));
|
||||
if (!orig_table) {
|
||||
WARN("malloc failed");
|
||||
|
|
@ -49,6 +56,22 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,
|
|||
|
||||
if (reloc_idx(reloc) + 1 == sec_num_entries(rsec))
|
||||
break;
|
||||
|
||||
if (strcmp(insn->sec->name, (reloc + 1)->sym->sec->name)) {
|
||||
list_for_each_entry(orig_table, &table_list, jump_info) {
|
||||
if (orig_table->insn_offset == insn->offset) {
|
||||
is_valid_list = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_valid_list) {
|
||||
list_del_init(&table_list);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(orig_table, &table_list, jump_info) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user