[PATCH v4 8/9] target/loongarch: Implement set vcpu intr for kvm
Implement loongarch kvm set vcpu interrupt interface, when a irq is set in vcpu, we use the KVM_INTERRUPT ioctl to set intr into kvm. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Song Gao --- target/loongarch/cpu.c | 34 +--- target/loongarch/kvm/kvm.c | 15 target/loongarch/kvm/kvm_loongarch.h | 16 + target/loongarch/trace-events| 1 + 4 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 target/loongarch/kvm/kvm_loongarch.h diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 6614a094c8..dfbbe0ace1 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -11,7 +11,6 @@ #include "qapi/error.h" #include "qemu/module.h" #include "sysemu/qtest.h" -#include "exec/cpu_ldst.h" #include "exec/exec-all.h" #include "cpu.h" #include "internals.h" @@ -20,8 +19,16 @@ #ifndef CONFIG_USER_ONLY #include "sysemu/reset.h" #endif -#include "tcg/tcg.h" #include "vec.h" +#include "sysemu/kvm.h" +#include "kvm/kvm_loongarch.h" +#ifdef CONFIG_KVM +#include +#endif +#ifdef CONFIG_TCG +#include "exec/cpu_ldst.h" +#include "tcg/tcg.h" +#endif const char * const regnames[32] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -110,12 +117,15 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) return; } -env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); - -if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { -cpu_interrupt(cs, CPU_INTERRUPT_HARD); +if (kvm_enabled()) { +kvm_loongarch_set_interrupt(cpu, irq, level); } else { -cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); +env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); +if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { +cpu_interrupt(cs, CPU_INTERRUPT_HARD); +} else { +cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); +} } } @@ -140,7 +150,10 @@ static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env) return (pending & status) != 0; } +#endif +#ifdef CONFIG_TCG +#ifndef CONFIG_USER_ONLY static void loongarch_cpu_do_interrupt(CPUState *cs) { LoongArchCPU *cpu = LOONGARCH_CPU(cs); @@ -322,7 +335,6 @@ static bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } #endif -#ifdef CONFIG_TCG static void loongarch_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -560,7 +572,9 @@ static void loongarch_cpu_reset_hold(Object *obj) } #endif +#ifdef CONFIG_TCG restore_fp_status(env); +#endif cs->exception_index = -1; } @@ -703,8 +717,10 @@ static void loongarch_cpu_init(Object *obj) CPULoongArchState *env = &cpu->env; qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS); +#ifdef CONFIG_TCG timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL, &loongarch_constant_timer_cb, cpu); +#endif memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL, env, "iocsr", UINT64_MAX); address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR"); @@ -804,7 +820,9 @@ static struct TCGCPUOps loongarch_tcg_ops = { #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps loongarch_sysemu_ops = { +#ifdef CONFIG_TCG .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, +#endif }; static int64_t loongarch_cpu_get_arch_id(CPUState *cs) diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index d2dab3fef4..bd33ec2114 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -748,6 +748,21 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) return ret; } +int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level) +{ +struct kvm_interrupt intr; +CPUState *cs = CPU(cpu); + +if (level) { +intr.irq = irq; +} else { +intr.irq = -irq; +} + +trace_kvm_set_intr(irq, level); +return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); +} + void kvm_arch_accel_class_init(ObjectClass *oc) { } diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h new file mode 100644 index 00..d945b6bb82 --- /dev/null +++ b/target/loongarch/kvm/kvm_loongarch.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch kvm interface + * + * Copyright (c) 2023 Loongson Technology Corporation Limited + */ + +#include "cpu.h" + +#ifndef QEMU_KVM_LOONGARCH_H +#define QEMU_KVM_LOONGARCH_H + +int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level); +void kvm_arch_reset_vcpu(CPULoongArchState *env); + +#endif diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index 021839880e..dea11edc0f 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/tr
[PATCH v4 4/9] target/loongarch: Implement kvm get/set registers
Implement kvm_arch_get/set_registers interfaces, many regs can be get/set in the function, such as core regs, csr regs, fpu regs, mp state, etc. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Song Gao Change-Id: Ia8fc48fe08b1768853f7729e77d37cdf270031e4 --- meson.build | 1 + target/loongarch/cpu.c| 3 + target/loongarch/cpu.h| 1 + target/loongarch/internals.h | 5 +- target/loongarch/kvm/kvm.c| 580 +- target/loongarch/trace-events | 11 + target/loongarch/trace.h | 1 + 7 files changed, 599 insertions(+), 3 deletions(-) create mode 100644 target/loongarch/trace-events create mode 100644 target/loongarch/trace.h diff --git a/meson.build b/meson.build index 6c77d9687d..445f2b7c2b 100644 --- a/meson.build +++ b/meson.build @@ -3358,6 +3358,7 @@ if have_system or have_user 'target/hppa', 'target/i386', 'target/i386/kvm', +'target/loongarch', 'target/mips/tcg', 'target/nios2', 'target/ppc', diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 72b83e49aa..6614a094c8 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -555,6 +555,9 @@ static void loongarch_cpu_reset_hold(Object *obj) #ifndef CONFIG_USER_ONLY env->pc = 0x1c00; memset(env->tlb, 0, sizeof(env->tlb)); +if (kvm_enabled()) { +kvm_arch_reset_vcpu(env); +} #endif restore_fp_status(env); diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index f6d5ef0852..f4a89bd626 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -360,6 +360,7 @@ typedef struct CPUArchState { MemoryRegion iocsr_mem; bool load_elf; uint64_t elf_address; +uint32_t mp_state; /* Store ipistate to access from this struct */ DeviceState *ipistate; #endif diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index c492863cc5..0beb034748 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -31,8 +31,10 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, const char *loongarch_exception_name(int32_t exception); +#ifdef CONFIG_TCG int ieee_ex_to_loongarch(int xcpt); void restore_fp_status(CPULoongArchState *env); +#endif #ifndef CONFIG_USER_ONLY extern const VMStateDescription vmstate_loongarch_cpu; @@ -44,12 +46,13 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu); uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu); void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu, uint64_t value); - +#ifdef CONFIG_TCG bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +#endif #endif /* !CONFIG_USER_ONLY */ uint64_t read_fcc(CPULoongArchState *env); diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 0d67322fd9..e7c9ef830c 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -26,19 +26,595 @@ #include "sysemu/runstate.h" #include "cpu-csr.h" #include "kvm_loongarch.h" +#include "trace.h" static bool cap_has_mp_state; const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; +static int kvm_loongarch_get_regs_core(CPUState *cs) +{ +int ret = 0; +int i; +struct kvm_regs regs; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; + +/* Get the current register set as KVM seems it */ +ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); +if (ret < 0) { +trace_kvm_failed_get_regs_core(strerror(errno)); +return ret; +} +/* gpr[0] value is always 0 */ +env->gpr[0] = 0; +for (i = 1; i < 32; i++) { +env->gpr[i] = regs.gpr[i]; +} + +env->pc = regs.pc; +return ret; +} + +static int kvm_loongarch_put_regs_core(CPUState *cs) +{ +int ret = 0; +int i; +struct kvm_regs regs; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; + +/* Set the registers based on QEMU's view of things */ +for (i = 0; i < 32; i++) { +regs.gpr[i] = env->gpr[i]; +} + +regs.pc = env->pc; +ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); +if (ret < 0) { +trace_kvm_failed_put_regs_core(strerror(errno)); +} + +return ret; +} + +static int kvm_loongarch_get_csr(CPUState *cs) +{ +int ret = 0; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; + +ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), + &env->CSR_CRMD); + +ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), + &env->CSR_PRMD); + +ret |= kvm_get_one_re
[PATCH v4 3/9] target/loongarch: Supplement vcpu env initial when vcpu reset
Supplement vcpu env initial when vcpu reset, including init vcpu CSR_CPUID,CSR_TID to cpu->cpu_index. The two regs will be used in kvm_get/set_csr_ioctl. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Song Gao --- target/loongarch/cpu.c | 2 ++ target/loongarch/cpu.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 07319d6fb9..72b83e49aa 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -533,10 +533,12 @@ static void loongarch_cpu_reset_hold(Object *obj) env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0); +env->CSR_CPUID = cs->cpu_index; env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); +env->CSR_TID = cs->cpu_index; env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 00d1fba597..f6d5ef0852 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -319,6 +319,7 @@ typedef struct CPUArchState { uint64_t CSR_PWCH; uint64_t CSR_STLBPS; uint64_t CSR_RVACFG; +uint64_t CSR_CPUID; uint64_t CSR_PRCFG1; uint64_t CSR_PRCFG2; uint64_t CSR_PRCFG3; @@ -350,7 +351,6 @@ typedef struct CPUArchState { uint64_t CSR_DBG; uint64_t CSR_DERA; uint64_t CSR_DSAVE; -uint64_t CSR_CPUID; #ifndef CONFIG_USER_ONLY LoongArchTLB tlb[LOONGARCH_TLB_MAX]; -- 2.39.1
[PATCH v4 7/9] target/loongarch: Implement kvm_arch_handle_exit
Implement kvm_arch_handle_exit for loongarch. In this function, the KVM_EXIT_LOONGARCH_IOCSR is handled, we read or write the iocsr address space by the addr, length and is_write argument in kvm_run. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson Reviewed-by: Song Gao --- target/loongarch/kvm/kvm.c| 24 +++- target/loongarch/trace-events | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 85e7aeb083..d2dab3fef4 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -723,7 +723,29 @@ bool kvm_arch_cpu_check_are_resettable(void) int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { -return 0; +int ret = 0; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; +MemTxAttrs attrs = {}; + +attrs.requester_id = env_cpu(env)->cpu_index; + +trace_kvm_arch_handle_exit(run->exit_reason); +switch (run->exit_reason) { +case KVM_EXIT_LOONGARCH_IOCSR: +address_space_rw(&env->address_space_iocsr, + run->iocsr_io.phys_addr, + attrs, + run->iocsr_io.data, + run->iocsr_io.len, + run->iocsr_io.is_write); +break; +default: +ret = -1; +warn_report("KVM: unknown exit reason %d", run->exit_reason); +break; +} +return ret; } void kvm_arch_accel_class_init(ObjectClass *oc) diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index 937c3c7c0c..021839880e 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/trace-events @@ -11,3 +11,4 @@ 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" -- 2.39.1
[PATCH v4 9/9] target/loongarch: Add loongarch kvm into meson build
Add kvm.c into meson.build to compile it when kvm is configed. Meanwhile in meson.build, we set the kvm_targets to loongarch64-softmmu when the cpu is loongarch. And fix the compiling error when config is enable-kvm,disable-tcg. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson --- meson.build | 2 ++ target/loongarch/kvm/meson.build | 1 + target/loongarch/meson.build | 1 + 3 files changed, 4 insertions(+) create mode 100644 target/loongarch/kvm/meson.build diff --git a/meson.build b/meson.build index 445f2b7c2b..0c62b4156d 100644 --- a/meson.build +++ b/meson.build @@ -114,6 +114,8 @@ elif cpu in ['riscv32'] kvm_targets = ['riscv32-softmmu'] elif cpu in ['riscv64'] kvm_targets = ['riscv64-softmmu'] +elif cpu in ['loongarch64'] + kvm_targets = ['loongarch64-softmmu'] else kvm_targets = [] endif diff --git a/target/loongarch/kvm/meson.build b/target/loongarch/kvm/meson.build new file mode 100644 index 00..2266de6ca9 --- /dev/null +++ b/target/loongarch/kvm/meson.build @@ -0,0 +1 @@ +loongarch_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build index 18e8191e2b..7f86caf373 100644 --- a/target/loongarch/meson.build +++ b/target/loongarch/meson.build @@ -31,3 +31,4 @@ loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss]) target_arch += {'loongarch': loongarch_ss} target_system_arch += {'loongarch': loongarch_system_ss} +subdir('kvm') -- 2.39.1
[PATCH v4 6/9] target/loongarch: Implement kvm_arch_init_vcpu
Implement kvm_arch_init_vcpu interface for loongarch, in this function, we register VM change state handler. And when VM state changes to running, the counter value should be put into kvm to keep consistent with kvm, and when state change to stop, counter value should be refreshed from kvm. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Song Gao --- target/loongarch/cpu.h| 2 ++ target/loongarch/kvm/kvm.c| 23 +++ target/loongarch/trace-events | 2 ++ 3 files changed, 27 insertions(+) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index f4a89bd626..8ebd6fa1a7 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -381,6 +381,8 @@ struct ArchCPU { /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; +/* used by KVM_REG_LOONGARCH_COUNTER ioctl to access guest time counters */ +uint64_t kvm_state_counter; }; /** diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 29944b9ef8..85e7aeb083 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -617,8 +617,31 @@ int kvm_arch_put_registers(CPUState *cs, int level) return ret; } +static void kvm_loongarch_vm_stage_change(void *opaque, bool running, + RunState state) +{ +int ret; +CPUState *cs = opaque; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); + +if (running) { +ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, + &cpu->kvm_state_counter); +if (ret < 0) { +trace_kvm_failed_put_counter(strerror(errno)); +} +} else { +ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, + &cpu->kvm_state_counter); +if (ret < 0) { +trace_kvm_failed_get_counter(strerror(errno)); +} +} +} + int kvm_arch_init_vcpu(CPUState *cs) { +qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs); return 0; } diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index 6827ab566a..937c3c7c0c 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/trace-events @@ -7,5 +7,7 @@ kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s" kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s" 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" -- 2.39.1
[PATCH v4 1/9] linux-headers: Synchronize linux headers from linux v6.7.0-rc8
Use the scripts/update-linux-headers.sh to synchronize linux headers from linux v6.7.0-rc8. We mainly want to add the loongarch linux headers and then add the loongarch kvm support based on it. Signed-off-by: Tianrui Zhao Acked-by: Song Gao --- include/standard-headers/drm/drm_fourcc.h | 2 + include/standard-headers/linux/fuse.h | 10 +- include/standard-headers/linux/pci_regs.h | 24 ++- include/standard-headers/linux/vhost_types.h | 7 + .../standard-headers/linux/virtio_config.h| 5 + include/standard-headers/linux/virtio_pci.h | 11 ++ linux-headers/asm-arm64/kvm.h | 32 linux-headers/asm-generic/unistd.h| 14 +- linux-headers/asm-loongarch/bitsperlong.h | 1 + linux-headers/asm-loongarch/kvm.h | 108 +++ linux-headers/asm-loongarch/mman.h| 1 + linux-headers/asm-loongarch/unistd.h | 5 + linux-headers/asm-mips/unistd_n32.h | 4 + linux-headers/asm-mips/unistd_n64.h | 4 + linux-headers/asm-mips/unistd_o32.h | 4 + linux-headers/asm-powerpc/unistd_32.h | 4 + linux-headers/asm-powerpc/unistd_64.h | 4 + linux-headers/asm-riscv/kvm.h | 12 ++ linux-headers/asm-s390/unistd_32.h| 4 + linux-headers/asm-s390/unistd_64.h| 4 + linux-headers/asm-x86/unistd_32.h | 4 + linux-headers/asm-x86/unistd_64.h | 3 + linux-headers/asm-x86/unistd_x32.h| 3 + linux-headers/linux/iommufd.h | 180 +- linux-headers/linux/kvm.h | 11 ++ linux-headers/linux/psp-sev.h | 1 + linux-headers/linux/stddef.h | 9 +- linux-headers/linux/userfaultfd.h | 9 +- linux-headers/linux/vfio.h| 47 +++-- linux-headers/linux/vhost.h | 8 + 30 files changed, 504 insertions(+), 31 deletions(-) create mode 100644 linux-headers/asm-loongarch/bitsperlong.h create mode 100644 linux-headers/asm-loongarch/kvm.h create mode 100644 linux-headers/asm-loongarch/mman.h create mode 100644 linux-headers/asm-loongarch/unistd.h diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h index 72279f4d25..3afb70160f 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -322,6 +322,8 @@ extern "C" { * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian */ #define DRM_FORMAT_NV15fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV20fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV30fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ /* * 2 plane YCbCr MSB aligned diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h index 6b9793842c..fc0dcd10ae 100644 --- a/include/standard-headers/linux/fuse.h +++ b/include/standard-headers/linux/fuse.h @@ -209,7 +209,7 @@ * - add FUSE_HAS_EXPIRE_ONLY * * 7.39 - * - add FUSE_DIRECT_IO_RELAX + * - add FUSE_DIRECT_IO_ALLOW_MMAP * - add FUSE_STATX and related structures */ @@ -405,8 +405,7 @@ struct fuse_file_lock { * FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir, * symlink and mknod (single group that matches parent) * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation - * FUSE_DIRECT_IO_RELAX: relax restrictions in FOPEN_DIRECT_IO mode, for now - * allow shared mmap + * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode. */ #define FUSE_ASYNC_READ(1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -445,7 +444,10 @@ struct fuse_file_lock { #define FUSE_HAS_INODE_DAX (1ULL << 33) #define FUSE_CREATE_SUPP_GROUP (1ULL << 34) #define FUSE_HAS_EXPIRE_ONLY (1ULL << 35) -#define FUSE_DIRECT_IO_RELAX (1ULL << 36) +#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36) + +/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ +#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP /** * CUSE INIT request/reply flags diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index e5f558d964..a39193213f 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -80,6 +80,7 @@ #define PCI_HEADER_TYPE_NORMAL0 #define PCI_HEADER_TYPE_BRIDGE1 #define PCI_HEADER_TYPE_CARDBUS 2 +#define PCI_HEADER_TYPE_MFD 0x80/* Multi-Function Device (possible) */ #define PCI_BIST 0x0f/* 8 bits */ #define PCI_BIST_CODE_MASK0x0f/* Return result */ @@ -637,6 +638,7 @@ #define PCI_EXP_RTCAP 0x1e/* Root Capabilities */ #define PCI_EXP_R
[PATCH v4 0/9] Add loongarch kvm accel support
The linux headers in this patch synchronized from linux kernel v6.7.0-rc8, and the loongarch kvm part of this patch series based on the header files. And the linux kernel has added the loongarch kvm support in master branch. This series add loongarch kvm support, mainly implement some interfaces used by kvm, such as kvm_arch_get/set_regs, kvm_arch_handle_exit, kvm_loongarch_set_interrupt, etc. Currently, we are able to boot LoongArch KVM Linux Guests. In loongarch VM, mmio devices and iocsr devices are emulated in user space such as APIC, IPI, pci devices, etc, other hardwares such as MMU, timer and csr are emulated in kernel. The running environment of LoongArch virt machine: 1. Get the Linux KVM environment of LoongArch in Linux mainline. make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- loongson3_defconfig make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- 2. Get the qemu source: https://github.com/loongson/qemu git checkout kvm-loongarch ./configure --target-list="loongarch64-softmmu" --enable-kvm make 3. Get uefi bios of LoongArch virt machine: Link: https://github.com/tianocore/edk2-platforms/tree/master/Platform/Loongson/LoongArchQemuPkg#readme 4. Also you can access the binary files we have already built: https://github.com/yangxiaojuan-loongson/qemu-binary The command to boot loongarch virt machine: $ qemu-system-loongarch64 -machine virt -m 4G -cpu la464 \ -smp 1 -bios QEMU_EFI.fd -kernel vmlinuz.efi -initrd ramdisk \ -serial stdio -monitor telnet:localhost:4495,server,nowait \ -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" \ --nographic Changes for v4: 1. Synchronize linux headers from linux v6.7.0-rc8. 2. Move kvm.c and kvm_loongarch.h into target/loongarch/kvm/ directory. 3. Add "#ifndef CONFIG_USER_ONLY" before loongarch_cpu_do_interrupt to fix compiling issue. 4. Remove "#ifdef CONFIG_TCG" before "#include "exec/cpu_ldst.h"" in fpu_helper.c, As it has been changed in other patches. Changes for v3: 1. Synchronize linux headers from linux v6.7.0-rc7. 2. Fix compiling error when config enable-kvm and disable-tcg at one time. Changes for v2: 1. Synchronize linux headers from linux v6.7.0-rc6. 2. Remove the stub function: kvm_loongarch_set_interrupt, as kvm_enabled 3. Move the kvm function such as kvm_arch_reset_vcpu from cpu.h to loongarch_kvm.h, and supplement "#include " in loongarch_kvm.h. Changes for v1: 1. Synchronous KVM headers about LoongArch KVM form linux kernel, as the LoongArch KVM patch series have been accepted by linux kernel. 2. Remove the KVM_GET/SET_ONE_UREG64 macro in target/loongarch, and use the common interface kvm_get/set_one_reg to replace it. 3. Resolve the compiling errors when LoongArch is built by other archs. Tianrui Zhao (9): linux-headers: Synchronize linux headers from linux v6.7.0-rc8 target/loongarch: Define some kvm_arch interfaces target/loongarch: Supplement vcpu env initial when vcpu reset target/loongarch: Implement kvm get/set registers target/loongarch: Implement kvm_arch_init function target/loongarch: Implement kvm_arch_init_vcpu target/loongarch: Implement kvm_arch_handle_exit target/loongarch: Implement set vcpu intr for kvm target/loongarch: Add loongarch kvm into meson build include/standard-headers/drm/drm_fourcc.h | 2 + include/standard-headers/linux/fuse.h | 10 +- include/standard-headers/linux/pci_regs.h | 24 +- include/standard-headers/linux/vhost_types.h | 7 + .../standard-headers/linux/virtio_config.h| 5 + include/standard-headers/linux/virtio_pci.h | 11 + linux-headers/asm-arm64/kvm.h | 32 + linux-headers/asm-generic/unistd.h| 14 +- linux-headers/asm-loongarch/bitsperlong.h | 1 + linux-headers/asm-loongarch/kvm.h | 108 +++ linux-headers/asm-loongarch/mman.h| 1 + linux-headers/asm-loongarch/unistd.h | 5 + linux-headers/asm-mips/unistd_n32.h | 4 + linux-headers/asm-mips/unistd_n64.h | 4 + linux-headers/asm-mips/unistd_o32.h | 4 + linux-headers/asm-powerpc/unistd_32.h | 4 + linux-headers/asm-powerpc/unistd_64.h | 4 + linux-headers/asm-riscv/kvm.h | 12 + linux-headers/asm-s390/unistd_32.h| 4 + linux-headers/asm-s390/unistd_64.h| 4 + linux-headers/asm-x86/unistd_32.h | 4 + linux-headers/asm-x86/unistd_64.h | 3 + linux-headers/asm-x86/unistd_x32.h| 3 + linux-headers/linux/iommufd.h | 180 +++- linux-headers/linux/kvm.h | 11 + linux-headers/linux/psp-sev.h | 1 + linux-headers/linux/stddef.h | 9 +- linux-headers/linux/userfaultfd.h | 9 +- linux-headers/linux/vfio.h| 47 +- linux-headers/linux/vhost.h | 8 + meson.build
[PATCH v4 2/9] target/loongarch: Define some kvm_arch interfaces
Define some functions in target/loongarch/kvm/kvm.c, such as kvm_arch_put_registers, kvm_arch_get_registers and kvm_arch_handle_exit, etc. which are needed by kvm/kvm-all.c. Now the most functions has no content and they will be implemented in the next patches. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson Reviewed-by: Song Gao --- target/loongarch/kvm/kvm.c | 131 + 1 file changed, 131 insertions(+) create mode 100644 target/loongarch/kvm/kvm.c diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c new file mode 100644 index 00..0d67322fd9 --- /dev/null +++ b/target/loongarch/kvm/kvm.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch KVM + * + * Copyright (c) 2023 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include +#include + +#include "qemu/timer.h" +#include "qemu/error-report.h" +#include "qemu/main-loop.h" +#include "sysemu/sysemu.h" +#include "sysemu/kvm.h" +#include "sysemu/kvm_int.h" +#include "hw/pci/pci.h" +#include "exec/memattrs.h" +#include "exec/address-spaces.h" +#include "hw/boards.h" +#include "hw/irq.h" +#include "qemu/log.h" +#include "hw/loader.h" +#include "migration/migration.h" +#include "sysemu/runstate.h" +#include "cpu-csr.h" +#include "kvm_loongarch.h" + +static bool cap_has_mp_state; +const KVMCapabilityInfo kvm_arch_required_capabilities[] = { +KVM_CAP_LAST_INFO +}; + +int kvm_arch_get_registers(CPUState *cs) +{ +return 0; +} +int kvm_arch_put_registers(CPUState *cs, int level) +{ +return 0; +} + +int kvm_arch_init_vcpu(CPUState *cs) +{ +return 0; +} + +int kvm_arch_destroy_vcpu(CPUState *cs) +{ +return 0; +} + +unsigned long kvm_arch_vcpu_id(CPUState *cs) +{ +return cs->cpu_index; +} + +int kvm_arch_release_virq_post(int virq) +{ +return 0; +} + +int kvm_arch_msi_data_to_gsi(uint32_t data) +{ +abort(); +} + +int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, + uint64_t address, uint32_t data, PCIDevice *dev) +{ +return 0; +} + +int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, +int vector, PCIDevice *dev) +{ +return 0; +} + +void kvm_arch_init_irq_routing(KVMState *s) +{ +} + +int kvm_arch_get_default_type(MachineState *ms) +{ +return 0; +} + +int kvm_arch_init(MachineState *ms, KVMState *s) +{ +return 0; +} + +int kvm_arch_irqchip_create(KVMState *s) +{ +return 0; +} + +void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) +{ +} + +MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) +{ +return MEMTXATTRS_UNSPECIFIED; +} + +int kvm_arch_process_async_events(CPUState *cs) +{ +return cs->halted; +} + +bool kvm_arch_stop_on_emulation_error(CPUState *cs) +{ +return true; +} + +bool kvm_arch_cpu_check_are_resettable(void) +{ +return true; +} + +int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +{ +return 0; +} + +void kvm_arch_accel_class_init(ObjectClass *oc) +{ +} -- 2.39.1
[PATCH v4 5/9] target/loongarch: Implement kvm_arch_init function
Implement the kvm_arch_init of loongarch, in the function, the KVM_CAP_MP_STATE cap is checked by kvm ioctl. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson Reviewed-by: Song Gao --- target/loongarch/kvm/kvm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index e7c9ef830c..29944b9ef8 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -665,6 +665,7 @@ int kvm_arch_get_default_type(MachineState *ms) int kvm_arch_init(MachineState *ms, KVMState *s) { +cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); return 0; } -- 2.39.1
[PATCH v3] scripts/checkpatch: Support codespell checking
From: Zhao Liu Add two spelling check options (--codespell and --codespellfile) to enhance spelling check through dictionary, which copied the Linux kernel's implementation in checkpatch.pl. This check uses the dictionary at "/usr/share/codespell/dictionary.txt" by default, if there is no dictionary specified under this path, it will look for the dictionary of python3's codespell (This requires user to add python3's path in environment variable $PATH, and to install codespell by "pip install codespell"). Tested-by: Yongwei Ma Tested-by: Samuel Tardieu Signed-off-by: Zhao Liu --- Changes since v2: * Fix the code style. (Samuel) v2: https://lore.kernel.org/qemu-devel/20231215103448.3822284-1-zhao1@linux.intel.com/ Changes since v1: * Drop the default dictionary "selling.text" and just support optional spelling check via --codespell and --codespellfile. (Thomas) v1: https://lore.kernel.org/qemu-devel/20231204082917.2430223-1-zhao1@linux.intel.com/ --- scripts/checkpatch.pl | 125 +++--- 1 file changed, 105 insertions(+), 20 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6e4100d2a41c..702689507412 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -35,6 +35,9 @@ my $summary_file = 0; my $root; my %debug; my $help = 0; +my $codespell = 0; +my $codespellfile = "/usr/share/codespell/dictionary.txt"; +my $user_codespellfile = ""; sub help { my ($exitcode) = @_; @@ -66,6 +69,9 @@ Options: is all off) --test-only=WORD report only warnings/errors containing WORD literally + --codespellUse the codespell dictionary for spelling/typos + (default: $codespellfile) + --codespellfileUse this codespell dictionary --color[=WHEN] Use colors 'always', 'never', or only when output is a terminal ('auto'). Default is 'auto'. -h, --help, --version display this help and exit @@ -85,28 +91,50 @@ foreach (@ARGV) { } GetOptions( - 'q|quiet+' => \$quiet, - 'tree!' => \$tree, - 'signoff!' => \$chk_signoff, - 'patch!'=> \$chk_patch, - 'branch!' => \$chk_branch, - 'emacs!'=> \$emacs, - 'terse!'=> \$terse, - 'f|file!' => \$file, - 'strict!' => \$no_warnings, - 'root=s'=> \$root, - 'summary!' => \$summary, - 'mailback!' => \$mailback, - 'summary-file!' => \$summary_file, - - 'debug=s' => \%debug, - 'test-only=s' => \$tst_only, - 'color=s' => \$color, - 'no-color' => sub { $color = 'never'; }, - 'h|help'=> \$help, - 'version' => \$help + 'q|quiet+' => \$quiet, + 'tree!' => \$tree, + 'signoff!' => \$chk_signoff, + 'patch!'=> \$chk_patch, + 'branch!' => \$chk_branch, + 'emacs!'=> \$emacs, + 'terse!'=> \$terse, + 'f|file!' => \$file, + 'strict!' => \$no_warnings, + 'root=s'=> \$root, + 'summary!' => \$summary, + 'mailback!' => \$mailback, + 'summary-file!' => \$summary_file, + 'debug=s' => \%debug, + 'test-only=s' => \$tst_only, + 'codespell!'=> \$codespell, + 'codespellfile=s' => \$user_codespellfile, + 'color=s' => \$color, + 'no-color' => sub { $color = 'never'; }, + 'h|help'=> \$help, + 'version' => \$help ) or help(1); +if ($user_codespellfile) { + # Use the user provided codespell file unconditionally + $codespellfile = $user_codespellfile; +} elsif (!(-f $codespellfile)) { + # If /usr/share/codespell/dictionary.txt is not present, try to find it + # under codespell's install directory: /data/dictionary.txt + if (($codespell || $help) && which("python3") ne "") { + my $python_codespell_dict = << "EOF"; + +import os.path as op +import codespell_lib +codespell_dir = op.dirname(codespell_lib.__file__) +codespell_file = op.join(codespell_dir, 'data', 'dictionary.txt') +print(codespell_file, end='') +EOF + + my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`; + $codespellfile = $codespell_dict if (-f $codespell_dict); + } +} + help(0) if ($help); my $exit = 0; @@ -337,6 +365,36 @@ our @typeList = ( qr{guintptr}, ); +# Load common spelling mistakes and build regular expression list. +my $misspellings; +my %spelling_fix; + +if ($codespell) { + if (open(my $spelling, '<', $codespellfile)) { +
[RESEND RFC v1 2/2] hw/riscv/virt-acpi-build.c: Generate SPCR table
Generate Serial Port Console Redirection Table (SPCR) for RISC-V virtual machine. Signed-off-by: Sia Jee Heng --- hw/riscv/virt-acpi-build.c | 39 ++ 1 file changed, 39 insertions(+) diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index d4a02579d6..388b3d1a84 100644 --- a/hw/riscv/virt-acpi-build.c +++ b/hw/riscv/virt-acpi-build.c @@ -174,6 +174,42 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, aml_append(scope, dev); } +/* + * Serial Port Console Redirection Table (SPCR) + * Rev: 1.07 + */ + +static void +build_spcr_rev2(GArray *table_data, BIOSLinker *linker, RISCVVirtState *s) +{ +AcpiSpcrData serial = { +.interface_type = 0, /* 16550 compatible */ +.base_addr.id = AML_AS_SYSTEM_MEMORY, +.base_addr.width = 32, +.base_addr.offset = 0, +.base_addr.size = 1, +.base_addr.addr = s->memmap[VIRT_UART0].base, +.interrupt_type = (1 << 4),/* Bit[4] RISC-V PLIC/APLIC */ +.pc_interrupt = 0, +.interrupt = UART0_IRQ, +.baud_rate = 7,/* 15200 */ +.parity = 0, +.stop_bits = 1, +.flow_control = 0, +.terminal_type = 3,/* ANSI */ +.language = 0, /* Language */ +.pci_device_id = 0x, /* not a PCI device*/ +.pci_vendor_id = 0x, /* not a PCI device*/ +.pci_bus = 0, +.pci_device = 0, +.pci_function = 0, +.pci_flags = 0, +.pci_segment = 0, +}; + +build_spcr(table_data, linker, &serial, s->oem_id, s->oem_table_id); +} + /* RHCT Node[N] starts at offset 56 */ #define RHCT_NODE_ARRAY_OFFSET 56 @@ -555,6 +591,9 @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_rhct(tables_blob, tables->linker, s); +acpi_add_table(table_offsets, tables_blob); +build_spcr_rev2(tables_blob, tables->linker, s); + acpi_add_table(table_offsets, tables_blob); { AcpiMcfgInfo mcfg = { -- 2.34.1
[RESEND RFC v1 0/2] RISC-V: ACPI: Enable SPCR
This series focuses on enabling the Serial Port Console Redirection (SPCR) table for the RISC-V virt platform. Considering that ARM utilizes the same function, the initial patch involves migrating the build_spcr function to common code. This consolidation ensures that RISC-V avoids duplicating the function. The patch set is built upon Alistair's riscv-to-apply.next branch and relies on Sunil's patches at [1]. [1] https://lore.kernel.org/qemu-devel/20231218150247.466427-1-suni...@ventanamicro.com/ Sia Jee Heng (2): hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location hw/riscv/virt-acpi-build.c: Generate SPCR table hw/acpi/aml-build.c | 51 hw/arm/virt-acpi-build.c| 68 +++-- hw/riscv/virt-acpi-build.c | 39 + include/hw/acpi/acpi-defs.h | 33 ++ include/hw/acpi/aml-build.h | 4 +++ 5 files changed, 154 insertions(+), 41 deletions(-) -- 2.34.1
[RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location
RISC-V should also generate the SPCR in a manner similar to ARM. Therefore, instead of replicating the code, relocate this function to the common AML build. Signed-off-by: Sia Jee Heng --- hw/acpi/aml-build.c | 51 hw/arm/virt-acpi-build.c| 68 +++-- include/hw/acpi/acpi-defs.h | 33 ++ include/hw/acpi/aml-build.h | 4 +++ 4 files changed, 115 insertions(+), 41 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index af66bde0f5..1efa534aa8 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1994,6 +1994,57 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, } } +void build_spcr(GArray *table_data, BIOSLinker *linker, +const AcpiSpcrData *f, const char *oem_id, +const char *oem_table_id) +{ +AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = oem_id, +.oem_table_id = oem_table_id }; + +acpi_table_begin(&table, table_data); +/* Interface type */ +build_append_int_noprefix(table_data, f->interface_type, 1); +/* Reserved */ +build_append_int_noprefix(table_data, 0, 3); +/* Base Address */ +build_append_gas(table_data, f->base_addr.id, f->base_addr.width, + f->base_addr.offset, f->base_addr.size, + f->base_addr.addr); +/* Interrupt type */ +build_append_int_noprefix(table_data, f->interrupt_type, 1); +/* IRQ */ +build_append_int_noprefix(table_data, f->pc_interrupt, 1); +/* Global System Interrupt */ +build_append_int_noprefix(table_data, f->interrupt, 4); +/* Baud Rate */ +build_append_int_noprefix(table_data, f->baud_rate, 1); +/* Parity */ +build_append_int_noprefix(table_data, f->parity, 1); +/* Stop Bits */ +build_append_int_noprefix(table_data, f->stop_bits, 1); +/* Flow Control */ +build_append_int_noprefix(table_data, f->flow_control, 1); +/* Terminal Type */ +build_append_int_noprefix(table_data, f->terminal_type, 1); +/* PCI Device ID */ +build_append_int_noprefix(table_data, f->pci_device_id, 2); +/* PCI Vendor ID */ +build_append_int_noprefix(table_data, f->pci_vendor_id, 2); +/* PCI Bus Number */ +build_append_int_noprefix(table_data, f->pci_bus, 1); +/* PCI Device Number */ +build_append_int_noprefix(table_data, f->pci_device, 1); +/* PCI Function Number */ +build_append_int_noprefix(table_data, f->pci_function, 1); +/* PCI Flags */ +build_append_int_noprefix(table_data, f->pci_flags, 4); +/* PCI Segment */ +build_append_int_noprefix(table_data, f->pci_segment, 1); +/* Reserved */ +build_append_int_noprefix(table_data, 0, 4); + +acpi_table_end(linker, &table); +} /* * ACPI spec, Revision 6.3 * 5.2.29 Processor Properties Topology Table (PPTT) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 510ab0dcca..a31f736d1a 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -431,48 +431,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) * Rev: 1.07 */ static void -build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) +build_spcr_v2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { -AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = vms->oem_id, -.oem_table_id = vms->oem_table_id }; - -acpi_table_begin(&table, table_data); - -/* Interface Type */ -build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */ -build_append_int_noprefix(table_data, 0, 3); /* Reserved */ -/* Base Address */ -build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 3, - vms->memmap[VIRT_UART].base); -/* Interrupt Type */ -build_append_int_noprefix(table_data, -(1 << 3) /* Bit[3] ARMH GIC interrupt */, 1); -build_append_int_noprefix(table_data, 0, 1); /* IRQ */ -/* Global System Interrupt */ -build_append_int_noprefix(table_data, - vms->irqmap[VIRT_UART] + ARM_SPI_BASE, 4); -build_append_int_noprefix(table_data, 3 /* 9600 */, 1); /* Baud Rate */ -build_append_int_noprefix(table_data, 0 /* No Parity */, 1); /* Parity */ -/* Stop Bits */ -build_append_int_noprefix(table_data, 1 /* 1 Stop bit */, 1); -/* Flow Control */ -build_append_int_noprefix(table_data, -(1 << 1) /* RTS/CTS hardware flow control */, 1); -/* Terminal Type */ -build_append_int_noprefix(table_data, 0 /* VT100 */, 1); -build_append_int_noprefix(table_data, 0, 1); /* Language */ -/* PCI Device ID */ -build_append_int_noprefix(table_data, 0x /* not a PCI device*/, 2); -/* PCI Vendor ID */ -build_append_int_noprefix(table_data, 0x /* not a PCI device*/, 2); -build_append_int_noprefix(table_data, 0, 1); /* PCI Bus Number */ -build_a
Re: [PATCH v9 01/11] virtio: split into vhost-user-base and vhost-user-device
On 4/1/24 22:09, Alex Bennée wrote: Lets keep a cleaner split between the base class and the derived vhost-user-device which we can use for generic vhost-user stubs. This includes an update to introduce the vq_size property so the number of entries in a virtq can be defined. Signed-off-by: Alex Bennée --- v5 - s/parent/parent_obj/ - remove left over vhost-user-device.h - use DEFINE_TYPES v6 - rebase and set .abstract = true for vhost-user-device v7 - checkpatch line length + MAINTAINERS - s/abstract = true/dc->user_creatable = false/ for both mmio and pci --- MAINTAINERS | 6 + ...{vhost-user-device.h => vhost-user-base.h} | 21 +- hw/virtio/vhost-user-base.c | 346 ++ hw/virtio/vhost-user-device-pci.c | 13 +- hw/virtio/vhost-user-device.c | 338 + hw/virtio/meson.build | 1 + 6 files changed, 383 insertions(+), 342 deletions(-) rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%) create mode 100644 hw/virtio/vhost-user-base.c @@ -358,6 +42,9 @@ static void vud_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); +/* Reason: stop inexperienced users confusing themselves */ +dc->user_creatable = false; What about making VHOST_USER_DEVICE_PCI and TYPE_VHOST_USER_DEVICE TypeInfos abstract instead? + device_class_set_props(dc, vud_properties); dc->vmsd = &vud_vmstate; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); @@ -366,14 +53,11 @@ static void vud_class_init(ObjectClass *klass, void *data) static const TypeInfo vud_info = { .name = TYPE_VHOST_USER_DEVICE, .parent = TYPE_VHOST_USER_BASE, -.instance_size = sizeof(VHostUserBase), .class_init = vud_class_init, -.class_size = sizeof(VHostUserBaseClass), };
Re: [PATCH 01/10] hw/audio/virtio-sound: remove command and stream mutexes
Hi On Fri, Jan 5, 2024 at 12:35 AM Volker Rümelin wrote: > > All code in virtio-snd.c runs with the BQL held. Remove the > command queue mutex and the stream queue mutexes. The qatomic > functions are also not needed. I am not comfortable with this assertion. Someone more familiar with virtio.c implementation should confirm Rust would really save us from thinking about this kind of problems, and a standalone vhost-user implementation.. > > Signed-off-by: Volker Rümelin > --- > hw/audio/virtio-snd.c | 294 +++--- > include/hw/audio/virtio-snd.h | 3 - > 2 files changed, 130 insertions(+), 167 deletions(-) > > diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c > index ea2aeaef14..8344f61c64 100644 > --- a/hw/audio/virtio-snd.c > +++ b/hw/audio/virtio-snd.c > @@ -19,7 +19,6 @@ > #include "qemu/iov.h" > #include "qemu/log.h" > #include "qemu/error-report.h" > -#include "include/qemu/lockable.h" > #include "sysemu/runstate.h" > #include "trace.h" > #include "qapi/error.h" > @@ -453,7 +452,6 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, > uint32_t stream_id) > stream->id = stream_id; > stream->pcm = s->pcm; > stream->s = s; > -qemu_mutex_init(&stream->queue_mutex); > QSIMPLEQ_INIT(&stream->queue); > QSIMPLEQ_INIT(&stream->invalid); > > @@ -580,9 +578,7 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound > *s, > > stream = virtio_snd_pcm_get_stream(s, stream_id); > if (stream) { > -WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { > -stream->active = start; > -} > +stream->active = start; > if (stream->info.direction == VIRTIO_SND_D_OUTPUT) { > AUD_set_active_out(stream->voice.out, start); > } else { > @@ -606,13 +602,11 @@ static size_t > virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream *stream) > VirtIOSoundPCMBuffer *buffer, *next; > size_t count = 0; > > -WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { > -QSIMPLEQ_FOREACH_SAFE(buffer, &stream->queue, entry, next) { > -count += 1; > -} > -QSIMPLEQ_FOREACH_SAFE(buffer, &stream->invalid, entry, next) { > -count += 1; > -} > +QSIMPLEQ_FOREACH_SAFE(buffer, &stream->queue, entry, next) { > +count += 1; > +} > +QSIMPLEQ_FOREACH_SAFE(buffer, &stream->invalid, entry, next) { > +count += 1; > } > return count; > } > @@ -762,23 +756,15 @@ static void virtio_snd_process_cmdq(VirtIOSound *s) > { > virtio_snd_ctrl_command *cmd; > > -if (unlikely(qatomic_read(&s->processing_cmdq))) { > -return; > -} > - > -WITH_QEMU_LOCK_GUARD(&s->cmdq_mutex) { > -qatomic_set(&s->processing_cmdq, true); > -while (!QTAILQ_EMPTY(&s->cmdq)) { > -cmd = QTAILQ_FIRST(&s->cmdq); > +while (!QTAILQ_EMPTY(&s->cmdq)) { > +cmd = QTAILQ_FIRST(&s->cmdq); > > -/* process command */ > -process_cmd(s, cmd); > +/* process command */ > +process_cmd(s, cmd); > > -QTAILQ_REMOVE(&s->cmdq, cmd, next); > +QTAILQ_REMOVE(&s->cmdq, cmd, next); > > -virtio_snd_ctrl_cmd_free(cmd); > -} > -qatomic_set(&s->processing_cmdq, false); > +virtio_snd_ctrl_cmd_free(cmd); > } > } > > @@ -840,32 +826,30 @@ static inline void empty_invalid_queue(VirtIODevice > *vdev, VirtQueue *vq) > stream = vsnd->pcm->streams[i]; > if (stream) { > any = false; > -WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { > -while (!QSIMPLEQ_EMPTY(&stream->invalid)) { > -buffer = QSIMPLEQ_FIRST(&stream->invalid); > -if (buffer->vq != vq) { > -break; > -} > -any = true; > -resp.status = cpu_to_le32(VIRTIO_SND_S_BAD_MSG); > -iov_from_buf(buffer->elem->in_sg, > - buffer->elem->in_num, > - 0, > - &resp, > - sizeof(virtio_snd_pcm_status)); > -virtqueue_push(vq, > - buffer->elem, > - sizeof(virtio_snd_pcm_status)); > -QSIMPLEQ_REMOVE_HEAD(&stream->invalid, entry); > -virtio_snd_pcm_buffer_free(buffer); > -} > -if (any) { > -/* > - * Notify vq about virtio_snd_pcm_status responses. > - * Buffer responses must be notified separately later. > - */ > -virtio_notify(vdev, vq); > +while (!QSIMPLEQ_EMPTY(&stream->invalid)) { > +buffer = QSIMPLEQ_FIRST(&stream->invalid); > +
Re: [PATCH v5 2/3] tests/qtest: Add STM32L4x5 EXTI QTest testcase
(+Mark & Eduardo) On 4/1/24 14:37, inesvarhol wrote: Le jeudi 4 janvier 2024 à 14:05, Philippe Mathieu-Daudé a écrit : Hello, +static void test_edge_selector(void) +{ + enable_nvic_irq(EXTI0_IRQ); + + / Configure EXTI line 0 irq on rising edge */ + qtest_set_irq_in(global_qtest, "/machine/unattached/device[0]/exti", Markus, this qtest use seems to expect some stability in QOM path... Inès, Arnaud, having the SoC unattached is dubious, it belongs to the machine. Noted, we will fix that. Should we be concerned about the "stability in QOM path" ? Don't worry about this Inès, I wanted to raise Markus attention on this. You showed a legit use of stable QOM path, and Markus told me recently there is no contract for QOM paths (it shouldn't be considered as a stable API). IIRC Markus explanation, "/unattached" container was added as a temporary hack to allow migrating QDev objects to QOM (see around commit da57febfed "qdev: give all devices a canonical path", 11 years ago). I agree anything under "/unattached" can be expected to be stable (but we need a community consensus). Then the big question remaining is "can any qom-path out of /unattached be considered stable?" Regards, Phil.
Re: [PATCH v3 00/33] linux-user: Improve host and guest page size handling
On 1/2/24 02:57, Richard Henderson wrote: Changes for v3: * Rebase. Blurb from v1: While working on mmap issues for 8.1, I noticed a lot of corner cases of host != guest page size that we implement poorly. This seems to be particularly visible on Apple M1 with 16k pages, more so than Power with 64k pages for some reason. Objective 1 is to deprecate and (essentially) disable the -p option. The effect of -p is apparently confusing, so much so that our own testsuite misuses it. One cannot really change the host page size, and pretending otherwise means that we don't treat the host memory system correctly, and stuff breaks. I have not yet done the same work for bsd-user. Objective 2 is to allow the guest page size to change to match the host. There are corner cases of host != guest page size will fail in odd ways. For case of host > guest page size, the issues could be solved with softmmu, allowing a non-linear mapping between host and guest addresses and also disconnecting host and guest page permissions. However, host < guest page has issues with SIGBUS which I believe to be totally unfixable. At minimum one would need to monitor changes to all files mapped in the address space, but I'm sure there is much more. But as always the best behaviour is obtained when the host and guest page sizes match -- there are no corner cases to contend with. There are a set of guests which can be configured to use multiple page sizes, and therefore software developed for those guests (usually) does not hard-code a particular page size. For those, we can allow the page size to vary and let the guest match the host. I have only changed aarch64, alpha and ppc guests so far, as those are both easy to test and, especially for the case of alpha's default 8k page size, prone to failure. I did some basic testing (built, installed, started chroots) for various targets and did not see any obvious issues. I did not specifically checked for particular page sizes though. Anyway, for the series: Acked-by: Helge Deller Helge r~ Richard Henderson (33): accel/tcg: Remove qemu_host_page_size from page_protect/page_unprotect linux-user: Adjust SVr4 NULL page mapping linux-user: Remove qemu_host_page_{size,mask} in probe_guest_base linux-user: Remove qemu_host_page_size from create_elf_tables linux-user/hppa: Simplify init_guest_commpage linux-user/nios2: Remove qemu_host_page_size from init_guest_commpage linux-user/arm: Remove qemu_host_page_size from init_guest_commpage linux-user: Remove qemu_host_page_{size,mask} from mmap.c linux-user: Remove REAL_HOST_PAGE_ALIGN from mmap.c linux-user: Remove HOST_PAGE_ALIGN from mmap.c migration: Remove qemu_host_page_size hw/tpm: Remove HOST_PAGE_ALIGN from tpm_ppi_init softmmu/physmem: Remove qemu_host_page_size softmmu/physmem: Remove HOST_PAGE_ALIGN linux-user: Remove qemu_host_page_size from main linux-user: Split out target_mmap__locked linux-user: Move some mmap checks outside the lock linux-user: Fix sub-host-page mmap linux-user: Split out mmap_end linux-user: Do early mmap placement only for reserved_va linux-user: Split out mmap_h_eq_g linux-user: Split out mmap_h_lt_g linux-user: Split out mmap_h_gt_g tests/tcg: Remove run-test-mmap-* tests/tcg: Extend file in linux-madvise.c *-user: Deprecate and disable -p pagesize cpu: Remove page_size_init accel/tcg: Disconnect TargetPageDataNode from page size linux-user: Allow TARGET_PAGE_BITS_VARY target/arm: Enable TARGET_PAGE_BITS_VARY for AArch64 user-only linux-user: Bound mmap_min_addr by host page size target/ppc: Enable TARGET_PAGE_BITS_VARY for user-only target/alpha: Enable TARGET_PAGE_BITS_VARY for user-only docs/about/deprecated.rst | 7 + docs/user/main.rst| 3 - bsd-user/qemu.h | 7 + include/exec/cpu-common.h | 7 - include/hw/core/cpu.h | 2 - target/alpha/cpu-param.h | 16 +- target/arm/cpu-param.h| 6 +- target/ppc/cpu-param.h| 9 +- accel/tcg/translate-all.c | 1 - accel/tcg/user-exec.c | 31 +- bsd-user/main.c | 21 +- cpu-target.c | 13 - hw/tpm/tpm_ppi.c | 3 +- linux-user/elfload.c | 67 +- linux-user/main.c | 33 +- linux-user/mmap.c | 714 +- migration/ram.c | 22 +- system/physmem.c | 17 +- system/vl.c | 1 - target/arm/cpu.c | 51 +- tests/tcg/multiarch/linux/linux-madvise.c | 2 + tests/tcg/alpha/Makefile.target | 3 - tests/tcg/arm/Makefile.target | 3 -
Re: [PATCH v5 2/3] tests/qtest: Add STM32L4x5 EXTI QTest testcase
On 5/1/24 11:13, Philippe Mathieu-Daudé wrote: (+Mark & Eduardo) On 4/1/24 14:37, inesvarhol wrote: Le jeudi 4 janvier 2024 à 14:05, Philippe Mathieu-Daudé a écrit : Hello, +static void test_edge_selector(void) +{ + enable_nvic_irq(EXTI0_IRQ); + + / Configure EXTI line 0 irq on rising edge */ + qtest_set_irq_in(global_qtest, "/machine/unattached/device[0]/exti", Markus, this qtest use seems to expect some stability in QOM path... Inès, Arnaud, having the SoC unattached is dubious, it belongs to the machine. Noted, we will fix that. Should we be concerned about the "stability in QOM path" ? Don't worry about this Inès, I wanted to raise Markus attention on this. You showed a legit use of stable QOM path, and Markus told me recently there is no contract for QOM paths (it shouldn't be considered as a stable API). IIRC Markus explanation, "/unattached" container was added as a temporary hack to allow migrating QDev objects to QOM (see around commit da57febfed "qdev: give all devices a canonical path", 11 years ago). Hmm am I getting confused with "/peripheral-anon" (commit 8eb02831af "dev: add an anonymous peripheral container")? I agree anything under "/unattached" can be expected to be stable (but we need a community consensus). Then the big question remaining is "can any qom-path out of /unattached be considered stable?" Regards, Phil.
Re: [PATCH v5 2/3] tests/qtest: Add STM32L4x5 EXTI QTest testcase
On Thu, Jan 04, 2024 at 01:37:22PM +, inesvarhol wrote: > > Le jeudi 4 janvier 2024 à 14:05, Philippe Mathieu-Daudé a > écrit : > > Hello, > > > > +static void test_edge_selector(void) > > > +{ > > > + enable_nvic_irq(EXTI0_IRQ); > > > + > > > + / Configure EXTI line 0 irq on rising edge */ > > > + qtest_set_irq_in(global_qtest, "/machine/unattached/device[0]/exti", > > > > > > Markus, this qtest use seems to expect some stability in QOM path... > > > > Inès, Arnaud, having the SoC unattached is dubious, it belongs to > > the machine. > > Noted, we will fix that. > Should we be concerned about the "stability in QOM path" ? QTest is a functional test harness that intentionally has knowledge about QEMU internals. IOW, usage of particular QOM path in qtest does *not* imply that QOM path needs to be stable. If QEMU internals change for whatever reason, it is expected that QTests may need some updates to match. QOM path stability only matters if there's a mgmt app facing use case, which requires the app to have hardcoded knowledge of the path. Even a mgmt app can use unstable QOM paths, provided it has a way to dynamically detect the path to be used, instead of hardcoding it. None the less, you may still choose to move it out of /unattached at your discretion. With regards, Daniel -- |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o-https://fstop138.berrange.com :| |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
[PATCH 8/9] leon3: check cpu_id in the tiny bootloader
Now that SMP is possible, the asr17 must be checked in the little boot code or the secondary CPU will reinitialize the Timer and the Uart. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/sparc/leon3.c | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 38fb8d9af1..7498eaa827 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -98,13 +98,27 @@ static uint32_t *gen_store_u32(uint32_t *code, hwaddr addr, uint32_t val) /* * When loading a kernel in RAM the machine is expected to be in a different - * state (eg: initialized by the bootloader). This little code reproduces - * this behavior. + * state (eg: initialized by the bootloader). This little code reproduces + * this behavior. Also this code can be executed by the secondary cpus as + * well since it looks at the %asr17 register before doing any + * initialization, it allows to use the same reset address for all the + * cpus. */ static void write_bootloader(CPUSPARCState *env, uint8_t *base, hwaddr kernel_addr) { uint32_t *p = (uint32_t *) base; +uint32_t *sec_cpu_branch_p = NULL; + +/* If we are running on a secondary CPU, jump directly to the kernel. */ + +stl_p(p++, 0x85444000); /* rd %asr17, %g2 */ +stl_p(p++, 0x8530a01c); /* srl %g2, 0x1c, %g2 */ +stl_p(p++, 0x80908000); /* tst %g2*/ +/* Fill that later. */ +sec_cpu_branch_p = p; +stl_p(p++, 0x0BADC0DE); /* bne xxx */ +stl_p(p++, 0x0100); /* nop */ /* Initialize the UARTs*/ /* *UART_CONTROL = UART_RECEIVE_ENABLE | UART_TRANSMIT_ENABLE; */ @@ -118,6 +132,10 @@ static void write_bootloader(CPUSPARCState *env, uint8_t *base, /* *GPTIMER0_CONFIG = GPTIMER_ENABLE | GPTIMER_RESTART;*/ p = gen_store_u32(p, 0x8318, 3); +/* Now, the relative branch above can be computed. */ +stl_p(sec_cpu_branch_p, 0x1280 + + (p - sec_cpu_branch_p)); + /* JUMP to the entry point */ stl_p(p++, 0x8210); /* mov %g0, %g1 */ stl_p(p++, 0x0300 + extract32(kernel_addr, 10, 22)); -- 2.25.1
[PATCH 4/9] intc/grlib_irqmp: implements multicore irq
Now there is an ncpus property, use it in order to deliver the IRQ to multiple CPU. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/intc/grlib_irqmp.c | 43 ++- hw/sparc/leon3.c | 3 ++- include/hw/intc/grlib_irqmp.h | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c index be0e840181..4df0293064 100644 --- a/hw/intc/grlib_irqmp.c +++ b/hw/intc/grlib_irqmp.c @@ -64,7 +64,7 @@ struct IRQMP { unsigned int ncpus; IRQMPState *state; qemu_irq start_signal[IRQMP_MAX_CPU]; -qemu_irq irq; +qemu_irq irq[IRQMP_MAX_CPU]; }; struct IRQMPState { @@ -83,37 +83,37 @@ struct IRQMPState { static void grlib_irqmp_check_irqs(IRQMPState *state) { -uint32_t pend = 0; -uint32_t level0 = 0; -uint32_t level1 = 0; +uint32_t pend = 0; +uint32_t level0 = 0; +uint32_t level1 = 0; +int i; assert(state != NULL); assert(state->parent != NULL); -/* IRQ for CPU 0 (no SMP support) */ -pend = (state->pending | state->force[0]) -& state->mask[0]; - -level0 = pend & ~state->level; -level1 = pend & state->level; +for (i = 0; i < state->parent->ncpus; i++) { +pend = (state->pending | state->force[i]) & state->mask[i]; +level0 = pend & ~state->level; +level1 = pend & state->level; -trace_grlib_irqmp_check_irqs(state->pending, state->force[0], - state->mask[0], level1, level0); +trace_grlib_irqmp_check_irqs(state->pending, state->force[i], + state->mask[i], level1, level0); -/* Trigger level1 interrupt first and level0 if there is no level1 */ -qemu_set_irq(state->parent->irq, level1 ?: level0); +/* Trigger level1 interrupt first and level0 if there is no level1 */ +qemu_set_irq(state->parent->irq[i], level1 ?: level0); +} } -static void grlib_irqmp_ack_mask(IRQMPState *state, uint32_t mask) +static void grlib_irqmp_ack_mask(IRQMPState *state, int cpu, uint32_t mask) { /* Clear registers */ state->pending &= ~mask; -state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */ +state->force[cpu] &= ~mask; grlib_irqmp_check_irqs(state); } -void grlib_irqmp_ack(DeviceState *dev, int intno) +void grlib_irqmp_ack(DeviceState *dev, int cpu, int intno) { IRQMP*irqmp = GRLIB_IRQMP(dev); IRQMPState *state; @@ -127,7 +127,7 @@ void grlib_irqmp_ack(DeviceState *dev, int intno) trace_grlib_irqmp_ack(intno); -grlib_irqmp_ack_mask(state, mask); +grlib_irqmp_ack_mask(state, cpu, mask); } static void grlib_irqmp_set_irq(void *opaque, int irq, int level) @@ -153,7 +153,6 @@ static void grlib_irqmp_set_irq(void *opaque, int irq, int level) s->pending |= 1 << irq; } grlib_irqmp_check_irqs(s); - } } @@ -257,7 +256,9 @@ static void grlib_irqmp_write(void *opaque, hwaddr addr, case CLEAR_OFFSET: value &= ~1; /* clean up the value */ -grlib_irqmp_ack_mask(state, value); +for (i = 0; i < irqmp->ncpus; i++) { +grlib_irqmp_ack_mask(state, i, value); +} return; case MP_STATUS_OFFSET: @@ -352,7 +353,7 @@ static void grlib_irqmp_realize(DeviceState *dev, Error **errp) /* Transitionning from 0 to 1 starts the CPUs. */ qdev_init_gpio_out_named(dev, irqmp->start_signal, "grlib-start-cpu", IRQMP_MAX_CPU); -qdev_init_gpio_out_named(dev, &irqmp->irq, "grlib-irq", 1); +qdev_init_gpio_out_named(dev, irqmp->irq, "grlib-irq", irqmp->ncpus); memory_region_init_io(&irqmp->iomem, OBJECT(dev), &grlib_irqmp_ops, irqmp, "irqmp", IRQMP_REG_SIZE); diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 7b9809b81f..94d8ec94b0 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -168,7 +168,8 @@ static void leon3_cache_control_int(CPUSPARCState *env) static void leon3_irq_ack(void *irq_manager, int intno) { -grlib_irqmp_ack((DeviceState *)irq_manager, intno); +/* No SMP support yet. */ +grlib_irqmp_ack((DeviceState *)irq_manager, 0, intno); } /* diff --git a/include/hw/intc/grlib_irqmp.h b/include/hw/intc/grlib_irqmp.h index b9cc584168..776a2508e1 100644 --- a/include/hw/intc/grlib_irqmp.h +++ b/include/hw/intc/grlib_irqmp.h @@ -34,6 +34,6 @@ /* IRQMP */ #define TYPE_GRLIB_IRQMP "grlib-irqmp" -void grlib_irqmp_ack(DeviceState *dev, int intno); +void grlib_irqmp_ack(DeviceState *dev, int cpu, int intno); #endif /* GRLIB_IRQMP_H */ -- 2.25.1
[PATCH 6/9] target/sparc: simplify qemu_irq_ack
This is a simple cleanup, since env is passed to qemu_irq_ack it can be accessed from inside qemu_irq_ack. Just drop this parameter. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/sparc/leon3.c| 8 target/sparc/cpu.h | 2 +- target/sparc/int32_helper.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 94d8ec94b0..6019fc4c2d 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -166,10 +166,10 @@ static void leon3_cache_control_int(CPUSPARCState *env) } } -static void leon3_irq_ack(void *irq_manager, int intno) +static void leon3_irq_ack(CPUSPARCState *env, int intno) { /* No SMP support yet. */ -grlib_irqmp_ack((DeviceState *)irq_manager, 0, intno); +grlib_irqmp_ack(env->irq_manager, 0, intno); } /* @@ -211,9 +211,9 @@ static void leon3_set_pil_in(void *opaque, int n, int level) } } -static void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno) +static void leon3_irq_manager(CPUSPARCState *env, int intno) { -leon3_irq_ack(irq_manager, intno); +leon3_irq_ack(env, intno); leon3_cache_control_int(env); } diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index 6999a10a40..12a11ecb26 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -549,7 +549,7 @@ struct CPUArchState { sparc_def_t def; void *irq_manager; -void (*qemu_irq_ack)(CPUSPARCState *env, void *irq_manager, int intno); +void (*qemu_irq_ack)(CPUSPARCState *env, int intno); /* Leon3 cache control */ uint32_t cache_control; diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c index 1563613582..8f4e08ed09 100644 --- a/target/sparc/int32_helper.c +++ b/target/sparc/int32_helper.c @@ -160,7 +160,7 @@ void sparc_cpu_do_interrupt(CPUState *cs) #if !defined(CONFIG_USER_ONLY) /* IRQ acknowledgment */ if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) { -env->qemu_irq_ack(env, env->irq_manager, intno); +env->qemu_irq_ack(env, intno); } #endif } -- 2.25.1
[PATCH 9/9] MAINTAINERS: replace Fabien by myself as Leon3 maintainer
CC: Fabien Chouteau Signed-off-by: Clément Chigot --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 395f26ba86..a065e0b21f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1694,7 +1694,7 @@ F: hw/rtc/sun4v-rtc.c F: include/hw/rtc/sun4v-rtc.h Leon3 -M: Fabien Chouteau +M: Clément Chigot M: Frederic Konrad S: Maintained F: hw/sparc/leon3.c -- 2.25.1
[PATCH 1/9] sparc/grlib: split out the headers for each peripherals
... and move them in their right hardware directory. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/char/grlib_apbuart.c | 4 +-- hw/intc/grlib_irqmp.c | 4 +-- hw/sparc/leon3.c | 6 ++-- hw/timer/grlib_gptimer.c | 4 +-- include/hw/char/grlib_uart.h | 30 +++ .../hw/{sparc/grlib.h => intc/grlib_irqmp.h} | 14 +++-- include/hw/timer/grlib_gptimer.h | 30 +++ 7 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 include/hw/char/grlib_uart.h rename include/hw/{sparc/grlib.h => intc/grlib_irqmp.h} (86%) create mode 100644 include/hw/timer/grlib_gptimer.h diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c index 82ff40a530..2c9ab70b85 100644 --- a/hw/char/grlib_apbuart.c +++ b/hw/char/grlib_apbuart.c @@ -1,7 +1,7 @@ /* * QEMU GRLIB APB UART Emulator * - * Copyright (c) 2010-2019 AdaCore + * Copyright (c) 2010-2024 AdaCore * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,7 @@ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" -#include "hw/sparc/grlib.h" +#include "hw/char/grlib_uart.h" #include "hw/sysbus.h" #include "qemu/module.h" #include "chardev/char-fe.h" diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c index 3bfe2544b7..c994d5dacc 100644 --- a/hw/intc/grlib_irqmp.c +++ b/hw/intc/grlib_irqmp.c @@ -3,7 +3,7 @@ * * (Multiprocessor and extended interrupt not supported) * - * Copyright (c) 2010-2019 AdaCore + * Copyright (c) 2010-2024 AdaCore * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ #include "hw/sysbus.h" #include "hw/qdev-properties.h" -#include "hw/sparc/grlib.h" +#include "hw/intc/grlib_irqmp.h" #include "trace.h" #include "qapi/error.h" diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 1e39d2e2d0..58784c099a 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -1,7 +1,7 @@ /* * QEMU Leon3 System Emulator * - * Copyright (c) 2010-2019 AdaCore + * Copyright (c) 2010-2024 AdaCore * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,7 +40,9 @@ #include "elf.h" #include "trace.h" -#include "hw/sparc/grlib.h" +#include "hw/timer/grlib_gptimer.h" +#include "hw/char/grlib_uart.h" +#include "hw/intc/grlib_irqmp.h" #include "hw/misc/grlib_ahb_apb_pnp.h" /* Default system clock. */ diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c index 5c4923c1e0..5c2cddcec3 100644 --- a/hw/timer/grlib_gptimer.c +++ b/hw/timer/grlib_gptimer.c @@ -1,7 +1,7 @@ /* * QEMU GRLIB GPTimer Emulator * - * Copyright (c) 2010-2019 AdaCore + * Copyright (c) 2010-2024 AdaCore * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,7 @@ */ #include "qemu/osdep.h" -#include "hw/sparc/grlib.h" +#include "hw/timer/grlib_gptimer.h" #include "hw/sysbus.h" #include "qemu/timer.h" #include "hw/irq.h" diff --git a/include/hw/char/grlib_uart.h b/include/hw/char/grlib_uart.h new file mode 100644 index 00..b67da6c62a --- /dev/null +++ b/include/hw/char/grlib_uart.h @@ -0,0 +1,30 @@ +/* + * QEMU GRLIB UART + * + * Copyright (c) 2024 AdaCore + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef GRLIB_UART_H +#define GRLIB_UART_H + +#define TYPE_GRLIB_APB_UART "grlib-apbuart" + +#endif diff --git a/include/hw/sparc/grlib.h b/include/hw/intc/grlib_irqmp.h si
[PATCH 3/9] intc/grlib_irqmp: implements the multiprocessor status register
This implements the multiprocessor status register in grlib-irqmp and bind it to a start signal, which will be later wired in leon3-generic to start a cpu. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/intc/grlib_irqmp.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c index 2bacc0ff56..be0e840181 100644 --- a/hw/intc/grlib_irqmp.c +++ b/hw/intc/grlib_irqmp.c @@ -63,6 +63,7 @@ struct IRQMP { unsigned int ncpus; IRQMPState *state; +qemu_irq start_signal[IRQMP_MAX_CPU]; qemu_irq irq; }; @@ -70,6 +71,7 @@ struct IRQMPState { uint32_t level; uint32_t pending; uint32_t clear; +uint32_t mpstatus; uint32_t broadcast; uint32_t mask[IRQMP_MAX_CPU]; @@ -180,10 +182,12 @@ static uint64_t grlib_irqmp_read(void *opaque, hwaddr addr, return state->force[0]; case CLEAR_OFFSET: -case MP_STATUS_OFFSET: /* Always read as 0 */ return 0; +case MP_STATUS_OFFSET: +return state->mpstatus; + case BROADCAST_OFFSET: return state->broadcast; @@ -222,8 +226,9 @@ static uint64_t grlib_irqmp_read(void *opaque, hwaddr addr, static void grlib_irqmp_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { -IRQMP *irqmp = opaque; +IRQMP *irqmp = opaque; IRQMPState *state; +int i; assert(irqmp != NULL); state = irqmp->state; @@ -256,7 +261,13 @@ static void grlib_irqmp_write(void *opaque, hwaddr addr, return; case MP_STATUS_OFFSET: -/* Read Only (no SMP support) */ +value &= 0x; +for (i = 0; i < irqmp->ncpus; i++) { +if ((value >> i) & 1) { +qemu_set_irq(irqmp->start_signal[i], 1); +state->mpstatus &= ~(1 << i); +} +} return; case BROADCAST_OFFSET: @@ -323,6 +334,8 @@ static void grlib_irqmp_reset(DeviceState *d) memset(irqmp->state, 0, sizeof *irqmp->state); irqmp->state->parent = irqmp; +irqmp->state->mpstatus = ((irqmp->ncpus - 1) << 28) +| ((1 << irqmp->ncpus) - 2); } static void grlib_irqmp_realize(DeviceState *dev, Error **errp) @@ -336,6 +349,9 @@ static void grlib_irqmp_realize(DeviceState *dev, Error **errp) } qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS); +/* Transitionning from 0 to 1 starts the CPUs. */ +qdev_init_gpio_out_named(dev, irqmp->start_signal, "grlib-start-cpu", + IRQMP_MAX_CPU); qdev_init_gpio_out_named(dev, &irqmp->irq, "grlib-irq", 1); memory_region_init_io(&irqmp->iomem, OBJECT(dev), &grlib_irqmp_ops, irqmp, "irqmp", IRQMP_REG_SIZE); -- 2.25.1
[PATCH 0/9] sparc/leon3: Add support for -smp
This series allows leon3 emulations to record up 4 CPUs. It requires some enhancements in the grlib_irqmp device and adding the cpu_index field in the asr17 instruction. It has been tested locally with various bareboard runtimes and through the Gitlab CI: https://gitlab.com/Helflym/qemu/-/pipelines/1127834623. Clément Chigot (9): sparc/grlib: split out the headers for each peripherals intc/grlib_irqmp: add ncpus property intc/grlib_irqmp: implements the multiprocessor status register intc/grlib_irqmp: implements multicore irq target/sparc: implement asr17 feature for smp target/sparc: simplify qemu_irq_ack leon3: implement multiprocessor leon3: check cpu_id in the tiny bootloader MAINTAINERS: replace Fabien by myself as Leon3 maintainer MAINTAINERS | 2 +- hw/char/grlib_apbuart.c | 4 +- hw/intc/grlib_irqmp.c | 97 hw/sparc/leon3.c | 145 +- hw/timer/grlib_gptimer.c | 4 +- include/hw/char/grlib_uart.h | 30 .../hw/{sparc/grlib.h => intc/grlib_irqmp.h} | 16 +- include/hw/timer/grlib_gptimer.h | 30 target/sparc/cpu.h| 2 +- target/sparc/helper.c | 16 ++ target/sparc/helper.h | 1 + target/sparc/int32_helper.c | 2 +- target/sparc/translate.c | 13 +- 13 files changed, 258 insertions(+), 104 deletions(-) create mode 100644 include/hw/char/grlib_uart.h rename include/hw/{sparc/grlib.h => intc/grlib_irqmp.h} (83%) create mode 100644 include/hw/timer/grlib_gptimer.h -- 2.25.1
[PATCH 7/9] leon3: implement multiprocessor
This allows to register more than one CPU on the leon3_generic machine. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/sparc/leon3.c | 106 +-- 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 6019fc4c2d..38fb8d9af1 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -52,6 +52,8 @@ #define LEON3_PROM_OFFSET(0x) #define LEON3_RAM_OFFSET (0x4000) +#define MAX_CPUS 4 + #define LEON3_UART_OFFSET (0x8100) #define LEON3_UART_IRQ (3) @@ -65,9 +67,12 @@ #define LEON3_AHB_PNP_OFFSET (0xF000) typedef struct ResetData { -SPARCCPU *cpu; -uint32_t entry;/* save kernel entry in case of reset */ -target_ulong sp;/* initial stack pointer */ +struct CPUResetData { +int id; +SPARCCPU *cpu; +target_ulong sp; /* initial stack pointer */ +} info[MAX_CPUS]; +uint32_t entry; /* save kernel entry in case of reset */ } ResetData; static uint32_t *gen_store_u32(uint32_t *code, hwaddr addr, uint32_t val) @@ -123,18 +128,19 @@ static void write_bootloader(CPUSPARCState *env, uint8_t *base, stl_p(p++, 0x0100); /* nop */ } -static void main_cpu_reset(void *opaque) +static void leon3_cpu_reset(void *opaque) { -ResetData *s = (ResetData *)opaque; -CPUState *cpu = CPU(s->cpu); -CPUSPARCState *env = &s->cpu->env; +struct CPUResetData *info = (struct CPUResetData *) opaque; +int id = info->id; +ResetData *s = (ResetData *)DO_UPCAST(ResetData, info[id], info); +CPUState *cpu = CPU(s->info[id].cpu); +CPUSPARCState *env = cpu_env(cpu); cpu_reset(cpu); - -cpu->halted = 0; -env->pc = s->entry; -env->npc= s->entry + 4; -env->regbase[6] = s->sp; +cpu->halted = cpu->cpu_index != 0; +env->pc = s->entry; +env->npc = s->entry + 4; +env->regbase[6] = s->info[id].sp; } static void leon3_cache_control_int(CPUSPARCState *env) @@ -168,8 +174,8 @@ static void leon3_cache_control_int(CPUSPARCState *env) static void leon3_irq_ack(CPUSPARCState *env, int intno) { -/* No SMP support yet. */ -grlib_irqmp_ack(env->irq_manager, 0, intno); +CPUState *cpu = CPU(env_cpu(env)); +grlib_irqmp_ack(env->irq_manager, cpu->cpu_index, intno); } /* @@ -211,6 +217,20 @@ static void leon3_set_pil_in(void *opaque, int n, int level) } } +static void leon3_start_cpu_async_work(CPUState *cpu, run_on_cpu_data data) +{ +cpu->halted = 0; +} + +static void leon3_start_cpu(void *opaque, int n, int level) +{ +CPUState *cs = CPU(opaque); + +if (level) { +async_run_on_cpu(cs, leon3_start_cpu_async_work, RUN_ON_CPU_NULL); +} +} + static void leon3_irq_manager(CPUSPARCState *env, int intno) { leon3_irq_ack(env, intno); @@ -236,17 +256,21 @@ static void leon3_generic_hw_init(MachineState *machine) AHBPnp *ahb_pnp; APBPnp *apb_pnp; -/* Init CPU */ -cpu = SPARC_CPU(cpu_create(machine->cpu_type)); -env = &cpu->env; +reset_info = g_malloc0(sizeof(ResetData)); -cpu_sparc_set_id(env, 0); +for (i = 0; i < machine->smp.cpus; i++) { +/* Init CPU */ +cpu = SPARC_CPU(cpu_create(machine->cpu_type)); +env = &cpu->env; -/* Reset data */ -reset_info= g_new0(ResetData, 1); -reset_info->cpu = cpu; -reset_info->sp= LEON3_RAM_OFFSET + ram_size; -qemu_register_reset(main_cpu_reset, reset_info); +cpu_sparc_set_id(env, i); + +/* Reset data */ +reset_info->info[i].id = i; +reset_info->info[i].cpu = cpu; +reset_info->info[i].sp = LEON3_RAM_OFFSET + ram_size; +qemu_register_reset(leon3_cpu_reset, &reset_info->info[i]); +} ahb_pnp = GRLIB_AHB_PNP(qdev_new(TYPE_GRLIB_AHB_PNP)); sysbus_realize_and_unref(SYS_BUS_DEVICE(ahb_pnp), &error_fatal); @@ -264,14 +288,28 @@ static void leon3_generic_hw_init(MachineState *machine) /* Allocate IRQ manager */ irqmpdev = qdev_new(TYPE_GRLIB_IRQMP); +object_property_set_int(OBJECT(irqmpdev), "ncpus", machine->smp.cpus, +&error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(irqmpdev), &error_fatal); -qdev_init_gpio_in_named_with_opaque(DEVICE(cpu), leon3_set_pil_in, -env, "pil", 1); -qdev_connect_gpio_out_named(irqmpdev, "grlib-irq", 0, -qdev_get_gpio_in_named(DEVICE(cpu), "pil", 0)); + +for (i = 0; i < machine->smp.cpus; i++) { +cpu = reset_info->info[i].cpu; +env = &cpu->env; +qdev_init_gpio_in_named_with_opaque(DEVICE(cpu), leon3_start_cpu, +cpu, "start_cpu", 1); +qdev_connect_gpio_out_named(irqmpdev, "grlib-start-cpu", i, +qdev_get_gpio_in_named(DEVICE(cpu)
[PATCH 2/9] intc/grlib_irqmp: add ncpus property
This adds a "ncpus" property to the "grlib-irqmp" device to be used later, this required a little refactoring of how we initialize the device (ie: use realize instead of init). Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/intc/grlib_irqmp.c | 30 +- hw/sparc/leon3.c | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c index c994d5dacc..2bacc0ff56 100644 --- a/hw/intc/grlib_irqmp.c +++ b/hw/intc/grlib_irqmp.c @@ -1,7 +1,7 @@ /* * QEMU GRLIB IRQMP Emulator * - * (Multiprocessor and extended interrupt not supported) + * (Extended interrupt not supported) * * Copyright (c) 2010-2024 AdaCore * @@ -61,6 +61,7 @@ struct IRQMP { MemoryRegion iomem; +unsigned int ncpus; IRQMPState *state; qemu_irq irq; }; @@ -324,33 +325,44 @@ static void grlib_irqmp_reset(DeviceState *d) irqmp->state->parent = irqmp; } -static void grlib_irqmp_init(Object *obj) +static void grlib_irqmp_realize(DeviceState *dev, Error **errp) { -IRQMP *irqmp = GRLIB_IRQMP(obj); -SysBusDevice *dev = SYS_BUS_DEVICE(obj); +IRQMP *irqmp = GRLIB_IRQMP(dev); -qdev_init_gpio_in(DEVICE(obj), grlib_irqmp_set_irq, MAX_PILS); -qdev_init_gpio_out_named(DEVICE(obj), &irqmp->irq, "grlib-irq", 1); -memory_region_init_io(&irqmp->iomem, obj, &grlib_irqmp_ops, irqmp, +if ((!irqmp->ncpus) || (irqmp->ncpus > IRQMP_MAX_CPU)) { +error_setg(errp, "Invalid ncpus properties: " + "%u, must be 0 < ncpus =< %u.", irqmp->ncpus, + IRQMP_MAX_CPU); +} + +qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS); +qdev_init_gpio_out_named(dev, &irqmp->irq, "grlib-irq", 1); +memory_region_init_io(&irqmp->iomem, OBJECT(dev), &grlib_irqmp_ops, irqmp, "irqmp", IRQMP_REG_SIZE); irqmp->state = g_malloc0(sizeof *irqmp->state); -sysbus_init_mmio(dev, &irqmp->iomem); +sysbus_init_mmio(SYS_BUS_DEVICE(dev), &irqmp->iomem); } +static Property grlib_irqmp_properties[] = { +DEFINE_PROP_UINT32("ncpus", IRQMP, ncpus, 1), +DEFINE_PROP_END_OF_LIST(), +}; + static void grlib_irqmp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); +dc->realize = grlib_irqmp_realize; dc->reset = grlib_irqmp_reset; +device_class_set_props(dc, grlib_irqmp_properties); } static const TypeInfo grlib_irqmp_info = { .name = TYPE_GRLIB_IRQMP, .parent= TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(IRQMP), -.instance_init = grlib_irqmp_init, .class_init= grlib_irqmp_class_init, }; diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 58784c099a..7b9809b81f 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -263,11 +263,11 @@ static void leon3_generic_hw_init(MachineState *machine) /* Allocate IRQ manager */ irqmpdev = qdev_new(TYPE_GRLIB_IRQMP); +sysbus_realize_and_unref(SYS_BUS_DEVICE(irqmpdev), &error_fatal); qdev_init_gpio_in_named_with_opaque(DEVICE(cpu), leon3_set_pil_in, env, "pil", 1); qdev_connect_gpio_out_named(irqmpdev, "grlib-irq", 0, qdev_get_gpio_in_named(DEVICE(cpu), "pil", 0)); -sysbus_realize_and_unref(SYS_BUS_DEVICE(irqmpdev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(irqmpdev), 0, LEON3_IRQMP_OFFSET); env->irq_manager = irqmpdev; env->qemu_irq_ack = leon3_irq_manager; -- 2.25.1
[PATCH 5/9] target/sparc: implement asr17 feature for smp
This allows the guest program to know its cpu id. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- target/sparc/helper.c| 16 target/sparc/helper.h| 1 + target/sparc/translate.c | 13 +++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/target/sparc/helper.c b/target/sparc/helper.c index bd10b60e4b..2247e243b5 100644 --- a/target/sparc/helper.c +++ b/target/sparc/helper.c @@ -212,4 +212,20 @@ void helper_power_down(CPUSPARCState *env) env->npc = env->pc + 4; cpu_loop_exit(cs); } + +target_ulong helper_rdasr17(CPUSPARCState *env) +{ +CPUState *cs = env_cpu(env); +target_ulong val; + +/* + * TODO: There are many more fields to be filled, + * some of which are writable. + */ +val = env->def.nwindows - 1;/* [4:0] NWIN */ +val |= 1 << 8; /* [8] V8*/ +val |= (cs->cpu_index) << 28; /* [31:28] INDEX */ + +return val; +} #endif diff --git a/target/sparc/helper.h b/target/sparc/helper.h index 55eff66283..fc818b8678 100644 --- a/target/sparc/helper.h +++ b/target/sparc/helper.h @@ -2,6 +2,7 @@ DEF_HELPER_1(rett, void, env) DEF_HELPER_2(wrpsr, void, env, tl) DEF_HELPER_1(rdpsr, tl, env) +DEF_HELPER_1(rdasr17, tl, env) DEF_HELPER_1(power_down, void, env) #else DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 9387299559..1cabda9565 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -37,6 +37,7 @@ #ifdef TARGET_SPARC64 # define gen_helper_rdpsr(D, E) qemu_build_not_reached() +# define gen_helper_rdasr17(D, E) qemu_build_not_reached() # define gen_helper_rett(E) qemu_build_not_reached() # define gen_helper_power_down(E) qemu_build_not_reached() # define gen_helper_wrpsr(E, S) qemu_build_not_reached() @@ -2681,16 +2682,8 @@ static bool trans_RDY(DisasContext *dc, arg_RDY *a) static TCGv do_rd_leon3_config(DisasContext *dc, TCGv dst) { -uint32_t val; - -/* - * TODO: There are many more fields to be filled, - * some of which are writable. - */ -val = dc->def->nwindows - 1; /* [4:0] NWIN */ -val |= 1 << 8; /* [8] V8 */ - -return tcg_constant_tl(val); +gen_helper_rdasr17(dst, tcg_env); +return dst; } TRANS(RDASR17, ASR17, do_rd_special, true, a->rd, do_rd_leon3_config) -- 2.25.1
Re: [PATCH 9/9] MAINTAINERS: replace Fabien by myself as Leon3 maintainer
On Fri, Jan 5, 2024 at 11:24 AM Clément Chigot wrote: > > CC: Fabien Chouteau Typo here... Should have been chout...@adacore.com... I'll update it in v2 if one is needed. Otherwise, could the one pushing these patches make the change for me ? Thanks and sorry for that. > Signed-off-by: Clément Chigot > --- > MAINTAINERS | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 395f26ba86..a065e0b21f 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1694,7 +1694,7 @@ F: hw/rtc/sun4v-rtc.c > F: include/hw/rtc/sun4v-rtc.h > > Leon3 > -M: Fabien Chouteau > +M: Clément Chigot > M: Frederic Konrad > S: Maintained > F: hw/sparc/leon3.c > -- > 2.25.1 >
Re: [PATCH 1/9] hw/hppa/machine: Allow up to 3840 MB total memory
On 1/4/24 19:36, del...@kernel.org wrote: From: Helge Deller The physical hardware allows DIMMs of 4 MB size and above, allowing up to 3840 MB of memory, but is restricted by setup code to 3 GB. Increase the limit to allow up to the maximum amount of memory. Btw. the memory area from 0xf000. to 0x. is reserved by the architecture for firmware and I/O memory and can not be used for standard memory. Signed-off-by: Helge Deller Noticed-by: Nelson H. F. Beebe Fixes: b7746b1194c8 ("hw/hppa/machine: Restrict the total memory size to 3GB") --- hw/hppa/machine.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index c8da7c18d5..6181f4b747 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -276,6 +276,7 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine) unsigned int smp_cpus = machine->smp.cpus; TranslateFn *translate; MemoryRegion *cpu_region; +ram_addr_t ram_max; /* Create CPUs. */ for (unsigned int i = 0; i < smp_cpus; i++) { @@ -288,8 +289,10 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine) */ if (hppa_is_pa20(&cpu[0]->env)) { translate = translate_pa20; +ram_max = 0xf000; /* 3.75 GB (limited by 32-bit firmware) */ } else { translate = translate_pa10; +ram_max = 0xf000; /* 3.75 GB (32-bit CPU) */ } for (unsigned int i = 0; i < smp_cpus; i++) { @@ -311,9 +314,9 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine) cpu_region); /* Main memory region. */ -if (machine->ram_size > 3 * GiB) { -error_report("RAM size is currently restricted to 3GB"); -exit(EXIT_FAILURE); +if (machine->ram_size > ram_max) { +info_report("Max RAM size limited to %ld MB", ram_max / MiB); Need to use RAM_ADDR_FMT instead of "%ld" here. Will fix in v2. Helge +machine->ram_size = ram_max; } memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);
Re: [PATCH v2 40/43] contrib/plugins: extend execlog to track register changes
Hello Alex, just reporting below what might be a riscv only oddity (also applies to patch 41 but easier to report here). Le 03/01/2024 à 18:33, Alex Bennée a écrit : With the new plugin register API we can now track changes to register values. Currently the implementation is fairly dumb which will slow down if a large number of register values are being tracked. This could be improved by only instrumenting instructions which mention registers we are interested in tracking. Example usage: ./qemu-aarch64 -D plugin.log -d plugin \ -cpu max,sve256=on \ -plugin contrib/plugins/libexeclog.so,reg=sp,reg=z\* \ ./tests/tcg/aarch64-linux-user/sha512-sve will display in the execlog any changes to the stack pointer (sp) and the SVE Z registers. Signed-off-by: Alex Bennée Cc: Akihiko Odaki Based-On: <20231025093128.33116-19-akihiko.od...@daynix.com> +static registers_init(int vcpu_index) +{ +GPtrArray *registers = g_ptr_array_new(); +g_autoptr(GArray) reg_list = qemu_plugin_get_registers(vcpu_index); + +if (reg_list && reg_list->len) { +/* + * Go through each register in the complete list and + * see if we want to track it. + */ +for (int r = 0; r < reg_list->len; r++) { +qemu_plugin_reg_descriptor *rd = &g_array_index( +reg_list, qemu_plugin_reg_descriptor, r); riscv csrs are not continously numbered and the dynamically generated gdb xml seems to follow that scheme. So the calls to Glib string functions output quite a few assertion warnings because for the non existing csrs rd->name is NULL (and there are a bit less than 4000 such cases for rv64g). Checking for NULL and then continue is a simple way to solve the issue, but I am not sure this is the proper way to proceed, as it might stand in the generation of the riscv xml description for gdb. Cheers, Frédéric +for (int p = 0; p < rmatches->len; p++) { +g_autoptr(GPatternSpec) pat = g_pattern_spec_new(rmatches->pdata[p]); +if (g_pattern_match_string(pat, rd->name)) { +Register *reg = init_vcpu_register(vcpu_index, rd); +g_ptr_array_add(registers, reg); +} +} +} +} +cpus[num_cpus].registers = registers; +}
Re: [PATCH 02/10] hw/audio/virtio-sound: allocate all streams in advance
Hi On Fri, Jan 5, 2024 at 12:34 AM Volker Rümelin wrote: > > It is much easier to migrate an array of structs than individual > structs that are accessed via a pointer to a pointer to an array > of pointers to struct, where some pointers can also be NULL. > > For this reason, the audio streams are already allocated during > the realization phase and all stream variables that are constant > at runtime are initialised immediately after allocation. This is > a step towards being able to migrate the audio streams of the > virtio sound device after the next few patches. > > Signed-off-by: Volker Rümelin > --- > hw/audio/virtio-snd.c | 35 ++- > include/hw/audio/virtio-snd.h | 1 + > 2 files changed, 23 insertions(+), 13 deletions(-) > > diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c > index 8344f61c64..36b1bb502c 100644 > --- a/hw/audio/virtio-snd.c > +++ b/hw/audio/virtio-snd.c > @@ -447,11 +447,9 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, > uint32_t stream_id) > > stream = virtio_snd_pcm_get_stream(s, stream_id); > if (stream == NULL) { > -stream = g_new0(VirtIOSoundPCMStream, 1); > +stream = &s->streams[stream_id]; > stream->active = false; > -stream->id = stream_id; > stream->pcm = s->pcm; > -stream->s = s; > QSIMPLEQ_INIT(&stream->queue); > QSIMPLEQ_INIT(&stream->invalid); note: I can't find where s->pcm->streams[stream_id] is reset to NULL on pcm_release... > > @@ -463,14 +461,6 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, > uint32_t stream_id) > } > > virtio_snd_get_qemu_audsettings(&as, params); > -stream->info.direction = stream_id < s->snd_conf.streams / 2 + > -(s->snd_conf.streams & 1) ? VIRTIO_SND_D_OUTPUT : VIRTIO_SND_D_INPUT; > -stream->info.hdr.hda_fn_nid = VIRTIO_SOUND_HDA_FN_NID; > -stream->info.features = 0; > -stream->info.channels_min = 1; > -stream->info.channels_max = as.nchannels; > -stream->info.formats = supported_formats; > -stream->info.rates = supported_rates; > stream->params = *params; > > stream->positions[0] = VIRTIO_SND_CHMAP_FL; > @@ -1074,6 +1064,24 @@ static void virtio_snd_realize(DeviceState *dev, Error > **errp) > vsnd->vmstate = > qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd); > > +vsnd->streams = g_new0(VirtIOSoundPCMStream, vsnd->snd_conf.streams); > + > +for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) { > +VirtIOSoundPCMStream *stream = &vsnd->streams[i]; > + > +stream->id = i; > +stream->s = vsnd; > +stream->info.hdr.hda_fn_nid = VIRTIO_SOUND_HDA_FN_NID; > +stream->info.features = 0; > +stream->info.formats = supported_formats; > +stream->info.rates = supported_rates; > +stream->info.direction = > +i < vsnd->snd_conf.streams / 2 + (vsnd->snd_conf.streams & 1) > +? VIRTIO_SND_D_OUTPUT : VIRTIO_SND_D_INPUT; > +stream->info.channels_min = 1; > +stream->info.channels_max = 2; Fixed max channels set to 2.. ? before this was set to MIN(AUDIO_MAX_CHANNELS, params->channels) > +} > + > vsnd->pcm = g_new0(VirtIOSoundPCM, 1); > vsnd->pcm->snd = vsnd; > vsnd->pcm->streams = > @@ -1314,14 +1322,13 @@ static void virtio_snd_unrealize(DeviceState *dev) > qemu_del_vm_change_state_handler(vsnd->vmstate); > trace_virtio_snd_unrealize(vsnd); > > -if (vsnd->pcm) { > +if (vsnd->streams) { > if (vsnd->pcm->streams) { > for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) { > stream = vsnd->pcm->streams[i]; > if (stream) { > virtio_snd_process_cmdq(stream->s); > virtio_snd_pcm_close(stream); > -g_free(stream); > } > } > g_free(vsnd->pcm->streams); > @@ -1329,6 +1336,8 @@ static void virtio_snd_unrealize(DeviceState *dev) > g_free(vsnd->pcm->pcm_params); > g_free(vsnd->pcm); > vsnd->pcm = NULL; > +g_free(vsnd->streams); > +vsnd->streams = NULL; > } > AUD_remove_card(&vsnd->card); > virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_CONTROL]); > diff --git a/include/hw/audio/virtio-snd.h b/include/hw/audio/virtio-snd.h > index ea6315f59b..05b4490488 100644 > --- a/include/hw/audio/virtio-snd.h > +++ b/include/hw/audio/virtio-snd.h > @@ -216,6 +216,7 @@ struct VirtIOSound { > VirtQueue *queues[VIRTIO_SND_VQ_MAX]; > uint64_t features; > VirtIOSoundPCM *pcm; > +VirtIOSoundPCMStream *streams; > QEMUSoundCard card; > VMChangeStateEntry *vmstate; > virtio_snd_config snd_conf; > -- > 2.35.3 >
Re: [PATCH 03/10] hw/audio/virtio-sound: split out virtio_snd_pcm_start_stop()
On Fri, Jan 5, 2024 at 12:34 AM Volker Rümelin wrote: > > Split out virtio_snd_pcm_start_stop(). This is a preparation > for the next patch so that it doesn't become too big. > > Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau > --- > hw/audio/trace-events | 3 ++- > hw/audio/virtio-snd.c | 57 --- > 2 files changed, 39 insertions(+), 21 deletions(-) > > diff --git a/hw/audio/trace-events b/hw/audio/trace-events > index b1870ff224..7554bfcc60 100644 > --- a/hw/audio/trace-events > +++ b/hw/audio/trace-events > @@ -50,7 +50,8 @@ virtio_snd_unrealize(void *snd) "snd %p: unrealize" > virtio_snd_handle_pcm_set_params(uint32_t stream) "VIRTIO_SND_PCM_SET_PARAMS > called for stream %"PRIu32 > virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for > queue %p" > virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called > for stream %"PRIu32 > -virtio_snd_handle_pcm_start_stop(const char *code, uint32_t stream) "%s > called for stream %"PRIu32 > +virtio_snd_handle_pcm_start(uint32_t stream) "VIRTIO_SND_R_PCM_START called > for stream %"PRIu32 > +virtio_snd_handle_pcm_stop(uint32_t stream) "VIRTIO_SND_R_PCM_STOP called > for stream %"PRIu32 > virtio_snd_handle_pcm_release(uint32_t stream) "VIRTIO_SND_PCM_RELEASE > called for stream %"PRIu32 > virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = > %"PRIu32" == %s" > virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called" > diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c > index 36b1bb502c..040bc32ebe 100644 > --- a/hw/audio/virtio-snd.c > +++ b/hw/audio/virtio-snd.c > @@ -534,7 +534,42 @@ static void virtio_snd_handle_pcm_prepare(VirtIOSound *s, > } > > /* > - * Handles VIRTIO_SND_R_PCM_START. > + * Starts/Stops a VirtIOSound card stream. > + * Returns the response status code. (VIRTIO_SND_S_*). > + * > + * @s: VirtIOSound device > + * @stream_id: stream id > + * @start: whether to start or stop the stream > + */ > +static uint32_t virtio_snd_pcm_start_stop(VirtIOSound *s, > + uint32_t stream_id, > + bool start) > +{ > +VirtIOSoundPCMStream *stream; > + > +stream = virtio_snd_pcm_get_stream(s, stream_id); > +if (!stream) { > +return cpu_to_le32(VIRTIO_SND_S_BAD_MSG); > +} > + > +if (start) { > +trace_virtio_snd_handle_pcm_start(stream_id); > +} else { > +trace_virtio_snd_handle_pcm_stop(stream_id); > +} > + > +stream->active = start; > +if (stream->info.direction == VIRTIO_SND_D_OUTPUT) { > +AUD_set_active_out(stream->voice.out, start); > +} else { > +AUD_set_active_in(stream->voice.in, start); > +} > + > +return cpu_to_le32(VIRTIO_SND_S_OK); > +} > + > +/* > + * Handles VIRTIO_SND_R_PCM_START and VIRTIO_SND_R_PCM_STOP. > * > * @s: VirtIOSound device > * @cmd: The request command queue element from VirtIOSound cmdq field > @@ -544,7 +579,6 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound > *s, > virtio_snd_ctrl_command *cmd, > bool start) > { > -VirtIOSoundPCMStream *stream; > virtio_snd_pcm_hdr req; > uint32_t stream_id; > size_t msg_sz = iov_to_buf(cmd->elem->out_sg, > @@ -562,24 +596,7 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound > *s, > } > > stream_id = le32_to_cpu(req.stream_id); > -cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_OK); > -trace_virtio_snd_handle_pcm_start_stop(start ? "VIRTIO_SND_R_PCM_START" : > -"VIRTIO_SND_R_PCM_STOP", stream_id); > - > -stream = virtio_snd_pcm_get_stream(s, stream_id); > -if (stream) { > -stream->active = start; > -if (stream->info.direction == VIRTIO_SND_D_OUTPUT) { > -AUD_set_active_out(stream->voice.out, start); > -} else { > -AUD_set_active_in(stream->voice.in, start); > -} > -} else { > -error_report("Invalid stream id: %"PRIu32, stream_id); > -cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_BAD_MSG); > -return; > -} > -stream->active = start; > +cmd->resp.code = virtio_snd_pcm_start_stop(s, stream_id, start); > } > > /* > -- > 2.35.3 >
Re: [PATCH v9 1/9] machine: Use error handling when CPU type is checked
On 4/12/23 01:47, Gavin Shan wrote: Functions that use an Error **errp parameter to return errors should not also report them to the user, because reporting is the caller's job. The principle is violated by machine_run_board_init() because it calls error_report(), error_printf(), and exit(1) when the machine doesn't support the requested CPU type. Clean this up by using error_setg() and error_append_hint() instead. No functional change, as the only caller passes &error_fatal. Suggested-by: Igor Mammedov Signed-off-by: Gavin Shan Reviewed-by: Markus Armbruster --- v9: Improved change log (Markus) --- hw/core/machine.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 0c17398141..bde7f4af6d 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1466,15 +1466,16 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error * if (!machine_class->valid_cpu_types[i]) { /* The user specified CPU is not valid */ -error_report("Invalid CPU type: %s", machine->cpu_type); -error_printf("The valid types are: %s", - machine_class->valid_cpu_types[0]); +error_setg(errp, "Invalid CPU type: %s", machine->cpu_type); +error_append_hint(errp, "The valid types are: %s", + machine_class->valid_cpu_types[0]); for (i = 1; machine_class->valid_cpu_types[i]; i++) { -error_printf(", %s", machine_class->valid_cpu_types[i]); +error_append_hint(errp, ", %s", + machine_class->valid_cpu_types[i]); } -error_printf("\n"); -exit(1); +error_append_hint(&errp, "\n"); This doesn't build: hw/core/machine.c:1488:31: error: incompatible pointer types passing 'Error ***' (aka 'struct Error ***') to parameter of type 'Error *const *' (aka 'struct Error *const *'); remove & [-Werror,-Wincompatible-pointer-types] error_append_hint(&errp, "\n"); ^ +return; } } Squashing: -- >8 -- diff --git a/hw/core/machine.c b/hw/core/machine.c index 021044aaaf..1898d1d1d7 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1487,3 +1487,3 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error * -error_append_hint(&errp, "\n"); +error_append_hint(errp, "\n"); return; ---
Re: [PATCH v8 2/9] machine: Introduce helper is_cpu_type_supported()
On 4/12/23 00:13, Gavin Shan wrote: Hi Phil, On 12/1/23 20:53, Philippe Mathieu-Daudé wrote: On 29/11/23 05:20, Gavin Shan wrote: The logic, to check if the specified CPU type is supported in machine_run_board_init(), is independent enough. Factor it out into helper is_cpu_type_supported(). machine_run_board_init() looks a bit clean with this. Since we're here, @machine_class is renamed to @mc to avoid multiple line spanning of code. The comments are tweaked a bit either. No functional change intended. Signed-off-by: Gavin Shan --- v8: Move the precise message hint to PATCH[v8 3/9] (Gavin) --- hw/core/machine.c | 83 +-- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index bde7f4af6d..1797e002f9 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1387,13 +1387,53 @@ out: return r; } +static bool is_cpu_type_supported(const MachineState *machine, Error **errp) +{ + MachineClass *mc = MACHINE_GET_CLASS(machine); + ObjectClass *oc = object_class_by_name(machine->cpu_type); + CPUClass *cc; + int i; + + /* + * Check if the user specified CPU type is supported when the valid + * CPU types have been determined. Note that the user specified CPU + * type is provided through '-cpu' option. + */ + if (mc->valid_cpu_types && machine->cpu_type) { + for (i = 0; mc->valid_cpu_types[i]; i++) { + if (object_class_dynamic_cast(oc, mc->valid_cpu_types[i])) { + break; + } + } + + /* The user specified CPU type isn't valid */ + if (!mc->valid_cpu_types[i]) { + error_setg(errp, "Invalid CPU type: %s", machine->cpu_type); + error_append_hint(errp, "The valid types are: %s", + mc->valid_cpu_types[0]); + for (i = 1; mc->valid_cpu_types[i]; i++) { + error_append_hint(errp, ", %s", mc->valid_cpu_types[i]); + } + + error_append_hint(errp, "\n"); + return false; + } + } + + /* Check if CPU type is deprecated and warn if so */ + cc = CPU_CLASS(oc); + if (cc && cc->deprecation_note) { cc can't be NULL, right? Otherwise, Reviewed-by: Philippe Mathieu-Daudé machine->cpu_type is either mc->default_cpu_type or returned from parse_cpu_option(). It can be NULL if mc->default_cpu_type is invalid, which is a program error. So assert(cc != NULL) should be used instead. I will fold the change to PATCH[v9 3/9] cpu_type and cc an be NULL with the 'none' machine. + warn_report("CPU model %s is deprecated -- %s", + machine->cpu_type, cc->deprecation_note); + } + + return true; +} Thanks, Gavin
Re: [PATCH 2/9] intc/grlib_irqmp: add ncpus property
On 5/1/24 11:24, Clément Chigot wrote: This adds a "ncpus" property to the "grlib-irqmp" device to be used later, this required a little refactoring of how we initialize the device (ie: use realize instead of init). Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/intc/grlib_irqmp.c | 30 +- hw/sparc/leon3.c | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) Reviewed-by: Philippe Mathieu-Daudé
Re: [PATCH 3/9] intc/grlib_irqmp: implements the multiprocessor status register
Hi Clément, On 5/1/24 11:24, Clément Chigot wrote: This implements the multiprocessor status register in grlib-irqmp and bind it to a start signal, which will be later wired in leon3-generic to start a cpu. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/intc/grlib_irqmp.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) @@ -323,6 +334,8 @@ static void grlib_irqmp_reset(DeviceState *d) memset(irqmp->state, 0, sizeof *irqmp->state); irqmp->state->parent = irqmp; +irqmp->state->mpstatus = ((irqmp->ncpus - 1) << 28) Can you #define this magic '28' number? +| ((1 << irqmp->ncpus) - 2); } static void grlib_irqmp_realize(DeviceState *dev, Error **errp) @@ -336,6 +349,9 @@ static void grlib_irqmp_realize(DeviceState *dev, Error **errp) } qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS); +/* Transitionning from 0 to 1 starts the CPUs. */ What about 1 -> 0? +qdev_init_gpio_out_named(dev, irqmp->start_signal, "grlib-start-cpu", + IRQMP_MAX_CPU); qdev_init_gpio_out_named(dev, &irqmp->irq, "grlib-irq", 1); memory_region_init_io(&irqmp->iomem, OBJECT(dev), &grlib_irqmp_ops, irqmp, "irqmp", IRQMP_REG_SIZE);
Re: [PATCH 6/9] target/sparc: simplify qemu_irq_ack
On 5/1/24 11:24, Clément Chigot wrote: This is a simple cleanup, since env is passed to qemu_irq_ack it can be accessed from inside qemu_irq_ack. Just drop this parameter. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/sparc/leon3.c| 8 target/sparc/cpu.h | 2 +- target/sparc/int32_helper.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) Reviewed-by: Philippe Mathieu-Daudé
Re: [PATCH 05/10] hw/audio/virtio-sound: return correct command response size
Hi On Fri, Jan 5, 2024 at 12:34 AM Volker Rümelin wrote: > > The payload size returned by command VIRTIO_SND_R_PCM_INFO is > wrong. The code in process_cmd() assumes that all commands > return only a virtio_snd_hdr payload, but some commands like > VIRTIO_SND_R_PCM_INFO may return an additional payload. > > Add a zero initialized payload_size variable to struct > virtio_snd_ctrl_command to allow for additional payloads. > > Signed-off-by: Volker Rümelin > --- > hw/audio/virtio-snd.c | 7 +-- > include/hw/audio/virtio-snd.h | 1 + > 2 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c > index a2817a64b5..9f3269d72b 100644 > --- a/hw/audio/virtio-snd.c > +++ b/hw/audio/virtio-snd.c > @@ -262,12 +262,13 @@ static void virtio_snd_handle_pcm_info(VirtIOSound *s, > memset(&pcm_info[i].padding, 0, 5); > } > > +cmd->payload_size = sizeof(virtio_snd_pcm_info) * count; > cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_OK); > iov_from_buf(cmd->elem->in_sg, > cmd->elem->in_num, > sizeof(virtio_snd_hdr), > pcm_info, > - sizeof(virtio_snd_pcm_info) * count); > + cmd->payload_size); iov_from_buf() return value should probably be checked to match the expected written size.. The earlier check for iov_size() is then probably redundant. Hmm, it checks for req.size, which should probably match sizeof(virtio_snd_pcm_info) too. > } > > /* > @@ -805,7 +806,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd) > 0, > &cmd->resp, > sizeof(virtio_snd_hdr)); > -virtqueue_push(cmd->vq, cmd->elem, sizeof(virtio_snd_hdr)); > +virtqueue_push(cmd->vq, cmd->elem, > + sizeof(virtio_snd_hdr) + cmd->payload_size); > virtio_notify(VIRTIO_DEVICE(s), cmd->vq); > } > > @@ -856,6 +858,7 @@ static void virtio_snd_handle_ctrl(VirtIODevice *vdev, > VirtQueue *vq) > cmd->elem = elem; > cmd->vq = vq; > cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_OK); > +/* implicit cmd->payload_size = 0; */ > QTAILQ_INSERT_TAIL(&s->cmdq, cmd, next); > elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); > } > diff --git a/include/hw/audio/virtio-snd.h b/include/hw/audio/virtio-snd.h > index d1a68444d0..d6e08bd30d 100644 > --- a/include/hw/audio/virtio-snd.h > +++ b/include/hw/audio/virtio-snd.h > @@ -210,6 +210,7 @@ struct virtio_snd_ctrl_command { > VirtQueue *vq; > virtio_snd_hdr ctrl; > virtio_snd_hdr resp; > +size_t payload_size; > QTAILQ_ENTRY(virtio_snd_ctrl_command) next; > }; > #endif > -- > 2.35.3 > otherwise, lgtm. Should it be backported to -stable ? Reviewed-by: Marc-André Lureau
Re: [PATCH v9 01/11] virtio: split into vhost-user-base and vhost-user-device
Philippe Mathieu-Daudé writes: > On 4/1/24 22:09, Alex Bennée wrote: >> Lets keep a cleaner split between the base class and the derived >> vhost-user-device which we can use for generic vhost-user stubs. This >> includes an update to introduce the vq_size property so the number of >> entries in a virtq can be defined. >> Signed-off-by: Alex Bennée >> --- >> v5 >>- s/parent/parent_obj/ >>- remove left over vhost-user-device.h >>- use DEFINE_TYPES >> v6 >>- rebase and set .abstract = true for vhost-user-device >> v7 >>- checkpatch line length + MAINTAINERS >>- s/abstract = true/dc->user_creatable = false/ for both mmio and pci >> --- >> MAINTAINERS | 6 + >> ...{vhost-user-device.h => vhost-user-base.h} | 21 +- >> hw/virtio/vhost-user-base.c | 346 ++ >> hw/virtio/vhost-user-device-pci.c | 13 +- >> hw/virtio/vhost-user-device.c | 338 + >> hw/virtio/meson.build | 1 + >> 6 files changed, 383 insertions(+), 342 deletions(-) >> rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%) >> create mode 100644 hw/virtio/vhost-user-base.c > > >> @@ -358,6 +42,9 @@ static void vud_class_init(ObjectClass *klass, void *data) >> { >> DeviceClass *dc = DEVICE_CLASS(klass); >> +/* Reason: stop inexperienced users confusing themselves */ >> +dc->user_creatable = false; > > > What about making VHOST_USER_DEVICE_PCI and > TYPE_VHOST_USER_DEVICE TypeInfos abstract instead? I had in a previous iteration (v7) but AIUI abstract really means something different - the device can be instantiated but we just want to stop the user from creating it arbitrarily. > >> + >> device_class_set_props(dc, vud_properties); >> dc->vmsd = &vud_vmstate; >> set_bit(DEVICE_CATEGORY_INPUT, dc->categories); >> @@ -366,14 +53,11 @@ static void vud_class_init(ObjectClass *klass, void >> *data) >> static const TypeInfo vud_info = { >> .name = TYPE_VHOST_USER_DEVICE, >> .parent = TYPE_VHOST_USER_BASE, >> -.instance_size = sizeof(VHostUserBase), >> .class_init = vud_class_init, >> -.class_size = sizeof(VHostUserBaseClass), >> }; -- Alex Bennée Virtualisation Tech Lead @ Linaro
Re: [PATCH 06/10] hw/audio/virtio-sound: introduce virtio_snd_pcm_open()
On Fri, Jan 5, 2024 at 12:34 AM Volker Rümelin wrote: > > Split out the function virtio_snd_pcm_open() from > virtio_snd_pcm_prepare(). A later patch also needs > the new function. There is no functional change. > > Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau > --- > hw/audio/virtio-snd.c | 57 +++ > 1 file changed, 31 insertions(+), 26 deletions(-) > > diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c > index 9f3269d72b..a1d2b3367e 100644 > --- a/hw/audio/virtio-snd.c > +++ b/hw/audio/virtio-snd.c > @@ -443,6 +443,36 @@ static void virtio_snd_get_qemu_audsettings(audsettings > *as, > as->endianness = target_words_bigendian() ? 1 : 0; > } > > +/* > + * Open a stream. > + * > + * @stream: VirtIOSoundPCMStream *stream > + */ > +static void virtio_snd_pcm_open(VirtIOSoundPCMStream *stream) > +{ > +virtio_snd_get_qemu_audsettings(&stream->as, &stream->params); > +stream->positions[0] = VIRTIO_SND_CHMAP_FL; > +stream->positions[1] = VIRTIO_SND_CHMAP_FR; > + > +if (stream->info.direction == VIRTIO_SND_D_OUTPUT) { > +stream->voice.out = AUD_open_out(&stream->s->card, > + stream->voice.out, > + "virtio-sound.out", > + stream, > + virtio_snd_pcm_out_cb, > + &stream->as); > +AUD_set_volume_out(stream->voice.out, 0, 255, 255); > +} else { > +stream->voice.in = AUD_open_in(&stream->s->card, > + stream->voice.in, > + "virtio-sound.in", > + stream, > + virtio_snd_pcm_in_cb, > + &stream->as); > +AUD_set_volume_in(stream->voice.in, 0, 255, 255); > +} > +} > + > /* > * Close a stream and free all its resources. > * > @@ -468,8 +498,6 @@ static void virtio_snd_pcm_close(VirtIOSoundPCMStream > *stream) > */ > static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id) > { > -audsettings as; > -virtio_snd_pcm_set_params *params; > VirtIOSoundPCMStream *stream; > > stream = virtio_snd_pcm_get_stream(s, stream_id); > @@ -491,30 +519,7 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, > uint32_t stream_id) > QSIMPLEQ_INIT(&stream->invalid); > } > > -params = virtio_snd_pcm_get_params(s, stream_id); > - > -virtio_snd_get_qemu_audsettings(&as, params); > -stream->positions[0] = VIRTIO_SND_CHMAP_FL; > -stream->positions[1] = VIRTIO_SND_CHMAP_FR; > -stream->as = as; > - > -if (stream->info.direction == VIRTIO_SND_D_OUTPUT) { > -stream->voice.out = AUD_open_out(&s->card, > - stream->voice.out, > - "virtio-sound.out", > - stream, > - virtio_snd_pcm_out_cb, > - &as); > -AUD_set_volume_out(stream->voice.out, 0, 255, 255); > -} else { > -stream->voice.in = AUD_open_in(&s->card, > -stream->voice.in, > -"virtio-sound.in", > -stream, > -virtio_snd_pcm_in_cb, > -&as); > -AUD_set_volume_in(stream->voice.in, 0, 255, 255); > -} > +virtio_snd_pcm_open(stream); > > stream->state = VSND_PCMSTREAM_STATE_PREPARED; > > -- > 2.35.3 >
Re: [PATCH 07/10] hw/audio/virtio-sound: introduce virtio_snd_set_active()
On Fri, Jan 5, 2024 at 12:34 AM Volker Rümelin wrote: > > Split out the function virtio_snd_pcm_set_active() from > virtio_snd_pcm_start_stop(). A later patch also needs this > new funcion. There is no functional change. > > Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau > --- > hw/audio/virtio-snd.c | 21 - > 1 file changed, 16 insertions(+), 5 deletions(-) > > diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c > index a1d2b3367e..16e8c49655 100644 > --- a/hw/audio/virtio-snd.c > +++ b/hw/audio/virtio-snd.c > @@ -473,6 +473,21 @@ static void virtio_snd_pcm_open(VirtIOSoundPCMStream > *stream) > } > } > > +/* > + * Activate/deactivate a stream. > + * > + * @stream: VirtIOSoundPCMStream *stream > + * @active: whether to activate or deactivate the stream > + */ > +static void virtio_snd_pcm_set_active(VirtIOSoundPCMStream *stream, bool > active) > +{ > +if (stream->info.direction == VIRTIO_SND_D_OUTPUT) { > +AUD_set_active_out(stream->voice.out, active); > +} else { > +AUD_set_active_in(stream->voice.in, active); > +} > +} > + > /* > * Close a stream and free all its resources. > * > @@ -613,11 +628,7 @@ static uint32_t virtio_snd_pcm_start_stop(VirtIOSound *s, > stream->state = VSND_PCMSTREAM_STATE_STOPPED; > } > > -if (stream->info.direction == VIRTIO_SND_D_OUTPUT) { > -AUD_set_active_out(stream->voice.out, start); > -} else { > -AUD_set_active_in(stream->voice.in, start); > -} > +virtio_snd_pcm_set_active(stream, start); > > return cpu_to_le32(VIRTIO_SND_S_OK); > } > -- > 2.35.3 >
Re: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location
On 1/5/24 06:06, Sia Jee Heng wrote: RISC-V should also generate the SPCR in a manner similar to ARM. Therefore, instead of replicating the code, relocate this function to the common AML build. Signed-off-by: Sia Jee Heng --- hw/acpi/aml-build.c | 51 hw/arm/virt-acpi-build.c| 68 +++-- include/hw/acpi/acpi-defs.h | 33 ++ include/hw/acpi/aml-build.h | 4 +++ 4 files changed, 115 insertions(+), 41 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index af66bde0f5..1efa534aa8 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1994,6 +1994,57 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, } } +void build_spcr(GArray *table_data, BIOSLinker *linker, +const AcpiSpcrData *f, const char *oem_id, +const char *oem_table_id) +{ +AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = oem_id, +.oem_table_id = oem_table_id }; + +acpi_table_begin(&table, table_data); +/* Interface type */ +build_append_int_noprefix(table_data, f->interface_type, 1); +/* Reserved */ +build_append_int_noprefix(table_data, 0, 3); +/* Base Address */ +build_append_gas(table_data, f->base_addr.id, f->base_addr.width, + f->base_addr.offset, f->base_addr.size, + f->base_addr.addr); +/* Interrupt type */ +build_append_int_noprefix(table_data, f->interrupt_type, 1); +/* IRQ */ +build_append_int_noprefix(table_data, f->pc_interrupt, 1); +/* Global System Interrupt */ +build_append_int_noprefix(table_data, f->interrupt, 4); +/* Baud Rate */ +build_append_int_noprefix(table_data, f->baud_rate, 1); +/* Parity */ +build_append_int_noprefix(table_data, f->parity, 1); +/* Stop Bits */ +build_append_int_noprefix(table_data, f->stop_bits, 1); +/* Flow Control */ +build_append_int_noprefix(table_data, f->flow_control, 1); +/* Terminal Type */ +build_append_int_noprefix(table_data, f->terminal_type, 1); +/* PCI Device ID */ +build_append_int_noprefix(table_data, f->pci_device_id, 2); +/* PCI Vendor ID */ +build_append_int_noprefix(table_data, f->pci_vendor_id, 2); +/* PCI Bus Number */ +build_append_int_noprefix(table_data, f->pci_bus, 1); +/* PCI Device Number */ +build_append_int_noprefix(table_data, f->pci_device, 1); +/* PCI Function Number */ +build_append_int_noprefix(table_data, f->pci_function, 1); +/* PCI Flags */ +build_append_int_noprefix(table_data, f->pci_flags, 4); +/* PCI Segment */ +build_append_int_noprefix(table_data, f->pci_segment, 1); +/* Reserved */ +build_append_int_noprefix(table_data, 0, 4); + +acpi_table_end(linker, &table); +} /* * ACPI spec, Revision 6.3 * 5.2.29 Processor Properties Topology Table (PPTT) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 510ab0dcca..a31f736d1a 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -431,48 +431,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) * Rev: 1.07 */ static void -build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) +build_spcr_v2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) Nit: I don't understand the '_v2' in the name of this function. Is it just to not collide with the now public build_spcr()? Or does it have to do with the SPCR table being '.rev = 2'? Because if it's the latter, you can name the common helper 'build_spcr_rev2' (since both ARM and RISC-V use SPCR rev 2), keep this local build_spcr() initializing the AcpiSpcrData struct with ARM attributes and then call the common build_spcr_rev2(). Code looks good othewise. Thanks, Daniel { -AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = vms->oem_id, -.oem_table_id = vms->oem_table_id }; - -acpi_table_begin(&table, table_data); - -/* Interface Type */ -build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */ -build_append_int_noprefix(table_data, 0, 3); /* Reserved */ -/* Base Address */ -build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 3, - vms->memmap[VIRT_UART].base); -/* Interrupt Type */ -build_append_int_noprefix(table_data, -(1 << 3) /* Bit[3] ARMH GIC interrupt */, 1); -build_append_int_noprefix(table_data, 0, 1); /* IRQ */ -/* Global System Interrupt */ -build_append_int_noprefix(table_data, - vms->irqmap[VIRT_UART] + ARM_SPI_BASE, 4); -build_append_int_noprefix(table_data, 3 /* 9600 */, 1); /* Baud Rate */ -build_append_int_noprefix(table_data, 0 /* No Parity */, 1); /* Parity */ -/* Stop Bits */ -build_append_int_noprefix(table_data, 1 /* 1 Stop bit */, 1); -/* Flow Cont
Re: [RESEND RFC v1 2/2] hw/riscv/virt-acpi-build.c: Generate SPCR table
On 1/5/24 06:06, Sia Jee Heng wrote: Generate Serial Port Console Redirection Table (SPCR) for RISC-V virtual machine. Signed-off-by: Sia Jee Heng --- hw/riscv/virt-acpi-build.c | 39 ++ 1 file changed, 39 insertions(+) diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index d4a02579d6..388b3d1a84 100644 --- a/hw/riscv/virt-acpi-build.c +++ b/hw/riscv/virt-acpi-build.c @@ -174,6 +174,42 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, aml_append(scope, dev); } +/* + * Serial Port Console Redirection Table (SPCR) + * Rev: 1.07 Shouldn't it be "Rev: 2.0"? The function is calling the common build_spcr() that specifies +AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = oem_id, +.oem_table_id = oem_table_id }; Code LGTM regardless of the "Rev: " comment value. Reviewed-by: Daniel Henrique Barboza + */ + +static void +build_spcr_rev2(GArray *table_data, BIOSLinker *linker, RISCVVirtState *s) +{ +AcpiSpcrData serial = { +.interface_type = 0, /* 16550 compatible */ +.base_addr.id = AML_AS_SYSTEM_MEMORY, +.base_addr.width = 32, +.base_addr.offset = 0, +.base_addr.size = 1, +.base_addr.addr = s->memmap[VIRT_UART0].base, +.interrupt_type = (1 << 4),/* Bit[4] RISC-V PLIC/APLIC */ +.pc_interrupt = 0, +.interrupt = UART0_IRQ, +.baud_rate = 7,/* 15200 */ +.parity = 0, +.stop_bits = 1, +.flow_control = 0, +.terminal_type = 3,/* ANSI */ +.language = 0, /* Language */ +.pci_device_id = 0x, /* not a PCI device*/ +.pci_vendor_id = 0x, /* not a PCI device*/ +.pci_bus = 0, +.pci_device = 0, +.pci_function = 0, +.pci_flags = 0, +.pci_segment = 0, +}; + +build_spcr(table_data, linker, &serial, s->oem_id, s->oem_table_id); +} + /* RHCT Node[N] starts at offset 56 */ #define RHCT_NODE_ARRAY_OFFSET 56 @@ -555,6 +591,9 @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_rhct(tables_blob, tables->linker, s); +acpi_add_table(table_offsets, tables_blob); +build_spcr_rev2(tables_blob, tables->linker, s); + acpi_add_table(table_offsets, tables_blob); { AcpiMcfgInfo mcfg = {
Re: [PULL 00/46] (mostly) target/i386 and meson changes for 2023-12-31
On Sun, 31 Dec 2023 at 08:50, Paolo Bonzini wrote: > > The following changes since commit 191710c221f65b1542f6ea7fa4d30dde6e134fd7: > > Merge tag 'pull-request-2023-12-20' of https://gitlab.com/thuth/qemu into > staging (2023-12-20 09:40:16 -0500) > > are available in the Git repository at: > > https://gitlab.com/bonzini/qemu.git tags/for-upstream > > for you to fetch changes up to f705c1f25d9a075534f8279048082af4ce2066bf: > > meson.build: report graphics backends separately (2023-12-31 09:11:29 +0100) > > > * configure: use a native non-cross compiler for linux-user > * meson: cleanups > * target/i386: miscellaneous cleanups and optimizations > * target/i386: implement CMPccXADD > * target/i386: the sgx_epc_get_section stub is reachable > * esp: check for NULL result from scsi_device_find() > Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/9.0 for any user-visible changes. -- PMM
Re: [PATCH 3/9] intc/grlib_irqmp: implements the multiprocessor status register
On Fri, Jan 5, 2024 at 12:32 PM Philippe Mathieu-Daudé wrote: > > Hi Clément, > > On 5/1/24 11:24, Clément Chigot wrote: > > This implements the multiprocessor status register in grlib-irqmp and bind > > it to a start signal, which will be later wired in leon3-generic to > > start a cpu. > > > > Co-developed-by: Frederic Konrad > > Signed-off-by: Clément Chigot > > --- > > hw/intc/grlib_irqmp.c | 22 +++--- > > 1 file changed, 19 insertions(+), 3 deletions(-) > > > > @@ -323,6 +334,8 @@ static void grlib_irqmp_reset(DeviceState *d) > > > > memset(irqmp->state, 0, sizeof *irqmp->state); > > irqmp->state->parent = irqmp; > > +irqmp->state->mpstatus = ((irqmp->ncpus - 1) << 28) > > Can you #define this magic '28' number? > > > +| ((1 << irqmp->ncpus) - 2); > > } > > > > static void grlib_irqmp_realize(DeviceState *dev, Error **errp) > > @@ -336,6 +349,9 @@ static void grlib_irqmp_realize(DeviceState *dev, Error > > **errp) > > } > > > > qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS); > > +/* Transitionning from 0 to 1 starts the CPUs. */ > > What about 1 -> 0? It does nothing. I have updated the comment to mention it. For the doc (also mention it in the commit message now). | [15:1] Power-down status of CPU [n]: reads ‘1’ = power-down, ‘0’ = running. | Write to start processor n: ‘1’=to start ‘0'=has no effect. > > +qdev_init_gpio_out_named(dev, irqmp->start_signal, "grlib-start-cpu", > > + IRQMP_MAX_CPU); > > qdev_init_gpio_out_named(dev, &irqmp->irq, "grlib-irq", 1); > > memory_region_init_io(&irqmp->iomem, OBJECT(dev), &grlib_irqmp_ops, > > irqmp, > > "irqmp", IRQMP_REG_SIZE); >
Re: [PATCH v6 11/11] virtio-gpu: make blob scanout use dmabuf fd
Huang Rui writes: > From: Robert Beckett > > This relies on a virglrenderer change to include the dmabuf fd when > returning resource info. > > +static void virgl_cmd_set_scanout_blob(VirtIOGPU *g, > + struct virtio_gpu_ctrl_command *cmd) > +{ > +struct virgl_gpu_resource *vres; > +struct virtio_gpu_framebuffer fb = { 0 }; > +struct virtio_gpu_set_scanout_blob ss; > +struct virgl_renderer_resource_info info; > +uint64_t fbend; > + > +VIRTIO_GPU_FILL_CMD(ss); > +virtio_gpu_scanout_blob_bswap(&ss); > +trace_virtio_gpu_cmd_set_scanout_blob(ss.scanout_id, ss.resource_id, > + ss.r.width, ss.r.height, ss.r.x, > + ss.r.y); > + > +if (ss.scanout_id >= g->parent_obj.conf.max_outputs) { > +qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d", > + __func__, ss.scanout_id); > +cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; > +return; > +} > + > +if (ss.resource_id == 0) { > +virtio_gpu_disable_scanout(g, ss.scanout_id); > +return; > +} > + > +if (ss.width < 16 || > +ss.height < 16 || > +ss.r.x + ss.r.width > ss.width || > +ss.r.y + ss.r.height > ss.height) { > +qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for" > + " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n", > + __func__, ss.scanout_id, ss.resource_id, > + ss.r.x, ss.r.y, ss.r.width, ss.r.height, > + ss.width, ss.height); > +cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; > +return; > +} > + > +if (!console_has_gl(g->parent_obj.scanout[ss.scanout_id].con)) { > +qemu_log_mask(LOG_GUEST_ERROR, "%s: unable to scanout blot without > GL!\n", __func__); > +return; > +} > + > +vres = virgl_gpu_find_resource(g, ss.resource_id); > +if (!vres) { > +qemu_log_mask(LOG_GUEST_ERROR, > + "%s: illegal resource specified %d\n", > + __func__, ss.resource_id); > +cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; > +return; > +} > +if (virgl_renderer_resource_get_info(ss.resource_id, &info)) { > +qemu_log_mask(LOG_GUEST_ERROR, > + "%s: illegal virgl resource specified %d\n", > + __func__, ss.resource_id); > +cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; > +return; > +} Minor nit, the format of the following needs to include braces. > +if (!vres->res.dmabuf_fd && info.fd) > +vres->res.dmabuf_fd = info.fd; However I'm seeing: cc -m64 -mcx16 -Ilibcommon.fa.p -I../../common-user/host/x86_64 -I../../linux-user/include/host/x86_64 -I../../linux-user/include -Iui -I../../ui -I/usr/include/capstone -I/usr/include/p11-kit-1 -I/usr/include/pixman-1 -I/usr/include/libpng16 -I/usr/include/spice-server -I/usr/include/spice-1 -I/usr/include/libusb-1.0 -I/usr/include/SDL2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/gio-unix-2.0 -I/usr/include/slirp -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/fribidi -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/x86_64-linux-gnu -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/vte-2.91 -I/usr/include/virgl -I/home/alex/lsrc/qemu.git/builds/extra.libs/install/include -I/usr/include/cacard -I/usr/include/nss -I/usr/include/nspr -I/usr/include/PCSC -I/usr/include/pipewire-0.3 -I/usr/include/spa-0.2 -fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g -fstack-protector-strong -Wundef -Wwrite-strings -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wold-style-declaration -Wold-style-definition -Wtype-limits -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wempty-body -Wnested-externs -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2 -Wmissing-format-attribute -Wno-missing-include-dirs -Wno-shift-negative-value -Wno-psabi -Wshadow=local -isystem /home/alex/lsrc/qemu.git/linux-headers -isystem linux-headers -iquote . -iquote /home/alex/lsrc/qemu.git -iquote /home/alex/lsrc/qemu.git/include -iquote /home/alex/lsrc/qemu.git/host/include/x86_64 -iquote /home/alex/lsrc/qemu.git/host/include/generic -iquote /home/alex/lsrc/qemu.git/tcg/i386 -pthread -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fno-strict-aliasing -fno-common -fwrapv -fPIE -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -DNCURSES_WIDECHAR=1 -D_REENTRANT -DSTRUCT_IOVEC_DEFINED -MD -MQ libcommon.fa.p/hw_display_virtio-gpu-virgl.c.o
Re: [PULL 0/2] loongarch-to-apply queue
On Fri, 5 Jan 2024 at 01:30, Song Gao wrote: > > The following changes since commit d328fef93ae757a0dd65ed786a4086e27952eef3: > > Merge tag 'pull-20231230' of https://gitlab.com/rth7680/qemu into staging > (2024-01-04 10:23:34 +) > > are available in the Git repository at: > > https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240105 > > for you to fetch changes up to 0cd8b379081fa71c23836052feb65da4685f8ec7: > > target/loongarch: move translate modules to tcg/ (2024-01-05 09:31:05 +0800) > > ---- > pull-loongarch-20240105 > > > Song Gao (2): > target/loongarch/meson: move gdbstub.c to loongarch.ss > target/loongarch: move translate modules to tcg/ Hi; this fails to build, with ../target/loongarch/tcg/meson.build:1:3: ERROR: Unknown variable "config_all". (eg https://gitlab.com/qemu-project/qemu/-/jobs/5868662017) I think your pullreq has unfortunately got a conflict with the meson cleanup patches that I just applied from Paolo. Could you have a look at this and respin the pullreq, please? thanks -- PMM
Re: [PATCH 3/9] intc/grlib_irqmp: implements the multiprocessor status register
On 5/1/24 14:23, Clément Chigot wrote: On Fri, Jan 5, 2024 at 12:32 PM Philippe Mathieu-Daudé wrote: Hi Clément, On 5/1/24 11:24, Clément Chigot wrote: This implements the multiprocessor status register in grlib-irqmp and bind it to a start signal, which will be later wired in leon3-generic to start a cpu. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/intc/grlib_irqmp.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) @@ -323,6 +334,8 @@ static void grlib_irqmp_reset(DeviceState *d) memset(irqmp->state, 0, sizeof *irqmp->state); irqmp->state->parent = irqmp; +irqmp->state->mpstatus = ((irqmp->ncpus - 1) << 28) Can you #define this magic '28' number? +| ((1 << irqmp->ncpus) - 2); } static void grlib_irqmp_realize(DeviceState *dev, Error **errp) @@ -336,6 +349,9 @@ static void grlib_irqmp_realize(DeviceState *dev, Error **errp) } qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS); +/* Transitionning from 0 to 1 starts the CPUs. */ What about 1 -> 0? It does nothing. I have updated the comment to mention it. For the doc (also mention it in the commit message now). | [15:1] Power-down status of CPU [n]: reads ‘1’ = power-down, ‘0’ = running. | Write to start processor n: ‘1’=to start ‘0'=has no effect. Then grlib_irqmp_write() could be simplified as: case MP_STATUS_OFFSET: -/* Read Only (no SMP support) */ +state->mpstatus = deposit32(state->mpstatus, +value, 0, IRQMP_MAX_CPU); +for (unsigned i = 0; i < irqmp->ncpus; i++) { +qemu_set_irq(irqmp->start_signal[i], + extract32(value, i, 1)); +} return;
Re: [RFC 0/3] aio-posix: call ->poll_end() when removing AioHandler
Am 03.01.24 um 14:35 schrieb Paolo Bonzini: > On 1/3/24 12:40, Fiona Ebner wrote: >> I'm happy to report that I cannot reproduce the CPU-usage-spike issue >> with the patch, but I did run into an assertion failure when trying to >> verify that it fixes my original stuck-guest-IO issue. See below for the >> backtrace [0]. Hanna wrote in https://issues.redhat.com/browse/RHEL-3934 >> >>> I think it’s sufficient to simply call virtio_queue_notify_vq(vq) >>> after the virtio_queue_aio_attach_host_notifier(vq, ctx) call, because >>> both virtio-scsi’s and virtio-blk’s .handle_output() implementations >>> acquire the device’s context, so this should be directly callable from >>> any context. >> >> I guess this is not true anymore now that the AioContext locking was >> removed? > > Good point and, in fact, even before it was much safer to use > virtio_queue_notify() instead. Not only does it use the event notifier > handler, but it also calls it in the right thread/AioContext just by > doing event_notifier_set(). > But with virtio_queue_notify() using the event notifier, the CPU-usage-spike issue is present: >> Back to the CPU-usage-spike issue: I experimented around and it doesn't >> seem to matter whether I notify the virt queue before or after attaching >> the notifiers. But there's another functional difference. My patch >> called virtio_queue_notify() which contains this block: >> >>> if (vq->host_notifier_enabled) { >>> event_notifier_set(&vq->host_notifier); >>> } else if (vq->handle_output) { >>> vq->handle_output(vdev, vq); >> >> In my testing, the first branch was taken, calling event_notifier_set(). >> Hanna's patch uses virtio_queue_notify_vq() and there, >> vq->handle_output() will be called. That seems to be the relevant >> difference regarding the CPU-usage-spike issue. I should mention that this is with a VirtIO SCSI disk. I also attempted to reproduce the CPU-usage-spike issue with a VirtIO block disk, but didn't manage yet. What I noticed is that in virtio_queue_host_notifier_aio_poll(), one of the queues (but only one) will always show as nonempty. And then, run_poll_handlers_once() will always detect progress which explains the CPU usage. The following shows 1. vq address 2. number of times vq was passed to virtio_queue_host_notifier_aio_poll() 3. number of times the result of virtio_queue_host_notifier_aio_poll() was true for the vq > 0x555fd93f9c80 17162000 0 > 0x555fd93f9e48 17162000 6 > 0x555fd93f9ee0 17162000 0 > 0x555fd93f9d18 17162000 17162000 > 0x555fd93f9db0 17162000 0 > 0x555fd93f9f78 17162000 0 And for the problematic one, the reason it is seen as nonempty is: > 0x555fd93f9d18 shadow_avail_idx 8 last_avail_idx 0 Those values stay like this while the call counts above increase. So something going wrong with the indices when the event notifier is set from QEMU side (in the main thread)? The guest is Debian 12 with a 6.1 kernel. Best Regards, Fiona
Re: [PATCH] qga-win: Fix guest-get-fsinfo multi-disks collection
On 27/12/23 08:15, peng...@smartx.com wrote: From: Peng Ji When a volume has more than one disk, all disks cannot be returned correctly because there is not enough malloced memory for disk extents, so before executing DeviceIoControl for the second time, get the correct size of the required memory space to store all disk extents. Signed-off-by: Peng Ji Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2075 --- qga/commands-win32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 697c65507c..a1015757d8 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -935,6 +935,8 @@ static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp) DWORD last_err = GetLastError(); if (last_err == ERROR_MORE_DATA) { /* Try once more with big enough buffer */ +size = sizeof(VOLUME_DISK_EXTENTS) + + (sizeof(DISK_EXTENT) * (extents->NumberOfDiskExtents - 1)); g_free(extents); extents = g_malloc0(size); if (!DeviceIoControl(
Re: [PATCH v3 00/33] linux-user: Improve host and guest page size handling
Cc'ing Pierrick On 2/1/24 02:57, Richard Henderson wrote: Changes for v3: * Rebase. Blurb from v1: While working on mmap issues for 8.1, I noticed a lot of corner cases of host != guest page size that we implement poorly. This seems to be particularly visible on Apple M1 with 16k pages, more so than Power with 64k pages for some reason. Objective 1 is to deprecate and (essentially) disable the -p option. The effect of -p is apparently confusing, so much so that our own testsuite misuses it. One cannot really change the host page size, and pretending otherwise means that we don't treat the host memory system correctly, and stuff breaks. I have not yet done the same work for bsd-user. Objective 2 is to allow the guest page size to change to match the host. There are corner cases of host != guest page size will fail in odd ways. For case of host > guest page size, the issues could be solved with softmmu, allowing a non-linear mapping between host and guest addresses and also disconnecting host and guest page permissions. However, host < guest page has issues with SIGBUS which I believe to be totally unfixable. At minimum one would need to monitor changes to all files mapped in the address space, but I'm sure there is much more. But as always the best behaviour is obtained when the host and guest page sizes match -- there are no corner cases to contend with. There are a set of guests which can be configured to use multiple page sizes, and therefore software developed for those guests (usually) does not hard-code a particular page size. For those, we can allow the page size to vary and let the guest match the host. I have only changed aarch64, alpha and ppc guests so far, as those are both easy to test and, especially for the case of alpha's default 8k page size, prone to failure. r~ Richard Henderson (33): accel/tcg: Remove qemu_host_page_size from page_protect/page_unprotect linux-user: Adjust SVr4 NULL page mapping linux-user: Remove qemu_host_page_{size,mask} in probe_guest_base linux-user: Remove qemu_host_page_size from create_elf_tables linux-user/hppa: Simplify init_guest_commpage linux-user/nios2: Remove qemu_host_page_size from init_guest_commpage linux-user/arm: Remove qemu_host_page_size from init_guest_commpage linux-user: Remove qemu_host_page_{size,mask} from mmap.c linux-user: Remove REAL_HOST_PAGE_ALIGN from mmap.c linux-user: Remove HOST_PAGE_ALIGN from mmap.c migration: Remove qemu_host_page_size hw/tpm: Remove HOST_PAGE_ALIGN from tpm_ppi_init softmmu/physmem: Remove qemu_host_page_size softmmu/physmem: Remove HOST_PAGE_ALIGN linux-user: Remove qemu_host_page_size from main linux-user: Split out target_mmap__locked linux-user: Move some mmap checks outside the lock linux-user: Fix sub-host-page mmap linux-user: Split out mmap_end linux-user: Do early mmap placement only for reserved_va linux-user: Split out mmap_h_eq_g linux-user: Split out mmap_h_lt_g linux-user: Split out mmap_h_gt_g tests/tcg: Remove run-test-mmap-* tests/tcg: Extend file in linux-madvise.c *-user: Deprecate and disable -p pagesize cpu: Remove page_size_init accel/tcg: Disconnect TargetPageDataNode from page size linux-user: Allow TARGET_PAGE_BITS_VARY target/arm: Enable TARGET_PAGE_BITS_VARY for AArch64 user-only linux-user: Bound mmap_min_addr by host page size target/ppc: Enable TARGET_PAGE_BITS_VARY for user-only target/alpha: Enable TARGET_PAGE_BITS_VARY for user-only docs/about/deprecated.rst | 7 + docs/user/main.rst| 3 - bsd-user/qemu.h | 7 + include/exec/cpu-common.h | 7 - include/hw/core/cpu.h | 2 - target/alpha/cpu-param.h | 16 +- target/arm/cpu-param.h| 6 +- target/ppc/cpu-param.h| 9 +- accel/tcg/translate-all.c | 1 - accel/tcg/user-exec.c | 31 +- bsd-user/main.c | 21 +- cpu-target.c | 13 - hw/tpm/tpm_ppi.c | 3 +- linux-user/elfload.c | 67 +- linux-user/main.c | 33 +- linux-user/mmap.c | 714 +- migration/ram.c | 22 +- system/physmem.c | 17 +- system/vl.c | 1 - target/arm/cpu.c | 51 +- tests/tcg/multiarch/linux/linux-madvise.c | 2 + tests/tcg/alpha/Makefile.target | 3 - tests/tcg/arm/Makefile.target | 3 - tests/tcg/hppa/Makefile.target| 3 - tests/tcg/i386/Makefile.target| 3 - tests/tcg/m68k/Makefile.target| 3 - tests/tcg/multiarch/Makefile.target | 9 - tests/tcg/ppc/Mak
[PATCH 2/2] hw/pflash: implement update buffer for block writes
Add an update buffer where all block updates are staged. Flush or discard updates properly, so we should never see half-completed block writes in pflash storage. Drop a bunch of FIXME comments ;) Signed-off-by: Gerd Hoffmann --- hw/block/pflash_cfi01.c | 104 ++-- 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 67f1c9773ab3..78ac95b3291e 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -80,16 +80,39 @@ struct PFlashCFI01 { uint16_t ident3; uint8_t cfi_table[0x52]; uint64_t counter; -unsigned int writeblock_size; +uint32_t writeblock_size; MemoryRegion mem; char *name; void *storage; VMChangeStateEntry *vmstate; bool old_multiple_chip_handling; + +/* block update buffer */ +unsigned char *blk_bytes; +uint32_t blk_offset; }; static int pflash_post_load(void *opaque, int version_id); +static bool pflash_blk_write_state_needed(void *opaque) +{ +PFlashCFI01 *pfl = opaque; + +return (pfl->blk_offset != -1); +} + +static const VMStateDescription vmstate_pflash_blk_write = { +.name = "pflash_cfi01_blk_write", +.version_id = 1, +.minimum_version_id = 1, +.needed = pflash_blk_write_state_needed, +.fields = (const VMStateField[]) { +VMSTATE_VBUFFER_UINT32(blk_bytes, PFlashCFI01, 0, NULL, writeblock_size), +VMSTATE_UINT32(blk_offset, PFlashCFI01), +VMSTATE_END_OF_LIST() +} +}; + static const VMStateDescription vmstate_pflash = { .name = "pflash_cfi01", .version_id = 1, @@ -101,6 +124,10 @@ static const VMStateDescription vmstate_pflash = { VMSTATE_UINT8(status, PFlashCFI01), VMSTATE_UINT64(counter, PFlashCFI01), VMSTATE_END_OF_LIST() +}, +.subsections = (const VMStateDescription * const []) { +&vmstate_pflash_blk_write, +NULL } }; @@ -400,13 +427,50 @@ static void pflash_update(PFlashCFI01 *pfl, int offset, } } +/* copy current flash content to block update buffer */ +static void pflash_blk_write_start(PFlashCFI01 *pfl, hwaddr offset) +{ +hwaddr mask = ~(pfl->writeblock_size - 1); + +pfl->blk_offset = offset & mask; +memcpy(pfl->blk_bytes, pfl->storage + pfl->blk_offset, + pfl->writeblock_size); +} + +/* commit block update buffer changes */ +static void pflash_blk_write_flush(PFlashCFI01 *pfl) +{ +g_assert(pfl->blk_offset != -1); +memcpy(pfl->storage + pfl->blk_offset, pfl->blk_bytes, + pfl->writeblock_size); +pflash_update(pfl, pfl->blk_offset, pfl->writeblock_size); +pfl->blk_offset = -1; +} + +/* discard block update buffer changes */ +static void pflash_blk_write_abort(PFlashCFI01 *pfl) +{ +pfl->blk_offset = -1; +} + static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset, uint32_t value, int width, int be) { uint8_t *p; -trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter); -p = pfl->storage + offset; +if (pfl->blk_offset != -1) { +/* block write: redirect writes to block update buffer */ +if ((offset < pfl->blk_offset) || +(offset + width > pfl->blk_offset + pfl->writeblock_size)) { +pfl->status |= 0x10; /* Programming error */ +return; +} +p = pfl->blk_bytes + (offset - pfl->blk_offset); +} else { +/* write directly to storage */ +trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter); +p = pfl->storage + offset; +} switch (width) { case 1: @@ -553,6 +617,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, trace_pflash_write_block(pfl->name, value); pfl->counter = value; pfl->wcycle++; +pflash_blk_write_start(pfl, offset); break; case 0x60: if (cmd == 0xd0) { @@ -583,12 +648,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, switch (pfl->cmd) { case 0xe8: /* Block write */ /* FIXME check @offset, @width */ -if (!pfl->ro) { -/* - * FIXME writing straight to memory is *wrong*. We - * should write to a buffer, and flush it to memory - * only on confirm command (see below). - */ +if (!pfl->ro && (pfl->blk_offset != -1)) { pflash_data_write(pfl, offset, value, width, be); } else { pfl->status |= 0x10; /* Programming error */ @@ -597,18 +657,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, pfl->status |= 0x80; if (!pfl->counter) { -hwaddr mask = pfl->writeblock_size - 1; -mask = ~mask; - trace_pflash_write(pfl->name, "block write finished");
[PATCH 1/2] hw/pflash: refactor pflash_data_write()
Move the offset calculation, do it once at the start of the function and let the 'p' variable point directly to the memory location which should be updated. This makes it simpler to update other buffers than pfl->storage in an upcoming patch. No functional change. Signed-off-by: Gerd Hoffmann --- hw/block/pflash_cfi01.c | 30 -- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 3e2dc08bd78f..67f1c9773ab3 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -403,33 +403,35 @@ static void pflash_update(PFlashCFI01 *pfl, int offset, static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset, uint32_t value, int width, int be) { -uint8_t *p = pfl->storage; +uint8_t *p; trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter); +p = pfl->storage + offset; + switch (width) { case 1: -p[offset] = value; +p[0] = value; break; case 2: if (be) { -p[offset] = value >> 8; -p[offset + 1] = value; +p[0] = value >> 8; +p[1] = value; } else { -p[offset] = value; -p[offset + 1] = value >> 8; +p[0] = value; +p[1] = value >> 8; } break; case 4: if (be) { -p[offset] = value >> 24; -p[offset + 1] = value >> 16; -p[offset + 2] = value >> 8; -p[offset + 3] = value; +p[0] = value >> 24; +p[1] = value >> 16; +p[2] = value >> 8; +p[3] = value; } else { -p[offset] = value; -p[offset + 1] = value >> 8; -p[offset + 2] = value >> 16; -p[offset + 3] = value >> 24; +p[0] = value; +p[1] = value >> 8; +p[2] = value >> 16; +p[3] = value >> 24; } break; } -- 2.43.0
[PATCH 0/2] hw/pflash: implement update buffer for block writes
When running qemu with edk2 efi firmware on aarch64 the efi variable store in pflash can get corrupted. qemu not doing proper block writes -- flush all or nothing to storage -- is a hot candidate for being the root cause. This little series tries to fix that with an update buffer where block writes are staged, so we can commit or discard the changes when the block write is completed or canceled. Gerd Hoffmann (2): hw/pflash: refactor pflash_data_write() hw/pflash: implement update buffer for block writes hw/block/pflash_cfi01.c | 132 1 file changed, 93 insertions(+), 39 deletions(-) -- 2.43.0
Re: [PATCH 1/9] sparc/grlib: split out the headers for each peripherals
On 5/1/24 11:24, Clément Chigot wrote: ... and move them in their right hardware directory. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/char/grlib_apbuart.c | 4 +-- hw/intc/grlib_irqmp.c | 4 +-- hw/sparc/leon3.c | 6 ++-- hw/timer/grlib_gptimer.c | 4 +-- include/hw/char/grlib_uart.h | 30 +++ .../hw/{sparc/grlib.h => intc/grlib_irqmp.h} | 14 +++-- include/hw/timer/grlib_gptimer.h | 30 +++ 7 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 include/hw/char/grlib_uart.h rename include/hw/{sparc/grlib.h => intc/grlib_irqmp.h} (86%) create mode 100644 include/hw/timer/grlib_gptimer.h This still matches the MAINTAINERS patterns, good. diff --git a/include/hw/char/grlib_uart.h b/include/hw/char/grlib_uart.h new file mode 100644 index 00..b67da6c62a --- /dev/null +++ b/include/hw/char/grlib_uart.h @@ -0,0 +1,30 @@ +/* + * QEMU GRLIB UART + * + * Copyright (c) 2024 AdaCore + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. When adding license, SPDX tag is prefered (although not enforced) because it eases tools parsing. + */ + +#ifndef GRLIB_UART_H +#define GRLIB_UART_H + +#define TYPE_GRLIB_APB_UART "grlib-apbuart" + +#endif Reviewed-by: Philippe Mathieu-Daudé
Re: [PATCH 1/2] hw/pflash: refactor pflash_data_write()
On 5/1/24 14:58, Gerd Hoffmann wrote: Move the offset calculation, do it once at the start of the function and let the 'p' variable point directly to the memory location which should be updated. This makes it simpler to update other buffers than pfl->storage in an upcoming patch. No functional change. Signed-off-by: Gerd Hoffmann --- hw/block/pflash_cfi01.c | 30 -- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 3e2dc08bd78f..67f1c9773ab3 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -403,33 +403,35 @@ static void pflash_update(PFlashCFI01 *pfl, int offset, static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset, uint32_t value, int width, int be) { -uint8_t *p = pfl->storage; +uint8_t *p; trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter); +p = pfl->storage + offset; + switch (width) { case 1: -p[offset] = value; +p[0] = value; break; case 2: if (be) { -p[offset] = value >> 8; -p[offset + 1] = value; +p[0] = value >> 8; +p[1] = value; } else { -p[offset] = value; -p[offset + 1] = value >> 8; +p[0] = value; +p[1] = value >> 8; } break; case 4: if (be) { -p[offset] = value >> 24; -p[offset + 1] = value >> 16; -p[offset + 2] = value >> 8; -p[offset + 3] = value; +p[0] = value >> 24; +p[1] = value >> 16; +p[2] = value >> 8; +p[3] = value; } else { -p[offset] = value; -p[offset + 1] = value >> 8; -p[offset + 2] = value >> 16; -p[offset + 3] = value >> 24; +p[0] = value; +p[1] = value >> 8; +p[2] = value >> 16; +p[3] = value >> 24; } break; } Close to commit c3d25271b2 ("hw/block/pflash_cfi02: Use the ldst API in pflash_write()"): if (be) { stn_be_p(p, width, value); } else { stn_le_p(p, width, value); }
Re: virtio-pci in qemu-system-arm is broken in 8.2
On Thu, 4 Jan 2024 at 17:17, Michael Tokarev wrote: > > 04.01.2024 19:25, Michael Tokarev wrote: > ... > > this archive contains kernel+initrd. I run it this way: > > > > qemu-system-arm -append root=LABEL=debvm -nographic -machine type=virt \ > > -drive media=disk,format=raw,file=vmlinuz,if=virtio,snapshot=on \ > > -no-user-config -m 1G -kernel vmlinuz -initrd initrd.img > > This is actually even more fishy. > > The reproducer needs -cpu max to "work." Without -cpu max, it > fails to recognize virtio pci devices in both cases - in 8.2.0 > with or without the commit in question (b8f7959f28c4f36496). > Only with -cpu max it works after reverting b8f7959f28c. > > Additional kernel message in case when it doesn't work: > > [1.372841] pci-host-generic 401000.pcie: \ >can't claim ECAM area [mem 0x1000-0x1fff]: \ >address conflict with pcie@1000 [mem 0x1000-0x3efe] > > which isn't generated in case everything's ok. This looks in fact like commit b8f7959f28c fixed a bug which was masking problems with booting newer kernels. What happens is: * arm_pamax() is a function for finding out the maximum physical address space size supported by the CPU * it is called by the virt board on a CPU object which has been inited but not realized * before b8f7959f28c the implications like "V7VE implies LPAE" were only done at realize, and so arm_pamax() has some manual workarounds to do the same logic * but those workarounds were missing the case "v8 implies v7ve implies lpae", so for a v8 CPU we incorrectly reported that it could only do 32 bit addressing (affecting only "max" on qemu-system-arm) b8f7959f28c moves where we do the "v8 implies v7ve etc" logic, which means that * the workarounds in arm_pamax() aren't needed any more * we now correctly report 40 bits as the pa size for 'max' (That is, '-cpu max' then behaves the same as '-cpu cortex-a15', as intended.) Unfortunately it seems like these kernels don't correctly handle how we report the PCI controller when we're using a 40-bit address space. This seems like it's probably a kernel bug, but it might be that we're getting the DTB wrong. In any case it seems a bit awkward to actively require the guest kernel to be LPAE in order to boot on an LPAE CPU, so maybe we should tweak the logic to not put the ECAM in high memory for a 32-bit CPU. thanks -- PMM
Re: [PATCH 3/9] intc/grlib_irqmp: implements the multiprocessor status register
On Fri, Jan 5, 2024 at 2:37 PM Philippe Mathieu-Daudé wrote: > > On 5/1/24 14:23, Clément Chigot wrote: > > On Fri, Jan 5, 2024 at 12:32 PM Philippe Mathieu-Daudé > > wrote: > >> > >> Hi Clément, > >> > >> On 5/1/24 11:24, Clément Chigot wrote: > >>> This implements the multiprocessor status register in grlib-irqmp and bind > >>> it to a start signal, which will be later wired in leon3-generic to > >>> start a cpu. > >>> > >>> Co-developed-by: Frederic Konrad > >>> Signed-off-by: Clément Chigot > >>> --- > >>>hw/intc/grlib_irqmp.c | 22 +++--- > >>>1 file changed, 19 insertions(+), 3 deletions(-) > >> > >> > >>> @@ -323,6 +334,8 @@ static void grlib_irqmp_reset(DeviceState *d) > >>> > >>>memset(irqmp->state, 0, sizeof *irqmp->state); > >>>irqmp->state->parent = irqmp; > >>> +irqmp->state->mpstatus = ((irqmp->ncpus - 1) << 28) > >> > >> Can you #define this magic '28' number? > >> > >>> +| ((1 << irqmp->ncpus) - 2); > >>>} > >>> > >>>static void grlib_irqmp_realize(DeviceState *dev, Error **errp) > >>> @@ -336,6 +349,9 @@ static void grlib_irqmp_realize(DeviceState *dev, > >>> Error **errp) > >>>} > >>> > >>>qdev_init_gpio_in(dev, grlib_irqmp_set_irq, MAX_PILS); > >>> +/* Transitionning from 0 to 1 starts the CPUs. */ > >> > >> What about 1 -> 0? > > > > It does nothing. I have updated the comment to mention it. > > For the doc (also mention it in the commit message now). > >| [15:1] Power-down status of CPU [n]: reads ‘1’ = power-down, ‘0’ = > > running. > >| Write to start processor n: ‘1’=to start ‘0'=has no effect. > > Then grlib_irqmp_write() could be simplified as: > > case MP_STATUS_OFFSET: > -/* Read Only (no SMP support) */ > +state->mpstatus = deposit32(state->mpstatus, > +value, 0, IRQMP_MAX_CPU); > +for (unsigned i = 0; i < irqmp->ncpus; i++) { > +qemu_set_irq(irqmp->start_signal[i], > + extract32(value, i, 1)); > +} > return; No, because the logic between write and read is reversed. Writing "1" starts the CPU but reading 1 means that the CPU is not started. Therefore, when writing 1, we must trigger the start signal and then write 0 in mpstatus.
Re: [PATCH 4/9] intc/grlib_irqmp: implements multicore irq
On 5/1/24 11:24, Clément Chigot wrote: Now there is an ncpus property, use it in order to deliver the IRQ to multiple CPU. Co-developed-by: Frederic Konrad Signed-off-by: Clément Chigot --- hw/intc/grlib_irqmp.c | 43 ++- hw/sparc/leon3.c | 3 ++- include/hw/intc/grlib_irqmp.h | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 7b9809b81f..94d8ec94b0 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -168,7 +168,8 @@ static void leon3_cache_control_int(CPUSPARCState *env) static void leon3_irq_ack(void *irq_manager, int intno) { -grlib_irqmp_ack((DeviceState *)irq_manager, intno); +/* No SMP support yet. */ +grlib_irqmp_ack((DeviceState *)irq_manager, 0, intno); This '0' was not obvious, now I figured, I suggest: /* No SMP support yet, only CPU #0 available so far. */ }
Re: [RFC 0/3] aio-posix: call ->poll_end() when removing AioHandler
Am 05.01.24 um 14:43 schrieb Fiona Ebner: > Am 03.01.24 um 14:35 schrieb Paolo Bonzini: >> On 1/3/24 12:40, Fiona Ebner wrote: >>> I'm happy to report that I cannot reproduce the CPU-usage-spike issue >>> with the patch, but I did run into an assertion failure when trying to >>> verify that it fixes my original stuck-guest-IO issue. See below for the >>> backtrace [0]. Hanna wrote in https://issues.redhat.com/browse/RHEL-3934 >>> I think it’s sufficient to simply call virtio_queue_notify_vq(vq) after the virtio_queue_aio_attach_host_notifier(vq, ctx) call, because both virtio-scsi’s and virtio-blk’s .handle_output() implementations acquire the device’s context, so this should be directly callable from any context. >>> >>> I guess this is not true anymore now that the AioContext locking was >>> removed? >> >> Good point and, in fact, even before it was much safer to use >> virtio_queue_notify() instead. Not only does it use the event notifier >> handler, but it also calls it in the right thread/AioContext just by >> doing event_notifier_set(). >> > > But with virtio_queue_notify() using the event notifier, the > CPU-usage-spike issue is present: > >>> Back to the CPU-usage-spike issue: I experimented around and it doesn't >>> seem to matter whether I notify the virt queue before or after attaching >>> the notifiers. But there's another functional difference. My patch >>> called virtio_queue_notify() which contains this block: >>> if (vq->host_notifier_enabled) { event_notifier_set(&vq->host_notifier); } else if (vq->handle_output) { vq->handle_output(vdev, vq); >>> >>> In my testing, the first branch was taken, calling event_notifier_set(). >>> Hanna's patch uses virtio_queue_notify_vq() and there, >>> vq->handle_output() will be called. That seems to be the relevant >>> difference regarding the CPU-usage-spike issue. > > I should mention that this is with a VirtIO SCSI disk. I also attempted > to reproduce the CPU-usage-spike issue with a VirtIO block disk, but > didn't manage yet. > > What I noticed is that in virtio_queue_host_notifier_aio_poll(), one of > the queues (but only one) will always show as nonempty. And then, > run_poll_handlers_once() will always detect progress which explains the > CPU usage. > > The following shows > 1. vq address > 2. number of times vq was passed to virtio_queue_host_notifier_aio_poll() > 3. number of times the result of virtio_queue_host_notifier_aio_poll() > was true for the vq > >> 0x555fd93f9c80 17162000 0 >> 0x555fd93f9e48 17162000 6 >> 0x555fd93f9ee0 17162000 0 >> 0x555fd93f9d18 17162000 17162000 >> 0x555fd93f9db0 17162000 0 >> 0x555fd93f9f78 17162000 0 > > And for the problematic one, the reason it is seen as nonempty is: > >> 0x555fd93f9d18 shadow_avail_idx 8 last_avail_idx 0 > vring_avail_idx(vq) also gives 8 here. This is the vs->event_vq and s->events_dropped is false in my testing, so virtio_scsi_handle_event_vq() doesn't do anything. > Those values stay like this while the call counts above increase. > > So something going wrong with the indices when the event notifier is set > from QEMU side (in the main thread)? > > The guest is Debian 12 with a 6.1 kernel. Best Regards, Fiona
Re: [PATCH 1/9] sparc/grlib: split out the headers for each peripherals
On Fri, Jan 5, 2024 at 3:00 PM Philippe Mathieu-Daudé wrote: > > On 5/1/24 11:24, Clément Chigot wrote: > > ... and move them in their right hardware directory. > > > > Co-developed-by: Frederic Konrad > > Signed-off-by: Clément Chigot > > --- > > hw/char/grlib_apbuart.c | 4 +-- > > hw/intc/grlib_irqmp.c | 4 +-- > > hw/sparc/leon3.c | 6 ++-- > > hw/timer/grlib_gptimer.c | 4 +-- > > include/hw/char/grlib_uart.h | 30 +++ > > .../hw/{sparc/grlib.h => intc/grlib_irqmp.h} | 14 +++-- > > include/hw/timer/grlib_gptimer.h | 30 +++ > > 7 files changed, 74 insertions(+), 18 deletions(-) > > create mode 100644 include/hw/char/grlib_uart.h > > rename include/hw/{sparc/grlib.h => intc/grlib_irqmp.h} (86%) > > create mode 100644 include/hw/timer/grlib_gptimer.h > > This still matches the MAINTAINERS patterns, good. > > > diff --git a/include/hw/char/grlib_uart.h b/include/hw/char/grlib_uart.h > > new file mode 100644 > > index 00..b67da6c62a > > --- /dev/null > > +++ b/include/hw/char/grlib_uart.h > > @@ -0,0 +1,30 @@ > > +/* > > + * QEMU GRLIB UART > > + * > > + * Copyright (c) 2024 AdaCore > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > copy > > + * of this software and associated documentation files (the "Software"), > > to deal > > + * in the Software without restriction, including without limitation the > > rights > > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or > > sell > > + * copies of the Software, and to permit persons to whom the Software is > > + * furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included > > in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > > OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > > OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > > FROM, > > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS > > IN > > + * THE SOFTWARE. > > When adding license, SPDX tag is prefered (although not enforced) > because it eases tools parsing. Should it be something like this ? * SPDX-FileCopyrightText: 20xx-2024 Adacore * SPDX-License-Identifier: MIT Would updating, now, all those files make it better ? > > + */ > > + > > +#ifndef GRLIB_UART_H > > +#define GRLIB_UART_H > > + > > +#define TYPE_GRLIB_APB_UART "grlib-apbuart" > > + > > +#endif > > Reviewed-by: Philippe Mathieu-Daudé >
Re: [PATCH-for-9.0 03/25] memory: Have memory_region_init_rom_nomigrate() handler return a boolean
On 21/11/23 13:10, Manos Pitsidianakis wrote: On Mon, 20 Nov 2023 23:32, Philippe Mathieu-Daudé wrote: Following the example documented since commit e3fe3988d7 ("error: Document Error API usage rules"), have cpu_exec_realizefn() return a boolean indicating whether an error is set or not. Signed-off-by: Philippe Mathieu-Daudé --- include/exec/memory.h | 4 +++- system/memory.c | 8 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/system/memory.c b/system/memory.c index 337b12a674..bfe0b62d59 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1729,14 +1729,18 @@ void memory_region_init_alias(MemoryRegion *mr, mr->alias_offset = offset; } -void memory_region_init_rom_nomigrate(MemoryRegion *mr, +bool memory_region_init_rom_nomigrate(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, Error **errp) { - memory_region_init_ram_flags_nomigrate(mr, owner, name, size, 0, errp); + bool rv; + + rv = memory_region_init_ram_flags_nomigrate(mr, owner, name, size, 0, errp); mr->readonly = true; + By the way, do we want to set mr->readonly on failure? Should there be modifications if an error is propagated upwards? Good point, I'm squashing: -- >8 -- diff --git a/system/memory.c b/system/memory.c index a748de3694..72c6441e20 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1707,12 +1707,13 @@ bool memory_region_init_rom_nomigrate(MemoryRegion *mr, uint64_t size, Error **errp) { -bool rv; - -rv = memory_region_init_ram_flags_nomigrate(mr, owner, name, size, 0, errp); +if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, +size, 0, errp)) { + return false; +} mr->readonly = true; -return rv; +return true; } ---
Question about CXL emulation in QEMU
Dear Experts, I am writing to seek your assistance about CXL emulation in QEMU. I am Zhou Tong and I am researching how to use QEMU to simulate CXL over Ethernet?? I want to implement remote registration of CXL.mem devices based on the QOM model. The general idea is: the CXL slave side notifies the master side of the size of the CXL memory and other control information through Ethernet, and the master side registers the CXL device locally based on the control information. When the master accesses the CXL device, KVM is responsible for intercepting the action of accessing the memory, and encapsulates the CXL message and forwards it to the slave through Ethernet??ultimately achieving remote CXL memory access.. Ask the experts how to register the CXL device locally based on the control information without occupying the HVA resources of the master host (OR display the CXL device). Thank you in advance for your attention to this email, and I eagerly look forward to any insights or advice you may be able to provide. If there is a more convenient time for us to discuss this matter further, please let me know, and I will be more than happy to accommodate your schedule. Once again, thank you for your impactful contributions to the open-source community, and I greatly appreciate your time and consideration. Regard, Zhou Tong. 273415...@qq.com
Question about CXL emulation in QEMU
Dear Experts, I am writing to seek your assistance about CXL emulation in QEMU. I am Zhou Tong and I am researching how to use QEMU to simulate CXL over Ethernet?? I want to implement remote registration of CXL.mem devices based on the QOM model. The general idea is: the CXL slave side notifies the master side of the size of the CXL memory and other control information through Ethernet, and the master side registers the CXL device locally based on the control information. When the master accesses the CXL device, KVM is responsible for intercepting the action of accessing the memory, and encapsulates the CXL message and forwards it to the slave through Ethernet??ultimately achieving remote CXL memory access.. Ask the experts how to register the CXL device locally based on the control information without occupying the HVA resources of the master host (OR display the CXL device). Thank you in advance for your attention to this email, and I eagerly look forward to any insights or advice you may be able to provide. If there is a more convenient time for us to discuss this matter further, please let me know, and I will be more than happy to accommodate your schedule. Once again, thank you for your impactful contributions to the open-source community, and I greatly appreciate your time and consideration. Regard, Zhou Tong. 273415...@qq.com
Re: [PATCH 9/9] MAINTAINERS: replace Fabien by myself as Leon3 maintainer
Looks good Clement. Reviewed-by: Fabien Chouteau -- Fabien Chouteau
Re: [PATCH-for-9.0 03/25] memory: Have memory_region_init_rom_nomigrate() handler return a boolean
On Fri, 5 Jan 2024 at 14:46, Philippe Mathieu-Daudé wrote: > > On 21/11/23 13:10, Manos Pitsidianakis wrote: > > On Mon, 20 Nov 2023 23:32, Philippe Mathieu-Daudé > > wrote: > >> Following the example documented since commit e3fe3988d7 ("error: > >> Document Error API usage rules"), have cpu_exec_realizefn() > >> return a boolean indicating whether an error is set or not. > >> > >> Signed-off-by: Philippe Mathieu-Daudé > >> --- > >> include/exec/memory.h | 4 +++- > >> system/memory.c | 8 ++-- > >> 2 files changed, 9 insertions(+), 3 deletions(-) > > > >> diff --git a/system/memory.c b/system/memory.c > >> index 337b12a674..bfe0b62d59 100644 > >> --- a/system/memory.c > >> +++ b/system/memory.c > >> @@ -1729,14 +1729,18 @@ void memory_region_init_alias(MemoryRegion *mr, > >> mr->alias_offset = offset; > >> } > >> > >> -void memory_region_init_rom_nomigrate(MemoryRegion *mr, > >> +bool memory_region_init_rom_nomigrate(MemoryRegion *mr, > >> Object *owner, > >> const char *name, > >> uint64_t size, > >> Error **errp) > >> { > >> -memory_region_init_ram_flags_nomigrate(mr, owner, name, size, 0, > >> errp); > >> +bool rv; > >> + > >> +rv = memory_region_init_ram_flags_nomigrate(mr, owner, name, > >> size, 0, errp); > >> mr->readonly = true; > >> + > > > > By the way, do we want to set mr->readonly on failure? Should there be > > modifications if an error is propagated upwards? > > Good point I don't think it matters much. If the init function fails, then the MemoryRegion is not initialized, and there's nothing you can do with the struct except free it (if it was in allocated memory). Whether the readonly field is true or false doesn't matter, because conceptually it's all undefined-values. And memory_region_init_ram_flags_nomigrate() has already written to some fields, so avoiding changing mr->readonly specifically doesn't seem worthwhile. -- PMM
Re: [PATCH-for-9.0 19/25] misc: Simplify qemu_prealloc_mem() calls
On 22/11/23 08:38, Manos Pitsidianakis wrote: On Mon, 20 Nov 2023 23:32, Philippe Mathieu-Daudé wrote: Signed-off-by: Philippe Mathieu-Daudé --- Commit message missing but indeed there's not much to say I amended: Since qemu_prealloc_mem() returns whether or not an error occured, we don't need to check the @errp pointer. Remove local_err uses when we can return directly. Reviewed-by: Manos Pitsidianakis Thanks!
[PULL 06/71] cpu: Add generic cpu_list()
From: Gavin Shan Add generic cpu_list() to replace the individual target's implementation in the subsequent commits. Currently, there are 3 targets with no cpu_list() implementation: microblaze and nios2. With this applied, those two targets switch to the generic cpu_list(). [gshan@gshan q]$ ./build/qemu-system-microblaze -cpu ? Available CPUs: microblaze-cpu [gshan@gshan q]$ ./build/qemu-system-nios2 -cpu ? Available CPUs: nios2-cpu Suggested-by: Richard Henderson Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-7-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- bsd-user/main.c | 5 + cpu-target.c| 29 ++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/bsd-user/main.c b/bsd-user/main.c index e6014f517e..4de226d211 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -378,10 +378,7 @@ int main(int argc, char **argv) } else if (!strcmp(r, "cpu")) { cpu_model = argv[optind++]; if (is_help_option(cpu_model)) { -/* XXX: implement xxx_cpu_list for targets that still miss it */ -#if defined(cpu_list) -cpu_list(); -#endif +list_cpus(); exit(1); } } else if (!strcmp(r, "B")) { diff --git a/cpu-target.c b/cpu-target.c index 6f4afc1dbc..5eecd7ea2d 100644 --- a/cpu-target.c +++ b/cpu-target.c @@ -24,6 +24,7 @@ #include "hw/qdev-core.h" #include "hw/qdev-properties.h" #include "qemu/error-report.h" +#include "qemu/qemu-print.h" #include "migration/vmstate.h" #ifdef CONFIG_USER_ONLY #include "qemu.h" @@ -283,12 +284,34 @@ const char *parse_cpu_option(const char *cpu_option) return cpu_type; } +#ifndef cpu_list +static void cpu_list_entry(gpointer data, gpointer user_data) +{ +CPUClass *cc = CPU_CLASS(OBJECT_CLASS(data)); +const char *typename = object_class_get_name(OBJECT_CLASS(data)); +g_autofree char *model = cpu_model_from_type(typename); + +if (cc->deprecation_note) { +qemu_printf(" %s (deprecated)\n", model); +} else { +qemu_printf(" %s\n", model); +} +} + +static void cpu_list(void) +{ +GSList *list; + +list = object_class_get_list_sorted(TYPE_CPU, false); +qemu_printf("Available CPUs:\n"); +g_slist_foreach(list, cpu_list_entry, NULL); +g_slist_free(list); +} +#endif + void list_cpus(void) { -/* XXX: implement xxx_cpu_list for targets that still miss it */ -#if defined(cpu_list) cpu_list(); -#endif } #if defined(CONFIG_USER_ONLY) -- 2.41.0
[PULL 02/71] target/alpha: Remove fallback to ev67 cpu class
From: Gavin Shan 'ev67' CPU class will be returned to match everything, which makes no sense as mentioned in the comments. Remove the logic to fall back to 'ev67' CPU class to match everything. Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-2-gs...@redhat.com> [PMD: Reword subject, replace 'any' -> 'ev67' on linux-user] Signed-off-by: Philippe Mathieu-Daudé --- linux-user/alpha/target_elf.h | 2 +- target/alpha/cpu.c| 7 ++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/linux-user/alpha/target_elf.h b/linux-user/alpha/target_elf.h index 344e9f4d39..b77d638f6d 100644 --- a/linux-user/alpha/target_elf.h +++ b/linux-user/alpha/target_elf.h @@ -9,6 +9,6 @@ #define ALPHA_TARGET_ELF_H static inline const char *cpu_get_model(uint32_t eflags) { -return "any"; +return "ev67"; } #endif diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 39cf841b3e..91fe8ae095 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -141,11 +141,8 @@ static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model) typename = g_strdup_printf(ALPHA_CPU_TYPE_NAME("%s"), cpu_model); oc = object_class_by_name(typename); g_free(typename); - -/* TODO: remove match everything nonsense */ -if (!oc || object_class_is_abstract(oc)) { -/* Default to ev67; no reason not to emulate insns by default. */ -oc = object_class_by_name(ALPHA_CPU_TYPE_NAME("ev67")); +if (!oc || !object_class_dynamic_cast(oc, TYPE_ALPHA_CPU)) { +return NULL; } return oc; -- 2.41.0
[PULL 07/71] target/alpha: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-alpha -cpu ? Available CPUs: ev4-alpha-cpu ev5-alpha-cpu ev56-alpha-cpu ev6-alpha-cpu ev67-alpha-cpu ev68-alpha-cpu pca56-alpha-cpu After it's applied: [gshan@gshan q]$ ./build/qemu-system-alpha -cpu ? Available CPUs: ev4 ev5 ev56 ev6 ev67 ev68 pca56 Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-ID: <20231114235628.534334-8-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/alpha/cpu.h | 3 --- target/alpha/cpu.c | 17 - 2 files changed, 20 deletions(-) diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index d672e911dd..ce806587ca 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -292,8 +292,6 @@ void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags); int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); -#define cpu_list alpha_cpu_list - #include "exec/cpu-all.h" enum { @@ -441,7 +439,6 @@ void alpha_translate_init(void); #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU -void alpha_cpu_list(void); G_NORETURN void dynamic_excp(CPUAlphaState *, uintptr_t, int, int); G_NORETURN void arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t); diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 83345c5c7d..b8ed29e343 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -87,23 +87,6 @@ static void alpha_cpu_realizefn(DeviceState *dev, Error **errp) acc->parent_realize(dev, errp); } -static void alpha_cpu_list_entry(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; - -qemu_printf(" %s\n", object_class_get_name(oc)); -} - -void alpha_cpu_list(void) -{ -GSList *list; - -list = object_class_get_list_sorted(TYPE_ALPHA_CPU, false); -qemu_printf("Available CPUs:\n"); -g_slist_foreach(list, alpha_cpu_list_entry, NULL); -g_slist_free(list); -} - /* Models */ typedef struct AlphaCPUAlias { const char *alias; -- 2.41.0
[PULL 04/71] cpu: Call object_class_dynamic_cast() once in cpu_class_by_name()
For all targets, the CPU class returned from CPUClass::class_by_name() and object_class_dynamic_cast(oc, CPU_RESOLVING_TYPE) need to be compatible. Lets apply the check in cpu_class_by_name() for once, instead of having the check in CPUClass::class_by_name() for individual target. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Gavin Shan Reviewed-by: Igor Mammedov Reviewed-by: Richard Henderson Signed-off-by: Gavin Shan Message-ID: <20231114235628.534334-4-gs...@redhat.com> --- hw/core/cpu-common.c | 8 +--- target/alpha/cpu.c | 3 --- target/arm/cpu.c | 4 +--- target/avr/cpu.c | 8 +--- target/cris/cpu.c | 4 +--- target/hexagon/cpu.c | 4 +--- target/hppa/cpu.c | 6 +- target/loongarch/cpu.c | 8 +--- target/m68k/cpu.c | 4 +--- target/openrisc/cpu.c | 4 +--- target/riscv/cpu.c | 4 +--- target/tricore/cpu.c | 4 +--- target/xtensa/cpu.c| 4 +--- 13 files changed, 16 insertions(+), 49 deletions(-) diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 82dae51a55..d0e7bbdf06 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -154,10 +154,12 @@ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model) assert(cc->class_by_name); assert(cpu_model); oc = cc->class_by_name(cpu_model); -if (oc == NULL || object_class_is_abstract(oc)) { -return NULL; +if (object_class_dynamic_cast(oc, typename) && +!object_class_is_abstract(oc)) { +return oc; } -return oc; + +return NULL; } static void cpu_common_parse_features(const char *typename, char *features, diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 91fe8ae095..83345c5c7d 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -141,9 +141,6 @@ static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model) typename = g_strdup_printf(ALPHA_CPU_TYPE_NAME("%s"), cpu_model); oc = object_class_by_name(typename); g_free(typename); -if (!oc || !object_class_dynamic_cast(oc, TYPE_ALPHA_CPU)) { -return NULL; -} return oc; } diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 650e09b29c..1c8b787482 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2411,9 +2411,7 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model) oc = object_class_by_name(typename); g_strfreev(cpuname); g_free(typename); -if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU)) { -return NULL; -} + return oc; } diff --git a/target/avr/cpu.c b/target/avr/cpu.c index 999c010ded..3e478294a6 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c @@ -160,13 +160,7 @@ static Property avr_cpu_properties[] = { static ObjectClass *avr_cpu_class_by_name(const char *cpu_model) { -ObjectClass *oc; - -oc = object_class_by_name(cpu_model); -if (object_class_dynamic_cast(oc, TYPE_AVR_CPU) == NULL) { -oc = NULL; -} -return oc; +return object_class_by_name(cpu_model); } static void avr_cpu_dump_state(CPUState *cs, FILE *f, int flags) diff --git a/target/cris/cpu.c b/target/cris/cpu.c index 675b73ac04..a5083a0077 100644 --- a/target/cris/cpu.c +++ b/target/cris/cpu.c @@ -95,9 +95,7 @@ static ObjectClass *cris_cpu_class_by_name(const char *cpu_model) typename = g_strdup_printf(CRIS_CPU_TYPE_NAME("%s"), cpu_model); oc = object_class_by_name(typename); g_free(typename); -if (oc != NULL && !object_class_dynamic_cast(oc, TYPE_CRIS_CPU)) { -oc = NULL; -} + return oc; } diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 9d1ffc3b4b..aa48f5fe89 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -63,9 +63,7 @@ static ObjectClass *hexagon_cpu_class_by_name(const char *cpu_model) oc = object_class_by_name(typename); g_strfreev(cpuname); g_free(typename); -if (!oc || !object_class_dynamic_cast(oc, TYPE_HEXAGON_CPU)) { -return NULL; -} + return oc; } diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index e3e7200b1d..1a5fb6c65b 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -160,12 +160,8 @@ static void hppa_cpu_initfn(Object *obj) static ObjectClass *hppa_cpu_class_by_name(const char *cpu_model) { g_autofree char *typename = g_strconcat(cpu_model, "-cpu", NULL); -ObjectClass *oc = object_class_by_name(typename); -if (oc && object_class_dynamic_cast(oc, TYPE_HPPA_CPU)) { -return oc; -} -return NULL; +return object_class_by_name(typename); } static void hppa_cpu_list_entry(gpointer data, gpointer user_data) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 07319d6fb9..81f2d8d8ed 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -718,15 +718,9 @@ static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model) g_autofree char *typename = g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_m
[PULL 09/71] target/avr: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-avr -cpu ? avr5-avr-cpu avr51-avr-cpu avr6-avr-cpu After it's applied: [gshan@gshan q]$ ./build/qemu-system-avr -cpu ? Available CPUs: avr5 avr51 avr6 Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-ID: <20231114235628.534334-10-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/avr/cpu.h | 2 -- target/avr/cpu.c | 15 --- 2 files changed, 17 deletions(-) diff --git a/target/avr/cpu.h b/target/avr/cpu.h index 7960c5c57a..7d5dd42575 100644 --- a/target/avr/cpu.h +++ b/target/avr/cpu.h @@ -184,7 +184,6 @@ static inline void set_avr_feature(CPUAVRState *env, int feature) env->features |= (1U << feature); } -#define cpu_list avr_cpu_list #define cpu_mmu_index avr_cpu_mmu_index static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch) @@ -194,7 +193,6 @@ static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch) void avr_cpu_tcg_init(void); -void avr_cpu_list(void); int cpu_avr_exec(CPUState *cpu); enum { diff --git a/target/avr/cpu.c b/target/avr/cpu.c index 3e478294a6..f5cbdc4a8c 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c @@ -362,21 +362,6 @@ typedef struct AVRCPUInfo { } AVRCPUInfo; -static void avr_cpu_list_entry(gpointer data, gpointer user_data) -{ -const char *typename = object_class_get_name(OBJECT_CLASS(data)); - -qemu_printf("%s\n", typename); -} - -void avr_cpu_list(void) -{ -GSList *list; -list = object_class_get_list_sorted(TYPE_AVR_CPU, false); -g_slist_foreach(list, avr_cpu_list_entry, NULL); -g_slist_free(list); -} - #define DEFINE_AVR_CPU_TYPE(model, initfn) \ { \ .parent = TYPE_AVR_CPU, \ -- 2.41.0
[PULL 13/71] target/loongarch: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-loongarch64 -cpu ? la132-loongarch-cpu la464-loongarch-cpu max-loongarch-cpu After it's applied: [gshan@gshan q]$ ./build/qemu-system-loongarch64 -cpu ? Available CPUs: la132 la464 max Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-14-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/loongarch/cpu.h | 4 target/loongarch/cpu.c | 15 --- 2 files changed, 19 deletions(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 00d1fba597..0c15a174e4 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -466,10 +466,6 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc, *flags |= is_va32(env) * HW_FLAGS_VA32; } -void loongarch_cpu_list(void); - -#define cpu_list loongarch_cpu_list - #include "exec/cpu-all.h" #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 81f2d8d8ed..87dfcdb0a5 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -483,21 +483,6 @@ static void loongarch_max_initfn(Object *obj) loongarch_la464_initfn(obj); } -static void loongarch_cpu_list_entry(gpointer data, gpointer user_data) -{ -const char *typename = object_class_get_name(OBJECT_CLASS(data)); - -qemu_printf("%s\n", typename); -} - -void loongarch_cpu_list(void) -{ -GSList *list; -list = object_class_get_list_sorted(TYPE_LOONGARCH_CPU, false); -g_slist_foreach(list, loongarch_cpu_list_entry, NULL); -g_slist_free(list); -} - static void loongarch_cpu_reset_hold(Object *obj) { CPUState *cs = CPU(obj); -- 2.41.0
[PULL 12/71] target/hppa: Use generic cpu_list()
From: Gavin Shan No changes in the output from the following command. [gshan@gshan q]$ ./build/qemu-system-hppa -cpu ? Available CPUs: hppa hppa64 Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-ID: <20231114235628.534334-13-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/hppa/cpu.h | 3 --- target/hppa/cpu.c | 24 2 files changed, 27 deletions(-) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 8be45c69c9..fd659ca88b 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -402,7 +402,4 @@ G_NORETURN void hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t ra); #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU -#define cpu_list hppa_cpu_list -void hppa_cpu_list(void); - #endif /* HPPA_CPU_H */ diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 1a5fb6c65b..e1f252cc45 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -164,30 +164,6 @@ static ObjectClass *hppa_cpu_class_by_name(const char *cpu_model) return object_class_by_name(typename); } -static void hppa_cpu_list_entry(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -CPUClass *cc = CPU_CLASS(oc); -const char *tname = object_class_get_name(oc); -g_autofree char *name = g_strndup(tname, strchr(tname, '-') - tname); - -if (cc->deprecation_note) { -qemu_printf(" %s (deprecated)\n", name); -} else { -qemu_printf(" %s\n", name); -} -} - -void hppa_cpu_list(void) -{ -GSList *list; - -list = object_class_get_list_sorted(TYPE_HPPA_CPU, false); -qemu_printf("Available CPUs:\n"); -g_slist_foreach(list, hppa_cpu_list_entry, NULL); -g_slist_free(list); -} - #ifndef CONFIG_USER_ONLY #include "hw/core/sysemu-cpu-ops.h" -- 2.41.0
[PULL 10/71] target/cris: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-cris -cpu ? Available CPUs: crisv8 crisv9 crisv10 crisv11 crisv17 crisv32 After it's applied: [gshan@gshan q]$ ./build/qemu-system-cris -cpu ? Available CPUs: crisv10 crisv11 crisv17 crisv32 crisv8 crisv9 Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-11-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/cris/cpu.h | 3 --- target/cris/cpu.c | 38 -- 2 files changed, 41 deletions(-) diff --git a/target/cris/cpu.h b/target/cris/cpu.h index 1be7f90319..d830dcac5b 100644 --- a/target/cris/cpu.h +++ b/target/cris/cpu.h @@ -287,7 +287,4 @@ static inline void cpu_get_tb_cpu_state(CPUCRISState *env, vaddr *pc, | X_FLAG | PFIX_FLAG)); } -#define cpu_list cris_cpu_list -void cris_cpu_list(void); - #endif diff --git a/target/cris/cpu.c b/target/cris/cpu.c index a5083a0077..9ba08e8b0c 100644 --- a/target/cris/cpu.c +++ b/target/cris/cpu.c @@ -99,44 +99,6 @@ static ObjectClass *cris_cpu_class_by_name(const char *cpu_model) return oc; } -/* Sort alphabetically by VR. */ -static gint cris_cpu_list_compare(gconstpointer a, gconstpointer b) -{ -CRISCPUClass *ccc_a = CRIS_CPU_CLASS(a); -CRISCPUClass *ccc_b = CRIS_CPU_CLASS(b); - -/* */ -if (ccc_a->vr > ccc_b->vr) { -return 1; -} else if (ccc_a->vr < ccc_b->vr) { -return -1; -} else { -return 0; -} -} - -static void cris_cpu_list_entry(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -const char *typename = object_class_get_name(oc); -char *name; - -name = g_strndup(typename, strlen(typename) - strlen(CRIS_CPU_TYPE_SUFFIX)); -qemu_printf(" %s\n", name); -g_free(name); -} - -void cris_cpu_list(void) -{ -GSList *list; - -list = object_class_get_list(TYPE_CRIS_CPU, false); -list = g_slist_sort(list, cris_cpu_list_compare); -qemu_printf("Available CPUs:\n"); -g_slist_foreach(list, cris_cpu_list_entry, NULL); -g_slist_free(list); -} - static void cris_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); -- 2.41.0
[PULL 18/71] target/rx: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-rx -cpu ? Available CPUs: rx62n-rx-cpu After it's applied: [gshan@gshan q]$ ./build/qemu-system-rx -cpu ? Available CPUs: rx62n Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-19-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/rx/cpu.h | 3 --- target/rx/cpu.c | 16 2 files changed, 19 deletions(-) diff --git a/target/rx/cpu.h b/target/rx/cpu.h index e931e77e85..65f9cd2d0a 100644 --- a/target/rx/cpu.h +++ b/target/rx/cpu.h @@ -139,11 +139,8 @@ int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void rx_translate_init(void); -void rx_cpu_list(void); void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte); -#define cpu_list rx_cpu_list - #include "exec/cpu-all.h" #define CPU_INTERRUPT_SOFT CPU_INTERRUPT_TGT_INT_0 diff --git a/target/rx/cpu.c b/target/rx/cpu.c index 9cc9d9d15e..c5ffeffe32 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c @@ -89,22 +89,6 @@ static void rx_cpu_reset_hold(Object *obj) set_flush_inputs_to_zero(1, &env->fp_status); } -static void rx_cpu_list_entry(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; - -qemu_printf(" %s\n", object_class_get_name(oc)); -} - -void rx_cpu_list(void) -{ -GSList *list; -list = object_class_get_list_sorted(TYPE_RX_CPU, false); -qemu_printf("Available CPUs:\n"); -g_slist_foreach(list, rx_cpu_list_entry, NULL); -g_slist_free(list); -} - static ObjectClass *rx_cpu_class_by_name(const char *cpu_model) { ObjectClass *oc; -- 2.41.0
[PULL 03/71] target/hppa: Remove object_class_is_abstract()
From: Gavin Shan Since commit 3a9d0d7b64 ("hw/cpu: Call object_class_is_abstract() once in cpu_class_by_name()"), there is no need to check if @oc is abstract because it has been covered by cpu_class_by_name(). Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-3-gs...@redhat.com> [PMD: Mention commit 3a9d0d7b64] Signed-off-by: Philippe Mathieu-Daudé --- target/hppa/cpu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 04de1689d7..e3e7200b1d 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -162,9 +162,7 @@ static ObjectClass *hppa_cpu_class_by_name(const char *cpu_model) g_autofree char *typename = g_strconcat(cpu_model, "-cpu", NULL); ObjectClass *oc = object_class_by_name(typename); -if (oc && -!object_class_is_abstract(oc) && -object_class_dynamic_cast(oc, TYPE_HPPA_CPU)) { +if (oc && object_class_dynamic_cast(oc, TYPE_HPPA_CPU)) { return oc; } return NULL; -- 2.41.0
[PULL 01/71] meson: Allow building binary with no target-specific files in hw/
Allow building a qemu-system-foo binary with target-agnostic only HW models. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20231121203129.67999-1-phi...@linaro.org> --- meson.build | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index 5a2582776c..371edafae6 100644 --- a/meson.build +++ b/meson.build @@ -3771,9 +3771,11 @@ foreach target : target_dirs arch_deps += t.dependencies() hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch -hw = hw_arch[hw_dir].apply(config_target, strict: false) -arch_srcs += hw.sources() -arch_deps += hw.dependencies() +if hw_arch.has_key(hw_dir) + hw = hw_arch[hw_dir].apply(config_target, strict: false) + arch_srcs += hw.sources() + arch_deps += hw.dependencies() +endif arch_srcs += config_devices_h[target] link_args += ['@block.syms', '@qemu.syms'] -- 2.41.0
[PULL 00/71] HW core patches for 2024-01-05
The following changes since commit 05470c3979d5485003e129ff4b0c2ef98af91d86: Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2024-01-04 19:55:20 +) are available in the Git repository at: https://github.com/philmd/qemu.git tags/hw-cpus-20240105 for you to fetch changes up to a318da6b3f6a88e6cfd6953c519def9457e8962f: target/sparc: Simplify qemu_irq_ack (2024-01-05 16:20:15 +0100) HW core patch queue - Unify CPU QOM type checks (Gavin) - Simplify uses of some CPU related property (Philippe) (start-powered-off, ARM reset-cbar and mp-affinity) - Header and documentation cleanups (Zhao, Philippe) - Have Memory API return boolean indicating possible error - Fix frame filter mask in CAN sja1000 model (Pavel) - QOM embed MCF5206 timer into SoC (Thomas) - Simplify LEON3 qemu_irq_ack handler (Clément) Clément Chigot (1): target/sparc: Simplify qemu_irq_ack Gavin Shan (29): target/alpha: Remove fallback to ev67 cpu class target/hppa: Remove object_class_is_abstract() cpu: Add helper cpu_model_from_type() cpu: Add generic cpu_list() target/alpha: Use generic cpu_list() target/arm: Use generic cpu_list() target/avr: Use generic cpu_list() target/cris: Use generic cpu_list() target/hexagon: Use generic cpu_list() target/hppa: Use generic cpu_list() target/loongarch: Use generic cpu_list() target/m68k: Use generic cpu_list() target/mips: Use generic cpu_list() target/openrisc: Use generic cpu_list() target/riscv: Use generic cpu_list() target/rx: Use generic cpu_list() target/sh4: Use generic cpu_list() target/tricore: Use generic cpu_list() target/xtensa: Use generic cpu_list() target: Use generic cpu_model_from_type() machine: Use error handling when CPU type is checked machine: Introduce helper is_cpu_type_supported() machine: Improve is_cpu_type_supported() machine: Print CPU model name instead of CPU type hw/arm/virt: Hide host CPU model for tcg hw/arm/virt: Check CPU type in machine_run_board_init() hw/arm/sbsa-ref: Check CPU type in machine_run_board_init() hw/arm: Check CPU type in machine_run_board_init() hw/riscv/shakti_c: Check CPU type in machine_run_board_init() Pavel Pisa (1): hw/net/can/sja1000: fix bug for single acceptance filter and standard frame Philippe Mathieu-Daudé (37): meson: Allow building binary with no target-specific files in hw/ cpu: Call object_class_dynamic_cast() once in cpu_class_by_name() hw/core: Add machine_class_default_cpu_type() hw/core/cpu: Remove final vestiges of dynamic state tracing hw/core/cpu: Update description of CPUState::node hw/audio/sb16: Do not migrate qdev properties hw/arm/bcm2836: Simplify use of 'reset-cbar' property hw/arm/bcm2836: Use ARM_CPU 'mp-affinity' property hw/ppc/spapr_cpu_core: Access QDev properties with proper API hw: Simplify accesses to the CPUState::'start-powered-off' property hw/ppc/xive2_regs: Remove unnecessary 'cpu.h' inclusion hw/mips: Inline 'bios.h' definitions memory: Have memory_region_init_ram_flags_nomigrate() return a boolean memory: Have memory_region_init_ram_nomigrate() handler return a boolean memory: Have memory_region_init_rom_nomigrate() handler return a boolean memory: Simplify memory_region_init_rom_nomigrate() calls memory: Simplify memory_region_init_ram_from_fd() calls memory: Have memory_region_init_ram() handler return a boolean memory: Have memory_region_init_rom() handler return a boolean memory: Have memory_region_init_rom_device_nomigrate() return a boolean memory: Simplify memory_region_init_rom_device_nomigrate() calls memory: Have memory_region_init_rom_device() handler return a boolean memory: Have memory_region_init_resizeable_ram() return a boolean memory: Have memory_region_init_ram_from_file() handler return a boolean memory: Have memory_region_init_ram_from_fd() handler return a boolean backends: Use g_autofree in HostMemoryBackendClass::alloc() handlers backends: Simplify host_memory_backend_memory_complete() backends: Have HostMemoryBackendClass::alloc() handler return a boolean backends: Reduce variable scope in host_memory_backend_memory_complete util/oslib: Have qemu_prealloc_mem() handler return a boolean misc: Simplify qemu_prealloc_mem() calls hw: Simplify memory_region_init_ram() calls hw/arm: Simplify memory_region_init_rom() calls hw/sparc: Simplify memory_region_init_ram_nomigrate() calls hw/misc: Simplify memory_region_init_ram_from_fd() calls hw/nvram: Simplify memory_region_init_rom_device() calls hw/pci-host/raven: Propagate error in raven_realize() Thomas Huth (1): hw/m68k/mcf5206: Embed m5206_timer_state in m5206_mbar_state Zhao Liu (2): hw/cpu/core: Cleanup unused included header i
[PULL 08/71] target/arm: Use generic cpu_list()
From: Gavin Shan No changes of the output from the following command before and after it's applied. [gshan@gshan q]$ ./build/qemu-system-aarch64 -cpu ? Available CPUs: a64fx arm1026 arm1136 arm1136-r2 arm1176 arm11mpcore arm926 arm946 cortex-a15 cortex-a35 cortex-a53 cortex-a55 cortex-a57 cortex-a7 cortex-a710 cortex-a72 cortex-a76 cortex-a8 cortex-a9 cortex-m0 cortex-m3 cortex-m33 cortex-m4 cortex-m55 cortex-m7 cortex-r5 cortex-r52 cortex-r5f max neoverse-n1 neoverse-n2 neoverse-v1 pxa250 pxa255 pxa260 pxa261 pxa262 pxa270-a0 pxa270-a1 pxa270 pxa270-b0 pxa270-b1 pxa270-c0 pxa270-c5 sa1100 sa1110 ti925t Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-ID: <20231114235628.534334-9-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/arm/cpu.h| 3 --- target/arm/helper.c | 46 - 2 files changed, 49 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index a0282e0d28..8c3ca2e231 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2737,7 +2737,6 @@ static inline bool access_secure_reg(CPUARMState *env) (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \ (_val)) -void arm_cpu_list(void); uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, uint32_t cur_el, bool secure); @@ -2840,8 +2839,6 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync); #define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU -#define cpu_list arm_cpu_list - /* ARM has the following "translation regimes" (as the ARM ARM calls them): * * If EL3 is 64-bit: diff --git a/target/arm/helper.c b/target/arm/helper.c index fc546df5c7..a2a7f6c29f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9468,52 +9468,6 @@ void register_cp_regs_for_features(ARMCPU *cpu) #endif } -/* Sort alphabetically by type name, except for "any". */ -static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b) -{ -ObjectClass *class_a = (ObjectClass *)a; -ObjectClass *class_b = (ObjectClass *)b; -const char *name_a, *name_b; - -name_a = object_class_get_name(class_a); -name_b = object_class_get_name(class_b); -if (strcmp(name_a, "any-" TYPE_ARM_CPU) == 0) { -return 1; -} else if (strcmp(name_b, "any-" TYPE_ARM_CPU) == 0) { -return -1; -} else { -return strcmp(name_a, name_b); -} -} - -static void arm_cpu_list_entry(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -CPUClass *cc = CPU_CLASS(oc); -const char *typename; -char *name; - -typename = object_class_get_name(oc); -name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_ARM_CPU)); -if (cc->deprecation_note) { -qemu_printf(" %s (deprecated)\n", name); -} else { -qemu_printf(" %s\n", name); -} -g_free(name); -} - -void arm_cpu_list(void) -{ -GSList *list; - -list = object_class_get_list(TYPE_ARM_CPU, false); -list = g_slist_sort(list, arm_cpu_list_compare); -qemu_printf("Available CPUs:\n"); -g_slist_foreach(list, arm_cpu_list_entry, NULL); -g_slist_free(list); -} - /* * Private utility function for define_one_arm_cp_reg_with_opaque(): * add a single reginfo struct to the hash table. -- 2.41.0
[PULL 22/71] target: Use generic cpu_model_from_type()
From: Gavin Shan Use generic cpu_model_from_type() when the CPU model name needs to be extracted from the CPU type name. Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-ID: <20231114235628.534334-23-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/arm/arm-qmp-cmds.c | 3 +-- target/i386/cpu.c | 3 +-- target/loongarch/loongarch-qmp-cmds.c | 3 +-- target/mips/sysemu/mips-qmp-cmds.c| 3 +-- target/ppc/cpu_init.c | 3 +-- target/ppc/ppc-qmp-cmds.c | 3 +-- target/riscv/cpu.c| 3 +-- target/riscv/riscv-qmp-cmds.c | 3 +-- 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index b53d5efe13..2250cd7ddf 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -237,8 +237,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data) typename = object_class_get_name(oc); info = g_malloc0(sizeof(*info)); -info->name = g_strndup(typename, - strlen(typename) - strlen("-" TYPE_ARM_CPU)); +info->name = cpu_model_from_type(typename); info->q_typename = g_strdup(typename); QAPI_LIST_PREPEND(*cpu_list, info); diff --git a/target/i386/cpu.c b/target/i386/cpu.c index fd47ee7def..2524881ce2 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1744,8 +1744,7 @@ static char *x86_cpu_class_get_model_name(X86CPUClass *cc) { const char *class_name = object_class_get_name(OBJECT_CLASS(cc)); assert(g_str_has_suffix(class_name, X86_CPU_TYPE_SUFFIX)); -return g_strndup(class_name, - strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX)); +return cpu_model_from_type(class_name); } typedef struct X86CPUVersionDefinition { diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c index 645672ff59..ec33ce81f0 100644 --- a/target/loongarch/loongarch-qmp-cmds.c +++ b/target/loongarch/loongarch-qmp-cmds.c @@ -22,8 +22,7 @@ static void loongarch_cpu_add_definition(gpointer data, gpointer user_data) CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1); const char *typename = object_class_get_name(oc); -info->name = g_strndup(typename, - strlen(typename) - strlen("-" TYPE_LOONGARCH_CPU)); +info->name = cpu_model_from_type(typename); info->q_typename = g_strdup(typename); QAPI_LIST_PREPEND(*cpu_list, info); diff --git a/target/mips/sysemu/mips-qmp-cmds.c b/target/mips/sysemu/mips-qmp-cmds.c index 6db4626412..7340ac70ba 100644 --- a/target/mips/sysemu/mips-qmp-cmds.c +++ b/target/mips/sysemu/mips-qmp-cmds.c @@ -19,8 +19,7 @@ static void mips_cpu_add_definition(gpointer data, gpointer user_data) typename = object_class_get_name(oc); info = g_malloc0(sizeof(*info)); -info->name = g_strndup(typename, - strlen(typename) - strlen("-" TYPE_MIPS_CPU)); +info->name = cpu_model_from_type(typename); info->q_typename = g_strdup(typename); QAPI_LIST_PREPEND(*cpu_list, info); diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 40fe14a6c2..344196a8ce 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -7036,8 +7036,7 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data) return; } -name = g_strndup(typename, - strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX)); +name = cpu_model_from_type(typename); qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr); for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { PowerPCCPUAlias *alias = &ppc_cpu_aliases[i]; diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c index f9acc21056..c0c137d9d7 100644 --- a/target/ppc/ppc-qmp-cmds.c +++ b/target/ppc/ppc-qmp-cmds.c @@ -181,8 +181,7 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) typename = object_class_get_name(oc); info = g_malloc0(sizeof(*info)); -info->name = g_strndup(typename, - strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX)); +info->name = cpu_model_from_type(typename); QAPI_LIST_PREPEND(*first, info); } diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 22d7422c89..b07a76ef6b 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -657,8 +657,7 @@ char *riscv_cpu_get_name(RISCVCPU *cpu) g_assert(g_str_has_suffix(typename, RISCV_CPU_TYPE_SUFFIX)); -return g_strndup(typename, - strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX)); +return cpu_model_from_type(typename); } static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c index 2f2dbae7c8..c5551d2cfe 100644 --- a/target/riscv/riscv-qmp-cmds.c +++ b/target/riscv/riscv-
[PULL 15/71] target/mips: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-mips64 -cpu ? MIPS '4Kc' MIPS '4Km' MIPS '4KEcR1' MIPS 'XBurstR1' MIPS '4KEmR1' MIPS '4KEc' MIPS '4KEm' MIPS '24Kc' MIPS '24KEc' MIPS '24Kf' MIPS '34Kf' MIPS '74Kf' MIPS 'XBurstR2' MIPS 'M14K' MIPS 'M14Kc' MIPS 'P5600' MIPS 'mips32r6-generic' MIPS 'I7200' MIPS 'R4000' MIPS 'VR5432' MIPS '5Kc' MIPS '5Kf' MIPS '20Kc' MIPS 'MIPS64R2-generic' MIPS '5KEc' MIPS '5KEf' MIPS 'I6400' MIPS 'I6500' MIPS 'Loongson-2E' MIPS 'Loongson-2F' MIPS 'Loongson-3A1000' MIPS 'Loongson-3A4000' MIPS 'mips64dspr2' MIPS 'Octeon68XX' After it's applied: [gshan@gshan q]$ ./build/qemu-system-mips64 -cpu ? Available CPUs: 20Kc 24Kc 24KEc 24Kf 34Kf 4Kc 4KEc 4KEcR1 4KEm 4KEmR1 4Km 5Kc 5KEc 5KEf 5Kf 74Kf I6400 I6500 I7200 Loongson-2E Loongson-2F Loongson-3A1000 Loongson-3A4000 M14K M14Kc mips32r6-generic mips64dspr2 MIPS64R2-generic Octeon68XX P5600 R4000 VR5432 XBurstR1 XBurstR2 Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-ID: <20231114235628.534334-16-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/mips/cpu.h | 4 target/mips/cpu-defs.c.inc | 9 - 2 files changed, 13 deletions(-) diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 52f13f0363..1163a71f3c 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1235,10 +1235,6 @@ struct MIPSCPUClass { bool no_data_aborts; }; -void mips_cpu_list(void); - -#define cpu_list mips_cpu_list - void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env); uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env); diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc index c0c389c59a..fbf787d8ce 100644 --- a/target/mips/cpu-defs.c.inc +++ b/target/mips/cpu-defs.c.inc @@ -1018,15 +1018,6 @@ const mips_def_t mips_defs[] = }; const int mips_defs_number = ARRAY_SIZE(mips_defs); -void mips_cpu_list(void) -{ -int i; - -for (i = 0; i < ARRAY_SIZE(mips_defs); i++) { -qemu_printf("MIPS '%s'\n", mips_defs[i].name); -} -} - static void fpu_init (CPUMIPSState *env, const mips_def_t *def) { int i; -- 2.41.0
[PULL 28/71] hw/arm/virt: Hide host CPU model for tcg
From: Gavin Shan The 'host' CPU model isn't available until KVM or HVF is enabled. For example, the following error messages are seen when the guest is started with option '-cpu cortex-a8' on tcg after the next commit is applied to check the CPU type in machine_run_board_init(). ERROR:../hw/core/machine.c:1423:is_cpu_type_supported: \ assertion failed: (model != NULL) Bail out! ERROR:../hw/core/machine.c:1423:is_cpu_type_supported: \ assertion failed: (model != NULL) Aborted (core dumped) Hide 'host' CPU model until KVM or HVF is enabled. With this applied, the valid CPU models can be shown. qemu-system-aarch64: Invalid CPU type: cortex-a8 The valid types are: cortex-a7, cortex-a15, cortex-a35, \ cortex-a55, cortex-a72, cortex-a76, cortex-a710, a64fx, \ neoverse-n1, neoverse-v1, neoverse-n2, cortex-a53, \ cortex-a57, max Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231204004726.483558-6-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/arm/virt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8b69aba189..8b060ef1d9 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -220,7 +220,9 @@ static const char *valid_cpus[] = { #endif ARM_CPU_TYPE_NAME("cortex-a53"), ARM_CPU_TYPE_NAME("cortex-a57"), +#if defined(CONFIG_KVM) || defined(CONFIG_HVF) ARM_CPU_TYPE_NAME("host"), +#endif ARM_CPU_TYPE_NAME("max"), }; -- 2.41.0
[PULL 21/71] target/xtensa: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-xtensa -cpu ? Available CPUs: test_mmuhifi_c3 sample_controller lx106 dsp3400 de233_fpu de212 dc233c dc232b After it's applied: [gshan@gshan q]$ ./build/qemu-system-xtensa -cpu ? Available CPUs: dc232b dc233c de212 de233_fpu dsp3400 lx106 sample_controller test_mmuhifi_c3 Signed-off-by: Gavin Shan Message-ID: <20231114235628.534334-22-gs...@redhat.com> [PMD: Split patch in 2, only include the "Use generic cpu_list" change] Message-ID: <51ffd060-b2f8-405c-83e1-a0663c018...@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- target/xtensa/cpu.h| 3 --- target/xtensa/helper.c | 9 - 2 files changed, 12 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index dd81729306..d9c49a35fa 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -600,8 +600,6 @@ G_NORETURN void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); -#define cpu_list xtensa_cpu_list - #define CPU_RESOLVING_TYPE TYPE_XTENSA_CPU #if TARGET_BIG_ENDIAN @@ -626,7 +624,6 @@ void check_interrupts(CPUXtensaState *s); void xtensa_irq_init(CPUXtensaState *env); qemu_irq *xtensa_get_extints(CPUXtensaState *env); qemu_irq xtensa_get_runstall(CPUXtensaState *env); -void xtensa_cpu_list(void); void xtensa_sync_window_from_phys(CPUXtensaState *env); void xtensa_sync_phys_from_window(CPUXtensaState *env); void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta); diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c index dbeb97a953..f6632df646 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -234,15 +234,6 @@ void xtensa_breakpoint_handler(CPUState *cs) } } -void xtensa_cpu_list(void) -{ -XtensaConfigList *core = xtensa_cores; -qemu_printf("Available CPUs:\n"); -for (; core; core = core->next) { -qemu_printf(" %s\n", core->config->name); -} -} - #ifndef CONFIG_USER_ONLY void xtensa_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, -- 2.41.0
[PULL 26/71] machine: Improve is_cpu_type_supported()
From: Gavin Shan It's no sense to check the CPU type when mc->valid_cpu_types[0] is NULL, which is a program error. Raise an assert on this. A precise hint for the error message is given when mc->valid_cpu_types[0] is the only valid entry. Besides, enumeration on mc->valid_cpu_types[0] when we have mutiple valid entries there is avoided to increase the code readability, as suggested by Philippe Mathieu-Daudé. Besides, @cc comes from machine->cpu_type or mc->default_cpu_type. For the later case, it can be NULL and it's also a program error. We should use assert() in this case. Signed-off-by: Gavin Shan Message-ID: <20231204004726.483558-4-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine.c | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 0119b11fc8..c523ce32eb 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1412,6 +1412,7 @@ static bool is_cpu_type_supported(const MachineState *machine, Error **errp) * type is provided through '-cpu' option. */ if (mc->valid_cpu_types) { +assert(mc->valid_cpu_types[0] != NULL); for (i = 0; mc->valid_cpu_types[i]; i++) { if (object_class_dynamic_cast(oc, mc->valid_cpu_types[i])) { break; @@ -1421,20 +1422,27 @@ static bool is_cpu_type_supported(const MachineState *machine, Error **errp) /* The user specified CPU type isn't valid */ if (!mc->valid_cpu_types[i]) { error_setg(errp, "Invalid CPU type: %s", machine->cpu_type); -error_append_hint(errp, "The valid types are: %s", - mc->valid_cpu_types[0]); -for (i = 1; mc->valid_cpu_types[i]; i++) { -error_append_hint(errp, ", %s", mc->valid_cpu_types[i]); +if (!mc->valid_cpu_types[1]) { +error_append_hint(errp, "The only valid type is: %s\n", + mc->valid_cpu_types[0]); +} else { +error_append_hint(errp, "The valid types are: "); +for (i = 0; mc->valid_cpu_types[i]; i++) { +error_append_hint(errp, "%s%s", + mc->valid_cpu_types[i], + mc->valid_cpu_types[i + 1] ? ", " : ""); +} +error_append_hint(errp, "\n"); } -error_append_hint(errp, "\n"); return false; } } /* Check if CPU type is deprecated and warn if so */ cc = CPU_CLASS(oc); -if (cc && cc->deprecation_note) { +assert(cc != NULL); +if (cc->deprecation_note) { warn_report("CPU model %s is deprecated -- %s", machine->cpu_type, cc->deprecation_note); } -- 2.41.0
[PULL 20/71] target/tricore: Use generic cpu_list()
From: Gavin Shan No changes in the output from the following command. [gshan@gshan q]$ ./build/qemu-system-tricore -cpu ? Available CPUs: tc1796 tc1797 tc27x tc37x Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-21-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/tricore/cpu.h| 4 target/tricore/helper.c | 22 -- 2 files changed, 26 deletions(-) diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h index de3ab53a83..2d4446cea5 100644 --- a/target/tricore/cpu.h +++ b/target/tricore/cpu.h @@ -246,10 +246,6 @@ void fpu_set_state(CPUTriCoreState *env); #define MMU_USER_IDX 2 -void tricore_cpu_list(void); - -#define cpu_list tricore_cpu_list - static inline int cpu_mmu_index(CPUTriCoreState *env, bool ifetch) { return 0; diff --git a/target/tricore/helper.c b/target/tricore/helper.c index 7e5da3cb23..174f666e1e 100644 --- a/target/tricore/helper.c +++ b/target/tricore/helper.c @@ -96,28 +96,6 @@ bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } } -static void tricore_cpu_list_entry(gpointer data, gpointer user_data) -{ -ObjectClass *oc = data; -const char *typename; -char *name; - -typename = object_class_get_name(oc); -name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_TRICORE_CPU)); -qemu_printf(" %s\n", name); -g_free(name); -} - -void tricore_cpu_list(void) -{ -GSList *list; - -list = object_class_get_list_sorted(TYPE_TRICORE_CPU, false); -qemu_printf("Available CPUs:\n"); -g_slist_foreach(list, tricore_cpu_list_entry, NULL); -g_slist_free(list); -} - void fpu_set_state(CPUTriCoreState *env) { switch (extract32(env->PSW, 24, 2)) { -- 2.41.0
[PULL 32/71] hw/riscv/shakti_c: Check CPU type in machine_run_board_init()
From: Gavin Shan Set mc->valid_cpu_types so that the user specified CPU type can be validated in machine_run_board_init(). We needn't to do it by ourselves. Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231204004726.483558-10-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/riscv/shakti_c.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c index 12ea74b032..3888034c2b 100644 --- a/hw/riscv/shakti_c.c +++ b/hw/riscv/shakti_c.c @@ -28,7 +28,6 @@ #include "exec/address-spaces.h" #include "hw/riscv/boot.h" - static const struct MemmapEntry { hwaddr base; hwaddr size; @@ -47,12 +46,6 @@ static void shakti_c_machine_state_init(MachineState *mstate) ShaktiCMachineState *sms = RISCV_SHAKTI_MACHINE(mstate); MemoryRegion *system_memory = get_system_memory(); -/* Allow only Shakti C CPU for this platform */ -if (strcmp(mstate->cpu_type, TYPE_RISCV_CPU_SHAKTI_C) != 0) { -error_report("This board can only be used with Shakti C CPU"); -exit(1); -} - /* Initialize SoC */ object_initialize_child(OBJECT(mstate), "soc", &sms->soc, TYPE_RISCV_SHAKTI_SOC); @@ -82,9 +75,15 @@ static void shakti_c_machine_instance_init(Object *obj) static void shakti_c_machine_class_init(ObjectClass *klass, void *data) { MachineClass *mc = MACHINE_CLASS(klass); +static const char * const valid_cpu_types[] = { +RISCV_CPU_TYPE_NAME("shakti-c"), +NULL +}; + mc->desc = "RISC-V Board compatible with Shakti SDK"; mc->init = shakti_c_machine_state_init; mc->default_cpu_type = TYPE_RISCV_CPU_SHAKTI_C; +mc->valid_cpu_types = valid_cpu_types; mc->default_ram_id = "riscv.shakti.c.ram"; } -- 2.41.0
[PULL 19/71] target/sh4: Use generic cpu_list()
From: Gavin Shan Before it's applied: [gshan@gshan q]$ ./build/qemu-system-sh4 -cpu ? sh7750r sh7751r sh7785 After it's applied: [gshan@gshan q]$ ./build/qemu-system-sh4 -cpu ? Available CPUs: sh7750r sh7751r sh7785 Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231114235628.534334-20-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/sh4/cpu.h | 3 --- target/sh4/cpu.c | 17 - 2 files changed, 20 deletions(-) diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 031dc0b457..0e6fa65bae 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -238,7 +238,6 @@ G_NORETURN void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, uintptr_t retaddr); void sh4_translate_init(void); -void sh4_cpu_list(void); #if !defined(CONFIG_USER_ONLY) hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); @@ -272,8 +271,6 @@ void cpu_load_tlb(CPUSH4State * env); #define CPU_RESOLVING_TYPE TYPE_SUPERH_CPU -#define cpu_list sh4_cpu_list - /* MMU modes definitions */ #define MMU_USER_IDX 1 static inline int cpu_mmu_index (CPUSH4State *env, bool ifetch) diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index a8ec98b134..806a0ef875 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -122,23 +122,6 @@ static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) info->print_insn = print_insn_sh; } -static void superh_cpu_list_entry(gpointer data, gpointer user_data) -{ -const char *typename = object_class_get_name(OBJECT_CLASS(data)); -int len = strlen(typename) - strlen(SUPERH_CPU_TYPE_SUFFIX); - -qemu_printf("%.*s\n", len, typename); -} - -void sh4_cpu_list(void) -{ -GSList *list; - -list = object_class_get_list_sorted(TYPE_SUPERH_CPU, false); -g_slist_foreach(list, superh_cpu_list_entry, NULL); -g_slist_free(list); -} - static ObjectClass *superh_cpu_class_by_name(const char *cpu_model) { ObjectClass *oc; -- 2.41.0
[PULL 36/71] hw/cpu/cluster: Cleanup unused included header in cluster.c
From: Zhao Liu Remove unused header (qemu/module.h and qemu/cutils.h) in cluster.c, and reorder the remaining header files (except qemu/osdep.h) in alphabetical order. Tested by "./configure" and then "make". Signed-off-by: Zhao Liu Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231127145611.925817-3-zhao1@linux.intel.com> --- hw/cpu/cluster.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c index e444b7c29d..61289a840d 100644 --- a/hw/cpu/cluster.c +++ b/hw/cpu/cluster.c @@ -19,12 +19,11 @@ */ #include "qemu/osdep.h" + +#include "hw/core/cpu.h" #include "hw/cpu/cluster.h" #include "hw/qdev-properties.h" -#include "hw/core/cpu.h" #include "qapi/error.h" -#include "qemu/module.h" -#include "qemu/cutils.h" static Property cpu_cluster_properties[] = { DEFINE_PROP_UINT32("cluster-id", CPUClusterState, cluster_id, 0), -- 2.41.0
[PULL 05/71] cpu: Add helper cpu_model_from_type()
From: Gavin Shan Add helper cpu_model_from_type() to extract the CPU model name from the CPU type name in two circumstances: (1) The CPU type name is the combination of the CPU model name and suffix. (2) The CPU type name is same to the CPU model name. The helper will be used in the subsequent commits to conver the CPU type name to the CPU model name. Suggested-by: Igor Mammedov Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-ID: <20231114235628.534334-6-gs...@redhat.com> [PMD: Mention returned string must be released with g_free()] Signed-off-by: Philippe Mathieu-Daudé --- include/hw/core/cpu.h | 13 + cpu-target.c | 15 +++ 2 files changed, 28 insertions(+) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index c0c8320413..76ef59de0a 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -779,6 +779,19 @@ void cpu_reset(CPUState *cpu); */ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); +/** + * cpu_model_from_type: + * @typename: The CPU type name + * + * Extract the CPU model name from the CPU type name. The + * CPU type name is either the combination of the CPU model + * name and suffix, or same to the CPU model name. + * + * Returns: CPU model name or NULL if the CPU class doesn't exist + * The user should g_free() the string once no longer needed. + */ +char *cpu_model_from_type(const char *typename); + /** * cpu_create: * @typename: The CPU type. diff --git a/cpu-target.c b/cpu-target.c index 430dc53566..6f4afc1dbc 100644 --- a/cpu-target.c +++ b/cpu-target.c @@ -241,6 +241,21 @@ void cpu_exec_initfn(CPUState *cpu) #endif } +char *cpu_model_from_type(const char *typename) +{ +const char *suffix = "-" CPU_RESOLVING_TYPE; + +if (!object_class_by_name(typename)) { +return NULL; +} + +if (g_str_has_suffix(typename, suffix)) { +return g_strndup(typename, strlen(typename) - strlen(suffix)); +} + +return g_strdup(typename); +} + const char *parse_cpu_option(const char *cpu_option) { ObjectClass *oc; -- 2.41.0
[PULL 30/71] hw/arm/sbsa-ref: Check CPU type in machine_run_board_init()
From: Gavin Shan Set mc->valid_cpu_types so that the user specified CPU type can be validated in machine_run_board_init(). We needn't to do it by ourselves. Signed-off-by: Gavin Shan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Leif Lindholm Reviewed-by: Richard Henderson Message-ID: <20231204004726.483558-8-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/arm/sbsa-ref.c | 36 ++-- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index f3c9704693..477dca0637 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -145,27 +145,6 @@ static const int sbsa_ref_irqmap[] = { [SBSA_GWDT_WS0] = 16, }; -static const char * const valid_cpus[] = { -ARM_CPU_TYPE_NAME("cortex-a57"), -ARM_CPU_TYPE_NAME("cortex-a72"), -ARM_CPU_TYPE_NAME("neoverse-n1"), -ARM_CPU_TYPE_NAME("neoverse-v1"), -ARM_CPU_TYPE_NAME("neoverse-n2"), -ARM_CPU_TYPE_NAME("max"), -}; - -static bool cpu_type_valid(const char *cpu) -{ -int i; - -for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) { -if (strcmp(cpu, valid_cpus[i]) == 0) { -return true; -} -} -return false; -} - static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx) { uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER; @@ -733,11 +712,6 @@ static void sbsa_ref_init(MachineState *machine) const CPUArchIdList *possible_cpus; int n, sbsa_max_cpus; -if (!cpu_type_valid(machine->cpu_type)) { -error_report("sbsa-ref: CPU type %s not supported", machine->cpu_type); -exit(1); -} - if (kvm_enabled()) { error_report("sbsa-ref: KVM is not supported for this machine"); exit(1); @@ -898,10 +872,20 @@ static void sbsa_ref_instance_init(Object *obj) static void sbsa_ref_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); +static const char * const valid_cpu_types[] = { +ARM_CPU_TYPE_NAME("cortex-a57"), +ARM_CPU_TYPE_NAME("cortex-a72"), +ARM_CPU_TYPE_NAME("neoverse-n1"), +ARM_CPU_TYPE_NAME("neoverse-v1"), +ARM_CPU_TYPE_NAME("neoverse-n2"), +ARM_CPU_TYPE_NAME("max"), +NULL, +}; mc->init = sbsa_ref_init; mc->desc = "QEMU 'SBSA Reference' ARM Virtual Machine"; mc->default_cpu_type = ARM_CPU_TYPE_NAME("neoverse-n1"); +mc->valid_cpu_types = valid_cpu_types; mc->max_cpus = 512; mc->pci_allow_0_address = true; mc->minimum_page_bits = 12; -- 2.41.0
[PULL 31/71] hw/arm: Check CPU type in machine_run_board_init()
From: Gavin Shan Set mc->valid_cpu_types so that the user specified CPU type can be validated in machine_run_board_init(). We needn't to do it by ourselves. Signed-off-by: Gavin Shan Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20231204004726.483558-9-gs...@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/arm/bananapi_m2u.c | 12 ++-- hw/arm/cubieboard.c | 12 ++-- hw/arm/mps2-tz.c| 26 -- hw/arm/mps2.c | 26 -- hw/arm/msf2-som.c | 12 ++-- hw/arm/musca.c | 12 +--- hw/arm/npcm7xx_boards.c | 12 +--- hw/arm/orangepi.c | 12 ++-- 8 files changed, 74 insertions(+), 50 deletions(-) diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c index 8f24b18d8c..0a4b6f29b1 100644 --- a/hw/arm/bananapi_m2u.c +++ b/hw/arm/bananapi_m2u.c @@ -71,12 +71,6 @@ static void bpim2u_init(MachineState *machine) exit(1); } -/* Only allow Cortex-A7 for this board */ -if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a7")) != 0) { -error_report("This board can only be used with cortex-a7 CPU"); -exit(1); -} - r40 = AW_R40(object_new(TYPE_AW_R40)); object_property_add_child(OBJECT(machine), "soc", OBJECT(r40)); object_unref(OBJECT(r40)); @@ -133,12 +127,18 @@ static void bpim2u_init(MachineState *machine) static void bpim2u_machine_init(MachineClass *mc) { +static const char * const valid_cpu_types[] = { +ARM_CPU_TYPE_NAME("cortex-a7"), +NULL +}; + mc->desc = "Bananapi M2U (Cortex-A7)"; mc->init = bpim2u_init; mc->min_cpus = AW_R40_NUM_CPUS; mc->max_cpus = AW_R40_NUM_CPUS; mc->default_cpus = AW_R40_NUM_CPUS; mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a7"); +mc->valid_cpu_types = valid_cpu_types; mc->default_ram_size = 1 * GiB; mc->default_ram_id = "bpim2u.ram"; } diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index 29146f5018..b976727eef 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -52,12 +52,6 @@ static void cubieboard_init(MachineState *machine) exit(1); } -/* Only allow Cortex-A8 for this board */ -if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a8")) != 0) { -error_report("This board can only be used with cortex-a8 CPU"); -exit(1); -} - a10 = AW_A10(object_new(TYPE_AW_A10)); object_property_add_child(OBJECT(machine), "soc", OBJECT(a10)); object_unref(OBJECT(a10)); @@ -114,8 +108,14 @@ static void cubieboard_init(MachineState *machine) static void cubieboard_machine_init(MachineClass *mc) { +static const char * const valid_cpu_types[] = { +ARM_CPU_TYPE_NAME("cortex-a8"), +NULL +}; + mc->desc = "cubietech cubieboard (Cortex-A8)"; mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8"); +mc->valid_cpu_types = valid_cpu_types; mc->default_ram_size = 1 * GiB; mc->init = cubieboard_init; mc->block_default_type = IF_IDE; diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index 668db5ed61..5d8cdc1a4c 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -813,12 +813,6 @@ static void mps2tz_common_init(MachineState *machine) int num_ppcs; int i; -if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) { -error_report("This board can only be used with CPU %s", - mc->default_cpu_type); -exit(1); -} - if (machine->ram_size != mc->default_ram_size) { char *sz = size_to_str(mc->default_ram_size); error_report("Invalid RAM size, should be %s", sz); @@ -1318,6 +1312,10 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc); +static const char * const valid_cpu_types[] = { +ARM_CPU_TYPE_NAME("cortex-m33"), +NULL +}; mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33"; mc->default_cpus = 1; @@ -1325,6 +1323,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data) mc->max_cpus = mc->default_cpus; mmc->fpga_type = FPGA_AN505; mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"); +mc->valid_cpu_types = valid_cpu_types; mmc->scc_id = 0x41045050; mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */ mmc->apb_periph_frq = mmc->sysclk_frq; @@ -1347,6 +1346,10 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc); +static const char * const valid_cpu_types[] = { +ARM_CPU_TYPE_NAME("cortex-m33"), +NULL +}; mc->desc = "ARM MPS2 with AN521 FPGA image for dual Cortex-M33"; mc->default_cpus = 2; @@ -1354,6 +1357,7 @@ static void mps2tz_an521_class_init(
[PULL 53/71] memory: Have memory_region_init_rom_device() handler return a boolean
Following the example documented since commit e3fe3988d7 ("error: Document Error API usage rules"), have memory_region_init_rom_device return a boolean indicating whether an error is set or not. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Peter Xu Reviewed-by: Gavin Shan Message-Id: <20231120213301.24349-11-phi...@linaro.org> --- include/exec/memory.h | 4 +++- system/memory.c | 6 -- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index 6d7b49b735..6209458f56 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1646,8 +1646,10 @@ bool memory_region_init_rom(MemoryRegion *mr, *must be unique within any device * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_rom_device(MemoryRegion *mr, +bool memory_region_init_rom_device(MemoryRegion *mr, Object *owner, const MemoryRegionOps *ops, void *opaque, diff --git a/system/memory.c b/system/memory.c index c6562f5e86..e5193d4623 100644 --- a/system/memory.c +++ b/system/memory.c @@ -3618,7 +3618,7 @@ bool memory_region_init_rom(MemoryRegion *mr, return true; } -void memory_region_init_rom_device(MemoryRegion *mr, +bool memory_region_init_rom_device(MemoryRegion *mr, Object *owner, const MemoryRegionOps *ops, void *opaque, @@ -3630,7 +3630,7 @@ void memory_region_init_rom_device(MemoryRegion *mr, if (!memory_region_init_rom_device_nomigrate(mr, owner, ops, opaque, name, size, errp)) { -return; +return false; } /* This will assert if owner is neither NULL nor a DeviceState. * We only want the owner here for the purposes of defining a @@ -3640,6 +3640,8 @@ void memory_region_init_rom_device(MemoryRegion *mr, */ owner_dev = DEVICE(owner); vmstate_register_ram(mr, owner_dev); + +return true; } /* -- 2.41.0
[PULL 46/71] memory: Have memory_region_init_rom_nomigrate() handler return a boolean
Following the example documented since commit e3fe3988d7 ("error: Document Error API usage rules"), have memory_region_init_rom_nomigrate return a boolean indicating whether an error is set or not. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Peter Xu Reviewed-by: Gavin Shan Message-Id: <20231120213301.24349-4-phi...@linaro.org> [PMD: Only update 'readonly' field on success (Manos Pitsidianakis)] Message-Id: --- include/exec/memory.h | 4 +++- system/memory.c | 9 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index 413fbda089..f3a4a76817 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1498,8 +1498,10 @@ void memory_region_init_alias(MemoryRegion *mr, *must be unique within any device * @size: size of the region. * @errp: pointer to Error*, to store an error if it happens. + * + * Return: true on success, else false setting @errp with error. */ -void memory_region_init_rom_nomigrate(MemoryRegion *mr, +bool memory_region_init_rom_nomigrate(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, diff --git a/system/memory.c b/system/memory.c index f9e5ae22d5..72c6441e20 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1701,14 +1701,19 @@ void memory_region_init_alias(MemoryRegion *mr, mr->alias_offset = offset; } -void memory_region_init_rom_nomigrate(MemoryRegion *mr, +bool memory_region_init_rom_nomigrate(MemoryRegion *mr, Object *owner, const char *name, uint64_t size, Error **errp) { -memory_region_init_ram_flags_nomigrate(mr, owner, name, size, 0, errp); +if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, +size, 0, errp)) { + return false; +} mr->readonly = true; + +return true; } void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, -- 2.41.0
[PULL 37/71] hw/audio/sb16: Do not migrate qdev properties
Since commit f7b4f61f63 ("qdev/isa: convert soundblaster") these fields have been converted to qdev properties, so don't need to be migrated: static Property sb16_properties[] = { DEFINE_AUDIO_PROPERTIES(SB16State, card), DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */ DEFINE_PROP_UINT32 ("iobase", SB16State, port, 0x220), DEFINE_PROP_UINT32 ("irq", SB16State, irq, 5), DEFINE_PROP_UINT32 ("dma", SB16State, dma, 1), DEFINE_PROP_UINT32 ("dma16", SB16State, hdma, 5), DEFINE_PROP_END_OF_LIST (), }; Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Fabiano Rosas Message-Id: <20231124182615.94943-1-phi...@linaro.org> --- hw/audio/sb16.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index bf7f35a42b..fd76e78d18 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -1325,11 +1325,11 @@ static const VMStateDescription vmstate_sb16 = { .minimum_version_id = 1, .post_load = sb16_post_load, .fields = (const VMStateField[]) { -VMSTATE_UINT32 (irq, SB16State), -VMSTATE_UINT32 (dma, SB16State), -VMSTATE_UINT32 (hdma, SB16State), -VMSTATE_UINT32 (port, SB16State), -VMSTATE_UINT32 (ver, SB16State), +VMSTATE_UNUSED( 4 /* irq */ + + 4 /* dma */ + + 4 /* hdma */ + + 4 /* port */ + + 4 /* ver */), VMSTATE_INT32 (in_index, SB16State), VMSTATE_INT32 (out_data_len, SB16State), VMSTATE_INT32 (fmt_stereo, SB16State), -- 2.41.0
[PULL 34/71] hw/core/cpu: Update description of CPUState::node
'next_cpu' was converted to 'node' in commit bdc44640cb ("cpu: Use QTAILQ for CPU list"). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20231129183243.15859-1-phi...@linaro.org> --- include/hw/core/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 44ff954207..238c02c05e 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -430,7 +430,7 @@ struct qemu_work_item; * @gdb_regs: Additional GDB registers. * @gdb_num_regs: Number of total registers accessible to GDB. * @gdb_num_g_regs: Number of registers in GDB 'g' packets. - * @next_cpu: Next CPU sharing TB cache. + * @node: QTAILQ of CPUs sharing TB cache. * @opaque: User data. * @mem_io_pc: Host Program Counter at which the memory was accessed. * @accel: Pointer to accelerator specific state. -- 2.41.0
[PULL 40/71] hw/ppc/spapr_cpu_core: Access QDev properties with proper API
CPUState::start_powered_off field is part of the internal implementation of a QDev CPU. It is exposed as the QDev "start-powered-off" property. External components should use the qdev properties API to access it. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-Id: <20231123143813.42632-2-phi...@linaro.org> --- hw/ppc/spapr_cpu_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 710078e9f7..5aa1ed474a 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -306,7 +306,7 @@ static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp) * All CPUs start halted. CPU0 is unhalted from the machine level reset code * and the rest are explicitly started up by the guest using an RTAS call. */ -cs->start_powered_off = true; +qdev_prop_set_bit(DEVICE(obj), "start-powered-off", true); cs->cpu_index = cc->core_id + i; if (!spapr_set_vcpu_id(cpu, cs->cpu_index, errp)) { return NULL; -- 2.41.0