diff --git a/.mailmap b/.mailmap index 8ade2eed66..593b6c2c53 100644 --- a/.mailmap +++ b/.mailmap @@ -119,6 +119,7 @@ Roman Bolshakov Sriram Yagnaraman Stefan Brankovic Stefan Weil Stefan Weil +Song Gao <17746591750@163.com> Taylor Simpson Yongbok Kim diff --git a/MAINTAINERS b/MAINTAINERS index e92a603e2e..6d81954619 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -280,7 +280,9 @@ F: disas/hppa.c F: tests/tcg/hppa/ LoongArch TCG CPUs -M: Song Gao +M: Song Gao <17746591750@163.com> +M: Bibo Mao +R: Xianglai Li S: Maintained F: target/loongarch/ F: tests/docker/dockerfiles/debian-loongarch-cross.docker @@ -1360,8 +1362,9 @@ F: docs/devel/hexagon-sys.rst LoongArch Machines ------------------ Virt -M: Song Gao +M: Song Gao <17746591750@163.com> M: Bibo Mao +R: Xianglai Li R: Jiaxun Yang S: Maintained F: docs/system/loongarch/virt.rst diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c index c877a8003b..e40292887c 100644 --- a/hw/intc/loongarch_dintc.c +++ b/hw/intc/loongarch_dintc.c @@ -19,6 +19,7 @@ #include "target/loongarch/cpu.h" #include "qemu/error-report.h" #include "system/hw_accel.h" +#include "qemu/log.h" /* msg addr field */ FIELD(MSG_ADDR, IRQ_NUM, 4, 8) @@ -52,7 +53,19 @@ static void loongarch_dintc_mem_write(void *opaque, hwaddr addr, CPUState *cs; cpu_num = FIELD_EX64(msg_addr, MSG_ADDR, CPU_NUM); + + /* Validate cpu_num against the configured number of CPUs */ + if (cpu_num >= s->num_cpu) { + qemu_log_mask(LOG_GUEST_ERROR, + "loongarch-dintc: invalid cpu number%d\n", cpu_num); + return; + } cs = cpu_by_arch_id(cpu_num); + if (!cs) { + qemu_log_mask(LOG_GUEST_ERROR, + "loongarch-dintc: no CPU for arch_id %d\n", cpu_num); + return; + } irq_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_NUM); async_run_on_cpu(cs, do_set_vcpu_dintc_irq, diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h index 3bcf77b375..6abe72ff5c 100644 --- a/target/loongarch/cpu-param.h +++ b/target/loongarch/cpu-param.h @@ -10,6 +10,11 @@ #define TARGET_VIRT_ADDR_SPACE_BITS 48 -#define TARGET_PAGE_BITS 12 +#ifdef CONFIG_USER_ONLY +/* Allow user-only to vary page size from 4k */ +# define TARGET_PAGE_BITS_VARY +#else +# define TARGET_PAGE_BITS 12 +#endif #endif diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 48cdb78a4c..4d0cad5732 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -46,12 +46,12 @@ static int kvm_get_stealtime(CPUState *cs) .addr = (uint64_t)&env->stealtime.guest_addr, }; - err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); + err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); if (err) { return 0; } - err = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, attr); + err = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); if (err) { error_report("PVTIME: KVM_GET_DEVICE_ATTR: %s", strerror(errno)); return err; @@ -70,12 +70,12 @@ static int kvm_set_stealtime(CPUState *cs) .addr = (uint64_t)&env->stealtime.guest_addr, }; - err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); + err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); if (err) { return 0; } - err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr); + err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr); if (err) { error_report("PVTIME: KVM_SET_DEVICE_ATTR %s with gpa "TARGET_FMT_lx, strerror(errno), env->stealtime.guest_addr); @@ -96,13 +96,13 @@ static int kvm_set_pv_features(CPUState *cs) .addr = (uint64_t)&val, }; - err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); + err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); if (err) { return 0; } val = env->pv_features; - err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr); + err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr); if (err) { error_report("Fail to set pv feature "TARGET_FMT_lx " with error %s", val, strerror(errno)); @@ -713,11 +713,11 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs) CPULoongArchState *env = cpu_env(cs); for (i = 0; i < 21; i++) { - ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val); - if (ret < 0) { - trace_kvm_failed_get_cpucfg(strerror(errno)); + int r = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val); + ret |= r; + if (!r) { + env->cpucfg[i] = (uint32_t)val; } - env->cpucfg[i] = (uint32_t)val; } return ret; } @@ -725,7 +725,7 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs) static int kvm_check_cpucfg2(CPUState *cs) { int ret; - uint64_t val; + uint64_t val = 0; struct kvm_device_attr attr = { .group = KVM_LOONGARCH_VCPU_CPUCFG, .attr = 2, @@ -736,8 +736,17 @@ static int kvm_check_cpucfg2(CPUState *cs) ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); if (!ret) { - kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); - env->cpucfg[2] &= val; + /* + * The &= mask is best-effort feature negotiation. If HAS succeeded, + * a GET failure is most likely a copy_{from,to}_user issue; warn and + * keep the cpucfg2 the guest already has rather than failing the sync. + */ + int r = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); + if (r) { + warn_report("CPUCFG2: KVM_GET_DEVICE_ATTR: %s", strerror(errno)); + } else { + env->cpucfg[2] &= val; + } if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) { /* The FP minimal version is 1. */ @@ -761,16 +770,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) for (i = 0; i < 21; i++) { if (i == 2) { - ret = kvm_check_cpucfg2(cs); - if (ret) { - return ret; + int r = kvm_check_cpucfg2(cs); + if (r) { + return r; } } val = env->cpucfg[i]; - ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); - if (ret < 0) { - trace_kvm_failed_put_cpucfg(strerror(errno)); - } + ret |= kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); } return ret; } diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index dea11edc0f..829d8e0f53 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/trace-events @@ -9,7 +9,5 @@ kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s" kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s" kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s" kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" -kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" -kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d" kvm_set_intr(int irq, int level) "kvm set interrupt, irq num: %d, level: %d"