Skip to content

Commit 39879e3

Browse files
committed
Merge tag 'loongarch-fixes-6.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch fixes from Huacai Chen: "Fix some build warnings for RUST-enabled objtool check, align ACPI structures for ARCH_STRICT_ALIGN, fix an unreliable stack for live patching, add some NULL pointer checkings, and fix some bugs around KVM" * tag 'loongarch-fixes-6.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: LoongArch: KVM: Avoid copy_*_user() with lock hold in kvm_pch_pic_regs_access() LoongArch: KVM: Avoid copy_*_user() with lock hold in kvm_eiointc_sw_status_access() LoongArch: KVM: Avoid copy_*_user() with lock hold in kvm_eiointc_regs_access() LoongArch: KVM: Avoid copy_*_user() with lock hold in kvm_eiointc_ctrl_access() LoongArch: KVM: Fix VM migration failure with PTW enabled LoongArch: KVM: Remove unused returns and semicolons LoongArch: vDSO: Check kcalloc() result in init_vdso() LoongArch: Fix unreliable stack for live patching LoongArch: Replace sprintf() with sysfs_emit() LoongArch: Check the return value when creating kobj LoongArch: Align ACPI structures if ARCH_STRICT_ALIGN enabled LoongArch: Update help info of ARCH_STRICT_ALIGN LoongArch: Handle jump tables options for RUST LoongArch: Make LTO case independent in Makefile objtool/LoongArch: Mark special atomic instruction as INSN_BUG type objtool/LoongArch: Mark types based on break immediate code
2 parents dcf7d9e + 8dc5245 commit 39879e3

13 files changed

Lines changed: 162 additions & 69 deletions

File tree

arch/loongarch/Kconfig

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,10 @@ config AS_HAS_LVZ_EXTENSION
298298
config CC_HAS_ANNOTATE_TABLEJUMP
299299
def_bool $(cc-option,-mannotate-tablejump)
300300

301+
config RUSTC_HAS_ANNOTATE_TABLEJUMP
302+
depends on RUST
303+
def_bool $(rustc-option,-Cllvm-args=--loongarch-annotate-tablejump)
304+
301305
menu "Kernel type and options"
302306

303307
source "kernel/Kconfig.hz"
@@ -563,10 +567,14 @@ config ARCH_STRICT_ALIGN
563567
-mstrict-align build parameter to prevent unaligned accesses.
564568

565569
CPUs with h/w unaligned access support:
566-
Loongson-2K2000/2K3000/3A5000/3C5000/3D5000.
570+
Loongson-2K2000/2K3000 and all of Loongson-3 series processors
571+
based on LoongArch.
567572

568573
CPUs without h/w unaligned access support:
569-
Loongson-2K500/2K1000.
574+
Loongson-2K0300/2K0500/2K1000.
575+
576+
If you want to make sure whether to support unaligned memory access
577+
on your hardware, please read the bit 20 (UAL) of CPUCFG1 register.
570578

571579
This option is enabled by default to make the kernel be able to run
572580
on all LoongArch systems. But you can disable it manually if you want

