[PATCH v2 1/4] sysemu/kvm: Restrict kvmppc_get_radix_page_info() to ppc targets

2023-10-03 Thread Philippe Mathieu-Daudé
kvm_get_radix_page_info() is only defined for ppc targets (in
target/ppc/kvm.c). The declaration is not useful in other targets,
reduce its scope.
Rename using the 'kvmppc_' prefix following other declarations
from target/ppc/kvm_ppc.h.

Suggested-by: Michael Tokarev 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/sysemu/kvm.h | 1 -
 target/ppc/kvm.c | 4 ++--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index ee9025f8e9..3bcd8f45be 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -551,7 +551,6 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void 
*source);
  * Returns: 0 on success, or a negative errno on failure.
  */
 int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
-struct ppc_radix_page_info *kvm_get_radix_page_info(void);
 int kvm_get_max_memslots(void);
 
 /* Notify resamplefd for EOI of specific interrupts. */
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 51112bd367..19fe6d2d00 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -268,7 +268,7 @@ static void kvm_get_smmu_info(struct kvm_ppc_smmu_info 
*info, Error **errp)
  "KVM failed to provide the MMU features it supports");
 }
 
-struct ppc_radix_page_info *kvm_get_radix_page_info(void)
+static struct ppc_radix_page_info *kvmppc_get_radix_page_info(void)
 {
 KVMState *s = KVM_STATE(current_accel());
 struct ppc_radix_page_info *radix_page_info;
@@ -2372,7 +2372,7 @@ static void kvmppc_host_cpu_class_init(ObjectClass *oc, 
void *data)
 }
 
 #if defined(TARGET_PPC64)
-pcc->radix_page_info = kvm_get_radix_page_info();
+pcc->radix_page_info = kvmppc_get_radix_page_info();
 
 if ((pcc->pvr & 0xff00) == CPU_POWERPC_POWER9_DD1) {
 /*
-- 
2.41.0




[PATCH v2 2/4] hw/ppc/e500: Restrict ppce500_init_mpic_kvm() to KVM

2023-10-03 Thread Philippe Mathieu-Daudé
Inline and guard the single call to kvm_openpic_connect_vcpu()
allows to remove kvm-stub.c.

Reviewed-by: Michael Tokarev 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ppc/e500.c  |  4 
 target/ppc/kvm-stub.c  | 19 ---
 target/ppc/meson.build |  2 +-
 3 files changed, 5 insertions(+), 20 deletions(-)
 delete mode 100644 target/ppc/kvm-stub.c

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index d5b6820d1d..d0e199fb2c 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -834,6 +834,7 @@ static DeviceState 
*ppce500_init_mpic_qemu(PPCE500MachineState *pms,
 static DeviceState *ppce500_init_mpic_kvm(const PPCE500MachineClass *pmc,
   IrqLines *irqs, Error **errp)
 {
+#ifdef CONFIG_KVM
 DeviceState *dev;
 CPUState *cs;
 
@@ -854,6 +855,9 @@ static DeviceState *ppce500_init_mpic_kvm(const 
PPCE500MachineClass *pmc,
 }
 
 return dev;
+#else
+g_assert_not_reached();
+#endif
 }
 
 static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms,
diff --git a/target/ppc/kvm-stub.c b/target/ppc/kvm-stub.c
deleted file mode 100644
index b98e1d404f..00
--- a/target/ppc/kvm-stub.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * QEMU KVM PPC specific function stubs
- *
- * Copyright Freescale Inc. 2013
- *
- * Author: Alexander Graf 
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "hw/ppc/openpic_kvm.h"
-
-int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
-{
-return -EINVAL;
-}
diff --git a/target/ppc/meson.build b/target/ppc/meson.build
index 4c2635039e..0bff3e39e5 100644
--- a/target/ppc/meson.build
+++ b/target/ppc/meson.build
@@ -30,7 +30,7 @@ gen = [
 ]
 ppc_ss.add(when: 'CONFIG_TCG', if_true: gen)
 
-ppc_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: 
files('kvm-stub.c'))
+ppc_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
 ppc_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user_only_helper.c'))
 
 ppc_system_ss = ss.source_set()
-- 
2.41.0




[PATCH v2 4/4] target/ppc: Prohibit target specific KVM prototypes on user emulation

2023-10-03 Thread Philippe Mathieu-Daudé
None of these target-specific prototypes should be used
by user emulation. Remove their declaration there, so we
get a compile failure if ever used (instead of having to
deal with linker and its possible optimizations, such
dead code removal).

Suggested-by: Kevin Wolf 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel Henrique Barboza 
---
 target/ppc/kvm_ppc.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 6a4dd9c560..1975fb5ee6 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -13,6 +13,10 @@
 #include "exec/hwaddr.h"
 #include "cpu.h"
 
+#ifdef CONFIG_USER_ONLY
+#error Cannot include kvm_ppc.h from user emulation
+#endif
+
 #ifdef CONFIG_KVM
 
 uint32_t kvmppc_get_tbfreq(void);
-- 
2.41.0




[PATCH v2 3/4] target/ppc: Restrict KVM objects to system emulation

2023-10-03 Thread Philippe Mathieu-Daudé
CONFIG_KVM is always FALSE on user emulation, so 'kvm.c'
won't be added to ppc_ss[] source set; direcly use the system
specific ppc_system_ss[] source set.

Reviewed-by: Michael Tokarev 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/ppc/meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/meson.build b/target/ppc/meson.build
index 0bff3e39e5..44462f95cd 100644
--- a/target/ppc/meson.build
+++ b/target/ppc/meson.build
@@ -30,7 +30,6 @@ gen = [
 ]
 ppc_ss.add(when: 'CONFIG_TCG', if_true: gen)
 
-ppc_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
 ppc_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user_only_helper.c'))
 
 ppc_system_ss = ss.source_set()
@@ -46,6 +45,7 @@ ppc_system_ss.add(when: 'CONFIG_TCG', if_true: files(
 ), if_false: files(
   'tcg-stub.c',
 ))
+ppc_system_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
 
 ppc_system_ss.add(when: 'TARGET_PPC64', if_true: files(
   'compat.c',
-- 
2.41.0




[PATCH v2 0/4] target/ppc: Prohibit target specific KVM prototypes on user emulation

2023-10-03 Thread Philippe Mathieu-Daudé
Since v1:
- Addressed Michael review comments,
- Added Daniel R-b tag.

Implement Kevin's suggestion to remove KVM declarations
for user emulation builds, so if KVM prototype are used
we directly get a compile failure.

Philippe Mathieu-Daudé (4):
  sysemu/kvm: Restrict kvmppc_get_radix_page_info() to ppc targets
  hw/ppc/e500: Restrict ppce500_init_mpic_kvm() to KVM
  target/ppc: Restrict KVM objects to system emulation
  target/ppc: Prohibit target specific KVM prototypes on user emulation

 include/sysemu/kvm.h   |  1 -
 target/ppc/kvm_ppc.h   |  4 
 hw/ppc/e500.c  |  4 
 target/ppc/kvm-stub.c  | 19 ---
 target/ppc/kvm.c   |  4 ++--
 target/ppc/meson.build |  2 +-
 6 files changed, 11 insertions(+), 23 deletions(-)
 delete mode 100644 target/ppc/kvm-stub.c

-- 
2.41.0




Re: [PATCH 0/2] hw/intc/apic: QOM cleanup

2023-10-03 Thread Philippe Mathieu-Daudé

On 3/10/23 08:45, Philippe Mathieu-Daudé wrote:

On 15/9/23 18:20, Philippe Mathieu-Daudé wrote:

Minor cleanup extracted from a bigger series
touching x86_cpu_realizefn().

Philippe Mathieu-Daudé (2):
   target/i386: Only realize existing APIC device
   hw/intc/apic: Pass CPU using QOM link property


Ping?


Oops I didn't noticed I sent these patches by mistake
in another series, and Richard already reviewed them
(with comment to address):
https://lore.kernel.org/qemu-devel/a6d0175f-a343-4b1f-232f-280786e7d...@linaro.org/



[PATCH v4 1/5] softmmu: add means to pass an exit code when requesting a shutdown

2023-10-03 Thread Clément Chigot
As of now, the exit code was either EXIT_FAILURE when a panic shutdown
was requested or EXIT_SUCCESS otherwise.
However, some hardware could want to pass more complex exit codes. Thus,
introduce a new shutdown request function allowing that.

Signed-off-by: Clément Chigot 
Reviewed-by: Alistair Francis 
---
 include/sysemu/runstate.h |  2 ++
 softmmu/runstate.c| 12 +++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
index 08afb97695..c8c2bd8a61 100644
--- a/include/sysemu/runstate.h
+++ b/include/sysemu/runstate.h
@@ -68,6 +68,8 @@ void qemu_system_wakeup_request(WakeupReason reason, Error 
**errp);
 void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
 void qemu_register_wakeup_notifier(Notifier *notifier);
 void qemu_register_wakeup_support(void);
+void qemu_system_shutdown_request_with_code(ShutdownCause reason,
+int exit_code);
 void qemu_system_shutdown_request(ShutdownCause reason);
 void qemu_system_powerdown_request(void);
 void qemu_register_powerdown_notifier(Notifier *notifier);
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index 1652ed0439..363a5ea8dd 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -385,6 +385,7 @@ void vm_state_notify(bool running, RunState state)
 
 static ShutdownCause reset_requested;
 static ShutdownCause shutdown_requested;
+static int shutdown_exit_code = EXIT_SUCCESS;
 static int shutdown_signal;
 static pid_t shutdown_pid;
 static int powerdown_requested;
@@ -664,6 +665,13 @@ void qemu_system_killed(int signal, pid_t pid)
 qemu_notify_event();
 }
 
+void qemu_system_shutdown_request_with_code(ShutdownCause reason,
+int exit_code)
+{
+shutdown_exit_code = exit_code;
+qemu_system_shutdown_request(reason);
+}
+
 void qemu_system_shutdown_request(ShutdownCause reason)
 {
 trace_qemu_system_shutdown_request(reason);
@@ -725,7 +733,9 @@ static bool main_loop_should_exit(int *status)
 if (shutdown_action == SHUTDOWN_ACTION_PAUSE) {
 vm_stop(RUN_STATE_SHUTDOWN);
 } else {
-if (request == SHUTDOWN_CAUSE_GUEST_PANIC &&
+if (shutdown_exit_code != EXIT_SUCCESS) {
+*status = shutdown_exit_code;
+} else if (request == SHUTDOWN_CAUSE_GUEST_PANIC &&
 panic_action == PANIC_ACTION_EXIT_FAILURE) {
 *status = EXIT_FAILURE;
 }
-- 
2.25.1




[PATCH v4 4/5] hw/char: riscv_htif: replace exit calls with proper shutdown

2023-10-03 Thread Clément Chigot
This replaces the exit calls by shutdown requests, ensuring a proper
cleanup of Qemu. Otherwise, some connections like gdb could be broken
before its final packet ("Wxx") is being sent. This part, being done
inside qemu_cleanup function, can be reached only when the main loop
exits after a shutdown request.

Signed-off-by: Clément Chigot 
Reviewed-by: Alistair Francis 
---
 hw/char/riscv_htif.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
index 40de6b8b77..9bef60def1 100644
--- a/hw/char/riscv_htif.c
+++ b/hw/char/riscv_htif.c
@@ -32,6 +32,7 @@
 #include "exec/address-spaces.h"
 #include "exec/tswap.h"
 #include "sysemu/dma.h"
+#include "sysemu/runstate.h"
 
 #define RISCV_DEBUG_HTIF 0
 #define HTIF_DEBUG(fmt, ...)   
\
@@ -206,7 +207,9 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t 
val_written)
 g_free(sig_data);
 }
 
-exit(exit_code);
+qemu_system_shutdown_request_with_code(
+SHUTDOWN_CAUSE_GUEST_SHUTDOWN, exit_code);
+return;
 } else {
 uint64_t syscall[8];
 cpu_physical_memory_read(payload, syscall, sizeof(syscall));
-- 
2.25.1




[PATCH v4 3/5] hw/misc/sifive_test.c: replace exit calls with proper shutdown

2023-10-03 Thread Clément Chigot
This replaces the exit calls by shutdown requests, ensuring a proper
cleanup of Qemu. Otherwise, some connections like gdb could be broken
before its final packet ("Wxx") is being sent. This part, being done
inside qemu_cleanup function, can be reached only when the main loop
exits after a shutdown request.

Signed-off-by: Clément Chigot 
Reviewed-by: Alistair Francis 
---
 hw/misc/sifive_test.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/misc/sifive_test.c b/hw/misc/sifive_test.c
index 56df45bfe5..ad688079c4 100644
--- a/hw/misc/sifive_test.c
+++ b/hw/misc/sifive_test.c
@@ -25,6 +25,7 @@
 #include "qemu/module.h"
 #include "sysemu/runstate.h"
 #include "hw/misc/sifive_test.h"
+#include "sysemu/sysemu.h"
 
 static uint64_t sifive_test_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -39,9 +40,13 @@ static void sifive_test_write(void *opaque, hwaddr addr,
 int code = (val64 >> 16) & 0x;
 switch (status) {
 case FINISHER_FAIL:
-exit(code);
+qemu_system_shutdown_request_with_code(
+SHUTDOWN_CAUSE_GUEST_PANIC, code);
+return;
 case FINISHER_PASS:
-exit(0);
+qemu_system_shutdown_request_with_code(
+SHUTDOWN_CAUSE_GUEST_SHUTDOWN, code);
+return;
 case FINISHER_RESET:
 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 return;
-- 
2.25.1




[PATCH v4 5/5] gdbstub: replace exit calls with proper shutdown for softmmu

2023-10-03 Thread Clément Chigot
This replaces the exit calls by shutdown requests, ensuring a proper
cleanup of Qemu. Features like net/vhost-vdpa.c are expecting
qemu_cleanup to be called to remove their last residuals.

Signed-off-by: Clément Chigot 
Reviewed-by: Alistair Francis 
---
 gdbstub/gdbstub.c  | 5 +++--
 gdbstub/softmmu.c  | 6 ++
 gdbstub/user.c | 6 ++
 include/gdbstub/syscalls.h | 9 +
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 349d348c7b..1cb6d65306 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -1327,7 +1327,7 @@ static void handle_v_kill(GArray *params, void *user_ctx)
 gdb_put_packet("OK");
 error_report("QEMU: Terminated via GDBstub");
 gdb_exit(0);
-exit(0);
+gdb_qemu_exit(0);
 }
 
 static const GdbCmdParseEntry gdb_v_commands_table[] = {
@@ -1846,7 +1846,8 @@ static int gdb_handle_packet(const char *line_buf)
 /* Kill the target */
 error_report("QEMU: Terminated via GDBstub");
 gdb_exit(0);
-exit(0);
+gdb_qemu_exit(0);
+break;
 case 'D':
 {
 static const GdbCmdParseEntry detach_cmd_desc = {
diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index 9f0b8b5497..a5d6e04c79 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -435,6 +435,12 @@ void gdb_exit(int code)
 qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
 }
 
+void gdb_qemu_exit(int code)
+{
+qemu_system_shutdown_request_with_code(SHUTDOWN_CAUSE_GUEST_SHUTDOWN,
+   code);
+}
+
 /*
  * Memory access
  */
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 7ab6e5d975..dbe1d9b887 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -113,6 +113,12 @@ void gdb_exit(int code)
 gdb_put_packet(buf);
 gdbserver_state.allow_stop_reply = false;
 }
+
+}
+
+void gdb_qemu_exit(int code)
+{
+exit(code);
 }
 
 int gdb_handlesig(CPUState *cpu, int sig)
diff --git a/include/gdbstub/syscalls.h b/include/gdbstub/syscalls.h
index 243eaf8ce4..54ff7245a1 100644
--- a/include/gdbstub/syscalls.h
+++ b/include/gdbstub/syscalls.h
@@ -110,4 +110,13 @@ int use_gdb_syscalls(void);
  */
 void gdb_exit(int code);
 
+/**
+ * gdb_qemu_exit: ask qemu to exit
+ * @code: exit code reported
+ *
+ * This requests qemu to exit. This function is allowed to return as
+ * the exit request might be processed asynchronously by qemu backend.
+ */
+void gdb_qemu_exit(int code);
+
 #endif /* _SYSCALLS_H_ */
-- 
2.25.1




[PATCH v4 0/5] Risc-V/gdb: replace exit calls with proper shutdown

2023-10-03 Thread Clément Chigot
This series replaces some of the call to exit in hardware used by
Risc-V boards. Otherwise, the gdb connection can be abruptly
disconnected resulting in the last gdb packet "Wxx" being not sent.

For the gdbstub modification, gdb_exit calls ensure that the "Wxx"
packet is sent before exiting. However, some features (see
net/vhost-vdpa.c: vhost_vdpa_cleanup for example) are expecting
that a cleanup is being made before exiting. This, it's probably
safer to follow the same logic here as well.

Difference with v3:
 - Rebase on riscv-to-apply

Clément Chigot (5):
  softmmu: add means to pass an exit code when requesting a shutdown
  softmmu: pass the main loop status to gdb "Wxx" packet
  hw/misc/sifive_test.c: replace exit calls with proper shutdown
  hw/char: riscv_htif: replace exit calls with proper shutdown
  gdbstub: replace exit calls with proper shutdown for softmmu

 gdbstub/gdbstub.c  |  5 +++--
 gdbstub/softmmu.c  |  6 ++
 gdbstub/user.c |  6 ++
 hw/char/riscv_htif.c   |  5 -
 hw/misc/sifive_test.c  |  9 +++--
 include/gdbstub/syscalls.h |  9 +
 include/sysemu/runstate.h  |  2 ++
 include/sysemu/sysemu.h|  2 +-
 softmmu/main.c |  2 +-
 softmmu/runstate.c | 16 +---
 10 files changed, 52 insertions(+), 10 deletions(-)

-- 
2.25.1




[PATCH v4 2/5] softmmu: pass the main loop status to gdb "Wxx" packet

2023-10-03 Thread Clément Chigot
gdb_exit function aims to close gdb sessions and sends the exit code of
the current execution. It's being called by qemu_cleanup once the main
loop is over.
Until now, the exit code sent was always 0. Now that hardware can
shutdown this main loop with custom exit codes, these codes must be
transfered to gdb as well.

Signed-off-by: Clément Chigot 
Reviewed-by: Alistair Francis 
---
 include/sysemu/sysemu.h | 2 +-
 softmmu/main.c  | 2 +-
 softmmu/runstate.c  | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 25be2a692e..73a37949c2 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -101,7 +101,7 @@ bool defaults_enabled(void);
 
 void qemu_init(int argc, char **argv);
 int qemu_main_loop(void);
-void qemu_cleanup(void);
+void qemu_cleanup(int);
 
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
diff --git a/softmmu/main.c b/softmmu/main.c
index 694388bd7f..9b91d21ea8 100644
--- a/softmmu/main.c
+++ b/softmmu/main.c
@@ -35,7 +35,7 @@ int qemu_default_main(void)
 int status;
 
 status = qemu_main_loop();
-qemu_cleanup();
+qemu_cleanup(status);
 
 return status;
 }
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index 363a5ea8dd..ea9d6c2a32 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -834,9 +834,9 @@ void qemu_init_subsystems(void)
 }
 
 
