Commit 2e51e0ac authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'loongarch-fixes-6.14-2' of...

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

Pull LoongArch fixes from Huacai Chen:
 "Fix bugs in kernel build, hibernation, memory management and KVM"

* tag 'loongarch-fixes-6.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  LoongArch: KVM: Fix GPA size issue about VM
  LoongArch: KVM: Reload guest CSR registers after sleep
  LoongArch: KVM: Add interrupt checking for AVEC
  LoongArch: Set hugetlb mmap base address aligned with pmd size
  LoongArch: Set max_pfn with the PFN of the last page
  LoongArch: Use polling play_dead() when resuming from hibernation
  LoongArch: Eliminate superfluous get_numa_distances_cnt()
  LoongArch: Convert unreachable() to BUG()
parents 2a520073 6bdbb73d
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -249,18 +249,6 @@ static __init int setup_node(int pxm)
	return acpi_map_pxm_to_node(pxm);
}

/*
 * Callback for SLIT parsing.  pxm_to_node() returns NUMA_NO_NODE for
 * I/O localities since SRAT does not list them.  I/O localities are
 * not supported at this point.
 */
unsigned int numa_distance_cnt;

static inline unsigned int get_numa_distances_cnt(struct acpi_table_slit *slit)
{
	return slit->locality_count;
}

void __init numa_set_distance(int from, int to, int distance)
{
	if ((u8)distance != distance || (from == to && distance != LOCAL_DISTANCE)) {
+2 −2
Original line number Diff line number Diff line
@@ -126,14 +126,14 @@ void kexec_reboot(void)
	/* All secondary cpus go to kexec_smp_wait */
	if (smp_processor_id() > 0) {
		relocated_kexec_smp_wait(NULL);
		unreachable();
		BUG();
	}
#endif

	do_kexec = (void *)reboot_code_buffer;
	do_kexec(efi_boot, cmdline_ptr, systable_ptr, start_addr, first_ind_entry);

	unreachable();
	BUG();
}


+3 −0
Original line number Diff line number Diff line
@@ -387,6 +387,9 @@ static void __init check_kernel_sections_mem(void)
 */
static void __init arch_mem_init(char **cmdline_p)
{
	/* Recalculate max_low_pfn for "mem=xxx" */
	max_pfn = max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());

	if (usermem)
		pr_info("User-defined physical RAM map overwrite\n");

+46 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/smp.h>
#include <linux/threads.h>
#include <linux/export.h>
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/time.h>
#include <linux/tracepoint.h>
@@ -423,7 +424,7 @@ void loongson_cpu_die(unsigned int cpu)
	mb();
}

void __noreturn arch_cpu_idle_dead(void)
static void __noreturn idle_play_dead(void)
{
	register uint64_t addr;
	register void (*init_fn)(void);
@@ -447,6 +448,50 @@ void __noreturn arch_cpu_idle_dead(void)
	BUG();
}

#ifdef CONFIG_HIBERNATION
static void __noreturn poll_play_dead(void)
{
	register uint64_t addr;
	register void (*init_fn)(void);

	idle_task_exit();
	__this_cpu_write(cpu_state, CPU_DEAD);

	__smp_mb();
	do {
		__asm__ __volatile__("nop\n\t");
		addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0);
	} while (addr == 0);

	init_fn = (void *)TO_CACHE(addr);
	iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR);

	init_fn();
	BUG();
}
#endif

static void (*play_dead)(void) = idle_play_dead;

void __noreturn arch_cpu_idle_dead(void)
{
	play_dead();
	BUG(); /* play_dead() doesn't return */
}

#ifdef CONFIG_HIBERNATION
int hibernate_resume_nonboot_cpu_disable(void)
{
	int ret;

	play_dead = poll_play_dead;
	ret = suspend_disable_secondary_cpus();
	play_dead = idle_play_dead;

	return ret;
}
#endif

#endif

/*
+6 −0
Original line number Diff line number Diff line
@@ -669,6 +669,12 @@ static int kvm_handle_rdwr_fault(struct kvm_vcpu *vcpu, bool write)
	struct kvm_run *run = vcpu->run;
	unsigned long badv = vcpu->arch.badv;

	/* Inject ADE exception if exceed max GPA size */
	if (unlikely(badv >= vcpu->kvm->arch.gpa_size)) {
		kvm_queue_exception(vcpu, EXCCODE_ADE, EXSUBCODE_ADEM);
		return RESUME_GUEST;
	}

	ret = kvm_handle_mm_fault(vcpu, badv, write);
	if (ret) {
		/* Treat as MMIO */
Loading