[PULL v2 6/9] backends/cryptodev-builtin: Fix local_error leaks

2024-04-29 Thread Michael Tokarev
From: Li Zhijian 

It seems that this error does not need to be propagated to the upper,
directly output the error to avoid the leaks

Closes: https://gitlab.com/qemu-project/qemu/-/issues/2283
Fixes: 2fda101de07 ("virtio-crypto: Support asynchronous mode")
Signed-off-by: Li Zhijian 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: zhenwei pi 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 backends/cryptodev-builtin.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
index a514bbb310..940104ee55 100644
--- a/backends/cryptodev-builtin.c
+++ b/backends/cryptodev-builtin.c
@@ -23,6 +23,7 @@
 
 #include "qemu/osdep.h"
 #include "sysemu/cryptodev.h"
+#include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "standard-headers/linux/virtio_crypto.h"
 #include "crypto/cipher.h"
@@ -396,8 +397,8 @@ static int cryptodev_builtin_create_session(
 case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
 case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
 default:
-error_setg(_error, "Unsupported opcode :%" PRIu32 "",
-   sess_info->op_code);
+error_report("Unsupported opcode :%" PRIu32 "",
+ sess_info->op_code);
 return -VIRTIO_CRYPTO_NOTSUPP;
 }
 
@@ -554,8 +555,8 @@ static int cryptodev_builtin_operation(
 
 if (op_info->session_id >= MAX_NUM_SESSIONS ||
   builtin->sessions[op_info->session_id] == NULL) {
-error_setg(_error, "Cannot find a valid session id: %" PRIu64 "",
-   op_info->session_id);
+error_report("Cannot find a valid session id: %" PRIu64 "",
+ op_info->session_id);
 return -VIRTIO_CRYPTO_INVSESS;
 }
 
-- 
2.39.2




[PULL v2 0/9] Trivial patches for 2024-04-29

2024-04-29 Thread Michael Tokarev
The following changes since commit fd87be1dada5672f877e03c2ca8504458292c479:

  Merge tag 'accel-20240426' of https://github.com/philmd/qemu into staging 
(2024-04-26 15:28:13 -0700)

are available in the Git repository at:

  https://gitlab.com/mjt0k/qemu.git tags/pull-trivial-patches

for you to fetch changes up to ce1992d45c875c29a9018b7ac2fa9bad6587c711:

  checkpatch.pl: forbid strerrorname_np() (2024-04-29 15:26:56 +0300)


trivial patches for 2024-04-29

v2: fix author of "backends/cryptodev-builtin: Fix local_error leaks"
(which should be catched now by checkpatch.pl additions in this series)
Only patch 6 is being resent.

Daniel Henrique Barboza (2):
  target/riscv/kvm: remove sneaky strerrorname_np() instance
  checkpatch.pl: forbid strerrorname_np()

Li Zhijian (1):
  backends/cryptodev-builtin: Fix local_error leaks

Michael Tokarev (1):
  target/loongarch/cpu.c: typo fix: expection

Philippe Mathieu-Daudé (2):
  scripts/checkpatch: Avoid author email mangled by qemu-*@nongnu.org
  scripts/checkpatch: Do not use mailmap

Thomas Huth (3):
  target/i386/cpu: Remove "x86" prefix from the CPU list
  target/s390x/cpu_models: Rework the output of "-cpu help"
  target/ppc/cpu_init: Remove "PowerPC" prefix from the CPU list

 backends/cryptodev-builtin.c |  9 +
 scripts/checkpatch.pl| 11 +++
 target/i386/cpu.c|  2 +-
 target/loongarch/cpu.c   |  2 +-
 target/ppc/cpu_init.c|  9 +
 target/riscv/kvm/kvm-cpu.c   |  4 ++--
 target/s390x/cpu_models.c|  9 +
 7 files changed, 26 insertions(+), 20 deletions(-)



Re: [PULL 1/1] hw/ufs: Fix buffer overflow bug

2024-04-29 Thread Michael Tokarev

29.04.2024 06:25, Jeuk Kim wrote:

From: Jeuk Kim 

It fixes the buffer overflow vulnerability in the ufs device.
The bug was detected by sanitizers.


...

Resolves: #2299
Fixes: 329f16624499 ("hw/ufs: Support for Query Transfer Requests")
Reported-by: Zheyu Ma 
Signed-off-by: Jeuk Kim 


Cc: qemu-stable@ for 8.2 and 9.0 series.

Please do not forget to Cc qemu-stable@ for relevant changes.

Thanks,

/mjt



[PULL 6/9] backends/cryptodev-builtin: Fix local_error leaks

2024-04-29 Thread Michael Tokarev
From: Li Zhijian via 

It seems that this error does not need to be propagated to the upper,
directly output the error to avoid the leaks

Closes: https://gitlab.com/qemu-project/qemu/-/issues/2283
Fixes: 2fda101de07 ("virtio-crypto: Support asynchronous mode")
Signed-off-by: Li Zhijian 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: zhenwei pi 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 backends/cryptodev-builtin.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
index a514bbb310..940104ee55 100644
--- a/backends/cryptodev-builtin.c
+++ b/backends/cryptodev-builtin.c
@@ -23,6 +23,7 @@
 
 #include "qemu/osdep.h"
 #include "sysemu/cryptodev.h"
+#include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "standard-headers/linux/virtio_crypto.h"
 #include "crypto/cipher.h"
@@ -396,8 +397,8 @@ static int cryptodev_builtin_create_session(
 case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
 case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
 default:
-error_setg(_error, "Unsupported opcode :%" PRIu32 "",
-   sess_info->op_code);
+error_report("Unsupported opcode :%" PRIu32 "",
+ sess_info->op_code);
 return -VIRTIO_CRYPTO_NOTSUPP;
 }
 
@@ -554,8 +555,8 @@ static int cryptodev_builtin_operation(
 
 if (op_info->session_id >= MAX_NUM_SESSIONS ||
   builtin->sessions[op_info->session_id] == NULL) {
-error_setg(_error, "Cannot find a valid session id: %" PRIu64 "",
-   op_info->session_id);
+error_report("Cannot find a valid session id: %" PRIu64 "",
+ op_info->session_id);
 return -VIRTIO_CRYPTO_INVSESS;
 }
 
-- 
2.39.2




[PULL 4/9] scripts/checkpatch: Avoid author email mangled by qemu-*@nongnu.org

2024-04-29 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Commit f5177798d8 ("scripts: report on author emails
that are mangled by the mailing list") added a check
for qemu-devel@ list, extend the regexp to cover more
such qemu-trivial@, qemu-block@ and qemu-ppc@.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 scripts/checkpatch.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 7026895074..12e9028b10 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1573,7 +1573,7 @@ sub process {
$is_patch = 1;
}
 
-   if ($line =~ /^(Author|From): .* via 
.*/) {
+   if ($line =~ /^(Author|From): .* via 
.*/) {
ERROR("Author email address is mangled by the mailing 
list\n" . $herecurr);
}
 
-- 
2.39.2




[PULL 0/9] Trivial patches for 2024-04-29

2024-04-29 Thread Michael Tokarev
The following changes since commit fd87be1dada5672f877e03c2ca8504458292c479:

  Merge tag 'accel-20240426' of https://github.com/philmd/qemu into staging 
(2024-04-26 15:28:13 -0700)

are available in the Git repository at:

  https://gitlab.com/mjt0k/qemu.git tags/pull-trivial-patches

for you to fetch changes up to d2f20c25281908a07bcb8c3dea8292abf68e5c8b:

  checkpatch.pl: forbid strerrorname_np() (2024-04-29 09:37:26 +0300)


trivial patches for 2024-04-29


Daniel Henrique Barboza (2):
  target/riscv/kvm: remove sneaky strerrorname_np() instance
  checkpatch.pl: forbid strerrorname_np()

Li Zhijian via (1):
  backends/cryptodev-builtin: Fix local_error leaks

Michael Tokarev (1):
  target/loongarch/cpu.c: typo fix: expection

Philippe Mathieu-Daudé (2):
  scripts/checkpatch: Avoid author email mangled by qemu-*@nongnu.org
  scripts/checkpatch: Do not use mailmap

Thomas Huth (3):
  target/i386/cpu: Remove "x86" prefix from the CPU list
  target/s390x/cpu_models: Rework the output of "-cpu help"
  target/ppc/cpu_init: Remove "PowerPC" prefix from the CPU list

 backends/cryptodev-builtin.c |  9 +
 scripts/checkpatch.pl| 11 +++
 target/i386/cpu.c|  2 +-
 target/loongarch/cpu.c   |  2 +-
 target/ppc/cpu_init.c|  9 +
 target/riscv/kvm/kvm-cpu.c   |  4 ++--
 target/s390x/cpu_models.c|  9 +
 7 files changed, 26 insertions(+), 20 deletions(-)



[PULL 2/9] target/s390x/cpu_models: Rework the output of "-cpu help"

2024-04-29 Thread Michael Tokarev
From: Thomas Huth 

Printing an "s390x" in front of each CPU name is not helpful at all:
It is confusing for the users since they don't know whether they
have to specify these letters for the "-cpu" parameter, too, and
it also takes some precious space in the dense output of the CPU
entries. Let's simply remove this now!

While we're at it, use two spaces at the beginning of the lines for
the indentation of the entries, and add a "Available CPUs" in the
very first line, like most other target architectures are doing it
for their "-cpu help" output already.

Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 target/s390x/cpu_models.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 8ed3bb6a27..58c58f05a0 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -355,9 +355,9 @@ static void s390_print_cpu_model_list_entry(gpointer data, 
gpointer user_data)
 /* strip off the -s390x-cpu */
 g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
 if (details->len) {
-qemu_printf("s390 %-15s %-35s (%s)\n", name, scc->desc, details->str);
+qemu_printf("  %-15s %-35s (%s)\n", name, scc->desc, details->str);
 } else {
-qemu_printf("s390 %-15s %-35s\n", name, scc->desc);
+qemu_printf("  %-15s %-35s\n", name, scc->desc);
 }
 g_free(name);
 }
@@ -402,6 +402,7 @@ void s390_cpu_list(void)
 S390Feat feat;
 GSList *list;
 
+qemu_printf("Available CPUs:\n");
 list = object_class_get_list(TYPE_S390_CPU, false);
 list = g_slist_sort(list, s390_cpu_list_compare);
 g_slist_foreach(list, s390_print_cpu_model_list_entry, NULL);
@@ -411,14 +412,14 @@ void s390_cpu_list(void)
 for (feat = 0; feat < S390_FEAT_MAX; feat++) {
 const S390FeatDef *def = s390_feat_def(feat);
 
-qemu_printf("%-20s %s\n", def->name, def->desc);
+qemu_printf("  %-20s %s\n", def->name, def->desc);
 }
 
 qemu_printf("\nRecognized feature groups:\n");
 for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
 const S390FeatGroupDef *def = s390_feat_group_def(group);
 
-qemu_printf("%-20s %s\n", def->name, def->desc);
+qemu_printf("  %-20s %s\n", def->name, def->desc);
 }
 }
 
-- 
2.39.2




[PULL 9/9] checkpatch.pl: forbid strerrorname_np()

2024-04-29 Thread Michael Tokarev
From: Daniel Henrique Barboza 

Commit d424db2354 removed an instance of strerrorname_np() because it
was breaking building with musl libc. A recent RISC-V patch ended up
re-introducing it again by accident.

Put this function in the baddies list in checkpatch.pl to avoid this
situation again. This is what it will look like next time:

 $ ./scripts/checkpatch.pl 0001-temp-test.patch
 ERROR: use strerror() instead of strerrorname_np()
 #22: FILE: target/riscv/kvm/kvm-cpu.c:1058:
 + strerrorname_np(errno));

 total: 1 errors, 0 warnings, 10 lines checked

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 scripts/checkpatch.pl | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 76a0b79266..ff373a7083 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -3078,6 +3078,9 @@ sub process {
if ($line =~ /\b(g_)?assert\(0\)/) {
ERROR("use g_assert_not_reached() instead of 
assert(0)\n" . $herecurr);
}
+   if ($line =~ /\bstrerrorname_np\(/) {
+   ERROR("use strerror() instead of strerrorname_np()\n" . 
$herecurr);
+   }
my $non_exit_glib_asserts = qr{g_assert_cmpstr|
g_assert_cmpint|
g_assert_cmpuint|
-- 
2.39.2




[PULL 5/9] scripts/checkpatch: Do not use mailmap

2024-04-29 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

The .mailmap file fixes mistake we already did.
Do not use it when running checkpatch.pl, otherwise
we might commit the very same mistakes.

Reported-by: Peter Maydell 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 scripts/checkpatch.pl | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 12e9028b10..76a0b79266 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -435,8 +435,8 @@ if ($chk_branch) {
my @patches;
my %git_commits = ();
my $HASH;
-   open($HASH, "-|", "git", "log", "--reverse", "--no-merges", 
"--format=%H %s", $ARGV[0]) ||
-   die "$P: git log --reverse --no-merges --format='%H %s' 
$ARGV[0] failed - $!\n";
+   open($HASH, "-|", "git", "log", "--reverse", "--no-merges", 
"--no-mailmap", "--format=%H %s", $ARGV[0]) ||
+   die "$P: git log --reverse --no-merges --no-mailmap 
--format='%H %s' $ARGV[0] failed - $!\n";
 
for my $line (<$HASH>) {
$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
@@ -460,7 +460,7 @@ if ($chk_branch) {
  "-c", "diff.renamelimit=0",
  "-c", "diff.renames=True",
  "-c", "diff.algorithm=histogram",
- "show",
+ "show", "--no-mailmap",
  "--patch-with-stat", $hash) ||
die "$P: git show $hash - $!\n";
while (<$FILE>) {
-- 
2.39.2




[PULL 1/9] target/i386/cpu: Remove "x86" prefix from the CPU list

2024-04-29 Thread Michael Tokarev
From: Thomas Huth 

Printing an "x86" in front of each CPU name is not helpful at all:
It is confusing for the users since they don't know whether they
have to specify these letters for the "-cpu" parameter, too, and
it also takes some precious space in the dense output of the CPU
entries. Let's simply remove this now and use two spaces at the
beginning of the lines for the indentation of the entries instead,
like most other target architectures are doing it for their CPU help
output already.

Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 target/i386/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fa1ea3735d..aa3b2d8391 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5708,7 +5708,7 @@ static void x86_cpu_list_entry(gpointer data, gpointer 
user_data)
 desc = g_strdup_printf("%s (deprecated)", olddesc);
 }
 
-qemu_printf("x86 %-20s  %s\n", name, desc);
+qemu_printf("  %-20s  %s\n", name, desc);
 }
 
 /* list available CPU models and flags */
-- 
2.39.2




[PULL 8/9] target/riscv/kvm: remove sneaky strerrorname_np() instance

2024-04-29 Thread Michael Tokarev
From: Daniel Henrique Barboza 

Commit d424db2354 excluded some strerrorname_np() instances because they
break musl libc builds. Another instance happened to slip by via commit
d4ff3da8f4.

Remove it before it causes trouble again.

Fixes: d4ff3da8f4 (target/riscv/kvm: initialize 'vlenb' via get-reg-list)
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 target/riscv/kvm/kvm-cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 49d2f3ad58..eaa36121c7 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1054,8 +1054,8 @@ static void kvm_riscv_read_vlenb(RISCVCPU *cpu, 
KVMScratchCPU *kvmcpu,
 
 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, );
 if (ret != 0) {
-error_report("Unable to read vlenb register, error code: %s",
- strerrorname_np(errno));
+error_report("Unable to read vlenb register, error code: %d",
+ errno);
 exit(EXIT_FAILURE);
 }
 
-- 
2.39.2




[PULL 3/9] target/ppc/cpu_init: Remove "PowerPC" prefix from the CPU list

2024-04-29 Thread Michael Tokarev
From: Thomas Huth 

Printing a "PowerPC" in front of each CPU name is not helpful at all:
It is confusing for the users since they don't know whether they
have to specify these letters for the "-cpu" parameter, too, and
it also takes some precious space in the dense output of the CPU
entries. Let's simply remove this now and use two spaces at the
beginning of the lines for the indentation of the entries instead,
and add a "Available CPUs" in the very first line, like most other
target architectures are doing it for their CPU help output already.

Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Reviewed-by: Michael Tokarev 
Signed-off-by: Michael Tokarev 
---
 target/ppc/cpu_init.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 6d82f24c87..c11a69fd90 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7063,7 +7063,7 @@ static void ppc_cpu_list_entry(gpointer data, gpointer 
user_data)
 }
 
 name = cpu_model_from_type(typename);
-qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
+qemu_printf("  %-16s PVR %08x\n", name, pcc->pvr);
 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
 PowerPCCPUAlias *alias = _cpu_aliases[i];
 ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
@@ -7076,10 +7076,10 @@ static void ppc_cpu_list_entry(gpointer data, gpointer 
user_data)
  * avoid printing the wrong alias here and use "preferred" instead
  */
 if (strcmp(alias->alias, family->desc) == 0) {
-qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
+qemu_printf("  %-16s (alias for preferred %s CPU)\n",
 alias->alias, family->desc);
 } else {
-qemu_printf("PowerPC %-16s (alias for %s)\n",
+qemu_printf("  %-16s (alias for %s)\n",
 alias->alias, name);
 }
 }
@@ -7090,6 +7090,7 @@ void ppc_cpu_list(void)
 {
 GSList *list;
 
+qemu_printf("Available CPUs:\n");
 list = object_class_get_list(TYPE_POWERPC_CPU, false);
 list = g_slist_sort(list, ppc_cpu_list_compare);
 g_slist_foreach(list, ppc_cpu_list_entry, NULL);
@@ -7097,7 +7098,7 @@ void ppc_cpu_list(void)
 
 #ifdef CONFIG_KVM
 qemu_printf("\n");
-qemu_printf("PowerPC %s\n", "host");
+qemu_printf("  %s\n", "host");
 #endif
 }
 
-- 
2.39.2




[PULL 7/9] target/loongarch/cpu.c: typo fix: expection

2024-04-29 Thread Michael Tokarev
Fixes: 1590154ee437 ("target/loongarch: Fix qemu-system-loongarch64 assert 
failed with the option '-d int'")
Signed-off-by: Michael Tokarev 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index bac84dca7a..1ebba043f4 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -92,7 +92,7 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env,
 {
 CPUState *cs = env_cpu(env);
 
-qemu_log_mask(CPU_LOG_INT, "%s: expection: %d (%s)\n",
+qemu_log_mask(CPU_LOG_INT, "%s: exception: %d (%s)\n",
   __func__,
   exception,
   loongarch_exception_name(exception));
-- 
2.39.2




Re: [PATCH v2] migration/colo: Fix bdrv_graph_rdlock_main_loop: Assertion `!qemu_in_coroutine()' failed.

2024-04-28 Thread Michael Tokarev

17.04.2024 05:56, Li Zhijian via wrote:

--- a/migration/colo.c
+++ b/migration/colo.c
@@ -835,6 +835,16 @@ static void *colo_process_incoming_thread(void *opaque)
  return NULL;
  }
  
+/* Make sure all file formats throw away their mutable metadata */

+bql_lock();
+bdrv_activate_all(_err);
+if (local_err) {
+bql_unlock();
+error_report_err(local_err);
+return NULL;
+}
+bql_unlock();

FWIW, this can be simplified as follows:

   bql_lock();
   bdrv_activate_all(_err);
   bql_unlock();
   if (local_err) {
error_report_err(local_err);
return NULL;
   }

(I know it is already too late)

/mjt

--
GPG Key transition (from rsa2048 to rsa4096) since 2024-04-24.
New key: rsa4096/61AD3D98ECDF2C8E  9D8B E14E 3F2A 9DD7 9199  28F1 61AD 3D98 
ECDF 2C8E
Old key: rsa2048/457CE0A0804465C5  6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 
8044 65C5
Transition statement: http://www.corpit.ru/mjt/gpg-transition-2024.txt




Re: [PATCH v2] migration/colo: Fix bdrv_graph_rdlock_main_loop: Assertion `!qemu_in_coroutine()' failed.

2024-04-28 Thread Michael Tokarev

17.04.2024 05:56, Li Zhijian via wrote:

bdrv_activate_all() should not be called from the coroutine context, move
it to the QEMU thread colo_process_incoming_thread() with the bql_lock
protected.

The backtrace is as follows:
  #4  0x561af7948362 in bdrv_graph_rdlock_main_loop () at 
../block/graph-lock.c:260
  #5  0x561af7907a68 in graph_lockable_auto_lock_mainloop 
(x=0x7fd29810be7b) at /patch/to/qemu/include/block/graph-lock.h:259
  #6  0x561af79167d1 in bdrv_activate_all (errp=0x7fd29810bed0) at 
../block.c:6906
  #7  0x561af762b4af in colo_incoming_co () at ../migration/colo.c:935
  #8  0x561af7607e57 in process_incoming_migration_co (opaque=0x0) at 
../migration/migration.c:793
  #9  0x561af7adbeeb in coroutine_trampoline (i0=-106876144, i1=22042) at 
../util/coroutine-ucontext.c:175
  #10 0x7fd2a5cf21c0 in  () at /lib64/libc.so.6

CC: Fabiano Rosas 
Closes: https://gitlab.com/qemu-project/qemu/-/issues/2277
Fixes: 2b3912f135 ("block: Mark bdrv_first_blk() and bdrv_is_root_node() 
GRAPH_RDLOCK")
Signed-off-by: Li Zhijian 


Commit 2b3912f135 is in 8.2 (v8.1.0-1575-g2b3912f135).  Is this fix supposed to 
go
to stable-8.2 series?  The prob here is that in 8.2, there's no bql_lock/unlock.
I guess it should use qemu_mutex_lock_iothread() instead, for before
195801d700c008 "system/cpus: rename qemu_mutex_lock_iothread() to bql_lock()".

Thanks,

/mjt


diff --git a/migration/colo.c b/migration/colo.c
index 84632a603e..5600a43d78 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -835,6 +835,16 @@ static void *colo_process_incoming_thread(void *opaque)
  return NULL;
  }
  
+/* Make sure all file formats throw away their mutable metadata */

+bql_lock();
+bdrv_activate_all(_err);
+if (local_err) {
+bql_unlock();
+error_report_err(local_err);
+return NULL;
+}
+bql_unlock();
+
  failover_init_state();
  
  mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);

@@ -922,7 +932,6 @@ out:
  int coroutine_fn colo_incoming_co(void)
  {
  MigrationIncomingState *mis = migration_incoming_get_current();
-Error *local_err = NULL;
  QemuThread th;
  
  assert(bql_locked());

@@ -931,13 +940,6 @@ int coroutine_fn colo_incoming_co(void)
  return 0;
  }
  
-/* Make sure all file formats throw away their mutable metadata */

-bdrv_activate_all(_err);
-if (local_err) {
-error_report_err(local_err);
-return -EINVAL;
-}
-
  qemu_thread_create(, "COLO incoming", colo_process_incoming_thread,
 mis, QEMU_THREAD_JOINABLE);
  


--
GPG Key transition (from rsa2048 to rsa4096) since 2024-04-24.
New key: rsa4096/61AD3D98ECDF2C8E  9D8B E14E 3F2A 9DD7 9199  28F1 61AD 3D98 
ECDF 2C8E
Old key: rsa2048/457CE0A0804465C5  6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 
8044 65C5
Transition statement: http://www.corpit.ru/mjt/gpg-transition-2024.txt




Re: [PATCH v2 1/1] target/riscv/kvm: fix timebase-frequency when using KVM acceleration

2024-04-27 Thread Michael Tokarev

27.04.2024 18:17, Andrew Jones :

I wrote instructions [2] for how to cross-compile without a full 
environment/container once. It might be better for quick, local testing.

[2] 
https://lore.kernel.org/qemu-riscv/20230726120706.335340-2-ajo...@ventanamicro.com/


I just extracted a few packages from debian riscv64 (like libglib & deps)
in a separate dir and pointed various tools (pkgconf, gcc -I, gcc -L) to
that dir.



49c211ffca00fdf7c is also needed.  So it's 3 so far, still not compile-
tested.  Anything else?


Those 3, the first of the series [1], are good. Not sure why it's still not 
compiling.


Yes, I picked up these 3 I mentioned, in addition to the problematic one
which is part of 8.2.3.  Once I had the build environment, I tried compiling
it, and it builds fine.  I wrote it is not compile-TESTED, not as it fails
to compile.

Also, I tried to build qemu on a real riscv64 hardware (on a debian porterbox),
-- it built fine (with the 3 mentioned changes applied) and is now running
tests, but it looks like it will be fine too.


[1] https://lists.gnu.org/archive/html/qemu-devel/2023-12/msg01132.html


So yes, I'm picking these additional 3 from this set, - the ones which
I already mentioned.

Thanks,

/mjt


--
GPG Key transition (from rsa2048 to rsa4096) since 2024-04-24.
New key: rsa4096/61AD3D98ECDF2C8E  9D8B E14E 3F2A 9DD7 9199  28F1 61AD 3D98 
ECDF 2C8E
Old key: rsa2048/457CE0A0804465C5  6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 
8044 65C5
Transition statement: http://www.corpit.ru/mjt/gpg-transition-2024.txt




Re: [PATCH v2 1/1] target/riscv/kvm: fix timebase-frequency when using KVM acceleration

2024-04-27 Thread Michael Tokarev

27.04.2024 09:59, Michael Tokarev wrote:

27.04.2024 09:23, Andrew Jones wrote:

...

It's possible to cross-compile qemu, so it'd be good to add that to the CI for 
riscv until we can add native compiling.


Yes, definitely.  Qemu is already being cross-compiled on all "other"
architectures during CI.  But it is also being *run*, not just compiled.
And this is what's broken on riscv64 for almost a year now, and this
job has been disabled.  Instead, the *run* part of this job needs to
be disabled, but *build* part should be kept.


Aha. I was wrong. And I was there before too, for sure, - just forgot
about it. In order to be cross-compiled, the cross-build environment
needs to have target -dev libraries, not only the cross-compiler.
And this is where debian riscv64 port is failing.

So no, it is not currently possible to cross-compile qemu at least
on debian without building whole cross-environment with all libraries
and other necessary stuff.

I'll try to use debian riscv64 porterbox to at least verify the new
set of patches we'll pick here to fix this breakage, at least compiles
on riscv64 :)


10f86d1b845087d1 isn't sufficient, since it relies on 450bd6618fda3d
"target/riscv/kvm: change KVM_REG_RISCV_FP_D to u64".  In the same series
there also was 49c211ffca00fdf7c "target/riscv/kvm: change KVM_REG_RISCV_FP_F
to u32" - is it also needed?


49c211ffca00fdf7c is also needed.  So it's 3 so far, still not compile-
tested.  Anything else?

/mjt



Re: [PATCH v2 1/1] target/riscv/kvm: fix timebase-frequency when using KVM acceleration

2024-04-27 Thread Michael Tokarev

27.04.2024 09:23, Andrew Jones wrote:

On April 27, 2024 1:44:42 AM GMT+02:00, Michael Tokarev  wrote:

14.03.2024 09:15, Yong-Xuan Wang:

The timebase-frequency of guest OS should be the same with host
machine. The timebase-frequency value in DTS should be got from
hypervisor when using KVM acceleration.


This change ended up in stable-8.2 (v8.2.3).  Interestingly, this thing
compiled not even once, or else it would be obvious it fails to compile.
Somehow I was too used to CI, forgetting that we don't have riscv *host*
in CI (and I don't have one locally either).  So 8.2.3 is broken on
riscv64 *host*.


It's possible to cross-compile qemu, so it'd be good to add that to the CI for 
riscv until we can add native compiling.


Yes, definitely.  Qemu is already being cross-compiled on all "other"
architectures during CI.  But it is also being *run*, not just compiled.
And this is what's broken on riscv64 for almost a year now, and this
job has been disabled.  Instead, the *run* part of this job needs to
be disabled, but *build* part should be kept.


In 8.2, KVM_RISCV_GET_TIMER macro accepts 4 arguments, because it does
not have 10f86d1b845087d1 "target/riscv/kvm: change timer regs size to u64".

What do you think, should I revert this change for stable-8.2, or pick
10f86d1b845087d1 too, or change this commit (fix timebase-frequency) to
provide the missing argument for this macro?


Changing the timer regs to u64 is an rv32 fix, so it's reasonable to also pick 
it up. I suggest we keep this patch one way or another, though.


Okay, so I need help choosing which patches to pick.

10f86d1b845087d1 isn't sufficient, since it relies on 450bd6618fda3d
"target/riscv/kvm: change KVM_REG_RISCV_FP_D to u64".  In the same series
there also was 49c211ffca00fdf7c "target/riscv/kvm: change KVM_REG_RISCV_FP_F
to u32" - is it also needed?

Please tell me the set of things I need for stable-8.2 here.  I'd
love to makes 8.2.4 release really soon, to fix this breakage.

Also, right now I don't know how to even compile-test it.  So meanwhile I'll
try to fix that and push this change to qemu master (to re-enable riscv64
CI job but only build part of it).  I don't have riscv hardware handy :)

Thanks,

/mjt



Re: [PATCH v2 1/1] target/riscv/kvm: fix timebase-frequency when using KVM acceleration

2024-04-26 Thread Michael Tokarev

14.03.2024 09:15, Yong-Xuan Wang:

The timebase-frequency of guest OS should be the same with host
machine. The timebase-frequency value in DTS should be got from
hypervisor when using KVM acceleration.


This change ended up in stable-8.2 (v8.2.3).  Interestingly, this thing
compiled not even once, or else it would be obvious it fails to compile.
Somehow I was too used to CI, forgetting that we don't have riscv *host*
in CI (and I don't have one locally either).  So 8.2.3 is broken on
riscv64 *host*.

In 8.2, KVM_RISCV_GET_TIMER macro accepts 4 arguments, because it does
not have 10f86d1b845087d1 "target/riscv/kvm: change timer regs size to u64".

What do you think, should I revert this change for stable-8.2, or pick
10f86d1b845087d1 too, or change this commit (fix timebase-frequency) to
provide the missing argument for this macro?

Thanks,

/mjt



Reviewed-by: Andrew Jones 
Signed-off-by: Yong-Xuan Wang 

---
Changelog
v2:
- update the function definition
- restructure if-else statement
---
  hw/riscv/virt.c  | 2 ++
  target/riscv/kvm/kvm-cpu.c   | 9 +
  target/riscv/kvm/kvm_riscv.h | 1 +
  3 files changed, 12 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a094af97c32a..533b17799581 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -711,6 +711,8 @@ static void create_fdt_sockets(RISCVVirtState *s, const 
MemMapEntry *memmap,
  
  qemu_fdt_add_subnode(ms->fdt, "/cpus");

  qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
+  kvm_enabled() ?
+  kvm_riscv_get_timebase_frequency(first_cpu) :
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
  qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
  qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index c7afdb1e81b7..bbb115eaa867 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -739,6 +739,15 @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
  env->kvm_timer_dirty = false;
  }
  
+uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs)

+{
+uint64_t reg;
+
+KVM_RISCV_GET_TIMER(cs, frequency, reg);
+
+return reg;
+}
+
  static int kvm_riscv_get_regs_vector(CPUState *cs)
  {
  RISCVCPU *cpu = RISCV_CPU(cs);
diff --git a/target/riscv/kvm/kvm_riscv.h b/target/riscv/kvm/kvm_riscv.h
index 4bd98fddc776..58518988681d 100644
--- a/target/riscv/kvm/kvm_riscv.h
+++ b/target/riscv/kvm/kvm_riscv.h
@@ -28,5 +28,6 @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t 
group_shift,
  void riscv_kvm_aplic_request(void *opaque, int irq, int level);
  int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state);
  void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
+uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs);
  
  #endif


--
GPG Key transition (from rsa2048 to rsa4096) since 2024-04-24.
New key: rsa4096/61AD3D98ECDF2C8E  9D8B E14E 3F2A 9DD7 9199  28F1 61AD 3D98 
ECDF 2C8E
Old key: rsa2048/457CE0A0804465C5  6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 
8044 65C5
Transition statement: http://www.corpit.ru/mjt/gpg-transition-2024.txt




Re: [ANNOUNCE] QEMU 8.2.3 Stable released

2024-04-25 Thread Michael Tokarev

24.04.2024 20:39, Michael Tokarev wrote:

Hi everyone,

The QEMU v8.2.3 stable release is now available.

You can grab the tarball from our download page here:

   https://www.qemu.org/download/#source

   https://download.qemu.org/qemu-8.2.3.tar.xz
   https://download.qemu.org/qemu-8.2.3.tar.xz.sig (signature)


There was an error when 8.2.3 tarball has been generated yesterday,
the initial tarball included subprojects/dtc/ directory with dtc
sources by mistake.  It now has been re-uploaded without this
directory (only dtc.wrap is needed in there).  Sorry for any
possible inconvenience.

/mjt

--
GPG Key transition (from rsa2048 to rsa4096) since 2024-04-24.
New key: rsa4096/61AD3D98ECDF2C8E  9D8B E14E 3F2A 9DD7 9199  28F1 61AD 3D98 
ECDF 2C8E
Old key: rsa2048/457CE0A0804465C5  6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 
8044 65C5
Transition statement: http://www.corpit.ru/mjt/gpg-transition-2024.txt




Re: [PATCH v2 0/2] riscv,kvm: remove another strerrorname_np()

2024-04-24 Thread Michael Tokarev

24.04.2024 23:24, Daniel Henrique Barboza wrote:

Hi,

In this new version a small change suggested by Phil was made in patch
2. No other changes made.


Applied to trivial-patches tree.


Note: checkpatch.pl is nagging quite a bit about the checkpatch.pl change
this time, claiming that I'm adding a line > 90 chars when in reality the
line has 80 chars:

ERROR: line over 90 characters
#39: FILE: scripts/checkpatch.pl:3082:
+   ERROR("use strerror() instead of strerrorname_np()\n" . 
$herecurr);

total: 1 errors, 0 warnings, 9 lines checked

I supposed it's counting each TAB as more than one char. Let me know if
I need to care about this error and I'll send a v3.


checkpatch complaining about checkpatch change is nice.
Nope, it is the style used here, all other tests are
like this too, but worse.

/mjt



[PATCH] target/loongarch/cpu.c: typo fix: expection

2024-04-24 Thread Michael Tokarev
Fixes: 1590154ee437 ("target/loongarch: Fix qemu-system-loongarch64 assert 
failed with the option '-d int'")
Signed-off-by: Michael Tokarev 
---
 target/loongarch/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 203a349055..294bdbfa93 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -92,7 +92,7 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env,
 {
 CPUState *cs = env_cpu(env);
 
-qemu_log_mask(CPU_LOG_INT, "%s: expection: %d (%s)\n",
+qemu_log_mask(CPU_LOG_INT, "%s: exception: %d (%s)\n",
   __func__,
   exception,
   loongarch_exception_name(exception));
-- 
2.39.2




[ANNOUNCE] QEMU 8.2.3 Stable released

2024-04-24 Thread Michael Tokarev
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Hi everyone,

The QEMU v8.2.3 stable release is now available.

You can grab the tarball from our download page here:

  https://www.qemu.org/download/#source

  https://download.qemu.org/qemu-8.2.3.tar.xz
  https://download.qemu.org/qemu-8.2.3.tar.xz.sig (signature)

v8.2.3 is now tagged in the official qemu.git repository, and the
stable-8.2 branch has been updated accordingly:

  https://gitlab.com/qemu-project/qemu/-/commits/stable-8.2

There are 116 changes since the previous v8.2.2 release.

Thank you everyone who has been involved and helped with the stable series!

/mjt

Changelog (stable-8.2-hash master-hash Author Name: Commmit-Subject):

8216663a5c Michael Tokarev:
 Update version for 8.2.3 release
51da750063 c4f91d7b7b Harsh Prateek Bora:
 ppc/spapr: Initialize max_cpus limit to SPAPR_IRQ_NR_IPIS.
c513ee1b91 2df5c1f5b0 Harsh Prateek Bora:
 ppc/spapr: Introduce SPAPR_IRQ_NR_IPIS to refer IRQ range for CPU IPIs.
1a78b89bcf 6e4aceba20 BALATON Zoltan:
 hw/pci-host/ppc440_pcix: Do not expose a bridge device on PCI bus
dd784cb65d f33274265a BALATON Zoltan:
 hw/isa/vt82c686: Keep track of PIRQ/PINT pins separately
fcbb086ae5 2ce6cff94d Cindy Lu:
 virtio-pci: fix use of a released vector
6e29509abc 4ef1f559f2 Richard Henderson:
 linux-user/x86_64: Handle the vsyscall page in open_self_maps_{2,4}
e2dfadfd07 dcb0a1ac03 Philippe Mathieu-Daudé:
 hw/audio/virtio-snd: Remove unused assignment
1cfe45956e 83ddb3dbba Philippe Mathieu-Daudé:
 hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()
35a67d2aa8 9e4b27ca6b Philippe Mathieu-Daudé:
 hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set
9666bd2b79 ad766d603f Philippe Mathieu-Daudé:
 hw/net/lan9118: Fix overflow in MIL TX FIFO
4e6240e184 a45223467e Philippe Mathieu-Daudé:
 hw/net/lan9118: Replace magic '2048' value by MIL_TXFIFO_SIZE definition
516bdbc234 eaf2bd2953 Philippe Mathieu-Daudé:
 backends/cryptodev: Do not abort for invalid session ID
1c5005c450 fc09ff2979 Philippe Mathieu-Daudé:
 hw/misc/applesmc: Fix memory leak in reset() handler
6e7e387b79 d39fdfff34 Philippe Mathieu-Daudé:
 hw/block/nand: Fix out-of-bound access in NAND block buffer
ab995895ad 2e3e09b368 Philippe Mathieu-Daudé:
 hw/block/nand: Have blk_load() take unsigned offset and return boolean
15b41461ea 7a86544f28 Philippe Mathieu-Daudé:
 hw/block/nand: Factor nand_load_iolen() method out
5d53ff200b aa88f99c87 Yuquan Wang:
 qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo
4f01537ced f4729ec39a Philippe Mathieu-Daudé:
 hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs
fbeb0a160c b4295bff25 Philippe Mathieu-Daudé:
 hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs
1b2a52712b ba28e0ff4d Philippe Mathieu-Daudé:
 hw/display/virtio-gpu: Protect from DMA re-entrancy bugs
eb546a3f49 ec0504b989 Philippe Mathieu-Daudé:
 hw/virtio: Introduce virtio_bh_new_guarded() helper
390da29ce5 5888357942 Keith Packard:
 target/m68k: Map FPU exceptions to FPSR register
0764b8a8e3 b754cb2dcd Zack Buhman:
 target/sh4: add missing CHECK_NOT_DELAY_SLOT
733511728a 7227c0cd50 Zack Buhman:
 target/sh4: Fix mac.w with saturation enabled
77e03229ca c97e8977dc Zack Buhman:
 target/sh4: Fix mac.l with saturation enabled
7fc1bcb65f 7d95db5e78 Richard Henderson:
 target/sh4: Merge mach and macl into a union
be88ed87a6 b0f2f2976b Zack Buhman:
 target/sh4: mac.w: memory accesses are 16-bit words
c02844b8e8 f0907ff4ca Richard Henderson:
 linux-user: Fix waitid return of siginfo_t and rusage
196601e759 e25fe886b8 Richard Henderson:
 tcg/optimize: Do not attempt to constant fold neg_vec
20cd0c8655 731655f87f Manos Pitsidianakis:
 virtio-snd: rewrite invalid tx/rx message handling
627aa460ba a45f09935c Zheyu Ma:
 virtio-snd: Enhance error handling for invalid transfers
cd461c8445 6ae72f609a lyx634449800:
 vdpa-dev: Fix the issue of device status not updating when configuration 
interruption is triggered
b57b102a81 2d9a31b3c2 Wafer:
 hw/virtio: Fix packed virtqueue flush used_idx
f7a1ff69ba 19b254e86a Peter Maydell:
 target/arm: Use correct SecuritySpace for AArch64 AT ops at EL3
6983d1657d 7afbdada7e Wei Wang:
 migration/postcopy: ensure preempt channel is ready before loading states
46f03be3ed bbdf902366 Zheyu Ma:
 block/virtio-blk: Fix memory leak from virtio_blk_zone_report
9c2b8194ac 4c54f5bc8e Yajun Wu:
 hw/net/virtio-net: fix qemu set used ring flag even vhost started
e961fa43e9 fbe5ac5671 Peter Maydell:
 target/arm: take HSTR traps of cp15 accesses to EL2, not EL1
2702763548 44e25fbc19 Peter Maydell:
 hw/intc/arm_gicv3: ICC_HPPIR* return SPURIOUS if int group is disabled
2befb8a9c7 1d2f2b35bc Michael Tokarev:
 gitlab-ci/cirrus: switch from 'master' to 'latest'
3168476965 d0ad271a76 Avihai Horon:
 migration/postcopy: Ensure postcopy_start() sets errp if it fails
35fface50f 4a3aa11e1f Richard Henderson:
 target/hppa: Clear psw_n for BE on use_nullify_skip path
3cdfd68e4e 2911e9b95f Richard Henderson:
 tcg/optimize

[ANNOUNCE] QEMU 7.2.11 Stable released

2024-04-24 Thread Michael Tokarev
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Hi everyone,

The QEMU v7.2.11 stable release is now available.

You can grab the tarball from our download page here:

  https://www.qemu.org/download/#source

  https://download.qemu.org/qemu-7.2.11.tar.xz
  https://download.qemu.org/qemu-7.2.11.tar.xz.sig (signature)

v7.2.11 is now tagged in the official qemu.git repository, and the
stable-7.2 branch has been updated accordingly:

  https://gitlab.com/qemu-project/qemu/-/commits/stable-7.2

There are 59 changes since the previous v7.2.10 release.

Thank you everyone who has been involved and helped with the stable series!

/mjt

Changelog (stable-7.2-hash master-hash Author Name: Commmit-Subject):

c6fe0f315c Michael Tokarev:
 Update version for 7.2.11 release
ab4a60c1b7 c4f91d7b7b Harsh Prateek Bora:
 ppc/spapr: Initialize max_cpus limit to SPAPR_IRQ_NR_IPIS.
3f481e3305 2df5c1f5b0 Harsh Prateek Bora:
 ppc/spapr: Introduce SPAPR_IRQ_NR_IPIS to refer IRQ range for CPU IPIs.
4741ae6b8e b754cb2dcd Zack Buhman:
 target/sh4: add missing CHECK_NOT_DELAY_SLOT
2429cb7a9f 9e4b27ca6b Philippe Mathieu-Daudé:
 hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set
f3130798d4 a45223467e Philippe Mathieu-Daudé:
 hw/net/lan9118: Replace magic '2048' value by MIL_TXFIFO_SIZE definition
cd7beea4a4 ad766d603f Philippe Mathieu-Daudé:
 hw/net/lan9118: Fix overflow in MIL TX FIFO
734314d8ce eaf2bd2953 Philippe Mathieu-Daudé:
 backends/cryptodev: Do not abort for invalid session ID
9b7bc39890 fc09ff2979 Philippe Mathieu-Daudé:
 hw/misc/applesmc: Fix memory leak in reset() handler
8394be7faa d39fdfff34 Philippe Mathieu-Daudé:
 hw/block/nand: Fix out-of-bound access in NAND block buffer
9ca7801c6a 2e3e09b368 Philippe Mathieu-Daudé:
 hw/block/nand: Have blk_load() take unsigned offset and return boolean
caeb4489b7 7a86544f28 Philippe Mathieu-Daudé:
 hw/block/nand: Factor nand_load_iolen() method out
d5c41e4491 aa88f99c87 Yuquan Wang:
 qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo
7aaf5f7778 f4729ec39a Philippe Mathieu-Daudé:
 hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs
e7c2df3fd7 b4295bff25 Philippe Mathieu-Daudé:
 hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs
6d37a30815 ba28e0ff4d Philippe Mathieu-Daudé:
 hw/display/virtio-gpu: Protect from DMA re-entrancy bugs
e070e5e674 ec0504b989 Philippe Mathieu-Daudé:
 hw/virtio: Introduce virtio_bh_new_guarded() helper
d6e7ec1f8e f0907ff4ca Richard Henderson:
 linux-user: Fix waitid return of siginfo_t and rusage
b198998b7f e25fe886b8 Richard Henderson:
 tcg/optimize: Do not attempt to constant fold neg_vec
fd01f5a847 2d9a31b3c2 Wafer:
 hw/virtio: Fix packed virtqueue flush used_idx
227d9450b5 4c54f5bc8e Yajun Wu:
 hw/net/virtio-net: fix qemu set used ring flag even vhost started
393b7ab067 44e25fbc19 Peter Maydell:
 hw/intc/arm_gicv3: ICC_HPPIR* return SPURIOUS if int group is disabled
eebb7fb506 1d2f2b35bc Michael Tokarev:
 gitlab-ci/cirrus: switch from 'master' to 'latest'
6fca92c9d1 4a3aa11e1f Richard Henderson:
 target/hppa: Clear psw_n for BE on use_nullify_skip path
162c54b7c1 2911e9b95f Richard Henderson:
 tcg/optimize: Fix sign_mask for logical right-shift
493b1cc785 1c188fc8cb Akihiko Odaki:
 virtio-net: Fix vhost virtqueue notifiers for RSS
70b0e142e6 a158c63b3b Yao Xingtao:
 monitor/hmp-cmds-target: Append a space in error message in gpa2hva()
2e1645ac6a 7c7a9f578e Lorenz Brun:
 hw/scsi/scsi-generic: Fix io_timeout property not applying
610db167da 1590154ee4 Song Gao:
 target/loongarch: Fix qemu-system-loongarch64 assert failed with the option 
'-d int'
e9e41446c2 7fd226b047 Tao Su:
 target/i386: Revert monitor_puts() in do_inject_x86_mce()
a6fc9a234b 2cc68629a6 Paolo Bonzini:
 target/i386: fix direction of "32-bit MMU" test
ad003650d5 90f641531c Paolo Bonzini:
 target/i386: use separate MMU indexes for 32-bit accesses
6332f3c12f 5f97afe254 Paolo Bonzini:
 target/i386: introduce function to query MMU indices
e4b23890b3 55f7c6a5f2 Peter Maydell:
 tests: Raise timeouts for bufferiszero and crypto-tlscredsx509
9405029750 63b18312d1 Kevin Wolf:
 tests/unit: Bump test-replication timeout to 60 seconds
4f048b771d e1b363e328 Thomas Huth:
 tests/unit: Bump test-crypto-block test timeout to 5 minutes
dcb9a64d22 c45f8f1aef Thomas Huth:
 tests/unit: Bump test-aio-multithread test timeout to 2 minutes
e1e9d74f57 2e128776dc Cédric Le Goater:
 migration: Skip only empty block devices
04b3d34d5c 74e2845c5f Jonathan Cameron:
 hmat acpi: Fix out of bounds access due to missing use of indirection
309051ac40 6081b4243c Akihiko Odaki:
 pcie_sriov: Validate NumVFs
3f7892be24 91bb64a8d2 Akihiko Odaki:
 hw/nvme: Use pcie_sriov_num_vfs()
e00b062da7 31180dbdca Akihiko Odaki:
 pcie: Introduce pcie_sriov_num_vfs
0b7ccfd1d2 fa905f65c5 Klaus Jensen:
 hw/nvme: add machine compatibility parameter to enable msix exclusive bar
6a5d6849d1 ee7bda4d38 Klaus Jensen:
 hw/nvme: generalize the mbar size helper
424e6209e5 4f0a4a3d58 Minw

Re: [PATCH] Fix incorrect disassembly format for certain RISC-V instructions

2024-04-24 Thread Michael Tokarev

03.04.2024 12:14, Simeon Krastnikov wrote:

* The immediate argument to lui/auipc should be an integer in the interval
  [0x0, 0xf]; e.g., 'auipc 0xf' and not 'auipc -1'
* The floating-point rounding mode is the last operand to the function,
   not the first; e.g., 'fcvt.w.s a0, fa0, rtz' and not 'fcvt.w.s rtz,
a0, fa0'. Note that fcvt.d.w[u] and fcvt.w[u].d are unaffected by the
rounding mode and hence it is omitted from their disassembly.
* When aq and rl are both present, they are not separated by a '.';
   e.g., 'lr.d.aqrl' and not 'lr.d.aq.rl'.

Based on the following assembly reference:
https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md


Can someone from the riscv team review this?

This change isn't "trivial enough" for qemu-trivial, it should be picked up
by the riscv team.  At the very least, it touches too many instructions.

Thanks,

/mjt




Re: [PATCH] backends/cryptodev-builtin: Fix local_error leaks

2024-04-24 Thread Michael Tokarev

22.04.2024 11:53, Li Zhijian via wrote:

It seems that this error does not need to be propagated to the upper,
directly output the error to avoid the leaks

Closes: https://gitlab.com/qemu-project/qemu/-/issues/2283
Signed-off-by: Li Zhijian 


Applied to trivial-patches tree, with s/Closes/Resolves/ and
with addition of "Fixes:" suggested by zhenwei pi.

Thanks,

/mjt



[PATCH 25/27] qemu-img: implement short --help, remove global help() function

2024-04-24 Thread Michael Tokarev
now once all individual subcommands has --help support, remove
the large unreadable help() thing and replace it with small
global --help, which refers to individual command --help for
more info.

While at it, also line-wrap list of formats after 75 chars.

Since missing_argument() and unrecognized_option() are now unused,
remove them.

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 172 -
 1 file changed, 39 insertions(+), 133 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 3721cf070b..39dfaa5144 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -94,11 +94,6 @@ typedef enum OutputFormat {
 /* Default to cache=writeback as data integrity is not important for qemu-img 
*/
 #define BDRV_DEFAULT_CACHE "writeback"
 
-static void format_print(void *opaque, const char *name)
-{
-printf(" %s", name);
-}
-
 static G_NORETURN
 void tryhelp(const char *argv0)
 {
@@ -118,18 +113,6 @@ void error_exit(const char *argv0, const char *fmt, ...)
 tryhelp(argv0);
 }
 
-static G_NORETURN
-void missing_argument(const char *option)
-{
-error_exit("qemu-img", "missing argument for option '%s'", option);
-}
-
-static G_NORETURN
-void unrecognized_option(const char *option)
-{
-error_exit("qemu-img", "unrecognized option '%s'", option);
-}
-
 /*
  * Print --help output for a command and exit.
  * syntax and description are multi-line with trailing EOL
@@ -167,114 +150,6 @@ static OutputFormat parse_output_format(const char 
*argv0, const char *arg)
 }
 }
 
-/* Please keep in synch with docs/tools/qemu-img.rst */
-static G_NORETURN
-void help(void)
-{
-const char *help_msg =
-   QEMU_IMG_VERSION
-   "usage: qemu-img [standard options] command [command options]\n"
-   "QEMU disk image utility\n"
-   "\n"
-   "'-h', '--help'   display this help and exit\n"
-   "'-V', '--version'output version information and exit\n"
-   "'-T', '--trace'  
[[enable=]][,events=][,file=]\n"
-   " specify tracing options\n"
-   "\n"
-   "Command syntax:\n"
-#define DEF(option, callback, arg_string)\
-   "  " arg_string "\n"
-#include "qemu-img-cmds.h"
-#undef DEF
-   "\n"
-   "Command parameters:\n"
-   "  'filename' is a disk image filename\n"
-   "  'objectdef' is a QEMU user creatable object definition. See the 
qemu(1)\n"
-   "manual page for a description of the object properties. The 
most common\n"
-   "object type is a 'secret', which is used to supply passwords 
and/or\n"
-   "encryption keys.\n"
-   "  'fmt' is the disk image format. It is guessed automatically in 
most cases\n"
-   "  'cache' is the cache mode used to write the output disk image, 
the valid\n"
-   "options are: 'none', 'writeback' (default, except for 
convert), 'writethrough',\n"
-   "'directsync' and 'unsafe' (default for convert)\n"
-   "  'src_cache' is the cache mode used to read input disk images, 
the valid\n"
-   "options are the same as for the 'cache' option\n"
-   "  'size' is the disk image size in bytes. Optional suffixes\n"
-   "'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' 
(gigabyte, 1024M),\n"
-   "'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 
1024P)  are\n"
-   "supported. 'b' is ignored.\n"
-   "  'output_filename' is the destination disk image filename\n"
-   "  'output_fmt' is the destination format\n"
-   "  'options' is a comma separated list of format specific options 
in a\n"
-   "name=value format. Use -o help for an overview of the options 
supported by\n"
-   "the used format\n"
-   "  'snapshot_param' is param used for internal snapshot, format\n"
-   "is 'snapshot.id=[ID],snapshot.name=[NAME]', or\n"
-   "'[ID_OR_NAME]'\n"
-   "  '-c' indicates that target image must be compressed (qcow format 
only)\n"
-   "  '-u' allows unsafe backing chains. For rebasing, it is assumed 
that old and\n"
-   "   new backing file match exactly. The image doesn't need a 
working\n"
-   "   backing file before rebasing in this case (useful for 
renaming the\n"
-   "   backing file). For image creation, allow creating w

[PATCH 23/27] qemu-img: dd: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 39 +--
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 7c20a5772d..b3e521bc09 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -5504,31 +5504,48 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char 
**argv)
 const struct option long_options[] = {
 { "help", no_argument, 0, 'h'},
 { "object", required_argument, 0, OPTION_OBJECT},
+{ "format", required_argument, 0, 'f'},
+{ "output-format", required_argument, 0, 'O'},
 { "image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 { "force-share", no_argument, 0, 'U'},
 { 0, 0, 0, 0 }
 };
 
-while ((c = getopt_long(argc, argv, ":hf:O:U", long_options, NULL))) {
+while ((c = getopt_long(argc, argv, "hf:O:U", long_options, NULL))) {
 if (c == EOF) {
 break;
 }
 switch (c) {
+case 'h':
+cmd_help(ccmd,
+"[-f FMT|--image-opts] [-O OUTPUT_FMT] [-U]\n"
+"[bs=BLOCK_SIZE] [count=BLOCKS] if=INPUT of=OUTPUT\n"
+,
+"  -f, --format FMT\n"
+" specify format for INPUT explicitly\n"
+"  --image-opts\n"
+" indicates that INPUT is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  -O, --output-format OUTPUT_FMT\n"
+" format of the OUTPUT (default raw)\n"
+"  -U, --force-share\n"
+" open images in shared mode for concurrent access\n"
+"  bs=BLOCK_SIZE[kKMGTP]\n"
+" size of I/O block (default 512)\n"
+"  count=COUNT\n"
+" number of blocks to convert (default whole INPUT)\n"
+"  if=INPUT\n"
+" input file name (or image specification with --image-opts)\n"
+"  of=OUTPUT\n"
+" output file name to create\n"
+);
+break;
 case 'O':
 out_fmt = optarg;
 break;
 case 'f':
 fmt = optarg;
 break;
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
-case 'h':
-help();
-break;
 case 'U':
 force_share = true;
 break;
@@ -5538,6 +,8 @@ static int img_dd(const img_cmd_t *ccmd, int argc, char 
**argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 27/27] qemu-img: extend cvtnum() and use it in more places

2024-04-24 Thread Michael Tokarev
cvtnum() expects input string to specify some sort of size
(optionally with KMG... suffix).  However, there are a lot
of other number conversions in there (using qemu_strtol ),
also, not all conversions which use cvtnum, actually expects
size, - like dd count=nn.

Add bool issize argument to cvtnum() to specify if it should
treat the argument as a size or something else, - this changes
conversion routine in use and error text.

Use the new cvtnum() in more places (like where strtol were used),
since it never return negative number in successful conversion.
When it makes sense, also specify upper or lower bounds at the
same time.  This simplifies option processing in multiple places,
removing the need of local temporary variables and longer error
reporting code.

While at it, fix errors, like depth in measure must be >= 1,
while the previous code allowed it to be 0.

In a few places, change unsigned variables (like of type size_t)
to be signed instead, - to avoid the need of temporary conversion
variable.  All these variables are okay to be signed, we never
assign <0 value to them except of the cases of conversion error,
where we return immediately.

While at it, remove allowed size suffixes from the error message
as it makes no sense most of the time (should be in help instead).

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 111 +
 tests/qemu-iotests/049.out |   9 +--
 2 files changed, 40 insertions(+), 80 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 694647f6ff..dbbf3495e8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -399,18 +399,16 @@ static int add_old_style_options(const char *fmt, 
QemuOpts *opts,
 return 0;
 }
 
-static int64_t cvtnum_full(const char *name, const char *value, int64_t min,
-   int64_t max)
+static int64_t cvtnum_full(const char *name, const char *value,
+   bool issize, int64_t min, int64_t max)
 {
 int err;
 uint64_t res;
 
-err = qemu_strtosz(value, NULL, );
+err = issize ? qemu_strtosz(value, NULL, ) :
+   qemu_strtou64(value, NULL, 0, );
 if (err < 0 && err != -ERANGE) {
-error_report("Invalid %s specified. You may use "
- "k, M, G, T, P or E suffixes for", name);
-error_report("kilobytes, megabytes, gigabytes, terabytes, "
- "petabytes and exabytes.");
+error_report("Invalid %s specified: '%s'.", name, value);
 return err;
 }
 if (err == -ERANGE || res > max || res < min) {
@@ -421,9 +419,9 @@ static int64_t cvtnum_full(const char *name, const char 
*value, int64_t min,
 return res;
 }
 
-static int64_t cvtnum(const char *name, const char *value)
+static int64_t cvtnum(const char *name, const char *value, bool issize)
 {
-return cvtnum_full(name, value, 0, INT64_MAX);
+return cvtnum_full(name, value, issize, 0, INT64_MAX);
 }
 
 static int img_create(const img_cmd_t *ccmd, int argc, char **argv)
@@ -527,7 +525,7 @@ static int img_create(const img_cmd_t *ccmd, int argc, char 
**argv)
 
 /* Get image size, if specified */
 if (optind < argc) {
-img_size = cvtnum("image size", argv[optind++]);
+img_size = cvtnum("image size", argv[optind++], true);
 if (img_size < 0) {
 goto fail;
 }
@@ -989,7 +987,7 @@ static int img_commit(const img_cmd_t *ccmd, int argc, char 
**argv)
 quiet = true;
 break;
 case 'r':
-rate_limit = cvtnum("rate limit", optarg);
+rate_limit = cvtnum("rate limit", optarg, true);
 if (rate_limit < 0) {
 return 1;
 }
@@ -2414,7 +2412,7 @@ static int img_convert(const img_cmd_t *ccmd, int argc, 
char **argv)
 {
 int64_t sval;
 
-sval = cvtnum("buffer size for sparse output", optarg);
+sval = cvtnum("buffer size for sparse output", optarg, true);
 if (sval < 0) {
 goto fail_getopt;
 } else if (!QEMU_IS_ALIGNED(sval, BDRV_SECTOR_SIZE) ||
@@ -2446,10 +2444,9 @@ static int img_convert(const img_cmd_t *ccmd, int argc, 
char **argv)
 skip_create = true;
 break;
 case 'm':
-if (qemu_strtol(optarg, NULL, 0, _coroutines) ||
-s.num_coroutines < 1 || s.num_coroutines > MAX_COROUTINES) {
-error_report("Invalid number of coroutines. Allowed number of"
- " coroutines is between 1 and %d", 
MAX_COROUTINES);
+s.num_coroutines = cvtnum_full("number of coroutines", optarg,
+   false, 1, MAX_COROUTINES);
+if (s.num_coroutines < 0) {
  

[PATCH 24/27] qemu-img: measure: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Also add -s short option for --size (and remove OPTION_SIZE).

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 53 -
 1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index b3e521bc09..3721cf070b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -71,7 +71,6 @@ enum {
 OPTION_FLUSH_INTERVAL = 261,
 OPTION_NO_DRAIN = 262,
 OPTION_TARGET_IMAGE_OPTS = 263,
-OPTION_SIZE = 264,
 OPTION_PREALLOCATION = 265,
 OPTION_SHRINK = 266,
 OPTION_SALVAGE = 267,
@@ -5748,15 +5747,6 @@ static void 
dump_json_block_measure_info(BlockMeasureInfo *info)
 
 static int img_measure(const img_cmd_t *ccmd, int argc, char **argv)
 {
-static const struct option long_options[] = {
-{"help", no_argument, 0, 'h'},
-{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
-{"object", required_argument, 0, OPTION_OBJECT},
-{"output", required_argument, 0, OPTION_OUTPUT},
-{"size", required_argument, 0, OPTION_SIZE},
-{"force-share", no_argument, 0, 'U'},
-{0, 0, 0, 0}
-};
 OutputFormat output_format = OFORMAT_HUMAN;
 BlockBackend *in_blk = NULL;
 BlockDriver *drv;
@@ -5777,12 +5767,47 @@ static int img_measure(const img_cmd_t *ccmd, int argc, 
char **argv)
 int ret = 1;
 int c;
 
+static const struct option long_options[] = {
+{"help", no_argument, 0, 'h'},
+{"target-format", required_argument, 0, 'O'},
+{"format", required_argument, 0, 'f'},
+{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"options", required_argument, 0, 'o'},
+{"snapshot", required_argument, 0, 'l'},
+{"object", required_argument, 0, OPTION_OBJECT},
+{"output", required_argument, 0, OPTION_OUTPUT},
+{"size", required_argument, 0, 's'},
+{"force-share", no_argument, 0, 'U'},
+{0, 0, 0, 0}
+};
+
 while ((c = getopt_long(argc, argv, "hf:O:o:l:U",
 long_options, NULL)) != -1) {
 switch (c) {
-case '?':
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT|--image-opts] [-o OPTIONS] [-O OUTPUT_FMT]\n"
+"   [--output OFMT] [--object OBJDEF] [-l SNAPSHOT_PARAM]\n"
+"   (--size SIZE | FILENAME)\n"
+,
+"  -O, --target-format FMT\n"
+" desired target/output image format (default raw)\n"
+"  -s, --size SIZE\n"
+" measure file size for given image size\n"
+"  FILENAME\n"
+" measure file size required to convert from FILENAME\n"
+"  -f, --format\n"
+" specify format of FILENAME explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  -l, --snapshot SNAPSHOT\n"
+" use this snapshot in FILENAME as source\n"
+"  --output human|json\n"
+" output format\n"
+"  -U, --force-share\n"
+" open images in shared mode for concurrent access\n"
+);
 break;
 case 'f':
 fmt = optarg;
@@ -5820,12 +5845,14 @@ static int img_measure(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_OUTPUT:
 output_format = parse_output_format(argv[0], optarg);
 break;
-case OPTION_SIZE:
+case 's':
 img_size = cvtnum("image size", optarg);
 if (img_size < 0) {
 goto out;
 }
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 26/27] qemu-img: inline list of supported commands, remove qemu-img-cmds.h include

2024-04-24 Thread Michael Tokarev
also add short description to each command and use it in --help

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 40 ++--
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 39dfaa5144..694647f6ff 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -61,6 +61,7 @@
 typedef struct img_cmd_t {
 const char *name;
 int (*handler)(const struct img_cmd_t *ccmd, int argc, char **argv);
+const char *description;
 } img_cmd_t;
 
 enum {
@@ -127,6 +128,7 @@ void cmd_help(const img_cmd_t *ccmd,
 {
 printf(
 "Usage:\n"
+"%s.  Usage:\n"
 "\n"
 "  %s %s %s"
 "\n"
@@ -134,7 +136,7 @@ void cmd_help(const img_cmd_t *ccmd,
 "  -h, --help\n"
 " print this help and exit\n"
 "%s\n",
-   "qemu-img", ccmd->name,
+   ccmd->description, "qemu-img", ccmd->name,
syntax, arguments);
 exit(EXIT_SUCCESS);
 }
@@ -5828,10 +5830,36 @@ out:
 }
 
 static const img_cmd_t img_cmds[] = {
-#define DEF(option, callback, arg_string)\
-{ option, callback },
-#include "qemu-img-cmds.h"
-#undef DEF
+{ "amend", img_amend,
+  "Update format-specific options of the image" },
+{ "bench", img_bench,
+  "Run simple image benchmark" },
+{ "bitmap", img_bitmap,
+  "Perform modifications of the persistent bitmap in the image" },
+{ "check", img_check,
+  "Check basic image integrity" },
+{ "commit", img_commit,
+  "Commit image to its backing file" },
+{ "compare", img_compare,
+  "Check if two images have the same contents" },
+{ "convert", img_convert,
+  "Copy one image to another with optional format conversion" },
+{ "create", img_create,
+  "Create and format new image file" },
+{ "dd", img_dd,
+  "Copy input to output with optional format conversion" },
+{ "info", img_info,
+  "Display information about image" },
+{ "map", img_map,
+  "Dump image metadata" },
+{ "measure", img_measure,
+  "Calculate file size requred for a new image" },
+{ "rebase", img_rebase,
+  "Change backing file of the image" },
+{ "resize", img_resize,
+  "Resize the image to the new size" },
+{ "snapshot", img_snapshot,
+  "List or manipulate snapshots within image" },
 { NULL, NULL, },
 };
 
@@ -5896,7 +5924,7 @@ QEMU_IMG_VERSION
 "\n"
 "Recognized commands (run qemu-img COMMAND --help for command-specific 
help):\n\n");
 for (cmd = img_cmds; cmd->name != NULL; cmd++) {
-printf("  %s\n", cmd->name);
+printf("  %s - %s\n", cmd->name, cmd->description);
 }
 printf("\nSupported image formats:\n");
 c = 99; /* force a newline */
-- 
2.39.2




[PATCH 01/27] qemu-img: measure: convert img_size to signed, simplify handling

2024-04-24 Thread Michael Tokarev
qemu_opt_set_number() expects signed int64_t.

Use int64_t instead of uint64_t for img_size, use -1 as "unset"
value instead of UINT64_MAX, and do not require temporary sval
for conversion from string.

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 7668f86769..6e7ac2048f 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -5364,7 +5364,7 @@ static int img_measure(int argc, char **argv)
 QemuOpts *sn_opts = NULL;
 QemuOptsList *create_opts = NULL;
 bool image_opts = false;
-uint64_t img_size = UINT64_MAX;
+int64_t img_size = -1;
 BlockMeasureInfo *info = NULL;
 Error *local_err = NULL;
 int ret = 1;
@@ -5422,16 +5422,11 @@ static int img_measure(int argc, char **argv)
 }
 break;
 case OPTION_SIZE:
-{
-int64_t sval;
-
-sval = cvtnum("image size", optarg);
-if (sval < 0) {
+img_size = cvtnum("image size", optarg);
+if (img_size < 0) {
 goto out;
 }
-img_size = (uint64_t)sval;
-}
-break;
+break;
 }
 }
 
@@ -5446,11 +5441,11 @@ static int img_measure(int argc, char **argv)
 error_report("--image-opts, -f, and -l require a filename argument.");
 goto out;
 }
-if (filename && img_size != UINT64_MAX) {
+if (filename && img_size != -1) {
 error_report("--size N cannot be used together with a filename.");
 goto out;
 }
-if (!filename && img_size == UINT64_MAX) {
+if (!filename && img_size == -1) {
 error_report("Either --size N or one filename must be specified.");
 goto out;
 }
@@ -5498,7 +5493,7 @@ static int img_measure(int argc, char **argv)
 goto out;
 }
 }
-if (img_size != UINT64_MAX) {
+if (img_size != -1) {
 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size, _abort);
 }
 
-- 
2.39.2




[PATCH 17/27] qemu-img: rebase: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Options added:
 --format, --cache - for the image in question
 --backing, --backing-format, --backing-cache, --backing-unsafe -
   for the new backing file
(was eg CACHE vs SRC_CACHE, which is unclear).

Probably should rename local variables.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 55 +-
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 62f9ce4069..47dfa137c1 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3793,26 +3793,61 @@ static int img_rebase(const img_cmd_t *ccmd, int argc, 
char **argv)
 for(;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
+{"progress", no_argument, 0, 'p'},
 {"object", required_argument, 0, OPTION_OBJECT},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 {"force-share", no_argument, 0, 'U'},
+{"format", required_argument, 0, 'f'},
+{"cache", required_argument, 0, 't'},
 {"compress", no_argument, 0, 'c'},
+{"backing", required_argument, 0, 'b'},
+{"backing-format", required_argument, 0, 'F'},
+{"backing-cache", required_argument, 0, 'T'},
+{"backing-unsafe", no_argument, 0, 'u'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":hf:F:b:upt:T:qUc",
+c = getopt_long(argc, argv, "hf:F:b:upt:T:qUc",
 long_options, NULL);
 if (c == -1) {
 break;
 }
-switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
+switch (c) {
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [-t CACHE] [-q] [-U] [-p]\n"
+"[-b BACKING_FILENAME [-F BACKING_FMT] [-T BACKING_CACHE]] [-u]\n"
+"[--object OBJDEF] [-c] FILENAME\n"
+"Rebases FILENAME on top of BACKING_FILENAME or no backing file\n"
+,
+"  -q, --quiet\n"
+" quiet operation\n"
+"  -p, --progress\n"
+" show progress indicator\n"
+"  -f, --format FMT\n"
+" specify FILENAME format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  -t, --cache CACHE\n"
+" cache mode for FILENAME (" BDRV_DEFAULT_CACHE ")\n"
+"  -b, --backing BACKING_FILENAME|\"\"\n"
+" rebase onto this file (or no backing file)\n"
+"  -F, --backing-format BACKING_FMT\n"
+" specify format for BACKING_FILENAME\n"
+"  -T, --backing-cache CACHE\n"
+" BACKING_FILENAME cache mode (" BDRV_DEFAULT_CACHE ")\n"
+"  -u, --backing-unsafe\n"
+" do not fail if BACKING_FILENAME can not be read\n"
+"  -c, --compress\n"
+" compress image (when image supports this)\n"
+"  -U, --force-share\n"
+" open image in shared mode for concurrent access\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  FILENAME\n"
+" image file name (or specification with --image-opts)\n"
+);
 return 0;
 case 'f':
 fmt = optarg;
@@ -3850,6 +3885,8 @@ static int img_rebase(const img_cmd_t *ccmd, int argc, 
char **argv)
 case 'c':
 compress = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 12/27] qemu-img: info: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.
Also add -b short option for --backing-chain, and remove
now-unused OPTION_BACKING_CHAIN.

While at it, remove unused option_index variable.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 40 +++-
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 0a32d890e3..34c4cd86de 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -65,7 +65,6 @@ typedef struct img_cmd_t {
 
 enum {
 OPTION_OUTPUT = 256,
-OPTION_BACKING_CHAIN = 257,
 OPTION_OBJECT = 258,
 OPTION_IMAGE_OPTS = 259,
 OPTION_PATTERN = 260,
@@ -3220,31 +3219,44 @@ static int img_info(const img_cmd_t *ccmd, int argc, 
char **argv)
 
 fmt = NULL;
 for(;;) {
-int option_index = 0;
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
 {"format", required_argument, 0, 'f'},
 {"output", required_argument, 0, OPTION_OUTPUT},
-{"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
+{"backing-chain", no_argument, 0, 'b'},
 {"object", required_argument, 0, OPTION_OBJECT},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 {"force-share", no_argument, 0, 'U'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":f:hU",
-long_options, _index);
+c = getopt_long(argc, argv, "f:hbU",
+long_options, NULL);
 if (c == -1) {
 break;
 }
 switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [-b] [-U] [--object OBJDEF]\n"
+"[--output human|json] FILENAME\n"
+,
+"  -f, --format FMT\n"
+" specify FILENAME image format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  -b, --backing-chain\n"
+" display information about backing chaing\n"
+"  (in case the image is stacked\n"
+"  -U, --force-share\n"
+" open image in shared mode for concurrent access\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  --output human|json\n"
+" specify output format name (default human)\n"
+"  FILENAME\n"
+" image file name (or specification with --image-opts)\n"
+);
 break;
 case 'f':
 fmt = optarg;
@@ -3255,7 +3267,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, char 
**argv)
 case OPTION_OUTPUT:
 output_format = parse_output_format(argv[0], optarg);
 break;
-case OPTION_BACKING_CHAIN:
+case 'b':
 chain = true;
 break;
 case OPTION_OBJECT:
@@ -3264,6 +3276,8 @@ static int img_info(const img_cmd_t *ccmd, int argc, char 
**argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 if (optind != argc - 1) {
-- 
2.39.2




[PATCH 19/27] qemu-img: resize: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 38 +-
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index da10fafffc..688c01722c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4324,27 +4324,45 @@ static int img_resize(const img_cmd_t *ccmd, int argc, 
char **argv)
 for(;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
 {"object", required_argument, 0, OPTION_OBJECT},
+{"format", required_argument, 0, 'f'},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 {"preallocation", required_argument, 0, OPTION_PREALLOCATION},
 {"shrink", no_argument, 0, OPTION_SHRINK},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, "-:f:hq",
+c = getopt_long(argc, argv, "-f:hq",
 long_options, NULL);
 if (c == -1) {
 break;
 }
 switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
-break;
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [--preallocation PREALLOC] [--shrink]\n"
+"[--object OBJECTDEF] [-q] FILENAME [+-]SIZE[bkKMGTPE]\n"
+,
+"  -q, --quiet\n"
+" quiet operation\n"
+"  -f, --format FMT\n"
+" specify FILENAME format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+"   instead of a file name (incompatible with --format)\n"
+"  --shrink\n"
+" allow operation when new size is smaller than original\n"
+"  --preallocation PREALLOC\n"
+" specify preallocation type for the new areas\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  FILENAME\n"
+" image file (specification) to resize\n"
+"  [+-]SIZE[bkKMGTPE]\n"
+" new image size or amount by which to shrink/grow,\n"
+" with optional suffix (1024-based multiplies)\n"
+);
+return 0;
 case 'f':
 fmt = optarg;
 break;
@@ -4386,6 +4404,8 @@ static int img_resize(const img_cmd_t *ccmd, int argc, 
char **argv)
 error_exit(argv[0], "Extra argument(s) in command line");
 }
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 if (!filename && optind < argc) {
-- 
2.39.2




[PATCH 14/27] qemu-img: snapshot: allow specifying -f fmt

2024-04-24 Thread Michael Tokarev
For consistency with other commands, and since it already
accepts --image-opts, allow specifying -f fmt too.

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 docs/tools/qemu-img.rst | 2 +-
 qemu-img-cmds.hx| 4 ++--
 qemu-img.c  | 9 ++---
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
index 3653adb963..9b628c4da5 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -663,7 +663,7 @@ Command description:
   bitmap support, or 0 if bitmaps are supported but there is nothing
   to copy.
 
-.. option:: snapshot [--object OBJECTDEF] [--image-opts] [-U] [-q] [-l | -a 
SNAPSHOT | -c SNAPSHOT | -d SNAPSHOT] FILENAME
+.. option:: snapshot [--object OBJECTDEF] [-f FMT | --image-opts] [-U] [-q] 
[-l | -a SNAPSHOT | -c SNAPSHOT | -d SNAPSHOT] FILENAME
 
   List, apply, create or delete snapshots in image *FILENAME*.
 
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index c9dd70a892..2c5a8a28f9 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -84,9 +84,9 @@ SRST
 ERST
 
 DEF("snapshot", img_snapshot,
-"snapshot [--object objectdef] [--image-opts] [-U] [-q] [-l | -a snapshot 
| -c snapshot | -d snapshot] filename")
+"snapshot [--object objectdef] [-f fmt | --image-opts] [-U] [-q] [-l | -a 
snapshot | -c snapshot | -d snapshot] filename")
 SRST
-.. option:: snapshot [--object OBJECTDEF] [--image-opts] [-U] [-q] [-l | -a 
SNAPSHOT | -c SNAPSHOT | -d SNAPSHOT] FILENAME
+.. option:: snapshot [--object OBJECTDEF] [-f FMT | --image-opts] [-U] [-q] 
[-l | -a SNAPSHOT | -c SNAPSHOT | -d SNAPSHOT] FILENAME
 ERST
 
 DEF("rebase", img_rebase,
diff --git a/qemu-img.c b/qemu-img.c
index 84e2e53fb7..8adc324496 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3595,7 +3595,7 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 BlockBackend *blk;
 BlockDriverState *bs;
 QEMUSnapshotInfo sn;
-char *filename, *snapshot_name = NULL;
+char *filename, *fmt = NULL, *snapshot_name = NULL;
 int c, ret = 0, bdrv_oflags;
 int action = 0;
 bool quiet = false;
@@ -3614,7 +3614,7 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 {"force-share", no_argument, 0, 'U'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":la:c:d:hqU",
+c = getopt_long(argc, argv, ":la:c:d:f:hqU",
 long_options, NULL);
 if (c == -1) {
 break;
@@ -3629,6 +3629,9 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 case 'h':
 help();
 return 0;
+case 'f':
+fmt = optarg;
+break;
 case 'l':
 if (action) {
 error_exit(argv[0], "Cannot mix '-l', '-a', '-c', '-d'");
@@ -3682,7 +3685,7 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 filename = argv[optind++];
 
 /* Open the image */
-blk = img_open(image_opts, filename, NULL, bdrv_oflags, false, quiet,
+blk = img_open(image_opts, filename, fmt, bdrv_oflags, false, quiet,
force_share);
 if (!blk) {
 return 1;
-- 
2.39.2




[PATCH 21/27] qemu-img: bench: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 64 +-
 1 file changed, 54 insertions(+), 10 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 76000c485c..fff537df26 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4849,28 +4849,70 @@ static int img_bench(const img_cmd_t *ccmd, int argc, 
char **argv)
 for (;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
-{"flush-interval", required_argument, 0, OPTION_FLUSH_INTERVAL},
+{"format", required_argument, 0, 'f'},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"cache", required_argument, 0, 't'},
+{"count", required_argument, 0, 'c'},
+{"depth", required_argument, 0, 'd'},
+{"offset", required_argument, 0, 'o'},
+{"buffer-size", required_argument, 0, 's'},
+{"step-size", required_argument, 0, 'S'},
+{"aio", required_argument, 0, 'i'},
+{"native", no_argument, 0, 'n'},
+{"write", no_argument, 0, 'w'},
 {"pattern", required_argument, 0, OPTION_PATTERN},
+{"flush-interval", required_argument, 0, OPTION_FLUSH_INTERVAL},
 {"no-drain", no_argument, 0, OPTION_NO_DRAIN},
 {"force-share", no_argument, 0, 'U'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":hc:d:f:ni:o:qs:S:t:wU", long_options,
-NULL);
+c = getopt_long(argc, argv, "hc:d:f:ni:o:qs:S:t:wU",
+long_options, NULL);
 if (c == -1) {
 break;
 }
 
 switch (c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [-t CACHE] [-c COUNT] [-d DEPTH]\n"
+"[-o OFFSET] [-s BUFFER_SIZE] [-S STEP_SIZE] [-i AIO] [-n]\n"
+"[-w [--pattern PATTERN] [--flush-interval INTERVAL [--no-drain]]]\n"
+,
+"  -q, --quiet\n"
+" quiet operations\n"
+"  -f, --format FMT\n"
+" specify FILENAME format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  -t, --cache CACHE\n"
+" cache mode for FILENAME (" BDRV_DEFAULT_CACHE ")\n"
+"  -c, --count COUNT\n"
+" number of I/O requests to perform\n"
+"  -s, --buffer-size BUFFER_SIZE\n"
+" size of each I/O request\n"
+"  -d, --depth DEPTH\n"
+" number of requests to perform in parallel\n"
+"  -o, --offset OFFSET\n"
+" start first request at this OFFSET\n"
+"  -S, --step-size STEP_SIZE\n"
+" each next request offset increment\n"
+"  -i, --aio AIO\n"
+" async-io backend (threads, native, io_uring)\n"
+"  -n, --native\n"
+" use native AIO backend if possible\n"
+"  -w, --write\n"
+" perform write test (default is read)\n"
+"  --pattern PATTERN\n"
+" write this pattern byte instead of zero\n"
+"  --flush-interval FLUSH_INTERVAL\n"
+" issue flush after this number of requests\n"
+"  --no-drain\n"
+" do not wait when flushing pending requests\n"
+"  -U, --force-share\n"
+" open images in shared mode for concurrent access\n"
+);
 break;
 case 'c':
 {
@@ -4987,6 +5029,8 @@ static int img_bench(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 13/27] qemu-img: map: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

While at it, remove unused option_index variable.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 34 --
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 34c4cd86de..84e2e53fb7 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3454,7 +3454,6 @@ static int img_map(const img_cmd_t *ccmd, int argc, char 
**argv)
 
 fmt = NULL;
 for (;;) {
-int option_index = 0;
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
 {"format", required_argument, 0, 'f'},
@@ -3466,20 +3465,33 @@ static int img_map(const img_cmd_t *ccmd, int argc, 
char **argv)
 {"max-length", required_argument, 0, 'l'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":f:s:l:hU",
-long_options, _index);
+c = getopt_long(argc, argv, "f:s:l:hU",
+long_options, NULL);
 if (c == -1) {
 break;
 }
 switch (c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [--object OBJDEF] [--output human|json]\n"
+"[--start-offset OFFSET] [--max-length LENGTH] [-U] FILENAME\n"
+,
+"  -f, --format FMT\n"
+" specify FILENAME image format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  --start-offset OFFSET\n"
+"  --max-length LENGTH\n"
+"  --output human|json\n"
+" specify output format name (default human)\n"
+"  -U, --force-share\n"
+" open image in shared mode for concurrent access\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  FILENAME\n"
+" image file name (or specification with --image-opts)\n"
+);
 break;
 case 'f':
 fmt = optarg;
@@ -3508,6 +3520,8 @@ static int img_map(const img_cmd_t *ccmd, int argc, char 
**argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 if (optind != argc - 1) {
-- 
2.39.2




[PATCH v3 00/27] qemu-img: refersh options and --help handling, cleanups

2024-04-24 Thread Michael Tokarev
Quite big patchset trying to implement normal, readable qemu-img --help
(and qemu-img COMMAND --help) output with readable descriptions, and
adding many long options in the process.

In the end I stopped using qemu-img-opts.hx in qemu-img.c, perhaps
this can be avoided, with only list of commands and their desrciptions
kept there, but I don't see big advantage here.  The same list should
be included in docs/tools/qemu-img.rst, - this is not done now.

Also each command syntax isn't reflected in the doc for now, because
I want to give good names for options first, - and there, we've quite
some inconsistences and questions.  For example, measure --output=OFMT
-O OFMT, - this is priceless :)  I've no idea why we have this ugly
--output=json thing, why not have --json? ;)  I gave the desired
format long name --target-format to avoid clash with --output.

For rebase, src vs tgt probably should be renamed in local variables
too, and I'm not even sure I've got the caches right. For caches,
the thing is inconsistent across commands.

For compare, I used --a-format/--b-format (for -f/-F), - this can
be made --souce-format and --target-format, to compare source (file1)
with target (file2).

For bitmap, things are scary, I'm not sure what -b SRC_FILENAME
really means, - for now I gave it --source option, but this does
not make it more clear, suggestions welcome.

There are many other inconsistencies, I can't fix them all in one go.

Changes since v2:

 - added Dan's R-Bs
 - refined couple cvtnum conversions
 - dropped "stop printing error twice in a few places"

Michael Tokarev (27):
  qemu-img: measure: convert img_size to signed, simplify handling
  qemu-img: create: convert img_size to signed, simplify handling
  qemu-img: global option processing and error printing
  qemu-img: pass current cmd info into command handlers
  qemu-img: create: refresh options/--help
  qemu-img: factor out parse_output_format() and use it in the code
  qemu-img: check: refresh options/--help
  qemu-img: simplify --repair error message
  qemu-img: commit: refresh options/--help
  qemu-img: compare: refresh options/--help
  qemu-img: convert: refresh options/--help
  qemu-img: info: refresh options/--help
  qemu-img: map: refresh options/--help
  qemu-img: snapshot: allow specifying -f fmt
  qemu-img: snapshot: make -l (list) the default, simplify option
handling
  qemu-img: snapshot: refresh options/--help
  qemu-img: rebase: refresh options/--help
  qemu-img: resize: do not always eat last argument
  qemu-img: resize: refresh options/--help
  qemu-img: amend: refresh options/--help
  qemu-img: bench: refresh options/--help
  qemu-img: bitmap: refresh options/--help
  qemu-img: dd: refresh options/--help
  qemu-img: measure: refresh options/--help
  qemu-img: implement short --help, remove global help() function
  qemu-img: inline list of supported commands, remove qemu-img-cmds.h
include
  qemu-img: extend cvtnum() and use it in more places

 docs/tools/qemu-img.rst|4 +-
 qemu-img-cmds.hx   |4 +-
 qemu-img.c | 1311 ++--
 tests/qemu-iotests/049.out |9 +-
 4 files changed, 821 insertions(+), 507 deletions(-)

-- 
2.39.2




[PATCH 22/27] qemu-img: bitmap: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 40 
 1 file changed, 32 insertions(+), 8 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index fff537df26..7c20a5772d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -5170,20 +5170,42 @@ static int img_bitmap(const img_cmd_t *ccmd, int argc, 
char **argv)
 {"source-format", required_argument, 0, 'F'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":b:f:F:g:h", long_options, NULL);
+c = getopt_long(argc, argv, "b:f:F:g:h",
+long_options, NULL);
 if (c == -1) {
 break;
 }
 
 switch (c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"( --merge SOURCE | --add | --remove | --clear |\n"
+"--enable | --disable ).. [-f FMT | --image-opts]\n"
+"[ -b SRC_FILENAME [-F SOURCE_FMT]] [-g SIZE[KMGTPE]] [--object 
OBJDEF]\n"
+"FILENAME BITMAP\n"
+,
+"  -f, --format FMT\n"
+" specify FILENAME format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  --add\n"
+" creates BITMAP, enables to record future edits\n"
+"   -g, --granularity SIZE[KMGTPE]\n"
+" sets non-default bitmap granularity for --add to this size\n"
+"  --remove\n"
+" removes BITMAP\n"
+"  --clear\n"
+" clears BITMAP\n"
+"  --enable, --disable\n"
+" starts and stops recording future edits to BITMAP\n"
+"  --merge SRC_FILENAME\n"
+" merges contents of SRC_FILENAME bitmap into BITMAP\n"
+"   -b, --source-file SRC_FILENAME\n"
+" select alternative source file for --merge\n"
+"   -F, --source-format SRC_FMT\n"
+" specify format for SRC_FILENAME explicitly\n"
+);
 break;
 case 'b':
 src_filename = optarg;
@@ -5239,6 +5261,8 @@ static int img_bitmap(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 18/27] qemu-img: resize: do not always eat last argument

2024-04-24 Thread Michael Tokarev
'qemu-img resize --help' does not work, since it wants more
arguments.  Also -size is only recognized as a very last
argument, but it is common for tools to handle other options
after positional arguments too.

Tell getopt_long() to return non-options together with options,
and process filename and size in the loop, and check if there's
an argument right after filename which looks like -N (number),
and treat it as size (decrement).  This way we can handle --help,
and we can also have options after filename and size, and `--'
will be handled fine too.

The only case which is not handled right is when there's an option
between filename and size, and size is given as decrement, - in
this case -size will be treated as option, not as size.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 41 +++--
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 47dfa137c1..da10fafffc 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4297,7 +4297,7 @@ static int img_resize(const img_cmd_t *ccmd, int argc, 
char **argv)
 {
 Error *err = NULL;
 int c, ret, relative;
-const char *filename, *fmt, *size;
+const char *filename = NULL, *fmt = NULL, *size = NULL;
 int64_t n, total_size, current_size;
 bool quiet = false;
 BlockBackend *blk = NULL;
@@ -4320,17 +4320,7 @@ static int img_resize(const img_cmd_t *ccmd, int argc, 
char **argv)
 bool image_opts = false;
 bool shrink = false;
 
-/* Remove size from argv manually so that negative numbers are not treated
- * as options by getopt. */
-if (argc < 3) {
-error_exit(argv[0], "Not enough arguments");
-return 1;
-}
-
-size = argv[--argc];
-
 /* Parse getopt arguments */
-fmt = NULL;
 for(;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
@@ -4340,7 +4330,7 @@ static int img_resize(const img_cmd_t *ccmd, int argc, 
char **argv)
 {"shrink", no_argument, 0, OPTION_SHRINK},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":f:hq",
+c = getopt_long(argc, argv, "-:f:hq",
 long_options, NULL);
 if (c == -1) {
 break;
@@ -4378,12 +4368,35 @@ static int img_resize(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_SHRINK:
 shrink = true;
 break;
+case 1: /* a non-optional argument */
+if (!filename) {
+filename = optarg;
+/* see if we have -size (number) next to filename */
+if (optind < argc) {
+size = argv[optind];
+if (size[0] == '-' && size[1] >= '0' && size[1] <= '9') {
+++optind;
+} else {
+size = NULL;
+}
+}
+} else if (!size) {
+size = optarg;
+} else {
+error_exit(argv[0], "Extra argument(s) in command line");
+}
+break;
 }
 }
-if (optind != argc - 1) {
+if (!filename && optind < argc) {
+filename = argv[optind++];
+}
+if (!size && optind < argc) {
+size = argv[optind++];
+}
+if (!filename || !size || optind < argc) {
 error_exit(argv[0], "Expecting image file name and size");
 }
-filename = argv[optind++];
 
 /* Choose grow, shrink, or absolute resize mode */
 switch (size[0]) {
-- 
2.39.2




[PATCH 20/27] qemu-img: amend: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 34 ++
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 688c01722c..76000c485c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4559,26 +4559,42 @@ static int img_amend(const img_cmd_t *ccmd, int argc, 
char **argv)
 for (;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
+{"progress", no_argument, 0, 'p'},
 {"object", required_argument, 0, OPTION_OBJECT},
+{"format", required_argument, 0, 'f'},
+{"cache", required_argument, 0, 't'},
+{"options", required_argument, 0, 'o'},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 {"force", no_argument, 0, OPTION_FORCE},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":ho:f:t:pq",
+c = getopt_long(argc, argv, "ho:f:t:pq",
 long_options, NULL);
 if (c == -1) {
 break;
 }
 
 switch (c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [t CACHE] [--force] [-p] [-q]\n"
+"[--object OBJDEF -o OPTIONS FILENAME\n"
+,
+"  -q, --quiet\n"
+" quiet operation\n"
+"  -p, --progres\n"
+" show progress\n"
+"  -f, --format FMT\n"
+" specify FILENAME format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+"   instead of a file name (incompatible with --format)\n"
+"  -t, --cache CACHE\n"
+" cache mode for FILENAME (" BDRV_DEFAULT_CACHE ")\n"
+"  --force\n"
+" allow certain unsafe operations\n"
+);
 break;
 case 'o':
 if (accumulate_options(, optarg) < 0) {
@@ -4607,6 +4623,8 @@ static int img_amend(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_FORCE:
 force = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 16/27] qemu-img: snapshot: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 45 -
 1 file changed, 36 insertions(+), 9 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 967f6343de..62f9ce4069 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3609,26 +3609,51 @@ static int img_snapshot(const img_cmd_t *ccmd, int 
argc, char **argv)
 for(;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
 {"object", required_argument, 0, OPTION_OBJECT},
+{"format", required_argument, 0, 'f'},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 {"force-share", no_argument, 0, 'U'},
+{"list", no_argument, 0, SNAPSHOT_LIST},
+{"apply", no_argument, 0, SNAPSHOT_APPLY},
+{"create", no_argument, 0, SNAPSHOT_CREATE},
+{"delete", no_argument, 0, SNAPSHOT_DELETE},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":la:c:d:f:hqU",
+c = getopt_long(argc, argv, "la:c:d:f:hqU",
 long_options, NULL);
 if (c == -1) {
 break;
 }
 switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
-return 0;
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [-l | -a|-c|-d SNAPSHOT]\n"
+"[-U] [--object OBJDEF] FILENAME\n"
+,
+"  -q, --quiet\n"
+"  quiet operations\n"
+"  -f, --format FMT\n"
+"  specify FILENAME format explicitly\n"
+"  --image-opts\n"
+"  indicates that FILENAME is a complete image specification\n"
+"   instead of a file name (incompatible with --format)\n"
+"  -U, --force-share\n"
+"  open image in shared mode for concurrent access\n"
+"  --object OBJDEF\n"
+"  QEMU user-creatable object (eg encryption key)\n"
+"  Operation, one of:\n"
+"-l, --list\n"
+"   list snapshots in FILENAME (the default)\n"
+"-c, --create SNAPSHOT\n"
+"   create named snapshot\n"
+"-a, --apply SNAPSHOT\n"
+"   apply named snapshot to the base\n"
+"-d, --delete SNAPSHOT\n"
+"   delete named snapshot\n"
+"  FILENAME - image file name (or specification with --image-opts)\n"
+);
+break;
 case 'f':
 fmt = optarg;
 break;
@@ -3655,6 +3680,8 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 07/27] qemu-img: check: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 38 ++
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 08536553c7..1bd88fcf63 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -805,7 +805,9 @@ static int img_check(const img_cmd_t *ccmd, int argc, char 
**argv)
 int option_index = 0;
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
 {"format", required_argument, 0, 'f'},
+{"cache", required_argument, 0, 'T'},
 {"repair", required_argument, 0, 'r'},
 {"output", required_argument, 0, OPTION_OUTPUT},
 {"object", required_argument, 0, OPTION_OBJECT},
@@ -813,20 +815,38 @@ static int img_check(const img_cmd_t *ccmd, int argc, 
char **argv)
 {"force-share", no_argument, 0, 'U'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":hf:r:T:qU",
+c = getopt_long(argc, argv, "hf:r:T:qU",
 long_options, _index);
 if (c == -1) {
 break;
 }
 switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [-T CACHE_MODE] [-r] [-u]\n"
+"[--output human|json] [--object OBJDEF] FILENAME\n"
+,
+"  -q, --quiet\n"
+" quiet operations\n"
+"  -f, --format FMT\n"
+" specifies format of the image explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  -T, --cache CACHE_MODE\n"
+" image cache mode (" BDRV_DEFAULT_CACHE ")\n"
+"  -U, --force-share\n"
+" open image in shared mode for concurrent access\n"
+"  --output human|json\n"
+" output format\n"
+"  -r, --repair leaks|all\n"
+" repair particular aspect of the image\n"
+" (image will be open in read-write mode, incompatible with 
--force-share)\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  FILENAME\n"
+" the image file (or image specification) to operate on\n"
+);
 break;
 case 'f':
 fmt = optarg;
@@ -861,6 +881,8 @@ static int img_check(const img_cmd_t *ccmd, int argc, char 
**argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 if (optind != argc - 1) {
-- 
2.39.2




[PATCH 05/27] qemu-img: create: refresh options/--help

2024-04-24 Thread Michael Tokarev
Create helper function cmd_help() to display command-specific
help text, and use it to print --help for 'create' subcommand.

Add missing long options (eg --format) in img_create().

Remove usage of missing_argument()/unrecognized_option() in
img_create().

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 69 +++---
 1 file changed, 61 insertions(+), 8 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index e8234104e5..7ed5e6d1a8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -132,6 +132,32 @@ void unrecognized_option(const char *option)
 error_exit("qemu-img", "unrecognized option '%s'", option);
 }
 
+/*
+ * Print --help output for a command and exit.
+ * syntax and description are multi-line with trailing EOL
+ * (to allow easy extending of the text)
+ * syntax has each subsequent line indented by 8 chars.
+ * desrciption is indented by 2 chars for argument on each own line,
+ * and with 5 chars for argument description (like -h arg below).
+ */
+static G_NORETURN
+void cmd_help(const img_cmd_t *ccmd,
+  const char *syntax, const char *arguments)
+{
+printf(
+"Usage:\n"
+"\n"
+"  %s %s %s"
+"\n"
+"Arguments:\n"
+"  -h, --help\n"
+" print this help and exit\n"
+"%s\n",
+   "qemu-img", ccmd->name,
+   syntax, arguments);
+exit(EXIT_SUCCESS);
+}
+
 /* Please keep in synch with docs/tools/qemu-img.rst */
 static G_NORETURN
 void help(void)
@@ -530,23 +556,48 @@ static int img_create(const img_cmd_t *ccmd, int argc, 
char **argv)
 for(;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
 {"object", required_argument, 0, OPTION_OBJECT},
+{"format", required_argument, 0, 'f'},
+{"backing", required_argument, 0, 'b'},
+{"backing-format", required_argument, 0, 'F'},
+{"backing-unsafe", no_argument, 0, 'u'},
+{"options", required_argument, 0, 'o'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":F:b:f:ho:qu",
+c = getopt_long(argc, argv, "F:b:f:ho:qu",
 long_options, NULL);
 if (c == -1) {
 break;
 }
 switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT] [-o FMT_OPTS] [-b BACKING_FILENAME [-F BACKING_FMT]]\n"
+"[--object OBJDEF] [-u] FILENAME [SIZE[bkKMGTPE]]\n"
+,
+"  -q, --quiet\n"
+" quiet operations\n"
+"  -f, --format FMT\n"
+" specifies format of the new image, default is raw\n"
+"  -o, --options FMT_OPTS\n"
+" format-specific options ('-o list' for list)\n"
+"  -b, --backing BACKING_FILENAME\n"
+" stack new image on top of BACKING_FILENAME\n"
+" (for formats which support stacking)\n"
+"  -F, --backing-format BACKING_FMT\n"
+" specify format of BACKING_FILENAME\n"
+"  -u, --backing-unsafe\n"
+" do not fail if BACKING_FMT can not be read\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  FILENAME\n"
+" image file to create.  It will be overridden if exists\n"
+"  SIZE\n"
+" image size with optional suffix (multiplies in 1024)\n"
+" SIZE is required unless BACKING_IMG is specified,\n"
+" in which case it will be the same as size of BACKING_IMG\n"
+);
 break;
 case 'F':
 base_fmt = optarg;
@@ -571,6 +622,8 @@ static int img_create(const img_cmd_t *ccmd, int argc, char 
**argv)
 case OPTION_OBJECT:
 user_creatable_process_cmdline(optarg);
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 11/27] qemu-img: convert: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

convert uses -B for --backing, - why not -b?

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 90 --
 1 file changed, 81 insertions(+), 9 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index ea66bfa195..0a32d890e3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2404,30 +2404,100 @@ static int img_convert(const img_cmd_t *ccmd, int 
argc, char **argv)
 for(;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
 {"object", required_argument, 0, OPTION_OBJECT},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"source-image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"source-format", required_argument, 0, 'f'},
+{"source-cache", required_argument, 0, 'T'},
+{"snapshot", required_argument, 0, 'l'},
+{"sparse-size", required_argument, 0, 'S'},
+{"output-format", required_argument, 0, 'O'},
+{"options", required_argument, 0, 'o'},
+{"output-cache", required_argument, 0, 't'},
+{"backing", required_argument, 0, 'B'},
+{"backing-format", required_argument, 0, 'F'},
 {"force-share", no_argument, 0, 'U'},
 {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
 {"salvage", no_argument, 0, OPTION_SALVAGE},
 {"target-is-zero", no_argument, 0, OPTION_TARGET_IS_ZERO},
 {"bitmaps", no_argument, 0, OPTION_BITMAPS},
 {"skip-broken-bitmaps", no_argument, 0, OPTION_SKIP_BROKEN},
+{"rate", required_argument, 0, 'r'},
+{"parallel", required_argument, 0, 'm'},
+{"oob-writes", no_argument, 0, 'W'},
+{"copy-range-offloading", no_argument, 0, 'C'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":hf:O:B:CcF:o:l:S:pt:T:qnm:WUr:",
+c = getopt_long(argc, argv, "hf:O:B:CcF:o:l:S:pt:T:qnm:WUr:",
 long_options, NULL);
 if (c == -1) {
 break;
 }
-switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
+switch (c) {
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f SRC_FMT|--image-opts] [-T SRC_CACHE] [--bitmaps 
[--skip-broken-bitmaps]]\n"
+"[-o TGT_OPTS|--target-image-opts] [-t TGT_CACHE] [-n]\n"
+"[-B BACKING_FILENAME [-F BACKING_FMT]]\n"
+"SRC_FILENAME [SRC_FILENAME2 [...]] TGT_FILENAME\n"
+,
+"  -q, --quiet\n"
+" quiet operations\n"
+"  -p, --progress\n"
+" show operation progress\n"
+"  -f, --source-format SRC_FMT\n"
+" specify SRC_FILENAME source image format explicitly\n"
+"  --source-image-opts\n"
+" indicates that SRC_FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --source-format)\n"
+"  -l, --source-snapshot SNAPSHOT_PARAMS\n"
+" specify source snapshot parameters\n"
+"  -T, --source-cache SRC_CACHE\n"
+" source image(s) cache mode (" BDRV_DEFAULT_CACHE ")\n"
+"  -O, --target-format TGT_FMT\n"
+" specify TGT_FILENAME image format (default is raw)\n"
+"  --target-image-opts\n"
+" indicates that TGT_FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --output-format)\n"
+"  -o, --target-options TGT_OPTS\n"
+" TARGET_FMT-specific options\n"
+"  -c, --compress\n"
+" create compressed output image (qcow and qcow2 format only)\n"
+"  -t, --target-cache TGT_CACHE\n"
+" cache mode when opening output image (unsafe)\n"
+"  -B, --backing BACKING_FILENAME\n"
+" create output to be a CoW on top of BACKING_FILENAME\n"
+"  -F, --backing-format BACKING_FMT\n"
+" specify BACKING_FILENAME image format explicitly\n"
+"  -n, --no-create\n"
+" omit target volume creation (eg on rbd)\n"
+"  --target-is-zero\n"
+"  -S, --sparse-size SPARSE_SIZE\n"
+" XXX todo\n"
+"  --bitmaps\n"
+" also copy any persistent bitmaps present in source\n"
+"  --skip-broken-bitmaps\n"
+" ski

[PATCH 08/27] qemu-img: simplify --repair error message

2024-04-24 Thread Michael Tokarev
Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 1bd88fcf63..9157a6b45d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -859,8 +859,9 @@ static int img_check(const img_cmd_t *ccmd, int argc, char 
**argv)
 } else if (!strcmp(optarg, "all")) {
 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
 } else {
-error_exit(argv[0], "Unknown option value for -r "
-   "(expecting 'leaks' or 'all'): %s", optarg);
+error_exit(argv[0],
+   "--repair (-r) expects 'leaks' or 'all' not '%s'",
+   optarg);
 }
 break;
 case OPTION_OUTPUT:
-- 
2.39.2




[PATCH 06/27] qemu-img: factor out parse_output_format() and use it in the code

2024-04-24 Thread Michael Tokarev
Use common code and simplify error message

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 63 --
 1 file changed, 18 insertions(+), 45 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 7ed5e6d1a8..08536553c7 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -158,6 +158,17 @@ void cmd_help(const img_cmd_t *ccmd,
 exit(EXIT_SUCCESS);
 }
 
+static OutputFormat parse_output_format(const char *argv0, const char *arg)
+{
+if (!strcmp(arg, "json")) {
+return OFORMAT_JSON;
+} else if (!strcmp(arg, "human")) {
+return OFORMAT_HUMAN;
+} else {
+error_exit(argv0, "--output expects 'human' or 'json' not '%s'", arg);
+}
+}
+
 /* Please keep in synch with docs/tools/qemu-img.rst */
 static G_NORETURN
 void help(void)
@@ -776,7 +787,7 @@ static int img_check(const img_cmd_t *ccmd, int argc, char 
**argv)
 {
 int c, ret;
 OutputFormat output_format = OFORMAT_HUMAN;
-const char *filename, *fmt, *output, *cache;
+const char *filename, *fmt, *cache;
 BlockBackend *blk;
 BlockDriverState *bs;
 int fix = 0;
@@ -788,7 +799,6 @@ static int img_check(const img_cmd_t *ccmd, int argc, char 
**argv)
 bool force_share = false;
 
 fmt = NULL;
-output = NULL;
 cache = BDRV_DEFAULT_CACHE;
 
 for(;;) {
@@ -834,7 +844,7 @@ static int img_check(const img_cmd_t *ccmd, int argc, char 
**argv)
 }
 break;
 case OPTION_OUTPUT:
-output = optarg;
+output_format = parse_output_format(argv[0], optarg);
 break;
 case 'T':
 cache = optarg;
@@ -858,15 +868,6 @@ static int img_check(const img_cmd_t *ccmd, int argc, char 
**argv)
 }
 filename = argv[optind++];
 
-if (output && !strcmp(output, "json")) {
-output_format = OFORMAT_JSON;
-} else if (output && !strcmp(output, "human")) {
-output_format = OFORMAT_HUMAN;
-} else if (output) {
-error_report("--output must be used with human or json as argument.");
-return 1;
-}
-
 ret = bdrv_parse_cache_mode(cache, , );
 if (ret < 0) {
 error_report("Invalid source cache option: %s", cache);
@@ -3060,13 +3061,12 @@ static int img_info(const img_cmd_t *ccmd, int argc, 
char **argv)
 int c;
 OutputFormat output_format = OFORMAT_HUMAN;
 bool chain = false;
-const char *filename, *fmt, *output;
+const char *filename, *fmt;
 BlockGraphInfoList *list;
 bool image_opts = false;
 bool force_share = false;
 
 fmt = NULL;
-output = NULL;
 for(;;) {
 int option_index = 0;
 static const struct option long_options[] = {
@@ -3101,7 +3101,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, char 
**argv)
 force_share = true;
 break;
 case OPTION_OUTPUT:
-output = optarg;
+output_format = parse_output_format(argv[0], optarg);
 break;
 case OPTION_BACKING_CHAIN:
 chain = true;
@@ -3119,15 +3119,6 @@ static int img_info(const img_cmd_t *ccmd, int argc, 
char **argv)
 }
 filename = argv[optind++];
 
-if (output && !strcmp(output, "json")) {
-output_format = OFORMAT_JSON;
-} else if (output && !strcmp(output, "human")) {
-output_format = OFORMAT_HUMAN;
-} else if (output) {
-error_report("--output must be used with human or json as argument.");
-return 1;
-}
-
 list = collect_image_info_list(image_opts, filename, fmt, chain,
force_share);
 if (!list) {
@@ -3286,7 +3277,7 @@ static int img_map(const img_cmd_t *ccmd, int argc, char 
**argv)
 OutputFormat output_format = OFORMAT_HUMAN;
 BlockBackend *blk;
 BlockDriverState *bs;
-const char *filename, *fmt, *output;
+const char *filename, *fmt;
 int64_t length;
 MapEntry curr = { .length = 0 }, next;
 int ret = 0;
@@ -3296,7 +3287,6 @@ static int img_map(const img_cmd_t *ccmd, int argc, char 
**argv)
 int64_t max_length = -1;
 
 fmt = NULL;
-output = NULL;
 for (;;) {
 int option_index = 0;
 static const struct option long_options[] = {
@@ -3332,7 +3322,7 @@ static int img_map(const img_cmd_t *ccmd, int argc, char 
**argv)
 force_share = true;
 break;
 case OPTION_OUTPUT:
-output = optarg;
+output_format = parse_output_format(argv[0], optarg);
 break;
 case 's':
 start_offset = cvtnum("start offset", optarg);
@@ -3359,15 +3349,6 @@ static int img_map(const img_cmd_t *ccmd, int argc, char 
**argv)
 }
 filename = argv[optind];
 
-if (output && !strcmp(output, "json&qu

[PATCH 15/27] qemu-img: snapshot: make -l (list) the default, simplify option handling

2024-04-24 Thread Michael Tokarev
When no -l/-a/-c/-d specified, assume -l (list).

Use the same values for SNAPSHOT_LIST/etc constants as the
option chars (lacd), this makes it possible to simplify
option handling a lot, combining cases for 4 options into
one.

Also remove bdrv_oflags handling (only list can use RO mode).

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 docs/tools/qemu-img.rst |  2 +-
 qemu-img.c  | 52 ++---
 2 files changed, 19 insertions(+), 35 deletions(-)

diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
index 9b628c4da5..df184d15b9 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -256,7 +256,7 @@ Parameters to snapshot subcommand:
 
 .. option:: -l
 
-  Lists all snapshots in the given image
+  Lists all snapshots in the given image (default action)
 
 Command description:
 
diff --git a/qemu-img.c b/qemu-img.c
index 8adc324496..967f6343de 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3585,10 +3585,11 @@ out:
 return ret < 0;
 }
 
-#define SNAPSHOT_LIST   1
-#define SNAPSHOT_CREATE 2
-#define SNAPSHOT_APPLY  3
-#define SNAPSHOT_DELETE 4
+/* the same as options */
+#define SNAPSHOT_LIST   'l'
+#define SNAPSHOT_CREATE 'c'
+#define SNAPSHOT_APPLY  'a'
+#define SNAPSHOT_DELETE 'd'
 
 static int img_snapshot(const img_cmd_t *ccmd, int argc, char **argv)
 {
@@ -3596,7 +3597,7 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 BlockDriverState *bs;
 QEMUSnapshotInfo sn;
 char *filename, *fmt = NULL, *snapshot_name = NULL;
-int c, ret = 0, bdrv_oflags;
+int c, ret = 0;
 int action = 0;
 bool quiet = false;
 Error *err = NULL;
@@ -3604,7 +3605,6 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 bool force_share = false;
 int64_t rt;
 
-bdrv_oflags = BDRV_O_RDWR;
 /* Parse commandline parameters */
 for(;;) {
 static const struct option long_options[] = {
@@ -3632,36 +3632,15 @@ static int img_snapshot(const img_cmd_t *ccmd, int 
argc, char **argv)
 case 'f':
 fmt = optarg;
 break;
-case 'l':
-if (action) {
-error_exit(argv[0], "Cannot mix '-l', '-a', '-c', '-d'");
-return 0;
-}
-action = SNAPSHOT_LIST;
-bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
-break;
-case 'a':
+case SNAPSHOT_LIST:
+case SNAPSHOT_APPLY:
+case SNAPSHOT_CREATE:
+case SNAPSHOT_DELETE:
 if (action) {
 error_exit(argv[0], "Cannot mix '-l', '-a', '-c', '-d'");
 return 0;
 }
-action = SNAPSHOT_APPLY;
-snapshot_name = optarg;
-break;
-case 'c':
-if (action) {
-error_exit(argv[0], "Cannot mix '-l', '-a', '-c', '-d'");
-return 0;
-}
-action = SNAPSHOT_CREATE;
-snapshot_name = optarg;
-break;
-case 'd':
-if (action) {
-error_exit(argv[0], "Cannot mix '-l', '-a', '-c', '-d'");
-return 0;
-}
-action = SNAPSHOT_DELETE;
+action = c;
 snapshot_name = optarg;
 break;
 case 'q':
@@ -3684,9 +3663,14 @@ static int img_snapshot(const img_cmd_t *ccmd, int argc, 
char **argv)
 }
 filename = argv[optind++];
 
+if (!action) {
+action = SNAPSHOT_LIST;
+}
+
 /* Open the image */
-blk = img_open(image_opts, filename, fmt, bdrv_oflags, false, quiet,
-   force_share);
+blk = img_open(image_opts, filename, fmt,
+   action == SNAPSHOT_LIST ? 0 : BDRV_O_RDWR,
+   false, quiet, force_share);
 if (!blk) {
 return 1;
 }
-- 
2.39.2




[PATCH 09/27] qemu-img: commit: refresh options/--help

2024-04-24 Thread Michael Tokarev
Add missing long options and --help output.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 44 
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 9157a6b45d..7a111bce72 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1048,24 +1048,50 @@ static int img_commit(const img_cmd_t *ccmd, int argc, 
char **argv)
 for(;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
 {"object", required_argument, 0, OPTION_OBJECT},
+{"format", required_argument, 0, 'f'},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"cache", required_argument, 0, 't'},
+{"drop", no_argument, 0, 'd'},
+{"base", required_argument, 0, 'b'},
+{"progress", no_argument, 0, 'p'},
+{"rate", required_argument, 0, 'r'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":f:ht:b:dpqr:",
+c = getopt_long(argc, argv, "f:ht:b:dpqr:",
 long_options, NULL);
 if (c == -1) {
 break;
 }
 switch(c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[-f FMT | --image-opts] [-t CACHE_MODE] [-b BASE_IMG] [-d]\n"
+"[-r RATE] [--object OBJDEF] FILENAME\n"
+,
+"  -q, --quiet\n"
+" quiet operations\n"
+"  -p, --progress\n"
+" show operation progress\n"
+"  -f, --format FMT\n"
+" specify FILENAME image format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAME is a complete image specification\n"
+" instead of a file name (incompatible with --format)\n"
+"  -t, --cache CACHE_MODE image cache mode (" BDRV_DEFAULT_CACHE ")\n"
+"  -d, --drop\n"
+" skip emptying FILENAME on completion\n"
+"  -b, --base BASE_IMG\n"
+" image in the backing chain to which to commit changes\n"
+" instead of the previous one (implies --drop)\n"
+"  -r, --rate RATE\n"
+" I/O rate limit\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  FILENAME\n"
+" name of the image file to operate on\n"
+);
 break;
 case 'f':
 fmt = optarg;
@@ -1099,6 +1125,8 @@ static int img_commit(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 03/27] qemu-img: global option processing and error printing

2024-04-24 Thread Michael Tokarev
In order to correctly print executable name in various
error messages, pass argv[0] to error_exit() function.
This way, error messages will refer to actual executable
name, which may be different from 'qemu-img'.

For subcommands, pass original command name from the
qemu-img argv[0], plus the subcommand name, as its own
argv[0] element, so error messages can be more useful.
Also don't require at least 3 options on the command
line: it makes no sense with options before subcommand.

Introduce tryhelp() function which just prints

 try 'command-name --help' for more info

and exits.  When tryhelp() is called from within a subcommand
handler, the message will look like:

 try 'command-name subcommand --help' for more info

qemu-img uses getopt_long() with ':' as the first char in
optstring parameter, which means it doesn't print error
messages but return ':' or '?' instead, and qemu-img uses
unrecognized_option() or missing_argument() function to
print error messages.  But it doesn't quite work:

 $ ./qemu-img -xx
 qemu-img: unrecognized option './qemu-img'

so the aim is to let getopt_long() to print regular error
messages instead (removing ':' prefix from optstring) and
remove handling of '?' and ':' "options" entirely.  With
concatenated argv[0] and the subcommand, it all finally
does the right thing in all cases.  This will be done in
subsequent changes command by command, with main() done
last.

unrecognized_option() and missing_argument() functions
prototypes aren't changed by this patch, since they're
called from many places and will be removed a few patches
later.  Only artifical "qemu-img" argv0 is provided in
there for now.

Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 80 +-
 1 file changed, 43 insertions(+), 37 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index fe22986931..130188e287 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -101,8 +101,15 @@ static void format_print(void *opaque, const char *name)
 printf(" %s", name);
 }
 
-static G_NORETURN G_GNUC_PRINTF(1, 2)
-void error_exit(const char *fmt, ...)
+static G_NORETURN
+void tryhelp(const char *argv0)
+{
+error_printf("Try '%s --help' for more info\n", argv0);
+exit(EXIT_FAILURE);
+}
+
+static G_NORETURN G_GNUC_PRINTF(2, 3)
+void error_exit(const char *argv0, const char *fmt, ...)
 {
 va_list ap;
 
@@ -110,20 +117,19 @@ void error_exit(const char *fmt, ...)
 error_vreport(fmt, ap);
 va_end(ap);
 
-error_printf("Try 'qemu-img --help' for more information\n");
-exit(EXIT_FAILURE);
+tryhelp(argv0);
 }
 
 static G_NORETURN
 void missing_argument(const char *option)
 {
-error_exit("missing argument for option '%s'", option);
+error_exit("qemu-img", "missing argument for option '%s'", option);
 }
 
 static G_NORETURN
 void unrecognized_option(const char *option)
 {
-error_exit("unrecognized option '%s'", option);
+error_exit("qemu-img", "unrecognized option '%s'", option);
 }
 
 /* Please keep in synch with docs/tools/qemu-img.rst */
@@ -576,7 +582,7 @@ static int img_create(int argc, char **argv)
 }
 
 if (optind >= argc) {
-error_exit("Expecting image file name");
+error_exit(argv[0], "Expecting image file name");
 }
 optind++;
 
@@ -588,7 +594,7 @@ static int img_create(int argc, char **argv)
 }
 }
 if (optind != argc) {
-error_exit("Unexpected argument: %s", argv[optind]);
+error_exit(argv[0], "Unexpected argument: %s", argv[optind]);
 }
 
 bdrv_img_create(filename, fmt, base_filename, base_fmt,
@@ -770,7 +776,7 @@ static int img_check(int argc, char **argv)
 } else if (!strcmp(optarg, "all")) {
 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
 } else {
-error_exit("Unknown option value for -r "
+error_exit(argv[0], "Unknown option value for -r "
"(expecting 'leaks' or 'all'): %s", optarg);
 }
 break;
@@ -795,7 +801,7 @@ static int img_check(int argc, char **argv)
 }
 }
 if (optind != argc - 1) {
-error_exit("Expecting one image file name");
+error_exit(argv[0], "Expecting one image file name");
 }
 filename = argv[optind++];
 
@@ -1025,7 +1031,7 @@ static int img_commit(int argc, char **argv)
 }
 
 if (optind != argc - 1) {
-error_exit("Expecting one image file name");
+error_exit(argv[0], "Expecting one image file name");
 }
 filename = argv[optind++];
 
@@ -1446,7 +1452,7 @@ static int img_compare(int argc, char **argv)
 
 
 if (optind != argc - 2) {
-error_exit("Expecting two image file names");
+error_exit(argv[0]

[PATCH 04/27] qemu-img: pass current cmd info into command handlers

2024-04-24 Thread Michael Tokarev
This info will be used to generate --help output.

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 130188e287..e8234104e5 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -60,7 +60,7 @@
 
 typedef struct img_cmd_t {
 const char *name;
-int (*handler)(int argc, char **argv);
+int (*handler)(const struct img_cmd_t *ccmd, int argc, char **argv);
 } img_cmd_t;
 
 enum {
@@ -514,7 +514,7 @@ static int64_t cvtnum(const char *name, const char *value)
 return cvtnum_full(name, value, 0, INT64_MAX);
 }
 
-static int img_create(int argc, char **argv)
+static int img_create(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int c;
 int64_t img_size = -1;
@@ -719,7 +719,7 @@ static int collect_image_check(BlockDriverState *bs,
  *  3 - Check completed, image has leaked clusters, but is good otherwise
  * 63 - Checks are not supported by the image format
  */
-static int img_check(int argc, char **argv)
+static int img_check(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int c, ret;
 OutputFormat output_format = OFORMAT_HUMAN;
@@ -951,7 +951,7 @@ static void run_block_job(BlockJob *job, Error **errp)
 }
 }
 
-static int img_commit(int argc, char **argv)
+static int img_commit(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int c, ret, flags;
 const char *filename, *fmt, *cache, *base;
@@ -1358,7 +1358,7 @@ static int check_empty_sectors(BlockBackend *blk, int64_t 
offset,
  * 1 - Images differ
  * >1 - Error occurred
  */
-static int img_compare(int argc, char **argv)
+static int img_compare(const img_cmd_t *ccmd, int argc, char **argv)
 {
 const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
 BlockBackend *blk1, *blk2;
@@ -2234,7 +2234,7 @@ static void set_rate_limit(BlockBackend *blk, int64_t 
rate_limit)
 blk_set_io_limits(blk, );
 }
 
-static int img_convert(int argc, char **argv)
+static int img_convert(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int c, bs_i, flags, src_flags = BDRV_O_NO_SHARE;
 const char *fmt = NULL, *out_fmt = NULL, *cache = "unsafe",
@@ -3002,7 +3002,7 @@ err:
 return NULL;
 }
 
-static int img_info(int argc, char **argv)
+static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int c;
 OutputFormat output_format = OFORMAT_HUMAN;
@@ -3227,7 +3227,7 @@ static inline bool entry_mergeable(const MapEntry *curr, 
const MapEntry *next)
 return true;
 }
 
-static int img_map(int argc, char **argv)
+static int img_map(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int c;
 OutputFormat output_format = OFORMAT_HUMAN;
@@ -3376,7 +3376,7 @@ out:
 #define SNAPSHOT_APPLY  3
 #define SNAPSHOT_DELETE 4
 
-static int img_snapshot(int argc, char **argv)
+static int img_snapshot(const img_cmd_t *ccmd, int argc, char **argv)
 {
 BlockBackend *blk;
 BlockDriverState *bs;
@@ -3534,7 +3534,7 @@ static int img_snapshot(int argc, char **argv)
 return 0;
 }
 
-static int img_rebase(int argc, char **argv)
+static int img_rebase(const img_cmd_t *ccmd, int argc, char **argv)
 {
 BlockBackend *blk = NULL, *blk_old_backing = NULL, *blk_new_backing = NULL;
 uint8_t *buf_old = NULL;
@@ -4028,7 +4028,7 @@ out:
 return 0;
 }
 
-static int img_resize(int argc, char **argv)
+static int img_resize(const img_cmd_t *ccmd, int argc, char **argv)
 {
 Error *err = NULL;
 int c, ret, relative;
@@ -4241,7 +4241,7 @@ static int print_amend_option_help(const char *format)
 return 0;
 }
 
-static int img_amend(int argc, char **argv)
+static int img_amend(const img_cmd_t *ccmd, int argc, char **argv)
 {
 Error *err = NULL;
 int c, ret = 0;
@@ -4505,7 +4505,7 @@ static void bench_cb(void *opaque, int ret)
 }
 }
 
-static int img_bench(int argc, char **argv)
+static int img_bench(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int c, ret = 0;
 const char *fmt = NULL, *filename;
@@ -4775,7 +4775,7 @@ typedef struct ImgBitmapAction {
 QSIMPLEQ_ENTRY(ImgBitmapAction) next;
 } ImgBitmapAction;
 
-static int img_bitmap(int argc, char **argv)
+static int img_bitmap(const img_cmd_t *ccmd, int argc, char **argv)
 {
 Error *err = NULL;
 int c, ret = 1;
@@ -5075,7 +5075,7 @@ static int img_dd_skip(const char *arg,
 return 0;
 }
 
-static int img_dd(int argc, char **argv)
+static int img_dd(const img_cmd_t *ccmd, int argc, char **argv)
 {
 int ret = 0;
 char *arg = NULL;
@@ -5343,7 +5343,7 @@ static void dump_json_block_measure_info(BlockMeasureInfo 
*info)
 g_string_free(str, true);
 }
 
-static int img_measure(int argc, char **argv)
+static int img_measure(const img_cmd_t *ccmd, int argc, char **argv)
 {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
@@ -5610,7 +5610,7 @@ int main(int argc, char **argv)

[PATCH 10/27] qemu-img: compare: refresh options/--help

2024-04-24 Thread Michael Tokarev
Signed-off-by: Michael Tokarev 
---
 qemu-img.c | 45 +
 1 file changed, 37 insertions(+), 8 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 7a111bce72..ea66bfa195 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1488,25 +1488,52 @@ static int img_compare(const img_cmd_t *ccmd, int argc, 
char **argv)
 for (;;) {
 static const struct option long_options[] = {
 {"help", no_argument, 0, 'h'},
+{"quiet", no_argument, 0, 'q'},
 {"object", required_argument, 0, OPTION_OBJECT},
+{"cache", required_argument, 0, 'T'},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"a-format", required_argument, 0, 'f'},
+{"left-format", required_argument, 0, 'f'},
+{"b-format", required_argument, 0, 'F'},
+{"right-format", required_argument, 0, 'F'},
 {"force-share", no_argument, 0, 'U'},
+{"strict", no_argument, 0, 's'},
+{"progress", no_argument, 0, 'p'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":hf:F:T:pqsU",
+c = getopt_long(argc, argv, "hf:F:T:pqsU",
 long_options, NULL);
 if (c == -1) {
 break;
 }
 switch (c) {
-case ':':
-missing_argument(argv[optind - 1]);
-break;
-case '?':
-unrecognized_option(argv[optind - 1]);
-break;
 case 'h':
-help();
+cmd_help(ccmd,
+"[--image-opts | [-f FMT] [-F FMT]] [-s]\n"
+"[-T CACHE] [-U] [--object OBJDEF] FILENAME1 FILENAME2\n"
+,
+"  -q, --quiet\n"
+" quiet operation\n"
+"  -p, --progress\n"
+" show operation progress\n"
+"  -f, --a-format FMT\n"
+" specify FILENAME1 image format explicitly\n"
+"  -F, --b-format FMT\n"
+" specify FILENAME2 image format explicitly\n"
+"  --image-opts\n"
+" indicates that FILENAMEs are complete image specifications\n"
+" instead of file names (incompatible with --a-format and --b-format)\n"
+"  -s, --strict\n"
+" strict mode, also check if sizes are equal\n"
+"  -T, --cache CACHE_MODE\n"
+" images caching mode (" BDRV_DEFAULT_CACHE ")\n"
+"  -U, --force-share\n"
+" open images in shared mode for concurrent access\n"
+"  --object OBJDEF\n"
+" QEMU user-creatable object (eg encryption key)\n"
+"  FILENAME1, FILENAME2\n"
+" image files (or specifications) to compare\n"
+);
 break;
 case 'f':
 fmt1 = optarg;
@@ -1547,6 +1574,8 @@ static int img_compare(const img_cmd_t *ccmd, int argc, 
char **argv)
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
+default:
+tryhelp(argv[0]);
 }
 }
 
-- 
2.39.2




[PATCH 02/27] qemu-img: create: convert img_size to signed, simplify handling

2024-04-24 Thread Michael Tokarev
Initializing an unsigned as -1, or using temporary
sval for conversion is awkward.  Since we don't allow
other "negative" values anyway, use signed value and
pass it to bdrv_img_create() (where it is properly
converted to unsigned), simplifying code.

Signed-off-by: Michael Tokarev 
Reviewed-by: Daniel P. Berrangé 
---
 qemu-img.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 6e7ac2048f..fe22986931 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -511,7 +511,7 @@ static int64_t cvtnum(const char *name, const char *value)
 static int img_create(int argc, char **argv)
 {
 int c;
-uint64_t img_size = -1;
+int64_t img_size = -1;
 const char *fmt = "raw";
 const char *base_fmt = NULL;
 const char *filename;
@@ -582,13 +582,10 @@ static int img_create(int argc, char **argv)
 
 /* Get image size, if specified */
 if (optind < argc) {
-int64_t sval;
-
-sval = cvtnum("image size", argv[optind++]);
-if (sval < 0) {
+img_size = cvtnum("image size", argv[optind++]);
+if (img_size < 0) {
 goto fail;
 }
-img_size = (uint64_t)sval;
 }
 if (optind != argc) {
 error_exit("Unexpected argument: %s", argv[optind]);
-- 
2.39.2




Re: [PATCH 0/3] Remove useless architecture prefix from the CPU list

2024-04-20 Thread Michael Tokarev

20.04.2024 08:46, Thomas Huth:

Printing an architecture prefix in front of each CPU name is not helpful
at all: It is confusing for the users since they don't know whether they
have to specify these letters for the "-cpu" parameter, too, and it also
takes some precious space in the dense output of the CPU entries. Let's
simply remove those now.

Thomas Huth (3):
   target/i386/cpu: Remove "x86" prefix from the CPU list
   target/s390x/cpu_models: Rework the output of "-cpu help"
   target/ppc/cpu_init: Remove "PowerPC" prefix from the CPU list


Reviewed-by: Michael Tokarev 

I'll pick it up for trivial-patches after 9.0 is out.

This also reminded me about https://gitlab.com/qemu-project/qemu/-/issues/2141

/mjt



[Stable-7.2.11 45/59] hw/display/virtio-gpu: Protect from DMA re-entrancy bugs

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed:

  $ cat << EOF | qemu-system-i386 -display none -nodefaults \
  -machine q35,accel=qtest \
  -m 512M \
  -device virtio-gpu \
  -qtest stdio
  outl 0xcf8 0x8820
  outl 0xcfc 0xe0004000
  outl 0xcf8 0x8804
  outw 0xcfc 0x06
  write 0xe0004030 0x4 0x024000e0
  write 0xe0004028 0x1 0xff
  write 0xe0004020 0x4 0x9300
  write 0xe000401c 0x1 0x01
  write 0x101 0x1 0x04
  write 0x103 0x1 0x1c
  write 0x9301c8 0x1 0x18
  write 0x105 0x1 0x1c
  write 0x107 0x1 0x1c
  write 0x109 0x1 0x1c
  write 0x10b 0x1 0x00
  write 0x10d 0x1 0x00
  write 0x10f 0x1 0x00
  write 0x111 0x1 0x00
  write 0x113 0x1 0x00
  write 0x115 0x1 0x00
  write 0x117 0x1 0x00
  write 0x119 0x1 0x00
  write 0x11b 0x1 0x00
  write 0x11d 0x1 0x00
  write 0x11f 0x1 0x00
  write 0x121 0x1 0x00
  write 0x123 0x1 0x00
  write 0x125 0x1 0x00
  write 0x127 0x1 0x00
  write 0x129 0x1 0x00
  write 0x12b 0x1 0x00
  write 0x12d 0x1 0x00
  write 0x12f 0x1 0x00
  write 0x131 0x1 0x00
  write 0x133 0x1 0x00
  write 0x135 0x1 0x00
  write 0x137 0x1 0x00
  write 0x139 0x1 0x00
  write 0xe0007003 0x1 0x00
  EOF
  ...
  =
  ==276099==ERROR: AddressSanitizer: heap-use-after-free on address 
0x60d11178
  at pc 0x562cc3b736c7 bp 0x7ffed49dee60 sp 0x7ffed49dee58
  READ of size 8 at 0x60d11178 thread T0
  #0 0x562cc3b736c6 in virtio_gpu_ctrl_response 
hw/display/virtio-gpu.c:180:42
  #1 0x562cc3b7c40b in virtio_gpu_ctrl_response_nodata 
hw/display/virtio-gpu.c:192:5
  #2 0x562cc3b7c40b in virtio_gpu_simple_process_cmd 
hw/display/virtio-gpu.c:1015:13
  #3 0x562cc3b82873 in virtio_gpu_process_cmdq 
hw/display/virtio-gpu.c:1050:9
  #4 0x562cc4a85514 in aio_bh_call util/async.c:169:5
  #5 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
  #6 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5
  #7 0x562cc4a8a2da in aio_ctx_dispatch util/async.c:358:5
  #8 0x7f36840547a8 in g_main_context_dispatch 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x547a8)
  #9 0x562cc4a8b753 in glib_pollfds_poll util/main-loop.c:290:9
  #10 0x562cc4a8b753 in os_host_main_loop_wait util/main-loop.c:313:5
  #11 0x562cc4a8b753 in main_loop_wait util/main-loop.c:592:11
  #12 0x562cc3938186 in qemu_main_loop system/runstate.c:782:9
  #13 0x562cc43b7af5 in qemu_default_main system/main.c:37:14
  #14 0x7f3683a6c189 in __libc_start_call_main 
csu/../sysdeps/nptl/libc_start_call_main.h:58:16
  #15 0x7f3683a6c244 in __libc_start_main csu/../csu/libc-start.c:381:3
  #16 0x562cc2a58ac0 in _start (qemu-system-i386+0x231bac0)

  0x60d11178 is located 56 bytes inside of 136-byte region 
[0x60d11140,0x60d111c8)
  freed by thread T0 here:
  #0 0x562cc2adb662 in __interceptor_free (qemu-system-i386+0x239e662)
  #1 0x562cc3b86b21 in virtio_gpu_reset hw/display/virtio-gpu.c:1524:9
  #2 0x562cc416e20e in virtio_reset hw/virtio/virtio.c:2145:9
  #3 0x562cc37c5644 in virtio_pci_reset hw/virtio/virtio-pci.c:2249:5
  #4 0x562cc4233758 in memory_region_write_accessor system/memory.c:497:5
  #5 0x562cc4232eea in access_with_adjusted_size system/memory.c:573:18

  previously allocated by thread T0 here:
  #0 0x562cc2adb90e in malloc (qemu-system-i386+0x239e90e)
  #1 0x7f368405a678 in g_malloc 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5a678)
  #2 0x562cc4163ffc in virtqueue_split_pop hw/virtio/virtio.c:1612:12
  #3 0x562cc4163ffc in virtqueue_pop hw/virtio/virtio.c:1783:16
  #4 0x562cc3b91a95 in virtio_gpu_handle_ctrl 
hw/display/virtio-gpu.c:1112:15
  #5 0x562cc4a85514 in aio_bh_call util/async.c:169:5
  #6 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
  #7 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5

  SUMMARY: AddressSanitizer: heap-use-after-free hw/display/virtio-gpu.c:180:42 
in virtio_gpu_ctrl_response

With this change, the same reproducer triggers:

  qemu-system-i386: warning: Blocked re-entrant IO on MemoryRegion: 
virtio-pci-common-virtio-gpu at addr: 0x6

Fixes: CVE-2024-3446
Cc: qemu-sta...@nongnu.org
Reported-by: Alexander Bulekov 
Reported-by: Yongkang Jia 
Reported-by: Xiao Lei 
Reported-by: Yiming Tao 
Buglink: https://bugs.launchpad.net/qemu/+bug/1888606
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-3-phi...@linaro.org>
(cherry picked from commit ba28e0ff4d95b56dc334aac2730ab3651ffc3132)
Signed-off-by: Michael Tokarev 
(Mjt: context fixup in hw/display/virtio-gpu.c:virtio_gpu_device_realize()
 due to missing v8.1.0-rc2-69-ga41e2d97f92b

[Stable-7.2.11 50/59] hw/block/nand: Have blk_load() take unsigned offset and return boolean

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Negative offset is meaningless, use unsigned type.
Return a boolean value indicating success.

Reviewed-by: Richard Henderson 
Reviewed-by: Kevin Wolf 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409135944.24997-3-phi...@linaro.org>
(cherry picked from commit 2e3e09b368001f7eaeeca7a9b49cb1f0c9092d85)
Signed-off-by: Michael Tokarev 

diff --git a/hw/block/nand.c b/hw/block/nand.c
index 4e3d7fb065..81b2bb804d 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -84,7 +84,11 @@ struct NANDFlashState {
 
 void (*blk_write)(NANDFlashState *s);
 void (*blk_erase)(NANDFlashState *s);
-void (*blk_load)(NANDFlashState *s, uint64_t addr, int offset);
+/*
+ * Returns %true when block containing (@addr + @offset) is
+ * successfully loaded, otherwise %false.
+ */
+bool (*blk_load)(NANDFlashState *s, uint64_t addr, unsigned offset);
 
 uint32_t ioaddr_vmstate;
 };
@@ -772,11 +776,11 @@ static void glue(nand_blk_erase_, 
NAND_PAGE_SIZE)(NANDFlashState *s)
 }
 }
 
-static void glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s,
-uint64_t addr, int offset)
+static bool glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s,
+ uint64_t addr, unsigned 
offset)
 {
 if (PAGE(addr) >= s->pages) {
-return;
+return false;
 }
 
 if (s->blk) {
@@ -804,6 +808,8 @@ static void glue(nand_blk_load_, 
NAND_PAGE_SIZE)(NANDFlashState *s,
 offset, NAND_PAGE_SIZE + OOB_SIZE - offset);
 s->ioaddr = s->io;
 }
+
+return true;
 }
 
 static void glue(nand_init_, NAND_PAGE_SIZE)(NANDFlashState *s)
-- 
2.39.2




[Stable-7.2.11 56/59] hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Per "SD Host Controller Standard Specification Version 3.00":

  * 2.2.5 Transfer Mode Register (Offset 00Ch)

Writes to this register shall be ignored when the Command
Inhibit (DAT) in the Present State register is 1.

Do not update the TRNMOD register when Command Inhibit (DAT)
bit is set to avoid the present-status register going out of
sync, leading to malicious guest using DMA mode and overflowing
the FIFO buffer:

  $ cat << EOF | qemu-system-i386 \
 -display none -nographic -nodefaults \
 -machine accel=qtest -m 512M \
 -device sdhci-pci,sd-spec-version=3 \
 -device sd-card,drive=mydrive \
 -drive 
if=none,index=0,file=null-co://,format=raw,id=mydrive \
 -qtest stdio
  outl 0xcf8 0x80001013
  outl 0xcfc 0x91
  outl 0xcf8 0x80001001
  outl 0xcfc 0x0600
  write 0x912c 0x1 0x05
  write 0x9158 0x1 0x16
  write 0x9105 0x1 0x04
  write 0x9128 0x1 0x08
  write 0x16 0x1 0x21
  write 0x19 0x1 0x20
  write 0x910c 0x1 0x01
  write 0x910e 0x1 0x20
  write 0x910f 0x1 0x00
  write 0x910c 0x1 0x00
  write 0x9120 0x1 0x00
  EOF

Stack trace (part):
=
==89993==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x61529900 at pc 0x55d5f885700d bp 0x7ffc1e1e9470 sp 0x7ffc1e1e9468
WRITE of size 1 at 0x61529900 thread T0
#0 0x55d5f885700c in sdhci_write_dataport hw/sd/sdhci.c:564:39
#1 0x55d5f8849150 in sdhci_write hw/sd/sdhci.c:1223:13
#2 0x55d5fa01db63 in memory_region_write_accessor system/memory.c:497:5
#3 0x55d5fa01d245 in access_with_adjusted_size system/memory.c:573:18
#4 0x55d5fa01b1a9 in memory_region_dispatch_write system/memory.c:1521:16
#5 0x55d5fa09f5c9 in flatview_write_continue system/physmem.c:2711:23
#6 0x55d5fa08f78b in flatview_write system/physmem.c:2753:12
#7 0x55d5fa08f258 in address_space_write system/physmem.c:2860:18
...
0x61529900 is located 0 bytes to the right of 512-byte region
[0x61529700,0x61529900) allocated by thread T0 here:
#0 0x55d5f7237b27 in __interceptor_calloc
#1 0x7f9e36dd4c50 in g_malloc0
#2 0x55d5f88672f7 in sdhci_pci_realize hw/sd/sdhci-pci.c:36:5
#3 0x55d5f844b582 in pci_qdev_realize hw/pci/pci.c:2092:9
#4 0x55d5fa2ee74b in device_set_realized hw/core/qdev.c:510:13
#5 0x55d5fa325bfb in property_set_bool qom/object.c:2358:5
#6 0x55d5fa31ea45 in object_property_set qom/object.c:1472:5
#7 0x55d5fa332509 in object_property_set_qobject om/qom-qobject.c:28:10
#8 0x55d5fa31f6ed in object_property_set_bool qom/object.c:1541:15
#9 0x55d5fa2e2948 in qdev_realize hw/core/qdev.c:292:12
#10 0x55d5f8eed3f1 in qdev_device_add_from_qdict 
system/qdev-monitor.c:719:10
#11 0x55d5f8eef7ff in qdev_device_add system/qdev-monitor.c:738:11
#12 0x55d5f8f211f0 in device_init_func system/vl.c:1200:11
#13 0x55d5fad0877d in qemu_opts_foreach util/qemu-option.c:1135:14
#14 0x55d5f8f0df9c in qemu_create_cli_devices system/vl.c:2638:5
#15 0x55d5f8f0db24 in qmp_x_exit_preconfig system/vl.c:2706:5
#16 0x55d5f8f14dc0 in qemu_init system/vl.c:3737:9
...
SUMMARY: AddressSanitizer: heap-buffer-overflow hw/sd/sdhci.c:564:39
in sdhci_write_dataport

Add assertions to ensure the fifo_buffer[] is not overflowed by
malicious accesses to the Buffer Data Port register.

Fixes: CVE-2024-3447
Cc: qemu-sta...@nongnu.org
Fixes: d7dfca0807 ("hw/sdhci: introduce standard SD host controller")
Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58813
Reported-by: Alexander Bulekov 
Reported-by: Chuhong Yuan 
Signed-off-by: Peter Maydell 
Message-Id: 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409145524.27913-1-phi...@linaro.org>
(cherry picked from commit 9e4b27ca6bf4974f169bbca7f3dca117b1208b6f)
Signed-off-by: Michael Tokarev 

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index ef60badc6b..abd503d168 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -473,6 +473,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned 
size)
 }
 
 for (i = 0; i < size; i++) {
+assert(s->data_count < s->buf_maxsz);
 value |= s->fifo_buffer[s->data_count] << i * 8;
 s->data_count++;
 /* check if we've read all valid data (blksize bytes) from buffer */
@@ -561,6 +562,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t 
value, unsigned size)
 }
 
 for (i = 0; i < size; i++) {
+assert(s->data_count < s->buf_maxsz);
 s->fifo_buffer[s->data_count] = value & 0xFF;
 s->data_count++;
 value >>= 8;
@@ -1208,6 +1210,12 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, 
unsigned size)
 if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) {

[Stable-7.2.11 52/59] hw/misc/applesmc: Fix memory leak in reset() handler

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

AppleSMCData is allocated with g_new0() in applesmc_add_key():
release it with g_free().

Leaked since commit 1ddda5cd36 ("AppleSMC device emulation").

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2272
Reported-by: Zheyu Ma 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20240408095217.57239-3-phi...@linaro.org>
(cherry picked from commit fc09ff2979defdcf8d00c2db94022d5d610e36ba)
Signed-off-by: Michael Tokarev 

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 5f9c742e50..80642efc57 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -273,6 +273,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
 /* Remove existing entries */
 QLIST_FOREACH_SAFE(d, >data_def, node, next) {
 QLIST_REMOVE(d, node);
+g_free(d);
 }
 s->status = 0x00;
 s->status_1e = 0x00;
-- 
2.39.2




[Stable-7.2.11 49/59] hw/block/nand: Factor nand_load_iolen() method out

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Reviewed-by: Richard Henderson 
Reviewed-by: Kevin Wolf 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409135944.24997-2-phi...@linaro.org>
(cherry picked from commit 7a86544f286d8af4fa5251101c1026ddae92cc3d)
Signed-off-by: Michael Tokarev 

diff --git a/hw/block/nand.c b/hw/block/nand.c
index 1aee1cb2b1..4e3d7fb065 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -243,9 +243,28 @@ static inline void nand_pushio_byte(NANDFlashState *s, 
uint8_t value)
 }
 }
 
+/*
+ * nand_load_block: Load block containing (s->addr + @offset).
+ * Returns length of data available at @offset in this block.
+ */
+static unsigned nand_load_block(NANDFlashState *s, unsigned offset)
+{
+unsigned iolen;
+
+s->blk_load(s, s->addr, offset);
+
+iolen = (1 << s->page_shift);
+if (s->gnd) {
+iolen += 1 << s->oob_shift;
+}
+assert(offset <= iolen);
+iolen -= offset;
+
+return iolen;
+}
+
 static void nand_command(NANDFlashState *s)
 {
-unsigned int offset;
 switch (s->cmd) {
 case NAND_CMD_READ0:
 s->iolen = 0;
@@ -271,12 +290,7 @@ static void nand_command(NANDFlashState *s)
 case NAND_CMD_NOSERIALREAD2:
 if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))
 break;
-offset = s->addr & ((1 << s->addr_shift) - 1);
-s->blk_load(s, s->addr, offset);
-if (s->gnd)
-s->iolen = (1 << s->page_shift) - offset;
-else
-s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
+s->iolen = nand_load_block(s, s->addr & ((1 << s->addr_shift) - 1));
 break;
 
 case NAND_CMD_RESET:
@@ -597,12 +611,7 @@ uint32_t nand_getio(DeviceState *dev)
 if (!s->iolen && s->cmd == NAND_CMD_READ0) {
 offset = (int) (s->addr & ((1 << s->addr_shift) - 1)) + s->offset;
 s->offset = 0;
-
-s->blk_load(s, s->addr, offset);
-if (s->gnd)
-s->iolen = (1 << s->page_shift) - offset;
-else
-s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
+s->iolen = nand_load_block(s, offset);
 }
 
 if (s->ce || s->iolen <= 0) {
-- 
2.39.2




[Stable-7.2.11 54/59] hw/net/lan9118: Fix overflow in MIL TX FIFO

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

When the MAC Interface Layer (MIL) transmit FIFO is full,
truncate the packet, and raise the Transmitter Error (TXE)
flag.

Broken since model introduction in commit 2a42499017
("LAN9118 emulation").

When using the reproducer from
https://gitlab.com/qemu-project/qemu/-/issues/2267 we get:

  hw/net/lan9118.c:798:17: runtime error:
  index 2048 out of bounds for type 'uint8_t[2048]' (aka 'unsigned char[2048]')
    #0 0x563ec9a057b1 in tx_fifo_push hw/net/lan9118.c:798:43
    #1 0x563ec99fbb28 in lan9118_writel hw/net/lan9118.c:1042:9
    #2 0x563ec99f2de2 in lan9118_16bit_mode_write hw/net/lan9118.c:1205:9
    #3 0x563ecbf78013 in memory_region_write_accessor system/memory.c:497:5
    #4 0x563ecbf776f5 in access_with_adjusted_size system/memory.c:573:18
    #5 0x563ecbf75643 in memory_region_dispatch_write system/memory.c:1521:16
    #6 0x563ecc01bade in flatview_write_continue_step system/physmem.c:2713:18
    #7 0x563ecc01b374 in flatview_write_continue system/physmem.c:2743:19
    #8 0x563ecbff1c9b in flatview_write system/physmem.c:2774:12
    #9 0x563ecbff1768 in address_space_write system/physmem.c:2894:18
...

[*] LAN9118 DS2266B.pdf, Table 5.3.3 "INTERRUPT STATUS REGISTER"

Cc: qemu-sta...@nongnu.org
Reported-by: Will Lester
Reported-by: Chuhong Yuan 
Suggested-by: Peter Maydell 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2267
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20240409133801.23503-3-phi...@linaro.org>
(cherry picked from commit ad766d603f39888309cfb1433ba2de1d0e9e4f58)
Signed-off-by: Michael Tokarev 

diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index 00a6d82efb..bf81c84984 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -798,8 +798,22 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
 /* Documentation is somewhat unclear on the ordering of bytes
in FIFO words.  Empirical results show it to be little-endian.
*/
-/* TODO: FIFO overflow checking.  */
 while (n--) {
+if (s->txp->len == MIL_TXFIFO_SIZE) {
+/*
+ * No more space in the FIFO. The datasheet is not
+ * precise about this case. We choose what is easiest
+ * to model: the packet is truncated, and TXE is raised.
+ *
+ * Note, it could be a fragmented packet, but we currently
+ * do not handle that (see earlier TX_B case).
+ */
+qemu_log_mask(LOG_GUEST_ERROR,
+  "MIL TX FIFO overrun, discarding %u 
byte%s\n",
+  n, n > 1 ? "s" : "");
+s->int_sts |= TXE_INT;
+break;
+}
 s->txp->data[s->txp->len] = val & 0xff;
 s->txp->len++;
 val >>= 8;
-- 
2.39.2




[Stable-7.2.11 57/59] target/sh4: add missing CHECK_NOT_DELAY_SLOT

2024-04-18 Thread Michael Tokarev
From: Zack Buhman 

CHECK_NOT_DELAY_SLOT is correctly applied to the branch-related
instructions, but not to the PC-relative mov* instructions.

I verified the existence of an illegal slot exception on a SH7091 when
any of these instructions are attempted inside a delay slot.

This also matches the behavior described in the SH-4 ISA manual.

Signed-off-by: Zack Buhman 
Reviewed-by: Richard Henderson 
Message-Id: <20240407150705.5965-1-z...@buhman.org>
Signed-off-by: Richard Henderson 
Reviewd-by: Yoshinori Sato 
(cherry picked from commit b754cb2dcde26a7bc8a9d17bb6900a0ac0dd38e2)
Signed-off-by: Michael Tokarev 
(Mjt: trivial context (whitespace before comments) fixup)

diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index 7db3468b01..8d6eae7ddf 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -528,6 +528,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_gen_movi_i32(REG(B11_8), B7_0s);
return;
 case 0x9000:   /* mov.w @(disp,PC),Rn */
+CHECK_NOT_DELAY_SLOT
{
 TCGv addr = tcg_const_i32(ctx->base.pc_next + 4 + B7_0 * 2);
 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
@@ -535,6 +536,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
 case 0xd000:   /* mov.l @(disp,PC),Rn */
+CHECK_NOT_DELAY_SLOT
{
 TCGv addr = tcg_const_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3);
 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
@@ -1295,6 +1297,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
 case 0xc700:   /* mova @(disp,PC),R0 */
+CHECK_NOT_DELAY_SLOT
 tcg_gen_movi_i32(REG(0), ((ctx->base.pc_next & 0xfffc) +
   4 + B7_0 * 4) & ~3);
return;
-- 
2.39.2




[Stable-7.2.11 48/59] qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo

2024-04-18 Thread Michael Tokarev
From: Yuquan Wang 

Fix the unit typo of interleave-granularity of CXL Fixed Memory
Window in qemu-option.hx.

Fixes: 03b39fcf64 ("hw/cxl: Make the CFMW a machine parameter.")
Signed-off-by: Yuquan Wang wangyuquan1...@phytium.com.cn
Message-ID: <20240407083539.1488172-2-wangyuquan1...@phytium.com.cn>
[PMD: Reworded]
Signed-off-by: Philippe Mathieu-Daudé 
(cherry picked from commit aa88f99c87c0e5d195d6d96190374650553ea61f)
Signed-off-by: Michael Tokarev 

diff --git a/qemu-options.hx b/qemu-options.hx
index 7f798ce47e..2c00ceac83 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -149,14 +149,14 @@ SRST
 platform and configuration dependent.
 
 ``interleave-granularity=granularity`` sets the granularity of
-interleave. Default 256KiB. Only 256KiB, 512KiB, 1024KiB, 2048KiB
-4096KiB, 8192KiB and 16384KiB granularities supported.
+interleave. Default 256 (bytes). Only 256, 512, 1k, 2k,
+4k, 8k and 16k granularities supported.
 
 Example:
 
 ::
 
--machine 
cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512k
+-machine 
cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512
 ERST
 
 DEF("M", HAS_ARG, QEMU_OPTION_M,
-- 
2.39.2




[Stable-7.2.11 53/59] backends/cryptodev: Do not abort for invalid session ID

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Instead of aborting when a session ID is invalid,
return VIRTIO_CRYPTO_INVSESS ("Invalid session id").

Reproduced using:

  $ cat << EOF | qemu-system-i386 -display none \
 -machine q35,accel=qtest -m 512M -nodefaults \
 -object cryptodev-backend-builtin,id=cryptodev0 \
 -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
 -qtest stdio
  outl 0xcf8 0x8804
  outw 0xcfc 0x06
  outl 0xcf8 0x8820
  outl 0xcfc 0xe0008000
  write 0x10800e 0x1 0x01
  write 0xe0008016 0x1 0x01
  write 0xe0008020 0x4 0x00801000
  write 0xe0008028 0x4 0x00c01000
  write 0xe000801c 0x1 0x01
  write 0x11 0x1 0x05
  write 0x110001 0x1 0x04
  write 0x108002 0x1 0x11
  write 0x108008 0x1 0x48
  write 0x10800c 0x1 0x01
  write 0x108018 0x1 0x10
  write 0x10801c 0x1 0x02
  write 0x10c002 0x1 0x01
  write 0xe000b005 0x1 0x00
  EOF
  Assertion failed: (session_id < MAX_NUM_SESSIONS && 
builtin->sessions[session_id]),
  function cryptodev_builtin_close_session, file cryptodev-builtin.c, line 430.

Cc: qemu-sta...@nongnu.org
Reported-by: Zheyu Ma 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2274
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: zhenwei pi 
Message-Id: <20240409094757.9127-1-phi...@linaro.org>
(cherry picked from commit eaf2bd29538d039df80bb4b1584de33a61312bc6)
Signed-off-by: Michael Tokarev 

diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
index cda6ca3b71..2e792be756 100644
--- a/backends/cryptodev-builtin.c
+++ b/backends/cryptodev-builtin.c
@@ -416,7 +416,9 @@ static int cryptodev_builtin_close_session(
   CRYPTODEV_BACKEND_BUILTIN(backend);
 CryptoDevBackendBuiltinSession *session;
 
-assert(session_id < MAX_NUM_SESSIONS && builtin->sessions[session_id]);
+if (session_id >= MAX_NUM_SESSIONS || !builtin->sessions[session_id]) {
+return -VIRTIO_CRYPTO_INVSESS;
+}
 
 session = builtin->sessions[session_id];
 if (session->cipher) {
-- 
2.39.2




[Stable-7.2.11 51/59] hw/block/nand: Fix out-of-bound access in NAND block buffer

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

nand_command() and nand_getio() don't check @offset points
into the block, nor the available data length (s->iolen) is
not negative.

In order to fix:

- check the offset is in range in nand_blk_load_NAND_PAGE_SIZE(),
- do not set @iolen if blk_load() failed.

Reproducer:

  $ cat << EOF | qemu-system-arm -machine tosa \
 -monitor none -serial none \
 -display none -qtest stdio
  write 0x1111 0x1 0xca
  write 0x1104 0x1 0x47
  write 0x1000ca04 0x1 0xd7
  write 0x1000ca01 0x1 0xe0
  write 0x1000ca04 0x1 0x71
  write 0x1000ca00 0x1 0x50
  write 0x1000ca04 0x1 0xd7
  read 0x1000ca02 0x1
  write 0x1000ca01 0x1 0x10
  EOF

=
==15750==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61f00de0
 at pc 0x560e61557210 bp 0x7ffcfc4a59f0 sp 0x7ffcfc4a59e8
READ of size 1 at 0x61f00de0 thread T0
#0 0x560e6155720f in mem_and hw/block/nand.c:101:20
#1 0x560e6155ac9c in nand_blk_write_512 hw/block/nand.c:663:9
#2 0x560e61544200 in nand_command hw/block/nand.c:293:13
#3 0x560e6153cc83 in nand_setio hw/block/nand.c:520:13
#4 0x560e61a0a69e in tc6393xb_nand_writeb hw/display/tc6393xb.c:380:13
#5 0x560e619f9bf7 in tc6393xb_writeb hw/display/tc6393xb.c:524:9
#6 0x560e647c7d03 in memory_region_write_accessor softmmu/memory.c:492:5
#7 0x560e647c7641 in access_with_adjusted_size softmmu/memory.c:554:18
#8 0x560e647c5f66 in memory_region_dispatch_write softmmu/memory.c:1514:16
#9 0x560e6485409e in flatview_write_continue softmmu/physmem.c:2825:23
#10 0x560e648421eb in flatview_write softmmu/physmem.c:2867:12
#11 0x560e64841ca8 in address_space_write softmmu/physmem.c:2963:18
#12 0x560e61170162 in qemu_writeb tests/qtest/videzzo/videzzo_qemu.c:1080:5
#13 0x560e6116eef7 in dispatch_mmio_write 
tests/qtest/videzzo/videzzo_qemu.c:1227:28

0x61f00de0 is located 0 bytes to the right of 3424-byte region 
[0x61f00080,0x61f00de0)
allocated by thread T0 here:
#0 0x560e611276cf in malloc 
/root/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7f7959a87e98 in g_malloc 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x57e98)
#2 0x560e64b98871 in object_new qom/object.c:749:12
#3 0x560e64b5d1a1 in qdev_new hw/core/qdev.c:153:19
#4 0x560e61547ea5 in nand_init hw/block/nand.c:639:11
#5 0x560e619f8772 in tc6393xb_init hw/display/tc6393xb.c:558:16
#6 0x560e6390bad2 in tosa_init hw/arm/tosa.c:250:12

SUMMARY: AddressSanitizer: heap-buffer-overflow hw/block/nand.c:101:20 in 
mem_and
==15750==ABORTING

Broken since introduction in commit 3e3d5815cb ("NAND Flash memory
emulation and ECC calculation helpers for use by NAND controllers").

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1445
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1446
Reported-by: Qiang Liu 
Reviewed-by: Richard Henderson 
Reviewed-by: Kevin Wolf 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409135944.24997-4-phi...@linaro.org>
(cherry picked from commit d39fdfff348fdf00173b7a58e935328a64db7d28)
Signed-off-by: Michael Tokarev 

diff --git a/hw/block/nand.c b/hw/block/nand.c
index 81b2bb804d..d994bfe372 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -255,7 +255,9 @@ static unsigned nand_load_block(NANDFlashState *s, unsigned 
offset)
 {
 unsigned iolen;
 
-s->blk_load(s, s->addr, offset);
+if (!s->blk_load(s, s->addr, offset)) {
+return 0;
+}
 
 iolen = (1 << s->page_shift);
 if (s->gnd) {
@@ -783,6 +785,10 @@ static bool glue(nand_blk_load_, 
NAND_PAGE_SIZE)(NANDFlashState *s,
 return false;
 }
 
+if (offset > NAND_PAGE_SIZE + OOB_SIZE) {
+return false;
+}
+
 if (s->blk) {
 if (s->mem_oob) {
 if (blk_pread(s->blk, SECTOR(addr) << BDRV_SECTOR_BITS,
-- 
2.39.2




[Stable-7.2.11 58/59] ppc/spapr: Introduce SPAPR_IRQ_NR_IPIS to refer IRQ range for CPU IPIs.

2024-04-18 Thread Michael Tokarev
From: Harsh Prateek Bora 

spapr_irq_init currently uses existing macro SPAPR_XIRQ_BASE to refer to
the range of CPU IPIs during initialization of nr-irqs property.
It is more appropriate to have its own define which can be further
reused as appropriate for correct interpretation.

Suggested-by: Cedric Le Goater 
Reviewed-by: Cédric Le Goater 
Tested-by: Kowshik Jois 
Signed-off-by: Harsh Prateek Bora 
Signed-off-by: Nicholas Piggin 
(cherry picked from commit 2df5c1f5b014126595a26c6797089d284a3b211c)
Signed-off-by: Michael Tokarev 

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index a0d1e1298e..97b2fc42ab 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -23,6 +23,8 @@
 
 #include "trace.h"
 
+QEMU_BUILD_BUG_ON(SPAPR_IRQ_NR_IPIS > SPAPR_XIRQ_BASE);
+
 static const TypeInfo spapr_intc_info = {
 .name = TYPE_SPAPR_INTC,
 .parent = TYPE_INTERFACE,
@@ -329,7 +331,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 int i;
 
 dev = qdev_new(TYPE_SPAPR_XIVE);
-qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
+qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + 
SPAPR_IRQ_NR_IPIS);
 /*
  * 8 XIVE END structures per CPU. One for each available
  * priority
@@ -356,7 +358,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 }
 
 spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
-  smc->nr_xirqs + SPAPR_XIRQ_BASE);
+  smc->nr_xirqs + SPAPR_IRQ_NR_IPIS);
 
 /*
  * Mostly we don't actually need this until reset, except that not
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index c22a72c9e2..4fd2d5853d 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -14,9 +14,21 @@
 #include "qom/object.h"
 
 /*
- * IRQ range offsets per device type
+ * The XIVE IRQ backend uses the same layout as the XICS backend but
+ * covers the full range of the IRQ number space. The IRQ numbers for
+ * the CPU IPIs are allocated at the bottom of this space, below 4K,
+ * to preserve compatibility with XICS which does not use that range.
+ */
+
+/*
+ * CPU IPI range (XIVE only)
  */
 #define SPAPR_IRQ_IPI0x0
+#define SPAPR_IRQ_NR_IPIS0x1000
+
+/*
+ * IRQ range offsets per device type
+ */
 
 #define SPAPR_XIRQ_BASE  XICS_IRQ_BASE /* 0x1000 */
 #define SPAPR_IRQ_EPOW   (SPAPR_XIRQ_BASE + 0x)
-- 
2.39.2




[Stable-7.2.11 42/59] tcg/optimize: Do not attempt to constant fold neg_vec

2024-04-18 Thread Michael Tokarev
From: Richard Henderson 

Split out the tail of fold_neg to fold_neg_no_const so that we
can avoid attempting to constant fold vector negate.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2150
Signed-off-by: Richard Henderson 
(cherry picked from commit e25fe886b89a396bae5847520b70c148587d490a)
Signed-off-by: Michael Tokarev 
(Mjt: context fixup in tests/tcg/aarch64/Makefile.target)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index b6f6436c74..100b75efd8 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -1634,16 +1634,10 @@ static bool fold_nand(OptContext *ctx, TCGOp *op)
 return false;
 }
 
-static bool fold_neg(OptContext *ctx, TCGOp *op)
+static bool fold_neg_no_const(OptContext *ctx, TCGOp *op)
 {
-uint64_t z_mask;
-
-if (fold_const1(ctx, op)) {
-return true;
-}
-
 /* Set to 1 all bits to the left of the rightmost.  */
-z_mask = arg_info(op->args[1])->z_mask;
+uint64_t z_mask = arg_info(op->args[1])->z_mask;
 ctx->z_mask = -(z_mask & -z_mask);
 
 /*
@@ -1654,6 +1648,11 @@ static bool fold_neg(OptContext *ctx, TCGOp *op)
 return true;
 }
 
+static bool fold_neg(OptContext *ctx, TCGOp *op)
+{
+return fold_const1(ctx, op) || fold_neg_no_const(ctx, op);
+}
+
 static bool fold_nor(OptContext *ctx, TCGOp *op)
 {
 if (fold_const2_commutative(ctx, op) ||
@@ -1949,7 +1948,7 @@ static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op)
 if (have_neg) {
 op->opc = neg_op;
 op->args[1] = op->args[2];
-return fold_neg(ctx, op);
+return fold_neg_no_const(ctx, op);
 }
 return false;
 }
diff --git a/tests/tcg/aarch64/Makefile.target 
b/tests/tcg/aarch64/Makefile.target
index 474f61bc30..bd29446835 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -10,7 +10,7 @@ VPATH += $(AARCH64_SRC)
 
 # Base architecture tests
 AARCH64_TESTS=fcvt pcalign-a64
-AARCH64_TESTS += test-2248
+AARCH64_TESTS += test-2248 test-2150
 
 fcvt: LDFLAGS+=-lm
 
diff --git a/tests/tcg/aarch64/test-2150.c b/tests/tcg/aarch64/test-2150.c
new file mode 100644
index 00..fb86c11958
--- /dev/null
+++ b/tests/tcg/aarch64/test-2150.c
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* See https://gitlab.com/qemu-project/qemu/-/issues/2150 */
+
+int main()
+{
+asm volatile(
+"movi v6.4s, #1\n"
+"movi v7.4s, #0\n"
+"sub  v6.2d, v7.2d, v6.2d\n"
+: : : "v6", "v7");
+return 0;
+}
-- 
2.39.2




[Stable-7.2.11 44/59] hw/virtio: Introduce virtio_bh_new_guarded() helper

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded()
but using the transport memory guard, instead of the device one
(there can only be one virtio device per virtio bus).

Inspired-by: Gerd Hoffmann 
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-2-phi...@linaro.org>
(cherry picked from commit ec0504b989ca61e03636384d3602b7bf07ffe4da)
Signed-off-by: Michael Tokarev 
(Mjt: trivial #include context fixup in include/hw/virtio/virtio.h)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index e4f8ed1e63..4a35d7cb0c 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -5029,3 +5029,13 @@ static void virtio_register_types(void)
 }
 
 type_init(virtio_register_types)
+
+QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+   QEMUBHFunc *cb, void *opaque,
+   const char *name)
+{
+DeviceState *transport = qdev_get_parent_bus(dev)->parent;
+
+return qemu_bh_new_full(cb, opaque, name,
+>mem_reentrancy_guard);
+}
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 96a56430a6..c1a7c9bd3b 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -23,6 +23,7 @@
 #include "standard-headers/linux/virtio_ring.h"
 #include "qom/object.h"
 #include "hw/virtio/vhost.h"
+#include "block/aio.h"
 
 /*
  * A guest should never accept this. It implies negotiation is broken
@@ -463,4 +464,10 @@ static inline bool virtio_device_disabled(VirtIODevice 
*vdev)
 bool virtio_legacy_allowed(VirtIODevice *vdev);
 bool virtio_legacy_check_disabled(VirtIODevice *vdev);
 
+QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+   QEMUBHFunc *cb, void *opaque,
+   const char *name);
+#define virtio_bh_new_guarded(dev, cb, opaque) \
+virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb)))
+
 #endif
-- 
2.39.2




[Stable-7.2.11 55/59] hw/net/lan9118: Replace magic '2048' value by MIL_TXFIFO_SIZE definition

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

The magic 2048 is explained in the LAN9211 datasheet (DS2414A)
in chapter 1.4, "10/100 Ethernet MAC":

  The MAC Interface Layer (MIL), within the MAC, contains a
  2K Byte transmit and a 128 Byte receive FIFO which is separate
  from the TX and RX FIFOs. [...]

Note, the use of the constant in lan9118_receive() reveals that
our implementation is using the same buffer for both tx and rx.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20240409133801.23503-2-phi...@linaro.org>
(cherry picked from commit a45223467e4e185fff1c76a6483784fa379ded77)
Signed-off-by: Michael Tokarev 

diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index bf81c84984..f269d72d9e 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -155,6 +155,12 @@ do { fprintf(stderr, "lan9118: error: " fmt , ## 
__VA_ARGS__);} while (0)
 
 #define GPT_TIMER_EN0x2000
 
+/*
+ * The MAC Interface Layer (MIL), within the MAC, contains a 2K Byte transmit
+ * and a 128 Byte receive FIFO which is separate from the TX and RX FIFOs.
+ */
+#define MIL_TXFIFO_SIZE 2048
+
 enum tx_state {
 TX_IDLE,
 TX_B,
@@ -171,7 +177,7 @@ typedef struct {
 int32_t pad;
 int32_t fifo_used;
 int32_t len;
-uint8_t data[2048];
+uint8_t data[MIL_TXFIFO_SIZE];
 } LAN9118Packet;
 
 static const VMStateDescription vmstate_lan9118_packet = {
@@ -187,7 +193,7 @@ static const VMStateDescription vmstate_lan9118_packet = {
 VMSTATE_INT32(pad, LAN9118Packet),
 VMSTATE_INT32(fifo_used, LAN9118Packet),
 VMSTATE_INT32(len, LAN9118Packet),
-VMSTATE_UINT8_ARRAY(data, LAN9118Packet, 2048),
+VMSTATE_UINT8_ARRAY(data, LAN9118Packet, MIL_TXFIFO_SIZE),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -549,7 +555,7 @@ static ssize_t lan9118_receive(NetClientState *nc, const 
uint8_t *buf,
 return -1;
 }
 
-if (size >= 2048 || size < 14) {
+if (size >= MIL_TXFIFO_SIZE || size < 14) {
 return -1;
 }
 
-- 
2.39.2




[Stable-7.2.11 59/59] ppc/spapr: Initialize max_cpus limit to SPAPR_IRQ_NR_IPIS.

2024-04-18 Thread Michael Tokarev
From: Harsh Prateek Bora 

Initialize the machine specific max_cpus limit as per the maximum range
of CPU IPIs available. Keeping between 4096 to 8192 will throw IRQ not
free error due to XIVE/XICS limitation and keeping beyond 8192 will hit
assert in tcg_region_init or spapr_xive_claim_irq.

Logs:

Without patch fix:

[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=4097
qemu-system-ppc64: IRQ 4096 is not free
[root@host build]#

On LPAR:
[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=8193
**
ERROR:../tcg/region.c:774:tcg_region_init: assertion failed:
(region_size >= 2 * page_size)
Bail out! ERROR:../tcg/region.c:774:tcg_region_init: assertion failed:
(region_size >= 2 * page_size)
Aborted (core dumped)
[root@host build]#

On x86:
[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=8193
qemu-system-ppc64: ../hw/intc/spapr_xive.c:596: spapr_xive_claim_irq:
Assertion `lisn < xive->nr_irqs' failed.
Aborted (core dumped)
[root@host build]#

With patch fix:
[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=4097
qemu-system-ppc64: Invalid SMP CPUs 4097. The max CPUs supported by
machine 'pseries-8.2' is 4096
[root@host build]#

Reported-by: Kowshik Jois 
Tested-by: Kowshik Jois 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
Signed-off-by: Nicholas Piggin 
(cherry picked from commit c4f91d7b7be76c47015521ab0109c6e998a369b0)
Signed-off-by: Michael Tokarev 

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 66b414d2e9..9e860f5047 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4602,13 +4602,10 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 mc->block_default_type = IF_SCSI;
 
 /*
- * Setting max_cpus to INT32_MAX. Both KVM and TCG max_cpus values
- * should be limited by the host capability instead of hardcoded.
- * max_cpus for KVM guests will be checked in kvm_init(), and TCG
- * guests are welcome to have as many CPUs as the host are capable
- * of emulate.
+ * While KVM determines max cpus in kvm_init() using kvm_max_vcpus(),
+ * In TCG the limit is restricted by the range of CPU IPIs available.
  */
-mc->max_cpus = INT32_MAX;
+mc->max_cpus = SPAPR_IRQ_NR_IPIS;
 
 mc->no_parallel = 1;
 mc->default_boot_order = "";
-- 
2.39.2




[Stable-7.2.11 46/59] hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.

Fixes: CVE-2024-3446
Cc: qemu-sta...@nongnu.org
Suggested-by: Alexander Bulekov 
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-4-phi...@linaro.org>
(cherry picked from commit b4295bff25f7b50de1d9cc94a9c6effd40056bca)
Signed-off-by: Michael Tokarev 

diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index dd619f0731..1221fb7f15 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -985,8 +985,7 @@ static void virtser_port_device_realize(DeviceState *dev, 
Error **errp)
 return;
 }
 
-port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port,
-   >mem_reentrancy_guard);
+port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port);
 port->elem = NULL;
 }
 
-- 
2.39.2




[Stable-7.2.11 43/59] linux-user: Fix waitid return of siginfo_t and rusage

2024-04-18 Thread Michael Tokarev
From: Richard Henderson 

The copy back to siginfo_t should be conditional only on arg3,
not the specific values that might have been written.
The copy back to rusage was missing entirely.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2262
Signed-off-by: Richard Henderson 
Tested-by: Alex Fan 
Reviewed-by: Philippe Mathieu-Daudé 
(cherry picked from commit f0907ff4cae743f1a4ef3d0a55a047029eed06ff)
Signed-off-by: Michael Tokarev 

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index aead0f6ac9..41017b0df2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8759,14 +8759,24 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 #ifdef TARGET_NR_waitid
 case TARGET_NR_waitid:
 {
+struct rusage ru;
 siginfo_t info;
-info.si_pid = 0;
-ret = get_errno(safe_waitid(arg1, arg2, , arg4, NULL));
-if (!is_error(ret) && arg3 && info.si_pid != 0) {
-if (!(p = lock_user(VERIFY_WRITE, arg3, 
sizeof(target_siginfo_t), 0)))
+
+ret = get_errno(safe_waitid(arg1, arg2, (arg3 ?  : NULL),
+arg4, (arg5 ?  : NULL)));
+if (!is_error(ret)) {
+if (arg3) {
+p = lock_user(VERIFY_WRITE, arg3,
+  sizeof(target_siginfo_t), 0);
+if (!p) {
+return -TARGET_EFAULT;
+}
+host_to_target_siginfo(p, );
+unlock_user(p, arg3, sizeof(target_siginfo_t));
+}
+if (arg5 && host_to_target_rusage(arg5, )) {
 return -TARGET_EFAULT;
-host_to_target_siginfo(p, );
-unlock_user(p, arg3, sizeof(target_siginfo_t));
+}
 }
 }
 return ret;
-- 
2.39.2




[Stable-7.2.11 47/59] hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.

Fixes: CVE-2024-3446
Cc: qemu-sta...@nongnu.org
Suggested-by: Alexander Bulekov 
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-5-phi...@linaro.org>
(cherry picked from commit f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc)
Signed-off-by: Michael Tokarev 

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index b2e0646d9a..ce995c66d8 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -1057,8 +1057,8 @@ static void virtio_crypto_device_realize(DeviceState 
*dev, Error **errp)
 vcrypto->vqs[i].dataq =
  virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
 vcrypto->vqs[i].dataq_bh =
- qemu_bh_new_guarded(virtio_crypto_dataq_bh, >vqs[i],
- >mem_reentrancy_guard);
+ virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh,
+   >vqs[i]);
 vcrypto->vqs[i].vcrypto = vcrypto;
 }
 
-- 
2.39.2




[Stable-7.2.11 v2 00/59] Patch Round-up for stable 7.2.11, freeze on 2024-04-20

2024-04-18 Thread Michael Tokarev
The following patches are queued for QEMU stable v7.2.11:

  https://gitlab.com/qemu-project/qemu/-/commits/staging-7.2

Patch freeze is 2024-04-20, and the release is planned for 2024-04-22:

  https://wiki.qemu.org/Planning/7.2

Please respond here or CC qemu-sta...@nongnu.org on any additional patches
you think should (or shouldn't) be included in the release.

The changes which are staging for inclusion, with the original commit hash
from master branch, are given below the bottom line.

Thanks!

/mjt

--
01* 9ea920dc2825 Daniel P. Berrangé:
   gitlab: update FreeBSD Cirrus CI image to 13.3
02* f5af80271aad David Parsons:
   ui/cocoa: Fix window clipping on macOS 14
03* bc6bd20ee353 Zhuojia Shen:
   target/arm: align exposed ID registers with Linux
04* 3dc2afeab296 Peter Maydell:
   tests/tcg/aarch64/sysregs.c: Use S syntax for id_aa64zfr0_el1 and 
   id_aa64smfr0_el1
05* 1f51573f7925 Richard Henderson:
   target/arm: Fix SME full tile indexing
06* fd7f95f23d6f Peter Maydell:
   hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
07* 012b170173bc Dmitrii Gavrilov:
   system/qdev-monitor: move drain_call_rcu call under if (!dev) in 
   qmp_device_add()
08* a9198b3132d8 Sven Schnelle:
   hw/scsi/lsi53c895a: stop script on phase mismatch
09* 8b09b7fe4708 Sven Schnelle:
   hw/scsi/lsi53c895a: add missing decrement of reentrancy counter
10* 9876359990dd Sven Schnelle:
   hw/scsi/lsi53c895a: add timer to scripts processing
11* 9bc9e9511944 Michael Tokarev:
   make-release: switch to .xz format by default
12* 4cadf1023498 Laurent Vivier:
   e1000e: fix link state on resume
13* 6a5287ce8047 Nick Briggs:
   Avoid unaligned fetch in ladr_match()
14* 784fd35387e9 Klaus Jensen:
   hw/nvme: clean up confusing use of errp/local_err
15* 973f76cf7743 Klaus Jensen:
   hw/nvme: cleanup error reporting in nvme_init_pci()
16* 4f0a4a3d5854 Minwoo Im:
   hw/nvme: separate 'serial' property for VFs
17* ee7bda4d38cd Klaus Jensen:
   hw/nvme: generalize the mbar size helper
18* fa905f65c554 Klaus Jensen:
   hw/nvme: add machine compatibility parameter to enable msix exclusive bar
19* 31180dbdca28 Akihiko Odaki:
   pcie: Introduce pcie_sriov_num_vfs
20* 91bb64a8d201 Akihiko Odaki:
   hw/nvme: Use pcie_sriov_num_vfs()
21* 6081b4243cd6 Akihiko Odaki:
   pcie_sriov: Validate NumVFs
22* 74e2845c5f95 Jonathan Cameron:
   hmat acpi: Fix out of bounds access due to missing use of indirection
23* 2e128776dc56 Cédric Le Goater:
   migration: Skip only empty block devices
24* c45f8f1aef35 Thomas Huth:
   tests/unit: Bump test-aio-multithread test timeout to 2 minutes
25* e1b363e328d5 Thomas Huth:
   tests/unit: Bump test-crypto-block test timeout to 5 minutes
26* 63b18312d14a Kevin Wolf:
   tests/unit: Bump test-replication timeout to 60 seconds
27* 55f7c6a5f2bd Peter Maydell:
   tests: Raise timeouts for bufferiszero and crypto-tlscredsx509
28* 5f97afe2543f Paolo Bonzini:
   target/i386: introduce function to query MMU indices
29* 90f641531c78 Paolo Bonzini:
   target/i386: use separate MMU indexes for 32-bit accesses
30* 2cc68629a6fc Paolo Bonzini:
   target/i386: fix direction of "32-bit MMU" test
31* 7fd226b04746 Tao Su:
   target/i386: Revert monitor_puts() in do_inject_x86_mce()
32* 1590154ee437 Song Gao:
   target/loongarch: Fix qemu-system-loongarch64 assert failed with the 
   option '-d int'
33* 7c7a9f578e4f Lorenz Brun:
   hw/scsi/scsi-generic: Fix io_timeout property not applying
34* a158c63b3ba1 Yao Xingtao:
   monitor/hmp-cmds-target: Append a space in error message in gpa2hva()
35* 1c188fc8cbff Akihiko Odaki:
   virtio-net: Fix vhost virtqueue notifiers for RSS
36* 2911e9b95f3b Richard Henderson:
   tcg/optimize: Fix sign_mask for logical right-shift
37* 4a3aa11e1fb2 Richard Henderson:
   target/hppa: Clear psw_n for BE on use_nullify_skip path
38* 1d2f2b35bc86 Michael Tokarev:
   gitlab-ci/cirrus: switch from 'master' to 'latest'
39* 44e25fbc1900 Peter Maydell:
   hw/intc/arm_gicv3: ICC_HPPIR* return SPURIOUS if int group is disabled
40* 4c54f5bc8e1d Yajun Wu:
   hw/net/virtio-net: fix qemu set used ring flag even vhost started
41* 2d9a31b3c273 Wafer:
   hw/virtio: Fix packed virtqueue flush used_idx
42 e25fe886b89a Richard Henderson:
   tcg/optimize: Do not attempt to constant fold neg_vec
43 f0907ff4cae7 Richard Henderson:
   linux-user: Fix waitid return of siginfo_t and rusage
44 ec0504b989ca Philippe Mathieu-Daudé:
   hw/virtio: Introduce virtio_bh_new_guarded() helper
45 ba28e0ff4d95 Philippe Mathieu-Daudé:
   hw/display/virtio-gpu: Protect from DMA re-entrancy bugs
46 b4295bff25f7 Philippe Mathieu-Daudé:
   hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs
47 f4729ec39ad9 Philippe Mathieu-Daudé:
   hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs
48 aa88f99c87c0 Yuquan Wang:
   qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo
49 7a86544f286d Philippe Mathieu-Daudé:
   hw/block/nand: Factor nand_load_iolen() method out
50 2e3e09b3680

[Stable-8.2.3 115/116] ppc/spapr: Introduce SPAPR_IRQ_NR_IPIS to refer IRQ range for CPU IPIs.

2024-04-18 Thread Michael Tokarev
From: Harsh Prateek Bora 

spapr_irq_init currently uses existing macro SPAPR_XIRQ_BASE to refer to
the range of CPU IPIs during initialization of nr-irqs property.
It is more appropriate to have its own define which can be further
reused as appropriate for correct interpretation.

Suggested-by: Cedric Le Goater 
Reviewed-by: Cédric Le Goater 
Tested-by: Kowshik Jois 
Signed-off-by: Harsh Prateek Bora 
Signed-off-by: Nicholas Piggin 
(cherry picked from commit 2df5c1f5b014126595a26c6797089d284a3b211c)
Signed-off-by: Michael Tokarev 

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index a0d1e1298e..97b2fc42ab 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -23,6 +23,8 @@
 
 #include "trace.h"
 
+QEMU_BUILD_BUG_ON(SPAPR_IRQ_NR_IPIS > SPAPR_XIRQ_BASE);
+
 static const TypeInfo spapr_intc_info = {
 .name = TYPE_SPAPR_INTC,
 .parent = TYPE_INTERFACE,
@@ -329,7 +331,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 int i;
 
 dev = qdev_new(TYPE_SPAPR_XIVE);
-qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
+qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + 
SPAPR_IRQ_NR_IPIS);
 /*
  * 8 XIVE END structures per CPU. One for each available
  * priority
@@ -356,7 +358,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 }
 
 spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
-  smc->nr_xirqs + SPAPR_XIRQ_BASE);
+  smc->nr_xirqs + SPAPR_IRQ_NR_IPIS);
 
 /*
  * Mostly we don't actually need this until reset, except that not
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index c22a72c9e2..4fd2d5853d 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -14,9 +14,21 @@
 #include "qom/object.h"
 
 /*
- * IRQ range offsets per device type
+ * The XIVE IRQ backend uses the same layout as the XICS backend but
+ * covers the full range of the IRQ number space. The IRQ numbers for
+ * the CPU IPIs are allocated at the bottom of this space, below 4K,
+ * to preserve compatibility with XICS which does not use that range.
+ */
+
+/*
+ * CPU IPI range (XIVE only)
  */
 #define SPAPR_IRQ_IPI0x0
+#define SPAPR_IRQ_NR_IPIS0x1000
+
+/*
+ * IRQ range offsets per device type
+ */
 
 #define SPAPR_XIRQ_BASE  XICS_IRQ_BASE /* 0x1000 */
 #define SPAPR_IRQ_EPOW   (SPAPR_XIRQ_BASE + 0x)
-- 
2.39.2




[Stable-8.2.3 114/116] hw/pci-host/ppc440_pcix: Do not expose a bridge device on PCI bus

2024-04-18 Thread Michael Tokarev
From: BALATON Zoltan 

Real 460EX SoC apparently does not expose a bridge device and having
it appear on PCI bus confuses an AmigaOS file system driver that uses
this to detect which machine it is running on.

Cc: qemu-sta...@nongnu.org
Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20240411192443.b4d644e6...@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
(cherry picked from commit 6e4aceba2079e3df42edc89d44f4ee02343bb09e)
Signed-off-by: Michael Tokarev 

diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c
index df4ee374d0..0468b22080 100644
--- a/hw/ppc/ppc440_pcix.c
+++ b/hw/ppc/ppc440_pcix.c
@@ -53,7 +53,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PPC440PCIXState, PPC440_PCIX_HOST)
 struct PPC440PCIXState {
 PCIHostState parent_obj;
 
-PCIDevice *dev;
+uint8_t config[PCI_CONFIG_SPACE_SIZE];
 struct PLBOutMap pom[PPC440_PCIX_NR_POMS];
 struct PLBInMap pim[PPC440_PCIX_NR_PIMS];
 uint32_t sts;
@@ -172,7 +172,7 @@ static void ppc440_pcix_reg_write4(void *opaque, hwaddr 
addr,
 trace_ppc440_pcix_reg_write(addr, val, size);
 switch (addr) {
 case PCI_VENDOR_ID ... PCI_MAX_LAT:
-stl_le_p(s->dev->config + addr, val);
+stl_le_p(s->config + addr, val);
 break;
 
 case PCIX0_POM0LAL:
@@ -303,7 +303,7 @@ static uint64_t ppc440_pcix_reg_read4(void *opaque, hwaddr 
addr,
 
 switch (addr) {
 case PCI_VENDOR_ID ... PCI_MAX_LAT:
-val = ldl_le_p(s->dev->config + addr);
+val = ldl_le_p(s->config + addr);
 break;
 
 case PCIX0_POM0LAL:
@@ -499,10 +499,7 @@ static void ppc440_pcix_realize(DeviceState *dev, Error 
**errp)
 memory_region_init(>iomem, OBJECT(dev), "pci-io", 64 * KiB);
 h->bus = pci_register_root_bus(dev, NULL, ppc440_pcix_set_irq,
  ppc440_pcix_map_irq, >irq, >busmem, >iomem,
- PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS);
-
-s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0),
-   TYPE_PPC4xx_HOST_BRIDGE);
+ PCI_DEVFN(1, 0), 1, TYPE_PCI_BUS);
 
 memory_region_init(>bm, OBJECT(s), "bm-ppc440-pcix", UINT64_MAX);
 memory_region_add_subregion(>bm, 0x0, >busmem);
-- 
2.39.2




[Stable-8.2.3 113/116] hw/isa/vt82c686: Keep track of PIRQ/PINT pins separately

2024-04-18 Thread Michael Tokarev
From: BALATON Zoltan 

Move calculation of mask after the switch which sets the function
number for PIRQ/PINT pins to make sure the state of these pins are
kept track of separately and IRQ is raised if any of them is active.

Cc: qemu-sta...@nongnu.org
Fixes: 7e01bd80c1 hw/isa/vt82c686: Bring back via_isa_set_irq()
Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20240410222543.0ea534e6...@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
(cherry picked from commit f33274265a242df5d9fdb00915fe72fbb1b2a3c4)
Signed-off-by: Michael Tokarev 

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 9c2333a277..0334431219 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -613,7 +613,7 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
 ViaISAState *s = VIA_ISA(pci_get_function_0(d));
 uint8_t irq = d->config[PCI_INTERRUPT_LINE], max_irq = 15;
 int f = PCI_FUNC(d->devfn);
-uint16_t mask = BIT(f);
+uint16_t mask;
 
 switch (f) {
 case 0: /* PIRQ/PINT inputs */
@@ -628,6 +628,7 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
 }
 
 /* Keep track of the state of all sources */
+mask = BIT(f);
 if (level) {
 s->irq_state[0] |= mask;
 } else {
-- 
2.39.2




[Stable-8.2.3 112/116] virtio-pci: fix use of a released vector

2024-04-18 Thread Michael Tokarev
From: Cindy Lu 

During the booting process of the non-standard image, the behavior of the
called function in qemu is as follows:

1. vhost_net_stop() was triggered by guest image. This will call the function
virtio_pci_set_guest_notifiers() with assgin= false,
virtio_pci_set_guest_notifiers() will release the irqfd for vector 0

2. virtio_reset() was triggered, this will set configure vector to 
VIRTIO_NO_VECTOR

3.vhost_net_start() was called (at this time, the configure vector is
still VIRTIO_NO_VECTOR) and then call virtio_pci_set_guest_notifiers() with
assgin=true, so the irqfd for vector 0 is still not "init" during this process

4. The system continues to boot and sets the vector back to 0. After that
msix_fire_vector_notifier() was triggered to unmask the vector 0 and  meet the 
crash

To fix the issue, we need to support changing the vector after 
VIRTIO_CONFIG_S_DRIVER_OK is set.

(gdb) bt
0  __pthread_kill_implementation (threadid=, 
signo=signo@entry=6, no_tid=no_tid@entry=0)
at pthread_kill.c:44
1  0x7fc87148ec53 in __pthread_kill_internal (signo=6, threadid=) at pthread_kill.c:78
2  0x7fc87143e956 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/posix/raise.c:26
3  0x7fc8714287f4 in __GI_abort () at abort.c:79
4  0x7fc87142871b in __assert_fail_base
(fmt=0x7fc8715bbde0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
assertion=0x5606413efd53 "ret == 0", file=0x5606413ef87d 
"../accel/kvm/kvm-all.c", line=1837, function=) at assert.c:92
5  0x7fc871437536 in __GI___assert_fail
(assertion=0x5606413efd53 "ret == 0", file=0x5606413ef87d 
"../accel/kvm/kvm-all.c", line=1837, function=0x5606413f06f0 
<__PRETTY_FUNCTION__.19> "kvm_irqchip_commit_routes") at assert.c:101
6  0x560640f884b5 in kvm_irqchip_commit_routes (s=0x560642cae1f0) at 
../accel/kvm/kvm-all.c:1837
7  0x560640c98f8e in virtio_pci_one_vector_unmask
(proxy=0x560643c65f00, queue_no=4294967295, vector=0, msg=..., 
n=0x560643c6e4c8)
at ../hw/virtio/virtio-pci.c:1005
8  0x560640c99201 in virtio_pci_vector_unmask (dev=0x560643c65f00, 
vector=0, msg=...)
at ../hw/virtio/virtio-pci.c:1070
9  0x560640bc402e in msix_fire_vector_notifier (dev=0x560643c65f00, 
vector=0, is_masked=false)
at ../hw/pci/msix.c:120
10 0x560640bc40f1 in msix_handle_mask_update (dev=0x560643c65f00, vector=0, 
was_masked=true)
at ../hw/pci/msix.c:140
11 0x560640bc4503 in msix_table_mmio_write (opaque=0x560643c65f00, addr=12, 
val=0, size=4)
at ../hw/pci/msix.c:231
12 0x560640f26d83 in memory_region_write_accessor
(mr=0x560643c66540, addr=12, value=0x7fc86b7bc628, size=4, shift=0, 
mask=4294967295, attrs=...)
at ../system/memory.c:497
13 0x560640f270a6 in access_with_adjusted_size

 (addr=12, value=0x7fc86b7bc628, size=4, access_size_min=1, 
access_size_max=4, access_fn=0x560640f26c8d , 
mr=0x560643c66540, attrs=...) at ../system/memory.c:573
14 0x560640f2a2b5 in memory_region_dispatch_write (mr=0x560643c66540, 
addr=12, data=0, op=MO_32, attrs=...)
at ../system/memory.c:1521
15 0x560640f37bac in flatview_write_continue
(fv=0x7fc65805e0b0, addr=4273803276, attrs=..., ptr=0x7fc871e9c028, len=4, 
addr1=12, l=4, mr=0x560643c66540)
at ../system/physmem.c:2714
16 0x560640f37d0f in flatview_write
(fv=0x7fc65805e0b0, addr=4273803276, attrs=..., buf=0x7fc871e9c028, len=4) 
at ../system/physmem.c:2756
17 0x560640f380bf in address_space_write
(as=0x560642161ae0 , addr=4273803276, attrs=..., 
buf=0x7fc871e9c028, len=4)
at ../system/physmem.c:2863
18 0x560640f3812c in address_space_rw
(as=0x560642161ae0 , addr=4273803276, attrs=..., 
buf=0x7fc871e9c028, len=4, is_write=true) at ../system/physmem.c:2873
--Type  for more, q to quit, c to continue without paging--
19 0x560640f8aa55 in kvm_cpu_exec (cpu=0x560642f205e0) at 
../accel/kvm/kvm-all.c:2915
20 0x560640f8d731 in kvm_vcpu_thread_fn (arg=0x560642f205e0) at 
../accel/kvm/kvm-accel-ops.c:51
21 0x5606411949f4 in qemu_thread_start (args=0x560642f292b0) at 
../util/qemu-thread-posix.c:541
22 0x7fc87148cdcd in start_thread (arg=) at 
pthread_create.c:442
23 0x7fc871512630 in clone3 () at 
../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
(gdb)

MST: coding style and typo fixups

Fixes: f9a09ca3ea ("vhost: add support for configure interrupt")
Cc: qemu-sta...@nongnu.org
Signed-off-by: Cindy Lu 
Message-ID: 
<2321ade5f601367efe7380c04e3f61379c59b48f.1713173550.git@redhat.com>
Cc: Lei Yang 
Cc: Jason Wang 
Signed-off-by: Michael S. Tsirkin 
Tested-by: Cindy Lu 
(cherry picked from commit 2ce6cff94df2650c460f809e5ad263f1d22507c0)
Signed-off-by: Michael Tokarev 

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e433879542..08faefe29a 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1424,6 +1424,38 @@ static int virtio_pci_add_mem_cap(VirtIOPCI

[Stable-8.2.3 110/116] hw/audio/virtio-snd: Remove unused assignment

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Coverity reported:

  >>> CID 1542933:  Code maintainability issues  (UNUSED_VALUE)
  >>> CID 1542934:  Code maintainability issues  (UNUSED_VALUE)
  >>> Assigning value "NULL" to "stream" here, but that stored
  value is overwritten before it can be used.

Simply remove the unused assignments.

Resolves: Coverity CID 1542933
Resolves: Coverity CID 1542934
Fixes: 731655f87f ("virtio-snd: rewrite invalid tx/rx message handling")
Fixes: 20cd0c8655 ("virtio-snd: rewrite invalid tx/rx message handling" in 
stable-8.2)
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Manos Pitsidianakis 
Message-Id: <20240410053712.34747-1-phi...@linaro.org>
(cherry picked from commit dcb0a1ac03d6b5ba6c7fcbe467f0215738006113)
Signed-off-by: Michael Tokarev 

diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 256a132ece..823f9ab084 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -885,7 +885,9 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, 
VirtQueue *vq)
 }
 trace_virtio_snd_handle_tx_xfer();
 
-for (VirtIOSoundPCMStream *stream = NULL;; stream = NULL) {
+for (;;) {
+VirtIOSoundPCMStream *stream;
+
 elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
 if (!elem) {
 break;
@@ -964,7 +966,9 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, 
VirtQueue *vq)
 }
 trace_virtio_snd_handle_rx_xfer();
 
-for (VirtIOSoundPCMStream *stream = NULL;; stream = NULL) {
+for (;;) {
+VirtIOSoundPCMStream *stream;
+
 elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
 if (!elem) {
 break;
-- 
2.39.2




[Stable-8.2.3 109/116] hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

If a fragmented packet size is too short, do not try to
calculate its checksum.

Reproduced using:

  $ cat << EOF | qemu-system-i386 -display none -nodefaults \
  -machine q35,accel=qtest -m 32M \
  -device igb,netdev=net0 \
  -netdev user,id=net0 \
  -qtest stdio
  outl 0xcf8 0x8810
  outl 0xcfc 0xe000
  outl 0xcf8 0x8804
  outw 0xcfc 0x06
  write 0xe403 0x1 0x02
  writel 0xe0003808 0x
  write 0xe000381a 0x1 0x5b
  write 0xe000381b 0x1 0x00
  EOF
  Assertion failed: (offset == 0), function iov_from_buf_full, file util/iov.c, 
line 39.
  #1 0x5575e81e952a in iov_from_buf_full qemu/util/iov.c:39:5
  #2 0x5575e6500768 in net_tx_pkt_update_sctp_checksum 
qemu/hw/net/net_tx_pkt.c:144:9
  #3 0x5575e659f3e1 in igb_setup_tx_offloads qemu/hw/net/igb_core.c:478:11
  #4 0x5575e659f3e1 in igb_tx_pkt_send qemu/hw/net/igb_core.c:552:10
  #5 0x5575e659f3e1 in igb_process_tx_desc qemu/hw/net/igb_core.c:671:17
  #6 0x5575e659f3e1 in igb_start_xmit qemu/hw/net/igb_core.c:903:9
  #7 0x5575e659f3e1 in igb_set_tdt qemu/hw/net/igb_core.c:2812:5
  #8 0x5575e657d6a4 in igb_core_write qemu/hw/net/igb_core.c:4248:9

Fixes: CVE-2024-3567
Cc: qemu-sta...@nongnu.org
Reported-by: Zheyu Ma 
Fixes: f199b13bc1 ("igb: Implement Tx SCTP CSO")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2273
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Akihiko Odaki 
Acked-by: Jason Wang 
Message-Id: <20240410070459.49112-1-phi...@linaro.org>
(cherry picked from commit 83ddb3dbba2ee0f1767442ae6ee665058aeb1093)
Signed-off-by: Michael Tokarev 

diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
index 2134a18c4c..b7b1de816d 100644
--- a/hw/net/net_tx_pkt.c
+++ b/hw/net/net_tx_pkt.c
@@ -141,6 +141,10 @@ bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt)
 uint32_t csum = 0;
 struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG;
 
+if (iov_size(pl_start_frag, pkt->payload_frags) < 8 + sizeof(csum)) {
+return false;
+}
+
 if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, , 
sizeof(csum)) < sizeof(csum)) {
 return false;
 }
-- 
2.39.2




[Stable-8.2.3 101/116] hw/block/nand: Factor nand_load_iolen() method out

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Reviewed-by: Richard Henderson 
Reviewed-by: Kevin Wolf 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409135944.24997-2-phi...@linaro.org>
(cherry picked from commit 7a86544f286d8af4fa5251101c1026ddae92cc3d)
Signed-off-by: Michael Tokarev 

diff --git a/hw/block/nand.c b/hw/block/nand.c
index 9c1b89cfa6..58ef547c5a 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -243,9 +243,28 @@ static inline void nand_pushio_byte(NANDFlashState *s, 
uint8_t value)
 }
 }
 
+/*
+ * nand_load_block: Load block containing (s->addr + @offset).
+ * Returns length of data available at @offset in this block.
+ */
+static unsigned nand_load_block(NANDFlashState *s, unsigned offset)
+{
+unsigned iolen;
+
+s->blk_load(s, s->addr, offset);
+
+iolen = (1 << s->page_shift);
+if (s->gnd) {
+iolen += 1 << s->oob_shift;
+}
+assert(offset <= iolen);
+iolen -= offset;
+
+return iolen;
+}
+
 static void nand_command(NANDFlashState *s)
 {
-unsigned int offset;
 switch (s->cmd) {
 case NAND_CMD_READ0:
 s->iolen = 0;
@@ -271,12 +290,7 @@ static void nand_command(NANDFlashState *s)
 case NAND_CMD_NOSERIALREAD2:
 if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))
 break;
-offset = s->addr & ((1 << s->addr_shift) - 1);
-s->blk_load(s, s->addr, offset);
-if (s->gnd)
-s->iolen = (1 << s->page_shift) - offset;
-else
-s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
+s->iolen = nand_load_block(s, s->addr & ((1 << s->addr_shift) - 1));
 break;
 
 case NAND_CMD_RESET:
@@ -597,12 +611,7 @@ uint32_t nand_getio(DeviceState *dev)
 if (!s->iolen && s->cmd == NAND_CMD_READ0) {
 offset = (int) (s->addr & ((1 << s->addr_shift) - 1)) + s->offset;
 s->offset = 0;
-
-s->blk_load(s, s->addr, offset);
-if (s->gnd)
-s->iolen = (1 << s->page_shift) - offset;
-else
-s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
+s->iolen = nand_load_block(s, offset);
 }
 
 if (s->ce || s->iolen <= 0) {
-- 
2.39.2




[Stable-8.2.3 097/116] hw/display/virtio-gpu: Protect from DMA re-entrancy bugs

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed:

  $ cat << EOF | qemu-system-i386 -display none -nodefaults \
  -machine q35,accel=qtest \
  -m 512M \
  -device virtio-gpu \
  -qtest stdio
  outl 0xcf8 0x8820
  outl 0xcfc 0xe0004000
  outl 0xcf8 0x8804
  outw 0xcfc 0x06
  write 0xe0004030 0x4 0x024000e0
  write 0xe0004028 0x1 0xff
  write 0xe0004020 0x4 0x9300
  write 0xe000401c 0x1 0x01
  write 0x101 0x1 0x04
  write 0x103 0x1 0x1c
  write 0x9301c8 0x1 0x18
  write 0x105 0x1 0x1c
  write 0x107 0x1 0x1c
  write 0x109 0x1 0x1c
  write 0x10b 0x1 0x00
  write 0x10d 0x1 0x00
  write 0x10f 0x1 0x00
  write 0x111 0x1 0x00
  write 0x113 0x1 0x00
  write 0x115 0x1 0x00
  write 0x117 0x1 0x00
  write 0x119 0x1 0x00
  write 0x11b 0x1 0x00
  write 0x11d 0x1 0x00
  write 0x11f 0x1 0x00
  write 0x121 0x1 0x00
  write 0x123 0x1 0x00
  write 0x125 0x1 0x00
  write 0x127 0x1 0x00
  write 0x129 0x1 0x00
  write 0x12b 0x1 0x00
  write 0x12d 0x1 0x00
  write 0x12f 0x1 0x00
  write 0x131 0x1 0x00
  write 0x133 0x1 0x00
  write 0x135 0x1 0x00
  write 0x137 0x1 0x00
  write 0x139 0x1 0x00
  write 0xe0007003 0x1 0x00
  EOF
  ...
  =
  ==276099==ERROR: AddressSanitizer: heap-use-after-free on address 
0x60d11178
  at pc 0x562cc3b736c7 bp 0x7ffed49dee60 sp 0x7ffed49dee58
  READ of size 8 at 0x60d11178 thread T0
  #0 0x562cc3b736c6 in virtio_gpu_ctrl_response 
hw/display/virtio-gpu.c:180:42
  #1 0x562cc3b7c40b in virtio_gpu_ctrl_response_nodata 
hw/display/virtio-gpu.c:192:5
  #2 0x562cc3b7c40b in virtio_gpu_simple_process_cmd 
hw/display/virtio-gpu.c:1015:13
  #3 0x562cc3b82873 in virtio_gpu_process_cmdq 
hw/display/virtio-gpu.c:1050:9
  #4 0x562cc4a85514 in aio_bh_call util/async.c:169:5
  #5 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
  #6 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5
  #7 0x562cc4a8a2da in aio_ctx_dispatch util/async.c:358:5
  #8 0x7f36840547a8 in g_main_context_dispatch 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x547a8)
  #9 0x562cc4a8b753 in glib_pollfds_poll util/main-loop.c:290:9
  #10 0x562cc4a8b753 in os_host_main_loop_wait util/main-loop.c:313:5
  #11 0x562cc4a8b753 in main_loop_wait util/main-loop.c:592:11
  #12 0x562cc3938186 in qemu_main_loop system/runstate.c:782:9
  #13 0x562cc43b7af5 in qemu_default_main system/main.c:37:14
  #14 0x7f3683a6c189 in __libc_start_call_main 
csu/../sysdeps/nptl/libc_start_call_main.h:58:16
  #15 0x7f3683a6c244 in __libc_start_main csu/../csu/libc-start.c:381:3
  #16 0x562cc2a58ac0 in _start (qemu-system-i386+0x231bac0)

  0x60d11178 is located 56 bytes inside of 136-byte region 
[0x60d11140,0x60d111c8)
  freed by thread T0 here:
  #0 0x562cc2adb662 in __interceptor_free (qemu-system-i386+0x239e662)
  #1 0x562cc3b86b21 in virtio_gpu_reset hw/display/virtio-gpu.c:1524:9
  #2 0x562cc416e20e in virtio_reset hw/virtio/virtio.c:2145:9
  #3 0x562cc37c5644 in virtio_pci_reset hw/virtio/virtio-pci.c:2249:5
  #4 0x562cc4233758 in memory_region_write_accessor system/memory.c:497:5
  #5 0x562cc4232eea in access_with_adjusted_size system/memory.c:573:18

  previously allocated by thread T0 here:
  #0 0x562cc2adb90e in malloc (qemu-system-i386+0x239e90e)
  #1 0x7f368405a678 in g_malloc 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5a678)
  #2 0x562cc4163ffc in virtqueue_split_pop hw/virtio/virtio.c:1612:12
  #3 0x562cc4163ffc in virtqueue_pop hw/virtio/virtio.c:1783:16
  #4 0x562cc3b91a95 in virtio_gpu_handle_ctrl 
hw/display/virtio-gpu.c:1112:15
  #5 0x562cc4a85514 in aio_bh_call util/async.c:169:5
  #6 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
  #7 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5

  SUMMARY: AddressSanitizer: heap-use-after-free hw/display/virtio-gpu.c:180:42 
in virtio_gpu_ctrl_response

With this change, the same reproducer triggers:

  qemu-system-i386: warning: Blocked re-entrant IO on MemoryRegion: 
virtio-pci-common-virtio-gpu at addr: 0x6

Fixes: CVE-2024-3446
Cc: qemu-sta...@nongnu.org
Reported-by: Alexander Bulekov 
Reported-by: Yongkang Jia 
Reported-by: Xiao Lei 
Reported-by: Yiming Tao 
Buglink: https://bugs.launchpad.net/qemu/+bug/1888606
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-3-phi...@linaro.org>
(cherry picked from commit ba28e0ff4d95b56dc334aac2730ab3651ffc3132)
Signed-off-by: Michael Tokarev 

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index b016d3bac8..a7b16ba072 100644
--- a/hw/display/

[Stable-8.2.3 088/116] tcg/optimize: Do not attempt to constant fold neg_vec

2024-04-18 Thread Michael Tokarev
From: Richard Henderson 

Split out the tail of fold_neg to fold_neg_no_const so that we
can avoid attempting to constant fold vector negate.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2150
Signed-off-by: Richard Henderson 
(cherry picked from commit e25fe886b89a396bae5847520b70c148587d490a)
Signed-off-by: Michael Tokarev 

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 6fcdda68ef..5ead14972a 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -1830,16 +1830,10 @@ static bool fold_nand(OptContext *ctx, TCGOp *op)
 return false;
 }
 
-static bool fold_neg(OptContext *ctx, TCGOp *op)
+static bool fold_neg_no_const(OptContext *ctx, TCGOp *op)
 {
-uint64_t z_mask;
-
-if (fold_const1(ctx, op)) {
-return true;
-}
-
 /* Set to 1 all bits to the left of the rightmost.  */
-z_mask = arg_info(op->args[1])->z_mask;
+uint64_t z_mask = arg_info(op->args[1])->z_mask;
 ctx->z_mask = -(z_mask & -z_mask);
 
 /*
@@ -1850,6 +1844,11 @@ static bool fold_neg(OptContext *ctx, TCGOp *op)
 return true;
 }
 
+static bool fold_neg(OptContext *ctx, TCGOp *op)
+{
+return fold_const1(ctx, op) || fold_neg_no_const(ctx, op);
+}
+
 static bool fold_nor(OptContext *ctx, TCGOp *op)
 {
 if (fold_const2_commutative(ctx, op) ||
@@ -2165,7 +2164,7 @@ static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op)
 if (have_neg) {
 op->opc = neg_op;
 op->args[1] = op->args[2];
-return fold_neg(ctx, op);
+return fold_neg_no_const(ctx, op);
 }
 return false;
 }
diff --git a/tests/tcg/aarch64/Makefile.target 
b/tests/tcg/aarch64/Makefile.target
index 0efd565f05..70d728ae9a 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -10,7 +10,7 @@ VPATH += $(AARCH64_SRC)
 
 # Base architecture tests
 AARCH64_TESTS=fcvt pcalign-a64 lse2-fault
-AARCH64_TESTS += test-2248
+AARCH64_TESTS += test-2248 test-2150
 
 fcvt: LDFLAGS+=-lm
 
diff --git a/tests/tcg/aarch64/test-2150.c b/tests/tcg/aarch64/test-2150.c
new file mode 100644
index 00..fb86c11958
--- /dev/null
+++ b/tests/tcg/aarch64/test-2150.c
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* See https://gitlab.com/qemu-project/qemu/-/issues/2150 */
+
+int main()
+{
+asm volatile(
+"movi v6.4s, #1\n"
+"movi v7.4s, #0\n"
+"sub  v6.2d, v7.2d, v6.2d\n"
+: : : "v6", "v7");
+return 0;
+}
-- 
2.39.2




[Stable-8.2.3 099/116] hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.

Fixes: CVE-2024-3446
Cc: qemu-sta...@nongnu.org
Suggested-by: Alexander Bulekov 
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-5-phi...@linaro.org>
(cherry picked from commit f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc)
Signed-off-by: Michael Tokarev 

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 0e2cc8d5a8..4aaced74be 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -1080,8 +1080,8 @@ static void virtio_crypto_device_realize(DeviceState 
*dev, Error **errp)
 vcrypto->vqs[i].dataq =
  virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
 vcrypto->vqs[i].dataq_bh =
- qemu_bh_new_guarded(virtio_crypto_dataq_bh, >vqs[i],
- >mem_reentrancy_guard);
+ virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh,
+   >vqs[i]);
 vcrypto->vqs[i].vcrypto = vcrypto;
 }
 
-- 
2.39.2




[Stable-8.2.3 089/116] linux-user: Fix waitid return of siginfo_t and rusage

2024-04-18 Thread Michael Tokarev
From: Richard Henderson 

The copy back to siginfo_t should be conditional only on arg3,
not the specific values that might have been written.
The copy back to rusage was missing entirely.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2262
Signed-off-by: Richard Henderson 
Tested-by: Alex Fan 
Reviewed-by: Philippe Mathieu-Daudé 
(cherry picked from commit f0907ff4cae743f1a4ef3d0a55a047029eed06ff)
Signed-off-by: Michael Tokarev 

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e384e14248..834a254895 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9154,14 +9154,24 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 #ifdef TARGET_NR_waitid
 case TARGET_NR_waitid:
 {
+struct rusage ru;
 siginfo_t info;
-info.si_pid = 0;
-ret = get_errno(safe_waitid(arg1, arg2, , arg4, NULL));
-if (!is_error(ret) && arg3 && info.si_pid != 0) {
-if (!(p = lock_user(VERIFY_WRITE, arg3, 
sizeof(target_siginfo_t), 0)))
+
+ret = get_errno(safe_waitid(arg1, arg2, (arg3 ?  : NULL),
+arg4, (arg5 ?  : NULL)));
+if (!is_error(ret)) {
+if (arg3) {
+p = lock_user(VERIFY_WRITE, arg3,
+  sizeof(target_siginfo_t), 0);
+if (!p) {
+return -TARGET_EFAULT;
+}
+host_to_target_siginfo(p, );
+unlock_user(p, arg3, sizeof(target_siginfo_t));
+}
+if (arg5 && host_to_target_rusage(arg5, )) {
 return -TARGET_EFAULT;
-host_to_target_siginfo(p, );
-unlock_user(p, arg3, sizeof(target_siginfo_t));
+}
 }
 }
 return ret;
-- 
2.39.2




[Stable-8.2.3 111/116] linux-user/x86_64: Handle the vsyscall page in open_self_maps_{2, 4}

2024-04-18 Thread Michael Tokarev
From: Richard Henderson 

This is the only case in which we expect to have no host memory backing
for a guest memory page, because in general linux user processes cannot
map any pages in the top half of the 64-bit address space.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2170
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
(cherry picked from commit 4ef1f559f270c66b3ffc23f6c845ff3d008c6356)
Signed-off-by: Michael Tokarev 

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 834a254895..11c75e3b4e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7994,6 +7994,10 @@ static void open_self_maps_4(const struct 
open_self_maps_data *d,
 path = "[heap]";
 } else if (start == info->vdso) {
 path = "[vdso]";
+#ifdef TARGET_X86_64
+} else if (start == TARGET_VSYSCALL_PAGE) {
+path = "[vsyscall]";
+#endif
 }
 
 /* Except null device (MAP_ANON), adjust offset for this fragment. */
@@ -8082,6 +8086,18 @@ static int open_self_maps_2(void *opaque, target_ulong 
guest_start,
 uintptr_t host_start = (uintptr_t)g2h_untagged(guest_start);
 uintptr_t host_last = (uintptr_t)g2h_untagged(guest_end - 1);
 
+#ifdef TARGET_X86_64
+/*
+ * Because of the extremely high position of the page within the guest
+ * virtual address space, this is not backed by host memory at all.
+ * Therefore the loop below would fail.  This is the only instance
+ * of not having host backing memory.
+ */
+if (guest_start == TARGET_VSYSCALL_PAGE) {
+return open_self_maps_3(opaque, guest_start, guest_end, flags);
+}
+#endif
+
 while (1) {
 IntervalTreeNode *n =
 interval_tree_iter_first(d->host_maps, host_start, host_start);
-- 
2.39.2




[Stable-8.2.3 116/116] ppc/spapr: Initialize max_cpus limit to SPAPR_IRQ_NR_IPIS.

2024-04-18 Thread Michael Tokarev
From: Harsh Prateek Bora 

Initialize the machine specific max_cpus limit as per the maximum range
of CPU IPIs available. Keeping between 4096 to 8192 will throw IRQ not
free error due to XIVE/XICS limitation and keeping beyond 8192 will hit
assert in tcg_region_init or spapr_xive_claim_irq.

Logs:

Without patch fix:

[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=4097
qemu-system-ppc64: IRQ 4096 is not free
[root@host build]#

On LPAR:
[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=8193
**
ERROR:../tcg/region.c:774:tcg_region_init: assertion failed:
(region_size >= 2 * page_size)
Bail out! ERROR:../tcg/region.c:774:tcg_region_init: assertion failed:
(region_size >= 2 * page_size)
Aborted (core dumped)
[root@host build]#

On x86:
[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=8193
qemu-system-ppc64: ../hw/intc/spapr_xive.c:596: spapr_xive_claim_irq:
Assertion `lisn < xive->nr_irqs' failed.
Aborted (core dumped)
[root@host build]#

With patch fix:
[root@host build]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=4097
qemu-system-ppc64: Invalid SMP CPUs 4097. The max CPUs supported by
machine 'pseries-8.2' is 4096
[root@host build]#

Reported-by: Kowshik Jois 
Tested-by: Kowshik Jois 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Harsh Prateek Bora 
Signed-off-by: Nicholas Piggin 
(cherry picked from commit c4f91d7b7be76c47015521ab0109c6e998a369b0)
Signed-off-by: Michael Tokarev 

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index df09aa9d6a..222d926f46 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4647,13 +4647,10 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 mc->block_default_type = IF_SCSI;
 
 /*
- * Setting max_cpus to INT32_MAX. Both KVM and TCG max_cpus values
- * should be limited by the host capability instead of hardcoded.
- * max_cpus for KVM guests will be checked in kvm_init(), and TCG
- * guests are welcome to have as many CPUs as the host are capable
- * of emulate.
+ * While KVM determines max cpus in kvm_init() using kvm_max_vcpus(),
+ * In TCG the limit is restricted by the range of CPU IPIs available.
  */
-mc->max_cpus = INT32_MAX;
+mc->max_cpus = SPAPR_IRQ_NR_IPIS;
 
 mc->no_parallel = 1;
 mc->default_boot_order = "";
-- 
2.39.2




[Stable-8.2.3 100/116] qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo

2024-04-18 Thread Michael Tokarev
From: Yuquan Wang 

Fix the unit typo of interleave-granularity of CXL Fixed Memory
Window in qemu-option.hx.

Fixes: 03b39fcf64 ("hw/cxl: Make the CFMW a machine parameter.")
Signed-off-by: Yuquan Wang wangyuquan1...@phytium.com.cn
Message-ID: <20240407083539.1488172-2-wangyuquan1...@phytium.com.cn>
[PMD: Reworded]
Signed-off-by: Philippe Mathieu-Daudé 
(cherry picked from commit aa88f99c87c0e5d195d6d96190374650553ea61f)
Signed-off-by: Michael Tokarev 

diff --git a/qemu-options.hx b/qemu-options.hx
index b6b4ad9e67..8f9d54a06b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -149,14 +149,14 @@ SRST
 platform and configuration dependent.
 
 ``interleave-granularity=granularity`` sets the granularity of
-interleave. Default 256KiB. Only 256KiB, 512KiB, 1024KiB, 2048KiB
-4096KiB, 8192KiB and 16384KiB granularities supported.
+interleave. Default 256 (bytes). Only 256, 512, 1k, 2k,
+4k, 8k and 16k granularities supported.
 
 Example:
 
 ::
 
--machine 
cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512k
+-machine 
cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512
 ERST
 
 DEF("M", HAS_ARG, QEMU_OPTION_M,
-- 
2.39.2




[Stable-8.2.3 v2 000/116] Patch Round-up for stable 8.2.3, freeze on 2024-04-20

2024-04-18 Thread Michael Tokarev
The following patches are queued for QEMU stable v8.2.3:

  https://gitlab.com/qemu-project/qemu/-/commits/staging-8.2

Patch freeze is 2024-04-20, and the release is planned for 2024-04-22:

  https://wiki.qemu.org/Planning/8.2

Please respond here or CC qemu-sta...@nongnu.org on any additional patches
you think should (or shouldn't) be included in the release.

The changes which are staging for inclusion, with the original commit hash
from master branch, are given below the bottom line.

Thanks!

/mjt

--
01* eae7509be9 Michael Tokarev:
   Revert "configure: run plugin TCG tests again"
02* 15cc10336249 Paolo Bonzini:
   configure: run plugin TCG tests again
03* 7f89fdf8ebe6 Richard Henderson:
   tcg/aarch64: Apple does not align __int128_t in even registers
04* b816e1b5ba58 Richard Henderson:
   linux-user: Remove pgb_dynamic alignment assertion
05* 9ea920dc2825 Daniel P. Berrangé:
   gitlab: update FreeBSD Cirrus CI image to 13.3
06* f5af80271aad David Parsons:
   ui/cocoa: Fix window clipping on macOS 14
07* d572bcb22201 Richard Henderson:
   target/arm: Fix 32-bit SMOPA
08* fd7f95f23d6f Peter Maydell:
   hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
09* 012b170173bc Dmitrii Gavrilov:
   system/qdev-monitor: move drain_call_rcu call under if (!dev) in 
   qmp_device_add()
10* a9198b3132d8 Sven Schnelle:
   hw/scsi/lsi53c895a: stop script on phase mismatch
11* 9876359990dd Sven Schnelle:
   hw/scsi/lsi53c895a: add timer to scripts processing
12* 9bc9e9511944 Michael Tokarev:
   make-release: switch to .xz format by default
13* 69f7b00d057f Yu Zhang:
   migration/rdma: Fix a memory issue for migration
14* 65c2ab808571 Laurent Vivier:
   igb: fix link state on resume
15* 4cadf1023498 Laurent Vivier:
   e1000e: fix link state on resume
16* 6a5287ce8047 Nick Briggs:
   Avoid unaligned fetch in ladr_match()
17* 9253d8306226 Peng Fan:
   xen: Drop out of coroutine context xen_invalidate_map_cache_entry
18* 4f0a4a3d5854 Minwoo Im:
   hw/nvme: separate 'serial' property for VFs
19* 8c78015a55d8 Klaus Jensen:
   hw/nvme: fix invalid check on mcl
20* ee7bda4d38cd Klaus Jensen:
   hw/nvme: generalize the mbar size helper
21* fa905f65c554 Klaus Jensen:
   hw/nvme: add machine compatibility parameter to enable msix exclusive bar
22* 91bb64a8d201 Akihiko Odaki:
   hw/nvme: Use pcie_sriov_num_vfs()
23* 6081b4243cd6 Akihiko Odaki:
   pcie_sriov: Validate NumVFs
24* 74e2845c5f95 Jonathan Cameron:
   hmat acpi: Fix out of bounds access due to missing use of indirection
25* 633487df8d30 Volker Rümelin:
   hw/audio/virtio-sound: return correct command response size
26* 2e128776dc56 Cédric Le Goater:
   migration: Skip only empty block devices
27* ae5a40e85811 Kevin Wolf:
   mirror: Don't call job_pause_point() under graph lock
28* f816310d0c32 Stefan Hajnoczi:
   nbd/server: only traverse NBDExport->clients from main loop thread
29* 7075d235114b Stefan Hajnoczi:
   nbd/server: introduce NBDClient->lock to protect fields
30* 9c707525cbb1 Kevin Wolf:
   nbd/server: Fix race in draining the export
31* e8fce34eccf6 Kevin Wolf:
   iotests: Add test for reset/AioContext switches with NBD exports
32* c45f8f1aef35 Thomas Huth:
   tests/unit: Bump test-aio-multithread test timeout to 2 minutes
33* e1b363e328d5 Thomas Huth:
   tests/unit: Bump test-crypto-block test timeout to 5 minutes
34* 63b18312d14a Kevin Wolf:
   tests/unit: Bump test-replication timeout to 60 seconds
35* 5f97afe2543f Paolo Bonzini:
   target/i386: introduce function to query MMU indices
36* 90f641531c78 Paolo Bonzini:
   target/i386: use separate MMU indexes for 32-bit accesses
37* 2cc68629a6fc Paolo Bonzini:
   target/i386: fix direction of "32-bit MMU" test
38* e8ee827ffdb8 Daniel P. Berrangé:
   Revert "chardev/char-socket: Fix TLS io channels sending too much data to 
   the backend"
39* d4069a84a338 Marc-André Lureau:
   ui: compile dbus-display1.c with -fPIC as necessary
40* 7fd226b04746 Tao Su:
   target/i386: Revert monitor_puts() in do_inject_x86_mce()
41* 72bace2d13cb Richard Henderson:
   target/hppa: Fix assemble_16 insns for wide mode
42* 4768c28edd40 Richard Henderson:
   target/hppa: Fix assemble_11a insns for wide mode
43* 46174e140d27 Richard Henderson:
   target/hppa: Fix assemble_12a insns for wide mode
44* c3ea1996a14d Sven Schnelle:
   target/hppa: ldcw,s uses static shift of 3
45* d37fad0ae5bd Sven Schnelle:
   target/hppa: fix shrp for wide mode
46* ae157fc25053 Sven Schnelle:
   target/hppa: fix access_id check
47* ad1fdacd1b93 Sven Schnelle:
   target/hppa: exit tb on flush cache instructions
48* b5e0b3a53c98 Sven Schnelle:
   target/hppa: mask privilege bits in mfia
49* 518d2f4300e5 Sven Schnelle:
   target/hppa: fix do_stdby_e()
50* 77642f92c0b7 Song Gao:
   target/loongarch: Fix qemu-loongarch64 hang when executing 'll.d $t0, 
   $t0, 0'
51* eb844330bd36 Thomas Huth:
   docs/conf.py: Remove usage of distutils
52* 1590154ee437 Song Gao:
   target/loongarch

[Stable-8.2.3 104/116] hw/misc/applesmc: Fix memory leak in reset() handler

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

AppleSMCData is allocated with g_new0() in applesmc_add_key():
release it with g_free().

Leaked since commit 1ddda5cd36 ("AppleSMC device emulation").

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2272
Reported-by: Zheyu Ma 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20240408095217.57239-3-phi...@linaro.org>
(cherry picked from commit fc09ff2979defdcf8d00c2db94022d5d610e36ba)
Signed-off-by: Michael Tokarev 

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 72300d0cbc..a77fb93e7f 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -274,6 +274,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
 /* Remove existing entries */
 QLIST_FOREACH_SAFE(d, >data_def, node, next) {
 QLIST_REMOVE(d, node);
+g_free(d);
 }
 s->status = 0x00;
 s->status_1e = 0x00;
-- 
2.39.2




[Stable-8.2.3 106/116] hw/net/lan9118: Replace magic '2048' value by MIL_TXFIFO_SIZE definition

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

The magic 2048 is explained in the LAN9211 datasheet (DS2414A)
in chapter 1.4, "10/100 Ethernet MAC":

  The MAC Interface Layer (MIL), within the MAC, contains a
  2K Byte transmit and a 128 Byte receive FIFO which is separate
  from the TX and RX FIFOs. [...]

Note, the use of the constant in lan9118_receive() reveals that
our implementation is using the same buffer for both tx and rx.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20240409133801.23503-2-phi...@linaro.org>
(cherry picked from commit a45223467e4e185fff1c76a6483784fa379ded77)
Signed-off-by: Michael Tokarev 

diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index cf7b8c897a..f0a8a3fa10 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -150,6 +150,12 @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
 
 #define GPT_TIMER_EN0x2000
 
+/*
+ * The MAC Interface Layer (MIL), within the MAC, contains a 2K Byte transmit
+ * and a 128 Byte receive FIFO which is separate from the TX and RX FIFOs.
+ */
+#define MIL_TXFIFO_SIZE 2048
+
 enum tx_state {
 TX_IDLE,
 TX_B,
@@ -166,7 +172,7 @@ typedef struct {
 int32_t pad;
 int32_t fifo_used;
 int32_t len;
-uint8_t data[2048];
+uint8_t data[MIL_TXFIFO_SIZE];
 } LAN9118Packet;
 
 static const VMStateDescription vmstate_lan9118_packet = {
@@ -182,7 +188,7 @@ static const VMStateDescription vmstate_lan9118_packet = {
 VMSTATE_INT32(pad, LAN9118Packet),
 VMSTATE_INT32(fifo_used, LAN9118Packet),
 VMSTATE_INT32(len, LAN9118Packet),
-VMSTATE_UINT8_ARRAY(data, LAN9118Packet, 2048),
+VMSTATE_UINT8_ARRAY(data, LAN9118Packet, MIL_TXFIFO_SIZE),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -544,7 +550,7 @@ static ssize_t lan9118_receive(NetClientState *nc, const 
uint8_t *buf,
 return -1;
 }
 
-if (size >= 2048 || size < 14) {
+if (size >= MIL_TXFIFO_SIZE || size < 14) {
 return -1;
 }
 
-- 
2.39.2




[Stable-8.2.3 108/116] hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Per "SD Host Controller Standard Specification Version 3.00":

  * 2.2.5 Transfer Mode Register (Offset 00Ch)

Writes to this register shall be ignored when the Command
Inhibit (DAT) in the Present State register is 1.

Do not update the TRNMOD register when Command Inhibit (DAT)
bit is set to avoid the present-status register going out of
sync, leading to malicious guest using DMA mode and overflowing
the FIFO buffer:

  $ cat << EOF | qemu-system-i386 \
 -display none -nographic -nodefaults \
 -machine accel=qtest -m 512M \
 -device sdhci-pci,sd-spec-version=3 \
 -device sd-card,drive=mydrive \
 -drive 
if=none,index=0,file=null-co://,format=raw,id=mydrive \
 -qtest stdio
  outl 0xcf8 0x80001013
  outl 0xcfc 0x91
  outl 0xcf8 0x80001001
  outl 0xcfc 0x0600
  write 0x912c 0x1 0x05
  write 0x9158 0x1 0x16
  write 0x9105 0x1 0x04
  write 0x9128 0x1 0x08
  write 0x16 0x1 0x21
  write 0x19 0x1 0x20
  write 0x910c 0x1 0x01
  write 0x910e 0x1 0x20
  write 0x910f 0x1 0x00
  write 0x910c 0x1 0x00
  write 0x9120 0x1 0x00
  EOF

Stack trace (part):
=
==89993==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x61529900 at pc 0x55d5f885700d bp 0x7ffc1e1e9470 sp 0x7ffc1e1e9468
WRITE of size 1 at 0x61529900 thread T0
#0 0x55d5f885700c in sdhci_write_dataport hw/sd/sdhci.c:564:39
#1 0x55d5f8849150 in sdhci_write hw/sd/sdhci.c:1223:13
#2 0x55d5fa01db63 in memory_region_write_accessor system/memory.c:497:5
#3 0x55d5fa01d245 in access_with_adjusted_size system/memory.c:573:18
#4 0x55d5fa01b1a9 in memory_region_dispatch_write system/memory.c:1521:16
#5 0x55d5fa09f5c9 in flatview_write_continue system/physmem.c:2711:23
#6 0x55d5fa08f78b in flatview_write system/physmem.c:2753:12
#7 0x55d5fa08f258 in address_space_write system/physmem.c:2860:18
...
0x61529900 is located 0 bytes to the right of 512-byte region
[0x61529700,0x61529900) allocated by thread T0 here:
#0 0x55d5f7237b27 in __interceptor_calloc
#1 0x7f9e36dd4c50 in g_malloc0
#2 0x55d5f88672f7 in sdhci_pci_realize hw/sd/sdhci-pci.c:36:5
#3 0x55d5f844b582 in pci_qdev_realize hw/pci/pci.c:2092:9
#4 0x55d5fa2ee74b in device_set_realized hw/core/qdev.c:510:13
#5 0x55d5fa325bfb in property_set_bool qom/object.c:2358:5
#6 0x55d5fa31ea45 in object_property_set qom/object.c:1472:5
#7 0x55d5fa332509 in object_property_set_qobject om/qom-qobject.c:28:10
#8 0x55d5fa31f6ed in object_property_set_bool qom/object.c:1541:15
#9 0x55d5fa2e2948 in qdev_realize hw/core/qdev.c:292:12
#10 0x55d5f8eed3f1 in qdev_device_add_from_qdict 
system/qdev-monitor.c:719:10
#11 0x55d5f8eef7ff in qdev_device_add system/qdev-monitor.c:738:11
#12 0x55d5f8f211f0 in device_init_func system/vl.c:1200:11
#13 0x55d5fad0877d in qemu_opts_foreach util/qemu-option.c:1135:14
#14 0x55d5f8f0df9c in qemu_create_cli_devices system/vl.c:2638:5
#15 0x55d5f8f0db24 in qmp_x_exit_preconfig system/vl.c:2706:5
#16 0x55d5f8f14dc0 in qemu_init system/vl.c:3737:9
...
SUMMARY: AddressSanitizer: heap-buffer-overflow hw/sd/sdhci.c:564:39
in sdhci_write_dataport

Add assertions to ensure the fifo_buffer[] is not overflowed by
malicious accesses to the Buffer Data Port register.

Fixes: CVE-2024-3447
Cc: qemu-sta...@nongnu.org
Fixes: d7dfca0807 ("hw/sdhci: introduce standard SD host controller")
Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58813
Reported-by: Alexander Bulekov 
Reported-by: Chuhong Yuan 
Signed-off-by: Peter Maydell 
Message-Id: 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409145524.27913-1-phi...@linaro.org>
(cherry picked from commit 9e4b27ca6bf4974f169bbca7f3dca117b1208b6f)
Signed-off-by: Michael Tokarev 

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 40473b0db0..e95ea34895 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -473,6 +473,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned 
size)
 }
 
 for (i = 0; i < size; i++) {
+assert(s->data_count < s->buf_maxsz);
 value |= s->fifo_buffer[s->data_count] << i * 8;
 s->data_count++;
 /* check if we've read all valid data (blksize bytes) from buffer */
@@ -561,6 +562,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t 
value, unsigned size)
 }
 
 for (i = 0; i < size; i++) {
+assert(s->data_count < s->buf_maxsz);
 s->fifo_buffer[s->data_count] = value & 0xFF;
 s->data_count++;
 value >>= 8;
@@ -1208,6 +1210,12 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, 
unsigned size)
 if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) {

[Stable-8.2.3 093/116] target/sh4: Fix mac.w with saturation enabled

2024-04-18 Thread Michael Tokarev
From: Zack Buhman 

The saturation arithmetic logic in helper_macw is not correct.
I tested and verified this behavior on a SH7091.

Reviewd-by: Yoshinori Sato 
Signed-off-by: Zack Buhman 
Message-Id: <20240405233802.29128-3-z...@buhman.org>
[rth: Reformat helper_macw, add a test case.]
Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
(cherry picked from commit 7227c0cd506eaab5b1d89d15832cac7e05ecb412)
Signed-off-by: Michael Tokarev 

diff --git a/target/sh4/helper.h b/target/sh4/helper.h
index 64056e4a39..29011d3dbb 100644
--- a/target/sh4/helper.h
+++ b/target/sh4/helper.h
@@ -12,7 +12,7 @@ DEF_HELPER_1(discard_movcal_backup, void, env)
 DEF_HELPER_2(ocbi, void, env, i32)
 
 DEF_HELPER_3(macl, void, env, s32, s32)
-DEF_HELPER_3(macw, void, env, i32, i32)
+DEF_HELPER_3(macw, void, env, s32, s32)
 
 DEF_HELPER_2(ld_fpscr, void, env, i32)
 
diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c
index c96c6008a1..8b7f378f23 100644
--- a/target/sh4/op_helper.c
+++ b/target/sh4/op_helper.c
@@ -179,22 +179,28 @@ void helper_macl(CPUSH4State *env, int32_t arg0, int32_t 
arg1)
 env->mac = res;
 }
 
-void helper_macw(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+void helper_macw(CPUSH4State *env, int32_t arg0, int32_t arg1)
 {
-int64_t res;
+/* Inputs are already sign-extended from 16 bits. */
+int32_t mul = arg0 * arg1;
 
-res = ((uint64_t) env->mach << 32) | env->macl;
-res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
-env->mach = (res >> 32) & 0x;
-env->macl = res & 0x;
 if (env->sr & (1u << SR_S)) {
-if (res < -0x8000) {
-env->mach = 1;
-env->macl = 0x8000;
-} else if (res > 0x7fff) {
+/*
+ * In saturation arithmetic mode, the accumulator is 32-bit
+ * with carry. MACH is not considered during the addition
+ * operation nor the 32-bit saturation logic.
+ */
+int32_t res, macl = env->macl;
+
+if (sadd32_overflow(macl, mul, )) {
+res = macl < 0 ? INT32_MIN : INT32_MAX;
+/* If overflow occurs, the MACH register is set to 1. */
 env->mach = 1;
-env->macl = 0x7fff;
 }
+env->macl = res;
+} else {
+/* In non-saturation arithmetic mode, the accumulator is 64-bit */
+env->mac += mul;
 }
 }
 
diff --git a/tests/tcg/sh4/Makefile.target b/tests/tcg/sh4/Makefile.target
index 3c0695c7ca..c3d7fa86e3 100644
--- a/tests/tcg/sh4/Makefile.target
+++ b/tests/tcg/sh4/Makefile.target
@@ -17,3 +17,6 @@ VPATH += $(SRC_PATH)/tests/tcg/sh4
 
 test-macl: CFLAGS += -O -g
 TESTS += test-macl
+
+test-macw: CFLAGS += -O -g
+TESTS += test-macw
diff --git a/tests/tcg/sh4/test-macw.c b/tests/tcg/sh4/test-macw.c
new file mode 100644
index 00..4eceec8634
--- /dev/null
+++ b/tests/tcg/sh4/test-macw.c
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include 
+#include 
+#include 
+
+int64_t mac_w(int64_t mac, const int16_t *a, const int16_t *b)
+{
+register uint32_t macl __asm__("macl") = mac;
+register uint32_t mach __asm__("mach") = mac >> 32;
+
+asm volatile("mac.w @%0+,@%1+"
+ : "+r"(a), "+r"(b), "+x"(macl), "+x"(mach));
+
+return ((uint64_t)mach << 32) | macl;
+}
+
+typedef struct {
+int64_t mac;
+int16_t a, b;
+int64_t res[2];
+} Test;
+
+__attribute__((noinline))
+void test(const Test *t, int sat)
+{
+int64_t res;
+
+if (sat) {
+asm volatile("sets");
+} else {
+asm volatile("clrs");
+}
+res = mac_w(t->mac, >a, >b);
+
+if (res != t->res[sat]) {
+fprintf(stderr, "%#llx + (%#x * %#x) = %#llx -- got %#llx\n",
+t->mac, t->a, t->b, t->res[sat], res);
+abort();
+}
+}
+
+int main()
+{
+static const Test tests[] = {
+{ 0, 2, 3, { 6, 6 } },
+{ 0x123456787ffell, 2, -3,
+  { 0x123456787ff8ll, 0x123456787ff8ll } },
+{ 0xabcdef127ffall, 2, 3,
+  { 0xabcdef128000ll, 0x00017fffll } },
+{ 0xfll, INT16_MAX, INT16_MAX,
+  { 0x103fffll, 0xf3fffll } },
+};
+
+for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
+for (int j = 0; j < 2; ++j) {
+test([i], j);
+}
+}
+return 0;
+}
-- 
2.39.2




[Stable-8.2.3 103/116] hw/block/nand: Fix out-of-bound access in NAND block buffer

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

nand_command() and nand_getio() don't check @offset points
into the block, nor the available data length (s->iolen) is
not negative.

In order to fix:

- check the offset is in range in nand_blk_load_NAND_PAGE_SIZE(),
- do not set @iolen if blk_load() failed.

Reproducer:

  $ cat << EOF | qemu-system-arm -machine tosa \
 -monitor none -serial none \
 -display none -qtest stdio
  write 0x1111 0x1 0xca
  write 0x1104 0x1 0x47
  write 0x1000ca04 0x1 0xd7
  write 0x1000ca01 0x1 0xe0
  write 0x1000ca04 0x1 0x71
  write 0x1000ca00 0x1 0x50
  write 0x1000ca04 0x1 0xd7
  read 0x1000ca02 0x1
  write 0x1000ca01 0x1 0x10
  EOF

=
==15750==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61f00de0
 at pc 0x560e61557210 bp 0x7ffcfc4a59f0 sp 0x7ffcfc4a59e8
READ of size 1 at 0x61f00de0 thread T0
#0 0x560e6155720f in mem_and hw/block/nand.c:101:20
#1 0x560e6155ac9c in nand_blk_write_512 hw/block/nand.c:663:9
#2 0x560e61544200 in nand_command hw/block/nand.c:293:13
#3 0x560e6153cc83 in nand_setio hw/block/nand.c:520:13
#4 0x560e61a0a69e in tc6393xb_nand_writeb hw/display/tc6393xb.c:380:13
#5 0x560e619f9bf7 in tc6393xb_writeb hw/display/tc6393xb.c:524:9
#6 0x560e647c7d03 in memory_region_write_accessor softmmu/memory.c:492:5
#7 0x560e647c7641 in access_with_adjusted_size softmmu/memory.c:554:18
#8 0x560e647c5f66 in memory_region_dispatch_write softmmu/memory.c:1514:16
#9 0x560e6485409e in flatview_write_continue softmmu/physmem.c:2825:23
#10 0x560e648421eb in flatview_write softmmu/physmem.c:2867:12
#11 0x560e64841ca8 in address_space_write softmmu/physmem.c:2963:18
#12 0x560e61170162 in qemu_writeb tests/qtest/videzzo/videzzo_qemu.c:1080:5
#13 0x560e6116eef7 in dispatch_mmio_write 
tests/qtest/videzzo/videzzo_qemu.c:1227:28

0x61f00de0 is located 0 bytes to the right of 3424-byte region 
[0x61f00080,0x61f00de0)
allocated by thread T0 here:
#0 0x560e611276cf in malloc 
/root/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7f7959a87e98 in g_malloc 
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x57e98)
#2 0x560e64b98871 in object_new qom/object.c:749:12
#3 0x560e64b5d1a1 in qdev_new hw/core/qdev.c:153:19
#4 0x560e61547ea5 in nand_init hw/block/nand.c:639:11
#5 0x560e619f8772 in tc6393xb_init hw/display/tc6393xb.c:558:16
#6 0x560e6390bad2 in tosa_init hw/arm/tosa.c:250:12

SUMMARY: AddressSanitizer: heap-buffer-overflow hw/block/nand.c:101:20 in 
mem_and
==15750==ABORTING

Broken since introduction in commit 3e3d5815cb ("NAND Flash memory
emulation and ECC calculation helpers for use by NAND controllers").

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1445
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1446
Reported-by: Qiang Liu 
Reviewed-by: Richard Henderson 
Reviewed-by: Kevin Wolf 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409135944.24997-4-phi...@linaro.org>
(cherry picked from commit d39fdfff348fdf00173b7a58e935328a64db7d28)
Signed-off-by: Michael Tokarev 

diff --git a/hw/block/nand.c b/hw/block/nand.c
index d945c0b9e3..902cc56a03 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -255,7 +255,9 @@ static unsigned nand_load_block(NANDFlashState *s, unsigned 
offset)
 {
 unsigned iolen;
 
-s->blk_load(s, s->addr, offset);
+if (!s->blk_load(s, s->addr, offset)) {
+return 0;
+}
 
 iolen = (1 << s->page_shift);
 if (s->gnd) {
@@ -783,6 +785,10 @@ static bool glue(nand_blk_load_, 
NAND_PAGE_SIZE)(NANDFlashState *s,
 return false;
 }
 
+if (offset > NAND_PAGE_SIZE + OOB_SIZE) {
+return false;
+}
+
 if (s->blk) {
 if (s->mem_oob) {
 if (blk_pread(s->blk, SECTOR(addr) << BDRV_SECTOR_BITS,
-- 
2.39.2




[Stable-8.2.3 105/116] backends/cryptodev: Do not abort for invalid session ID

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Instead of aborting when a session ID is invalid,
return VIRTIO_CRYPTO_INVSESS ("Invalid session id").

Reproduced using:

  $ cat << EOF | qemu-system-i386 -display none \
 -machine q35,accel=qtest -m 512M -nodefaults \
 -object cryptodev-backend-builtin,id=cryptodev0 \
 -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
 -qtest stdio
  outl 0xcf8 0x8804
  outw 0xcfc 0x06
  outl 0xcf8 0x8820
  outl 0xcfc 0xe0008000
  write 0x10800e 0x1 0x01
  write 0xe0008016 0x1 0x01
  write 0xe0008020 0x4 0x00801000
  write 0xe0008028 0x4 0x00c01000
  write 0xe000801c 0x1 0x01
  write 0x11 0x1 0x05
  write 0x110001 0x1 0x04
  write 0x108002 0x1 0x11
  write 0x108008 0x1 0x48
  write 0x10800c 0x1 0x01
  write 0x108018 0x1 0x10
  write 0x10801c 0x1 0x02
  write 0x10c002 0x1 0x01
  write 0xe000b005 0x1 0x00
  EOF
  Assertion failed: (session_id < MAX_NUM_SESSIONS && 
builtin->sessions[session_id]),
  function cryptodev_builtin_close_session, file cryptodev-builtin.c, line 430.

Cc: qemu-sta...@nongnu.org
Reported-by: Zheyu Ma 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2274
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: zhenwei pi 
Message-Id: <20240409094757.9127-1-phi...@linaro.org>
(cherry picked from commit eaf2bd29538d039df80bb4b1584de33a61312bc6)
Signed-off-by: Michael Tokarev 

diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
index 39d0455280..a514bbb310 100644
--- a/backends/cryptodev-builtin.c
+++ b/backends/cryptodev-builtin.c
@@ -427,7 +427,9 @@ static int cryptodev_builtin_close_session(
   CRYPTODEV_BACKEND_BUILTIN(backend);
 CryptoDevBackendBuiltinSession *session;
 
-assert(session_id < MAX_NUM_SESSIONS && builtin->sessions[session_id]);
+if (session_id >= MAX_NUM_SESSIONS || !builtin->sessions[session_id]) {
+return -VIRTIO_CRYPTO_INVSESS;
+}
 
 session = builtin->sessions[session_id];
 if (session->cipher) {
-- 
2.39.2




[Stable-8.2.3 107/116] hw/net/lan9118: Fix overflow in MIL TX FIFO

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

When the MAC Interface Layer (MIL) transmit FIFO is full,
truncate the packet, and raise the Transmitter Error (TXE)
flag.

Broken since model introduction in commit 2a42499017
("LAN9118 emulation").

When using the reproducer from
https://gitlab.com/qemu-project/qemu/-/issues/2267 we get:

  hw/net/lan9118.c:798:17: runtime error:
  index 2048 out of bounds for type 'uint8_t[2048]' (aka 'unsigned char[2048]')
    #0 0x563ec9a057b1 in tx_fifo_push hw/net/lan9118.c:798:43
    #1 0x563ec99fbb28 in lan9118_writel hw/net/lan9118.c:1042:9
    #2 0x563ec99f2de2 in lan9118_16bit_mode_write hw/net/lan9118.c:1205:9
    #3 0x563ecbf78013 in memory_region_write_accessor system/memory.c:497:5
    #4 0x563ecbf776f5 in access_with_adjusted_size system/memory.c:573:18
    #5 0x563ecbf75643 in memory_region_dispatch_write system/memory.c:1521:16
    #6 0x563ecc01bade in flatview_write_continue_step system/physmem.c:2713:18
    #7 0x563ecc01b374 in flatview_write_continue system/physmem.c:2743:19
    #8 0x563ecbff1c9b in flatview_write system/physmem.c:2774:12
    #9 0x563ecbff1768 in address_space_write system/physmem.c:2894:18
...

[*] LAN9118 DS2266B.pdf, Table 5.3.3 "INTERRUPT STATUS REGISTER"

Cc: qemu-sta...@nongnu.org
Reported-by: Will Lester
Reported-by: Chuhong Yuan 
Suggested-by: Peter Maydell 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2267
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20240409133801.23503-3-phi...@linaro.org>
(cherry picked from commit ad766d603f39888309cfb1433ba2de1d0e9e4f58)
Signed-off-by: Michael Tokarev 

diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index f0a8a3fa10..4b081cc827 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -799,8 +799,22 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
 /* Documentation is somewhat unclear on the ordering of bytes
in FIFO words.  Empirical results show it to be little-endian.
*/
-/* TODO: FIFO overflow checking.  */
 while (n--) {
+if (s->txp->len == MIL_TXFIFO_SIZE) {
+/*
+ * No more space in the FIFO. The datasheet is not
+ * precise about this case. We choose what is easiest
+ * to model: the packet is truncated, and TXE is raised.
+ *
+ * Note, it could be a fragmented packet, but we currently
+ * do not handle that (see earlier TX_B case).
+ */
+qemu_log_mask(LOG_GUEST_ERROR,
+  "MIL TX FIFO overrun, discarding %u 
byte%s\n",
+  n, n > 1 ? "s" : "");
+s->int_sts |= TXE_INT;
+break;
+}
 s->txp->data[s->txp->len] = val & 0xff;
 s->txp->len++;
 val >>= 8;
-- 
2.39.2




[Stable-8.2.3 098/116] hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.

Fixes: CVE-2024-3446
Cc: qemu-sta...@nongnu.org
Suggested-by: Alexander Bulekov 
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-4-phi...@linaro.org>
(cherry picked from commit b4295bff25f7b50de1d9cc94a9c6effd40056bca)
Signed-off-by: Michael Tokarev 

diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index dd619f0731..1221fb7f15 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -985,8 +985,7 @@ static void virtser_port_device_realize(DeviceState *dev, 
Error **errp)
 return;
 }
 
-port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port,
-   >mem_reentrancy_guard);
+port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port);
 port->elem = NULL;
 }
 
-- 
2.39.2




[Stable-8.2.3 102/116] hw/block/nand: Have blk_load() take unsigned offset and return boolean

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Negative offset is meaningless, use unsigned type.
Return a boolean value indicating success.

Reviewed-by: Richard Henderson 
Reviewed-by: Kevin Wolf 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20240409135944.24997-3-phi...@linaro.org>
(cherry picked from commit 2e3e09b368001f7eaeeca7a9b49cb1f0c9092d85)
Signed-off-by: Michael Tokarev 

diff --git a/hw/block/nand.c b/hw/block/nand.c
index 58ef547c5a..d945c0b9e3 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -84,7 +84,11 @@ struct NANDFlashState {
 
 void (*blk_write)(NANDFlashState *s);
 void (*blk_erase)(NANDFlashState *s);
-void (*blk_load)(NANDFlashState *s, uint64_t addr, int offset);
+/*
+ * Returns %true when block containing (@addr + @offset) is
+ * successfully loaded, otherwise %false.
+ */
+bool (*blk_load)(NANDFlashState *s, uint64_t addr, unsigned offset);
 
 uint32_t ioaddr_vmstate;
 };
@@ -772,11 +776,11 @@ static void glue(nand_blk_erase_, 
NAND_PAGE_SIZE)(NANDFlashState *s)
 }
 }
 
-static void glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s,
-uint64_t addr, int offset)
+static bool glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s,
+ uint64_t addr, unsigned 
offset)
 {
 if (PAGE(addr) >= s->pages) {
-return;
+return false;
 }
 
 if (s->blk) {
@@ -804,6 +808,8 @@ static void glue(nand_blk_load_, 
NAND_PAGE_SIZE)(NANDFlashState *s,
 offset, NAND_PAGE_SIZE + OOB_SIZE - offset);
 s->ioaddr = s->io;
 }
+
+return true;
 }
 
 static void glue(nand_init_, NAND_PAGE_SIZE)(NANDFlashState *s)
-- 
2.39.2




[Stable-8.2.3 096/116] hw/virtio: Introduce virtio_bh_new_guarded() helper

2024-04-18 Thread Michael Tokarev
From: Philippe Mathieu-Daudé 

Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded()
but using the transport memory guard, instead of the device one
(there can only be one virtio device per virtio bus).

Inspired-by: Gerd Hoffmann 
Reviewed-by: Gerd Hoffmann 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20240409105537.18308-2-phi...@linaro.org>
(cherry picked from commit ec0504b989ca61e03636384d3602b7bf07ffe4da)
Signed-off-by: Michael Tokarev 

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index aa02c4937c..c177c31ca0 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -4145,3 +4145,13 @@ static void virtio_register_types(void)
 }
 
 type_init(virtio_register_types)
+
+QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+   QEMUBHFunc *cb, void *opaque,
+   const char *name)
+{
+DeviceState *transport = qdev_get_parent_bus(dev)->parent;
+
+return qemu_bh_new_full(cb, opaque, name,
+>mem_reentrancy_guard);
+}
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index c8f72850bc..7d5ffdc145 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -22,6 +22,7 @@
 #include "standard-headers/linux/virtio_config.h"
 #include "standard-headers/linux/virtio_ring.h"
 #include "qom/object.h"
+#include "block/aio.h"
 
 /*
  * A guest should never accept this. It implies negotiation is broken
@@ -508,4 +509,10 @@ static inline bool virtio_device_disabled(VirtIODevice 
*vdev)
 bool virtio_legacy_allowed(VirtIODevice *vdev);
 bool virtio_legacy_check_disabled(VirtIODevice *vdev);
 
+QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+   QEMUBHFunc *cb, void *opaque,
+   const char *name);
+#define virtio_bh_new_guarded(dev, cb, opaque) \
+virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb)))
+
 #endif
-- 
2.39.2




[Stable-8.2.3 095/116] target/m68k: Map FPU exceptions to FPSR register

2024-04-18 Thread Michael Tokarev
From: Keith Packard 

Add helpers for reading/writing the 68881 FPSR register so that
changes in floating point exception state can be seen by the
application.

Call these helpers in pre_load/post_load hooks to synchronize
exception state.

Signed-off-by: Keith Packard 
Reviewed-by: Richard Henderson 
Message-Id: <20230803035231.429697-1-kei...@keithp.com>
Signed-off-by: Richard Henderson 
(cherry picked from commit 5888357942da1fd5a50efb6e4a6af8b1a27a5af8)
Signed-off-by: Michael Tokarev 

diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 11c7e0a790..d95deaafcd 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -396,12 +396,19 @@ static const VMStateDescription vmstate_freg = {
 }
 };
 
-static int fpu_post_load(void *opaque, int version)
+static int fpu_pre_save(void *opaque)
 {
 M68kCPU *s = opaque;
 
-cpu_m68k_restore_fp_status(>env);
+s->env.fpsr = cpu_m68k_get_fpsr(>env);
+return 0;
+}
+
+static int fpu_post_load(void *opaque, int version)
+{
+M68kCPU *s = opaque;
 
+cpu_m68k_set_fpsr(>env, s->env.fpsr);
 return 0;
 }
 
@@ -410,6 +417,7 @@ const VMStateDescription vmmstate_fpu = {
 .version_id = 1,
 .minimum_version_id = 1,
 .needed = fpu_needed,
+.pre_save = fpu_pre_save,
 .post_load = fpu_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(env.fpcr, M68kCPU),
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 6cfc696d2b..4d78da9d5f 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -199,7 +199,8 @@ void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);
 void cpu_m68k_set_sr(CPUM68KState *env, uint32_t);
 void cpu_m68k_restore_fp_status(CPUM68KState *env);
 void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val);
-
+uint32_t cpu_m68k_get_fpsr(CPUM68KState *env);
+void cpu_m68k_set_fpsr(CPUM68KState *env, uint32_t val);
 
 /*
  * Instead of computing the condition codes after each m68k instruction,
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index ab120b5f59..8314791f50 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -164,6 +164,78 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
 cpu_m68k_set_fpcr(env, val);
 }
 
+/* Convert host exception flags to cpu_m68k form.  */
+static int cpu_m68k_exceptbits_from_host(int host_bits)
+{
+int target_bits = 0;
+
+if (host_bits & float_flag_invalid) {
+target_bits |= 0x80;
+}
+if (host_bits & float_flag_overflow) {
+target_bits |= 0x40;
+}
+if (host_bits & (float_flag_underflow | float_flag_output_denormal)) {
+target_bits |= 0x20;
+}
+if (host_bits & float_flag_divbyzero) {
+target_bits |= 0x10;
+}
+if (host_bits & float_flag_inexact) {
+target_bits |= 0x08;
+}
+return target_bits;
+}
+
+/* Convert cpu_m68k exception flags to target form.  */
+static int cpu_m68k_exceptbits_to_host(int target_bits)
+{
+int host_bits = 0;
+
+if (target_bits & 0x80) {
+host_bits |= float_flag_invalid;
+}
+if (target_bits & 0x40) {
+host_bits |= float_flag_overflow;
+}
+if (target_bits & 0x20) {
+host_bits |= float_flag_underflow;
+}
+if (target_bits & 0x10) {
+host_bits |= float_flag_divbyzero;
+}
+if (target_bits & 0x08) {
+host_bits |= float_flag_inexact;
+}
+return host_bits;
+}
+
+uint32_t cpu_m68k_get_fpsr(CPUM68KState *env)
+{
+int host_flags = get_float_exception_flags(>fp_status);
+int target_flags = cpu_m68k_exceptbits_from_host(host_flags);
+int except = (env->fpsr & ~(0xf8)) | target_flags;
+return except;
+}
+
+uint32_t HELPER(get_fpsr)(CPUM68KState *env)
+{
+return cpu_m68k_get_fpsr(env);
+}
+
+void cpu_m68k_set_fpsr(CPUM68KState *env, uint32_t val)
+{
+env->fpsr = val;
+
+int host_flags = cpu_m68k_exceptbits_to_host((int) env->fpsr);
+set_float_exception_flags(host_flags, >fp_status);
+}
+
+void HELPER(set_fpsr)(CPUM68KState *env, uint32_t val)
+{
+cpu_m68k_set_fpsr(env, val);
+}
+
 #define PREC_BEGIN(prec)\
 do {\
 FloatX80RoundPrec old = \
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 0a1544cd68..beab4b96bc 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -118,7 +118,7 @@ static int m68k_fpu_gdb_get_reg(CPUM68KState *env, 
GByteArray *mem_buf, int n)
 case 8: /* fpcontrol */
 return gdb_get_reg32(mem_buf, env->fpcr);
 case 9: /* fpstatus */
-return gdb_get_reg32(mem_buf, env->fpsr);
+return gdb_get_reg32(mem_buf, cpu_m68k_get_fpsr(env));
 case 10: /* fpiar, not implemented */
 return gdb_get_reg32(mem_buf, 0);
 }
@@ -137,7 +137,7 @@ static int m68k_fpu_gdb_set_reg(CPUM68KState *env, uint8_t 
*mem_buf, 

  1   2   3   4   5   6   7   8   9   10   >