Commit efa0adb5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'loongarch-fixes-7.0-1' of...

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

Pull LoongArch fixes from Huacai Chen:

 - only use SC.Q when supported by the assembler to fix a build failure

 - fix calling smp_processor_id() in preemptible code

 - make a BPF helper arch_protect_bpf_trampoline() return 0 to fix a
   kernel memory access failure

 - fix a typo issue in kvm_vm_init_features()

* tag 'loongarch-fixes-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  LoongArch: KVM: Fix typo issue in kvm_vm_init_features()
  LoongArch: BPF: Make arch_protect_bpf_trampoline() return 0
  LoongArch: No need to flush icache if text copy failed
  LoongArch: Check return values for set_memory_{rw,rox}
  LoongArch: Give more information if kmem access failed
  LoongArch: Fix calling smp_processor_id() in preemptible code
  LoongArch: Only use SC.Q when supported by the assembler
parents a989fde7 c252c12d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -304,6 +304,9 @@ config AS_HAS_LBT_EXTENSION
config AS_HAS_LVZ_EXTENSION
	def_bool $(as-instr,hvcl 0)

config AS_HAS_SCQ_EXTENSION
	def_bool $(as-instr,sc.q \$t0$(comma)\$t1$(comma)\$t2)

config CC_HAS_ANNOTATE_TABLEJUMP
	def_bool $(cc-option,-mannotate-tablejump)

+5 −0
Original line number Diff line number Diff line
@@ -238,6 +238,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, unsigned int
	arch_cmpxchg((ptr), (o), (n));					\
  })

#ifdef CONFIG_AS_HAS_SCQ_EXTENSION

union __u128_halves {
	u128 full;
	struct {
@@ -290,6 +292,9 @@ union __u128_halves {
	BUILD_BUG_ON(sizeof(*(ptr)) != 16);				\
	__arch_cmpxchg128(ptr, o, n, "");				\
})

#endif /* CONFIG_AS_HAS_SCQ_EXTENSION */

#else
#include <asm-generic/cmpxchg-local.h>
#define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
+12 −2
Original line number Diff line number Diff line
@@ -253,8 +253,13 @@ do { \
									\
	__get_kernel_common(*((type *)(dst)), sizeof(type),		\
			    (__force type *)(src));			\
	if (unlikely(__gu_err))						\
	if (unlikely(__gu_err))	{					\
		pr_info("%s: memory access failed, ecode 0x%x\n",	\
			__func__, read_csr_excode());			\
		pr_info("%s: the caller is %pS\n",			\
			__func__, __builtin_return_address(0));		\
		goto err_label;						\
	}								\
} while (0)

#define __put_kernel_nofault(dst, src, type, err_label)			\
@@ -264,8 +269,13 @@ do { \
									\
	__pu_val = *(__force type *)(src);				\
	__put_kernel_common(((type *)(dst)), sizeof(type));		\
	if (unlikely(__pu_err))						\
	if (unlikely(__pu_err))	{					\
		pr_info("%s: memory access failed, ecode 0x%x\n",	\
			__func__, read_csr_excode());			\
		pr_info("%s: the caller is %pS\n",			\
			__func__, __builtin_return_address(0));		\
		goto err_label;						\
	}								\
} while (0)

extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
+25 −6
Original line number Diff line number Diff line
@@ -246,32 +246,51 @@ static int text_copy_cb(void *data)

	if (smp_processor_id() == copy->cpu) {
		ret = copy_to_kernel_nofault(copy->dst, copy->src, copy->len);
		if (ret)
		if (ret) {
			pr_err("%s: operation failed\n", __func__);
			return ret;
		}
	}

	flush_icache_range((unsigned long)copy->dst, (unsigned long)copy->dst + copy->len);

	return ret;
	return 0;
}

int larch_insn_text_copy(void *dst, void *src, size_t len)
{
	int ret = 0;
	int err = 0;
	size_t start, end;
	struct insn_copy copy = {
		.dst = dst,
		.src = src,
		.len = len,
		.cpu = smp_processor_id(),
		.cpu = raw_smp_processor_id(),
	};

	/*
	 * Ensure copy.cpu won't be hot removed before stop_machine.
	 * If it is removed nobody will really update the text.
	 */
	lockdep_assert_cpus_held();

	start = round_down((size_t)dst, PAGE_SIZE);
	end   = round_up((size_t)dst + len, PAGE_SIZE);

	set_memory_rw(start, (end - start) / PAGE_SIZE);
	ret = stop_machine(text_copy_cb, &copy, cpu_online_mask);
	set_memory_rox(start, (end - start) / PAGE_SIZE);
	err = set_memory_rw(start, (end - start) / PAGE_SIZE);
	if (err) {
		pr_info("%s: set_memory_rw() failed\n", __func__);
		return err;
	}

	ret = stop_machine_cpuslocked(text_copy_cb, &copy, cpu_online_mask);

	err = set_memory_rox(start, (end - start) / PAGE_SIZE);
	if (err) {
		pr_info("%s: set_memory_rox() failed\n", __func__);
		return err;
	}

	return ret;
}
+2 −2
Original line number Diff line number Diff line
@@ -49,8 +49,8 @@ static void kvm_vm_init_features(struct kvm *kvm)
		kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PMU);

	/* Enable all PV features by default */
	kvm->arch.pv_features = BIT(KVM_FEATURE_IPI);
	kvm->arch.kvm_features = BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI);
	kvm->arch.pv_features |= BIT(KVM_FEATURE_IPI);
	kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI);
	if (kvm_pvtime_supported()) {
		kvm->arch.pv_features |= BIT(KVM_FEATURE_PREEMPT);
		kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
Loading