-void qemu_cleanup(void)
+void qemu_cleanup(int status)
 {
-gdb_exit(0);
+gdb_exit(status);
 
 /*
  * cleaning up the migration object cancels any existing migration
-- 
2.25.1




Re: [PATCH 1/2] blockdev: qmp_transaction: harden transaction properties for bitmaps

2023-10-03 Thread Vladimir Sementsov-Ogievskiy

On 19.09.23 13:02, Andrey Zhadchenko wrote:

Hi!

Thanks for the review

On 9/12/23 21:29, Vladimir Sementsov-Ogievskiy wrote:

On 04.09.23 11:31, Andrey Zhadchenko wrote:

Unlike other transaction commands, bitmap operations do not drain target
bds. If we have an IOThread, this may result in some inconsistencies, as
bitmap content may change during transaction command.
Add bdrv_drained_begin()/end() to bitmap operations.

Signed-off-by: Andrey Zhadchenko


Hi!

First, please always include cover letter when more than 1 patch.

Next. Hmm. Good idea, but I'm afraid that's still not enough.

Assume you have two BSs A and B in two different iothreads. So, the sequence 
may be like this:

1. drain_begin A

2. do operation with bitmap in A

3. guest writes to B, B is modified and bitmap in B is modified as well

4. drain_begin B

5. do operation with bitmap in B

6. drain_end B

7. drain_end A

User may expect, that all the operations are done atomically in relation to any 
guest IO operations. And if operations are dependent, the intermediate write 
[3] make break the result.


I see your point, but can the difference really be observed in this case? It is 
probably only relevant if user can copy/merge bitmaps between block nodes (as 
far as I know this is not the case for now)


User can (see qmp block-dirty-bitmap-merge). Also consider, for example, 
starting several backups of all disks, which are in different iothreads. The 
whole backup should be consistent and should correspond to one point of time, 
so all backup jobs should be started inside one drained_all section.





So, we should drain all participant drives during the whole transactions. The 
simplest solution is bdrv_drain_all_begin() / bdrv_drain_all_end() pair in 
qmp_transaction(), could we start with it?



That would definitely get rig of all problems, but I do not really like the 
idea of draining unrelated nodes.

What do you think if I add a new function prototype to the 
TransactionActionDrv, which will return transaction bds? Then we can get a list 
of all bds and lock them before prepairing and clean afterwards.


that looks not generic.. Transaction API is not part of block layer, and I'd 
better not change this. And you add it into TransactionActionDrv, but you'll 
use it in blockdev.c? You'll have to add somethink like transaction_action() 
with big switch-case operation. And than no reason to add something to 
TransactionActionDrv, as that may be just function defined in blockdev.c

--
Best regards,
Vladimir




Re: [PATCH v2 4/5] ramfb: make migration conditional

2023-10-03 Thread Cédric Le Goater

On 10/2/23 22:38, Alex Williamson wrote:

On Mon, 2 Oct 2023 21:41:55 +0200
Laszlo Ersek  wrote:


On 10/2/23 21:26, Alex Williamson wrote:

On Mon, 2 Oct 2023 20:24:11 +0200
Laszlo Ersek  wrote:
   

On 10/2/23 16:41, Alex Williamson wrote:

On Mon, 2 Oct 2023 15:38:10 +0200
Cédric Le Goater  wrote:
 

On 10/2/23 13:11, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

RAMFB migration was unsupported until now, let's make it conditional.
The following patch will prevent machines <= 8.1 to migrate it.

Signed-off-by: Marc-André Lureau 

Maybe localize the new 'ramfb_migrate' attribute close to 'enable_ramfb'
in VFIOPCIDevice. Anyhow,


Shouldn't this actually be tied to whether the device is migratable
(which for GVT-g - the only ramfb user afaik - it's not)?  What does it
mean to have a ramfb-migrate=true property on a device that doesn't
support migration, or false on a device that does support migration.  I
don't understand why this is a user controllable property.  Thanks,


The comments in 
(which are unfortunately not public :/ ) suggest that ramfb migration
was simply forgotten when vGPU migration was implemented. So, "now
that vGPU migration is done", this should be added.

Comment 8 suggests that the following domain XML snippet

  
 
   
   


is migratable, but the ramfb device malfunctions on the destination
host.

There's also a huge QEMU cmdline in comment#0 of the bug; I've not
tried to read that.

AIUI BTW the property is not for the user to control, it's just a
compat knob for versioned machine types. AIUI those are usually
implemented with such (user-visible / -tweakable) device properties.


If it's not for user control it's unfortunate that we expose it to the
user at all, but should it at least use the "x-" prefix to indicate that
it's not intended to be an API?


I *think* it was your commit db32d0f43839 ("vfio/pci: Add option to
disable GeForce quirks", 2018-02-06) that hda introduced me to the "x-"
prefixed properties!

For some reason though, machine type compat knobs are never named like
that, AFAIR.


Maybe I'm misunderstanding your comment, but it appears quite common to
use "x-" prefix things in the compat tables...

GlobalProperty hw_compat_8_0[] = {
 { "migration", "multifd-flush-after-each-section", "on"},
 { TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
 { TYPE_VIRTIO_NET, "host_uso", "off"},
 { TYPE_VIRTIO_NET, "guest_uso4", "off"},
 { TYPE_VIRTIO_NET, "guest_uso6", "off"},
};
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);

GlobalProperty hw_compat_7_2[] = {
 { "e1000e", "migrate-timadj", "off" },
 { "virtio-mem", "x-early-migration", "false" },
 { "migration", "x-preempt-pre-7-2", "true" },
 { TYPE_PCI_DEVICE, "x-pcie-err-unc-mask", "off" },
};
const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
[etc]


It's still odd to think that we can
have scenarios of a non-migratable vfio device registering a migratable
ramfb, and vice versa, but I suppose in the end it doesn't matter.


I do think it matters! For one, if migration is not possible with
vfio-pci-nohotplug, then how can QE (or anyone else) *test* the patch
(i.e. that it makes a difference)? In that case, the ramfb_setup() call
from vfio-pci-nohotplug should just open-code "false" for the
"migratable" parameter.


Some vfio devices support migration, most don't.  I was thinking
ramfb_setup might be called with something like:

(vdev->ramfb_migrate && vdev->enable_migration)

so that at least the ramfb migration state matches the device, but I
think ultimately it only saves a little bit of overhead in registering
the vmstate, either one not supporting migration should block migration.

Hmm, since enable_migration is auto/on/off, it seems like device
realize should fail if set to 'on' and ramfb_migrate is false.  I think
that's the only way the device options don't become self contradictory.


Why isn't VFIODisplay a QOM object ? vfio_display_probe() is more or
less a realize routine, and we have a reset and finalize handlers for it.

(thinking aloud) the "ramfb-migrate" property could then be moved
down VFIODisplay, along with the other specific display properties.
Compatibility could be handled with property aliases. "enable_migration"
could set "ramfb-migrate".This looks like it would be nice model cleanup.

May be not the right time ?

Thanks,

C.




[PATCH v3] virtio: add VIRTQUEUE_ERROR QAPI event

2023-10-03 Thread Vladimir Sementsov-Ogievskiy
For now we only log the vhost device error, when virtqueue is actually
stopped. Let's add a QAPI event, which makes possible:

 - collect statistics of such errors
 - make immediate actions: take core dumps or do some other debugging
 - inform the user through a management API or UI, so that (s)he can
  react somehow, e.g. reset the device driver in the guest or even
  build up some automation to do so

Note that basically every inconsistency discovered during virtqueue
processing results in a silent virtqueue stop.  The guest then just
sees the requests getting stuck somewhere in the device for no visible
reason.  This event provides a means to inform the management layer of
this situation in a timely fashion.

The event could be reused for some other virtqueue problems (not only
for vhost devices) in future. For this it gets a generic name and
structure.

We keep original VHOST_OPS_DEBUG(), to keep original debug output as is
here, it's not the only call to VHOST_OPS_DEBUG in the file.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Denis Plotnikov 
---

v3: add r-b by Den
s/err/error/ in qapi
add host-vring-err description in qapi

 hw/virtio/vhost.c | 12 +---
 monitor/monitor.c | 10 ++
 qapi/qdev.json| 28 
 3 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index e2f6ffb446..43b7caaff3 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -15,6 +15,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-events-qdev.h"
 #include "hw/virtio/vhost.h"
 #include "qemu/atomic.h"
 #include "qemu/range.h"
@@ -1332,11 +1333,16 @@ static void 
vhost_virtqueue_error_notifier(EventNotifier *n)
 struct vhost_virtqueue *vq = container_of(n, struct vhost_virtqueue,
   error_notifier);
 struct vhost_dev *dev = vq->dev;
-int index = vq - dev->vqs;
 
 if (event_notifier_test_and_clear(n) && dev->vdev) {
-VHOST_OPS_DEBUG(-EINVAL,  "vhost vring error in virtqueue %d",
-dev->vq_index + index);
+int ind = vq - dev->vqs + dev->vq_index;
+DeviceState *ds = &dev->vdev->parent_obj;
+
+VHOST_OPS_DEBUG(-EINVAL,  "vhost vring error in virtqueue %d", ind);
+qapi_event_send_virtqueue_error(ds->id, ds->canonical_path, ind,
+VIRTQUEUE_ERROR_VHOST_VRING_ERROR,
+"vhost reported failure through vring "
+"error fd");
 }
 }
 
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 941f87815a..cb1ee31156 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -313,6 +313,7 @@ static MonitorQAPIEventConf 
monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
 [QAPI_EVENT_BALLOON_CHANGE]= { 1000 * SCALE_MS },
 [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
 [QAPI_EVENT_QUORUM_FAILURE]= { 1000 * SCALE_MS },
+[QAPI_EVENT_VIRTQUEUE_ERROR]   = { 1000 * SCALE_MS },
 [QAPI_EVENT_VSERPORT_CHANGE]   = { 1000 * SCALE_MS },
 [QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
 };
@@ -497,6 +498,10 @@ static unsigned int qapi_event_throttle_hash(const void 
*key)
 hash += g_str_hash(qdict_get_str(evstate->data, "qom-path"));
 }
 
+if (evstate->event == QAPI_EVENT_VIRTQUEUE_ERROR) {
+hash += g_str_hash(qdict_get_str(evstate->data, "device"));
+}
+
 return hash;
 }
 
@@ -524,6 +529,11 @@ static gboolean qapi_event_throttle_equal(const void *a, 
const void *b)
qdict_get_str(evb->data, "qom-path"));
 }
 
+if (eva->event == QAPI_EVENT_VIRTQUEUE_ERROR) {
+return !strcmp(qdict_get_str(eva->data, "device"),
+   qdict_get_str(evb->data, "device"));
+}
+
 return TRUE;
 }
 
diff --git a/qapi/qdev.json b/qapi/qdev.json
index 6bc5a733b8..55d6c9018e 100644
--- a/qapi/qdev.json
+++ b/qapi/qdev.json
@@ -161,3 +161,31 @@
 ##
 { 'event': 'DEVICE_UNPLUG_GUEST_ERROR',
   'data': { '*device': 'str', 'path': 'str' } }
+
+##
+# @VirtqueueError:
+#
+# @vhost-vring-error: Vhost device reported failure through
+# through vring error fd.
+#
+# Since: 8.2
+##
+{ 'enum': 'VirtqueueError',
+  'data': [ 'vhost-vring-error' ] }
+
+##
+# @VIRTQUEUE_ERROR:
+#
+# Emitted when a device virtqueue fails in runtime.
+#
+# @device: the device's ID if it has one
+# @path: the device's QOM path
+# @virtqueue: virtqueue index
+# @error: error identifier
+# @description: human readable description
+#
+# Since: 8.2
+##
+{ 'event': 'VIRTQUEUE_ERROR',
+ 'data': { '*device': 'str', 'path': 'str', 'virtqueue': 'int',
+'error': 'VirtqueueError', 'description': 'str'} }
-- 
2.34.1




Re: [PATCH RESEND 08/15] ppc: spapr: Implement nested PAPR hcall - H_GUEST_CREATE

2023-10-03 Thread Harsh Prateek Bora




On 9/7/23 07:58, Nicholas Piggin wrote:

On Wed Sep 6, 2023 at 2:33 PM AEST, Harsh Prateek Bora wrote:

This hcall is used by L1 to indicate to L0 that a new nested guest needs
to be created and therefore necessary resource allocation shall be made.
The L0 uses a hash table for nested guest specific resource management.
This data structure is further utilized by other hcalls to operate on
related members during entire life cycle of the nested guest.


Similar comment for changelog re detail. Detailed specification of API
and implementation could go in comments or documentation if useful.

Sure, squashing guest create/delete together and updating commit log to 
be abstract as needed.




Signed-off-by: Michael Neuling 
Signed-off-by: Shivaprasad G Bhat 
Signed-off-by: Harsh Prateek Bora 
---
  hw/ppc/spapr_nested.c | 75 +++
  include/hw/ppc/spapr_nested.h |  3 ++
  2 files changed, 78 insertions(+)

diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c
index 9af65f257f..09bbbfb341 100644
--- a/hw/ppc/spapr_nested.c
+++ b/hw/ppc/spapr_nested.c
@@ -444,6 +444,80 @@ static target_ulong h_guest_set_capabilities(PowerPCCPU 
*cpu,
  return H_SUCCESS;
  }
  
+static void

+destroy_guest_helper(gpointer value)
+{
+struct SpaprMachineStateNestedGuest *guest = value;
+g_free(guest);
+}
+
+static target_ulong h_guest_create(PowerPCCPU *cpu,
+   SpaprMachineState *spapr,
+   target_ulong opcode,
+   target_ulong *args)
+{
+CPUPPCState *env = &cpu->env;
+target_ulong flags = args[0];
+target_ulong continue_token = args[1];
+uint64_t lpid;
+int nguests = 0;
+struct SpaprMachineStateNestedGuest *guest;
+
+if (flags) { /* don't handle any flags for now */
+return H_UNSUPPORTED_FLAG;
+}
+
+if (continue_token != -1) {
+return H_P2;
+}
+
+if (!spapr_get_cap(spapr, SPAPR_CAP_NESTED_PAPR)) {
+return H_FUNCTION;
+}
+
+if (!spapr->nested.capabilities_set) {
+return H_STATE;
+}
+
+if (!spapr->nested.guests) {
+spapr->nested.lpid_max = NESTED_GUEST_MAX;
+spapr->nested.guests = g_hash_table_new_full(NULL,
+ NULL,
+ NULL,
+ destroy_guest_helper);


Is lpid_max only used by create? Probably no need to have it in spapr
then->nested then. Also, do we even need to have a limit?


Yes, as of now, it is being used only by create and doesnt need to part
of spapr->nested. We can simply use the macro for max guests. Keeping it
to emulate a finite resource model.
For all practical purposes, nested guests in an TCG emulated L0
shouldn't reach that limit.




+}
+
+nguests = g_hash_table_size(spapr->nested.guests);
+
+if (nguests == spapr->nested.lpid_max) {
+return H_NO_MEM;
+}
+
+/* Lookup for available lpid */
+for (lpid = 1; lpid < spapr->nested.lpid_max; lpid++) {


PAPR API calls it "guest ID" I think. Should change all references to
lpid to that.


Changing it to "guestid".




+if (!(g_hash_table_lookup(spapr->nested.guests,
+  GINT_TO_POINTER(lpid {
+break;
+}
+}
+if (lpid == spapr->nested.lpid_max) {
+return H_NO_MEM;
+}
+
+guest = g_try_new0(struct SpaprMachineStateNestedGuest, 1);
+if (!guest) {
+return H_NO_MEM;
+}
+
+guest->pvr_logical = spapr->nested.pvr_base;
+
+g_hash_table_insert(spapr->nested.guests, GINT_TO_POINTER(lpid), guest);
+printf("%s: lpid: %lu (MAX: %i)\n", __func__, lpid, 
spapr->nested.lpid_max);


Remove printf.


Done.


+
+env->gpr[4] = lpid;
+return H_SUCCESS;
+}
+
  void spapr_register_nested(void)
  {
  spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
@@ -456,6 +530,7 @@ void spapr_register_nested_phyp(void)
  {
  spapr_register_hypercall(H_GUEST_GET_CAPABILITIES, 
h_guest_get_capabilities);
  spapr_register_hypercall(H_GUEST_SET_CAPABILITIES, 
h_guest_set_capabilities);
+spapr_register_hypercall(H_GUEST_CREATE  , h_guest_create);
  }
  
  #else

diff --git a/include/hw/ppc/spapr_nested.h b/include/hw/ppc/spapr_nested.h
index a7996251cb..7841027df8 100644
--- a/include/hw/ppc/spapr_nested.h
+++ b/include/hw/ppc/spapr_nested.h
@@ -197,6 +197,9 @@
  #define H_GUEST_CAP_P9_MODE_BMAP1
  #define H_GUEST_CAP_P10_MODE_BMAP   2
  
+/* Nested PAPR API macros */

+#define NESTED_GUEST_MAX 4096


Prefix with PAPR_?


Done.

Thanks
Harsh


Thanks,
Nick


+
  typedef struct SpaprMachineStateNestedGuest {
  unsigned long vcpus;
  struct SpaprMachineStateNestedGuestVcpu *vcpu;






Re: [PATCH RESEND 14/15] ppc: spapr: Implement nested PAPR hcall - H_GUEST_DELETE

2023-10-03 Thread Harsh Prateek Bora




On 9/7/23 08:01, Nicholas Piggin wrote:

On Wed Sep 6, 2023 at 2:33 PM AEST, Harsh Prateek Bora wrote:

This hcall is used by L1 to delete a guest entry in L0 or can also be
used to delete all guests if needed (usually in shutdown scenarios).


I'd squash with at least the create hcall.


Done.





Signed-off-by: Michael Neuling 
Signed-off-by: Harsh Prateek Bora 
---
  hw/ppc/spapr_nested.c | 32 
  include/hw/ppc/spapr_nested.h |  1 +
  2 files changed, 33 insertions(+)

diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c
index 3605f27115..5afdad4990 100644
--- a/hw/ppc/spapr_nested.c
+++ b/hw/ppc/spapr_nested.c
@@ -1692,6 +1692,37 @@ static void exit_process_output_buffer(PowerPCCPU *cpu,
  return;
  }
  
+static target_ulong h_guest_delete(PowerPCCPU *cpu,

+   SpaprMachineState *spapr,
+   target_ulong opcode,
+   target_ulong *args)
+{
+target_ulong flags = args[0];
+target_ulong lpid = args[1];
+struct SpaprMachineStateNestedGuest *guest;
+
+if (!spapr_get_cap(spapr, SPAPR_CAP_NESTED_PAPR)) {
+return H_FUNCTION;
+}


If you only register these hcalls when you apply the cap, then you
don't need to test it, right?


Yes, cleaned up now.


Open question as to whether it's better to register hcalls when
enabling such caps, or do the tests for them here. I guess the
former makes sense.


Yeh, I am inclined towards former as well.




+
+/* handle flag deleteAllGuests, remaining bits reserved */


This comment is confusing. What is flag deleteAllGuests?


This flag, as per spec, if set, should delete all guests and the
provided guestID is ignored. Updating comment to mention the same.


H_GUEST_DELETE_ALL_MASK? Is that a mask, or a flag?


Flag, Updating it to H_GUEST_DELETE_ALL_FLAG.




+if (flags & ~H_GUEST_DELETE_ALL_MASK) {
+return H_UNSUPPORTED_FLAG;
+} else if (flags & H_GUEST_DELETE_ALL_MASK) {
+g_hash_table_destroy(spapr->nested.guests);
+return H_SUCCESS;
+}
+
+guest = g_hash_table_lookup(spapr->nested.guests, GINT_TO_POINTER(lpid));
+if (!guest) {
+return H_P2;
+}
+
+g_hash_table_remove(spapr->nested.guests, GINT_TO_POINTER(lpid));
+
+return H_SUCCESS;
+}
+
  void spapr_register_nested(void)
  {
  spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
@@ -1709,6 +1740,7 @@ void spapr_register_nested_phyp(void)
  spapr_register_hypercall(H_GUEST_SET_STATE   , h_guest_set_state);
  spapr_register_hypercall(H_GUEST_GET_STATE   , h_guest_get_state);
  spapr_register_hypercall(H_GUEST_RUN_VCPU, h_guest_run_vcpu);
+spapr_register_hypercall(H_GUEST_DELETE  , h_guest_delete);
  }
  
  #else

diff --git a/include/hw/ppc/spapr_nested.h b/include/hw/ppc/spapr_nested.h
index ca5d28c06e..9eb43778ad 100644
--- a/include/hw/ppc/spapr_nested.h
+++ b/include/hw/ppc/spapr_nested.h
@@ -209,6 +209,7 @@
  #define H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE 0x8000 /* BE in GSB 
*/
  #define GUEST_STATE_REQUEST_GUEST_WIDE   0x1
  #define GUEST_STATE_REQUEST_SET  0x2
+#define H_GUEST_DELETE_ALL_MASK  0x8000ULL
  
  #define GUEST_STATE_ELEMENT(i, sz, s, f, ptr, c) { \

  .id = (i), \






Re: [PATCH RESEND 06/15] ppc: spapr: Implement nested PAPR hcall - H_GUEST_GET_CAPABILITIES

2023-10-03 Thread Cédric Le Goater

On 9/7/23 04:02, Nicholas Piggin wrote:

On Wed Sep 6, 2023 at 2:33 PM AEST, Harsh Prateek Bora wrote:

This patch implements nested PAPR hcall H_GUEST_GET_CAPABILITIES and
also enables registration of nested PAPR hcalls whenever an L0 is
launched with cap-nested-papr=true. The common registration routine
shall be used by future patches for registration of related hcall
support
being added. This hcall is used by L1 kernel to get the set of guest
capabilities that are supported by L0 (Qemu TCG).


Changelog can drop "This patch". Probably don't have to be so
detailed here either -- we already established that PAPR hcalls can
be used with cap-nested-papr in the last patch, we know that L1
kernels make the hcalls to the vhyp, etc.

"Introduce the nested PAPR hcall H_GUEST_GET_CAPABILITIES which
is used to query the capabilities of the API and the L2 guests
it provides."

I would squash this with set.



Signed-off-by: Michael Neuling 
Signed-off-by: Harsh Prateek Bora 
---
  hw/ppc/spapr_caps.c   |  1 +
  hw/ppc/spapr_nested.c | 35 +++
  include/hw/ppc/spapr_nested.h |  6 ++
  3 files changed, 42 insertions(+)

diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index d3b9f107aa..cbe53a79ec 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -511,6 +511,7 @@ static void cap_nested_papr_apply(SpaprMachineState *spapr,
  return;
  }
  spapr->nested.api = NESTED_API_PAPR;
+spapr_register_nested_phyp();
  } else if (kvm_enabled()) {
  /*
   * this gets executed in L1 qemu when L2 is launched,


Hmm, this doesn't match nested HV registration. If you want to register
the hcalls in the cap apply, can you move spapr_register_nested()
there first? It may make more sense to go in as a dummy function with
the cap patch first, since you don't introduce all hcalls together.

Also phyp->papr. Scrub for phyp please.


Ah. I was going to say the opposit since on an LPAR :

Architecture:ppc64le
  Byte Order:Little Endian
CPU(s):  192
  On-line CPU(s) list:   0-191
Model name:  POWER10 (architected), altivec supported
  Model: 2.0 (pvr 0080 0200)
  Thread(s) per core:8
  Core(s) per socket:6
  Socket(s): 4
Virtualization features:
  Hypervisor vendor: pHyp   <-
  Virtualization type:   para



C.





diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c
index a669470f1a..37f3a49be2 100644
--- a/hw/ppc/spapr_nested.c
+++ b/hw/ppc/spapr_nested.c
@@ -6,6 +6,7 @@
  #include "hw/ppc/spapr.h"
  #include "hw/ppc/spapr_cpu_core.h"
  #include "hw/ppc/spapr_nested.h"
+#include "cpu-models.h"
  
  #ifdef CONFIG_TCG

  #define PRTS_MASK  0x1f
@@ -375,6 +376,29 @@ void spapr_exit_nested(PowerPCCPU *cpu, int excp)
  address_space_unmap(CPU(cpu)->as, regs, len, len, true);
  }
  
+static target_ulong h_guest_get_capabilities(PowerPCCPU *cpu,

+ SpaprMachineState *spapr,
+ target_ulong opcode,
+ target_ulong *args)
+{
+CPUPPCState *env = &cpu->env;
+target_ulong flags = args[0];
+
+if (flags) { /* don't handle any flags capabilities for now */
+return H_PARAMETER;
+}
+
+if ((env->spr[SPR_PVR] & CPU_POWERPC_POWER_SERVER_MASK) ==
+(CPU_POWERPC_POWER9_BASE))
+env->gpr[4] = H_GUEST_CAPABILITIES_P9_MODE;
+
+if ((env->spr[SPR_PVR] & CPU_POWERPC_POWER_SERVER_MASK) ==
+(CPU_POWERPC_POWER10_BASE))
+env->gpr[4] = H_GUEST_CAPABILITIES_P10_MODE;
+
+return H_SUCCESS;
+}
+
  void spapr_register_nested(void)
  {
  spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
@@ -382,6 +406,12 @@ void spapr_register_nested(void)
  spapr_register_hypercall(KVMPPC_H_TLB_INVALIDATE, h_tlb_invalidate);
  spapr_register_hypercall(KVMPPC_H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
  }
+
+void spapr_register_nested_phyp(void)
+{
+spapr_register_hypercall(H_GUEST_GET_CAPABILITIES, 
h_guest_get_capabilities);
+}
+
  #else
  void spapr_exit_nested(PowerPCCPU *cpu, int excp)
  {
@@ -392,4 +422,9 @@ void spapr_register_nested(void)
  {
  /* DO NOTHING */
  }
+
+void spapr_register_nested_phyp(void)
+{
+/* DO NOTHING */
+}
  #endif
diff --git a/include/hw/ppc/spapr_nested.h b/include/hw/ppc/spapr_nested.h
index f8db31075b..ce198e9f70 100644
--- a/include/hw/ppc/spapr_nested.h
+++ b/include/hw/ppc/spapr_nested.h
@@ -189,6 +189,11 @@
  /* End of list of Guest State Buffer Element IDs */
  #define GSB_LASTGSB_VCPU_SPR_ASDR
  
+/* Bit masks to be used in nested PAPR API */

+#define H_GUEST_CAPABILITIES_COPY_MEM 0x8000
+#define H_GUEST_CAPABILITIES_P9_MODE  0x4000
+#define H_GUEST_CAPABILITIES_P10_MODE 0x2000


See introducing these defines with the patch that uses them i

Re: [PATCH v2 4/5] ramfb: make migration conditional

2023-10-03 Thread Marc-André Lureau
Hi

On Tue, Oct 3, 2023 at 11:43 AM Cédric Le Goater  wrote:
>
> On 10/2/23 22:38, Alex Williamson wrote:
> > On Mon, 2 Oct 2023 21:41:55 +0200
> > Laszlo Ersek  wrote:
> >
> >> On 10/2/23 21:26, Alex Williamson wrote:
> >>> On Mon, 2 Oct 2023 20:24:11 +0200
> >>> Laszlo Ersek  wrote:
> >>>
>  On 10/2/23 16:41, Alex Williamson wrote:
> > On Mon, 2 Oct 2023 15:38:10 +0200
> > Cédric Le Goater  wrote:
> >
> >> On 10/2/23 13:11, marcandre.lur...@redhat.com wrote:
> >>> From: Marc-André Lureau 
> >>>
> >>> RAMFB migration was unsupported until now, let's make it conditional.
> >>> The following patch will prevent machines <= 8.1 to migrate it.
> >>>
> >>> Signed-off-by: Marc-André Lureau 
> >> Maybe localize the new 'ramfb_migrate' attribute close to 
> >> 'enable_ramfb'
> >> in VFIOPCIDevice. Anyhow,
> >
> > Shouldn't this actually be tied to whether the device is migratable
> > (which for GVT-g - the only ramfb user afaik - it's not)?  What does it
> > mean to have a ramfb-migrate=true property on a device that doesn't
> > support migration, or false on a device that does support migration.  I
> > don't understand why this is a user controllable property.  Thanks,
> 
>  The comments in 
>  (which are unfortunately not public :/ ) suggest that ramfb migration
>  was simply forgotten when vGPU migration was implemented. So, "now
>  that vGPU migration is done", this should be added.
> 
>  Comment 8 suggests that the following domain XML snippet
> 
>     model='vfio-pci' display='on' ramfb='on'> 
>   
> 
> 
>   function='0x0'/> 
> 
>  is migratable, but the ramfb device malfunctions on the destination
>  host.
> 
>  There's also a huge QEMU cmdline in comment#0 of the bug; I've not
>  tried to read that.
> 
>  AIUI BTW the property is not for the user to control, it's just a
>  compat knob for versioned machine types. AIUI those are usually
>  implemented with such (user-visible / -tweakable) device properties.
> >>>
> >>> If it's not for user control it's unfortunate that we expose it to the
> >>> user at all, but should it at least use the "x-" prefix to indicate that
> >>> it's not intended to be an API?
> >>
> >> I *think* it was your commit db32d0f43839 ("vfio/pci: Add option to
> >> disable GeForce quirks", 2018-02-06) that hda introduced me to the "x-"
> >> prefixed properties!
> >>
> >> For some reason though, machine type compat knobs are never named like
> >> that, AFAIR.
> >
> > Maybe I'm misunderstanding your comment, but it appears quite common to
> > use "x-" prefix things in the compat tables...
> >
> > GlobalProperty hw_compat_8_0[] = {
> >  { "migration", "multifd-flush-after-each-section", "on"},
> >  { TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
> >  { TYPE_VIRTIO_NET, "host_uso", "off"},
> >  { TYPE_VIRTIO_NET, "guest_uso4", "off"},
> >  { TYPE_VIRTIO_NET, "guest_uso6", "off"},
> > };
> > const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
> >
> > GlobalProperty hw_compat_7_2[] = {
> >  { "e1000e", "migrate-timadj", "off" },
> >  { "virtio-mem", "x-early-migration", "false" },
> >  { "migration", "x-preempt-pre-7-2", "true" },
> >  { TYPE_PCI_DEVICE, "x-pcie-err-unc-mask", "off" },
> > };
> > const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
> > [etc]
> >
> >>> It's still odd to think that we can
> >>> have scenarios of a non-migratable vfio device registering a migratable
> >>> ramfb, and vice versa, but I suppose in the end it doesn't matter.
> >>
> >> I do think it matters! For one, if migration is not possible with
> >> vfio-pci-nohotplug, then how can QE (or anyone else) *test* the patch
> >> (i.e. that it makes a difference)? In that case, the ramfb_setup() call
> >> from vfio-pci-nohotplug should just open-code "false" for the
> >> "migratable" parameter.
> >
> > Some vfio devices support migration, most don't.  I was thinking
> > ramfb_setup might be called with something like:
> >
> >   (vdev->ramfb_migrate && vdev->enable_migration)
> >
> > so that at least the ramfb migration state matches the device, but I
> > think ultimately it only saves a little bit of overhead in registering
> > the vmstate, either one not supporting migration should block migration.
> >
> > Hmm, since enable_migration is auto/on/off, it seems like device
> > realize should fail if set to 'on' and ramfb_migrate is false.  I think
> > that's the only way the device options don't become self contradictory.
>
> Why isn't VFIODisplay a QOM object ? vfio_display_probe() is more or
> less a realize routine, and we have a reset and finalize handlers for it.
>
> (thinking aloud) the "ramfb-migrate" property could then be moved
> down VFIODisplay, along with the other specific display pro

[PATCH v2 0/5] hw/intc/apic: QOM cleanup

2023-10-03 Thread Philippe Mathieu-Daudé
Since v1:
- Dropped change in x86_cpu_realizefn (rth)
- Simplify kvm_apic_realize() error propagation

Minor cleanup extracted from a bigger series
touching x86_cpu_realizefn().

Philippe Mathieu-Daudé (5):
  hw/intc/apic: Use ERRP_GUARD() in apic_common_realize()
  hw/i386/apic: Defer error check from apic_get_class to
kvm_apic_realize
  hw/i386/apic: Simplify apic_get_class()
  hw/intc/apic: Rename x86_cpu_apic_create() -> x86_cpu_apic_new()
  hw/intc/apic: Pass CPU using QOM link property

 include/hw/i386/apic_internal.h |  2 +-
 target/i386/cpu-internal.h  |  2 +-
 hw/i386/amd_iommu.c |  2 +-
 hw/i386/intel_iommu.c   |  4 ++--
 hw/i386/kvm/apic.c  |  5 +
 hw/intc/apic_common.c   |  8 +++-
 target/i386/cpu-sysemu.c| 23 +++
 target/i386/cpu.c   |  5 +
 8 files changed, 25 insertions(+), 26 deletions(-)

-- 
2.41.0




[PATCH v2 4/5] hw/intc/apic: Rename x86_cpu_apic_create() -> x86_cpu_apic_new()

2023-10-03 Thread Philippe Mathieu-Daudé
x86_cpu_apic_create()'s Error** parameter is unused, drop it.

While there is no convention, QDev methods are usually named
with _new() / _realize() suffixes. Rename as appropriate.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/i386/cpu-internal.h | 2 +-
 hw/intc/apic_common.c  | 2 +-
 target/i386/cpu-sysemu.c   | 2 +-
 target/i386/cpu.c  | 5 +
 4 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/target/i386/cpu-internal.h b/target/i386/cpu-internal.h
index 9baac5c0b4..8299b347f7 100644
--- a/target/i386/cpu-internal.h
+++ b/target/i386/cpu-internal.h
@@ -62,7 +62,7 @@ GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs);
 void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
 const char *name, void *opaque, Error **errp);
 
-void x86_cpu_apic_create(X86CPU *cpu, Error **errp);
+void x86_cpu_apic_new(X86CPU *cpu);
 void x86_cpu_apic_realize(X86CPU *cpu, Error **errp);
 void x86_cpu_machine_reset_cb(void *opaque);
 #endif /* !CONFIG_USER_ONLY */
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index bccb4241c2..8a79eacdb0 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -451,7 +451,7 @@ static void apic_common_class_init(ObjectClass *klass, void 
*data)
 dc->unrealize = apic_common_unrealize;
 /*
  * Reason: APIC and CPU need to be wired up by
- * x86_cpu_apic_create()
+ * x86_cpu_apic_new()
  */
 dc->user_creatable = false;
 }
diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c
index 9038c65267..373dc6b1c7 100644
--- a/target/i386/cpu-sysemu.c
+++ b/target/i386/cpu-sysemu.c
@@ -263,7 +263,7 @@ APICCommonClass *apic_get_class(void)
 return APIC_COMMON_CLASS(object_class_by_name(apic_type));
 }
 
-void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
+void x86_cpu_apic_new(X86CPU *cpu)
 {
 APICCommonState *apic;
 APICCommonClass *apic_class = apic_get_class();
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ed72883bf3..69d56bae91 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7418,10 +7418,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error 
**errp)
 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
 
 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || ms->smp.cpus > 1) {
-x86_cpu_apic_create(cpu, &local_err);
-if (local_err != NULL) {
-goto out;
-}
+x86_cpu_apic_new(cpu);
 }
 #endif
 
-- 
2.41.0




[PATCH v2 1/5] hw/intc/apic: Use ERRP_GUARD() in apic_common_realize()

2023-10-03 Thread Philippe Mathieu-Daudé
APICCommonClass::realize() is a DeviceRealize() handler which
take an Error** parameter and can fail. Do not proceed further
on failure.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/intc/apic_common.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 68ad30e2f5..bccb4241c2 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -257,6 +257,7 @@ static const VMStateDescription vmstate_apic_common;
 
 static void apic_common_realize(DeviceState *dev, Error **errp)
 {
+ERRP_GUARD();
 APICCommonState *s = APIC_COMMON(dev);
 APICCommonClass *info;
 static DeviceState *vapic;
@@ -267,6 +268,9 @@ static void apic_common_realize(DeviceState *dev, Error 
**errp)
 
 info = APIC_COMMON_GET_CLASS(s);
 info->realize(dev, errp);
+if (*errp) {
+return;
+}
 
 /* Note: We need at least 1M to map the VAPIC option ROM */
 if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK &&
-- 
2.41.0




[PATCH v2 2/5] hw/i386/apic: Defer error check from apic_get_class to kvm_apic_realize

2023-10-03 Thread Philippe Mathieu-Daudé
apic_get_class() isn't supposed to fail. kvm_apic_realize() is
DeviceRealize() handler, which can fail. Defer the error check
to the latter.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/kvm/apic.c   | 5 +
 target/i386/cpu-sysemu.c | 8 
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index 1e89ca0899..4883308247 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -228,6 +228,11 @@ static void kvm_apic_realize(DeviceState *dev, Error 
**errp)
 {
 APICCommonState *s = APIC_COMMON(dev);
 
+if (!kvm_irqchip_in_kernel()) {
+error_setg(errp, "KVM does not support userspace APIC");
+return;
+}
+
 memory_region_init_io(&s->io_memory, OBJECT(s), &kvm_apic_io_ops, s,
   "kvm-apic-msi", APIC_SPACE_SIZE);
 
diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c
index 2375e48178..6a228c9178 100644
--- a/target/i386/cpu-sysemu.c
+++ b/target/i386/cpu-sysemu.c
@@ -253,10 +253,6 @@ APICCommonClass *apic_get_class(Error **errp)
 
 /* TODO: in-kernel irqchip for hvf */
 if (kvm_enabled()) {
-if (!kvm_irqchip_in_kernel()) {
-error_setg(errp, "KVM does not support userspace APIC");
-return NULL;
-}
 apic_type = "kvm-apic";
 } else if (xen_enabled()) {
 apic_type = "xen-apic";
@@ -272,10 +268,6 @@ void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
 APICCommonState *apic;
 APICCommonClass *apic_class = apic_get_class(errp);
 
-if (!apic_class) {
-return;
-}
-
 cpu->apic_state = DEVICE(object_new_with_class(OBJECT_CLASS(apic_class)));
 object_property_add_child(OBJECT(cpu), "lapic",
   OBJECT(cpu->apic_state));
-- 
2.41.0




[PATCH v2 3/5] hw/i386/apic: Simplify apic_get_class()

2023-10-03 Thread Philippe Mathieu-Daudé
Now than apic_get_class() can not fail, remove its
Error** parameter. It can't return NULL neither, so
simplify x86_cpu_apic_create().

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/i386/apic_internal.h | 2 +-
 hw/i386/amd_iommu.c | 2 +-
 hw/i386/intel_iommu.c   | 4 ++--
 target/i386/cpu-sysemu.c| 4 ++--
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 5f2ba24bfc..e61ad04769 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -225,6 +225,6 @@ static inline int apic_get_bit(uint32_t *tab, int index)
 return !!(tab[i] & mask);
 }
 
-APICCommonClass *apic_get_class(Error **errp);
+APICCommonClass *apic_get_class(void);
 
 #endif /* QEMU_APIC_INTERNAL_H */
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index c98a3c6e11..0a95025ab7 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1368,7 +1368,7 @@ static MemTxResult amdvi_mem_ir_write(void *opaque, 
hwaddr addr,
 return MEMTX_ERROR;
 }
 
-apic_get_class(NULL)->send_msi(&to);
+apic_get_class()->send_msi(&to);
 
 trace_amdvi_mem_ir_write(to.address, to.data);
 return MEMTX_OK;
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 2c832ab68b..dffe3583bd 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -397,7 +397,7 @@ static void vtd_generate_interrupt(IntelIOMMUState *s, 
hwaddr mesg_addr_reg,
 
 trace_vtd_irq_generate(msi.address, msi.data);
 
-apic_get_class(NULL)->send_msi(&msi);
+apic_get_class()->send_msi(&msi);
 }
 
 /* Generate a fault event to software via MSI if conditions are met.
@@ -3554,7 +3554,7 @@ static MemTxResult vtd_mem_ir_write(void *opaque, hwaddr 
addr,
 return MEMTX_ERROR;
 }
 
-apic_get_class(NULL)->send_msi(&to);
+apic_get_class()->send_msi(&to);
 
 return MEMTX_OK;
 }
diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c
index 6a228c9178..9038c65267 100644
--- a/target/i386/cpu-sysemu.c
+++ b/target/i386/cpu-sysemu.c
@@ -247,7 +247,7 @@ void x86_cpu_machine_reset_cb(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
-APICCommonClass *apic_get_class(Error **errp)
+APICCommonClass *apic_get_class(void)
 {
 const char *apic_type = "apic";
 
@@ -266,7 +266,7 @@ APICCommonClass *apic_get_class(Error **errp)
 void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
 {
 APICCommonState *apic;
-APICCommonClass *apic_class = apic_get_class(errp);
+APICCommonClass *apic_class = apic_get_class();
 
 cpu->apic_state = DEVICE(object_new_with_class(OBJECT_CLASS(apic_class)));
 object_property_add_child(OBJECT(cpu), "lapic",
-- 
2.41.0




Re: [PATCH v2 4/5] ramfb: make migration conditional

2023-10-03 Thread Cédric Le Goater

On 10/3/23 10:23, Marc-André Lureau wrote:

Hi

On Tue, Oct 3, 2023 at 11:43 AM Cédric Le Goater  wrote:


On 10/2/23 22:38, Alex Williamson wrote:

On Mon, 2 Oct 2023 21:41:55 +0200
Laszlo Ersek  wrote:


On 10/2/23 21:26, Alex Williamson wrote:

On Mon, 2 Oct 2023 20:24:11 +0200
Laszlo Ersek  wrote:


On 10/2/23 16:41, Alex Williamson wrote:

On Mon, 2 Oct 2023 15:38:10 +0200
Cédric Le Goater  wrote:


On 10/2/23 13:11, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

RAMFB migration was unsupported until now, let's make it conditional.
The following patch will prevent machines <= 8.1 to migrate it.

Signed-off-by: Marc-André Lureau 

Maybe localize the new 'ramfb_migrate' attribute close to 'enable_ramfb'
in VFIOPCIDevice. Anyhow,


Shouldn't this actually be tied to whether the device is migratable
(which for GVT-g - the only ramfb user afaik - it's not)?  What does it
mean to have a ramfb-migrate=true property on a device that doesn't
support migration, or false on a device that does support migration.  I
don't understand why this is a user controllable property.  Thanks,


The comments in 
(which are unfortunately not public :/ ) suggest that ramfb migration
was simply forgotten when vGPU migration was implemented. So, "now
that vGPU migration is done", this should be added.

Comment 8 suggests that the following domain XML snippet

   
  


 

is migratable, but the ramfb device malfunctions on the destination
host.

There's also a huge QEMU cmdline in comment#0 of the bug; I've not
tried to read that.

AIUI BTW the property is not for the user to control, it's just a
compat knob for versioned machine types. AIUI those are usually
implemented with such (user-visible / -tweakable) device properties.


If it's not for user control it's unfortunate that we expose it to the
user at all, but should it at least use the "x-" prefix to indicate that
it's not intended to be an API?


I *think* it was your commit db32d0f43839 ("vfio/pci: Add option to
disable GeForce quirks", 2018-02-06) that hda introduced me to the "x-"
prefixed properties!

For some reason though, machine type compat knobs are never named like
that, AFAIR.


Maybe I'm misunderstanding your comment, but it appears quite common to
use "x-" prefix things in the compat tables...

GlobalProperty hw_compat_8_0[] = {
  { "migration", "multifd-flush-after-each-section", "on"},
  { TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
  { TYPE_VIRTIO_NET, "host_uso", "off"},
  { TYPE_VIRTIO_NET, "guest_uso4", "off"},
  { TYPE_VIRTIO_NET, "guest_uso6", "off"},
};
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);

GlobalProperty hw_compat_7_2[] = {
  { "e1000e", "migrate-timadj", "off" },
  { "virtio-mem", "x-early-migration", "false" },
  { "migration", "x-preempt-pre-7-2", "true" },
  { TYPE_PCI_DEVICE, "x-pcie-err-unc-mask", "off" },
};
const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
[etc]


It's still odd to think that we can
have scenarios of a non-migratable vfio device registering a migratable
ramfb, and vice versa, but I suppose in the end it doesn't matter.


I do think it matters! For one, if migration is not possible with
vfio-pci-nohotplug, then how can QE (or anyone else) *test* the patch
(i.e. that it makes a difference)? In that case, the ramfb_setup() call
from vfio-pci-nohotplug should just open-code "false" for the
"migratable" parameter.


Some vfio devices support migration, most don't.  I was thinking
ramfb_setup might be called with something like:

   (vdev->ramfb_migrate && vdev->enable_migration)

so that at least the ramfb migration state matches the device, but I
think ultimately it only saves a little bit of overhead in registering
the vmstate, either one not supporting migration should block migration.

Hmm, since enable_migration is auto/on/off, it seems like device
realize should fail if set to 'on' and ramfb_migrate is false.  I think
that's the only way the device options don't become self contradictory.


Why isn't VFIODisplay a QOM object ? vfio_display_probe() is more or
less a realize routine, and we have a reset and finalize handlers for it.

(thinking aloud) the "ramfb-migrate" property could then be moved
down VFIODisplay, along with the other specific display properties.
Compatibility could be handled with property aliases. "enable_migration"
could set "ramfb-migrate".This looks like it would be nice model cleanup.

May be not the right time ?


Yes, I thought about some similar changes (though I am not sure QOM is
necessary).

Now I am trying to test my changes that add a VFIODisplay migration
subsection, but I don't think I have a GVT-g GPU (TGL GT1). When I try
with a random PCI device, I get "VFIO migration is not supported in
kernel". I can try to comment out some code, but that seems hazardous.


I have recently setup a T480 with GVT-g and a wi

[PATCH v2 5/5] hw/intc/apic: Pass CPU using QOM link property

2023-10-03 Thread Philippe Mathieu-Daudé
QOM objects shouldn't access each other internals fields
except using the QOM API.

Declare the 'cpu' and 'base-addr' properties, set them
using object_property_set_link() and qdev_prop_set_uint32()
respectively. Since the _set_link() call can't fail, use
&error_abort in case there is a programming error.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/intc/apic_common.c| 2 ++
 target/i386/cpu-sysemu.c | 9 -
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 8a79eacdb0..be7cf3b332 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -398,6 +398,8 @@ static Property apic_properties_common[] = {
 true),
 DEFINE_PROP_BOOL("legacy-instance-id", APICCommonState, legacy_instance_id,
  false),
+DEFINE_PROP_LINK("cpu", APICCommonState, cpu, TYPE_X86_CPU, X86CPU *),
+DEFINE_PROP_UINT32("base-addr", APICCommonState, apicbase, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c
index 373dc6b1c7..b084706531 100644
--- a/target/i386/cpu-sysemu.c
+++ b/target/i386/cpu-sysemu.c
@@ -265,7 +265,6 @@ APICCommonClass *apic_get_class(void)
 
 void x86_cpu_apic_new(X86CPU *cpu)
 {
-APICCommonState *apic;
 APICCommonClass *apic_class = apic_get_class();
 
 cpu->apic_state = DEVICE(object_new_with_class(OBJECT_CLASS(apic_class)));
@@ -273,11 +272,11 @@ void x86_cpu_apic_new(X86CPU *cpu)
   OBJECT(cpu->apic_state));
 object_unref(OBJECT(cpu->apic_state));
 
+object_property_set_link(OBJECT(cpu->apic_state), "cpu",
+ OBJECT(cpu), &error_abort);
 qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
-/* TODO: convert to link<> */
-apic = APIC_COMMON(cpu->apic_state);
-apic->cpu = cpu;
-apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
+qdev_prop_set_uint32(cpu->apic_state, "base-addr",
+ APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE);
 }
 
 void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
-- 
2.41.0




[PULL 01/24] optionrom: Remove build-id section

2023-10-03 Thread Paolo Bonzini
From: Fabiano Rosas 

Our linker script for optionroms specifies only the placement of the
.text section, leaving the linker free to place the remaining sections
at arbitrary places in the file.

Since at least binutils 2.39, the .note.gnu.build-id section is now
being placed at the start of the file, which causes label addresses to
be shifted. For linuxboot_dma.bin that means that the PnP header
(among others) will not be found when determining the type of ROM at
optionrom_setup():

(0x1c is the label _pnph, where the magic "PnP" is)

$ xxd /usr/share/qemu/linuxboot_dma.bin | grep "PnP"
0010:      1c00 2450 6e50  $PnP

$ xxd pc-bios/optionrom/linuxboot_dma.bin | grep "PnP"
0010:      4c00 2450 6e50  $PnP
   ^bad

Using a freshly built linuxboot_dma.bin ROM results in a broken boot:

  SeaBIOS (version rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org)
  Booting from Hard Disk...
  Boot failed: could not read the boot disk

  Booting from Floppy...
  Boot failed: could not read the boot disk

  No bootable device.

We're not using the build-id section, so pass the --build-id=none
option to the linker to remove it entirely.

Note: In theory, this same issue could happen with any other
section. The ideal solution would be to have all unused sections
discarded in the linker script. However that would be a larger change,
specially for the pvh rom which uses the .bss and COMMON sections so
I'm addressing only the immediate issue here.

Reported-by: Vasiliy Ulyanov 
Signed-off-by: Fabiano Rosas 
Reviewed-by: Thomas Huth 
Message-ID: <20230926192502.15986-1-faro...@suse.de>
Cc: sta...@vger.kernel.org
Signed-off-by: Paolo Bonzini 
---
 pc-bios/optionrom/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index b1fff0ba6c8..30d07026c79 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -36,7 +36,7 @@ config-cc.mak: Makefile
$(call cc-option,-Wno-array-bounds)) 3> config-cc.mak
 -include config-cc.mak
 
-override LDFLAGS = -nostdlib -Wl,-T,$(SRC_DIR)/flat.lds
+override LDFLAGS = -nostdlib -Wl,--build-id=none,-T,$(SRC_DIR)/flat.lds
 
 pvh.img: pvh.o pvh_main.o
 
-- 
2.41.0




[PULL 06/24] meson: clean up static_library keyword arguments

2023-10-03 Thread Paolo Bonzini
These are either built because they are dependencies of other targets,
or not needed at all because they are used via extract_objects().
Mark them as "build_by_default: false"; if applicable, mark them
as "fa" so that -Wl,--whole-archive does not interact with the
linker script used for fuzzing.

(The "fa" hack is brittle; updating to Meson 1.1 would allow using
declare_dependency(objects: ...) instead).

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1044
Signed-off-by: Paolo Bonzini 
---
 gdbstub/meson.build |  4 ++--
 meson.build | 11 +++
 tcg/meson.build |  4 ++--
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index 9500b9dc4e6..a5a1f4e433f 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -21,12 +21,12 @@ libgdb_user = static_library('gdb_user',
  gdb_user_ss.sources() + genh,
  name_suffix: 'fa',
  c_args: '-DCONFIG_USER_ONLY',
- build_by_default: have_user)
+ build_by_default: false)
 
 libgdb_softmmu = static_library('gdb_softmmu',
 gdb_system_ss.sources() + genh,
 name_suffix: 'fa',
-build_by_default: have_system)
+build_by_default: false)
 
 gdb_user = declare_dependency(link_whole: libgdb_user)
 user_ss.add(gdb_user)
diff --git a/meson.build b/meson.build
index 81430ce2348..21a1bc03f87 100644
--- a/meson.build
+++ b/meson.build
@@ -3180,7 +3180,6 @@ foreach d : hx_headers
 input: files(d[0]),
 output: d[1],
 capture: true,
-build_by_default: true, # to be removed when added to a target
 command: [hxtool, '-h', '@INPUT0@'])
 endforeach
 genh += hxdep
@@ -3366,12 +3365,15 @@ endif
 qom_ss = qom_ss.apply(config_targetos, strict: false)
 libqom = static_library('qom', qom_ss.sources() + genh,
 dependencies: [qom_ss.dependencies()],
-name_suffix: 'fa')
+name_suffix: 'fa',
+build_by_default: false)
 qom = declare_dependency(link_whole: libqom)
 
 event_loop_base = files('event-loop-base.c')
-event_loop_base = static_library('event-loop-base', sources: event_loop_base + 
genh,
- build_by_default: true)
+event_loop_base = static_library('event-loop-base',
+ sources: event_loop_base + genh,
+ name_suffix: 'fa',
+ build_by_default: false)
 event_loop_base = declare_dependency(link_whole: event_loop_base,
  dependencies: [qom])
 
