forked from mirrors/linux
LoongArch fixes for v6.14-rc6
-----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmfL36wWHGNoZW5odWFj YWlAa2VybmVsLm9yZwAKCRAChivD8uImevvSD/9FvNZe83pHebd06msLvIiduYs/ ioXT32g/Wc9t05YRIi4UkmmwpkBM2uHE2JbgZF76HS/2auU6AkUQHuA41mIv4FJQ cfD4PydQuvNgLtbuVMZTPww6jEAHlH44YRPcSjqaqKlMhTMr1YtDJjoMv9hmsEZa C2ysYa5nZASpLTktYxsJowu3sjlmiTMTeWnm3kR0C+mvk4iPufBix0PCyuhJ3Qnu 4Z/vBAdQgtSkCLFkVKC3DREZWp5nTyW/zmGbtUCayja46RcBoXvEMjd4SVhYBEHu 8ST/bmtWolKQ8GwDbV8Ewu7p+SQctbTWo4fxLXtaf9jcs2xU/nmrID8gPjmQsbwa gzrmHwXd3oElurnNEgvtQaCSoxFZDlB9V/Tuq6tK5TtY+OOsIHDe6PnHhYWf+2D+ W1uCqOyik1JCznd76MqIZZL8GAf2hW6JYAjdpSFPOXXoHSc0FyDjRNd6Nt11rFqB tMCstPLlK/uaZ/cCyCxaur862j8x+fXXvZOho2Fd9BOyj246qIA57hMinPcmzdov dCgeexUFn5lerUbaGAP65uB50uM6qiAowo/H2kNh5Y2OazeY50ygpfUhRY1nDaqO J6VDsV5DOAJjCWMpkxBLEknZCg6Antcmv/qQYE1ktHJVR8wg6zVnvlfvoYk1z4Eh ucZrR2E644Ep4Kqtqg== =QG87 -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
2e51e0ac57
9 changed files with 75 additions and 18 deletions
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -317,6 +317,13 @@ int kvm_arch_enable_virtualization_cpu(void)
|
|||
kvm_debug("GCFG:%lx GSTAT:%lx GINTC:%lx GTLBC:%lx",
|
||||
read_csr_gcfg(), read_csr_gstat(), read_csr_gintc(), read_csr_gtlbc());
|
||||
|
||||
/*
|
||||
* HW Guest CSR registers are lost after CPU suspend and resume.
|
||||
* Clear last_vcpu so that Guest CSR registers forced to reload
|
||||
* from vCPU SW state.
|
||||
*/
|
||||
this_cpu_ptr(vmcs)->last_vcpu = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ static int kvm_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
|||
{
|
||||
int ret = RESUME_GUEST;
|
||||
unsigned long estat = vcpu->arch.host_estat;
|
||||
u32 intr = estat & 0x1fff; /* Ignore NMI */
|
||||
u32 intr = estat & CSR_ESTAT_IS;
|
||||
u32 ecode = (estat & CSR_ESTAT_EXC) >> CSR_ESTAT_EXC_SHIFT;
|
||||
|
||||
vcpu->mode = OUTSIDE_GUEST_MODE;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,11 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
if (kvm_pvtime_supported())
|
||||
kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
|
||||
|
||||
kvm->arch.gpa_size = BIT(cpu_vabits - 1);
|
||||
/*
|
||||
* cpu_vabits means user address space only (a half of total).
|
||||
* GPA size of VM is the same with the size of user address space.
|
||||
*/
|
||||
kvm->arch.gpa_size = BIT(cpu_vabits);
|
||||
kvm->arch.root_level = CONFIG_PGTABLE_LEVELS - 1;
|
||||
kvm->arch.invalid_ptes[0] = 0;
|
||||
kvm->arch.invalid_ptes[1] = (unsigned long)invalid_pte_table;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#include <linux/export.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kfence.h>
|
||||
#include <linux/memblock.h>
|
||||
|
|
@ -63,8 +64,11 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
|
|||
}
|
||||
|
||||
info.length = len;
|
||||
info.align_mask = do_color_align ? (PAGE_MASK & SHM_ALIGN_MASK) : 0;
|
||||
info.align_offset = pgoff << PAGE_SHIFT;
|
||||
if (filp && is_file_hugepages(filp))
|
||||
info.align_mask = huge_page_mask_align(filp);
|
||||
else
|
||||
info.align_mask = do_color_align ? (PAGE_MASK & SHM_ALIGN_MASK) : 0;
|
||||
|
||||
if (dir == DOWN) {
|
||||
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
|
||||
|
|
|
|||
Loading…
Reference in a new issue