arch/loongarch/Makefile

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,21 @@ KBUILD_CFLAGS += $(call cc-option,-mthin-add-sub) $(call cc-option,-Wa$(comma)
102102

103103
ifdef CONFIG_OBJTOOL
104104
ifdef CONFIG_CC_HAS_ANNOTATE_TABLEJUMP
105+
KBUILD_CFLAGS += -mannotate-tablejump
106+
else
107+
KBUILD_CFLAGS += -fno-jump-tables # keep compatibility with older compilers
108+
endif
109+
ifdef CONFIG_RUSTC_HAS_ANNOTATE_TABLEJUMP
110+
KBUILD_RUSTFLAGS += -Cllvm-args=--loongarch-annotate-tablejump
111+
else
112+
KBUILD_RUSTFLAGS += -Zno-jump-tables # keep compatibility with older compilers
113+
endif
114+
ifdef CONFIG_LTO_CLANG
105115
# The annotate-tablejump option can not be passed to LLVM backend when LTO is enabled.
106116
# Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' also needs to
107117
# be passed via '-mllvm' to ld.lld.
108-
KBUILD_CFLAGS += -mannotate-tablejump
109-
ifdef CONFIG_LTO_CLANG
110118
KBUILD_LDFLAGS += -mllvm --loongarch-annotate-tablejump
111119
endif
112-
else
113-
KBUILD_CFLAGS += -fno-jump-tables # keep compatibility with older compilers
114-
endif
115120
endif
116121

117122
KBUILD_RUSTFLAGS += --target=loongarch64-unknown-none-softfloat -Ccode-model=small

arch/loongarch/include/asm/acenv.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010
#ifndef _ASM_LOONGARCH_ACENV_H
1111
#define _ASM_LOONGARCH_ACENV_H
1212

13-
/*
14-
* This header is required by ACPI core, but we have nothing to fill in
15-
* right now. Will be updated later when needed.
16-
*/
13+
#ifdef CONFIG_ARCH_STRICT_ALIGN
14+
#define ACPI_MISALIGNMENT_NOT_SUPPORTED
15+
#endif /* CONFIG_ARCH_STRICT_ALIGN */
1716

1817
#endif /* _ASM_LOONGARCH_ACENV_H */

arch/loongarch/include/asm/kvm_mmu.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
*/
1717
#define KVM_MMU_CACHE_MIN_PAGES (CONFIG_PGTABLE_LEVELS - 1)
1818

19+
/*
20+
* _PAGE_MODIFIED is a SW pte bit, it records page ever written on host
21+
* kernel, on secondary MMU it records the page writeable attribute, in
22+
* order for fast path handling.
23+
*/
24+
#define KVM_PAGE_WRITEABLE _PAGE_MODIFIED
25+
1926
#define _KVM_FLUSH_PGTABLE 0x1
2027
#define _KVM_HAS_PGMASK 0x2
2128
#define kvm_pfn_pte(pfn, prot) (((pfn) << PFN_PTE_SHIFT) | pgprot_val(prot))
@@ -52,10 +59,10 @@ static inline void kvm_set_pte(kvm_pte_t *ptep, kvm_pte_t val)
5259
WRITE_ONCE(*ptep, val);
5360
}
5461

55-
static inline int kvm_pte_write(kvm_pte_t pte) { return pte & _PAGE_WRITE; }
56-
static inline int kvm_pte_dirty(kvm_pte_t pte) { return pte & _PAGE_DIRTY; }
5762
static inline int kvm_pte_young(kvm_pte_t pte) { return pte & _PAGE_ACCESSED; }
5863
static inline int kvm_pte_huge(kvm_pte_t pte) { return pte & _PAGE_HUGE; }
64+
static inline int kvm_pte_dirty(kvm_pte_t pte) { return pte & __WRITEABLE; }
65+
static inline int kvm_pte_writeable(kvm_pte_t pte) { return pte & KVM_PAGE_WRITEABLE; }
5966

6067
static inline kvm_pte_t kvm_pte_mkyoung(kvm_pte_t pte)
6168
{
@@ -69,12 +76,12 @@ static inline kvm_pte_t kvm_pte_mkold(kvm_pte_t pte)
6976

7077
static inline kvm_pte_t kvm_pte_mkdirty(kvm_pte_t pte)
7178
{
72-
return pte | _PAGE_DIRTY;
79+
return pte | __WRITEABLE;
7380
}
7481

7582
static inline kvm_pte_t kvm_pte_mkclean(kvm_pte_t pte)
7683
{
77-
return pte & ~_PAGE_DIRTY;
84+
return pte & ~__WRITEABLE;
7885
}
7986

8087
static inline kvm_pte_t kvm_pte_mkhuge(kvm_pte_t pte)
@@ -87,6 +94,11 @@ static inline kvm_pte_t kvm_pte_mksmall(kvm_pte_t pte)
8794
return pte & ~_PAGE_HUGE;
8895
}
8996