@@ -3380,6 +3382,7 @@ stub_ss = stub_ss.apply(config_all, strict: false)
 util_ss.add_all(trace_ss)
 util_ss = util_ss.apply(config_all, strict: false)
 libqemuutil = static_library('qemuutil',
+ build_by_default: false,
  sources: util_ss.sources() + stub_ss.sources() + 
genh,
  dependencies: [util_ss.dependencies(), libm, 
threads, glib, socket, malloc, pixman])
 qemuutil = declare_dependency(link_with: libqemuutil,
diff --git a/tcg/meson.build b/tcg/meson.build
index 0014dca7d4f..4be4a616caa 100644
--- a/tcg/meson.build
+++ b/tcg/meson.build
@@ -28,7 +28,7 @@ libtcg_user = static_library('tcg_user',
  tcg_ss.sources() + genh,
  name_suffix: 'fa',
  c_args: '-DCONFIG_USER_ONLY',
- build_by_default: have_user)
+ build_by_default: false)
 
 tcg_user = declare_dependency(link_with: libtcg_user,
   dependencies: tcg_ss.dependencies())
@@ -38,7 +38,7 @@ libtcg_softmmu = static_library('tcg_softmmu',
 tcg_ss.sources() + genh,
 name_suffix: 'fa',
 c_args: '-DCONFIG_SOFTMMU',
-build_by_default: have_system)
+build_by_default: false)
 
 tcg_softmmu = declare_dependency(link_with: libtcg_softmmu,
  dependencies: tcg_ss.dependencies())
-- 
2.41.0




[PULL 02/24] accel/kvm/kvm-all: Handle register access errors

2023-10-03 Thread Paolo Bonzini
From: Akihiko Odaki 

A register access error typically means something seriously wrong
happened so that anything bad can happen after that and recovery is
impossible.
Even failing one register access is catastorophic as
architecture-specific code are not written so that it torelates such
failures.

Make sure the VM stop and nothing worse happens if such an error occurs.

Signed-off-by: Akihiko Odaki 
Message-ID: <20221201102728.69751-1-akihiko.od...@daynix.com>
Signed-off-by: Paolo Bonzini 
---
 accel/kvm/kvm-all.c | 32 
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index ff1578bb32b..72e1d1141c4 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2851,7 +2851,13 @@ bool kvm_cpu_check_are_resettable(void)
 static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
 {
 if (!cpu->vcpu_dirty) {
-kvm_arch_get_registers(cpu);
+int ret = kvm_arch_get_registers(cpu);
+if (ret) {
+error_report("Failed to get registers: %s", strerror(-ret));
+cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
+vm_stop(RUN_STATE_INTERNAL_ERROR);
+}
+
 cpu->vcpu_dirty = true;
 }
 }
@@ -2865,7 +2871,13 @@ void kvm_cpu_synchronize_state(CPUState *cpu)
 
 static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data 
arg)
 {
-kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
+int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
+if (ret) {
+error_report("Failed to put registers after reset: %s", 
strerror(-ret));
+cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
+vm_stop(RUN_STATE_INTERNAL_ERROR);
+}
+
 cpu->vcpu_dirty = false;
 }
 
@@ -2876,7 +2888,12 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu)
 
 static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data 
arg)
 {
-kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
+int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
+if (ret) {
+error_report("Failed to put registers after init: %s", strerror(-ret));
+exit(1);
+}
+
 cpu->vcpu_dirty = false;
 }
 
@@ -2969,7 +2986,14 @@ int kvm_cpu_exec(CPUState *cpu)
 MemTxAttrs attrs;
 
 if (cpu->vcpu_dirty) {
-kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
+ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
+if (ret) {
+error_report("Failed to put registers after init: %s",
+ strerror(-ret));
+ret = -1;
+break;
+}
+
 cpu->vcpu_dirty = false;
 }
 
-- 
2.41.0




[PULL 11/24] crypto: only include tls-cipher-suites in emulators

2023-10-03 Thread Paolo Bonzini
tls-cipher-suites is an object that is used to inject TLS configuration
into the guest (via fw_cfg).  It is never used for host-side TLS
operation, and therefore it need not be available in the tools.

Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Paolo Bonzini 
---
 crypto/meson.build   | 3 ++-
 hw/nvram/meson.build | 6 +-
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/crypto/meson.build b/crypto/meson.build
index 9ac1a898027..c46f9c22a7f 100644
--- a/crypto/meson.build
+++ b/crypto/meson.build
@@ -46,7 +46,8 @@ endif
 if have_afalg
   crypto_ss.add(if_true: files('afalg.c', 'cipher-afalg.c', 'hash-afalg.c'))
 endif
-crypto_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c'))
+
+system_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c'))
 
 util_ss.add(files(
   'aes.c',
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
index 988dff6f8e5..75e415b1a01 100644
--- a/hw/nvram/meson.build
+++ b/hw/nvram/meson.build
@@ -1,8 +1,4 @@
-if have_system or have_tools
-  # QOM interfaces must be available anytime QOM is used.
-  qom_ss.add(files('fw_cfg-interface.c'))
-endif
-
+system_ss.add(files('fw_cfg-interface.c'))
 system_ss.add(files('fw_cfg.c'))
 system_ss.add(when: 'CONFIG_CHRP_NVRAM', if_true: files('chrp_nvram.c'))
 system_ss.add(when: 'CONFIG_DS1225Y', if_true: files('ds1225y.c'))
-- 
2.41.0




[PULL 14/24] audio: allow returning an error from the driver init

2023-10-03 Thread Paolo Bonzini
An error is already printed by audio_driver_init, but we can make
it more precise if the driver can return an Error *.

Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Paolo Bonzini 
---
 audio/alsaaudio.c   |  2 +-
 audio/audio.c   | 13 ++---
 audio/audio_int.h   |  2 +-
 audio/coreaudio.m   |  2 +-
 audio/dbusaudio.c   |  2 +-
 audio/dsoundaudio.c |  2 +-
 audio/jackaudio.c   |  2 +-
 audio/noaudio.c |  2 +-
 audio/ossaudio.c| 11 ---
 audio/paaudio.c |  7 +--
 audio/pwaudio.c | 16 +---
 audio/sdlaudio.c|  5 +++--
 audio/sndioaudio.c  |  2 +-
 audio/spiceaudio.c  |  5 -
 audio/wavaudio.c|  2 +-
 15 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 057571dd1e0..6fb78e5b972 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -904,7 +904,7 @@ static void 
alsa_init_per_direction(AudiodevAlsaPerDirectionOptions *apdo)
 }
 }
 
