[PATCH v4 8/9] target/loongarch: Implement set vcpu intr for kvm

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Tianrui Zhao
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

2024-01-05 Thread Zhao Liu
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

2024-01-05 Thread Sia Jee Heng
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

2024-01-05 Thread Sia Jee Heng
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

2024-01-05 Thread Sia Jee Heng
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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Marc-André Lureau
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

2024-01-05 Thread Philippe Mathieu-Daudé

(+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

2024-01-05 Thread Helge Deller

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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Daniel P . Berrangé
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
... 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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Helge Deller

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

2024-01-05 Thread Frédéric Pétrot

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

2024-01-05 Thread Marc-André Lureau
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()

2024-01-05 Thread Marc-André Lureau
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

2024-01-05 Thread Philippe Mathieu-Daudé

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()

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Marc-André Lureau
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

2024-01-05 Thread Alex Bennée
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()

2024-01-05 Thread Marc-André Lureau
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()

2024-01-05 Thread Marc-André Lureau
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

2024-01-05 Thread Daniel Henrique Barboza




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

2024-01-05 Thread Daniel Henrique Barboza




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

2024-01-05 Thread Peter Maydell
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Alex Bennée
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

2024-01-05 Thread Peter Maydell
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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread 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

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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Gerd Hoffmann
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()

2024-01-05 Thread Gerd Hoffmann
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

2024-01-05 Thread Gerd Hoffmann
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

2024-01-05 Thread Philippe Mathieu-Daudé

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()

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Peter Maydell
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread Fiona Ebner
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

2024-01-05 Thread Clément Chigot
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

2024-01-05 Thread Philippe Mathieu-Daudé

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

2024-01-05 Thread ????
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

2024-01-05 Thread ????
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

2024-01-05 Thread Fabien Chouteau
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

2024-01-05 Thread Peter Maydell
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

2024-01-05 Thread Philippe Mathieu-Daudé

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()

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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/

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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()

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
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

2024-01-05 Thread Philippe Mathieu-Daudé
'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

2024-01-05 Thread Philippe Mathieu-Daudé
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




  1   2   3   >