97+
static inline kvm_pte_t kvm_pte_mkwriteable(kvm_pte_t pte)
98+
{
99+
return pte | KVM_PAGE_WRITEABLE;
100+
}
101+
90102
static inline int kvm_need_flush(kvm_ptw_ctx *ctx)
91103
{
92104
return ctx->flag & _KVM_FLUSH_PGTABLE;

arch/loongarch/kernel/env.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ late_initcall(fdt_cpu_clk_init);
8686
static ssize_t boardinfo_show(struct kobject *kobj,
8787
struct kobj_attribute *attr, char *buf)
8888
{
89-
return sprintf(buf,
89+
return sysfs_emit(buf,
9090
"BIOS Information\n"
9191
"Vendor\t\t\t: %s\n"
9292
"Version\t\t\t: %s\n"
@@ -109,6 +109,8 @@ static int __init boardinfo_init(void)
109109
struct kobject *loongson_kobj;
110110

111111
loongson_kobj = kobject_create_and_add("loongson", firmware_kobj);
112+
if (!loongson_kobj)
113+
return -ENOMEM;
112114

113115
return sysfs_create_file(loongson_kobj, &boardinfo_attr.attr);
114116
}

arch/loongarch/kernel/stacktrace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
5151
if (task == current) {
5252
regs->regs[3] = (unsigned long)__builtin_frame_address(0);
5353
regs->csr_era = (unsigned long)__builtin_return_address(0);
54+
regs->regs[22] = 0;
5455
} else {
5556
regs->regs[3] = thread_saved_fp(task);
5657
regs->csr_era = thread_saved_ra(task);
58+
regs->regs[22] = task->thread.reg22;
5759
}
5860
regs->regs[1] = 0;
59-
regs->regs[22] = 0;
6061

6162
for (unwind_start(&state, task, regs);
6263
!unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {

arch/loongarch/kernel/vdso.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ static int __init init_vdso(void)
5454
vdso_info.code_mapping.pages =
5555
kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL);
5656

57+
if (!vdso_info.code_mapping.pages)
58+
return -ENOMEM;
59+
5760
pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso));
5861
for (i = 0; i < vdso_info.size / PAGE_SIZE; i++)
5962
vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i);

arch/loongarch/kvm/exit.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -778,10 +778,8 @@ static long kvm_save_notify(struct kvm_vcpu *vcpu)
778778
return 0;
779779
default:
780780
return KVM_HCALL_INVALID_CODE;
781-
};
782-
783-
return KVM_HCALL_INVALID_CODE;
784-
};
781+
}
782+
}
785783