-static void *alsa_audio_init(Audiodev *dev)
+static void *alsa_audio_init(Audiodev *dev, Error **errp)
 {
 AudiodevAlsaOptions *aopts;
 assert(dev->driver == AUDIODEV_DRIVER_ALSA);
diff --git a/audio/audio.c b/audio/audio.c
index d4387cb3e21..fdc34a77520 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -33,6 +33,7 @@
 #include "qapi/qapi-visit-audio.h"
 #include "qapi/qapi-commands-audio.h"
 #include "qemu/cutils.h"
+#include "qemu/error-report.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "qemu/help_option.h"
@@ -1555,7 +1556,9 @@ size_t audio_generic_read(HWVoiceIn *hw, void *buf, 
size_t size)
 static int audio_driver_init(AudioState *s, struct audio_driver *drv,
  bool msg, Audiodev *dev)
 {
-s->drv_opaque = drv->init(dev);
+Error *local_err = NULL;
+
+s->drv_opaque = drv->init(dev, &local_err);
 
 if (s->drv_opaque) {
 if (!drv->pcm_ops->get_buffer_in) {
@@ -1572,8 +1575,12 @@ static int audio_driver_init(AudioState *s, struct 
audio_driver *drv,
 s->drv = drv;
 return 0;
 } else {
-if (msg) {
-dolog("Could not init `%s' audio driver\n", drv->name);
+if (!msg) {
+error_free(local_err);
+} else if (local_err) {
+error_report_err(local_err);
+} else {
+error_report("Could not init `%s' audio driver", drv->name);
 }
 return -1;
 }
diff --git a/audio/audio_int.h b/audio/audio_int.h
index e57ff50155a..06e815de9f6 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -140,7 +140,7 @@ typedef struct audio_driver audio_driver;
 struct audio_driver {
 const char *name;
 const char *descr;
-void *(*init) (Audiodev *);
+void *(*init) (Audiodev *, Error **);
 void (*fini) (void *);
 #ifdef CONFIG_GIO
 void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager, 
bool p2p);
diff --git a/audio/coreaudio.m b/audio/coreaudio.m
index 4695291621a..7cfb38fb6ae 100644
--- a/audio/coreaudio.m
+++ b/audio/coreaudio.m
@@ -644,7 +644,7 @@ static void coreaudio_enable_out(HWVoiceOut *hw, bool 
enable)
 update_device_playback_state(core);
 }
 
-static void *coreaudio_audio_init(Audiodev *dev)
+static void *coreaudio_audio_init(Audiodev *dev, Error **errp)
 {
 return dev;
 }
diff --git a/audio/dbusaudio.c b/audio/dbusaudio.c
index 7a11fbfb420..310ca997ff4 100644
--- a/audio/dbusaudio.c
+++ b/audio/dbusaudio.c
@@ -395,7 +395,7 @@ dbus_enable_in(HWVoiceIn *hw, bool enable)
 }
 
 static void *
-dbus_audio_init(Audiodev *dev)
+dbus_audio_init(Audiodev *dev, Error **errp)
 {
 DBusAudio *da = g_new0(DBusAudio, 1);
 
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index 3fb67ec3eed..eefde88edcb 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -619,7 +619,7 @@ static void dsound_audio_fini (void *opaque)
 g_free(s);
 }
 
-static void *dsound_audio_init(Audiodev *dev)
+static void *dsound_audio_init(Audiodev *dev, Error **errp)
 {
 int err;
 HRESULT hr;
diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index e1eaa3477dc..823e7d96bae 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -645,7 +645,7 @@ static int qjack_thread_creator(jack_native_thread_t 
*thread,
 }
 #endif
 
-static void *qjack_init(Audiodev *dev)
+static void *qjack_init(Audiodev *dev, Error **errp)
 {
 assert(dev->driver == AUDIODEV_DRIVER_JACK);
 return dev;
diff --git a/audio/noaudio.c b/audio/noaudio.c
index 4fdee5adecf..a36bfeffd14 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -104,7 +104,7 @@ static void no_enable_in(HWVoiceIn *hw, bool enable)
 }
 }
 
-static void *no_audio_init(Audiodev *dev)
+static void *no_audio_init(Audiodev *dev, Error **errp)
 {
 return &no_audio_init;
 }
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index e8d732b612c..ec4448d573d 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -28,6 +28,7 @@
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
 #include "qemu/host-util

[PULL 03/24] e1000: remove old compatibility code

2023-10-03 Thread Paolo Bonzini
This code is not needed anymore in the supported machine types.

Signed-off-by: Paolo Bonzini 
---
 hw/net/e1000.c | 79 +-
 1 file changed, 27 insertions(+), 52 deletions(-)

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 093c2d45315..548bcabcbba 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -127,13 +127,9 @@ struct E1000State_st {
 QEMUTimer *flush_queue_timer;
 
 /* Compatibility flags for migration to/from qemu 1.3.0 and older */
-#define E1000_FLAG_AUTONEG_BIT 0
-#define E1000_FLAG_MIT_BIT 1
 #define E1000_FLAG_MAC_BIT 2
 #define E1000_FLAG_TSO_BIT 3
 #define E1000_FLAG_VET_BIT 4
-#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
-#define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT)
 #define E1000_FLAG_MAC (1 << E1000_FLAG_MAC_BIT)
 #define E1000_FLAG_TSO (1 << E1000_FLAG_TSO_BIT)
 #define E1000_FLAG_VET (1 << E1000_FLAG_VET_BIT)
@@ -180,7 +176,7 @@ e1000_autoneg_done(E1000State *s)
 static bool
 have_autoneg(E1000State *s)
 {
-return chkflag(AUTONEG) && (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN);
+return (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN);
 }
 
 static void
@@ -308,35 +304,34 @@ set_interrupt_cause(E1000State *s, int index, uint32_t 
val)
 if (s->mit_timer_on) {
 return;
 }
-if (chkflag(MIT)) {
-/* Compute the next mitigation delay according to pending
- * interrupts and the current values of RADV (provided
- * RDTR!=0), TADV and ITR.
- * Then rearm the timer.
- */
-mit_delay = 0;
-if (s->mit_ide &&
-(pending_ints & (E1000_ICR_TXQE | E1000_ICR_TXDW))) {
-mit_update_delay(&mit_delay, s->mac_reg[TADV] * 4);
-}
-if (s->mac_reg[RDTR] && (pending_ints & E1000_ICS_RXT0)) {
-mit_update_delay(&mit_delay, s->mac_reg[RADV] * 4);
-}
-mit_update_delay(&mit_delay, s->mac_reg[ITR]);
 
-/*
- * According to e1000 SPEC, the Ethernet controller guarantees
- * a maximum observable interrupt rate of 7813 interrupts/sec.
- * Thus if mit_delay < 500 then the delay should be set to the
- * minimum delay possible which is 500.
- */
-mit_delay = (mit_delay < 500) ? 500 : mit_delay;
-
-s->mit_timer_on = 1;
-timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-  mit_delay * 256);
-s->mit_ide = 0;
+/* Compute the next mitigation delay according to pending
+ * interrupts and the current values of RADV (provided
+ * RDTR!=0), TADV and ITR.
+ * Then rearm the timer.
+ */
+mit_delay = 0;
+if (s->mit_ide &&
+(pending_ints & (E1000_ICR_TXQE | E1000_ICR_TXDW))) {
+mit_update_delay(&mit_delay, s->mac_reg[TADV] * 4);
 }
+if (s->mac_reg[RDTR] && (pending_ints & E1000_ICS_RXT0)) {
+mit_update_delay(&mit_delay, s->mac_reg[RADV] * 4);
+}
+mit_update_delay(&mit_delay, s->mac_reg[ITR]);
+
+/*
+ * According to e1000 SPEC, the Ethernet controller guarantees
+ * a maximum observable interrupt rate of 7813 interrupts/sec.
+ * Thus if mit_delay < 500 then the delay should be set to the
+ * minimum delay possible which is 500.
+ */
+mit_delay = (mit_delay < 500) ? 500 : mit_delay;
+
+s->mit_timer_on = 1;
+timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+  mit_delay * 256);
+s->mit_ide = 0;
 }
 
 s->mit_irq_level = (pending_ints != 0);
@@ -1223,9 +1218,6 @@ enum { MAC_ACCESS_PARTIAL = 1, MAC_ACCESS_FLAG_NEEDED = 2 
};
  * n - flag needed
  * p - partially implenented */
 static const uint8_t mac_reg_access[0x8000] = {
-[RDTR]= markflag(MIT),[TADV]= markflag(MIT),
-[RADV]= markflag(MIT),[ITR] = markflag(MIT),
-
 [IPAV]= markflag(MAC),[WUC] = markflag(MAC),
 [IP6AT]   = markflag(MAC),[IP4AT]   = markflag(MAC),
 [FFVT]= markflag(MAC),[WUPM]= markflag(MAC),
@@ -1394,11 +1386,6 @@ static int e1000_post_load(void *opaque, int version_id)
 E1000State *s = opaque;
 NetClientState *nc = qemu_get_queue(s->nic);
 
-if (!chkflag(MIT)) {
-s->mac_reg[ITR] = s->mac_reg[RDTR] = s->mac_reg[RADV] =
-s->mac_reg[TADV] = 0;
-s->mit_irq_level = false;
-}
 s->mit_ide = 0;
 s->mit_timer_on = true;
 timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1);
@@ -1432,13 +1419,6 @@ static int e1000_tx_tso_post_load(void *opaque, int 
version_id)
 return 0;
 }
 
-static bool e1000_mit_state_needed(void *opaque)
-{
-E1000State *s = opaque;
-
-return chkflag(MIT);
-}
-
 static bool e1000_full_mac_needed(void *opaque)
 {
 E1000State *s = opaque;
@

[PULL 17/24] audio: simplify flow in audio_init

2023-10-03 Thread Paolo Bonzini
Merge two ifs into one.

Signed-off-by: Paolo Bonzini 
---
 audio/audio.c | 76 +--
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index bb1734a95d3..2e22664daf9 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1707,12 +1707,12 @@ static AudiodevListEntry *audiodev_find(
  * if dev == NULL => legacy implicit initialization, return the already created
  *   state or create a new one
  */
-static AudioState *audio_init(Audiodev *dev, const char *name)
+static AudioState *audio_init(Audiodev *dev)
 {
 static bool atexit_registered;
 size_t i;
 int done = 0;
-const char *drvname = NULL;
+const char *drvname;
 VMChangeStateEntry *vmse;
 AudioState *s;
 struct audio_driver *driver;
@@ -1736,17 +1736,32 @@ static AudioState *audio_init(Audiodev *dev, const char 
*name)
 }
 }
 
+s = g_new0(AudioState, 1);
+
+QLIST_INIT (&s->hw_head_out);
+QLIST_INIT (&s->hw_head_in);
+QLIST_INIT (&s->cap_head);
+if (!atexit_registered) {
+atexit(audio_cleanup);
+atexit_registered = true;
+}
+
+s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
+
 if (dev) {
 /* -audiodev option */
-legacy_config = false;
+s->dev = dev;
 drvname = AudiodevDriver_str(dev->driver);
-} else if (!QTAILQ_EMPTY(&audio_states)) {
-if (!legacy_config) {
-dolog("Device %s: audiodev default parameter is deprecated, please 
"
-  "specify audiodev=%s\n", name,
-  QTAILQ_FIRST(&audio_states)->dev->id);
+driver = audio_driver_lookup(drvname);
+if (driver) {
+done = !audio_driver_init(s, driver, true, dev);
+} else {
+dolog ("Unknown audio driver `%s'\n", drvname);
+}
+if (!done) {
+free_audio_state(s);
+return NULL;
 }
-return QTAILQ_FIRST(&audio_states);
 } else {
 /* legacy implicit initialization */
 head = audio_handle_legacy_opts();
@@ -1759,33 +1774,7 @@ static AudioState *audio_init(Audiodev *dev, const char 
*name)
  */
 dev = QSIMPLEQ_FIRST(&head)->dev;
 audio_validate_opts(dev, &error_abort);
-}
 
-s = g_new0(AudioState, 1);
-s->dev = dev;
-
-QLIST_INIT (&s->hw_head_out);
-QLIST_INIT (&s->hw_head_in);
-QLIST_INIT (&s->cap_head);
-if (!atexit_registered) {
-atexit(audio_cleanup);
-atexit_registered = true;
-}
-
-s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
-
-if (drvname) {
-driver = audio_driver_lookup(drvname);
-if (driver) {
-done = !audio_driver_init(s, driver, true, dev);
-} else {
-dolog ("Unknown audio driver `%s'\n", drvname);
-}
-if (!done) {
-free_audio_state(s);
-return NULL;
-}
-} else {
 for (i = 0; audio_prio_list[i]; i++) {
 AudiodevListEntry *e = audiodev_find(&head, audio_prio_list[i]);
 driver = audio_driver_lookup(audio_prio_list[i]);
@@ -1800,8 +1789,9 @@ static AudioState *audio_init(Audiodev *dev, const char 
*name)
 }
 }
 }
+
+audio_free_audiodev_list(&head);
 }
-audio_free_audiodev_list(&head);
 
 if (!done) {
 driver = audio_driver_lookup("none");
@@ -1841,7 +1831,16 @@ void audio_free_audiodev_list(AudiodevListHead *head)
 void AUD_register_card (const char *name, QEMUSoundCard *card)
 {
 if (!card->state) {
-card->state = audio_init(NULL, name);
+if (!QTAILQ_EMPTY(&audio_states)) {
+if (!legacy_config) {
+dolog("Device %s: audiodev default parameter is deprecated, 
please "
+  "specify audiodev=%s\n", name,
+  QTAILQ_FIRST(&audio_states)->dev->id);
+}
+card->state = QTAILQ_FIRST(&audio_states);
+} else {
+card->state = audio_init(NULL);
+}
 }
 
 card->name = g_strdup (name);
@@ -2171,6 +2170,7 @@ void audio_define(Audiodev *dev)
 e = g_new0(AudiodevListEntry, 1);
 e->dev = dev;
 QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next);
+legacy_config = false;
 }
 
 bool audio_init_audiodevs(void)
@@ -2178,7 +2178,7 @@ bool audio_init_audiodevs(void)
 AudiodevListEntry *e;
 
 QSIMPLEQ_FOREACH(e, &audiodevs, next) {
-if (!audio_init(e->dev, NULL)) {
+if (!audio_init(e->dev)) {
 return false;
 }
 }
-- 
2.41.0




[PULL 18/24] audio: remove QEMU_AUDIO_* and -audio-help support

2023-10-03 Thread Paolo Bonzini
These have been deprecated for a long time, and the introduction of
-audio in 7.1.0 has cemented the new way of specifying an audio backend's
parameters.  However, there is still a need for simple configuration
of the audio backend in the desktop case; therefore, if no audiodev is
passed to audio_init(), go through a bunch of simple Audiodev* structures
and pick the first that can be initialized successfully.

The only QEMU_AUDIO_* option that is left in, waiting for a better idea,
is QEMU_AUDIO_DRV=none which is used by qtest.

Remove all the parsing code, including the concept of "can_be_default"
audio drivers: now that audio_prio_list[] is only used in a single place,
wav can be excluded directly in that function.

Signed-off-by: Paolo Bonzini 
---
 audio/alsaaudio.c   |   1 -
 audio/audio.c   | 138 
 audio/audio.h   |   1 -
 audio/audio_int.h   |   5 -
 audio/audio_legacy.c| 591 
 audio/coreaudio.m   |   1 -
 audio/dbusaudio.c   |   1 -
 audio/dsoundaudio.c |   1 -
 audio/jackaudio.c   |   1 -
 audio/meson.build   |   1 -
 audio/noaudio.c |   1 -
 audio/ossaudio.c|   1 -
 audio/paaudio.c |   1 -
 audio/pwaudio.c |   1 -
 audio/sdlaudio.c|   1 -
 audio/sndioaudio.c  |   1 -
 audio/wavaudio.c|   1 -
 docs/about/deprecated.rst   |   8 -
 docs/about/removed-features.rst |   6 +
 qemu-options.hx |  10 -
 softmmu/vl.c|   4 -
 21 files changed, 65 insertions(+), 711 deletions(-)
 delete mode 100644 audio/audio_legacy.c

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 6fb78e5b972..cacae1ea59c 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -960,7 +960,6 @@ static struct audio_driver alsa_audio_driver = {
 .init   = alsa_audio_init,
 .fini   = alsa_audio_fini,
 .pcm_ops= &alsa_pcm_ops,
-.can_be_default = 1,
 .max_voices_out = INT_MAX,
 .max_voices_in  = INT_MAX,
 .voice_size_out = sizeof (ALSAVoiceOut),
diff --git a/audio/audio.c b/audio/audio.c
index 2e22664daf9..818d79e50f0 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -32,6 +32,7 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qapi-visit-audio.h"
 #include "qapi/qapi-commands-audio.h"
+#include "qapi/qmp/qdict.h"
 #include "qemu/cutils.h"
 #include "qemu/error-report.h"
 #include "qemu/log.h"
@@ -62,19 +63,22 @@ const char *audio_prio_list[] = {
 "spice",
 CONFIG_AUDIO_DRIVERS
 "none",
-"wav",
 NULL
 };
 
 static QLIST_HEAD(, audio_driver) audio_drivers;
-static AudiodevListHead audiodevs = QSIMPLEQ_HEAD_INITIALIZER(audiodevs);
+static AudiodevListHead audiodevs =
+QSIMPLEQ_HEAD_INITIALIZER(audiodevs);
+static AudiodevListHead default_audiodevs =
+QSIMPLEQ_HEAD_INITIALIZER(default_audiodevs);
+
 
 void audio_driver_register(audio_driver *drv)
 {
 QLIST_INSERT_HEAD(&audio_drivers, drv, next);
 }
 
-audio_driver *audio_driver_lookup(const char *name)
+static audio_driver *audio_driver_lookup(const char *name)
 {
 struct audio_driver *d;
 Error *local_err = NULL;
@@ -112,8 +116,6 @@ const struct mixeng_volume nominal_volume = {
 #endif
 };
 
-static bool legacy_config = true;
-
 int audio_bug (const char *funcname, int cond)
 {
 if (cond) {
@@ -1688,17 +1690,41 @@ static const VMStateDescription vmstate_audio = {
 
 static void audio_validate_opts(Audiodev *dev, Error **errp);
 
-static AudiodevListEntry *audiodev_find(
-AudiodevListHead *head, const char *drvname)
+static void audio_create_default_audiodevs(void)
 {
-AudiodevListEntry *e;
-QSIMPLEQ_FOREACH(e, head, next) {
-if (strcmp(AudiodevDriver_str(e->dev->driver), drvname) == 0) {
-return e;
-}
+const char *drvname = getenv("QEMU_AUDIO_DRV");
+
+/* QEMU_AUDIO_DRV=none is used by libqtest.  */
+if (drvname && !g_str_equal(drvname, "none")) {
+error_report("Please use -audiodev instead of QEMU_AUDIO_*");
+exit(1);
 }
 
-return NULL;
+for (int i = 0; audio_prio_list[i]; i++) {
+if (drvname && !g_str_equal(drvname, audio_prio_list[i])) {
+continue;
+}
+
+if (audio_driver_lookup(audio_prio_list[i])) {
+QDict *dict = qdict_new();
+Audiodev *dev = NULL;
+AudiodevListEntry *e;
+Visitor *v;
+
+qdict_put_str(dict, "driver", audio_prio_list[i]);
+qdict_put_str(dict, "id", "#default");
+
+v = qobject_input_visitor_new_keyval(QOBJECT(dict));
+qobject_unref(dict);
+visit_type_Audiodev(v, NULL, &dev, &error_fatal);
+visit_free(v);
+
+audio_validate_opts(dev, &error_abort);
+e = g_new0(AudiodevListEntry, 1);
+e->de

[PULL 07/24] Makefile: build plugins before running TCG tests

2023-10-03 Thread Paolo Bonzini
Add back test-plugins and, after making sure it is always defined,
do so unconditionally.

Reported-by: Alex Bennée 
Fixes: 2c13c574418 ("configure, meson: move --enable-plugins to meson", 
2023-09-07)
Reviewed-by: Alex Bennée 
Tested-by: Alex Bennée 
Signed-off-by: Paolo Bonzini 
---
 tests/Makefile.include   |  2 +-
 tests/meson.build|  5 +
 tests/plugin/meson.build | 18 --
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 38987426594..dab1989a071 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -73,7 +73,7 @@ $(TCG_TESTS_TARGETS:%=distclean-tcg-tests-%): 
distclean-tcg-tests-%:
 build-tcg: $(BUILD_TCG_TARGET_RULES)
 
 .PHONY: check-tcg
-.ninja-goals.check-tcg = all
+.ninja-goals.check-tcg = all test-plugins
 check-tcg: $(RUN_TCG_TARGET_RULES)
 
 .PHONY: clean-tcg
diff --git a/tests/meson.build b/tests/meson.build
index debaa4505eb..9996a293fbb 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -80,10 +80,7 @@ if 'CONFIG_TCG' in config_all
   subdir('fp')
 endif
 
-if get_option('plugins')
-  subdir('plugin')
-endif
-
+subdir('plugin')
 subdir('unit')
 subdir('qapi-schema')
 subdir('qtest')
diff --git a/tests/plugin/meson.build b/tests/plugin/meson.build
index 2bbfc4b19e1..322cafcdf6b 100644
--- a/tests/plugin/meson.build
+++ b/tests/plugin/meson.build
@@ -1,7 +1,13 @@
 t = []
-foreach i : ['bb', 'empty', 'insn', 'mem', 'syscall']
-  t += shared_module(i, files(i + '.c'),
- include_directories: '../../include/qemu',
- dependencies: glib)
-endforeach
-alias_target('test-plugins', t)
+if get_option('plugins')
+  foreach i : ['bb', 'empty', 'insn', 'mem', 'syscall']
+t += shared_module(i, files(i + '.c'),
+   include_directories: '../../include/qemu',
+   dependencies: glib)
+  endforeach
+endif
+if t.length() > 0
+  alias_target('test-plugins', t)
+else
+  run_target('test-plugins', command: find_program('true'))
+endif
-- 
2.41.0




[PULL 12/24] ui/vnc: Require audiodev= to enable audio

2023-10-03 Thread Paolo Bonzini
If there is no audiodev do not send the audio ack in response to
VNC_ENCODING_AUDIO, so that clients aren't told audio exists, and
immediately drop the client if they try to send any audio control messages
when audio is not advertised.

Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Paolo Bonzini 
---
 docs/about/deprecated.rst   |  8 +++-
 docs/about/removed-features.rst |  6 ++
 ui/vnc.c| 11 ++-
 ui/vnc.h|  2 ++
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 8f3fef97bd4..c07bf58dde1 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -45,13 +45,11 @@ backend settings instead of environment variables.  To ease 
migration to
 the new format, the ``-audiodev-help`` option can be used to convert
 the current values of the environment variables to ``-audiodev`` options.
 
-Creating sound card devices and vnc without ``audiodev=`` property (since 4.2)
-''
+Creating sound card devices without ``audiodev=`` property (since 4.2)
+''
 
 When not using the deprecated legacy audio config, each sound card
-should specify an ``audiodev=`` property.  Additionally, when using
-vnc, you should specify an ``audiodev=`` property if you plan to
-transmit audio through the VNC protocol.
+should specify an ``audiodev=`` property.
 
 Short-form boolean options (since 6.0)
 ''
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
index 97ec47f1d25..276060b320c 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -436,6 +436,12 @@ the process listing. This was replaced by the new 
``password-secret``
 option which lets the password be securely provided on the command
 line using a ``secret`` object instance.
 
+Creating vnc without ``audiodev=`` property (removed in 8.2)
+
+
+When using vnc, you should specify an ``audiodev=`` property if
+you plan to transmit audio through the VNC protocol.
+
 QEMU Machine Protocol (QMP) commands
 
 
diff --git a/ui/vnc.c b/ui/vnc.c
index c302bb07a5b..acb56461b2d 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2195,7 +2195,10 @@ static void set_encodings(VncState *vs, int32_t 
*encodings, size_t n_encodings)
 send_ext_key_event_ack(vs);
 break;
 case VNC_ENCODING_AUDIO:
-send_ext_audio_ack(vs);
+if (vs->vd->audio_state) {
+vs->features |= VNC_FEATURE_AUDIO_MASK;
+send_ext_audio_ack(vs);
+}
 break;
 case VNC_ENCODING_WMVi:
 vs->features |= VNC_FEATURE_WMVI_MASK;
@@ -2502,6 +2505,12 @@ static int protocol_client_msg(VncState *vs, uint8_t 
*data, size_t len)
   read_u32(data, 4), read_u32(data, 8));
 break;
 case VNC_MSG_CLIENT_QEMU_AUDIO:
+if (!vnc_has_feature(vs, VNC_FEATURE_AUDIO)) {
+error_report("Audio message %d with audio disabled", 
read_u8(data, 2));
+vnc_client_error(vs);
+break;
+}
+
 if (len == 2)
 return 4;
 
diff --git a/ui/vnc.h b/ui/vnc.h
index 757fa83044e..96d19dce199 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -464,6 +464,7 @@ enum VncFeatures {
 VNC_FEATURE_LED_STATE,
 VNC_FEATURE_XVP,
 VNC_FEATURE_CLIPBOARD_EXT,
+VNC_FEATURE_AUDIO,
 };
 
 #define VNC_FEATURE_RESIZE_MASK  (1 << VNC_FEATURE_RESIZE)
@@ -481,6 +482,7 @@ enum VncFeatures {
 #define VNC_FEATURE_LED_STATE_MASK   (1 << VNC_FEATURE_LED_STATE)
 #define VNC_FEATURE_XVP_MASK (1 << VNC_FEATURE_XVP)
 #define VNC_FEATURE_CLIPBOARD_EXT_MASK   (1 <<  VNC_FEATURE_CLIPBOARD_EXT)
+#define VNC_FEATURE_AUDIO_MASK   (1 <<  VNC_FEATURE_AUDIO)
 
 
 /* Client -> Server message IDs */
-- 
2.41.0




[PULL 13/24] audio: Require AudioState in AUD_add_capture

2023-10-03 Thread Paolo Bonzini
From: Martin Kletzander 

Since all callers require a valid audiodev this function can now safely
abort in case of missing AudioState.

Signed-off-by: Martin Kletzander 
Message-ID: 

Signed-off-by: Paolo Bonzini 
---
 audio/audio.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 2f479657117..d4387cb3e21 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1876,10 +1876,8 @@ CaptureVoiceOut *AUD_add_capture(
 struct capture_callback *cb;
 
 if (!s) {
-if (!legacy_config) {
-dolog("Capturing without setting an audiodev is deprecated\n");
-}
-s = audio_init(NULL, NULL);
+error_report("Capturing without setting an audiodev is not supported");
+abort();
 }
 
 if (!audio_get_pdo_out(s->dev)->mixing_engine) {
-- 
2.41.0




[PULL 00/24] Audio, build system, misc fixes for 2023-10-03

2023-10-03 Thread Paolo Bonzini
The following changes since commit 36e9aab3c569d4c9ad780473596e18479838d1aa:

  migration: Move return path cleanup to main migration thread (2023-09-27 
13:58:02 -0400)

are available in the Git repository at:

  https://gitlab.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 9f8cf356723702272af124e621e4c0e9805c8e22:

  audio: forbid default audiodev backend with -nodefaults (2023-10-03 10:29:40 
+0200)


* fix from optionrom build
* fix for KVM on Apple M2
* introduce machine property "audiodev"
* ui/vnc: Require audiodev= to enable audio
* audio: remove QEMU_AUDIO_* and -audio-help support
* audio: forbid using default audiodev backend with -audiodev and -nodefaults
* remove compatibility code for old machine types
* make-release: do not ship dtc sources
* build system cleanups


Akihiko Odaki (1):
  accel/kvm/kvm-all: Handle register access errors

Fabiano Rosas (1):
  optionrom: Remove build-id section

Mark Cave-Ayland (3):
  esp: use correct type for esp_dma_enable() in sysbus_esp_gpio_demux()
  esp: restrict non-DMA transfer length to that of available data
  scsi-disk: ensure that FORMAT UNIT commands are terminated

Martin Kletzander (5):
  audio: Require AudioState in AUD_add_capture
  Introduce machine property "audiodev"
  hw/arm: Support machine-default audiodev with fallback
  hw/ppc: Support machine-default audiodev with fallback
  audio: propagate Error * out of audio_init

Paolo Bonzini (14):
  e1000: remove old compatibility code
  pc: remove short_root_bus property
  make-release: do not ship dtc sources
  meson: clean up static_library keyword arguments
  Makefile: build plugins before running TCG tests
  crypto: only include tls-cipher-suites in emulators
  ui/vnc: Require audiodev= to enable audio
  audio: allow returning an error from the driver init
  audio: return Error ** from audio_state_by_name
  audio: commonize voice initialization
  audio: simplify flow in audio_init
  audio: remove QEMU_AUDIO_* and -audio-help support
  vt82c686 machines: Support machine-default audiodev with fallback
  audio: forbid default audiodev backend with -nodefaults

 accel/kvm/kvm-all.c  |  32 ++-
 audio/alsaaudio.c|   3 +-
 audio/audio-hmp-cmds.c   |   6 +-
 audio/audio.c| 246 
 audio/audio.h|   7 +-
 audio/audio_int.h|   7 +-
 audio/audio_legacy.c | 591 ---
 audio/audio_template.h   |   9 +-
 audio/coreaudio.m|   3 +-
 audio/dbusaudio.c|   3 +-
 audio/dsoundaudio.c  |   3 +-
 audio/jackaudio.c|   3 +-
 audio/meson.build|   1 -
 audio/noaudio.c  |   3 +-
 audio/ossaudio.c |  12 +-
 audio/paaudio.c  |   8 +-
 audio/pwaudio.c  |  17 +-
 audio/sdlaudio.c |   6 +-
 audio/sndioaudio.c   |   3 +-
 audio/spiceaudio.c   |   5 +-
 audio/wavaudio.c |   3 +-
 crypto/meson.build   |   3 +-
 docs/about/deprecated.rst|  16 +-
 docs/about/removed-features.rst  |  12 +
 gdbstub/meson.build  |   4 +-
 hw/arm/integratorcp.c|  11 +-
 hw/arm/musicpal.c|  11 +-
 hw/arm/nseries.c |   4 +
 hw/arm/omap2.c   |   7 +-
 hw/arm/palm.c|   2 +
 hw/arm/realview.c|  12 +
 hw/arm/spitz.c   |  17 +-
 hw/arm/versatilepb.c |   8 +
 hw/arm/vexpress.c|   5 +
 hw/arm/xlnx-zcu102.c |   6 +
 hw/arm/z2.c  |  15 +-
 hw/audio/ac97.c  |   6 +-
 hw/audio/adlib.c |   6 +-
 hw/audio/cs4231a.c   |   6 +-
 hw/audio/es1370.c|   5 +-
 hw/audio/gus.c   |   6 +-
 hw/audio/hda-codec.c |   5 +-
 hw/audio/lm4549.c|   8 +-
 hw/audio/pcspk.c |   4 +-
 hw/audio/sb16.c  |   6 +-
 hw/audio/via-ac97.c  |   6 +-
 hw/audio/wm8750.c|   5 +-
 hw/core/machine.c|  33 +++
 hw/core/qdev-properties-system.c |  16 +-
 hw/display/xlnx_dp.c |   6 +-
 hw/input/tsc210x.c   |   7 +-
 hw/mips/fuloong2e.c  |  15 +-
 hw/net/e1000.c   |  79 ++
 hw/nvram/meson.build |   6 +-
 hw/pci-host/i440fx.c |   8 -
 hw/pci-host/q35.c|   7 -
 hw/ppc/pegasos2.c|  12 +-
 hw/ppc/prep.c|   7 +
 hw/scsi/esp.c|   5 +-
 hw/scsi/scsi-disk.c  |   4 +
 hw/usb/dev-audi

[PULL 21/24] hw/ppc: Support machine-default audiodev with fallback

2023-10-03 Thread Paolo Bonzini
From: Martin Kletzander 

Signed-off-by: Martin Kletzander 
Signed-off-by: Paolo Bonzini 
---
 hw/ppc/prep.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f6fd35fcb9e..137276bcb92 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -45,6 +45,7 @@
 #include "trace.h"
 #include "elf.h"
 #include "qemu/units.h"
+#include "audio/audio.h"
 
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
@@ -310,6 +311,10 @@ static void ibm_40p_init(MachineState *machine)
 dev = DEVICE(isa_dev);
 qdev_prop_set_uint32(dev, "iobase", 0x830);
 qdev_prop_set_uint32(dev, "irq", 10);
+
+if (machine->audiodev) {
+qdev_prop_set_string(dev, "audiodev", machine->audiodev);
+}
 isa_realize_and_unref(isa_dev, isa_bus, &error_fatal);
 
 isa_dev = isa_new("pc87312");
@@ -426,6 +431,8 @@ static void ibm_40p_machine_init(MachineClass *mc)
 mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("604");
 mc->default_display = "std";
 mc->default_nic = "pcnet";
+
+machine_add_audiodev_property(mc);
 }
 
 DEFINE_MACHINE("40p", ibm_40p_machine_init)
-- 
2.41.0




[PULL 09/24] esp: restrict non-DMA transfer length to that of available data

2023-10-03 Thread Paolo Bonzini
From: Mark Cave-Ayland 

In the case where a SCSI layer transfer is incorrectly terminated, it is
possible for a TI command to cause a SCSI buffer overflow due to the
expected transfer data length being less than the available data in the
FIFO. When this occurs the unsigned async_len variable underflows and
becomes a large offset which writes past the end of the allocated SCSI
buffer.

Restrict the non-DMA transfer length to be the smallest of the expected
transfer length and the available FIFO data to ensure that it is no longer
possible for the SCSI buffer overflow to occur.

Signed-off-by: Mark Cave-Ayland 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1810
Reviewed-by: Thomas Huth 
Message-ID: <20230913204410.65650-3-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Paolo Bonzini 
---
 hw/scsi/esp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 4218a6a9605..9b11d8c5738 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -759,7 +759,8 @@ static void esp_do_nodma(ESPState *s)
 }
 
 if (to_device) {
-len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ);
+len = MIN(s->async_len, ESP_FIFO_SZ);
+len = MIN(len, fifo8_num_used(&s->fifo));
 esp_fifo_pop_buf(&s->fifo, s->async_buf, len);
 s->async_buf += len;
 s->async_len -= len;
-- 
2.41.0




[PULL 10/24] scsi-disk: ensure that FORMAT UNIT commands are terminated

2023-10-03 Thread Paolo Bonzini
From: Mark Cave-Ayland 

Otherwise when a FORMAT UNIT command is issued, the SCSI layer can become
confused because it can find itself in the situation where it thinks there
is still data to be transferred which can cause the next emulated SCSI
command to fail.

Signed-off-by: Mark Cave-Ayland 
Fixes: 6ab71761 ("scsi-disk: add FORMAT UNIT command")
Tested-by: Thomas Huth 
Message-ID: <20230913204410.65650-4-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Paolo Bonzini 
---
 hw/scsi/scsi-disk.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 477ee2bcd47..6691f5edb84 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1959,6 +1959,10 @@ static void scsi_disk_emulate_write_data(SCSIRequest 
*req)
 scsi_disk_emulate_write_same(r, r->iov.iov_base);
 break;
 
+case FORMAT_UNIT:
+scsi_req_complete(&r->req, GOOD);
+break;
+
 default:
 abort();
 }
-- 
2.41.0




[PULL 22/24] vt82c686 machines: Support machine-default audiodev with fallback

2023-10-03 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/mips/fuloong2e.c | 15 ---
 hw/ppc/pegasos2.c   | 12 ++--
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index c827f615f3b..c6109633fee 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -295,9 +295,17 @@ static void mips_fuloong2e_init(MachineState *machine)
 pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
 
 /* South bridge -> IP5 */
-pci_dev = pci_create_simple_multifunction(pci_bus,
-  PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
-  TYPE_VT82C686B_ISA);
+pci_dev = pci_new_multifunction(PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
+TYPE_VT82C686B_ISA);
+
+/* Set properties on individual devices before realizing the south bridge 
*/
+if (machine->audiodev) {
+dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ac97"));
+qdev_prop_set_string(dev, "audiodev", machine->audiodev);
+}
+
+pci_realize_and_unref(pci_dev, pci_bus, &error_abort);
+
 object_property_add_alias(OBJECT(machine), "rtc-time",
   object_resolve_path_component(OBJECT(pci_dev),
 "rtc"),
@@ -337,6 +345,7 @@ static void mips_fuloong2e_machine_init(MachineClass *mc)
 mc->default_ram_size = 256 * MiB;
 mc->default_ram_id = "fuloong2e.ram";
 mc->minimum_page_bits = 14;
+machine_add_audiodev_property(mc);
 }
 
 DEFINE_MACHINE("fuloong2e", mips_fuloong2e_machine_init)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index bd397cf2b5c..3203a4a7289 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -180,8 +180,15 @@ static void pegasos2_init(MachineState *machine)
 pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
 
 /* VIA VT8231 South Bridge (multifunction PCI device) */
-via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
- TYPE_VT8231_ISA));
+via = OBJECT(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
+
+/* Set properties on individual devices before realizing the south bridge 
*/
+if (machine->audiodev) {
+dev = PCI_DEVICE(object_resolve_path_component(via, "ac97"));
+qdev_prop_set_string(DEVICE(dev), "audiodev", machine->audiodev);
+}
+
+pci_realize_and_unref(PCI_DEVICE(via), pci_bus, &error_abort);
 for (i = 0; i < PCI_NUM_PINS; i++) {
 pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
 }
@@ -556,6 +563,7 @@ static void pegasos2_machine_class_init(ObjectClass *oc, 
void *data)
 mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7457_v1.2");
 mc->default_ram_id = "pegasos2.ram";
 mc->default_ram_size = 512 * MiB;
+machine_add_audiodev_property(mc);
 
 vhc->cpu_in_nested = pegasos2_cpu_in_nested;
 vhc->hypercall = pegasos2_hypercall;
-- 
2.41.0




[PULL 05/24] make-release: do not ship dtc sources

2023-10-03 Thread Paolo Bonzini
A new enough libfdt is included in all of Debian 11, Ubuntu 20.04
and MSYS2.  It has also been included for several minor releases
in Fedora and openSUSE Leap, as well as in CentOS.  Therefore
there is no need anymore to ship the sources together with the QEMU
tarballs.

Keep the wrap file so that it can be used with --enable-download,
but do not ship the sources anymore with either archive-source.sh
or make-release.

Signed-off-by: Paolo Bonzini 
---
 meson.build   | 3 +++
 scripts/archive-source.sh | 2 +-
 scripts/make-release  | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/meson.build b/meson.build
index 5139db2ff7c..81430ce2348 100644
--- a/meson.build
+++ b/meson.build
@@ -3070,6 +3070,9 @@ if fdt_required.length() > 0 or fdt_opt == 'enabled'
   endif
 
   if fdt_opt in ['enabled', 'auto', 'system']
+if get_option('wrap_mode') == 'nodownload'
+  fdt_opt = 'system'
+endif
 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
 if fdt.found() and cc.links('''
#include 
diff --git a/scripts/archive-source.sh b/scripts/archive-source.sh
index 48996304910..65af8063e4b 100755
--- a/scripts/archive-source.sh
+++ b/scripts/archive-source.sh
@@ -26,7 +26,7 @@ sub_file="${sub_tdir}/submodule.tar"
 # independent of what the developer currently has initialized
 # in their checkout, because the build environment is completely
 # different to the host OS.
-subprojects="dtc keycodemapdb libvfio-user berkeley-softfloat-3 
berkeley-testfloat-3"
+subprojects="keycodemapdb libvfio-user berkeley-softfloat-3 
berkeley-testfloat-3"
 sub_deinit=""
 
 function cleanup() {
diff --git a/scripts/make-release b/scripts/make-release
index c5db87b3f91..9c570b87f4a 100755
--- a/scripts/make-release
+++ b/scripts/make-release
@@ -17,7 +17,7 @@ if [ $# -ne 2 ]; then
 fi
 
 # Only include wraps that are invoked with subproject()
-SUBPROJECTS="dtc libvfio-user keycodemapdb berkeley-softfloat-3 
berkeley-testfloat-3"
+SUBPROJECTS="libvfio-user keycodemapdb berkeley-softfloat-3 
berkeley-testfloat-3"
 
 src="$1"
 version="$2"
-- 
2.41.0




[PULL 19/24] Introduce machine property "audiodev"

2023-10-03 Thread Paolo Bonzini
From: Martin Kletzander 

Many machine types have default audio devices with no way to set the underlying
audiodev.  Instead of adding an option for each and every one of them, this new
property can be used as a default during machine initialisation when creating
such devices.

Signed-off-by: Martin Kletzander 
[Make the property optional, instead of including it in all machines. - Paolo]
Signed-off-by: Paolo Bonzini 
---
 hw/core/machine.c   | 33 +
 include/hw/boards.h |  9 +
 2 files changed, 42 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index cb38b8cf4cb..6aa49c8d4f1 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -39,6 +39,7 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-pci.h"
 #include "hw/virtio/virtio-net.h"
+#include "audio/audio.h"
 
 GlobalProperty hw_compat_8_1[] = {};
 const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
@@ -686,6 +687,26 @@ bool device_type_is_dynamic_sysbus(MachineClass *mc, const 
char *type)
 return allowed;
 }
 
+static char *machine_get_audiodev(Object *obj, Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+return g_strdup(ms->audiodev);
+}
+
+static void machine_set_audiodev(Object *obj, const char *value,
+ Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+if (!audio_state_by_name(value, errp)) {
+return;
+}
+
+g_free(ms->audiodev);
+ms->audiodev = g_strdup(value);
+}
+
 HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
 {
 int i;
@@ -931,6 +952,17 @@ out_free:
 qapi_free_BootConfiguration(config);
 }
 
+void machine_add_audiodev_property(MachineClass *mc)
+{
+ObjectClass *oc = OBJECT_CLASS(mc);
+
+object_class_property_add_str(oc, "audiodev",
+  machine_get_audiodev,
+  machine_set_audiodev);
+object_class_property_set_description(oc, "audiodev",
+  "Audiodev to use for default machine 
devices");
+}
+
 static void machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -1136,6 +1168,7 @@ static void machine_finalize(Object *obj)
 g_free(ms->device_memory);
 g_free(ms->nvdimms_state);
 g_free(ms->numa_state);
+g_free(ms->audiodev);
 }
 
 bool machine_usb(MachineState *machine)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6c67af196a3..55a64a13fdf 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -24,6 +24,7 @@ OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
 
 extern MachineState *current_machine;
 
+void machine_add_audiodev_property(MachineClass *mc);
 void machine_run_board_init(MachineState *machine, const char *mem_path, Error 
**errp);
 bool machine_usb(MachineState *machine);
 int machine_phandle_start(MachineState *machine);
@@ -358,6 +359,14 @@ struct MachineState {
 MemoryRegion *ram;
 DeviceMemoryState *device_memory;
 
+/*
+ * Included in MachineState for simplicity, but not supported
+ * unless machine_add_audiodev_property is called.  Boards
+ * that have embedded audio devices can call it from the
+ * machine init function and forward the property to the device.
+ */
+char *audiodev;
+
 ram_addr_t ram_size;
 ram_addr_t maxram_size;
 uint64_t   ram_slots;
-- 
2.41.0




[PULL 08/24] esp: use correct type for esp_dma_enable() in sysbus_esp_gpio_demux()

2023-10-03 Thread Paolo Bonzini
From: Mark Cave-Ayland 

The call to esp_dma_enable() was being made with the SYSBUS_ESP type instead of
the ESP type. This meant that when GPIO 1 was being used to trigger a DMA
request from an external DMA controller, the setting of ESPState's dma_enabled
field would clobber unknown memory whilst the dma_cb callback pointer would
typically return NULL so the DMA request would never start.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Message-ID: <20230913204410.65650-2-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Paolo Bonzini 
---
 hw/scsi/esp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index e52188d0228..4218a6a9605 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -1395,7 +1395,7 @@ static void sysbus_esp_gpio_demux(void *opaque, int irq, 
int level)
 parent_esp_reset(s, irq, level);
 break;
 case 1:
-esp_dma_enable(opaque, irq, level);
+esp_dma_enable(s, irq, level);
 break;
 }
 }
-- 
2.41.0




[PULL 24/24] audio: forbid default audiodev backend with -nodefaults

2023-10-03 Thread Paolo Bonzini
Now that all callers support setting an audiodev, forbid using the default
audiodev if -nodefaults is provided on the command line.

Signed-off-by: Paolo Bonzini 
---
 audio/audio.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/audio/audio.c b/audio/audio.c
index 4289b7bf028..730bf2498dc 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1692,6 +1692,10 @@ static void audio_create_default_audiodevs(void)
 {
 const char *drvname = getenv("QEMU_AUDIO_DRV");
 
+if (!defaults_enabled()) {
+return;
+}
+
 /* QEMU_AUDIO_DRV=none is used by libqtest.  */
 if (drvname && !g_str_equal(drvname, "none")) {
 error_report("Please use -audiodev instead of QEMU_AUDIO_*");
@@ -1808,6 +1812,14 @@ bool AUD_register_card (const char *name, QEMUSoundCard 
*card, Error **errp)
 {
 if (!card->state) {
 if (!QTAILQ_EMPTY(&audio_states)) {
+/*
+ * FIXME: once it is possible to create an arbitrary
+ * default device via -audio DRIVER,OPT=VALUE (no "model"),
+ * replace this special case with the default AudioState*,
+ * storing it in a separate global.  For now, keep the
+ * warning to encourage moving off magic use of the first
+ * -audiodev.
+ */
 if (QSIMPLEQ_EMPTY(&default_audiodevs)) {
 dolog("Device %s: audiodev default parameter is deprecated, 
please "
   "specify audiodev=%s\n", name,
@@ -1820,6 +1832,10 @@ bool AUD_register_card (const char *name, QEMUSoundCard 
*card, Error **errp)
 }
 card->state = audio_init(NULL, errp);
 if (!card->state) {
+if (!QSIMPLEQ_EMPTY(&audiodevs)) {
+error_append_hint(errp, "Perhaps you wanted to set 
audiodev=%s?",
+  QSIMPLEQ_FIRST(&audiodevs)->dev->id);
+}
 return false;
 }
 }
-- 
2.41.0




[PULL 23/24] audio: propagate Error * out of audio_init

2023-10-03 Thread Paolo Bonzini
From: Martin Kletzander 

Starting from audio_driver_init, propagate errors via Error ** so that
audio_init_audiodevs can simply pass &error_fatal, and AUD_register_card
can signal faiure.

Signed-off-by: Martin Kletzander 
[Reworked the audio/audio.c parts, while keeping Martin's hw/ changes. - Paolo]
Signed-off-by: Paolo Bonzini 
---
 audio/audio.c| 37 ++---
 audio/audio.h|  4 ++--
 hw/arm/omap2.c   |  2 +-
 hw/audio/ac97.c  |  6 +-
 hw/audio/adlib.c |  6 --
 hw/audio/cs4231a.c   |  6 --
 hw/audio/es1370.c|  5 -
 hw/audio/gus.c   |  6 --
 hw/audio/hda-codec.c |  5 -
 hw/audio/lm4549.c|  8 +---
 hw/audio/pcspk.c |  4 +---
 hw/audio/sb16.c  |  6 --
 hw/audio/via-ac97.c  |  6 --
 hw/audio/wm8750.c|  5 -
 hw/display/xlnx_dp.c |  6 --
 hw/input/tsc210x.c   |  2 +-
 hw/usb/dev-audio.c   |  5 -
 softmmu/vl.c |  4 +---
 18 files changed, 74 insertions(+), 49 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 818d79e50f0..4289b7bf028 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1556,7 +1556,7 @@ size_t audio_generic_read(HWVoiceIn *hw, void *buf, 
size_t size)
 }
 
 static int audio_driver_init(AudioState *s, struct audio_driver *drv,
- bool msg, Audiodev *dev)
+ Audiodev *dev, Error **errp)
 {
 Error *local_err = NULL;
 
@@ -1577,12 +1577,10 @@ static int audio_driver_init(AudioState *s, struct 
audio_driver *drv,
 s->drv = drv;
 return 0;
 } else {
-if (!msg) {
-error_free(local_err);
-} else if (local_err) {
-error_report_err(local_err);
+if (local_err) {
+error_propagate(errp, local_err);
 } else {
-error_report("Could not init `%s' audio driver", drv->name);
+error_setg(errp, "Could not init `%s' audio driver", drv->name);
 }
 return -1;
 }
@@ -1733,7 +1731,7 @@ static void audio_create_default_audiodevs(void)
  * if dev == NULL => legacy implicit initialization, return the already created
  *   state or create a new one
  */
-static AudioState *audio_init(Audiodev *dev)
+static AudioState *audio_init(Audiodev *dev, Error **errp)
 {
 static bool atexit_registered;
 int done = 0;
@@ -1760,9 +1758,9 @@ static AudioState *audio_init(Audiodev *dev)
 drvname = AudiodevDriver_str(dev->driver);
 driver = audio_driver_lookup(drvname);
 if (driver) {
-done = !audio_driver_init(s, driver, true, dev);
+done = !audio_driver_init(s, driver, dev, errp);
 } else {
-dolog ("Unknown audio driver `%s'\n", drvname);
+error_setg(errp, "Unknown audio driver `%s'\n", drvname);
 }
 if (!done) {
 goto out;
@@ -1771,13 +1769,13 @@ static AudioState *audio_init(Audiodev *dev)
 for (;;) {
 AudiodevListEntry *e = QSIMPLEQ_FIRST(&default_audiodevs);
 if (!e) {
-dolog("no default audio driver available\n");
+error_setg(errp, "no default audio driver available");
 goto out;
 }
 s->dev = dev = e->dev;
 drvname = AudiodevDriver_str(dev->driver);
 driver = audio_driver_lookup(drvname);
-if (!audio_driver_init(s, driver, false, dev)) {
+if (!audio_driver_init(s, driver, dev, NULL)) {
 break;
 }
 QSIMPLEQ_REMOVE_HEAD(&default_audiodevs, next);
@@ -1806,7 +1804,7 @@ out:
 return NULL;
 }
 
-void AUD_register_card (const char *name, QEMUSoundCard *card)
+bool AUD_register_card (const char *name, QEMUSoundCard *card, Error **errp)
 {
 if (!card->state) {
 if (!QTAILQ_EMPTY(&audio_states)) {
@@ -1820,13 +1818,18 @@ void AUD_register_card (const char *name, QEMUSoundCard 
*card)
 if (QSIMPLEQ_EMPTY(&default_audiodevs)) {
 audio_create_default_audiodevs();
 }
-card->state = audio_init(NULL);
+card->state = audio_init(NULL, errp);
+if (!card->state) {
+return false;
+}
 }
 }
 
 card->name = g_strdup (name);
 memset (&card->entries, 0, sizeof (card->entries));
 QLIST_INSERT_HEAD(&card->state->card_head, card, entries);
+
+return true;
 }
 
 void AUD_remove_card (QEMUSoundCard *card)
@@ -2153,17 +2156,13 @@ void audio_define(Audiodev *dev)
 QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next);
 }
 
-bool audio_init_audiodevs(void)
+void audio_init_audiodevs(void)
 {
 AudiodevListEntry *e;
 
 QSIMPLEQ_FOREACH(e, &audiodevs, next) {
-if (!audio_init(e->dev)) {
-return false;
-}
+audio_init(e->dev, &error_fatal);
 }
-
-return true;
 }
 
 audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo)
diff --git a/a

[PULL 20/24] hw/arm: Support machine-default audiodev with fallback

2023-10-03 Thread Paolo Bonzini
From: Martin Kletzander 

Signed-off-by: Martin Kletzander 
Signed-off-by: Paolo Bonzini 
---
 hw/arm/integratorcp.c | 11 ++-
 hw/arm/musicpal.c | 11 +--
 hw/arm/nseries.c  |  4 
 hw/arm/omap2.c|  5 +
 hw/arm/palm.c |  2 ++
 hw/arm/realview.c | 12 
 hw/arm/spitz.c| 17 -
 hw/arm/versatilepb.c  |  8 
 hw/arm/vexpress.c |  5 +
 hw/arm/xlnx-zcu102.c  |  6 ++
 hw/arm/z2.c   | 15 ++-
 hw/input/tsc210x.c|  5 +
 12 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index b109ece3ae0..d176e9af7ee 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -27,6 +27,7 @@
 #include "hw/irq.h"
 #include "hw/sd/sd.h"
 #include "qom/object.h"
+#include "audio/audio.h"
 
 #define TYPE_INTEGRATOR_CM "integrator_core"
 OBJECT_DECLARE_SIMPLE_TYPE(IntegratorCMState, INTEGRATOR_CM)
@@ -660,7 +661,13 @@ static void integratorcp_init(MachineState *machine)
&error_fatal);
 }
 
-sysbus_create_varargs("pl041", 0x1d00, pic[25], NULL);
+dev = qdev_new("pl041");
+if (machine->audiodev) {
+qdev_prop_set_string(dev, "audiodev", machine->audiodev);
+}
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x1d00);
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[25]);
 
 if (nd_table[0].used)
 smc91c111_init(&nd_table[0], 0xc800, pic[27]);
@@ -678,6 +685,8 @@ static void integratorcp_machine_init(MachineClass *mc)
 mc->ignore_memory_transaction_failures = true;
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
 mc->default_ram_id = "integrator.ram";
+
+machine_add_audiodev_property(mc);
 }
 
 DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index dc4e43e0ee2..9703bfb97fb 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -37,9 +37,9 @@
 #include "qemu/cutils.h"
 #include "qom/object.h"
 #include "hw/net/mv88w8618_eth.h"
+#include "audio/audio.h"
 #include "qemu/error-report.h"
 
-
 #define MP_MISC_BASE0x80002000
 #define MP_MISC_SIZE0x1000
 
@@ -1326,7 +1326,12 @@ static void musicpal_init(MachineState *machine)
 qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 15));
 }
 
-wm8750_dev = i2c_slave_create_simple(i2c, TYPE_WM8750, MP_WM_ADDR);
+wm8750_dev = i2c_slave_new(TYPE_WM8750, MP_WM_ADDR);
+if (machine->audiodev) {
+qdev_prop_set_string(DEVICE(wm8750_dev), "audiodev", 
machine->audiodev);
+}
+i2c_slave_realize_and_unref(wm8750_dev, i2c, &error_abort);
+
 dev = qdev_new(TYPE_MV88W8618_AUDIO);
 s = SYS_BUS_DEVICE(dev);
 object_property_set_link(OBJECT(dev), "wm8750", OBJECT(wm8750_dev),
@@ -1347,6 +1352,8 @@ static void musicpal_machine_init(MachineClass *mc)
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
 mc->default_ram_size = MP_RAM_DEFAULT_SIZE;
 mc->default_ram_id = "musicpal.ram";
+
+machine_add_audiodev_property(mc);
 }
 
 DEFINE_MACHINE("musicpal", musicpal_machine_init)
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 9e49e9e1776..35aff46b4b4 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1432,6 +1432,8 @@ static void n800_class_init(ObjectClass *oc, void *data)
 /* Actually two chips of 0x400 bytes each */
 mc->default_ram_size = 0x0800;
 mc->default_ram_id = "omap2.dram";
+
+machine_add_audiodev_property(mc);
 }
 
 static const TypeInfo n800_type = {
@@ -1452,6 +1454,8 @@ static void n810_class_init(ObjectClass *oc, void *data)
 /* Actually two chips of 0x400 bytes each */
 mc->default_ram_size = 0x0800;
 mc->default_ram_id = "omap2.dram";
+
+machine_add_audiodev_property(mc);
 }
 
 static const TypeInfo n810_type = {
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index d5a2ae7af6e..41b1f596dca 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -37,6 +37,7 @@
 #include "hw/block/flash.h"
 #include "hw/arm/soc_dma.h"
 #include "hw/sysbus.h"
+#include "hw/boards.h"
 #include "audio/audio.h"
 
 /* Enhanced Audio Controller (CODEC only) */
@@ -609,6 +610,10 @@ static struct omap_eac_s *omap_eac_init(struct 
omap_target_agent_s *ta,
 s->codec.txdrq = *drq;
 omap_eac_reset(s);
 
+if (current_machine->audiodev) {
+s->codec.card.name = g_strdup(current_machine->audiodev);
+s->codec.card.state = audio_state_by_name(s->codec.card.name, 
&error_fatal);
+}
 AUD_register_card("OMAP EAC", &s->codec.card);
 
 memory_region_init_io(&s->iomem, NULL, &omap_eac_ops, s, "omap.eac",
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index 17c11ac4cec..b86f2c331bb 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -310,6 +310,8 @@ static void palmte_machine_init(MachineClass *mc)
 mc->default_cpu_type = ARM_CPU_TYPE_NAM

[PULL 15/24] audio: return Error ** from audio_state_by_name

2023-10-03 Thread Paolo Bonzini
Remove duplicate error formatting code.

Signed-off-by: Paolo Bonzini 
---
 audio/audio-hmp-cmds.c   |  6 --
 audio/audio.c|  3 ++-
 audio/audio.h|  2 +-
 hw/core/qdev-properties-system.c | 16 
 ui/dbus.c|  3 +--
 ui/vnc.c |  3 +--
 6 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/audio/audio-hmp-cmds.c b/audio/audio-hmp-cmds.c
index 1237ce9e750..c9608b715b8 100644
--- a/audio/audio-hmp-cmds.c
+++ b/audio/audio-hmp-cmds.c
@@ -26,6 +26,7 @@
 #include "audio/audio.h"
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
+#include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 
 static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
@@ -65,10 +66,11 @@ void hmp_wavcapture(Monitor *mon, const QDict *qdict)
 int nchannels = qdict_get_try_int(qdict, "nchannels", 2);
 const char *audiodev = qdict_get_str(qdict, "audiodev");
 CaptureState *s;
-AudioState *as = audio_state_by_name(audiodev);
+Error *local_err = NULL;
+AudioState *as = audio_state_by_name(audiodev, &local_err);
 
 if (!as) {
-monitor_printf(mon, "Audiodev '%s' not found\n", audiodev);
+error_report_err(local_err);
 return;
 }
 
diff --git a/audio/audio.c b/audio/audio.c
index fdc34a77520..874a4c3c412 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2260,7 +2260,7 @@ int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo,
 audioformat_bytes_per_sample(as->fmt);
 }
 
-AudioState *audio_state_by_name(const char *name)
+AudioState *audio_state_by_name(const char *name, Error **errp)
 {
 AudioState *s;
 QTAILQ_FOREACH(s, &audio_states, list) {
@@ -2269,6 +2269,7 @@ AudioState *audio_state_by_name(const char *name)
 return s;
 }
 }
+error_setg(errp, "audiodev '%s' not found", name);
 return NULL;
 }
 
diff --git a/audio/audio.h b/audio/audio.h
index 01bdc567fb1..e0c13b5dcdf 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -174,7 +174,7 @@ bool audio_init_audiodevs(void);
 void audio_help(void);
 void audio_legacy_help(void);
 
-AudioState *audio_state_by_name(const char *name);
+AudioState *audio_state_by_name(const char *name, Error **errp);
 const char *audio_get_id(QEMUSoundCard *card);
 
 #define DEFINE_AUDIO_PROPERTIES(_s, _f) \
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 41b7e682c78..688340610ec 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -480,24 +480,16 @@ static void set_audiodev(Object *obj, Visitor *v, const 
char* name,
 Property *prop = opaque;
 QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
 AudioState *state;
-int err = 0;
-char *str;
+g_autofree char *str = NULL;
 
 if (!visit_type_str(v, name, &str, errp)) {
 return;
 }
 
-state = audio_state_by_name(str);
-
-if (!state) {
-err = -ENOENT;
-goto out;
+state = audio_state_by_name(str, errp);
+if (state) {
+card->state = state;
 }
-card->state = state;
-
-out:
-error_set_from_qdev_prop_error(errp, err, obj, name, str);
-g_free(str);
 }
 
 const PropertyInfo qdev_prop_audiodev = {
diff --git a/ui/dbus.c b/ui/dbus.c
index 32f1bbe81ae..866467ad2e3 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -220,9 +220,8 @@ dbus_display_complete(UserCreatable *uc, Error **errp)
 }
 
 if (dd->audiodev && *dd->audiodev) {
-AudioState *audio_state = audio_state_by_name(dd->audiodev);
+AudioState *audio_state = audio_state_by_name(dd->audiodev, errp);
 if (!audio_state) {
-error_setg(errp, "Audiodev '%s' not found", dd->audiodev);
 return;
 }
 if (!g_str_equal(audio_state->drv->name, "dbus")) {
diff --git a/ui/vnc.c b/ui/vnc.c
index acb56461b2d..82929469130 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -4181,9 +4181,8 @@ void vnc_display_open(const char *id, Error **errp)
 
 audiodev = qemu_opt_get(opts, "audiodev");
 if (audiodev) {
-vd->audio_state = audio_state_by_name(audiodev);
+vd->audio_state = audio_state_by_name(audiodev, errp);
 if (!vd->audio_state) {
-error_setg(errp, "Audiodev '%s' not found", audiodev);
 goto fail;
 }
 }
-- 
2.41.0




[PULL 04/24] pc: remove short_root_bus property

2023-10-03 Thread Paolo Bonzini
The property was only used on QEMU 1.6 machine types.

Signed-off-by: Paolo Bonzini 
---
 hw/pci-host/i440fx.c  | 8 
 hw/pci-host/q35.c | 7 ---
 include/hw/pci-host/q35.h | 1 -
 3 files changed, 16 deletions(-)

diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c
index 62d62876818..653cc3f1495 100644
--- a/hw/pci-host/i440fx.c
+++ b/hw/pci-host/i440fx.c
@@ -56,7 +56,6 @@ struct I440FXState {
 uint64_t above_4g_mem_size;
 uint64_t pci_hole64_size;
 bool pci_hole64_fix;
-uint32_t short_root_bus;
 
 char *pci_type;
 };
@@ -351,19 +350,12 @@ static const TypeInfo i440fx_info = {
 static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
 PCIBus *rootbus)
 {
-I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge);
-
-/* For backwards compat with old device paths */
-if (s->short_root_bus) {
-return "";
-}
 return ":00";
 }
 
 static Property i440fx_props[] = {
 DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
  pci_hole64_size, I440FX_PCI_HOST_HOLE64_SIZE_DEFAULT),
-DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0),
 DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, I440FXState,
  below_4g_mem_size, 0),
 DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, I440FXState,
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 91c46df9ae3..08534bc7cc0 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -73,12 +73,6 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
 static const char *q35_host_root_bus_path(PCIHostState *host_bridge,
   PCIBus *rootbus)
 {
-Q35PCIHost *s = Q35_HOST_DEVICE(host_bridge);
-
- /* For backwards compat with old device paths */
-if (s->mch.short_root_bus) {
-return "";
-}
 return ":00";
 }
 
@@ -181,7 +175,6 @@ static Property q35_host_props[] = {
 MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
 DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
  mch.pci_hole64_size, Q35_PCI_HOST_HOLE64_SIZE_DEFAULT),
-DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
 DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
  mch.below_4g_mem_size, 0),
 DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 1d98bbfe0dd..bafcbe67521 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -54,7 +54,6 @@ struct MCHPCIState {
 uint64_t below_4g_mem_size;
 uint64_t above_4g_mem_size;
 uint64_t pci_hole64_size;
-uint32_t short_root_bus;
 uint16_t ext_tseg_mbytes;
 };
 
-- 
2.41.0




[PULL 16/24] audio: commonize voice initialization

2023-10-03 Thread Paolo Bonzini
Move some mostly irrelevant code out of audio_init.

Signed-off-by: Paolo Bonzini 
---
 audio/audio.c  | 19 ++-
 audio/audio_template.h |  9 -
 2 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 874a4c3c412..bb1734a95d3 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1570,8 +1570,8 @@ static int audio_driver_init(AudioState *s, struct 
audio_driver *drv,
 drv->pcm_ops->put_buffer_out = audio_generic_put_buffer_out;
 }
 
-audio_init_nb_voices_out(s, drv);
-audio_init_nb_voices_in(s, drv);
+audio_init_nb_voices_out(s, drv, 1);
+audio_init_nb_voices_in(s, drv, 0);
 s->drv = drv;
 return 0;
 } else {
@@ -1774,21 +1774,6 @@ static AudioState *audio_init(Audiodev *dev, const char 
*name)
 
 s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
 
-s->nb_hw_voices_out = audio_get_pdo_out(dev)->voices;
-s->nb_hw_voices_in = audio_get_pdo_in(dev)->voices;
-
-if (s->nb_hw_voices_out < 1) {
-dolog ("Bogus number of playback voices %d, setting to 1\n",
-   s->nb_hw_voices_out);
-s->nb_hw_voices_out = 1;
-}
-
-if (s->nb_hw_voices_in < 0) {
-dolog ("Bogus number of capture voices %d, setting to 0\n",
-   s->nb_hw_voices_in);
-s->nb_hw_voices_in = 0;
-}
-
 if (drvname) {
 driver = audio_driver_lookup(drvname);
 if (driver) {
diff --git a/audio/audio_template.h b/audio/audio_template.h
index dc0c74aa746..7ccfec01168 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -37,11 +37,12 @@
 #endif
 
 static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
-  struct audio_driver *drv)
+  struct audio_driver *drv, int 
min_voices)
 {
 int max_voices = glue (drv->max_voices_, TYPE);
 size_t voice_size = glue(drv->voice_size_, TYPE);
 
+glue (s->nb_hw_voices_, TYPE) = glue(audio_get_pdo_, TYPE)(s->dev)->voices;
 if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
 if (!max_voices) {
 #ifdef DAC
@@ -56,6 +57,12 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
 glue (s->nb_hw_voices_, TYPE) = max_voices;
 }
 
+if (glue (s->nb_hw_voices_, TYPE) < min_voices) {
+dolog ("Bogus number of " NAME " voices %d, setting to %d\n",
+   glue (s->nb_hw_voices_, TYPE),
+   min_voices);
+}
+
 if (audio_bug(__func__, !voice_size && max_voices)) {
 dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
drv->name, max_voices);
-- 
2.41.0




Re: [PATCH 1/5] accel: Rename accel_cpu_realizefn() -> accel_cpu_realize()

2023-10-03 Thread Claudio Fontana
Reviewed-by: Claudio Fontana 

On 9/15/23 21:00, Philippe Mathieu-Daudé wrote:
> We use the '*fn' suffix for handlers, this is a public method.
> Drop the suffix.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  include/qemu/accel.h  | 4 ++--
>  accel/accel-common.c  | 2 +-
>  cpu.c | 2 +-
>  target/i386/kvm/kvm-cpu.c | 2 +-
>  4 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/include/qemu/accel.h b/include/qemu/accel.h
> index e84db2e3e5..cb64a07b84 100644
> --- a/include/qemu/accel.h
> +++ b/include/qemu/accel.h
> @@ -90,11 +90,11 @@ void accel_setup_post(MachineState *ms);
>  void accel_cpu_instance_init(CPUState *cpu);
>  
>  /**
> - * accel_cpu_realizefn:
> + * accel_cpu_realize:
>   * @cpu: The CPU that needs to call accel-specific cpu realization.
>   * @errp: currently unused.
>   */
> -bool accel_cpu_realizefn(CPUState *cpu, Error **errp);
> +bool accel_cpu_realize(CPUState *cpu, Error **errp);
>  
>  /**
>   * accel_supported_gdbstub_sstep_flags:
> diff --git a/accel/accel-common.c b/accel/accel-common.c
> index df72cc989a..b953855e8b 100644
> --- a/accel/accel-common.c
> +++ b/accel/accel-common.c
> @@ -119,7 +119,7 @@ void accel_cpu_instance_init(CPUState *cpu)
>  }
>  }
>  
> -bool accel_cpu_realizefn(CPUState *cpu, Error **errp)
> +bool accel_cpu_realize(CPUState *cpu, Error **errp)
>  {
>  CPUClass *cc = CPU_GET_CLASS(cpu);
>  
> diff --git a/cpu.c b/cpu.c
> index 0769b0b153..61c9760e62 100644
> --- a/cpu.c
> +++ b/cpu.c
> @@ -136,7 +136,7 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
>  /* cache the cpu class for the hotpath */
>  cpu->cc = CPU_GET_CLASS(cpu);
>  
> -if (!accel_cpu_realizefn(cpu, errp)) {
> +if (!accel_cpu_realize(cpu, errp)) {
>  return;
>  }
>  
> diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
> index 7237378a7d..4474689f81 100644
> --- a/target/i386/kvm/kvm-cpu.c
> +++ b/target/i386/kvm/kvm-cpu.c
> @@ -35,7 +35,7 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp)
>   * x86_cpu_realize():
>   *  -> x86_cpu_expand_features()
>   *  -> cpu_exec_realizefn():
> - *-> accel_cpu_realizefn()
> + *-> accel_cpu_realize()
>   *   kvm_cpu_realizefn() -> host_cpu_realizefn()
>   *  -> check/update ucode_rev, phys_bits, mwait
>   */




Re: [PATCH 3/5] accel: Declare AccelClass::[un]realize_cpu() handlers

2023-10-03 Thread Claudio Fontana
On 9/15/23 21:00, Philippe Mathieu-Daudé wrote:
> Currently accel_cpu_realize() only performs target-specific
> realization. Introduce the [un]realize_cpu fields in the
> base AccelClass to be able to perform target-agnostic
> [un]realization of vCPUs.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Just thinking, for the benefit of the reader trying to understand the code 
later on,
maybe putting in a "target_" in there somewhere in the function name?
like "realize_cpu_target", vs "realize_cpu_generic" ?

Ciao,

C

> ---
>  include/qemu/accel.h |  2 ++
>  accel/accel-common.c | 21 +++--
>  2 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/include/qemu/accel.h b/include/qemu/accel.h
> index 23254c6c9c..7bd9907d2a 100644
> --- a/include/qemu/accel.h
> +++ b/include/qemu/accel.h
> @@ -43,6 +43,8 @@ typedef struct AccelClass {
>  bool (*has_memory)(MachineState *ms, AddressSpace *as,
> hwaddr start_addr, hwaddr size);
>  #endif
> +bool (*realize_cpu)(CPUState *cpu, Error **errp);
> +void (*unrealize_cpu)(CPUState *cpu);
>  
>  /* gdbstub related hooks */
>  int (*gdbstub_supported_sstep_flags)(void);
> diff --git a/accel/accel-common.c b/accel/accel-common.c
> index cc3a45e663..6d427f2b9d 100644
> --- a/accel/accel-common.c
> +++ b/accel/accel-common.c
> @@ -122,15 +122,32 @@ void accel_cpu_instance_init(CPUState *cpu)
>  bool accel_cpu_realize(CPUState *cpu, Error **errp)
>  {
>  CPUClass *cc = CPU_GET_CLASS(cpu);
> +AccelState *accel = current_accel();
> +AccelClass *acc = ACCEL_GET_CLASS(accel);
>  
> -if (cc->accel_cpu && cc->accel_cpu->cpu_realizefn) {
> -return cc->accel_cpu->cpu_realizefn(cpu, errp);
> +/* target specific realization */
> +if (cc->accel_cpu && cc->accel_cpu->cpu_realizefn
> +&& !cc->accel_cpu->cpu_realizefn(cpu, errp)) {
> +return false;
>  }
> +
> +/* generic realization */
> +if (acc->realize_cpu && !acc->realize_cpu(cpu, errp)) {
> +return false;
> +}
> +
>  return true;
>  }
>  
>  void accel_cpu_unrealize(CPUState *cpu)
>  {
> +AccelState *accel = current_accel();
> +AccelClass *acc = ACCEL_GET_CLASS(accel);
> +
> +/* generic unrealization */
> +if (acc->unrealize_cpu) {
> +acc->unrealize_cpu(cpu);
> +}
>  }
>  
>  int accel_supported_gdbstub_sstep_flags(void)




Re: [PATCH 4/5] accel/tcg: Have tcg_exec_realizefn() return a boolean

2023-10-03 Thread Claudio Fontana
On 9/15/23 21:00, Philippe Mathieu-Daudé wrote:
> Following the example documented since commit e3fe3988d7 ("error:
> Document Error API usage rules"), have tcg_exec_realizefn() return
> a boolean indicating whether an error is set or not.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Claudio Fontana 

> ---
>  include/exec/cpu-all.h | 2 +-
>  accel/tcg/cpu-exec.c   | 4 +++-
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index c2c62160c6..1e5c530ee1 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -422,7 +422,7 @@ void dump_exec_info(GString *buf);
>  
>  /* accel/tcg/cpu-exec.c */
>  int cpu_exec(CPUState *cpu);
> -void tcg_exec_realizefn(CPUState *cpu, Error **errp);
> +bool tcg_exec_realizefn(CPUState *cpu, Error **errp);
>  void tcg_exec_unrealizefn(CPUState *cpu);
>  
>  /**
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index e2c494e75e..fa97e9f191 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -1088,7 +1088,7 @@ int cpu_exec(CPUState *cpu)
>  return ret;
>  }
>  
> -void tcg_exec_realizefn(CPUState *cpu, Error **errp)
> +bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
>  {
>  static bool tcg_target_initialized;
>  CPUClass *cc = CPU_GET_CLASS(cpu);
> @@ -1104,6 +1104,8 @@ void tcg_exec_realizefn(CPUState *cpu, Error **errp)
>  tcg_iommu_init_notifier_list(cpu);
>  #endif /* !CONFIG_USER_ONLY */
>  /* qemu_plugin_vcpu_init_hook delayed until cpu_index assigned. */
> +
> +return true;
>  }
>  
>  /* undo the initializations in reverse order */




[PATCH v3 2/5] hw/pc: remove needless includes

2023-10-03 Thread marcandre . lureau
From: Marc-André Lureau 

The include list is gigantic, make it smaller.

Signed-off-by: Marc-André Lureau 
Acked-by: Laszlo Ersek 
---
 hw/i386/pc.c | 41 -
 1 file changed, 41 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5d399b6247..c376c5032d 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -24,79 +24,38 @@
 
 #include "qemu/osdep.h"
 #include "qemu/units.h"
-#include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
 #include "hw/char/serial.h"
 #include "hw/char/parallel.h"
-#include "hw/i386/topology.h"
 #include "hw/i386/fw_cfg.h"
 #include "hw/i386/vmport.h"
 #include "sysemu/cpus.h"
-#include "hw/block/fdc.h"
 #include "hw/ide/internal.h"
-#include "hw/ide/isa.h"
-#include "hw/pci/pci.h"
-#include "hw/pci/pci_bus.h"
-#include "hw/pci-bridge/pci_expander_bridge.h"
-#include "hw/nvram/fw_cfg.h"
 #include "hw/timer/hpet.h"
-#include "hw/firmware/smbios.h"
 #include "hw/loader.h"
-#include "elf.h"
-#include "migration/vmstate.h"
-#include "multiboot.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/intc/i8259.h"
-#include "hw/intc/ioapic.h"
 #include "hw/timer/i8254.h"
 #include "hw/input/i8042.h"
-#include "hw/irq.h"
 #include "hw/audio/pcspk.h"
-#include "hw/pci/msi.h"
-#include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/tcg.h"
-#include "sysemu/numa.h"
-#include "sysemu/kvm.h"
 #include "sysemu/xen.h"
 #include "sysemu/reset.h"
-#include "sysemu/runstate.h"
 #include "kvm/kvm_i386.h"
-#include "hw/xen/xen.h"
-#include "hw/xen/start_info.h"
-#include "ui/qemu-spice.h"
-#include "exec/memory.h"
-#include "qemu/bitmap.h"
-#include "qemu/config-file.h"
-#include "qemu/error-report.h"
-#include "qemu/option.h"
-#include "qemu/cutils.h"
-#include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "acpi-build.h"
-#include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
-#include "hw/cxl/cxl.h"
 #include "hw/cxl/cxl_host.h"
-#include "qapi/error.h"
-#include "qapi/qapi-visit-common.h"
-#include "qapi/qapi-visit-machine.h"
-#include "qapi/visitor.h"
-#include "hw/core/cpu.h"
 #include "hw/usb.h"
 #include "hw/i386/intel_iommu.h"
 #include "hw/net/ne2000-isa.h"
-#include "standard-headers/asm-x86/bootparam.h"
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/virtio/virtio-md-pci.h"
 #include "hw/i386/kvm/xen_overlay.h"
 #include "hw/i386/kvm/xen_evtchn.h"
 #include "hw/i386/kvm/xen_gnttab.h"
 #include "hw/i386/kvm/xen_xenstore.h"
-#include "sysemu/replay.h"
-#include "target/i386/cpu.h"
 #include "e820_memory_layout.h"
-#include "fw_cfg.h"
 #include "trace.h"
 #include CONFIG_DEVICES
 
-- 
2.41.0




[PATCH v3 0/5] WIP: ramfb: migration support

2023-10-03 Thread marcandre . lureau
From: Marc-André Lureau 

Hi,

Implement RAMFB migration, and add properties to enable it only on >= 8.2
machines, + a few related cleanups.

v3:
- add a "x-" prefix to properties, as they are not meant for users.
- RAMFB now exports a ramfb_vmstate for actual devices to include
- VFIOPCIDevice now has a VFIODisplay optional subsection whenever ramfb
  migration is required (untested)

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1859424

Marc-André Lureau (5):
  hw/core: remove needless includes
  hw/pc: remove needless includes
  ramfb: add migration support
  ramfb-standalone: add migration support
  hw/vfio: add ramfb migration support

 hw/vfio/pci.h |  3 +++
 include/hw/display/ramfb.h|  4 
 hw/core/machine.c | 15 -
 hw/display/ramfb-standalone.c | 27 +++
 hw/display/ramfb.c| 19 
 hw/i386/pc.c  | 41 ---
 hw/vfio/display.c | 23 
 hw/vfio/pci.c | 32 +++
 8 files changed, 112 insertions(+), 52 deletions(-)

-- 
2.41.0




[PATCH v3 5/5] hw/vfio: add ramfb migration support

2023-10-03 Thread marcandre . lureau
From: Marc-André Lureau 

Add a "VFIODisplay" subsection whenever "x-ramfb-migrate" is turned on.

Turn it off by default on machines <= 8.1 for compatibility reasons.

Signed-off-by: Marc-André Lureau 
---
 hw/vfio/pci.h |  3 +++
 hw/core/machine.c |  1 +
 hw/vfio/display.c | 23 +++
 hw/vfio/pci.c | 32 
 4 files changed, 59 insertions(+)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 2d836093a8..fd06695542 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -173,6 +173,7 @@ struct VFIOPCIDevice {
 bool no_kvm_ioeventfd;
 bool no_vfio_ioeventfd;
 bool enable_ramfb;
+OnOffAuto ramfb_migrate;
 bool defer_kvm_irq_routing;
 bool clear_parent_atomics_on_exit;
 VFIODisplay *dpy;
@@ -226,4 +227,6 @@ void vfio_display_reset(VFIOPCIDevice *vdev);
 int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
 void vfio_display_finalize(VFIOPCIDevice *vdev);
 
+extern const VMStateDescription vfio_display_vmstate;
+
 #endif /* HW_VFIO_VFIO_PCI_H */
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 47a07d1d9b..f2f8940a85 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -32,6 +32,7 @@
 
 GlobalProperty hw_compat_8_1[] = {
 { "ramfb", "x-migrate", "off" },
+{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }
 };
 const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
 
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index bec864f482..de5bf71dd1 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -542,3 +542,26 @@ void vfio_display_finalize(VFIOPCIDevice *vdev)
 vfio_display_edid_exit(vdev->dpy);
 g_free(vdev->dpy);
 }
+
+static bool migrate_needed(void *opaque)
+{
+/*
+ * If we are here, it's because vfio_display_needed(), which is only true
+ * when dpy->ramfb_migrate atm.
+ *
+ * If the migration condition is changed, we should check here if
+ * ramfb_migrate is true. (this will need a way to lookup the associated
+ * VFIOPCIDevice somehow, or fields to be moved, ..)
+ */
+return true;
+}
+
+const VMStateDescription vfio_display_vmstate = {
+.name = "VFIODisplay",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = migrate_needed,
+.fields = (VMStateField[]) {
+VMSTATE_STRUCT_POINTER(ramfb, VFIODisplay, ramfb_vmstate, RAMFBState),
+}
+};
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 3b2ca3c24c..4689f2e5c1 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2608,6 +2608,25 @@ static bool vfio_msix_present(void *opaque, int 
version_id)
 return msix_present(pdev);
 }
 
+static bool vfio_display_needed(void *opaque)
+{
+VFIOPCIDevice *vdev = opaque;
+
+/* the only thing that justifies the VFIODisplay sub-section atm */
+return vdev->ramfb_migrate != ON_OFF_AUTO_OFF;
+}
+
+const VMStateDescription vmstate_vfio_display = {
+.name = "VFIOPCIDevice/VFIODisplay",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = vfio_display_needed,
+.fields = (VMStateField[]){
+VMSTATE_STRUCT_POINTER(dpy, VFIOPCIDevice, vfio_display_vmstate, 
VFIODisplay),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_vfio_pci_config = {
 .name = "VFIOPCIDevice",
 .version_id = 1,
@@ -2616,6 +2635,10 @@ const VMStateDescription vmstate_vfio_pci_config = {
 VMSTATE_PCI_DEVICE(pdev, VFIOPCIDevice),
 VMSTATE_MSIX_TEST(pdev, VFIOPCIDevice, vfio_msix_present),
 VMSTATE_END_OF_LIST()
+},
+.subsections = (const VMStateDescription*[]) {
+&vmstate_vfio_display,
+NULL
 }
 };
 
@@ -3275,6 +3298,14 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 if (!vfio_migration_realize(vbasedev, errp)) {
 goto out_deregister;
 }
+if (vbasedev->enable_migration == ON_OFF_AUTO_OFF) {
+if (vdev->ramfb_migrate == ON_OFF_AUTO_AUTO) {
+vdev->ramfb_migrate = ON_OFF_AUTO_OFF;
+} else if (vdev->ramfb_migrate == ON_OFF_AUTO_ON) {
+error_setg(errp, "x-ramfb-migrate requires migration");
+goto out_deregister;
+}
+}
 }
 
 vfio_register_err_notifier(vdev);
@@ -3484,6 +3515,7 @@ static const TypeInfo vfio_pci_dev_info = {
 
 static Property vfio_pci_dev_nohotplug_properties[] = {
 DEFINE_PROP_BOOL("ramfb", VFIOPCIDevice, enable_ramfb, false),
+DEFINE_PROP_ON_OFF_AUTO("x-ramfb-migrate", VFIOPCIDevice, ramfb_migrate, 
ON_OFF_AUTO_AUTO),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.41.0




[PATCH v3 4/5] ramfb-standalone: add migration support

2023-10-03 Thread marcandre . lureau
From: Marc-André Lureau 

Add a "ramfb-dev" section whenever "x-migrate" is turned on. Turn it off
by default on machines <= 8.1 for compatibility reasons.

Signed-off-by: Marc-André Lureau 
---
 hw/core/machine.c |  4 +++-
 hw/display/ramfb-standalone.c | 27 +++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index df40f10dfa..47a07d1d9b 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -30,7 +30,9 @@
 #include "hw/virtio/virtio-pci.h"
 #include "hw/virtio/virtio-net.h"
 
-GlobalProperty hw_compat_8_1[] = {};
+GlobalProperty hw_compat_8_1[] = {
+{ "ramfb", "x-migrate", "off" },
+};
 const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
 
 GlobalProperty hw_compat_8_0[] = {
diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c
index 8c0094397f..a96e7ebcd9 100644
--- a/hw/display/ramfb-standalone.c
+++ b/hw/display/ramfb-standalone.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/loader.h"
@@ -15,6 +16,7 @@ struct RAMFBStandaloneState {
 SysBusDevice parent_obj;
 QemuConsole *con;
 RAMFBState *state;
+bool migrate;
 };
 
 static void display_update_wrapper(void *dev)
@@ -40,14 +42,39 @@ static void ramfb_realizefn(DeviceState *dev, Error **errp)
 ramfb->state = ramfb_setup(errp);
 }
 
+static bool migrate_needed(void *opaque)
+{
+RAMFBStandaloneState *ramfb = RAMFB(opaque);
+
+return ramfb->migrate;
+}
+
+static const VMStateDescription ramfb_dev_vmstate = {
+.name = "ramfb-dev",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = migrate_needed,
+.fields = (VMStateField[]) {
+VMSTATE_STRUCT_POINTER(state, RAMFBStandaloneState, ramfb_vmstate, 
RAMFBState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static Property ramfb_properties[] = {
+DEFINE_PROP_BOOL("x-migrate", RAMFBStandaloneState, migrate,  true),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void ramfb_class_initfn(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
+dc->vmsd = &ramfb_dev_vmstate;
 dc->realize = ramfb_realizefn;
 dc->desc = "ram framebuffer standalone device";
 dc->user_creatable = true;
+device_class_set_props(dc, ramfb_properties);
 }
 
 static const TypeInfo ramfb_info = {
-- 
2.41.0




[PATCH v3 3/5] ramfb: add migration support

2023-10-03 Thread marcandre . lureau
From: Marc-André Lureau 

Implementing RAMFB migration is quite straightforward. One caveat is to
treat the whole RAMFBCfg as a blob, since that's what is exposed to the
guest directly. This avoid having to fiddle with endianness issues if we
were to migrate fields individually as integers.

The devices using RAMFB will have to include ramfb_vmstate in their
migration description.

Signed-off-by: Marc-André Lureau 
---
 include/hw/display/ramfb.h |  4 
 hw/display/ramfb.c | 19 +++
 2 files changed, 23 insertions(+)

diff --git a/include/hw/display/ramfb.h b/include/hw/display/ramfb.h
index b33a2c467b..a7e0019144 100644
--- a/include/hw/display/ramfb.h
+++ b/include/hw/display/ramfb.h
@@ -1,11 +1,15 @@
 #ifndef RAMFB_H
 #define RAMFB_H
 
+#include "migration/vmstate.h"
+
 /* ramfb.c */
 typedef struct RAMFBState RAMFBState;
 void ramfb_display_update(QemuConsole *con, RAMFBState *s);
 RAMFBState *ramfb_setup(Error **errp);
 
+extern const VMStateDescription ramfb_vmstate;
+
 /* ramfb-standalone.c */
 #define TYPE_RAMFB_DEVICE "ramfb"
 
diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c
index 79b9754a58..32ccb7053b 100644
--- a/hw/display/ramfb.c
+++ b/hw/display/ramfb.c
@@ -28,6 +28,8 @@ struct QEMU_PACKED RAMFBCfg {
 uint32_t stride;
 };
 
+typedef struct RAMFBCfg RAMFBCfg;
+
 struct RAMFBState {
 DisplaySurface *ds;
 uint32_t width, height;
@@ -115,6 +117,23 @@ void ramfb_display_update(QemuConsole *con, RAMFBState *s)
 dpy_gfx_update_full(con);
 }
 
+static int ramfb_post_load(void *opaque, int version_id)
+{
+ramfb_fw_cfg_write(opaque, 0, 0);
+return 0;
+}
+
+const VMStateDescription ramfb_vmstate = {
+.name = "ramfb",
+.version_id = 1,
+.minimum_version_id = 1,
+.post_load = ramfb_post_load,
+.fields = (VMStateField[]) {
+VMSTATE_BUFFER_UNSAFE(cfg, RAMFBState, 0, sizeof(RAMFBCfg)),
+VMSTATE_END_OF_LIST()
+}
+};
+
 RAMFBState *ramfb_setup(Error **errp)
 {
 FWCfgState *fw_cfg = fw_cfg_find();
-- 
2.41.0




[PATCH v3 1/5] hw/core: remove needless includes

2023-10-03 Thread marcandre . lureau
From: Marc-André Lureau 

The include list is large, make it smaller.

Signed-off-by: Marc-André Lureau 
Acked-by: Laszlo Ersek 
---
 hw/core/machine.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index a232ae0bcd..df40f10dfa 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -11,32 +11,22 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/option.h"
 #include "qemu/accel.h"
 #include "sysemu/replay.h"
-#include "qemu/units.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "qapi/error.h"
-#include "qapi/qapi-visit-common.h"
 #include "qapi/qapi-visit-machine.h"
-#include "qapi/visitor.h"
 #include "qom/object_interfaces.h"
-#include "hw/sysbus.h"
 #include "sysemu/cpus.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/reset.h"
 #include "sysemu/runstate.h"
-#include "sysemu/numa.h"
 #include "sysemu/xen.h"
-#include "qemu/error-report.h"
 #include "sysemu/qtest.h"
-#include "hw/pci/pci.h"
 #include "hw/mem/nvdimm.h"
 #include "migration/global_state.h"
-#include "migration/vmstate.h"
 #include "exec/confidential-guest-support.h"
-#include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-pci.h"
 #include "hw/virtio/virtio-net.h"
 
-- 
2.41.0




Re: [PATCH 5/5] accel/tcg: Restrict tcg_exec_[un]realizefn() to TCG

2023-10-03 Thread Claudio Fontana
On 9/15/23 21:00, Philippe Mathieu-Daudé wrote:
> We don't need to expose these TCG-specific methods to the
> whole code base. Register them as AccelClass handlers, they
> will be called by the generic accel_cpu_[un]realize() methods.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Claudio Fontana 

> ---
>  accel/tcg/internal.h   | 3 +++
>  include/exec/cpu-all.h | 2 --
>  accel/tcg/tcg-all.c| 2 ++
>  cpu.c  | 8 
>  4 files changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
> index e8cbbde581..57ab397df1 100644
> --- a/accel/tcg/internal.h
> +++ b/accel/tcg/internal.h
> @@ -80,6 +80,9 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, 
> uintptr_t pc);
>  void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
> uintptr_t host_pc);
>  
> +bool tcg_exec_realizefn(CPUState *cpu, Error **errp);
> +void tcg_exec_unrealizefn(CPUState *cpu);
> +
>  /* Return the current PC from CPU, which may be cached in TB. */
>  static inline vaddr log_pc(CPUState *cpu, const TranslationBlock *tb)
>  {
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 1e5c530ee1..230525ebf7 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -422,8 +422,6 @@ void dump_exec_info(GString *buf);
>  
>  /* accel/tcg/cpu-exec.c */
>  int cpu_exec(CPUState *cpu);
> -bool tcg_exec_realizefn(CPUState *cpu, Error **errp);
> -void tcg_exec_unrealizefn(CPUState *cpu);
>  
>  /**
>   * cpu_set_cpustate_pointers(cpu)
> diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
> index 03dfd67e9e..6942a9766a 100644
> --- a/accel/tcg/tcg-all.c
> +++ b/accel/tcg/tcg-all.c
> @@ -227,6 +227,8 @@ static void tcg_accel_class_init(ObjectClass *oc, void 
> *data)
>  AccelClass *ac = ACCEL_CLASS(oc);
>  ac->name = "tcg";
>  ac->init_machine = tcg_init_machine;
> +ac->realize_cpu = tcg_exec_realizefn;
> +ac->unrealize_cpu = tcg_exec_unrealizefn;
>  ac->allowed = &tcg_allowed;
>  ac->gdbstub_supported_sstep_flags = tcg_gdbstub_supported_sstep_flags;
>  
> diff --git a/cpu.c b/cpu.c
> index b928bbed50..1a8e730bed 100644
> --- a/cpu.c
> +++ b/cpu.c
> @@ -140,11 +140,6 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
>  return;
>  }
>  
> -/* NB: errp parameter is unused currently */
> -if (tcg_enabled()) {
> -tcg_exec_realizefn(cpu, errp);
> -}
> -
>  /* Wait until cpu initialization complete before exposing cpu. */
>  cpu_list_add(cpu);
>  
> @@ -190,9 +185,6 @@ void cpu_exec_unrealizefn(CPUState *cpu)
>   * accel_cpu_unrealize, which may free fields using call_rcu.
>   */
>  accel_cpu_unrealize(cpu);
> -if (tcg_enabled()) {
> -tcg_exec_unrealizefn(cpu);
> -}
>  }
>  
>  /*




Re: [PATCH v2] hw/i386: changes towards enabling -Wshadow=local

2023-10-03 Thread Ani Sinha



> On 03-Oct-2023, at 11:13 AM, Ani Sinha  wrote:
> 
> Code changes that addresses all compiler complaints coming from enabling
> -Wshadow flags. Enabling -Wshadow catches cases of local variables shadowing
> other local variables or parameters. These makes the code confusing and/or 
> adds
> bugs that are difficult to catch.
> 
> CC: Markus Armbruster 
> CC: Philippe Mathieu-Daude 
> CC: m...@redhat.com
> Message-Id: <87r0mqlf9x@pond.sub.org>
> Signed-off-by: Ani Sinha 
> Reviewed-by: Daniel P. Berrangé 
> Reviewed-by: Peter Xu 
> ---
> hw/i386/acpi-microvm.c | 4 ++--
> hw/i386/intel_iommu.c  | 8 
> hw/i386/pc.c   | 1 -
> hw/i386/x86.c  | 2 --
> 4 files changed, 6 insertions(+), 9 deletions(-)
> 
> changelog:
> v2: addressed suggestion from mst.

Please ignore this. This was supposed to be v3. I will re-send. Will split-up 
intel_iommu into a separate patch.

> 
> diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
> index a075360d85..6ddcfb0419 100644
> --- a/hw/i386/acpi-microvm.c
> +++ b/hw/i386/acpi-microvm.c
> @@ -55,8 +55,8 @@ static void acpi_dsdt_add_virtio(Aml *scope,
> 
> bus = sysbus_get_default();
> QTAILQ_FOREACH(kid, &bus->children, sibling) {
> -DeviceState *dev = kid->child;
> -Object *obj = object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MMIO);
> +Object *obj = object_dynamic_cast(OBJECT(kid->child),
> +  TYPE_VIRTIO_MMIO);
> 
> if (obj) {
> VirtIOMMIOProxy *mmio = VIRTIO_MMIO(obj);
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index c0ce896668..2c832ab68b 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -3744,7 +3744,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, 
> PCIBus *bus,
> /* Unmap the whole range in the notifier's scope. */
> static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
> {
> -hwaddr size, remain;
> +hwaddr total, remain;
> hwaddr start = n->start;
> hwaddr end = n->end;
> IntelIOMMUState *s = as->iommu_state;
> @@ -3765,7 +3765,7 @@ static void vtd_address_space_unmap(VTDAddressSpace 
> *as, IOMMUNotifier *n)
> }
> 
> assert(start <= end);
> -size = remain = end - start + 1;
> +total = remain = end - start + 1;
> 
> while (remain >= VTD_PAGE_SIZE) {
> IOMMUTLBEvent event;
> @@ -3793,10 +3793,10 @@ static void vtd_address_space_unmap(VTDAddressSpace 
> *as, IOMMUNotifier *n)
> trace_vtd_as_unmap_whole(pci_bus_num(as->bus),
>  VTD_PCI_SLOT(as->devfn),
>  VTD_PCI_FUNC(as->devfn),
> - n->start, size);
> + n->start, total);
> 
> map.iova = n->start;
> -map.size = size - 1; /* Inclusive */
> +map.size = total - 1; /* Inclusive */
> iova_tree_remove(as->iova_tree, map);
> }
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 3db0743f31..e7a233e886 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1116,7 +1116,6 @@ void pc_memory_init(PCMachineState *pcms,
> 
> if (machine->device_memory) {
> uint64_t *val = g_malloc(sizeof(*val));
> -PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
> uint64_t res_mem_end = machine->device_memory->base;
> 
> if (!pcmc->broken_reserved_end) {
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index f034df8bf6..b3d054889b 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -365,8 +365,6 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
> 
> cpu_slot = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx);
> if (!cpu_slot) {
> -MachineState *ms = MACHINE(x86ms);
> -
> x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
> error_setg(errp,
> "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
> -- 
> 2.42.0
> 




Re: [PATCH v2 5/5] hw: turn off ramfb migration for machines <= 8.1

2023-10-03 Thread Marc-André Lureau
Hi

On Mon, Oct 2, 2023 at 6:42 PM Laszlo Ersek  wrote:
>
> On 10/2/23 13:11, marcandre.lur...@redhat.com wrote:
> > From: Marc-André Lureau 
> >
> > For compatibility reasons.
> >
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  hw/core/machine.c | 5 -
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index 68cb556197..2fa7647422 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -30,7 +30,10 @@
> >  #include "hw/virtio/virtio-pci.h"
> >  #include "hw/virtio/virtio-net.h"
> >
> > -GlobalProperty hw_compat_8_1[] = {};
> > +GlobalProperty hw_compat_8_1[] = {
> > +{ "ramfb", "migrate", "off" },
> > +{ "vfio-pci-nohotplug", "ramfb-migrate", "off" }
> > +};
> >  const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
> >
> >  GlobalProperty hw_compat_8_0[] = {
>
> In the other discussion, you mentioned the concrete reason for this -- I
> think if we don't do this, then the ramfb vmstate blocks backward
> migration? Can you document the reason here explicitly (commit message,
> I mean, doesn't have to be a code comment)?

By using device section/subsection in v3, I changed a little bit the
reasons for the properties. Now it falls under the common issue
documented in migration.rst "Changing migration data structure".

>From v3, let me know if you still think we should document that better
in the commit message.

thanks

-- 
Marc-André Lureau



[PATCH RESEND] osdep: set _FORTIFY_SOURCE=2 when optimization is enabled

2023-10-03 Thread Daniel P . Berrangé
Currently we set _FORTIFY_SOURCE=2 as a compiler argument when the
meson 'optimization' setting is non-zero, the compiler is GCC and
the target is Linux.

While the default QEMU optimization level is 2, user could override
this by setting CFLAGS="-O0" or --extra-cflags="-O0" when running
configure and this won't be reflected in the meson 'optimization'
setting. As a result we try to enable _FORTIFY_SOURCE=2 and then the
user gets compile errors as it only works with optimization.

Rather than trying to improve detection in meson, it is simpler to
just check the __OPTIMIZE__ define from osdep.h.

The comment about being incompatible with clang appears to be
outdated, as compilation works fine without excluding clang.

In the coroutine code we must set _FORTIFY_SOURCE=0 to stop the
logic in osdep.h then enabling it.

Signed-off-by: Daniel P. Berrangé 
---

Re-sent due to previous bad patch submission

 include/qemu/osdep.h |  4 
 meson.build  | 10 --
 util/coroutine-sigaltstack.c |  4 ++--
 util/coroutine-ucontext.c|  4 ++--
 4 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 18b940db75..475a1c62ff 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -27,6 +27,10 @@
 #ifndef QEMU_OSDEP_H
 #define QEMU_OSDEP_H
 
+#if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__ && 
defined __linux__
+# define _FORTIFY_SOURCE 2
+#endif
+
 #include "config-host.h"
 #ifdef NEED_CPU_H
 #include CONFIG_TARGET
diff --git a/meson.build b/meson.build
index 5139db2ff7..b12ead85f6 100644
--- a/meson.build
+++ b/meson.build
@@ -479,16 +479,6 @@ if 'cpp' in all_languages
   qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', 
'-D__STDC_FORMAT_MACROS'] + qemu_cflags
 endif
 
-# clang does not support glibc + FORTIFY_SOURCE (is it still true?)
-if get_option('optimization') != '0' and targetos == 'linux'
-  if cc.get_id() == 'gcc'
-qemu_cflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
-  endif
-  if 'cpp' in all_languages and cxx.get_id() == 'gcc'
-qemu_cxxflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
-  endif
-endif
-
 add_project_arguments(qemu_cflags, native: false, language: 'c')
 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, 
language: 'c')
 if 'cpp' in all_languages
diff --git a/util/coroutine-sigaltstack.c b/util/coroutine-sigaltstack.c
index e2690c5f41..037d6416c4 100644
--- a/util/coroutine-sigaltstack.c
+++ b/util/coroutine-sigaltstack.c
@@ -22,9 +22,9 @@
  */
 
 /* XXX Is there a nicer way to disable glibc's stack check for longjmp? */
-#ifdef _FORTIFY_SOURCE
 #undef _FORTIFY_SOURCE
-#endif
+#define _FORTIFY_SOURCE 0
+
 #include "qemu/osdep.h"
 #include 
 #include "qemu/coroutine_int.h"
diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
index ddc98fb4f8..7b304c79d9 100644
--- a/util/coroutine-ucontext.c
+++ b/util/coroutine-ucontext.c
@@ -19,9 +19,9 @@
  */
 
 /* XXX Is there a nicer way to disable glibc's stack check for longjmp? */
-#ifdef _FORTIFY_SOURCE
 #undef _FORTIFY_SOURCE
-#endif
+#define _FORTIFY_SOURCE 0
+
 #include "qemu/osdep.h"
 #include 
 #include "qemu/coroutine_int.h"
-- 
2.41.0




Re: [PATCH 3/5] accel: Declare AccelClass::[un]realize_cpu() handlers

2023-10-03 Thread Philippe Mathieu-Daudé

On 3/10/23 10:55, Claudio Fontana wrote:

On 9/15/23 21:00, Philippe Mathieu-Daudé wrote:

Currently accel_cpu_realize() only performs target-specific
realization. Introduce the [un]realize_cpu fields in the
base AccelClass to be able to perform target-agnostic
[un]realization of vCPUs.

Signed-off-by: Philippe Mathieu-Daudé 


Just thinking, for the benefit of the reader trying to understand the code 
later on,
maybe putting in a "target_" in there somewhere in the function name?
like "realize_cpu_target", vs "realize_cpu_generic" ?


Good idea, I like it, thanks!




Re: [PATCH v3 4/5] ramfb-standalone: add migration support

2023-10-03 Thread Laszlo Ersek
On 10/3/23 10:56, marcandre.lur...@redhat.com wrote:
> From: Marc-André Lureau 
> 
> Add a "ramfb-dev" section whenever "x-migrate" is turned on. Turn it off
> by default on machines <= 8.1 for compatibility reasons.
> 
> Signed-off-by: Marc-André Lureau 
> ---
>  hw/core/machine.c |  4 +++-
>  hw/display/ramfb-standalone.c | 27 +++
>  2 files changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index df40f10dfa..47a07d1d9b 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -30,7 +30,9 @@
>  #include "hw/virtio/virtio-pci.h"
>  #include "hw/virtio/virtio-net.h"
>  
> -GlobalProperty hw_compat_8_1[] = {};
> +GlobalProperty hw_compat_8_1[] = {
> +{ "ramfb", "x-migrate", "off" },
> +};
>  const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
>  
>  GlobalProperty hw_compat_8_0[] = {
> diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c
> index 8c0094397f..a96e7ebcd9 100644
> --- a/hw/display/ramfb-standalone.c
> +++ b/hw/display/ramfb-standalone.c
> @@ -1,4 +1,5 @@
>  #include "qemu/osdep.h"
> +#include "migration/vmstate.h"
>  #include "qapi/error.h"
>  #include "qemu/module.h"
>  #include "hw/loader.h"
> @@ -15,6 +16,7 @@ struct RAMFBStandaloneState {
>  SysBusDevice parent_obj;
>  QemuConsole *con;
>  RAMFBState *state;
> +bool migrate;
>  };
>  
>  static void display_update_wrapper(void *dev)
> @@ -40,14 +42,39 @@ static void ramfb_realizefn(DeviceState *dev, Error 
> **errp)
>  ramfb->state = ramfb_setup(errp);
>  }
>  
> +static bool migrate_needed(void *opaque)
> +{
> +RAMFBStandaloneState *ramfb = RAMFB(opaque);
> +
> +return ramfb->migrate;
> +}
> +
> +static const VMStateDescription ramfb_dev_vmstate = {
> +.name = "ramfb-dev",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.needed = migrate_needed,
> +.fields = (VMStateField[]) {
> +VMSTATE_STRUCT_POINTER(state, RAMFBStandaloneState, ramfb_vmstate, 
> RAMFBState),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
> +static Property ramfb_properties[] = {
> +DEFINE_PROP_BOOL("x-migrate", RAMFBStandaloneState, migrate,  true),
> +DEFINE_PROP_END_OF_LIST(),
> +};
> +
>  static void ramfb_class_initfn(ObjectClass *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
>  set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
> +dc->vmsd = &ramfb_dev_vmstate;
>  dc->realize = ramfb_realizefn;
>  dc->desc = "ram framebuffer standalone device";
>  dc->user_creatable = true;
> +device_class_set_props(dc, ramfb_properties);
>  }
>  
>  static const TypeInfo ramfb_info = {

This patch (and patch #3) is *exactly* what I had in mind, when I was
racking my brain about RHBZ 1859424 a week (or a few weeks?) ago.
Specifically the VMSTATE_STRUCT_POINTER + VMSTATE_BUFFER_UNSAFE chain.

That's not to say I could have *completed* the patch myself, of course.
:) (From the many things, I didn't know that it was
VMSTATE_BUFFER_UNSAFE that we'd need -- but I certainly thought of
VMSTATE_STRUCT_POINTER for the higher-level devices.)

It's interesting that we don't have to do this in a "subsection" here --
this device used to have no VMStateDescription at all!

FWIW (patches #3 and #4):

Reviewed-by: Laszlo Ersek 

Laszlo




Re: [PATCH v4] block-jobs: flush target at the end of .run()

2023-10-03 Thread Vladimir Sementsov-Ogievskiy

On 03.08.23 05:43, Evanzhang wrote:

[...]


diff --git a/block/mirror.c b/block/mirror.c
index d3cacd1708..cd19b49f7f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1143,6 +1143,10 @@ immediate_exit:
 g_free(s->in_flight_bitmap);
 bdrv_dirty_iter_free(s->dbi);

+if (ret >= 0) {
+ret = block_job_final_target_flush(&s->common, blk_bs(s->target));
+}
+
 if (need_drain) {
 s->in_drain = true;
 bdrv_drained_begin(bs);


hi,I use gdb tested drive-mirror,break block_job_final_target_flush,
mirror_run  was not called it.
qmp command:
{"execute": "drive-mirror","arguments": {"device": "drive-virtio1","target":
"./data1.test","sync": "full"}}


Sorry for long answer. I"m going to resend a new version soon.

I now checked, and I see that block_job_final_target_flush() is called.

But it is called after executing block-job-complete command.




--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -152,4 +152,15 @@ void block_job_ratelimit_sleep(BlockJob *job);
BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
 int is_read, int error);

+/**
+ * block_job_final_target_flush:
+ * @job: The job to signal an error for if flush failed.
+ * @target_bs: The bs to flush.
+ *
+ * The function is intended to be called at the end of .run() for any data
+ * copying job.
+ */
+int coroutine_fn
+block_job_final_target_flush(BlockJob *job, BlockDriverState *target_bs);
+
#endif
--
2.34.1


--
Best regards,
Vladimir




Re: [PULL 01/24] optionrom: Remove build-id section

2023-10-03 Thread Michael Tokarev

03.10.2023 11:30, Paolo Bonzini wrote:

From: Fabiano Rosas 

Our linker script for optionroms specifies only the placement of the
.text section, leaving the linker free to place the remaining sections
at arbitrary places in the file.

..


Cc: sta...@vger.kernel.org


Are you sure you mean *that* stable? :)

/mjt



[PATCH v3 00/15] Prerequisite changes for IOMMUFD support

2023-10-03 Thread Eric Auger
Hi All, 

With the agreement of Zhenzhong, here is a v3 respin of the IOMMUFD
prerequisite series. This applies on top of vfio-next:
https://github.com/legoater/qemu/, branch vfio-next.

Per Cédric's suggestion, the IOMMUFD patchset v1[1] is now split
into two series, this prerequisite series and the new IOMMUFD backend
introduction support series. Hopefully this will ease the review.

The main purpose of this series is to make "common.c" group agnostic:
all group related code are moved into container.c. Then we are prepared
for next series, abstract base container, adding new backend, etc.

This series can be found at :
https://github.com/eauger/qemu/tree/prereq_v3

Test done:
- PCI device were tested
- device hotplug test
- with or without vIOMMU
- VFIO migration with a E800 net card(no dirty sync support) passthrough
- platform, ccw and ap were only compile-tested due to environment limit

Zhenzhong, Yi, Eric

[1] 
https://lore.kernel.org/all/20230830103754.36461-1-zhenzhong.d...@intel.com/t/#u

Changelog:

v3:
- rebased on vfio-next as suggested by Cedric
- added vfio/common: Propagate KVM_SET_DEVICE_ATTR error if any
- collected Cedric's R-b
- Fix some error paths in vfio/cpi which now properly detach the device
  and also free the vbasedev->name
- Fix vfio/ccw migration (hopefully) [Matthew inputs]
- Split [PATCH v2 11/12] vfio/common: Introduce two kinds of VFIO device lists
  into 3 patches

v2:
- Refine patch description per Eric
- return errno and errp in vfio_kvm_device_[add/del]_fd per Eric
- make memory listener register/deregister in seperate patch per Eric
- Include the .h file first per Cédric
- Add trace event in vfio_attach_device per Cédric
- drop the change to vfio_viommu_preset by refactor per Cédric
- Introduce global VFIO device list and per container list per Alex

Note changelog below are from full IOMMUFD series:

v1:
- Alloc hwpt instead of using auto hwpt
- elaborate iommufd code per Nicolin
- consolidate two patches and drop as.c
- typo error fix and function rename

rfcv4:
- rebase on top of v8.0.3
- Add one patch from Yi which is about vfio device add in kvm
- Remove IOAS_COPY optimization and focus on functions in this patchset
- Fix wrong name issue reported and fix suggested by Matthew
- Fix compilation issue reported and fix sugggsted by Nicolin
- Use query_dirty_bitmap callback to replace get_dirty_bitmap for better
granularity
- Add dev_iter_next() callback to avoid adding so many callback
  at container scope, add VFIODevice.hwpt to support that
- Restore all functions back to common from container whenever possible,
  mainly migration and reset related functions
- Add --enable/disable-iommufd config option, enabled by default in linux
- Remove VFIODevice.hwpt_next as it's redundant with VFIODevice.next
- Adapt new VFIO_DEVICE_PCI_HOT_RESET uAPI for IOMMUFD backed device
- vfio_kvm_device_add/del_group call vfio_kvm_device_add/del_fd to remove
redundant code
- Add FD passing support for vfio device backed by IOMMUFD
- Fix hot unplug resource leak issue in vfio_legacy_detach_device()
- Fix FD leak in vfio_get_devicefd()

rfcv3:
- rebase on top of v7.2.0
- Fix the compilation with CONFIG_IOMMUFD unset by using true classes for
  VFIO backends
- Fix use after free in error path, reported by Alister
- Split common.c in several steps to ease the review

rfcv2:
- remove the first three patches of rfcv1
- add open cdev helper suggested by Jason
- remove the QOMification of the VFIOContainer and simply use standard ops
(David)
- add "-object iommufd" suggested by Alex

Thanks
Zhenzhong

Eric Auger (7):
  scripts/update-linux-headers: Add iommufd.h
  vfio/common: Propagate KVM_SET_DEVICE_ATTR error if any
  vfio/common: Introduce vfio_container_add|del_section_window()
  vfio/pci: Introduce vfio_[attach/detach]_device
  vfio/platform: Use vfio_[attach/detach]_device
  vfio/ap: Use vfio_[attach/detach]_device
  vfio/ccw: Use vfio_[attach/detach]_device

Yi Liu (2):
  vfio/common: Move IOMMU agnostic helpers to a separate file
  vfio/common: Move legacy VFIO backend code into separate container.c

Zhenzhong Duan (6):
  linux-headers: Add iommufd.h
  vfio/common: Extract out vfio_kvm_device_[add/del]_fd
  vfio/common: Move VFIO reset handler registration to a group agnostic
function
  vfio/common: Introduce a per container device list
  vfio/common: Store the parent container in VFIODevice
  vfio/common: Introduce a global VFIODevice list

 include/hw/vfio/vfio-common.h   |   60 +-
 linux-headers/linux/iommufd.h   |  444 
 hw/vfio/ap.c|   70 +-
 hw/vfio/ccw.c   |  122 +-
 hw/vfio/common.c| 1851 ++-
 hw/vfio/container.c | 1156 +++
 hw/vfio/helpers.c   |  611 ++
 hw/vfio/pci.c   |   67 +-
 hw/vfio/platform.c  |   43 +-
 hw/vfio/meson.build |2 +
 hw/vfio/trace-events|4 +-
 scripts/update

[PATCH v3 08/15] vfio/platform: Use vfio_[attach/detach]_device

2023-10-03 Thread Eric Auger
Let the vfio-platform device use vfio_attach_device() and
vfio_detach_device(), hence hiding the details of the used
IOMMU backend.

Drop the trace event for vfio-platform as we have similar
one in vfio_attach_device.

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
---
 hw/vfio/platform.c   | 43 +++
 hw/vfio/trace-events |  1 -
 2 files changed, 3 insertions(+), 41 deletions(-)

diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 5af73f9287..8e3d4ac458 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -529,12 +529,7 @@ static VFIODeviceOps vfio_platform_ops = {
  */
 static int vfio_base_device_init(VFIODevice *vbasedev, Error **errp)
 {
-VFIOGroup *group;
-VFIODevice *vbasedev_iter;
-char *tmp, group_path[PATH_MAX], *group_name;
-ssize_t len;
 struct stat st;
-int groupid;
 int ret;
 
 /* @sysfsdev takes precedence over @host */
@@ -557,47 +552,15 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
 return -errno;
 }
 
-tmp = g_strdup_printf("%s/iommu_group", vbasedev->sysfsdev);
-len = readlink(tmp, group_path, sizeof(group_path));
-g_free(tmp);
-
-if (len < 0 || len >= sizeof(group_path)) {
-ret = len < 0 ? -errno : -ENAMETOOLONG;
-error_setg_errno(errp, -ret, "no iommu_group found");
-return ret;
-}
-
-group_path[len] = 0;
-
-group_name = basename(group_path);
-if (sscanf(group_name, "%d", &groupid) != 1) {
-error_setg_errno(errp, errno, "failed to read %s", group_path);
-return -errno;
-}
-
-trace_vfio_platform_base_device_init(vbasedev->name, groupid);
-
-group = vfio_get_group(groupid, &address_space_memory, errp);
-if (!group) {
-return -ENOENT;
-}
-
-QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
-if (strcmp(vbasedev_iter->name, vbasedev->name) == 0) {
-error_setg(errp, "device is already attached");
-vfio_put_group(group);
-return -EBUSY;
-}
-}
-ret = vfio_get_device(group, vbasedev->name, vbasedev, errp);
+ret = vfio_attach_device(vbasedev->name, vbasedev,
+ &address_space_memory, errp);
 if (ret) {
-vfio_put_group(group);
 return ret;
 }
 
 ret = vfio_populate_device(vbasedev, errp);
 if (ret) {
-vfio_put_group(group);
+vfio_detach_device(vbasedev);
 }
 
 return ret;
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 8ac13eb106..0eb2387cf2 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -121,7 +121,6 @@ vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, 
uint64_t bitmap_size
 vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu 
dirty @ 0x%"PRIx64" - 0x%"PRIx64
 
 # platform.c
-vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group 
#%d"
 vfio_platform_realize(char *name, char *compat) "vfio device %s, compat = %s"
 vfio_platform_eoi(int pin, int fd) "EOI IRQ pin %d (fd=%d)"
 vfio_platform_intp_mmap_enable(int pin) "IRQ #%d still active, stay in slow 
path"
-- 
2.41.0




Re: [PATCH v3 5/5] hw/vfio: add ramfb migration support

2023-10-03 Thread Cédric Le Goater

On 10/3/23 10:56, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

Add a "VFIODisplay" subsection whenever "x-ramfb-migrate" is turned on.

Turn it off by default on machines <= 8.1 for compatibility reasons.



This change breaks linking on various platforms with :

/usr/bin/ld: libqemu-xtensa-softmmu.fa.p/hw_vfio_display.c.o:(.data.rel+0x50): 
undefined reference to `ramfb_vmstate'

Some stubs updates are missing it seems..

Thanks,

C.



Signed-off-by: Marc-André Lureau 
---
  hw/vfio/pci.h |  3 +++
  hw/core/machine.c |  1 +
  hw/vfio/display.c | 23 +++
  hw/vfio/pci.c | 32 
  4 files changed, 59 insertions(+)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 2d836093a8..fd06695542 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -173,6 +173,7 @@ struct VFIOPCIDevice {
  bool no_kvm_ioeventfd;
  bool no_vfio_ioeventfd;
  bool enable_ramfb;
+OnOffAuto ramfb_migrate;
  bool defer_kvm_irq_routing;
  bool clear_parent_atomics_on_exit;
  VFIODisplay *dpy;
@@ -226,4 +227,6 @@ void vfio_display_reset(VFIOPCIDevice *vdev);
  int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
  void vfio_display_finalize(VFIOPCIDevice *vdev);
  
+extern const VMStateDescription vfio_display_vmstate;

+
  #endif /* HW_VFIO_VFIO_PCI_H */
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 47a07d1d9b..f2f8940a85 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -32,6 +32,7 @@
  
  GlobalProperty hw_compat_8_1[] = {

  { "ramfb", "x-migrate", "off" },
+{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }
  };
  const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
  
diff --git a/hw/vfio/display.c b/hw/vfio/display.c

index bec864f482..de5bf71dd1 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -542,3 +542,26 @@ void vfio_display_finalize(VFIOPCIDevice *vdev)
  vfio_display_edid_exit(vdev->dpy);
  g_free(vdev->dpy);
  }
+
+static bool migrate_needed(void *opaque)
+{
+/*
+ * If we are here, it's because vfio_display_needed(), which is only true
+ * when dpy->ramfb_migrate atm.
+ *
+ * If the migration condition is changed, we should check here if
+ * ramfb_migrate is true. (this will need a way to lookup the associated
+ * VFIOPCIDevice somehow, or fields to be moved, ..)
+ */
+return true;
+}
+
+const VMStateDescription vfio_display_vmstate = {
+.name = "VFIODisplay",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = migrate_needed,
+.fields = (VMStateField[]) {
+VMSTATE_STRUCT_POINTER(ramfb, VFIODisplay, ramfb_vmstate, RAMFBState),
+}
+};
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 3b2ca3c24c..4689f2e5c1 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2608,6 +2608,25 @@ static bool vfio_msix_present(void *opaque, int 
version_id)
  return msix_present(pdev);
  }
  
+static bool vfio_display_needed(void *opaque)

+{
+VFIOPCIDevice *vdev = opaque;
+
+/* the only thing that justifies the VFIODisplay sub-section atm */
+return vdev->ramfb_migrate != ON_OFF_AUTO_OFF;
+}
+
+const VMStateDescription vmstate_vfio_display = {
+.name = "VFIOPCIDevice/VFIODisplay",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = vfio_display_needed,
+.fields = (VMStateField[]){
+VMSTATE_STRUCT_POINTER(dpy, VFIOPCIDevice, vfio_display_vmstate, 
VFIODisplay),
+VMSTATE_END_OF_LIST()
+}
+};
+
  const VMStateDescription vmstate_vfio_pci_config = {
  .name = "VFIOPCIDevice",
  .version_id = 1,
@@ -2616,6 +2635,10 @@ const VMStateDescription vmstate_vfio_pci_config = {
  VMSTATE_PCI_DEVICE(pdev, VFIOPCIDevice),
  VMSTATE_MSIX_TEST(pdev, VFIOPCIDevice, vfio_msix_present),
  VMSTATE_END_OF_LIST()
+},
+.subsections = (const VMStateDescription*[]) {
+&vmstate_vfio_display,
+NULL
  }
  };
  
@@ -3275,6 +3298,14 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)

  if (!vfio_migration_realize(vbasedev, errp)) {
  goto out_deregister;
  }
+if (vbasedev->enable_migration == ON_OFF_AUTO_OFF) {
+if (vdev->ramfb_migrate == ON_OFF_AUTO_AUTO) {
+vdev->ramfb_migrate = ON_OFF_AUTO_OFF;
+} else if (vdev->ramfb_migrate == ON_OFF_AUTO_ON) {
+error_setg(errp, "x-ramfb-migrate requires migration");
+goto out_deregister;
+}
+}
  }
  
  vfio_register_err_notifier(vdev);

@@ -3484,6 +3515,7 @@ static const TypeInfo vfio_pci_dev_info = {
  
  static Property vfio_pci_dev_nohotplug_properties[] = {

  DEFINE_PROP_BOOL("ramfb", VFIOPCIDevice, enable_ramfb, false),
+DEFINE_PROP_ON_OFF_AUTO("x-ramfb-migrate", VFIOPCIDevice, ramfb_migrate, 
ON_OFF_AUTO_AUTO),
  DEFINE_PROP_END_OF_LIST(),
  };
  





[PATCH v3 04/15] vfio/common: Propagate KVM_SET_DEVICE_ATTR error if any

2023-10-03 Thread Eric Auger
In the VFIO_SPAPR_TCE_v2_IOMMU container case, when
KVM_SET_DEVICE_ATTR fails, we currently don't propagate the
error as we do on the vfio_spapr_create_window() failure
case. Let's align the code. Take the opportunity to
reword the error message and make it more explicit.

Signed-off-by: Eric Auger 

---

I think thise should end up in the
if (!container->initialized) {
if (!container->error) {
path and call the error_propagate_prepend()
---
 hw/vfio/common.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 4e122fc4e4..c54a72ec80 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -878,11 +878,11 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 QLIST_FOREACH(group, &container->group_list, container_next) {
 param.groupfd = group->fd;
 if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) 
{
-error_report("vfio: failed to setup fd %d "
- "for a group with fd %d: %s",
- param.tablefd, param.groupfd,
- strerror(errno));
-return;
+error_setg_errno(&err, errno,
+ "vfio: failed GROUP_SET_SPAPR_TCE for 
"
+ "KVM VFIO device %d and group fd %d",
+ param.tablefd, param.groupfd);
+goto fail;
 }
 trace_vfio_spapr_group_attach(param.groupfd, 
param.tablefd);
 }
-- 
2.41.0




[PATCH v3 07/15] vfio/pci: Introduce vfio_[attach/detach]_device

2023-10-03 Thread Eric Auger
We want the VFIO devices to be able to use two different
IOMMU backends, the legacy VFIO one and the new iommufd one.

Introduce vfio_[attach/detach]_device which aim at hiding the
underlying IOMMU backend (IOCTLs, datatypes, ...).

Once vfio_attach_device completes, the device is attached
to a security context and its fd can be used. Conversely
When vfio_detach_device completes, the device has been
detached from the security context.

At the moment only the implementation based on the legacy
container/group exists. Let's use it from the vfio-pci device.
Subsequent patches will handle other devices.

We also take benefit of this patch to properly free
vbasedev->name on failure.

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 

---

v2 -> v3:
- added trace_vfio_detach_device
- added a comment explaining why we pass @name to vfio_attach_device
  although vbasedev->name is populated
- free vbasedev->name and detach_device if needed
---
 include/hw/vfio/vfio-common.h |  3 ++
 hw/vfio/common.c  | 74 +++
 hw/vfio/pci.c | 67 +++
 hw/vfio/trace-events  |  3 +-
 4 files changed, 94 insertions(+), 53 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index c4e7c3b4a7..12fbfbc37d 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -225,6 +225,9 @@ void vfio_put_group(VFIOGroup *group);
 struct vfio_device_info *vfio_get_device_info(int fd);
 int vfio_get_device(VFIOGroup *group, const char *name,
 VFIODevice *vbasedev, Error **errp);
+int vfio_attach_device(char *name, VFIODevice *vbasedev,
+   AddressSpace *as, Error **errp);
+void vfio_detach_device(VFIODevice *vbasedev);
 
 int vfio_kvm_device_add_fd(int fd, Error **errp);
 int vfio_kvm_device_del_fd(int fd, Error **errp);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index d8ed432cb6..f4c33c9858 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -2611,3 +2611,77 @@ int vfio_eeh_as_op(AddressSpace *as, uint32_t op)
 }
 return vfio_eeh_container_op(container, op);
 }
+
+static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp)
+{
+char *tmp, group_path[PATH_MAX], *group_name;
+int ret, groupid;
+ssize_t len;
+
+tmp = g_strdup_printf("%s/iommu_group", vbasedev->sysfsdev);
+len = readlink(tmp, group_path, sizeof(group_path));
+g_free(tmp);
+
+if (len <= 0 || len >= sizeof(group_path)) {
+ret = len < 0 ? -errno : -ENAMETOOLONG;
+error_setg_errno(errp, -ret, "no iommu_group found");
+return ret;
+}
+
+group_path[len] = 0;
+
+group_name = basename(group_path);
+if (sscanf(group_name, "%d", &groupid) != 1) {
+error_setg_errno(errp, errno, "failed to read %s", group_path);
+return -errno;
+}
+return groupid;
+}
+
+/*
+ * vfio_attach_device: attach a device to a security context
+ * @name and @vbasedev->name are likely to be different depending
+ * on the type of the device, hence the need for passing @name
+ */
+int vfio_attach_device(char *name, VFIODevice *vbasedev,
+   AddressSpace *as, Error **errp)
+{
+int groupid = vfio_device_groupid(vbasedev, errp);
+VFIODevice *vbasedev_iter;
+VFIOGroup *group;
+int ret;
+
+if (groupid < 0) {
+return groupid;
+}
+
+trace_vfio_attach_device(vbasedev->name, groupid);
+
+group = vfio_get_group(groupid, as, errp);
+if (!group) {
+return -ENOENT;
+}
+
+QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
+if (strcmp(vbasedev_iter->name, vbasedev->name) == 0) {
+error_setg(errp, "device is already attached");
+vfio_put_group(group);
+return -EBUSY;
+}
+}
+ret = vfio_get_device(group, name, vbasedev, errp);
+if (ret) {
+vfio_put_group(group);
+}
+
+return ret;
+}
+
+void vfio_detach_device(VFIODevice *vbasedev)
+{
+VFIOGroup *group = vbasedev->group;
+
+trace_vfio_detach_device(vbasedev->name, group->groupid);
+vfio_put_base_device(vbasedev);
+vfio_put_group(group);
+}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 898296fd54..60e10d0eee 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2895,10 +2895,10 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 
 static void vfio_pci_put_device(VFIOPCIDevice *vdev)
 {
+vfio_detach_device(&vdev->vbasedev);
+
 g_free(vdev->vbasedev.name);
 g_free(vdev->msix);
-
-vfio_put_base_device(&vdev->vbasedev);
 }
 
 static void vfio_err_notifier_handler(void *opaque)
@@ -3045,13 +3045,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 {
 VFIOPCIDevice *vdev = VFIO_PCI(pdev);
 VFIODevice *vbasedev = &vdev->vbasedev;
-VFIODevice *vbasedev_iter;
-VFIOGroup *group;
-char *tmp, *subsys, group_path[PATH_MAX], *group_

[PATCH v3 02/15] linux-headers: Add iommufd.h

2023-10-03 Thread Eric Auger
From: Zhenzhong Duan 

Since commit da3c22c74a3c ("linux-headers: Update to Linux v6.6-rc1"),
linux-headers has been updated to v6.6-rc1.

As previous patch added iommufd.h to update-linux-headers.sh,
run the script again against TAG v6.6-rc1 to have iommufd.h included.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
---
 linux-headers/linux/iommufd.h | 444 ++
 1 file changed, 444 insertions(+)
 create mode 100644 linux-headers/linux/iommufd.h

diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h
new file mode 100644
index 00..218bf7ac98
--- /dev/null
+++ b/linux-headers/linux/iommufd.h
@@ -0,0 +1,444 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES.
+ */
+#ifndef _IOMMUFD_H
+#define _IOMMUFD_H
+
+#include 
+#include 
+
+#define IOMMUFD_TYPE (';')
+
+/**
+ * DOC: General ioctl format
+ *
+ * The ioctl interface follows a general format to allow for extensibility. 
Each
+ * ioctl is passed in a structure pointer as the argument providing the size of
+ * the structure in the first u32. The kernel checks that any structure space
+ * beyond what it understands is 0. This allows userspace to use the backward
+ * compatible portion while consistently using the newer, larger, structures.
+ *
+ * ioctls use a standard meaning for common errnos:
+ *
+ *  - ENOTTY: The IOCTL number itself is not supported at all
+ *  - E2BIG: The IOCTL number is supported, but the provided structure has
+ *non-zero in a part the kernel does not understand.
+ *  - EOPNOTSUPP: The IOCTL number is supported, and the structure is
+ *understood, however a known field has a value the kernel does not
+ *understand or support.
+ *  - EINVAL: Everything about the IOCTL was understood, but a field is not
+ *correct.
+ *  - ENOENT: An ID or IOVA provided does not exist.
+ *  - ENOMEM: Out of memory.
+ *  - EOVERFLOW: Mathematics overflowed.
+ *
+ * As well as additional errnos, within specific ioctls.
+ */
+enum {
+   IOMMUFD_CMD_BASE = 0x80,
+   IOMMUFD_CMD_DESTROY = IOMMUFD_CMD_BASE,
+   IOMMUFD_CMD_IOAS_ALLOC,
+   IOMMUFD_CMD_IOAS_ALLOW_IOVAS,
+   IOMMUFD_CMD_IOAS_COPY,
+   IOMMUFD_CMD_IOAS_IOVA_RANGES,
+   IOMMUFD_CMD_IOAS_MAP,
+   IOMMUFD_CMD_IOAS_UNMAP,
+   IOMMUFD_CMD_OPTION,
+   IOMMUFD_CMD_VFIO_IOAS,
+   IOMMUFD_CMD_HWPT_ALLOC,
+   IOMMUFD_CMD_GET_HW_INFO,
+};
+
+/**
+ * struct iommu_destroy - ioctl(IOMMU_DESTROY)
+ * @size: sizeof(struct iommu_destroy)
+ * @id: iommufd object ID to destroy. Can be any destroyable object type.
+ *
+ * Destroy any object held within iommufd.
+ */
+struct iommu_destroy {
+   __u32 size;
+   __u32 id;
+};
+#define IOMMU_DESTROY _IO(IOMMUFD_TYPE, IOMMUFD_CMD_DESTROY)
+
+/**
+ * struct iommu_ioas_alloc - ioctl(IOMMU_IOAS_ALLOC)
+ * @size: sizeof(struct iommu_ioas_alloc)
+ * @flags: Must be 0
+ * @out_ioas_id: Output IOAS ID for the allocated object
+ *
+ * Allocate an IO Address Space (IOAS) which holds an IO Virtual Address (IOVA)
+ * to memory mapping.
+ */
+struct iommu_ioas_alloc {
+   __u32 size;
+   __u32 flags;
+   __u32 out_ioas_id;
+};
+#define IOMMU_IOAS_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_ALLOC)
+
+/**
+ * struct iommu_iova_range - ioctl(IOMMU_IOVA_RANGE)
+ * @start: First IOVA
+ * @last: Inclusive last IOVA
+ *
+ * An interval in IOVA space.
+ */
+struct iommu_iova_range {
+   __aligned_u64 start;
+   __aligned_u64 last;
+};
+
+/**
+ * struct iommu_ioas_iova_ranges - ioctl(IOMMU_IOAS_IOVA_RANGES)
+ * @size: sizeof(struct iommu_ioas_iova_ranges)
+ * @ioas_id: IOAS ID to read ranges from
+ * @num_iovas: Input/Output total number of ranges in the IOAS
+ * @__reserved: Must be 0
+ * @allowed_iovas: Pointer to the output array of struct iommu_iova_range
+ * @out_iova_alignment: Minimum alignment required for mapping IOVA
+ *
+ * Query an IOAS for ranges of allowed IOVAs. Mapping IOVA outside these ranges
+ * is not allowed. num_iovas will be set to the total number of iovas and
+ * the allowed_iovas[] will be filled in as space permits.
+ *
+ * The allowed ranges are dependent on the HW path the DMA operation takes, and
+ * can change during the lifetime of the IOAS. A fresh empty IOAS will have a
+ * full range, and each attached device will narrow the ranges based on that
+ * device's HW restrictions. Detaching a device can widen the ranges. Userspace
+ * should query ranges after every attach/detach to know what IOVAs are valid
+ * for mapping.
+ *
+ * On input num_iovas is the length of the allowed_iovas array. On output it is
+ * the total number of iovas filled in. The ioctl will return -EMSGSIZE and set
+ * num_iovas to the required value if num_iovas is too small. In this case the
+ * caller should allocate a larger output array and re-issue the ioctl.
+ *
+ * out_iova_alignment returns the minimum IOVA alignment that can be given
+ * to IOMMU

[PATCH v3 09/15] vfio/ap: Use vfio_[attach/detach]_device

2023-10-03 Thread Eric Auger
Let the vfio-ap device use vfio_attach_device() and
vfio_detach_device(), hence hiding the details of the used
IOMMU backend.

We take the opportunity to use g_path_get_basename() which
is prefered, as suggested by
3e015d815b ("use g_path_get_basename instead of basename")

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 

---

v2 -> v3:
- Mention g_path_get_basename in commit message and properly free
  vbasedev->name, call vfio_detach_device
---
 hw/vfio/ap.c | 70 ++--
 1 file changed, 13 insertions(+), 57 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 6e21d1da5a..d0b587b3b1 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -53,40 +53,6 @@ struct VFIODeviceOps vfio_ap_ops = {
 .vfio_compute_needs_reset = vfio_ap_compute_needs_reset,
 };
 
-static void vfio_ap_put_device(VFIOAPDevice *vapdev)
-{
-g_free(vapdev->vdev.name);
-vfio_put_base_device(&vapdev->vdev);
-}
-
-static VFIOGroup *vfio_ap_get_group(VFIOAPDevice *vapdev, Error **errp)
-{
-GError *gerror = NULL;
-char *symlink, *group_path;
-int groupid;
-
-symlink = g_strdup_printf("%s/iommu_group", vapdev->vdev.sysfsdev);
-group_path = g_file_read_link(symlink, &gerror);
-g_free(symlink);
-
-if (!group_path) {
-error_setg(errp, "%s: no iommu_group found for %s: %s",
-   TYPE_VFIO_AP_DEVICE, vapdev->vdev.sysfsdev, 
gerror->message);
-g_error_free(gerror);
-return NULL;
-}
-
-if (sscanf(basename(group_path), "%d", &groupid) != 1) {
-error_setg(errp, "vfio: failed to read %s", group_path);
-g_free(group_path);
-return NULL;
-}
-
-g_free(group_path);
-
-return vfio_get_group(groupid, &address_space_memory, errp);
-}
-
 static void vfio_ap_req_notifier_handler(void *opaque)
 {
 VFIOAPDevice *vapdev = opaque;
@@ -189,22 +155,15 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice 
*vapdev,
 static void vfio_ap_realize(DeviceState *dev, Error **errp)
 {
 int ret;
-char *mdevid;
 Error *err = NULL;
-VFIOGroup *vfio_group;
 APDevice *apdev = AP_DEVICE(dev);
 VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
+VFIODevice *vbasedev = &vapdev->vdev;
 
-vfio_group = vfio_ap_get_group(vapdev, errp);
-if (!vfio_group) {
-return;
-}
-
-vapdev->vdev.ops = &vfio_ap_ops;
-vapdev->vdev.type = VFIO_DEVICE_TYPE_AP;
-mdevid = basename(vapdev->vdev.sysfsdev);
-vapdev->vdev.name = g_strdup_printf("%s", mdevid);
-vapdev->vdev.dev = dev;
+vbasedev->name = g_path_get_basename(vbasedev->sysfsdev);
+vbasedev->ops = &vfio_ap_ops;
+vbasedev->type = VFIO_DEVICE_TYPE_AP;
+vbasedev->dev = dev;
 
 /*
  * vfio-ap devices operate in a way compatible with discarding of
@@ -214,9 +173,11 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
  */
 vapdev->vdev.ram_block_discard_allowed = true;
 
-ret = vfio_get_device(vfio_group, mdevid, &vapdev->vdev, errp);
+ret = vfio_attach_device(vbasedev->name, vbasedev,
+ &address_space_memory, errp);
 if (ret) {
-goto out_get_dev_err;
+g_free(vbasedev->name);
+return;
 }
 
 vfio_ap_register_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX, &err);
@@ -225,25 +186,20 @@ static void vfio_ap_realize(DeviceState *dev, Error 
**errp)
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
  */
+vfio_detach_device(vbasedev);
 error_report_err(err);
+g_free(vbasedev->name);
 }
-
-return;
-
-out_get_dev_err:
-vfio_ap_put_device(vapdev);
-vfio_put_group(vfio_group);
 }
 
 static void vfio_ap_unrealize(DeviceState *dev)
 {
 APDevice *apdev = AP_DEVICE(dev);
 VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
-VFIOGroup *group = vapdev->vdev.group;
 
 vfio_ap_unregister_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX);
-vfio_ap_put_device(vapdev);
-vfio_put_group(group);
+vfio_detach_device(&vapdev->vdev);
+g_free(vapdev->vdev.name);
 }
 
 static Property vfio_ap_properties[] = {
-- 
2.41.0




[PATCH v3 11/15] vfio/common: Move VFIO reset handler registration to a group agnostic function

2023-10-03 Thread Eric Auger
From: Zhenzhong Duan 

Move the reset handler registration/unregistration to a place that is not
group specific. vfio_[get/put]_address_space are the best places for that
purpose.

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
---
 hw/vfio/common.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 56cfe94d97..019da387d2 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1909,6 +1909,10 @@ static VFIOAddressSpace 
*vfio_get_address_space(AddressSpace *as)
 space->as = as;
 QLIST_INIT(&space->containers);
 
+if (QLIST_EMPTY(&vfio_address_spaces)) {
+qemu_register_reset(vfio_reset_handler, NULL);
+}
+
 QLIST_INSERT_HEAD(&vfio_address_spaces, space, list);
 
 return space;
@@ -1920,6 +1924,9 @@ static void vfio_put_address_space(VFIOAddressSpace 
*space)
 QLIST_REMOVE(space, list);
 g_free(space);
 }
+if (QLIST_EMPTY(&vfio_address_spaces)) {
+qemu_unregister_reset(vfio_reset_handler, NULL);
+}
 }
 
 /*
@@ -2385,10 +2392,6 @@ static VFIOGroup *vfio_get_group(int groupid, 
AddressSpace *as, Error **errp)
 goto close_fd_exit;
 }
 
-if (QLIST_EMPTY(&vfio_group_list)) {
-qemu_register_reset(vfio_reset_handler, NULL);
-}
-
 QLIST_INSERT_HEAD(&vfio_group_list, group, next);
 
 return group;
@@ -2417,10 +2420,6 @@ static void vfio_put_group(VFIOGroup *group)
 trace_vfio_put_group(group->fd);
 close(group->fd);
 g_free(group);
-
-if (QLIST_EMPTY(&vfio_group_list)) {
-qemu_unregister_reset(vfio_reset_handler, NULL);
-}
 }
 
 struct vfio_device_info *vfio_get_device_info(int fd)
-- 
2.41.0




[PATCH v3 10/15] vfio/ccw: Use vfio_[attach/detach]_device

2023-10-03 Thread Eric Auger
Let the vfio-ccw device use vfio_attach_device() and
vfio_detach_device(), hence hiding the details of the used
IOMMU backend.

Note that the migration reduces the following trace
"vfio: subchannel %s has already been attached" (featuring
cssid.ssid.devid) into "device is already attached"

Also now all the devices have been migrated to use the new
vfio_attach_device/vfio_detach_device API, let's turn the
legacy functions into static functions, local to container.c.

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 

---
v2 -> v3:
- Hopefully fix confusion beteen vbasedev->name, mdevid and sysfsdev
  while keeping into account Matthew's comment
  
https://lore.kernel.org/qemu-devel/6e04ab8f-dc84-e9c2-deea-2b6b31678...@linux.ibm.com/
---
 include/hw/vfio/vfio-common.h |   5 --
 hw/vfio/ccw.c | 122 +-
 hw/vfio/common.c  |  10 +--
 3 files changed, 37 insertions(+), 100 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 12fbfbc37d..c486bdef2a 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -202,7 +202,6 @@ typedef struct {
 hwaddr pages;
 } VFIOBitmap;
 
-void vfio_put_base_device(VFIODevice *vbasedev);
 void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
 void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
 void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
@@ -220,11 +219,7 @@ void vfio_region_unmap(VFIORegion *region);
 void vfio_region_exit(VFIORegion *region);
 void vfio_region_finalize(VFIORegion *region);
 void vfio_reset_handler(void *opaque);
-VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp);
-void vfio_put_group(VFIOGroup *group);
 struct vfio_device_info *vfio_get_device_info(int fd);
-int vfio_get_device(VFIOGroup *group, const char *name,
-VFIODevice *vbasedev, Error **errp);
 int vfio_attach_device(char *name, VFIODevice *vbasedev,
AddressSpace *as, Error **errp);
 void vfio_detach_device(VFIODevice *vbasedev);
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 1e2fce83b0..84eafb2e87 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -572,88 +572,15 @@ static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
 g_free(vcdev->io_region);
 }
 
-static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
-{
-g_free(vcdev->vdev.name);
-vfio_put_base_device(&vcdev->vdev);
-}
-
-static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
-Error **errp)
-{
-S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
-char *name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
- cdev->hostid.ssid,
- cdev->hostid.devid);
-VFIODevice *vbasedev;
-
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-if (strcmp(vbasedev->name, name) == 0) {
-error_setg(errp, "vfio: subchannel %s has already been attached",
-   name);
-goto out_err;
-}
-}
-
-/*
- * All vfio-ccw devices are believed to operate in a way compatible with
- * discarding of memory in RAM blocks, ie. pages pinned in the host are
- * in the current working set of the guest driver and therefore never
- * overlap e.g., with pages available to the guest balloon driver.  This
- * needs to be set before vfio_get_device() for vfio common to handle
- * ram_block_discard_disable().
- */
-vcdev->vdev.ram_block_discard_allowed = true;
-
-if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
-goto out_err;
-}
-
-vcdev->vdev.ops = &vfio_ccw_ops;
-vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
-vcdev->vdev.name = name;
-vcdev->vdev.dev = DEVICE(vcdev);
-
-return;
-
-out_err:
-g_free(name);
-}
-
-static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, Error **errp)
-{
-char *tmp, group_path[PATH_MAX];
-ssize_t len;
-int groupid;
-
-tmp = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/%s/iommu_group",
-  cdev->hostid.cssid, cdev->hostid.ssid,
-  cdev->hostid.devid, cdev->mdevid);
-len = readlink(tmp, group_path, sizeof(group_path));
-g_free(tmp);
-
-if (len <= 0 || len >= sizeof(group_path)) {
-error_setg(errp, "vfio: no iommu_group found");
-return NULL;
-}
-
-group_path[len] = 0;
-
-if (sscanf(basename(group_path), "%d", &groupid) != 1) {
-error_setg(errp, "vfio: failed to read %s", group_path);
-return NULL;
-}
-
-return vfio_get_group(groupid, &address_space_memory, errp);
-}
-
 static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 {
-VFIOGroup *group;
 S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
 VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_C

[PATCH v3 12/15] vfio/common: Introduce a per container device list

2023-10-03 Thread Eric Auger
From: Zhenzhong Duan 

Several functions need to iterate over the VFIO devices attached to
a given container.  This is currently achieved by iterating over the
groups attached to the container and then over the devices in the group.
Let's introduce a per container device list that simplifies this
search.

Per container list is used in below functions:
vfio_devices_all_dirty_tracking
vfio_devices_all_device_dirty_tracking
vfio_devices_all_running_and_mig_active
vfio_devices_dma_logging_stop
vfio_devices_dma_logging_start
vfio_devices_query_dirty_bitmap

This will also ease the migration of IOMMUFD by hiding the group
specificity.

Suggested-by: Alex Williamson 
Signed-off-by: Zhenzhong Duan 
Signed-off-by: Eric Auger 
---
 include/hw/vfio/vfio-common.h |   2 +
 hw/vfio/common.c  | 145 +++---
 2 files changed, 67 insertions(+), 80 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index c486bdef2a..8ca70dd821 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -98,6 +98,7 @@ typedef struct VFIOContainer {
 QLIST_HEAD(, VFIOGroup) group_list;
 QLIST_HEAD(, VFIORamDiscardListener) vrdl_list;
 QLIST_ENTRY(VFIOContainer) next;
+QLIST_HEAD(, VFIODevice) device_list;
 } VFIOContainer;
 
 typedef struct VFIOGuestIOMMU {
@@ -129,6 +130,7 @@ typedef struct VFIODeviceOps VFIODeviceOps;
 
 typedef struct VFIODevice {
 QLIST_ENTRY(VFIODevice) next;
+QLIST_ENTRY(VFIODevice) container_next;
 struct VFIOGroup *group;
 char *sysfsdev;
 char *name;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 019da387d2..ef9dc7c747 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -218,7 +218,6 @@ bool vfio_device_state_is_precopy(VFIODevice *vbasedev)
 
 static bool vfio_devices_all_dirty_tracking(VFIOContainer *container)
 {
-VFIOGroup *group;
 VFIODevice *vbasedev;
 MigrationState *ms = migrate_get_current();
 
@@ -227,19 +226,17 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer 
*container)
 return false;
 }
 
-QLIST_FOREACH(group, &container->group_list, container_next) {
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-VFIOMigration *migration = vbasedev->migration;
+QLIST_FOREACH(vbasedev, &container->device_list, container_next) {
+VFIOMigration *migration = vbasedev->migration;
 
-if (!migration) {
-return false;
-}
+if (!migration) {
+return false;
+}
 
-if (vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF &&
-(vfio_device_state_is_running(vbasedev) ||
- vfio_device_state_is_precopy(vbasedev))) {
-return false;
-}
+if (vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF &&
+(vfio_device_state_is_running(vbasedev) ||
+ vfio_device_state_is_precopy(vbasedev))) {
+return false;
 }
 }
 return true;
@@ -247,14 +244,11 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer 
*container)
 
 static bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container)
 {
-VFIOGroup *group;
 VFIODevice *vbasedev;
 
-QLIST_FOREACH(group, &container->group_list, container_next) {
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-if (!vbasedev->dirty_pages_supported) {
-return false;
-}
+QLIST_FOREACH(vbasedev, &container->device_list, container_next) {
+if (!vbasedev->dirty_pages_supported) {
+return false;
 }
 }
 
@@ -267,27 +261,24 @@ static bool 
vfio_devices_all_device_dirty_tracking(VFIOContainer *container)
  */
 static bool vfio_devices_all_running_and_mig_active(VFIOContainer *container)
 {
-VFIOGroup *group;
 VFIODevice *vbasedev;
 
 if (!migration_is_active(migrate_get_current())) {
 return false;
 }
 
-QLIST_FOREACH(group, &container->group_list, container_next) {
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-VFIOMigration *migration = vbasedev->migration;
+QLIST_FOREACH(vbasedev, &container->device_list, container_next) {
+VFIOMigration *migration = vbasedev->migration;
 
-if (!migration) {
-return false;
-}
+if (!migration) {
+return false;
+}
 
-if (vfio_device_state_is_running(vbasedev) ||
-vfio_device_state_is_precopy(vbasedev)) {
-continue;
-} else {
-return false;
-}
+if (vfio_device_state_is_running(vbasedev) ||
+vfio_device_state_is_precopy(vbasedev)) {
+continue;
+} else {
+return false;
 }
 }
 return true;
@@ -1187,20 +1178,17 @@ static bool 
vfio_section_is_vfio_pci(MemoryRegionSection *sec

[PATCH v3 15/15] vfio/common: Move legacy VFIO backend code into separate container.c

2023-10-03 Thread Eric Auger
From: Yi Liu 

Move all the code really dependent on the legacy VFIO container/group
into a separate file: container.c. What does remain in common.c is
the code related to VFIOAddressSpace, MemoryListeners, migration and
all other general operations.

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
---
 include/hw/vfio/vfio-common.h |   35 +
 hw/vfio/common.c  | 1155 +---
 hw/vfio/container.c   | 1156 +
 hw/vfio/meson.build   |1 +
 4 files changed, 1208 insertions(+), 1139 deletions(-)
 create mode 100644 hw/vfio/container.c

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 54905b9dd4..7780b9073a 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -206,6 +206,30 @@ typedef struct {
 hwaddr pages;
 } VFIOBitmap;
 
+void vfio_host_win_add(VFIOContainer *container,
+   hwaddr min_iova, hwaddr max_iova,
+   uint64_t iova_pgsizes);
+int vfio_host_win_del(VFIOContainer *container, hwaddr min_iova,
+  hwaddr max_iova);
+VFIOAddressSpace *vfio_get_address_space(AddressSpace *as);
+void vfio_put_address_space(VFIOAddressSpace *space);
+bool vfio_devices_all_running_and_saving(VFIOContainer *container);
+
+/* container->fd */
+int vfio_dma_unmap(VFIOContainer *container, hwaddr iova,
+   ram_addr_t size, IOMMUTLBEntry *iotlb);
+int vfio_dma_map(VFIOContainer *container, hwaddr iova,
+ ram_addr_t size, void *vaddr, bool readonly);
+int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start);
+int vfio_query_dirty_bitmap(VFIOContainer *container, VFIOBitmap *vbmap,
+hwaddr iova, hwaddr size);
+
+int vfio_container_add_section_window(VFIOContainer *container,
+  MemoryRegionSection *section,
+  Error **errp);
+void vfio_container_del_section_window(VFIOContainer *container,
+   MemoryRegionSection *section);
+
 void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
 void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
 void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
@@ -235,6 +259,10 @@ extern const MemoryRegionOps vfio_region_ops;
 typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
 typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList;
 extern VFIOGroupList vfio_group_list;
+extern VFIODeviceList vfio_device_list;
+
+extern const MemoryListener vfio_memory_listener;
+extern int vfio_kvm_device_fd;
 
 bool vfio_mig_active(void);
 int vfio_block_multiple_devices_migration(VFIODevice *vbasedev, Error **errp);
@@ -272,4 +300,11 @@ bool vfio_migration_realize(VFIODevice *vbasedev, Error 
**errp);
 void vfio_migration_exit(VFIODevice *vbasedev);
 
 int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size);
+bool vfio_devices_all_running_and_mig_active(VFIOContainer *container);
+bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container);
+int vfio_devices_query_dirty_bitmap(VFIOContainer *container,
+VFIOBitmap *vbmap, hwaddr iova,
+hwaddr size);
+int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova,
+ uint64_t size, ram_addr_t ram_addr);
 #endif /* HW_VFIO_VFIO_COMMON_H */
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 95bc50bcda..9e61de03ee 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -46,9 +46,7 @@
 #include "migration/qemu-file.h"
 #include "sysemu/tpm.h"
 
-VFIOGroupList vfio_group_list =
-QLIST_HEAD_INITIALIZER(vfio_group_list);
-static VFIODeviceList vfio_device_list =
+VFIODeviceList vfio_device_list =
 QLIST_HEAD_INITIALIZER(vfio_device_list);
 static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces =
 QLIST_HEAD_INITIALIZER(vfio_address_spaces);
@@ -61,39 +59,13 @@ static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces =
  * initialized, this file descriptor is only released on QEMU exit and
  * we'll re-use it should another vfio device be attached before then.
  */
-static int vfio_kvm_device_fd = -1;
+int vfio_kvm_device_fd = -1;
 #endif
 
-static int vfio_ram_block_discard_disable(VFIOContainer *container, bool state)
-{
-switch (container->iommu_type) {
-case VFIO_TYPE1v2_IOMMU:
-case VFIO_TYPE1_IOMMU:
-/*
- * We support coordinated discarding of RAM via the RamDiscardManager.
- */
-return ram_block_uncoordinated_discard_disable(state);
-default:
-/*
- * VFIO_SPAPR_TCE_IOMMU most probably works just fine with
- * RamDiscardManager, however, it is completely untested.
- *
- * VFIO_SPAPR_TCE_v2_IOMMU with "DMA memory preregistering" does
- * completely the opposite of managing mapping

[PATCH v3 14/15] vfio/common: Introduce a global VFIODevice list

2023-10-03 Thread Eric Auger
From: Zhenzhong Duan 

Some functions iterate over all the VFIODevices. This is currently
achieved by iterating over all groups/devices. Let's
introduce a global list of VFIODevices simplifying that scan.

This will also be useful while migrating to IOMMUFD by hiding the
group specificity.

Signed-off-by: Eric Auger 
Signed-off-by: Zhenzhong Duan 
Suggested-by: Alex Williamson 
---
 include/hw/vfio/vfio-common.h |  2 ++
 hw/vfio/common.c  | 45 +++
 2 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index bf12e40667..54905b9dd4 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -131,6 +131,7 @@ typedef struct VFIODeviceOps VFIODeviceOps;
 typedef struct VFIODevice {
 QLIST_ENTRY(VFIODevice) next;
 QLIST_ENTRY(VFIODevice) container_next;
+QLIST_ENTRY(VFIODevice) global_next;
 struct VFIOGroup *group;
 VFIOContainer *container;
 char *sysfsdev;
@@ -232,6 +233,7 @@ int vfio_kvm_device_del_fd(int fd, Error **errp);
 
 extern const MemoryRegionOps vfio_region_ops;
 typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
+typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList;
 extern VFIOGroupList vfio_group_list;
 
 bool vfio_mig_active(void);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 55f8a113ea..95bc50bcda 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -48,6 +48,8 @@
 
 VFIOGroupList vfio_group_list =
 QLIST_HEAD_INITIALIZER(vfio_group_list);
+static VFIODeviceList vfio_device_list =
+QLIST_HEAD_INITIALIZER(vfio_device_list);
 static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces =
 QLIST_HEAD_INITIALIZER(vfio_address_spaces);
 
@@ -94,18 +96,15 @@ static int vfio_get_dirty_bitmap(VFIOContainer *container, 
uint64_t iova,
 
 bool vfio_mig_active(void)
 {
-VFIOGroup *group;
 VFIODevice *vbasedev;
 
-if (QLIST_EMPTY(&vfio_group_list)) {
+if (QLIST_EMPTY(&vfio_device_list)) {
 return false;
 }
 
-QLIST_FOREACH(group, &vfio_group_list, next) {
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-if (vbasedev->migration_blocker) {
-return false;
-}
+QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
+if (vbasedev->migration_blocker) {
+return false;
 }
 }
 return true;
@@ -120,19 +119,16 @@ static Error *multiple_devices_migration_blocker;
  */
 static bool vfio_multiple_devices_migration_is_supported(void)
 {
-VFIOGroup *group;
 VFIODevice *vbasedev;
 unsigned int device_num = 0;
 bool all_support_p2p = true;
 
-QLIST_FOREACH(group, &vfio_group_list, next) {
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-if (vbasedev->migration) {
-device_num++;
+QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
+if (vbasedev->migration) {
+device_num++;
 
-if (!(vbasedev->migration->mig_flags & VFIO_MIGRATION_P2P)) {
-all_support_p2p = false;
-}
+if (!(vbasedev->migration->mig_flags & VFIO_MIGRATION_P2P)) {
+all_support_p2p = false;
 }
 }
 }
@@ -1777,22 +1773,17 @@ bool vfio_get_info_dma_avail(struct 
vfio_iommu_type1_info *info,
 
 void vfio_reset_handler(void *opaque)
 {
-VFIOGroup *group;
 VFIODevice *vbasedev;
 
-QLIST_FOREACH(group, &vfio_group_list, next) {
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-if (vbasedev->dev->realized) {
-vbasedev->ops->vfio_compute_needs_reset(vbasedev);
-}
+QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
+if (vbasedev->dev->realized) {
+vbasedev->ops->vfio_compute_needs_reset(vbasedev);
 }
 }
 
-QLIST_FOREACH(group, &vfio_group_list, next) {
-QLIST_FOREACH(vbasedev, &group->device_list, next) {
-if (vbasedev->dev->realized && vbasedev->needs_reset) {
-vbasedev->ops->vfio_hot_reset_multi(vbasedev);
-}
+QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
+if (vbasedev->dev->realized && vbasedev->needs_reset) {
+vbasedev->ops->vfio_hot_reset_multi(vbasedev);
 }
 }
 }
@@ -2657,6 +2648,7 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev,
 container = group->container;
 vbasedev->container = container;
 QLIST_INSERT_HEAD(&container->device_list, vbasedev, container_next);
+QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next);
 
 return ret;
 }
@@ -2669,6 +2661,7 @@ void vfio_detach_device(VFIODevice *vbasedev)
 return;
 }
 
+QLIST_REMOVE(vbasedev, global_next);
 QLIST_REMOVE(vbasedev, container_next);
 vbasedev->container = NULL;
 trace_vfio_detach_device(vbasedev->name, group->groupid);
-- 
2.41.0




[PATCH v3 06/15] vfio/common: Extract out vfio_kvm_device_[add/del]_fd

2023-10-03 Thread Eric Auger
From: Zhenzhong Duan 

Introduce two new helpers, vfio_kvm_device_[add/del]_fd
which take as input a file descriptor which can be either a group fd or
a cdev fd. This uses the new KVM_DEV_VFIO_FILE VFIO KVM device group,
which aliases to the legacy KVM_DEV_VFIO_GROUP.

vfio_kvm_device_[add/del]_group then call those new helpers.

Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Eric Auger 
---
 include/hw/vfio/vfio-common.h |  3 ++
 hw/vfio/common.c  | 69 +++
 2 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index e0483893d1..c4e7c3b4a7 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -226,6 +226,9 @@ struct vfio_device_info *vfio_get_device_info(int fd);
 int vfio_get_device(VFIOGroup *group, const char *name,
 VFIODevice *vbasedev, Error **errp);
 
+int vfio_kvm_device_add_fd(int fd, Error **errp);
+int vfio_kvm_device_del_fd(int fd, Error **errp);
+
 extern const MemoryRegionOps vfio_region_ops;
 typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
 extern VFIOGroupList vfio_group_list;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 0397788aa5..d8ed432cb6 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1818,17 +1818,17 @@ void vfio_reset_handler(void *opaque)
 }
 }
 
-static void vfio_kvm_device_add_group(VFIOGroup *group)
+int vfio_kvm_device_add_fd(int fd, Error **errp)
 {
 #ifdef CONFIG_KVM
 struct kvm_device_attr attr = {
-.group = KVM_DEV_VFIO_GROUP,
-.attr = KVM_DEV_VFIO_GROUP_ADD,
-.addr = (uint64_t)(unsigned long)&group->fd,
+.group = KVM_DEV_VFIO_FILE,
+.attr = KVM_DEV_VFIO_FILE_ADD,
+.addr = (uint64_t)(unsigned long)&fd,
 };
 
 if (!kvm_enabled()) {
-return;
+return 0;
 }
 
 if (vfio_kvm_device_fd < 0) {
@@ -1837,38 +1837,61 @@ static void vfio_kvm_device_add_group(VFIOGroup *group)
 };
 
 if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
-error_report("Failed to create KVM VFIO device: %m");
-return;
+error_setg_errno(errp, errno, "Failed to create KVM VFIO device");
+return -errno;
 }
 
 vfio_kvm_device_fd = cd.fd;
 }
 
 if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
-error_report("Failed to add group %d to KVM VFIO device: %m",
- group->groupid);
+error_setg_errno(errp, errno, "Failed to add fd %d to KVM VFIO device",
+ fd);
+return -errno;
 }
 #endif
+return 0;
+}
+
+int vfio_kvm_device_del_fd(int fd, Error **errp)
+{
+#ifdef CONFIG_KVM
+struct kvm_device_attr attr = {
+.group = KVM_DEV_VFIO_FILE,
+.attr = KVM_DEV_VFIO_FILE_DEL,
+.addr = (uint64_t)(unsigned long)&fd,
+};
+
+if (vfio_kvm_device_fd < 0) {
+error_setg(errp, "KVM VFIO device isn't created yet");
+return -EINVAL;
+}
+
+if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+error_setg_errno(errp, errno,
+ "Failed to remove fd %d from KVM VFIO device", fd);
+return -errno;
+}
+#endif
+return 0;
+}
+
+static void vfio_kvm_device_add_group(VFIOGroup *group)
+{
+Error *err = NULL;
+
+if (vfio_kvm_device_add_fd(group->fd, &err)) {
+error_reportf_err(err, "group ID %d: ", group->groupid);
+}
 }
 
 static void vfio_kvm_device_del_group(VFIOGroup *group)
 {
-#ifdef CONFIG_KVM
-struct kvm_device_attr attr = {
-.group = KVM_DEV_VFIO_GROUP,
-.attr = KVM_DEV_VFIO_GROUP_DEL,
-.addr = (uint64_t)(unsigned long)&group->fd,
-};
+Error *err = NULL;
 
-if (vfio_kvm_device_fd < 0) {
-return;
+if (vfio_kvm_device_del_fd(group->fd, &err)) {
+error_reportf_err(err, "group ID %d: ", group->groupid);
 }
-
-if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
-error_report("Failed to remove group %d from KVM VFIO device: %m",
- group->groupid);
-}
-#endif
 }
 
 static VFIOAddressSpace *vfio_get_address_space(AddressSpace *as)
-- 
2.41.0




[PATCH v3 05/15] vfio/common: Introduce vfio_container_add|del_section_window()

2023-10-03 Thread Eric Auger
Introduce helper functions that isolate the code used for
VFIO_SPAPR_TCE_v2_IOMMU.

Those helpers hide implementation details beneath the container object
and make the vfio_listener_region_add/del() implementations more
readable. No code change intended.

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
---
 hw/vfio/common.c | 156 +++
 1 file changed, 89 insertions(+), 67 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index c54a72ec80..0397788aa5 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -807,6 +807,92 @@ static bool vfio_get_section_iova_range(VFIOContainer 
*container,
 return true;
 }
 
+static int vfio_container_add_section_window(VFIOContainer *container,
+ MemoryRegionSection *section,
+ Error **errp)
+{
+VFIOHostDMAWindow *hostwin;
+hwaddr pgsize = 0;
+int ret;
+
+if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
+return 0;
+}
+
+/* For now intersections are not allowed, we may relax this later */
+QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
+if (ranges_overlap(hostwin->min_iova,
+   hostwin->max_iova - hostwin->min_iova + 1,
+   section->offset_within_address_space,
+   int128_get64(section->size))) {
+error_setg(errp,
+"region [0x%"PRIx64",0x%"PRIx64"] overlaps with existing"
+"host DMA window [0x%"PRIx64",0x%"PRIx64"]",
+section->offset_within_address_space,
+section->offset_within_address_space +
+int128_get64(section->size) - 1,
+hostwin->min_iova, hostwin->max_iova);
+return -EINVAL;
+}
+}
+
+ret = vfio_spapr_create_window(container, section, &pgsize);
+if (ret) {
+error_setg_errno(errp, -ret, "Failed to create SPAPR window");
+return ret;
+}
+
+vfio_host_win_add(container, section->offset_within_address_space,
+  section->offset_within_address_space +
+  int128_get64(section->size) - 1, pgsize);
+#ifdef CONFIG_KVM
+if (kvm_enabled()) {
+VFIOGroup *group;
+IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+struct kvm_vfio_spapr_tce param;
+struct kvm_device_attr attr = {
+.group = KVM_DEV_VFIO_GROUP,
+.attr = KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE,
+.addr = (uint64_t)(unsigned long)¶m,
+};
+
+if (!memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_SPAPR_TCE_FD,
+  ¶m.tablefd)) {
+QLIST_FOREACH(group, &container->group_list, container_next) {
+param.groupfd = group->fd;
+if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+error_setg_errno(errp, errno,
+ "vfio: failed GROUP_SET_SPAPR_TCE for "
+ "KVM VFIO device %d and group fd %d",
+ param.tablefd, param.groupfd);
+return -errno;
+}
+trace_vfio_spapr_group_attach(param.groupfd, param.tablefd);
+}
+}
+}
+#endif
+return 0;
+}
+
+static void vfio_container_del_section_window(VFIOContainer *container,
+  MemoryRegionSection *section)
+{
+if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
+return;
+}
+
+vfio_spapr_remove_window(container,
+ section->offset_within_address_space);
+if (vfio_host_win_del(container,
+  section->offset_within_address_space,
+  section->offset_within_address_space +
+  int128_get64(section->size) - 1) < 0) {
+hw_error("%s: Cannot delete missing window at %"HWADDR_PRIx,
+ __func__, section->offset_within_address_space);
+}
+}
+
 static void vfio_listener_region_add(MemoryListener *listener,
  MemoryRegionSection *section)
 {
@@ -833,62 +919,8 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 return;
 }
 
-if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) {
-hwaddr pgsize = 0;
-
-/* For now intersections are not allowed, we may relax this later */
-QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
-if (ranges_overlap(hostwin->min_iova,
-   hostwin->max_iova - hostwin->min_iova + 1,
-   section->offset_within_address_space,
-   int128_get64(section->size))) {
-

[PATCH v3 03/15] vfio/common: Move IOMMU agnostic helpers to a separate file

2023-10-03 Thread Eric Auger
From: Yi Liu 

Move low-level iommu agnostic helpers to a separate helpers.c
file. They relate to regions, interrupts, device/region
capabilities and etc.

Signed-off-by: Eric Auger 
Signed-off-by: Yi Sun 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |   9 +
 hw/vfio/common.c  | 588 
 hw/vfio/helpers.c | 611 ++
 hw/vfio/meson.build   |   1 +
 4 files changed, 621 insertions(+), 588 deletions(-)
 create mode 100644 hw/vfio/helpers.c

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index e9b8954595..e0483893d1 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -196,6 +196,12 @@ typedef struct VFIODisplay {
 } dmabuf;
 } VFIODisplay;
 
+typedef struct {
+unsigned long *bitmap;
+hwaddr size;
+hwaddr pages;
+} VFIOBitmap;
+
 void vfio_put_base_device(VFIODevice *vbasedev);
 void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
 void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
@@ -245,6 +251,8 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info 
*info,
  unsigned int *avail);
 struct vfio_info_cap_header *
 vfio_get_device_info_cap(struct vfio_device_info *info, uint16_t id);
+struct vfio_info_cap_header *
+vfio_get_cap(void *ptr, uint32_t cap_offset, uint16_t id);
 #endif
 extern const MemoryListener vfio_prereg_listener;
 
@@ -257,4 +265,5 @@ int vfio_spapr_remove_window(VFIOContainer *container,
 bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp);
 void vfio_migration_exit(VFIODevice *vbasedev);
 
+int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size);
 #endif /* HW_VFIO_VFIO_COMMON_H */
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 134649226d..4e122fc4e4 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -62,84 +62,6 @@ static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces =
 static int vfio_kvm_device_fd = -1;
 #endif
 
-/*
- * Common VFIO interrupt disable
- */
-void vfio_disable_irqindex(VFIODevice *vbasedev, int index)
-{
-struct vfio_irq_set irq_set = {
-.argsz = sizeof(irq_set),
-.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER,
-.index = index,
-.start = 0,
-.count = 0,
-};
-
-ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
-}
-
-void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index)
-{
-struct vfio_irq_set irq_set = {
-.argsz = sizeof(irq_set),
-.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK,
-.index = index,
-.start = 0,
-.count = 1,
-};
-
-ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
-}
-
-void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index)
-{
-struct vfio_irq_set irq_set = {
-.argsz = sizeof(irq_set),
-.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_MASK,
-.index = index,
-.start = 0,
-.count = 1,
-};
-
-ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
-}
-
-static inline const char *action_to_str(int action)
-{
-switch (action) {
-case VFIO_IRQ_SET_ACTION_MASK:
-return "MASK";
-case VFIO_IRQ_SET_ACTION_UNMASK:
-return "UNMASK";
-case VFIO_IRQ_SET_ACTION_TRIGGER:
-return "TRIGGER";
-default:
-return "UNKNOWN ACTION";
-}
-}
-
-static const char *index_to_str(VFIODevice *vbasedev, int index)
-{
-if (vbasedev->type != VFIO_DEVICE_TYPE_PCI) {
-return NULL;
-}
-
-switch (index) {
-case VFIO_PCI_INTX_IRQ_INDEX:
-return "INTX";
-case VFIO_PCI_MSI_IRQ_INDEX:
-return "MSI";
-case VFIO_PCI_MSIX_IRQ_INDEX:
-return "MSIX";
-case VFIO_PCI_ERR_IRQ_INDEX:
-return "ERR";
-case VFIO_PCI_REQ_IRQ_INDEX:
-return "REQ";
-default:
-return NULL;
-}
-}
-
 static int vfio_ram_block_discard_disable(VFIOContainer *container, bool state)
 {
 switch (container->iommu_type) {
@@ -163,183 +85,10 @@ static int vfio_ram_block_discard_disable(VFIOContainer 
*container, bool state)
 }
 }
 
-int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
-   int action, int fd, Error **errp)
-{
-struct vfio_irq_set *irq_set;
-int argsz, ret = 0;
-const char *name;
-int32_t *pfd;
-
-argsz = sizeof(*irq_set) + sizeof(*pfd);
-
-irq_set = g_malloc0(argsz);
-irq_set->argsz = argsz;
-irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | action;
-irq_set->index = index;
-irq_set->start = subindex;
-irq_set->count = 1;
-pfd = (int32_t *)&irq_set->data;
-*pfd = fd;
-
-if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
-ret = -errno;
-}
-g_free(irq_set);
-
-if (!ret) {
-return 0;
-}
-
-error_setg_errno(errp,

[PATCH v3 13/15] vfio/common: Store the parent container in VFIODevice

2023-10-03 Thread Eric Auger
From: Zhenzhong Duan 

let's store the parent contaienr within the VFIODevice.
This simplifies the logic in vfio_viommu_preset() and
brings the benefice to hide the group specificity which
is useful for IOMMUFD migration.

Signed-off-by: Eric Auger 
Signed-off-by: Zhenzhong Duan 
---
 include/hw/vfio/vfio-common.h | 1 +
 hw/vfio/common.c  | 8 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 8ca70dd821..bf12e40667 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -132,6 +132,7 @@ typedef struct VFIODevice {
 QLIST_ENTRY(VFIODevice) next;
 QLIST_ENTRY(VFIODevice) container_next;
 struct VFIOGroup *group;
+VFIOContainer *container;
 char *sysfsdev;
 char *name;
 DeviceState *dev;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index ef9dc7c747..55f8a113ea 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -184,7 +184,7 @@ void vfio_unblock_multiple_devices_migration(void)
 
 bool vfio_viommu_preset(VFIODevice *vbasedev)
 {
-return vbasedev->group->container->space->as != &address_space_memory;
+return vbasedev->container->space->as != &address_space_memory;
 }
 
 static void vfio_set_migration_error(int err)
@@ -2655,6 +2655,7 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev,
 }
 
 container = group->container;
+vbasedev->container = container;
 QLIST_INSERT_HEAD(&container->device_list, vbasedev, container_next);
 
 return ret;
@@ -2664,7 +2665,12 @@ void vfio_detach_device(VFIODevice *vbasedev)
 {
 VFIOGroup *group = vbasedev->group;
 
+if (!vbasedev->container) {
+return;
+}
+
 QLIST_REMOVE(vbasedev, container_next);
+vbasedev->container = NULL;
 trace_vfio_detach_device(vbasedev->name, group->groupid);
 vfio_put_base_device(vbasedev);
 vfio_put_group(group);
-- 
2.41.0




[PATCH v3 01/15] scripts/update-linux-headers: Add iommufd.h

2023-10-03 Thread Eric Auger
Update the script to import iommufd.h

Signed-off-by: Eric Auger 
Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
---
 scripts/update-linux-headers.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 35a64bb501..34295c0fe5 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -161,7 +161,8 @@ done
 rm -rf "$output/linux-headers/linux"
 mkdir -p "$output/linux-headers/linux"
 for header in const.h stddef.h kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h \
-  psci.h psp-sev.h userfaultfd.h memfd.h mman.h nvme_ioctl.h 
vduse.h; do
+  psci.h psp-sev.h userfaultfd.h memfd.h mman.h nvme_ioctl.h \
+  vduse.h iommufd.h; do
 cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux"
 done
 
-- 
2.41.0




RE: [PATCH RFC V2 31/37] physmem,gdbstub: Common helping funcs/changes to *unrealize* vCPU

2023-10-03 Thread Salil Mehta via
Hi Phil,

> From: Philippe Mathieu-Daudé 
> Sent: Tuesday, October 3, 2023 7:34 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; qemu-
> a...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> eric.au...@redhat.com; w...@kernel.org; a...@kernel.org;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> gs...@redhat.com; raf...@kernel.org; borntrae...@linux.ibm.com;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn
> Subject: Re: [PATCH RFC V2 31/37] physmem,gdbstub: Common helping
> funcs/changes to *unrealize* vCPU
> 
> Hi Salil,
> 
> On 26/9/23 12:04, Salil Mehta wrote:
> > Supporting vCPU Hotplug for ARM arch also means introducing new
> functionality of
> > unrealizing the ARMCPU. This requires some new common functions.
> >
> > Defining them as part of architecture independent change so that this
> code could
> > be reused by other interested parties.
> >
> > Signed-off-by: Salil Mehta 
> > ---
> >   gdbstub/gdbstub.c | 13 +
> >   include/exec/cpu-common.h |  8 
> >   include/exec/gdbstub.h|  1 +
> >   include/hw/core/cpu.h |  1 +
> >   softmmu/physmem.c | 25 +
> >   5 files changed, 48 insertions(+)
> 
> 
> > diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> > index dab572c9bd..ffd815a0d8 100644
> > --- a/include/hw/core/cpu.h
> > +++ b/include/hw/core/cpu.h
> > @@ -366,6 +366,7 @@ struct CPUState {
> >   QSIMPLEQ_HEAD(, qemu_work_item) work_list;
> >
> >   CPUAddressSpace *cpu_ases;
> > +int cpu_ases_ref_count;
> >   int num_ases;
> >   AddressSpace *as;
> >   MemoryRegion *memory;
> > diff --git a/softmmu/physmem.c b/softmmu/physmem.c
> > index 3df73542e1..a93ae783af 100644
> > --- a/softmmu/physmem.c
> > +++ b/softmmu/physmem.c
> > @@ -762,6 +762,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
> >
> >   if (!cpu->cpu_ases) {
> >   cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
> > +cpu->cpu_ases_ref_count = cpu->num_ases;
> >   }
> >
> >   newas = &cpu->cpu_ases[asidx];
> > @@ -775,6 +776,30 @@ void cpu_address_space_init(CPUState *cpu, int
> asidx,
> >   }
> >   }
> >
> > +void cpu_address_space_destroy(CPUState *cpu, int asidx)
> > +{
> > +CPUAddressSpace *cpuas;
> > +
> > +assert(asidx < cpu->num_ases);
> > +assert(asidx == 0 || !kvm_enabled());
> > +assert(cpu->cpu_ases);
> > +
> > +cpuas = &cpu->cpu_ases[asidx];
> > +if (tcg_enabled()) {
> > +memory_listener_unregister(&cpuas->tcg_as_listener);
> > +}
> > +
> > +address_space_destroy(cpuas->as);
> > +g_free_rcu(cpuas->as, rcu);
> > +
> > +if (cpu->cpu_ases_ref_count == 1) {
> > +g_free(cpu->cpu_ases);
> > +cpu->cpu_ases = NULL;
> > +}
> > +
> > +cpu->cpu_ases_ref_count--;
> 
> See Richard comment from:
> https://lore.kernel.org/qemu-devel/594b2550-9a73-684f-6e54-
> 29401dc6c...@linaro.org/
> 
> "I think it would be better to destroy all address spaces at once,
> "so that you don't need  to invent a reference count that isn't used
> "for anything else.

Yes, we can do that and remove the reference count. The only reason I
did it was because I was not sure if it is safe to assume that all
the AddressSpace will always be destroyed *together*. And now since
this is being ported to other architectures will the same hold
true everywhere?


Thanks
Salil.




RE: [PATCH 4/9] hw/acpi: Init GED framework with cpu hotplug events

2023-10-03 Thread Salil Mehta via
Hi Jonathan,
Thanks for looking at it.

> From: Jonathan Cameron 
> Sent: Monday, October 2, 2023 5:06 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; imamm...@redhat.com; andrew.jo...@linux.dev;
> da...@redhat.com; phi...@linaro.org; eric.au...@redhat.com;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> w...@kernel.org; gs...@redhat.com; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH 4/9] hw/acpi: Init GED framework with cpu hotplug
> events
> 
> On Fri, 29 Sep 2023 13:42:59 +0100
> Salil Mehta  wrote:
> 
> > ACPI GED(as described in the ACPI 6.2 spec) can be used to generate ACPI
> events
> > when OSPM/guest receives an interrupt listed in the _CRS object of GED.
> OSPM
> > then maps or demultiplexes the event by evaluating _EVT method.
> >
> > This change adds the support of cpu hotplug event initialization in the
> > existing GED framework.
> >
> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> FWIW this looks good to me.
> 
> Reviewed-by: Jonathan Cameron 

Thank you!
Salil.




[PATCH v3] hw/i386: changes towards enabling -Wshadow=local for x86 machines

2023-10-03 Thread Ani Sinha
Code changes that addresses all compiler complaints coming from enabling
-Wshadow flags. Enabling -Wshadow catches cases of local variables shadowing
other local variables or parameters. These makes the code confusing and/or adds
bugs that are difficult to catch.

See also

   Subject: Help wanted for enabling -Wshadow=local
   Message-Id: <87r0mqlf9x@pond.sub.org>
   https://lore.kernel.org/qemu-devel/87r0mqlf9x@pond.sub.org

CC: Markus Armbruster 
CC: Philippe Mathieu-Daude 
CC: m...@redhat.com

Signed-off-by: Ani Sinha 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Peter Xu 
---
 hw/i386/acpi-microvm.c | 4 ++--
 hw/i386/pc.c   | 1 -
 hw/i386/x86.c  | 2 --
 3 files changed, 2 insertions(+), 5 deletions(-)

changelog:
v3: split the patches. Peter's changes are now in a seperate patch.
Addressed mst's suggestions. Removed message-ID
from commit log and added the reference to previous discussion thread
explicitly.
v2: kept Peter's changes from 
https://lore.kernel.org/r/20230922160410.138786-1-pet...@redhat.com
and removed mine.

diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index a075360d85..6ddcfb0419 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -55,8 +55,8 @@ static void acpi_dsdt_add_virtio(Aml *scope,
 
 bus = sysbus_get_default();
 QTAILQ_FOREACH(kid, &bus->children, sibling) {
-DeviceState *dev = kid->child;
-Object *obj = object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MMIO);
+Object *obj = object_dynamic_cast(OBJECT(kid->child),
+  TYPE_VIRTIO_MMIO);
 
 if (obj) {
 VirtIOMMIOProxy *mmio = VIRTIO_MMIO(obj);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3db0743f31..e7a233e886 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1116,7 +1116,6 @@ void pc_memory_init(PCMachineState *pcms,
 
 if (machine->device_memory) {
 uint64_t *val = g_malloc(sizeof(*val));
-PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
 uint64_t res_mem_end = machine->device_memory->base;
 
 if (!pcmc->broken_reserved_end) {
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index f034df8bf6..b3d054889b 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -365,8 +365,6 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
 
 cpu_slot = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx);
 if (!cpu_slot) {
-MachineState *ms = MACHINE(x86ms);
-
 x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
 error_setg(errp,
 "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
-- 
2.42.0




Re: [PATCH] tests/avocado: Re-enable MIPS Malta tests (GitLab issue #1884 fixed)

2023-10-03 Thread Alex Bennée


Philippe Mathieu-Daudé  writes:

> Commit 18a536f1f8 ("accel/tcg: Always require can_do_io") fixed
> the GitLab issue #1884: we can now re-enable those tests.
>
> This reverts commit f959c3d87ccfa585b105de6964a6261e368cc1da.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH] hw/i386/intel_iommu: changes towards enabling -Wshadow=local

2023-10-03 Thread Ani Sinha
Code changes that addresses all compiler complaints coming from enabling
-Wshadow flags. Enabling -Wshadow catches cases of local variables shadowing
other local variables or parameters. These makes the code confusing and/or adds
bugs that are difficult to catch.

See also

   Subject: Help wanted for enabling -Wshadow=local
   Message-Id: <87r0mqlf9x@pond.sub.org>
   https://lore.kernel.org/qemu-devel/87r0mqlf9x@pond.sub.org

Signed-off-by: Ani Sinha 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

See also 
Peter's changes from
https://lore.kernel.org/r/20230922160410.138786-1-pet...@redhat.com.
This patch is same as above.

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index c0ce896668..2c832ab68b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3744,7 +3744,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, 
PCIBus *bus,
 /* Unmap the whole range in the notifier's scope. */
 static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
 {
-hwaddr size, remain;
+hwaddr total, remain;
 hwaddr start = n->start;
 hwaddr end = n->end;
 IntelIOMMUState *s = as->iommu_state;
@@ -3765,7 +3765,7 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, 
IOMMUNotifier *n)
 }
 
 assert(start <= end);
-size = remain = end - start + 1;
+total = remain = end - start + 1;
 
 while (remain >= VTD_PAGE_SIZE) {
 IOMMUTLBEvent event;
@@ -3793,10 +3793,10 @@ static void vtd_address_space_unmap(VTDAddressSpace 
*as, IOMMUNotifier *n)
 trace_vtd_as_unmap_whole(pci_bus_num(as->bus),
  VTD_PCI_SLOT(as->devfn),
  VTD_PCI_FUNC(as->devfn),
- n->start, size);
+ n->start, total);
 
 map.iova = n->start;
-map.size = size - 1; /* Inclusive */
+map.size = total - 1; /* Inclusive */
 iova_tree_remove(as->iova_tree, map);
 }
 
-- 
2.42.0




Re: [PATCH] hw/i386/intel_iommu: changes towards enabling -Wshadow=local

2023-10-03 Thread Ani Sinha



> On 03-Oct-2023, at 4:06 PM, Ani Sinha  wrote:
> 
> Code changes that addresses all compiler complaints coming from enabling
> -Wshadow flags. Enabling -Wshadow catches cases of local variables shadowing
> other local variables or parameters. These makes the code confusing and/or 
> adds
> bugs that are difficult to catch.
> 
> See also
> 
>   Subject: Help wanted for enabling -Wshadow=local
>   Message-Id: <87r0mqlf9x@pond.sub.org>
>   https://lore.kernel.org/qemu-devel/87r0mqlf9x@pond.sub.org
> 
> Signed-off-by: Ani Sinha 
> Reviewed-by: Daniel P. Berrangé 
> Reviewed-by: Peter Xu 

Although I sent this for completeness, I see this already got merged

https://gitlab.com/qemu-project/qemu/-/commit/a082739eb390d2aad679b5efa9afc40cfa2a496d

So we can toss this patch out.

> ---
> hw/i386/intel_iommu.c | 8 
> 1 file changed, 4 insertions(+), 4 deletions(-)
> 
> See also 
> Peter's changes from
> https://lore.kernel.org/r/20230922160410.138786-1-pet...@redhat.com.
> This patch is same as above.
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index c0ce896668..2c832ab68b 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -3744,7 +3744,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, 
> PCIBus *bus,
> /* Unmap the whole range in the notifier's scope. */
> static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
> {
> -hwaddr size, remain;
> +hwaddr total, remain;
> hwaddr start = n->start;
> hwaddr end = n->end;
> IntelIOMMUState *s = as->iommu_state;
> @@ -3765,7 +3765,7 @@ static void vtd_address_space_unmap(VTDAddressSpace 
> *as, IOMMUNotifier *n)
> }
> 
> assert(start <= end);
> -size = remain = end - start + 1;
> +total = remain = end - start + 1;
> 
> while (remain >= VTD_PAGE_SIZE) {
> IOMMUTLBEvent event;
> @@ -3793,10 +3793,10 @@ static void vtd_address_space_unmap(VTDAddressSpace 
> *as, IOMMUNotifier *n)
> trace_vtd_as_unmap_whole(pci_bus_num(as->bus),
>  VTD_PCI_SLOT(as->devfn),
>  VTD_PCI_FUNC(as->devfn),
> - n->start, size);
> + n->start, total);
> 
> map.iova = n->start;
> -map.size = size - 1; /* Inclusive */
> +map.size = total - 1; /* Inclusive */
> iova_tree_remove(as->iova_tree, map);
> }
> 
> -- 
> 2.42.0
> 




Re: [PATCH v3 5/5] hw/vfio: add ramfb migration support

2023-10-03 Thread Marc-André Lureau
Hi

On Tue, Oct 3, 2023 at 2:17 PM Cédric Le Goater  wrote:
>
> On 10/3/23 10:56, marcandre.lur...@redhat.com wrote:
> > From: Marc-André Lureau 
> >
> > Add a "VFIODisplay" subsection whenever "x-ramfb-migrate" is turned on.
> >
> > Turn it off by default on machines <= 8.1 for compatibility reasons.
>
>
> This change breaks linking on various platforms with :
>
> /usr/bin/ld: 
> libqemu-xtensa-softmmu.fa.p/hw_vfio_display.c.o:(.data.rel+0x50): undefined 
> reference to `ramfb_vmstate'
>
> Some stubs updates are missing it seems..
>

diff --git a/stubs/ramfb.c b/stubs/ramfb.c
index 48143f3354..cf64733b10 100644
--- a/stubs/ramfb.c
+++ b/stubs/ramfb.c
@@ -2,6 +2,8 @@
 #include "qapi/error.h"
 #include "hw/display/ramfb.h"

+const VMStateDescription ramfb_vmstate = {};
+


And I think we should also change the "needed" condition to:

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 4689f2e5c1..b327844764 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2613,7 +2613,7 @@ static bool vfio_display_needed(void *opaque)
 VFIOPCIDevice *vdev = opaque;

 /* the only thing that justifies the VFIODisplay sub-section atm */
-return vdev->ramfb_migrate != ON_OFF_AUTO_OFF;
+return vdev->enable_ramfb && vdev->ramfb_migrate != ON_OFF_AUTO_OFF;
 }



> Thanks,
>
> C.
>
> >
> > Signed-off-by: Marc-André Lureau 
> > ---
> >   hw/vfio/pci.h |  3 +++
> >   hw/core/machine.c |  1 +
> >   hw/vfio/display.c | 23 +++
> >   hw/vfio/pci.c | 32 
> >   4 files changed, 59 insertions(+)
> >
> > diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> > index 2d836093a8..fd06695542 100644
> > --- a/hw/vfio/pci.h
> > +++ b/hw/vfio/pci.h
> > @@ -173,6 +173,7 @@ struct VFIOPCIDevice {
> >   bool no_kvm_ioeventfd;
> >   bool no_vfio_ioeventfd;
> >   bool enable_ramfb;
> > +OnOffAuto ramfb_migrate;
> >   bool defer_kvm_irq_routing;
> >   bool clear_parent_atomics_on_exit;
> >   VFIODisplay *dpy;
> > @@ -226,4 +227,6 @@ void vfio_display_reset(VFIOPCIDevice *vdev);
> >   int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
> >   void vfio_display_finalize(VFIOPCIDevice *vdev);
> >
> > +extern const VMStateDescription vfio_display_vmstate;
> > +
> >   #endif /* HW_VFIO_VFIO_PCI_H */
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index 47a07d1d9b..f2f8940a85 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -32,6 +32,7 @@
> >
> >   GlobalProperty hw_compat_8_1[] = {
> >   { "ramfb", "x-migrate", "off" },
> > +{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }
> >   };
> >   const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
> >
> > diff --git a/hw/vfio/display.c b/hw/vfio/display.c
> > index bec864f482..de5bf71dd1 100644
> > --- a/hw/vfio/display.c
> > +++ b/hw/vfio/display.c
> > @@ -542,3 +542,26 @@ void vfio_display_finalize(VFIOPCIDevice *vdev)
> >   vfio_display_edid_exit(vdev->dpy);
> >   g_free(vdev->dpy);
> >   }
> > +
> > +static bool migrate_needed(void *opaque)
> > +{
> > +/*
> > + * If we are here, it's because vfio_display_needed(), which is only 
> > true
> > + * when dpy->ramfb_migrate atm.
> > + *
> > + * If the migration condition is changed, we should check here if
> > + * ramfb_migrate is true. (this will need a way to lookup the 
> > associated
> > + * VFIOPCIDevice somehow, or fields to be moved, ..)
> > + */
> > +return true;
> > +}
> > +
> > +const VMStateDescription vfio_display_vmstate = {
> > +.name = "VFIODisplay",
> > +.version_id = 1,
> > +.minimum_version_id = 1,
> > +.needed = migrate_needed,
> > +.fields = (VMStateField[]) {
> > +VMSTATE_STRUCT_POINTER(ramfb, VFIODisplay, ramfb_vmstate, 
> > RAMFBState),
> > +}
> > +};
> > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> > index 3b2ca3c24c..4689f2e5c1 100644
> > --- a/hw/vfio/pci.c
> > +++ b/hw/vfio/pci.c
> > @@ -2608,6 +2608,25 @@ static bool vfio_msix_present(void *opaque, int 
> > version_id)
> >   return msix_present(pdev);
> >   }
> >
> > +static bool vfio_display_needed(void *opaque)
> > +{
> > +VFIOPCIDevice *vdev = opaque;
> > +
> > +/* the only thing that justifies the VFIODisplay sub-section atm */
> > +return vdev->ramfb_migrate != ON_OFF_AUTO_OFF;
> > +}
> > +
> > +const VMStateDescription vmstate_vfio_display = {
> > +.name = "VFIOPCIDevice/VFIODisplay",
> > +.version_id = 1,
> > +.minimum_version_id = 1,
> > +.needed = vfio_display_needed,
> > +.fields = (VMStateField[]){
> > +VMSTATE_STRUCT_POINTER(dpy, VFIOPCIDevice, vfio_display_vmstate, 
> > VFIODisplay),
> > +VMSTATE_END_OF_LIST()
> > +}
> > +};
> > +
> >   const VMStateDescription vmstate_vfio_pci_config = {
> >   .name = "VFIOPCIDevice",
> >   .version_id = 1,
> > @@ -2616,6 +2635,10 @@ const VMStateDescription vmstate_vfio_pci_config = {
> >   VMSTATE_PCI_DEVICE(pdev, VFIOPCIDevice),
> >   VMST

RE: [PATCH V2 01/10] accel/kvm: Extract common KVM vCPU {creation,parking} code

2023-10-03 Thread Salil Mehta via
Hi Jonathan,

> From: Jonathan Cameron 
> Sent: Monday, October 2, 2023 4:53 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; imamm...@redhat.com; andrew.jo...@linux.dev;
> da...@redhat.com; phi...@linaro.org; eric.au...@redhat.com;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> w...@kernel.org; gs...@redhat.com; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 01/10] accel/kvm: Extract common KVM vCPU
> {creation,parking} code
> 
> On Sat, 30 Sep 2023 01:19:24 +0100
> Salil Mehta  wrote:
> 
> > KVM vCPU creation is done once during the initialization of the VM when Qemu
> > threads are spawned. This is common to all the architectures.
> >
> > Hot-unplug of vCPU results in destruction of the vCPU objects in QOM but
> > the KVM vCPU objects in the Host KVM are not destroyed and their 
> > representative
> > KVM vCPU objects/context in Qemu are parked.
> >
> > Refactor common logic so that some APIs could be reused by vCPU Hotplug 
> > code.
> >
> > Signed-off-by: Salil Mehta 
> 
> Hi Salil,
> 
> A few trivial things inline, plus a question about why
> cpu->cpu_index can now be used but kvm_arch_vcpu_id(cpu);
> was previously needed.

Good point. I used the API because it was returning
'unsigned long' and it was being used across the archs.
I thought maybe the size of the index could vary across
archs. For example, for PowerPC above API returns vcpu_id
which presumably could have different data type than
an 'integer'.

But after Alex's comment, I was made to believe that this
assumption might not be correct and CPU index is an
'integer' across archs and perhaps semantics of above
API is not correct.

But perhaps original code was functionally correct?


> >  accel/kvm/kvm-all.c  | 63 +---
> >  include/sysemu/kvm.h | 14 ++
> >  2 files changed, 61 insertions(+), 16 deletions(-)
> >
> > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> > index ff1578bb32..b8c36ba50a 100644
> > --- a/accel/kvm/kvm-all.c
> > +++ b/accel/kvm/kvm-all.c
> > @@ -80,7 +80,7 @@
> >  #endif
> >
> >  struct KVMParkedVcpu {
> > -unsigned long vcpu_id;
> > +int vcpu_id;
> >  int kvm_fd;
> >  QLIST_ENTRY(KVMParkedVcpu) node;
> >  };
> > @@ -137,6 +137,7 @@ static QemuMutex kml_slots_lock;
> >  #define kvm_slots_unlock()  qemu_mutex_unlock(&kml_slots_lock)
> >
> >  static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
> > +static int kvm_get_vcpu(KVMState *s, int vcpu_id);
> >
> >  static inline void kvm_resample_fd_remove(int gsi)
> >  {
> > @@ -320,11 +321,49 @@ err:
> >  return ret;
> >  }
> >
> > +void kvm_park_vcpu(CPUState *cpu)
> > +{
> > +int vcpu_id = cpu->cpu_index;
> > +struct KVMParkedVcpu *vcpu;
> > +
> > +vcpu = g_malloc0(sizeof(*vcpu));
> > +vcpu->vcpu_id = vcpu_id;
> 
> As vcpu_id is only used here why have the local variable?
> Maybe that changes in later patches, in which case ignore this.
> 
> vcpu->vcpu_id = cpu->cpu_index;


Yes, thanks.


> 
> Why is kvm_arch_vcpu_id() not necessary here any more but was
> before?


Because I have now changed the type of vcpu_id from 'unsigned long'
to an 'integer'.

> 
> > +vcpu->kvm_fd = cpu->kvm_fd;
> > +QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
> > +}
> > +
> > +int kvm_create_vcpu(CPUState *cpu)
> > +{
> > +int vcpu_id = cpu->cpu_index;
> 
> See below. I'm not sure why it's safe not to use kvm_arch_vcpu_id()
> Seems a few architectures have less than trivial implementations of
> that function currently.

I doubt this as well. Other architectures like PowerPC are returning
different type?


> > +KVMState *s = kvm_state;
> > +int kvm_fd;
> > +
> > +DPRINTF("kvm_create_vcpu\n");
> > +
> > +/* check if the KVM vCPU already exist but is parked */
> > +kvm_fd = kvm_get_vcpu(s, vcpu_id);
> > +if (kvm_fd < 0) {
> > +/* vCPU not parked: create a new KVM vCPU */
> > +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
> > +if (kvm_fd < 0) {
> > +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %d", 
> > vcpu_id);
> > +return kvm_fd;
> > +}
> > +}
> > +
> > +cpu->vcpu_dirty = true;
> > +cpu->kvm_fd = kvm_fd;
> > +cpu->kvm_state = s;
> > +cpu->dirty_pages = 0;
> > +cpu->throttle_us_per_full = 0;
> 
> Trivial but I would have maintained the order wrt to the code removed
> below just to avoid a reviewer having to check the two bits of code
> do the same thing a

RE: [PATCH V2 01/10] accel/kvm: Extract common KVM vCPU {creation,parking} code

2023-10-03 Thread Salil Mehta via
Hi Gavin,

> From: Gavin Shan 
> Sent: Tuesday, October 3, 2023 12:18 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; qemu-
> a...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 01/10] accel/kvm: Extract common KVM vCPU
> {creation,parking} code
> 
> On 9/30/23 10:19, Salil Mehta wrote:
> > KVM vCPU creation is done once during the initialization of the VM when Qemu
> > threads are spawned. This is common to all the architectures.
>^^^
>thread is spawned.

Yes, will fix.

Thanks
Salil.


> > Hot-unplug of vCPU results in destruction of the vCPU objects in QOM but
> > the KVM vCPU objects in the Host KVM are not destroyed and their
> representative
> > KVM vCPU objects/context in Qemu are parked.
> >
> > Refactor common logic so that some APIs could be reused by vCPU Hotplug 
> > code.
> >
> > Signed-off-by: Salil Mehta 
> > ---
> >   accel/kvm/kvm-all.c  | 63 +---
> >   include/sysemu/kvm.h | 14 ++
> >   2 files changed, 61 insertions(+), 16 deletions(-)
> >
> > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> > index ff1578bb32..b8c36ba50a 100644
> > --- a/accel/kvm/kvm-all.c
> > +++ b/accel/kvm/kvm-all.c
> > @@ -80,7 +80,7 @@
> >   #endif
> >
> >   struct KVMParkedVcpu {
> > -unsigned long vcpu_id;
> > +int vcpu_id;
> 
> @vcpu_id represents the vCPU index (CPUState::cpu_index) instead of the
> architectural CPU ID any more. However, I don't understand how it works
> for x86, and more comments regarding it can be seen below.

I missed the reason why I had used 'unsigned long' everywhere in the
first change. You can check the PowerPC, it returns vcpu_id which might
not be an 'integer'. Hence, this change could actually create a problem.


> >   int kvm_fd;
> >   QLIST_ENTRY(KVMParkedVcpu) node;
> >   };
> > @@ -137,6 +137,7 @@ static QemuMutex kml_slots_lock;
> >   #define kvm_slots_unlock()  qemu_mutex_unlock(&kml_slots_lock)
> >
> >   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
> > +static int kvm_get_vcpu(KVMState *s, int vcpu_id);
> >
> >   static inline void kvm_resample_fd_remove(int gsi)
> >   {
> > @@ -320,11 +321,49 @@ err:
> >   return ret;
> >   }
> >
> > +void kvm_park_vcpu(CPUState *cpu)
> > +{
> > +int vcpu_id = cpu->cpu_index;
> > +struct KVMParkedVcpu *vcpu;
> > +
> > +vcpu = g_malloc0(sizeof(*vcpu));
> > +vcpu->vcpu_id = vcpu_id;
> > +vcpu->kvm_fd = cpu->kvm_fd;
> > +QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
> > +}
> > +
> 
> @vcpu_id can be dropped as suggested previously.
> 
> vcpu->vcpu_id = cpu->cpu_index;


Yes, agreed.

Thanks
Salil.


> > +int kvm_create_vcpu(CPUState *cpu)
> > +{
> > +int vcpu_id = cpu->cpu_index;
> > +KVMState *s = kvm_state;
> > +int kvm_fd;
> > +
> > +DPRINTF("kvm_create_vcpu\n");
> > +
> > +/* check if the KVM vCPU already exist but is parked */
> > +kvm_fd = kvm_get_vcpu(s, vcpu_id);
> > +if (kvm_fd < 0) {
> > +/* vCPU not parked: create a new KVM vCPU */
> > +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
> > +if (kvm_fd < 0) {
> > +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %d", 
> > vcpu_id);
> > +return kvm_fd;
> > +}
> > +}
> > +
> > +cpu->vcpu_dirty = true;
> > +cpu->kvm_fd = kvm_fd;
> > +cpu->kvm_state = s;
> > +cpu->dirty_pages = 0;
> > +cpu->throttle_us_per_full = 0;
> > +
> > +return 0;
> > +}
> > +
> 
> The comments here can be dropped since the code is self-explaining.
> 
> @vcpu_id represents vCPU index, instead of the architecrual vCPU ID any
> more.
> @vcpu_id is passed to host through ioctl(KVM_CREATE_VCPU), which is
> expected
> as an architecrual vCPU ID instead of a vCPU index by host. It's indicated
> by 'struct kvm_vcpu' as below.


That should not be part of this change. I think.


> struct kvm_vcpu {
>   :
>   int vcpu_id;  /* id given by userspace at creation */
>  int vcpu_idx; /* index into kvm->vcpu_array */
> };
> 
> Function kvm_arch_vcpu_id() converts the vCPU instance or vCPU index to
> the architecrual vCPU ID. All architectures except x86 simply returns
> vCPU index (CPUState::cpu_index) as the architecrural vCPU ID. x86 returns
> the APIC ID. Tr

RE: [PATCH V2 02/10] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2023-10-03 Thread Salil Mehta via
Hi Jonathan,

> From: Jonathan Cameron 
> Sent: Monday, October 2, 2023 4:55 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; imamm...@redhat.com; andrew.jo...@linux.dev;
> da...@redhat.com; phi...@linaro.org; eric.au...@redhat.com;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> w...@kernel.org; gs...@redhat.com; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 02/10] hw/acpi: Move CPU ctrl-dev MMIO region len
> macro to common header file
> 
> On Sat, 30 Sep 2023 01:19:25 +0100
> Salil Mehta  wrote:
> 
> > CPU ctrl-dev MMIO region length could be used in ACPI GED and various
> other
> > architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
> > appropriate common header file.
> >
> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Alex Bennée 
> LGTM
> 
> Reviewed-by: Jonathan Cameron 

Thanks
Salil.






RE: [PATCH V2 02/10] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2023-10-03 Thread Salil Mehta via
Hi Gavin,

> From: Gavin Shan 
> Sent: Tuesday, October 3, 2023 12:20 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; qemu-
> a...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 02/10] hw/acpi: Move CPU ctrl-dev MMIO region len
> macro to common header file
> 
> On 9/30/23 10:19, Salil Mehta wrote:
> > CPU ctrl-dev MMIO region length could be used in ACPI GED and various
> other
> > architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
> > appropriate common header file.
> >
> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Alex Bennée 
> > ---
> >   hw/acpi/cpu.c | 2 +-
> >   include/hw/acpi/cpu_hotplug.h | 2 ++
> >   2 files changed, 3 insertions(+), 1 deletion(-)
> >
> 
> Reviewed-by: Gavin Shan 

Thanks
Salil.


RE: [PATCH V2 03/10] hw/acpi: Add ACPI CPU hotplug init stub

2023-10-03 Thread Salil Mehta via
> From: Jonathan Cameron 
> Sent: Monday, October 2, 2023 5:01 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; imamm...@redhat.com; andrew.jo...@linux.dev;
> da...@redhat.com; phi...@linaro.org; eric.au...@redhat.com;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> w...@kernel.org; gs...@redhat.com; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 03/10] hw/acpi: Add ACPI CPU hotplug init stub
> 
> On Sat, 30 Sep 2023 01:19:26 +0100
> Salil Mehta  wrote:
> 
> > ACPI CPU hotplug related initialization should only happen if
> ACPI_CPU_HOTPLUG
> > support has been enabled for particular architecture. Add
> cpu_hotplug_hw_init()
> > stub to avoid compilation break.
> >
> > Signed-off-by: Salil Mehta 
> Seems reasonable.  For the other similar cases a stub isn't needed
> because GED is built when CONFIG_ACPI_HW_REDUCED=y and
> that select ACPI_MEMORY_HOTPLUG and ACPI_NVDIMM
> 
> You could do the same for the CPU hotplug case and instantiate
> a potentially useless memory region etc.  This seems more sensible to me
> 
> Reviewed-by: Jonathan Cameron 


Thanks
Salil.

> >  hw/acpi/acpi-cpu-hotplug-stub.c | 6 ++
> >  1 file changed, 6 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-
> stub.c
> > index 3fc4b14c26..c6c61bb9cd 100644
> > --- a/hw/acpi/acpi-cpu-hotplug-stub.c
> > +++ b/hw/acpi/acpi-cpu-hotplug-stub.c
> > @@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion
> *parent, Object *owner,
> >  return;
> >  }
> >
> > +void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
> > + CPUHotplugState *state, hwaddr base_addr)
> > +{
> > +return;
> > +}
> > +
> >  void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList
> ***list)
> >  {
> >  return;




RE: [PATCH V2 03/10] hw/acpi: Add ACPI CPU hotplug init stub

2023-10-03 Thread Salil Mehta via
> From: Gavin Shan 
> Sent: Tuesday, October 3, 2023 12:25 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; qemu-
> a...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 03/10] hw/acpi: Add ACPI CPU hotplug init stub
> 
> 
> On 9/30/23 10:19, Salil Mehta wrote:
> > ACPI CPU hotplug related initialization should only happen if
> ACPI_CPU_HOTPLUG
> > support has been enabled for particular architecture. Add
> cpu_hotplug_hw_init()
> > stub to avoid compilation break.
> >
> > Signed-off-by: Salil Mehta 
> > ---
> >   hw/acpi/acpi-cpu-hotplug-stub.c | 6 ++
> >   1 file changed, 6 insertions(+)
> >
> 
> Reviewed-by: Gavin Shan 

Thanks
Salil.


> 
> > diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-
> stub.c
> > index 3fc4b14c26..c6c61bb9cd 100644
> > --- a/hw/acpi/acpi-cpu-hotplug-stub.c
> > +++ b/hw/acpi/acpi-cpu-hotplug-stub.c
> > @@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion
> *parent, Object *owner,
> >   return;
> >   }
> >
> > +void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
> > + CPUHotplugState *state, hwaddr base_addr)
> > +{
> > +return;
> ^^
> > +}
> > +
> 
> I guess the return is the outcome by following the pattern of other
> functions ;-)


I can remove it. :)




RE: [PATCH V2 04/10] hw/acpi: Init GED framework with cpu hotplug events

2023-10-03 Thread Salil Mehta via
> From: Jonathan Cameron 
> Sent: Monday, October 2, 2023 5:07 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; imamm...@redhat.com; andrew.jo...@linux.dev;
> da...@redhat.com; phi...@linaro.org; eric.au...@redhat.com;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> w...@kernel.org; gs...@redhat.com; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 04/10] hw/acpi: Init GED framework with cpu hotplug
> events
> 
> On Sat, 30 Sep 2023 01:19:27 +0100
> Salil Mehta  wrote:
> 
> > ACPI GED(as described in the ACPI 6.2 spec) can be used to generate ACPI
> events
> > when OSPM/guest receives an interrupt listed in the _CRS object of GED.
> OSPM
> > then maps or demultiplexes the event by evaluating _EVT method.
> >
> > This change adds the support of cpu hotplug event initialization in the
> > existing GED framework.
> >
> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> Oops. I replied to v1 I think.
> 
> Reviewed-by: Jonathan Cameron 

Thanks
Salil.



RE: [PATCH V2 04/10] hw/acpi: Init GED framework with cpu hotplug events

2023-10-03 Thread Salil Mehta via
> From: Gavin Shan 
> Sent: Tuesday, October 3, 2023 12:29 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; qemu-
> a...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; raf...@kernel.org;
> alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V2 04/10] hw/acpi: Init GED framework with cpu hotplug
> events
> 
> On 9/30/23 10:19, Salil Mehta wrote:
> > ACPI GED(as described in the ACPI 6.2 spec) can be used to generate ACPI
> events
> > when OSPM/guest receives an interrupt listed in the _CRS object of GED.
> OSPM
> > then maps or demultiplexes the event by evaluating _EVT method.
> >
> > This change adds the support of cpu hotplug event initialization in the
> > existing GED framework.
> >
> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> > ---
> >   hw/acpi/generic_event_device.c | 8 
> >   include/hw/acpi/generic_event_device.h | 5 +
> >   2 files changed, 13 insertions(+)
> >
> 
> Reviewed-by: Gavin Shan 

Thanks
Salil.



  1   2   3   4   5   >