786784
/*
787785
* kvm_handle_lsx_disabled() - Guest used LSX while disabled in root.

arch/loongarch/kvm/intc/eiointc.c

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -426,21 +426,26 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
426426
struct loongarch_eiointc *s = dev->kvm->arch.eiointc;
427427

428428
data = (void __user *)attr->addr;
429-
spin_lock_irqsave(&s->lock, flags);
430429
switch (type) {
431430
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
431+
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE:
432432
if (copy_from_user(&val, data, 4))
433-
ret = -EFAULT;
434-
else {
435-
if (val >= EIOINTC_ROUTE_MAX_VCPUS)
436-
ret = -EINVAL;
437-
else
438-
s->num_cpu = val;
439-
}
433+
return -EFAULT;
434+
break;
435+
default:
436+
break;
437+
}
438+
439+
spin_lock_irqsave(&s->lock, flags);
440+
switch (type) {
441+
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
442+
if (val >= EIOINTC_ROUTE_MAX_VCPUS)
443+
ret = -EINVAL;
444+
else
445+
s->num_cpu = val;
440446
break;
441447
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE:
442-
if (copy_from_user(&s->features, data, 4))
443-
ret = -EFAULT;
448+
s->features = val;
444449
if (!(s->features & BIT(EIOINTC_HAS_VIRT_EXTENSION)))
445450
s->status |= BIT(EIOINTC_ENABLE);
446451
break;
@@ -462,19 +467,17 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
462467

463468
static int kvm_eiointc_regs_access(struct kvm_device *dev,
464469
struct kvm_device_attr *attr,
465-
bool is_write)
470+
bool is_write, int *data)
466471
{
467472
int addr, cpu, offset, ret = 0;
468473
unsigned long flags;
469474
void *p = NULL;
470-
void __user *data;
471475
struct loongarch_eiointc *s;
472476

473477
s = dev->kvm->arch.eiointc;
474478
addr = attr->attr;
475479
cpu = addr >> 16;
476480
addr &= 0xffff;
477-
data = (void __user *)attr->addr;
478481
switch (addr) {
479482
case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
480483
offset = (addr - EIOINTC_NODETYPE_START) / 4;
@@ -513,33 +516,28 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
513516
}
514517

515518
spin_lock_irqsave(&s->lock, flags);
516-
if (is_write) {
517-
if (copy_from_user(p, data, 4))
518-
ret = -EFAULT;
519-
} else {
520-
if (copy_to_user(data, p, 4))
521-
ret = -EFAULT;
522-
}
519+
if (is_write)
520+
memcpy(p, data, 4);
521+
else
522+
memcpy(data, p, 4);
523523
spin_unlock_irqrestore(&s->lock, flags);
524524

525525
return ret;
526526
}
527527

528528
static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
529529
struct kvm_device_attr *attr,
530-
bool is_write)
530+
bool is_write, int *data)
531531
{
532532
int addr, ret = 0;
533533
unsigned long flags;
534534
void *p = NULL;
535-
void __user *data;
536535
struct loongarch_eiointc *s;
537536

538537
s = dev->kvm->arch.eiointc;
539538
addr = attr->attr;
540539
addr &= 0xffff;
541540

542-
data = (void __user *)attr->addr;
543541
switch (addr) {
544542
case KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU:
545543
if (is_write)
@@ -561,13 +559,10 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
561559
return -EINVAL;
562560
}
563561
spin_lock_irqsave(&s->lock, flags);
564-
if (is_write) {
565-
if (copy_from_user(p, data, 4))
566-
ret = -EFAULT;
567-
} else {
568-
if (copy_to_user(data, p, 4))
569-
ret = -EFAULT;
570-
}
562+
if (is_write)
563+
memcpy(p, data, 4);
564+
else
565+
memcpy(data, p, 4);
571566
spin_unlock_irqrestore(&s->lock, flags);
572567

573568
return ret;
@@ -576,11 +571,27 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
576571
static int kvm_eiointc_get_attr(struct kvm_device *dev,
577572
struct kvm_device_attr *attr)
578573
{
574+
int ret, data;
575+
579576
switch (attr->group) {
580577
case KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS:
581-
return kvm_eiointc_regs_access(dev, attr, false);
578+
ret = kvm_eiointc_regs_access(dev, attr, false, &data);
579+
if (ret)
580+
return ret;
581+
582+
if (copy_to_user((void __user *)attr->addr, &data, 4))
583+
ret = -EFAULT;
584+
585+
return ret;
582586
case KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS:
583-
return kvm_eiointc_sw_status_access(dev, attr, false);
587+
ret = kvm_eiointc_sw_status_access(dev, attr, false, &data);
588+
if (ret)
589+
return ret;
590+
591+
if (copy_to_user((void __user *)attr->addr, &data, 4))
592+
ret = -EFAULT;
593+
594+
return ret;
584595
default:
585596
return -EINVAL;
586597
}
@@ -589,13 +600,21 @@ static int kvm_eiointc_get_attr(struct kvm_device *dev,
589600
static int kvm_eiointc_set_attr(struct kvm_device *dev,
590601
struct kvm_device_attr *attr)
591602
{
603+
int data;
604+
592605
switch (attr->group) {
593606
case KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL:
594607
return kvm_eiointc_ctrl_access(dev, attr);
595608
case KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS:
596-
return kvm_eiointc_regs_access(dev, attr, true);
609+
if (copy_from_user(&data, (void __user *)attr->addr, 4))
610+
return -EFAULT;
611+
612+
return kvm_eiointc_regs_access(dev, attr, true, &data);
597613
case KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS:
598-
return kvm_eiointc_sw_status_access(dev, attr, true);
614+
if (copy_from_user(&data, (void __user *)attr->addr, 4))
615+
return -EFAULT;
616+
617+
return kvm_eiointc_sw_status_access(dev, attr, true, &data);
599618
default:
600619
return -EINVAL;
601620
}

arch/loongarch/kvm/intc/pch_pic.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ static int kvm_pch_pic_regs_access(struct kvm_device *dev,
348348
struct kvm_device_attr *attr,
349349
bool is_write)
350350
{
351+
char buf[8];
351352
int addr, offset, len = 8, ret = 0;
352353
void __user *data;
353354
void *p = NULL;
@@ -397,17 +398,23 @@ static int kvm_pch_pic_regs_access(struct kvm_device *dev,
397398
return -EINVAL;
398399
}
399400

400-
spin_lock(&s->lock);
401-
/* write or read value according to is_write */
402401
if (is_write) {
403-
if (copy_from_user(p, data, len))
404-
ret = -EFAULT;
405-
} else {
406-
if (copy_to_user(data, p, len))
407-
ret = -EFAULT;
402+
if (copy_from_user(buf, data, len))
403+
return -EFAULT;
408404
}
405+
406+
spin_lock(&s->lock);
407+
if (is_write)
408+
memcpy(p, buf, len);
409+
else
410+
memcpy(buf, p, len);
409411
spin_unlock(&s->lock);
410412

413+
if (!is_write) {
414+
if (copy_to_user(data, buf, len))
415+
return -EFAULT;
416+
}
417+
411418
return ret;
412419
}
413420

0 commit comments

Comments
 (0)