* [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16
@ 2024-09-06 11:12 Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 01/69] hw/scsi/lsi53c895a: bump instruction limit in scripts processing to fix regression Michael Tokarev
` (68 more replies)
0 siblings, 69 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Michael Tokarev
The following patches are queued for QEMU stable v9.0.3:
https://gitlab.com/qemu-project/qemu/-/commits/staging-9.0
Patch freeze is 2024-09-16, and the release is planned for 2024-09-18:
https://wiki.qemu.org/Planning/9.0
Please respond here or CC qemu-stable@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 a4975023fb13 Fiona Ebner:
hw/scsi/lsi53c895a: bump instruction limit in scripts processing to fix
regression
02 57a8a80d1a5b Fiona Ebner:
scsi: fix regression and honor bootindex again for legacy drives
03 3becc9390810 Markus Armbruster:
qapi/qom: Document feature unstable of @x-vfio-user-server
04 5669d26ec614 Peter Maydell:
target/arm: Fix handling of LDAPR/STLR with negative offset
05 25489b521b61 Peter Maydell:
target/arm: LDAPR should honour SCTLR_ELx.nAA
06 31d93fedf41c Daniyal Khan:
target/arm: Use float_status copy in sme_fmopa_s
07 207d30b5fdb5 Richard Henderson:
target/arm: Use FPST_F16 for SME FMOPA (widening)
08 30a1690f2402 Akihiko Odaki:
hvf: arm: Do not advance PC when raising an exception
09 c510fe78f1b7 Zheyu Ma:
hw/nvme: fix memory leak in nvme_dsm
10 a207d5f87d66 Zhao Liu:
hw/cxl/cxl-host: Fix segmentation fault when getting cxl-fmw property
11 98e77e3dd8dd Manos Pitsidianakis:
virtio-snd: add max size bounds check in input cb
12 9b6083465fb8 Manos Pitsidianakis:
virtio-snd: check for invalid param shift operands
13 a3c8d7e38550 Clément Mathieu--Drif:
intel_iommu: fix FRCD construction macro
14 13be929aff80 Paolo Bonzini:
target/i386: do not crash if microvm guest uses SGX CPUID leaves
15 903cc9e1173e songziming:
chardev/char-win-stdio.c: restore old console mode
16 2465c89fb983 Bibo Mao:
hw/intc/loongson_ipi: Access memory in little endian
17 0c2086bc7360 Philippe Mathieu-Daudé:
hw/intc/loongson_ipi: Fix resource leak
18 a18ffbcf8b9f Song Gao:
target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue
19 851495571d14 Peter Maydell:
util/async.c: Forbid negative min/max in
aio_context_set_thread_pool_params()
20 e0bf95443ee9 Sergey Dyasli:
Revert "qemu-char: do not operate on sources from finalize callbacks"
21 d72479b11797 Thomas Huth:
hw/virtio: Fix the de-initialization of vhost-user devices
22 83340193b991 Richard Henderson:
target/rx: Use target_ulong for address in LI
23 546d574b11e0 Frederik van Hövell:
hw/char/bcm2835_aux: Fix assert when receive FIFO fills up
24 0892fffc2aba Peter Maydell:
hw/misc/bcm2835_property: Fix handling of FRAMEBUFFER_SET_PALETTE
25 56f1c0db928a Peter Maydell:
target/arm: Don't assert for 128-bit tile accesses when SVL is 128
26 ea3f5a90f036 Peter Maydell:
target/arm: Fix UMOPA/UMOPS of 16-bit values
27 76916dfa89e8 Peter Maydell:
target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl()
28 f573ac059ed0 Peter Maydell:
target/arm: Ignore SMCR_EL2.LEN and SVCR_EL2.LEN if EL2 is not enabled
29 48e5b5f994bc Peter Maydell:
docs/sphinx/depfile.py: Handle env.doc2path() returning a Path not a str
30 9a45b0761628 Peter Maydell:
hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb()
31 5a558be93ad6 Marco Palumbi:
hw/arm/mps2-tz.c: fix RX/TX interrupts order
32 55f9f4ee018c Peter Maydell:
target/arm: Handle denormals correctly for FMOPA (widening)
33 f1595ceb9aad Akihiko Odaki:
virtio-net: Ensure queue index fits with RSS
34 f937309fbdbb thomas:
virtio-net: Fix network stall at the host side waiting for kick
35 64f75f57f9d2 David Woodhouse:
net: Reinstate '-net nic, model=help' output as documented in man page
36 0bd5b9284fa9 Fabiano Rosas:
migration/multifd: Fix multifd_send_setup cleanup when channel creation
fails
37 5b0c2742c839 Ilya Leoshkevich:
linux-user/elfload: Fix pr_pid values in core files
38 ac63755b2001 Richard Henderson:
target/i386: Fix VSIB decode
39 682a05280504 Richard Henderson:
tcg/ppc: Sync tcg_out_test and constraints
40 ed5a159c3de4 Philippe Mathieu-Daudé:
hw/sd/sdhci: Reset @data_count index on invalid ADMA transfers
41 b881cf00c99e Amjad Alsharafi:
vvfat: Fix bug in writing to middle of file
42 21b25a0e466a Amjad Alsharafi:
vvfat: Fix usage of `info.file.offset`
43 f60a6f7e17bf Amjad Alsharafi:
vvfat: Fix wrong checks for cluster mappings invariant
44 5eed3db33650 Amjad Alsharafi:
vvfat: Fix reading files with non-continuous clusters
45 c8f60bfb4345 Amjad Alsharafi:
iotests: Add `vvfat` tests
46 fb1c2aaa981e Eric Blake:
nbd/server: Plumb in new args to nbd_client_add()
47 c8a76dbd90c2 Eric Blake:
nbd/server: CVE-2024-7409: Cap default max-connections to 100
48 b9b72cb3ce15 Eric Blake:
nbd/server: CVE-2024-7409: Drop non-negotiating clients
49 3e7ef738c846 Eric Blake:
nbd/server: CVE-2024-7409: Close stray clients at server-stop
50 3874f5f73c44 Eric Blake:
nbd/server: CVE-2024-7409: Avoid use-after-free when closing server
51 fa62cb989a91 David Woodhouse:
net: Fix '-net nic,model=' for non-help arguments
52 446e5e8b4515 Jianzhou Yue:
hw/core/ptimer: fix timer zero period condition for freq > 1GHz
53 547c4e50929e Stefano Garzarella:
block/blkio: use FUA flag on write zeroes only if supported
54 416f2b16c02c Richard Henderson:
target/i386: Do not apply REX to MMX operands
55 8e0c9a9efa21 Richard Henderson:
target/arm: Clear high SVE elements in handle_vec_simd_wshli
56 150c24f34e9c Peter Maydell:
target/arm: Update translation regime comment for new features
57 4c2c04746932 Peter Maydell:
target/arm: Fix usage of MMU indexes when EL3 is AArch32
58 940d802b24e6 Alexander Ivanov:
module: Prevent crash by resetting local_err in module_load_qom_all()
59 fe68cc0923eb Alyssa Ross:
target/hexagon: don't look for static glib
60 3aefee3ec01e Richard Henderson:
linux-user: Preserve NULL hit in target_mmap subroutines
61 12d36294a2d9 Richard Henderson:
target/sparc: Restrict STQF to sparcv9
62 87e012f29f2e Peter Maydell:
crypto/tlscredspsk: Free username on finalize
63 6a22121c4f25 Klaus Jensen:
hw/nvme: fix leak of uninitialized memory in io_mgmt_recv
64 a8e63ff289d1 Cindy Lu:
virtio-pci: Fix the use of an uninitialized irqfd
65 4c107870e8b2 Peter Maydell:
migration/multifd: Free MultiFDRecvParams::data
66 a4ad4a9d98f7 Richard Henderson:
linux-user: Handle short reads in mmap_h_gt_g
67 94962ff00d09 Nicholas Piggin:
Revert "replay: stop us hanging in rr_wait_io_event"
68 7d14471a1218 Volker Rümelin:
hw/audio/virtio-snd: fix invalid param check
69 ead5078cf1a5 Helge Deller:
target/hppa: Fix PSW V-bit packaging in cpu_hppa_get for hppa64
^ permalink raw reply [flat|nested] 70+ messages in thread
* [Stable-9.0.3 01/69] hw/scsi/lsi53c895a: bump instruction limit in scripts processing to fix regression
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 02/69] scsi: fix regression and honor bootindex again for legacy drives Michael Tokarev
` (67 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Fiona Ebner, Sven Schnelle, Paolo Bonzini,
Michael Tokarev
From: Fiona Ebner <f.ebner@proxmox.com>
Commit 9876359990 ("hw/scsi/lsi53c895a: add timer to scripts
processing") reduced the maximum allowed instruction count by
a factor of 100 all the way down to 100.
This causes the "Check Point R81.20 Gaia" appliance [0] to fail to
boot after fully finishing the installation via the appliance's web
interface (there is already one reboot before that).
With a limit of 150, the appliance still fails to boot, while with a
limit of 200, it works. Bump to 500 to fix the regression and be on
the safe side.
Originally reported in the Proxmox community forum[1].
[0]: https://support.checkpoint.com/results/download/124397
[1]: https://forum.proxmox.com/threads/149772/post-683459
Cc: qemu-stable@nongnu.org
Fixes: 9876359990 ("hw/scsi/lsi53c895a: add timer to scripts processing")
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Acked-by: Sven Schnelle <svens@stackframe.org>
Link: https://lore.kernel.org/r/20240715131403.223239-1-f.ebner@proxmox.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a4975023fb13cf229bd59c9ceec1b8cbdc5b9a20)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index eb9828dd5e..f1935e5328 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -188,7 +188,7 @@ static const char *names[] = {
#define LSI_TAG_VALID (1 << 16)
/* Maximum instructions to process. */
-#define LSI_MAX_INSN 100
+#define LSI_MAX_INSN 500
typedef struct lsi_request {
SCSIRequest *req;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 02/69] scsi: fix regression and honor bootindex again for legacy drives
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 01/69] hw/scsi/lsi53c895a: bump instruction limit in scripts processing to fix regression Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 03/69] qapi/qom: Document feature unstable of @x-vfio-user-server Michael Tokarev
` (66 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Fiona Ebner, Kevin Wolf, Paolo Bonzini,
Michael Tokarev
From: Fiona Ebner <f.ebner@proxmox.com>
Commit 3089637461 ("scsi: Don't ignore most usb-storage properties")
removed the call to object_property_set_int() and thus the 'set'
method for the bootindex property was also not called anymore. Here
that method is device_set_bootindex() (as configured by
scsi_dev_instance_init() -> device_add_bootindex_property()) which as
a side effect registers the device via add_boot_device_path().
As reported by a downstream user [0], the bootindex property did not
have the desired effect anymore for legacy drives. Fix the regression
by explicitly calling the add_boot_device_path() function after
checking that the bootindex is not yet used (to avoid
add_boot_device_path() calling exit()).
[0]: https://forum.proxmox.com/threads/149772/post-679433
Cc: qemu-stable@nongnu.org
Fixes: 3089637461 ("scsi: Don't ignore most usb-storage properties")
Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Link: https://lore.kernel.org/r/20240710152529.1737407-1-f.ebner@proxmox.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 57a8a80d1a5b28797b21d30bfc60601945820e51)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 9e40b0c920..53eff5dd3d 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -384,6 +384,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
DeviceState *dev;
SCSIDevice *s;
DriveInfo *dinfo;
+ Error *local_err = NULL;
if (blk_is_sg(blk)) {
driver = "scsi-generic";
@@ -403,6 +404,14 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
s = SCSI_DEVICE(dev);
s->conf = *conf;
+ check_boot_index(conf->bootindex, &local_err);
+ if (local_err) {
+ object_unparent(OBJECT(dev));
+ error_propagate(errp, local_err);
+ return NULL;
+ }
+ add_boot_device_path(conf->bootindex, dev, NULL);
+
qdev_prop_set_uint32(dev, "scsi-id", unit);
if (object_property_find(OBJECT(dev), "removable")) {
qdev_prop_set_bit(dev, "removable", removable);
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 03/69] qapi/qom: Document feature unstable of @x-vfio-user-server
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 01/69] hw/scsi/lsi53c895a: bump instruction limit in scripts processing to fix regression Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 02/69] scsi: fix regression and honor bootindex again for legacy drives Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 04/69] target/arm: Fix handling of LDAPR/STLR with negative offset Michael Tokarev
` (65 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Markus Armbruster, Elena Ufimtseva, John G Johnson,
Jagannathan Raman, John Snow, Michael Tokarev
From: Markus Armbruster <armbru@redhat.com>
Commit 8f9a9259d32c added ObjectType member @x-vfio-user-server with
feature unstable, but neglected to explain why it is unstable. Do
that now.
Fixes: 8f9a9259d32c (vfio-user: define vfio-user-server object)
Cc: Elena Ufimtseva <elena.ufimtseva@oracle.com>
Cc: John G Johnson <john.g.johnson@oracle.com>
Cc: Jagannathan Raman <jag.raman@oracle.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20240703095310.1242102-1-armbru@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
[Indentation fixed]
(cherry picked from commit 3becc939081097ccfed6968771f33d65ce8551eb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/qapi/qom.json b/qapi/qom.json
index 85e6b4f84a..09f4e4b22e 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -937,7 +937,8 @@
#
# Features:
#
-# @unstable: Member @x-remote-object is experimental.
+# @unstable: Members @x-remote-object and @x-vfio-user-server are
+# experimental.
#
# Since: 6.0
##
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 04/69] target/arm: Fix handling of LDAPR/STLR with negative offset
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (2 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 03/69] qapi/qom: Document feature unstable of @x-vfio-user-server Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 05/69] target/arm: LDAPR should honour SCTLR_ELx.nAA Michael Tokarev
` (64 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Philippe Mathieu-Daudé,
Richard Henderson, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
When we converted the LDAPR/STLR instructions to decodetree we
accidentally introduced a regression where the offset is negative.
The 9-bit immediate field is signed, and the old hand decoder
correctly used sextract32() to get it out of the insn word,
but the ldapr_stlr_i pattern in the decode file used "imm:9"
instead of "imm:s9", so it treated the field as unsigned.
Fix the pattern to treat the field as a signed immediate.
Cc: qemu-stable@nongnu.org
Fixes: 2521b6073b7 ("target/arm: Convert LDAPR/STLR (imm) to decodetree")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2419
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240709134504.3500007-2-peter.maydell@linaro.org
(cherry picked from commit 5669d26ec614b3f4c56cf1489b9095ed327938b1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 8a20dce3c8..6cc29a4bce 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -467,7 +467,7 @@ LDAPR sz:2 111 0 00 1 0 1 11111 1100 00 rn:5 rt:5
LDRA 11 111 0 00 m:1 . 1 ......... w:1 1 rn:5 rt:5 imm=%ldra_imm
&ldapr_stlr_i rn rt imm sz sign ext
-@ldapr_stlr_i .. ...... .. . imm:9 .. rn:5 rt:5 &ldapr_stlr_i
+@ldapr_stlr_i .. ...... .. . imm:s9 .. rn:5 rt:5 &ldapr_stlr_i
STLR_i sz:2 011001 00 0 ......... 00 ..... ..... @ldapr_stlr_i sign=0 ext=0
LDAPR_i sz:2 011001 01 0 ......... 00 ..... ..... @ldapr_stlr_i sign=0 ext=0
LDAPR_i 00 011001 10 0 ......... 00 ..... ..... @ldapr_stlr_i sign=1 ext=0 sz=0
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 05/69] target/arm: LDAPR should honour SCTLR_ELx.nAA
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (3 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 04/69] target/arm: Fix handling of LDAPR/STLR with negative offset Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 06/69] target/arm: Use float_status copy in sme_fmopa_s Michael Tokarev
` (63 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Richard Henderson, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
In commit c1a1f80518d360b when we added the FEAT_LSE2 relaxations to
the alignment requirements for atomic and ordered loads and stores,
we didn't quite get it right for LDAPR/LDAPRH/LDAPRB with no
immediate offset. These instructions were handled in the old decoder
as part of disas_ldst_atomic(), but unlike all the other insns that
function decoded (LDADD, LDCLR, etc) these insns are "ordered", not
"atomic", so they should be using check_ordered_align() rather than
check_atomic_align(). Commit c1a1f80518d360b used
check_atomic_align() regardless for everything in
disas_ldst_atomic(). We then carried that incorrect check over in
the decodetree conversion, where LDAPR/LDAPRH/LDAPRB are now handled
by trans_LDAPR().
The effect is that when FEAT_LSE2 is implemented, these instructions
don't honour the SCTLR_ELx.nAA bit and will generate alignment
faults when they should not.
(The LDAPR insns with an immediate offset were in disas_ldst_ldapr_stlr()
and then in trans_LDAPR_i() and trans_STLR_i(), and have always used
the correct check_ordered_align().)
Use check_ordered_align() in trans_LDAPR().
Cc: qemu-stable@nongnu.org
Fixes: c1a1f80518d360b ("target/arm: Relax ordered/atomic alignment checks for LSE2")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240709134504.3500007-3-peter.maydell@linaro.org
(cherry picked from commit 25489b521b61b874c4c6583956db0012a3674e3a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 2666d52711..922a16e5d4 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -3428,7 +3428,7 @@ static bool trans_LDAPR(DisasContext *s, arg_LDAPR *a)
if (a->rn == 31) {
gen_check_sp_alignment(s);
}
- mop = check_atomic_align(s, a->rn, a->sz);
+ mop = check_ordered_align(s, a->rn, 0, false, a->sz);
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, a->rn), false,
a->rn != 31, mop);
/*
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 06/69] target/arm: Use float_status copy in sme_fmopa_s
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (4 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 05/69] target/arm: LDAPR should honour SCTLR_ELx.nAA Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 07/69] target/arm: Use FPST_F16 for SME FMOPA (widening) Michael Tokarev
` (62 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Daniyal Khan, Richard Henderson,
Philippe Mathieu-Daudé, Alex Bennée, Peter Maydell,
Michael Tokarev
From: Daniyal Khan <danikhan632@gmail.com>
We made a copy above because the fp exception flags
are not propagated back to the FPST register, but
then failed to use the copy.
Cc: qemu-stable@nongnu.org
Fixes: 558e956c719 ("target/arm: Implement FMOPA, FMOPS (non-widening)")
Signed-off-by: Daniyal Khan <danikhan632@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20240717060149.204788-2-richard.henderson@linaro.org
[rth: Split from a larger patch]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 31d93fedf41c24b0badb38cd9317590d1ef74e37)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
index e2e0575039..5a6dd76489 100644
--- a/target/arm/tcg/sme_helper.c
+++ b/target/arm/tcg/sme_helper.c
@@ -916,7 +916,7 @@ void HELPER(sme_fmopa_s)(void *vza, void *vzn, void *vzm, void *vpn,
if (pb & 1) {
uint32_t *a = vza_row + H1_4(col);
uint32_t *m = vzm + H1_4(col);
- *a = float32_muladd(n, *m, *a, 0, vst);
+ *a = float32_muladd(n, *m, *a, 0, &fpst);
}
col += 4;
pb >>= 4;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 07/69] target/arm: Use FPST_F16 for SME FMOPA (widening)
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (5 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 06/69] target/arm: Use float_status copy in sme_fmopa_s Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 08/69] hvf: arm: Do not advance PC when raising an exception Michael Tokarev
` (61 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Richard Henderson, Daniyal Khan, Alex Bennée,
Peter Maydell, Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
This operation has float16 inputs and thus must use
the FZ16 control not the FZ control.
Cc: qemu-stable@nongnu.org
Fixes: 3916841ac75 ("target/arm: Implement FMOPA, FMOPS (widening)")
Reported-by: Daniyal Khan <danikhan632@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20240717060149.204788-3-richard.henderson@linaro.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2374
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 207d30b5fdb5b45a36f26eefcf52fe2c1714dd4f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
index 46c7fce8b4..185a8a917b 100644
--- a/target/arm/tcg/translate-sme.c
+++ b/target/arm/tcg/translate-sme.c
@@ -304,6 +304,7 @@ static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz,
}
static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
+ ARMFPStatusFlavour e_fpst,
gen_helper_gvec_5_ptr *fn)
{
int svl = streaming_vec_reg_size(s);
@@ -319,15 +320,18 @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
zm = vec_full_reg_ptr(s, a->zm);
pn = pred_full_reg_ptr(s, a->pn);
pm = pred_full_reg_ptr(s, a->pm);
- fpst = fpstatus_ptr(FPST_FPCR);
+ fpst = fpstatus_ptr(e_fpst);
fn(za, zn, zm, pn, pm, fpst, tcg_constant_i32(desc));
return true;
}
-TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_h)
-TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s)
-TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d)
+TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_fpst, a,
+ MO_32, FPST_FPCR_F16, gen_helper_sme_fmopa_h)
+TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a,
+ MO_32, FPST_FPCR, gen_helper_sme_fmopa_s)
+TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a,
+ MO_64, FPST_FPCR, gen_helper_sme_fmopa_d)
/* TODO: FEAT_EBF16 */
TRANS_FEAT(BFMOPA, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_bfmopa)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 08/69] hvf: arm: Do not advance PC when raising an exception
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (6 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 07/69] target/arm: Use FPST_F16 for SME FMOPA (widening) Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 09/69] hw/nvme: fix memory leak in nvme_dsm Michael Tokarev
` (60 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Akihiko Odaki, Peter Maydell, Michael Tokarev
From: Akihiko Odaki <akihiko.odaki@daynix.com>
hvf did not advance PC when raising an exception for most unhandled
system registers, but it mistakenly advanced PC when raising an
exception for GICv3 registers.
Cc: qemu-stable@nongnu.org
Fixes: a2260983c655 ("hvf: arm: Add support for GICv3")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-id: 20240716-pmu-v3-4-8c7c1858a227@daynix.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 30a1690f2402e6c1582d5b3ebcf7940bfe2fad4b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index ee657f455b..ddf49087ec 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1277,6 +1277,7 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
/* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
if (!hvf_sysreg_read_cp(cpu, reg, &val)) {
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
+ return 1;
}
break;
case SYSREG_DBGBVR0_EL1:
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 09/69] hw/nvme: fix memory leak in nvme_dsm
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (7 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 08/69] hvf: arm: Do not advance PC when raising an exception Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 10/69] hw/cxl/cxl-host: Fix segmentation fault when getting cxl-fmw property Michael Tokarev
` (59 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Zheyu Ma, Klaus Jensen, Michael Tokarev
From: Zheyu Ma <zheyuma97@gmail.com>
The allocated memory to hold LBA ranges leaks in the nvme_dsm function. This
happens because the allocated memory for iocb->range is not freed in all
error handling paths.
Fix this by adding a free to ensure that the allocated memory is properly freed.
ASAN log:
==3075137==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 480 byte(s) in 6 object(s) allocated from:
#0 0x55f1f8a0eddd in malloc llvm/compiler-rt/lib/asan/asan_malloc_linux.cpp:129:3
#1 0x7f531e0f6738 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5e738)
#2 0x55f1faf1f091 in blk_aio_get block/block-backend.c:2583:12
#3 0x55f1f945c74b in nvme_dsm hw/nvme/ctrl.c:2609:30
#4 0x55f1f945831b in nvme_io_cmd hw/nvme/ctrl.c:4470:16
#5 0x55f1f94561b7 in nvme_process_sq hw/nvme/ctrl.c:7039:29
Cc: qemu-stable@nongnu.org
Fixes: d7d1474fd85d ("hw/nvme: reimplement dsm to allow cancellation")
Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit c510fe78f1b7c966524489d6ba752107423b20c8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index e89f9f7808..652116085e 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -2592,6 +2592,7 @@ next:
done:
iocb->aiocb = NULL;
iocb->common.cb(iocb->common.opaque, iocb->ret);
+ g_free(iocb->range);
qemu_aio_unref(iocb);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 10/69] hw/cxl/cxl-host: Fix segmentation fault when getting cxl-fmw property
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (8 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 09/69] hw/nvme: fix memory leak in nvme_dsm Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 11/69] virtio-snd: add max size bounds check in input cb Michael Tokarev
` (58 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Zhao Liu, Li Zhijian, Xingtao Yao, Jonathan Cameron,
Michael S . Tsirkin, Michael Tokarev
From: Zhao Liu <zhao1.liu@intel.com>
QEMU crashes (Segmentation fault) when getting cxl-fmw property via
qmp:
(QEMU) qom-get path=machine property=cxl-fmw
This issue is caused by accessing wrong callback (opaque) type in
machine_get_cfmw().
cxl_machine_init() sets the callback as `CXLState *` type but
machine_get_cfmw() treats the callback as
`CXLFixedMemoryWindowOptionsList **`.
Fix this error by casting opaque to `CXLState *` type in
machine_get_cfmw().
Fixes: 03b39fcf64bc ("hw/cxl: Make the CXL fixed memory window setup a machine parameter.")
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
Reviewed-by: Xingtao Yao <yaoxt.fnst@fujitsu.com>
Link: https://lore.kernel.org/r/20240704093404.1848132-1-zhao1.liu@linux.intel.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20240705113956.941732-2-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a207d5f87d66f7933b50677e047498fc4af63e1f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
index c5f5fcfd64..e9f2543c43 100644
--- a/hw/cxl/cxl-host.c
+++ b/hw/cxl/cxl-host.c
@@ -315,7 +315,8 @@ static void machine_set_cxl(Object *obj, Visitor *v, const char *name,
static void machine_get_cfmw(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- CXLFixedMemoryWindowOptionsList **list = opaque;
+ CXLState *state = opaque;
+ CXLFixedMemoryWindowOptionsList **list = &state->cfmw_list;
visit_type_CXLFixedMemoryWindowOptionsList(v, name, list, errp);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 11/69] virtio-snd: add max size bounds check in input cb
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (9 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 10/69] hw/cxl/cxl-host: Fix segmentation fault when getting cxl-fmw property Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 12/69] virtio-snd: check for invalid param shift operands Michael Tokarev
` (57 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Manos Pitsidianakis, Zheyu Ma,
Philippe Mathieu-Daudé, Michael S . Tsirkin, Michael Tokarev
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
When reading input audio in the virtio-snd input callback,
virtio_snd_pcm_in_cb(), we do not check whether the iov can actually fit
the data buffer. This is because we use the buffer->size field as a
total-so-far accumulator instead of byte-size-left like in TX buffers.
This triggers an out of bounds write if the size of the virtio queue
element is equal to virtio_snd_pcm_status, which makes the available
space for audio data zero. This commit adds a check for reaching the
maximum buffer size before attempting any writes.
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2427
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-Id: <virtio-snd-fuzz-2427-fix-v1-manos.pitsidianakis@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 98e77e3dd8dd6e7aa9a7dffa60f49c8c8a49d4e3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 4a56c00ec9..541f0797ac 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -1261,7 +1261,7 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
{
VirtIOSoundPCMStream *stream = data;
VirtIOSoundPCMBuffer *buffer;
- size_t size;
+ size_t size, max_size;
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
while (!QSIMPLEQ_EMPTY(&stream->queue)) {
@@ -1275,7 +1275,12 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
continue;
}
+ max_size = iov_size(buffer->elem->in_sg, buffer->elem->in_num);
for (;;) {
+ if (buffer->size >= max_size) {
+ return_rx_buffer(stream, buffer);
+ break;
+ }
size = AUD_read(stream->voice.in,
buffer->data + buffer->size,
MIN(available, (stream->params.period_bytes -
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 12/69] virtio-snd: check for invalid param shift operands
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (10 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 11/69] virtio-snd: add max size bounds check in input cb Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 13/69] intel_iommu: fix FRCD construction macro Michael Tokarev
` (56 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Manos Pitsidianakis, Zheyu Ma,
Philippe Mathieu-Daudé, Michael S . Tsirkin, Michael Tokarev
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
When setting the parameters of a PCM stream, we compute the bit flag
with the format and rate values as shift operand to check if they are
set in supported_formats and supported_rates.
If the guest provides a format/rate value which when shifting 1 results
in a value bigger than the number of bits in
supported_formats/supported_rates, we must report an error.
Previously, this ended up triggering the not reached assertions later
when converting to internal QEMU values.
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2416
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-Id: <virtio-snd-fuzz-2416-fix-v1-manos.pitsidianakis@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 9b6083465fb8311f2410615f8303a41f580a2a20)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 541f0797ac..2b80072b04 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -282,11 +282,13 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
error_report("Number of channels is not supported.");
return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
}
- if (!(supported_formats & BIT(params->format))) {
+ if (BIT(params->format) > sizeof(supported_formats) ||
+ !(supported_formats & BIT(params->format))) {
error_report("Stream format is not supported.");
return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
}
- if (!(supported_rates & BIT(params->rate))) {
+ if (BIT(params->rate) > sizeof(supported_rates) ||
+ !(supported_rates & BIT(params->rate))) {
error_report("Stream rate is not supported.");
return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 13/69] intel_iommu: fix FRCD construction macro
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (11 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 12/69] virtio-snd: check for invalid param shift operands Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 14/69] target/i386: do not crash if microvm guest uses SGX CPUID leaves Michael Tokarev
` (55 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Clément Mathieu--Drif, Yi Liu, Zhenzhong Duan,
Minwoo Im, Michael S . Tsirkin, Michael Tokarev
From: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
The constant must be unsigned, otherwise the two's complement
overrides the other fields when a PASID is present.
Fixes: 1b2b12376c8a ("intel-iommu: PASID support")
Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Minwoo Im <minwoo.im@samsung.com>
Message-Id: <20240709142557.317271-2-clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a3c8d7e38550c3d5a46e6fa94ffadfa625a4861d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index f8cf99bddf..cbc4030031 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -267,7 +267,7 @@
/* For the low 64-bit of 128-bit */
#define VTD_FRCD_FI(val) ((val) & ~0xfffULL)
#define VTD_FRCD_PV(val) (((val) & 0xffffULL) << 40)
-#define VTD_FRCD_PP(val) (((val) & 0x1) << 31)
+#define VTD_FRCD_PP(val) (((val) & 0x1ULL) << 31)
#define VTD_FRCD_IR_IDX(val) (((val) & 0xffffULL) << 48)
/* DMA Remapping Fault Conditions */
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 14/69] target/i386: do not crash if microvm guest uses SGX CPUID leaves
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (12 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 13/69] intel_iommu: fix FRCD construction macro Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 15/69] chardev/char-win-stdio.c: restore old console mode Michael Tokarev
` (54 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Paolo Bonzini, Michael Tokarev
From: Paolo Bonzini <pbonzini@redhat.com>
sgx_epc_get_section assumes a PC platform is in use:
bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
{
PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
However, sgx_epc_get_section is called by CPUID regardless of whether
SGX state has been initialized or which platform is in use. Check
whether the machine has the right QOM class and if not behave as if
there are no EPC sections.
Fixes: 1dec2e1f19f ("i386: Update SGX CPUID info according to hardware/KVM/user input", 2021-09-30)
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2142
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 13be929aff804581b21e69087a9caf3698fd5c3c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index de76397bcf..25b2055d65 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -266,10 +266,12 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict)
bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
{
- PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+ PCMachineState *pcms =
+ (PCMachineState *)object_dynamic_cast(qdev_get_machine(),
+ TYPE_PC_MACHINE);
SGXEPCDevice *epc;
- if (pcms->sgx_epc.size == 0 || pcms->sgx_epc.nr_sections <= section_nr) {
+ if (!pcms || pcms->sgx_epc.size == 0 || pcms->sgx_epc.nr_sections <= section_nr) {
return true;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 15/69] chardev/char-win-stdio.c: restore old console mode
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (13 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 14/69] target/i386: do not crash if microvm guest uses SGX CPUID leaves Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 16/69] hw/intc/loongson_ipi: Access memory in little endian Michael Tokarev
` (53 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, songziming, Marc-André Lureau, Michael Tokarev
From: songziming <s.ziming@hotmail.com>
If I use `-serial stdio` on Windows, after QEMU exits, the terminal
could not handle arrow keys and tab any more. Because stdio backend
on Windows sets console mode to virtual terminal input when starts,
but does not restore the old mode when finalize.
This small patch saves the old console mode and set it back.
Signed-off-by: Ziming Song <s.ziming@hotmail.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <ME3P282MB25488BE7C39BF0C35CD0DA5D8CA82@ME3P282MB2548.AUSP282.PROD.OUTLOOK.COM>
(cherry picked from commit 903cc9e1173e0778caa50871e8275c898770c690)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index 1a18999e78..13325ca967 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -33,6 +33,7 @@
struct WinStdioChardev {
Chardev parent;
HANDLE hStdIn;
+ DWORD dwOldMode;
HANDLE hInputReadyEvent;
HANDLE hInputDoneEvent;
HANDLE hInputThread;
@@ -159,6 +160,7 @@ static void qemu_chr_open_stdio(Chardev *chr,
}
is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
+ stdio->dwOldMode = dwMode;
if (is_console) {
if (qemu_add_wait_object(stdio->hStdIn,
@@ -221,6 +223,9 @@ static void char_win_stdio_finalize(Object *obj)
{
WinStdioChardev *stdio = WIN_STDIO_CHARDEV(obj);
+ if (stdio->hStdIn != INVALID_HANDLE_VALUE) {
+ SetConsoleMode(stdio->hStdIn, stdio->dwOldMode);
+ }
if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
CloseHandle(stdio->hInputReadyEvent);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 16/69] hw/intc/loongson_ipi: Access memory in little endian
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (14 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 15/69] chardev/char-win-stdio.c: restore old console mode Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 17/69] hw/intc/loongson_ipi: Fix resource leak Michael Tokarev
` (52 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Bibo Mao, Philippe Mathieu-Daudé, Song Gao,
Richard Henderson, Jiaxun Yang, Michael Tokarev
From: Bibo Mao <maobibo@loongson.cn>
Loongson IPI is only available in little-endian,
so use that to access the guest memory (in case
we run on a big-endian host).
Cc: qemu-stable@nongnu.org
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Fixes: f6783e3438 ("hw/loongarch: Add LoongArch ipi interrupt support")
[PMD: Extracted from bigger commit, added commit description]
Co-Developed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Tested-by: Bibo Mao <maobibo@loongson.cn>
Acked-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Message-Id: <20240718133312.10324-3-philmd@linaro.org>
(cherry picked from commit 2465c89fb983eed670007742bd68c7d91b6d6f85)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: fixups for 9.0, for lack of:
v9.0.0-583-g91d0b151de4c "hw/intc/loongson_ipi: Implement IOCSR address space for MIPS"
v9.0.0-582-gb4a12dfc2132 "hw/intc/loongarch_ipi: Rename as loongson_ipi")
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index a184112b09..521731342c 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -13,6 +13,7 @@
#include "qapi/error.h"
#include "qemu/log.h"
#include "exec/address-spaces.h"
+#include "exec/memory.h"
#include "hw/loongarch/virt.h"
#include "migration/vmstate.h"
#include "target/loongarch/internals.h"
@@ -66,8 +67,8 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
* if the mask is 0, we need not to do anything.
*/
if ((val >> 27) & 0xf) {
- data = address_space_ldl(env->address_space_iocsr, addr,
- attrs, NULL);
+ data = address_space_ldl_le(env->address_space_iocsr, addr,
+ attrs, NULL);
for (i = 0; i < 4; i++) {
/* get mask for byte writing */
if (val & (0x1 << (27 + i))) {
@@ -78,8 +79,8 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
data &= mask;
data |= (val >> 32) & ~mask;
- address_space_stl(env->address_space_iocsr, addr,
- data, attrs, NULL);
+ address_space_stl_le(env->address_space_iocsr, addr,
+ data, attrs, NULL);
}
static int archid_cmp(const void *a, const void *b)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 17/69] hw/intc/loongson_ipi: Fix resource leak
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (15 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 16/69] hw/intc/loongson_ipi: Access memory in little endian Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 18/69] target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue Michael Tokarev
` (51 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Philippe Mathieu-Daudé, Song Gao,
Michael Tokarev
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Once initialised, QOM objects can be realized and
unrealized multiple times before being finalized.
Resources allocated in REALIZE must be deallocated
in an equivalent UNREALIZE handler.
Free the CPU array in loongson_ipi_unrealize()
instead of loongson_ipi_finalize().
Cc: qemu-stable@nongnu.org
Fixes: 5e90b8db382 ("hw/loongarch: Set iocsr address space per-board rather than percpu")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Message-Id: <20240723111405.14208-3-philmd@linaro.org>
(cherry picked from commit 0c2086bc7360565dfb9933181dafaefe2c94cddf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: rename loongson back to longarch for 9.0 due to lack of
v9.0.0-582-gb4a12dfc2132 "hw/intc/loongarch_ipi: Rename as loongson_ipi")
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index 521731342c..c210b51811 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -301,6 +301,13 @@ static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
}
}
+static void loongarch_ipi_unrealize(DeviceState *dev)
+{
+ LoongArchIPI *s = LOONGARCH_IPI(dev);
+
+ g_free(s->cpu);
+}
+
static const VMStateDescription vmstate_ipi_core = {
.name = "ipi-single",
.version_id = 2,
@@ -336,23 +343,16 @@ static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = loongarch_ipi_realize;
+ dc->unrealize = loongarch_ipi_unrealize;
device_class_set_props(dc, ipi_properties);
dc->vmsd = &vmstate_loongarch_ipi;
}
-static void loongarch_ipi_finalize(Object *obj)
-{
- LoongArchIPI *s = LOONGARCH_IPI(obj);
-
- g_free(s->cpu);
-}
-
static const TypeInfo loongarch_ipi_info = {
.name = TYPE_LOONGARCH_IPI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LoongArchIPI),
.class_init = loongarch_ipi_class_init,
- .instance_finalize = loongarch_ipi_finalize,
};
static void loongarch_ipi_register_types(void)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 18/69] target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (16 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 17/69] hw/intc/loongson_ipi: Fix resource leak Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 19/69] util/async.c: Forbid negative min/max in aio_context_set_thread_pool_params() Michael Tokarev
` (50 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Song Gao, Richard Henderson, Michael Tokarev
From: Song Gao <gaosong@loongson.cn>
When the lddir level is 4 and the base is a HugePage, we may try to put value 4
into a field in the TLBENTRY that is only 2 bits wide.
Fixes: Coverity CID 1547717
Fixes: 9c70db9a43388 ("target/loongarch: Fix tlb huge page loading issue")
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240724015853.1317396-1-gaosong@loongson.cn>
(cherry picked from commit a18ffbcf8b9fabfc6c850ebb1d3e40a21b885c67)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 57f5308632..2262005499 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -524,6 +524,7 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
if (unlikely(level == 4)) {
qemu_log_mask(LOG_GUEST_ERROR,
"Attempted use of level 4 huge page\n");
+ return base;
}
if (FIELD_EX64(base, TLBENTRY, LEVEL)) {
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 19/69] util/async.c: Forbid negative min/max in aio_context_set_thread_pool_params()
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (17 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 18/69] target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 20/69] Revert "qemu-char: do not operate on sources from finalize callbacks" Michael Tokarev
` (49 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Philippe Mathieu-Daudé,
Stefan Hajnoczi, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
aio_context_set_thread_pool_params() takes two int64_t arguments to
set the minimum and maximum number of threads in the pool. We do
some bounds checking on these, but we don't catch the case where the
inputs are negative. This means that later in the function when we
assign these inputs to the AioContext::thread_pool_min and
::thread_pool_max fields, which are of type int, the values might
overflow the smaller type.
A negative number of threads is meaningless, so make
aio_context_set_thread_pool_params() return an error if either min or
max are negative.
Resolves: Coverity CID 1547605
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240723150927.1396456-1-peter.maydell@linaro.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 851495571d14fe2226c52b9d423f88a4f5460836)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/util/async.c b/util/async.c
index 0467890052..3e3e4fc712 100644
--- a/util/async.c
+++ b/util/async.c
@@ -746,7 +746,7 @@ void aio_context_set_thread_pool_params(AioContext *ctx, int64_t min,
int64_t max, Error **errp)
{
- if (min > max || !max || min > INT_MAX || max > INT_MAX) {
+ if (min > max || max <= 0 || min < 0 || min > INT_MAX || max > INT_MAX) {
error_setg(errp, "bad thread-pool-min/thread-pool-max values");
return;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 20/69] Revert "qemu-char: do not operate on sources from finalize callbacks"
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (18 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 19/69] util/async.c: Forbid negative min/max in aio_context_set_thread_pool_params() Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 21/69] hw/virtio: Fix the de-initialization of vhost-user devices Michael Tokarev
` (48 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Sergey Dyasli, Paolo Bonzini, Michael Tokarev
From: Sergey Dyasli <sergey.dyasli@nutanix.com>
This reverts commit 2b316774f60291f57ca9ecb6a9f0712c532cae34.
After 038b4217884c ("Revert "chardev: use a child source for qio input
source"") we've been observing the "iwp->src == NULL" assertion
triggering periodically during the initial capabilities querying by
libvirtd. One of possible backtraces:
Thread 1 (Thread 0x7f16cd4f0700 (LWP 43858)):
0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
1 0x00007f16c6c21e65 in __GI_abort () at abort.c:79
2 0x00007f16c6c21d39 in __assert_fail_base at assert.c:92
3 0x00007f16c6c46e86 in __GI___assert_fail (assertion=assertion@entry=0x562e9bcdaadd "iwp->src == NULL", file=file@entry=0x562e9bcdaac8 "../chardev/char-io.c", line=line@entry=99, function=function@entry=0x562e9bcdab10 <__PRETTY_FUNCTION__.20549> "io_watch_poll_finalize") at assert.c:101
4 0x0000562e9ba20c2c in io_watch_poll_finalize (source=<optimized out>) at ../chardev/char-io.c:99
5 io_watch_poll_finalize (source=<optimized out>) at ../chardev/char-io.c:88
6 0x00007f16c904aae0 in g_source_unref_internal () from /lib64/libglib-2.0.so.0
7 0x00007f16c904baf9 in g_source_destroy_internal () from /lib64/libglib-2.0.so.0
8 0x0000562e9ba20db0 in io_remove_watch_poll (source=0x562e9d6720b0) at ../chardev/char-io.c:147
9 remove_fd_in_watch (chr=chr@entry=0x562e9d5f3800) at ../chardev/char-io.c:153
10 0x0000562e9ba23ffb in update_ioc_handlers (s=0x562e9d5f3800) at ../chardev/char-socket.c:592
11 0x0000562e9ba2072f in qemu_chr_fe_set_handlers_full at ../chardev/char-fe.c:279
12 0x0000562e9ba207a9 in qemu_chr_fe_set_handlers at ../chardev/char-fe.c:304
13 0x0000562e9ba2ca75 in monitor_qmp_setup_handlers_bh (opaque=0x562e9d4c2c60) at ../monitor/qmp.c:509
14 0x0000562e9bb6222e in aio_bh_poll (ctx=ctx@entry=0x562e9d4c2f20) at ../util/async.c:216
15 0x0000562e9bb4de0a in aio_poll (ctx=0x562e9d4c2f20, blocking=blocking@entry=true) at ../util/aio-posix.c:722
16 0x0000562e9b99dfaa in iothread_run (opaque=0x562e9d4c26f0) at ../iothread.c:63
17 0x0000562e9bb505a4 in qemu_thread_start (args=0x562e9d4c7ea0) at ../util/qemu-thread-posix.c:543
18 0x00007f16c70081ca in start_thread (arg=<optimized out>) at pthread_create.c:479
19 0x00007f16c6c398d3 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
io_remove_watch_poll(), which makes sure that iwp->src is NULL, calls
g_source_destroy() which finds that iwp->src is not NULL in the finalize
callback. This can only happen if another thread has managed to trigger
io_watch_poll_prepare() callback in the meantime.
Move iwp->src destruction back to the finalize callback to prevent the
described race, and also remove the stale comment. The deadlock glib bug
was fixed back in 2010 by b35820285668 ("gmain: move finalization of
GSource outside of context lock").
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sergey Dyasli <sergey.dyasli@nutanix.com>
Link: https://lore.kernel.org/r/20240712092659.216206-1-sergey.dyasli@nutanix.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e0bf95443ee9326d44031373420cf9f3513ee255)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/chardev/char-io.c b/chardev/char-io.c
index dab77b112e..3be17b51ca 100644
--- a/chardev/char-io.c
+++ b/chardev/char-io.c
@@ -87,16 +87,12 @@ static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
static void io_watch_poll_finalize(GSource *source)
{
- /*
- * Due to a glib bug, removing the last reference to a source
- * inside a finalize callback causes recursive locking (and a
- * deadlock). This is not a problem inside other callbacks,
- * including dispatch callbacks, so we call io_remove_watch_poll
- * to remove this source. At this point, iwp->src must
- * be NULL, or we would leak it.
- */
IOWatchPoll *iwp = io_watch_poll_from_source(source);
- assert(iwp->src == NULL);
+ if (iwp->src) {
+ g_source_destroy(iwp->src);
+ g_source_unref(iwp->src);
+ iwp->src = NULL;
+ }
}
static GSourceFuncs io_watch_poll_funcs = {
@@ -139,11 +135,6 @@ static void io_remove_watch_poll(GSource *source)
IOWatchPoll *iwp;
iwp = io_watch_poll_from_source(source);
- if (iwp->src) {
- g_source_destroy(iwp->src);
- g_source_unref(iwp->src);
- iwp->src = NULL;
- }
g_source_destroy(&iwp->parent);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 21/69] hw/virtio: Fix the de-initialization of vhost-user devices
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (19 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 20/69] Revert "qemu-char: do not operate on sources from finalize callbacks" Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 22/69] target/rx: Use target_ulong for address in LI Michael Tokarev
` (47 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Thomas Huth, Manos Pitsidianakis,
Michael S . Tsirkin, Michael Tokarev
From: Thomas Huth <thuth@redhat.com>
The unrealize functions of the various vhost-user devices are
calling the corresponding vhost_*_set_status() functions with a
status of 0 to shut down the device correctly.
Now these vhost_*_set_status() functions all follow this scheme:
bool should_start = virtio_device_should_start(vdev, status);
if (vhost_dev_is_started(&vvc->vhost_dev) == should_start) {
return;
}
if (should_start) {
/* ... do the initialization stuff ... */
} else {
/* ... do the cleanup stuff ... */
}
The problem here is virtio_device_should_start(vdev, 0) currently
always returns "true" since it internally only looks at vdev->started
instead of looking at the "status" parameter. Thus once the device
got started once, virtio_device_should_start() always returns true
and thus the vhost_*_set_status() functions return early, without
ever doing any clean-up when being called with status == 0. This
causes e.g. problems when trying to hot-plug and hot-unplug a vhost
user devices multiple times since the de-initialization step is
completely skipped during the unplug operation.
This bug has been introduced in commit 9f6bcfd99f ("hw/virtio: move
vm_running check to virtio_device_started") which replaced
should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
with
should_start = virtio_device_started(vdev, status);
which later got replaced by virtio_device_should_start(). This blocked
the possibility to set should_start to false in case the status flag
VIRTIO_CONFIG_S_DRIVER_OK was not set.
Fix it by adjusting the virtio_device_should_start() function to
only consider the status flag instead of vdev->started. Since this
function is only used in the various vhost_*_set_status() functions
for exactly the same purpose, it should be fine to fix it in this
central place there without any risk to change the behavior of other
code.
Fixes: 9f6bcfd99f ("hw/virtio: move vm_running check to virtio_device_started")
Buglink: https://issues.redhat.com/browse/RHEL-40708
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20240618121958.88673-1-thuth@redhat.com>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit d72479b11797c28893e1e3fc565497a9cae5ca16)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 7d5ffdc145..2eafad17b8 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -470,9 +470,9 @@ static inline bool virtio_device_started(VirtIODevice *vdev, uint8_t status)
* @vdev - the VirtIO device
* @status - the devices status bits
*
- * This is similar to virtio_device_started() but also encapsulates a
- * check on the VM status which would prevent a device starting
- * anyway.
+ * This is similar to virtio_device_started() but ignores vdev->started
+ * and also encapsulates a check on the VM status which would prevent a
+ * device from starting anyway.
*/
static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status)
{
@@ -480,7 +480,7 @@ static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status
return false;
}
- return virtio_device_started(vdev, status);
+ return status & VIRTIO_CONFIG_S_DRIVER_OK;
}
static inline void virtio_set_started(VirtIODevice *vdev, bool started)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 22/69] target/rx: Use target_ulong for address in LI
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (20 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 21/69] hw/virtio: Fix the de-initialization of vhost-user devices Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 23/69] hw/char/bcm2835_aux: Fix assert when receive FIFO fills up Michael Tokarev
` (46 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Thomas Huth, Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
Using int32_t meant that the address was sign-extended to uint64_t
when passing to translator_ld*, triggering an assert.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2453
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 83340193b991e7a974f117baa86a04db1fd835a9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/rx/translate.c b/target/rx/translate.c
index f6e9e0ec90..30d30770ac 100644
--- a/target/rx/translate.c
+++ b/target/rx/translate.c
@@ -86,7 +86,8 @@ static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
static uint32_t li(DisasContext *ctx, int sz)
{
- int32_t tmp, addr;
+ target_ulong addr;
+ uint32_t tmp;
CPURXState *env = ctx->env;
addr = ctx->base.pc_next;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 23/69] hw/char/bcm2835_aux: Fix assert when receive FIFO fills up
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (21 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 22/69] target/rx: Use target_ulong for address in LI Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 24/69] hw/misc/bcm2835_property: Fix handling of FRAMEBUFFER_SET_PALETTE Michael Tokarev
` (45 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Frederik van Hövell, Cryptjar,
Philippe Mathieu-Daudé, Peter Maydell, Michael Tokarev
From: Frederik van Hövell <frederik@fvhovell.nl>
When a bare-metal application on the raspi3 board reads the
AUX_MU_STAT_REG MMIO register while the device's buffer is
at full receive FIFO capacity
(i.e. `s->read_count == BCM2835_AUX_RX_FIFO_LEN`) the
assertion `assert(s->read_count < BCM2835_AUX_RX_FIFO_LEN)`
fails.
Reported-by: Cryptjar <cryptjar@junk.studio>
Suggested-by: Cryptjar <cryptjar@junk.studio>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/459
Signed-off-by: Frederik van Hövell <frederik@fvhovell.nl>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
[PMM: commit message tweaks]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 546d574b11e02bfd5b15cdf1564842c14516dfab)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index 83990e20f7..fca2f27a55 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -138,7 +138,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
res = 0x30e; /* space in the output buffer, empty tx fifo, idle tx/rx */
if (s->read_count > 0) {
res |= 0x1; /* data in input buffer */
- assert(s->read_count < BCM2835_AUX_RX_FIFO_LEN);
+ assert(s->read_count <= BCM2835_AUX_RX_FIFO_LEN);
res |= ((uint32_t)s->read_count) << 16; /* rx fifo fill level */
}
return res;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 24/69] hw/misc/bcm2835_property: Fix handling of FRAMEBUFFER_SET_PALETTE
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (22 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 23/69] hw/char/bcm2835_aux: Fix assert when receive FIFO fills up Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 25/69] target/arm: Don't assert for 128-bit tile accesses when SVL is 128 Michael Tokarev
` (44 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Philippe Mathieu-Daudé,
Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
The documentation of the "Set palette" mailbox property at
https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#set-palette
says it has the form:
Length: 24..1032
Value:
u32: offset: first palette index to set (0-255)
u32: length: number of palette entries to set (1-256)
u32...: RGBA palette values (offset to offset+length-1)
We get this wrong in a couple of ways:
* we aren't checking the offset and length are in range, so the guest
can make us spin for a long time by providing a large length
* the bounds check on our loop is wrong: we should iterate through
'length' palette entries, not 'length - offset' entries
Fix the loop to implement the bounds checks and get the loop
condition right. In the process, make the variables local to
this switch case, rather than function-global, so it's clearer
what type they are when reading the code.
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240723131029.1159908-2-peter.maydell@linaro.org
(cherry picked from commit 0892fffc2abaadfb5d8b79bb0250ae1794862560)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fix due to lack of
v9.0.0-1812-g5d5f1b60916a "hw/misc: Implement mailbox properties for customer OTP and device specific private keys"
also remove now-unused local `n' variable which gets removed in the next change in this file,
v9.0.0-2720-g32f1c201eedf "hw/misc/bcm2835_property: Avoid overflow in OTP access properties")
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index bdd9a6bbce..faa489491c 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -30,8 +30,6 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
uint32_t tot_len;
size_t resplen;
uint32_t tmp;
- int n;
- uint32_t offset, length, color;
/*
* Copy the current state of the framebuffer config; we will update
@@ -273,19 +271,25 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
resplen = 16;
break;
case RPI_FWREQ_FRAMEBUFFER_SET_PALETTE:
- offset = ldl_le_phys(&s->dma_as, value + 12);
- length = ldl_le_phys(&s->dma_as, value + 16);
- n = 0;
- while (n < length - offset) {
- color = ldl_le_phys(&s->dma_as, value + 20 + (n << 2));
- stl_le_phys(&s->dma_as,
- s->fbdev->vcram_base + ((offset + n) << 2), color);
- n++;
+ {
+ uint32_t offset = ldl_le_phys(&s->dma_as, value + 12);
+ uint32_t length = ldl_le_phys(&s->dma_as, value + 16);
+ int resp;
+
+ if (offset > 255 || length < 1 || length > 256) {
+ resp = 1; /* invalid request */
+ } else {
+ for (uint32_t e = 0; e < length; e++) {
+ uint32_t color = ldl_le_phys(&s->dma_as, value + 20 + (e << 2));
+ stl_le_phys(&s->dma_as,
+ s->fbdev->vcram_base + ((offset + e) << 2), color);
+ }
+ resp = 0;
}
- stl_le_phys(&s->dma_as, value + 12, 0);
+ stl_le_phys(&s->dma_as, value + 12, resp);
resplen = 4;
break;
-
+ }
case RPI_FWREQ_FRAMEBUFFER_GET_NUM_DISPLAYS:
stl_le_phys(&s->dma_as, value + 12, 1);
resplen = 4;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 25/69] target/arm: Don't assert for 128-bit tile accesses when SVL is 128
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (23 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 24/69] hw/misc/bcm2835_property: Fix handling of FRAMEBUFFER_SET_PALETTE Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 26/69] target/arm: Fix UMOPA/UMOPS of 16-bit values Michael Tokarev
` (43 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Richard Henderson, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
For an instruction which accesses a 128-bit element tile when
the SVL is also 128 (for example MOV z0.Q, p0/M, ZA0H.Q[w0,0]),
we will assert in get_tile_rowcol():
qemu-system-aarch64: ../../tcg/tcg-op.c:926: tcg_gen_deposit_z_i32: Assertion `len > 0' failed.
This happens because we calculate
len = ctz32(streaming_vec_reg_size(s)) - esz;$
but if the SVL and the element size are the same len is 0, and
the deposit operation asserts.
In this case the ZA storage contains exactly one 128 bit
element ZA tile, and the horizontal or vertical slice is just
that tile. This means that regardless of the index value in
the Ws register, we always access that tile. (In pseudocode terms,
we calculate (index + offset) MOD 1, which is 0.)
Special case the len == 0 case to avoid hitting the assertion
in tcg_gen_deposit_z_i32().
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240722172957.1041231-2-peter.maydell@linaro.org
(cherry picked from commit 56f1c0db928aae0b83fd91c89ddb226b137e2b21)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
index 185a8a917b..a50a419af2 100644
--- a/target/arm/tcg/translate-sme.c
+++ b/target/arm/tcg/translate-sme.c
@@ -49,7 +49,15 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
/* Prepare a power-of-two modulo via extraction of @len bits. */
len = ctz32(streaming_vec_reg_size(s)) - esz;
- if (vertical) {
+ if (!len) {
+ /*
+ * SVL is 128 and the element size is 128. There is exactly
+ * one 128x128 tile in the ZA storage, and so we calculate
+ * (Rs + imm) MOD 1, which is always 0. We need to special case
+ * this because TCG doesn't allow deposit ops with len 0.
+ */
+ tcg_gen_movi_i32(tmp, 0);
+ } else if (vertical) {
/*
* Compute the byte offset of the index within the tile:
* (index % (svl / size)) * size
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 26/69] target/arm: Fix UMOPA/UMOPS of 16-bit values
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (24 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 25/69] target/arm: Don't assert for 128-bit tile accesses when SVL is 128 Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 27/69] target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl() Michael Tokarev
` (42 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Richard Henderson, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
The UMOPA/UMOPS instructions are supposed to multiply unsigned 8 or
16 bit elements and accumulate the products into a 64-bit element.
In the Arm ARM pseudocode, this is done with the usual
infinite-precision signed arithmetic. However our implementation
doesn't quite get it right, because in the DEF_IMOP_64() macro we do:
sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0);
where NTYPE and MTYPE are uint16_t or int16_t. In the uint16_t case,
the C usual arithmetic conversions mean the values are converted to
"int" type and the multiply is done as a 32-bit multiply. This means
that if the inputs are, for example, 0xffff and 0xffff then the
result is 0xFFFE0001 as an int, which is then promoted to uint64_t
for the accumulation into sum; this promotion incorrectly sign
extends the multiply.
Avoid the incorrect sign extension by casting to int64_t before
the multiply, so we do the multiply as 64-bit signed arithmetic,
which is a type large enough that the multiply can never
overflow into the sign bit.
(The equivalent 8-bit operations in DEF_IMOP_32() are fine, because
the 8-bit multiplies can never overflow into the sign bit of a
32-bit integer.)
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2372
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240722172957.1041231-3-peter.maydell@linaro.org
(cherry picked from commit ea3f5a90f036734522e9af3bffd77e69e9f47355)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
index 5a6dd76489..f9001f5213 100644
--- a/target/arm/tcg/sme_helper.c
+++ b/target/arm/tcg/sme_helper.c
@@ -1146,10 +1146,10 @@ static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
uint64_t sum = 0; \
/* Apply P to N as a mask, making the inactive elements 0. */ \
n &= expand_pred_h(p); \
- sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
- sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
- sum += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
- sum += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
+ sum += (int64_t)(NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
+ sum += (int64_t)(NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
+ sum += (int64_t)(NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
+ sum += (int64_t)(NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
return neg ? a - sum : a + sum; \
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 27/69] target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl()
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (25 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 26/69] target/arm: Fix UMOPA/UMOPS of 16-bit values Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 28/69] target/arm: Ignore SMCR_EL2.LEN and SVCR_EL2.LEN if EL2 is not enabled Michael Tokarev
` (41 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Richard Henderson, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
The function tszimm_esz() returns a shift amount, or possibly -1 in
certain cases that correspond to unallocated encodings in the
instruction set. We catch these later in the trans_ functions
(generally with an "a-esz < 0" check), but before we do the
decodetree-generated code will also call tszimm_shr() or tszimm_sl(),
which will use the tszimm_esz() return value as a shift count without
checking that it is not negative, which is undefined behaviour.
Avoid the UB by checking the return value in tszimm_shr() and
tszimm_shl().
Cc: qemu-stable@nongnu.org
Resolves: Coverity CID 1547617, 1547694
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240722172957.1041231-4-peter.maydell@linaro.org
(cherry picked from commit 76916dfa89e8900639c1055c07a295c06628a0bc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index ada05aa530..466a19c25a 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -50,13 +50,27 @@ static int tszimm_esz(DisasContext *s, int x)
static int tszimm_shr(DisasContext *s, int x)
{
- return (16 << tszimm_esz(s, x)) - x;
+ /*
+ * We won't use the tszimm_shr() value if tszimm_esz() returns -1 (the
+ * trans function will check for esz < 0), so we can return any
+ * value we like from here in that case as long as we avoid UB.
+ */
+ int esz = tszimm_esz(s, x);
+ if (esz < 0) {
+ return esz;
+ }
+ return (16 << esz) - x;
}
/* See e.g. LSL (immediate, predicated). */
static int tszimm_shl(DisasContext *s, int x)
{
- return x - (8 << tszimm_esz(s, x));
+ /* As with tszimm_shr(), value will be unused if esz < 0 */
+ int esz = tszimm_esz(s, x);
+ if (esz < 0) {
+ return esz;
+ }
+ return x - (8 << esz);
}
/* The SH bit is in bit 8. Extract the low 8 and shift. */
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 28/69] target/arm: Ignore SMCR_EL2.LEN and SVCR_EL2.LEN if EL2 is not enabled
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (26 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 27/69] target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl() Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 29/69] docs/sphinx/depfile.py: Handle env.doc2path() returning a Path not a str Michael Tokarev
` (40 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Richard Henderson, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
When determining the current vector length, the SMCR_EL2.LEN and
SVCR_EL2.LEN settings should only be considered if EL2 is enabled
(compare the pseudocode CurrentSVL and CurrentNSVL which call
EL2Enabled()).
We were checking against ARM_FEATURE_EL2 rather than calling
arm_is_el2_enabled(), which meant that we would look at
SMCR_EL2/SVCR_EL2 when in Secure EL1 or Secure EL0 even if Secure EL2
was not enabled.
Use the correct check in sve_vqm1_for_el_sm().
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240722172957.1041231-5-peter.maydell@linaro.org
(cherry picked from commit f573ac059ed060234fcef4299fae9e500d357c33)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/helper.c b/target/arm/helper.c
index a620481d7c..42044ae14b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7191,7 +7191,7 @@ uint32_t sve_vqm1_for_el_sm(CPUARMState *env, int el, bool sm)
if (el <= 1 && !el_is_in_host(env, el)) {
len = MIN(len, 0xf & (uint32_t)cr[1]);
}
- if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) {
+ if (el <= 2 && arm_is_el2_enabled(env)) {
len = MIN(len, 0xf & (uint32_t)cr[2]);
}
if (arm_feature(env, ARM_FEATURE_EL3)) {
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 29/69] docs/sphinx/depfile.py: Handle env.doc2path() returning a Path not a str
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (27 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 28/69] target/arm: Ignore SMCR_EL2.LEN and SVCR_EL2.LEN if EL2 is not enabled Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 30/69] hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb() Michael Tokarev
` (39 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Philippe Mathieu-Daudé,
Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
In newer versions of Sphinx the env.doc2path() API is going to change
to return a Path object rather than a str. This was originally visible
in Sphinx 8.0.0rc1, but has been rolled back for the final 8.0.0
release. However it will probably emit a deprecation warning and is
likely to change for good in 9.0:
https://github.com/sphinx-doc/sphinx/issues/12686
Our use in depfile.py assumes a str, and if it is passed a Path
it will fall over:
Handler <function write_depfile at 0x77a1775ff560> for event 'build-finished' threw an exception (exception: unsupported operand type(s) for +: 'PosixPath' and 'str')
Wrapping the env.doc2path() call in str() will coerce a Path object
to the str we expect, and have no effect in older Sphinx versions
that do return a str.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2458
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240729120533.2486427-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 48e5b5f994bccf161dd88a67fdd819d4bfb400f1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/docs/sphinx/depfile.py b/docs/sphinx/depfile.py
index afdcbcec6e..e74be6af98 100644
--- a/docs/sphinx/depfile.py
+++ b/docs/sphinx/depfile.py
@@ -19,7 +19,7 @@
def get_infiles(env):
for x in env.found_docs:
- yield env.doc2path(x)
+ yield str(env.doc2path(x))
yield from ((os.path.join(env.srcdir, dep)
for dep in env.dependencies[x]))
for mod in sys.modules.values():
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 30/69] hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb()
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (28 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 29/69] docs/sphinx/depfile.py: Handle env.doc2path() returning a Path not a str Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 31/69] hw/arm/mps2-tz.c: fix RX/TX interrupts order Michael Tokarev
` (38 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Michael S . Tsirkin, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
In amdvi_update_iotlb() we will only put a new entry in the hash
table if to_cache.perm is not IOMMU_NONE. However we allocate the
memory for the new AMDVIIOTLBEntry and for the hash table key
regardless. This means that in the IOMMU_NONE case we will leak the
memory we alloacted.
Move the allocations into the if() to the point where we know we're
going to add the item to the hash table.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2452
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20240731170019.3590563-1-peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 9a45b0761628cc59267b3283a85d15294464ac31)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 6d4fde72f9..87643d2891 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -357,12 +357,12 @@ static void amdvi_update_iotlb(AMDVIState *s, uint16_t devid,
uint64_t gpa, IOMMUTLBEntry to_cache,
uint16_t domid)
{
- AMDVIIOTLBEntry *entry = g_new(AMDVIIOTLBEntry, 1);
- uint64_t *key = g_new(uint64_t, 1);
- uint64_t gfn = gpa >> AMDVI_PAGE_SHIFT_4K;
-
/* don't cache erroneous translations */
if (to_cache.perm != IOMMU_NONE) {
+ AMDVIIOTLBEntry *entry = g_new(AMDVIIOTLBEntry, 1);
+ uint64_t *key = g_new(uint64_t, 1);
+ uint64_t gfn = gpa >> AMDVI_PAGE_SHIFT_4K;
+
trace_amdvi_cache_update(domid, PCI_BUS_NUM(devid), PCI_SLOT(devid),
PCI_FUNC(devid), gpa, to_cache.translated_addr);
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 31/69] hw/arm/mps2-tz.c: fix RX/TX interrupts order
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (29 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 30/69] hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb() Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 32/69] target/arm: Handle denormals correctly for FMOPA (widening) Michael Tokarev
` (37 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Marco Palumbi, Peter Maydell, Michael Tokarev
From: Marco Palumbi <Marco.Palumbi@tii.ae>
The order of the RX and TX interrupts are swapped.
This commit fixes the order as per the following documents:
* https://developer.arm.com/documentation/dai0505/latest/
* https://developer.arm.com/documentation/dai0521/latest/
* https://developer.arm.com/documentation/dai0524/latest/
* https://developer.arm.com/documentation/dai0547/latest/
Cc: qemu-stable@nongnu.org
Signed-off-by: Marco Palumbi <Marco.Palumbi@tii.ae>
Message-id: 20240730073123.72992-1-marco@palumbi.it
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 5a558be93ad628e5bed6e0ee062870f49251725c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index a2d18afd79..aec57c0d68 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -435,7 +435,7 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
const char *name, hwaddr size,
const int *irqs, const PPCExtraData *extradata)
{
- /* The irq[] array is tx, rx, combined, in that order */
+ /* The irq[] array is rx, tx, combined, in that order */
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
CMSDKAPBUART *uart = opaque;
int i = uart - &mms->uart[0];
@@ -447,8 +447,8 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->apb_periph_frq);
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
s = SYS_BUS_DEVICE(uart);
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[1]));
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[0]));
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 32/69] target/arm: Handle denormals correctly for FMOPA (widening)
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (30 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 31/69] hw/arm/mps2-tz.c: fix RX/TX interrupts order Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 33/69] virtio-net: Ensure queue index fits with RSS Michael Tokarev
` (36 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Richard Henderson, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
The FMOPA (widening) SME instruction takes pairs of half-precision
floating point values, widens them to single-precision, does a
two-way dot product and accumulates the results into a
single-precision destination. We don't quite correctly handle the
FPCR bits FZ and FZ16 which control flushing of denormal inputs and
outputs. This is because at the moment we pass a single float_status
value to the helper function, which then uses that configuration for
all the fp operations it does. However, because the inputs to this
operation are float16 and the outputs are float32 we need to use the
fp_status_f16 for the float16 input widening but the normal fp_status
for everything else. Otherwise we will apply the flushing control
FPCR.FZ16 to the 32-bit output rather than the FPCR.FZ control, and
incorrectly flush a denormal output to zero when we should not (or
vice-versa).
(In commit 207d30b5fdb5b we tried to fix the FZ handling but
didn't get it right, switching from "use FPCR.FZ for everything" to
"use FPCR.FZ16 for everything".)
(Mjt: it is commit 43929c818c4b in stable-9.0)
Pass the CPU env to the sme_fmopa_h helper instead of an fp_status
pointer, and have the helper pass an extra fp_status into the
f16_dotadd() function so that we can use the right status for the
right parts of this operation.
Cc: qemu-stable@nongnu.org
Fixes: 207d30b5fdb5 ("target/arm: Use FPST_F16 for SME FMOPA (widening)")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2373
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 55f9f4ee018c5ccea81d8c8c586756d7711ae46f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/helper-sme.h b/target/arm/tcg/helper-sme.h
index 27eef49a11..d22bf9d21b 100644
--- a/target/arm/tcg/helper-sme.h
+++ b/target/arm/tcg/helper-sme.h
@@ -121,7 +121,7 @@ DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sme_fmopa_h, TCG_CALL_NO_RWG,
- void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
+ void, ptr, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
index f9001f5213..3906bb51c0 100644
--- a/target/arm/tcg/sme_helper.c
+++ b/target/arm/tcg/sme_helper.c
@@ -976,12 +976,23 @@ static inline uint32_t f16mop_adj_pair(uint32_t pair, uint32_t pg, uint32_t neg)
}
static float32 f16_dotadd(float32 sum, uint32_t e1, uint32_t e2,
- float_status *s_std, float_status *s_odd)
+ float_status *s_f16, float_status *s_std,
+ float_status *s_odd)
{
- float64 e1r = float16_to_float64(e1 & 0xffff, true, s_std);
- float64 e1c = float16_to_float64(e1 >> 16, true, s_std);
- float64 e2r = float16_to_float64(e2 & 0xffff, true, s_std);
- float64 e2c = float16_to_float64(e2 >> 16, true, s_std);
+ /*
+ * We need three different float_status for different parts of this
+ * operation:
+ * - the input conversion of the float16 values must use the
+ * f16-specific float_status, so that the FPCR.FZ16 control is applied
+ * - operations on float32 including the final accumulation must use
+ * the normal float_status, so that FPCR.FZ is applied
+ * - we have pre-set-up copy of s_std which is set to round-to-odd,
+ * for the multiply (see below)
+ */
+ float64 e1r = float16_to_float64(e1 & 0xffff, true, s_f16);
+ float64 e1c = float16_to_float64(e1 >> 16, true, s_f16);
+ float64 e2r = float16_to_float64(e2 & 0xffff, true, s_f16);
+ float64 e2c = float16_to_float64(e2 >> 16, true, s_f16);
float64 t64;
float32 t32;
@@ -1003,20 +1014,23 @@ static float32 f16_dotadd(float32 sum, uint32_t e1, uint32_t e2,
}
void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn,
- void *vpm, void *vst, uint32_t desc)
+ void *vpm, CPUARMState *env, uint32_t desc)
{
intptr_t row, col, oprsz = simd_maxsz(desc);
uint32_t neg = simd_data(desc) * 0x80008000u;
uint16_t *pn = vpn, *pm = vpm;
- float_status fpst_odd, fpst_std;
+ float_status fpst_odd, fpst_std, fpst_f16;
/*
- * Make a copy of float_status because this operation does not
- * update the cumulative fp exception status. It also produces
- * default nans. Make a second copy with round-to-odd -- see above.
+ * Make copies of fp_status and fp_status_f16, because this operation
+ * does not update the cumulative fp exception status. It also
+ * produces default NaNs. We also need a second copy of fp_status with
+ * round-to-odd -- see above.
*/
- fpst_std = *(float_status *)vst;
+ fpst_f16 = env->vfp.fp_status_f16;
+ fpst_std = env->vfp.fp_status;
set_default_nan_mode(true, &fpst_std);
+ set_default_nan_mode(true, &fpst_f16);
fpst_odd = fpst_std;
set_float_rounding_mode(float_round_to_odd, &fpst_odd);
@@ -1036,7 +1050,8 @@ void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn,
uint32_t m = *(uint32_t *)(vzm + H1_4(col));
m = f16mop_adj_pair(m, pcol, 0);
- *a = f16_dotadd(*a, n, m, &fpst_std, &fpst_odd);
+ *a = f16_dotadd(*a, n, m,
+ &fpst_f16, &fpst_std, &fpst_odd);
}
col += 4;
pcol >>= 4;
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
index a50a419af2..ae42ddef7b 100644
--- a/target/arm/tcg/translate-sme.c
+++ b/target/arm/tcg/translate-sme.c
@@ -334,8 +334,29 @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
return true;
}
-TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_fpst, a,
- MO_32, FPST_FPCR_F16, gen_helper_sme_fmopa_h)
+static bool do_outprod_env(DisasContext *s, arg_op *a, MemOp esz,
+ gen_helper_gvec_5_ptr *fn)
+{
+ int svl = streaming_vec_reg_size(s);
+ uint32_t desc = simd_desc(svl, svl, a->sub);
+ TCGv_ptr za, zn, zm, pn, pm;
+
+ if (!sme_smza_enabled_check(s)) {
+ return true;
+ }
+
+ za = get_tile(s, esz, a->zad);
+ zn = vec_full_reg_ptr(s, a->zn);
+ zm = vec_full_reg_ptr(s, a->zm);
+ pn = pred_full_reg_ptr(s, a->pn);
+ pm = pred_full_reg_ptr(s, a->pm);
+
+ fn(za, zn, zm, pn, pm, tcg_env, tcg_constant_i32(desc));
+ return true;
+}
+
+TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_env, a,
+ MO_32, gen_helper_sme_fmopa_h)
TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a,
MO_32, FPST_FPCR, gen_helper_sme_fmopa_s)
TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a,
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 33/69] virtio-net: Ensure queue index fits with RSS
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (31 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 32/69] target/arm: Handle denormals correctly for FMOPA (widening) Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 34/69] virtio-net: Fix network stall at the host side waiting for kick Michael Tokarev
` (35 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Akihiko Odaki, Zhibin Hu, Michael S . Tsirkin,
Jason Wang, Michael Tokarev
From: Akihiko Odaki <akihiko.odaki@daynix.com>
Ensure the queue index points to a valid queue when software RSS
enabled. The new calculation matches with the behavior of Linux's TAP
device with the RSS eBPF program.
Fixes: 4474e37a5b3a ("virtio-net: implement RX RSS processing")
Reported-by: Zhibin Hu <huzhibin5@huawei.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit f1595ceb9aad36a6c1da95bcb77ab9509b38822d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Fixes: CVE-2024-6505
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3644bfd91b..f48588638d 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1949,7 +1949,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
if (!no_rss && n->rss_data.enabled && n->rss_data.enabled_software_rss) {
int index = virtio_net_process_rss(nc, buf, size);
if (index >= 0) {
- NetClientState *nc2 = qemu_get_subqueue(n->nic, index);
+ NetClientState *nc2 =
+ qemu_get_subqueue(n->nic, index % n->curr_queue_pairs);
return virtio_net_receive_rcu(nc2, buf, size, true);
}
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 34/69] virtio-net: Fix network stall at the host side waiting for kick
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (32 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 33/69] virtio-net: Ensure queue index fits with RSS Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 35/69] net: Reinstate '-net nic, model=help' output as documented in man page Michael Tokarev
` (34 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, thomas, Michael S . Tsirkin, Jason Wang,
Michael Tokarev
From: thomas <east.moutain.yang@gmail.com>
Patch 06b12970174 ("virtio-net: fix network stall under load")
added double-check to test whether the available buffer size
can satisfy the request or not, in case the guest has added
some buffers to the avail ring simultaneously after the first
check. It will be lucky if the available buffer size becomes
okay after the double-check, then the host can send the packet
to the guest. If the buffer size still can't satisfy the request,
even if the guest has added some buffers, viritio-net would
stall at the host side forever.
The patch enables notification and checks whether the guest has
added some buffers since last check of available buffers when
the available buffers are insufficient. If no buffer is added,
return false, else recheck the available buffers in the loop.
If the available buffers are sufficient, disable notification
and return true.
Changes:
1. Change the return type of virtqueue_get_avail_bytes() from void
to int, it returns an opaque that represents the shadow_avail_idx
of the virtqueue on success, else -1 on error.
2. Add a new API: virtio_queue_enable_notification_and_check(),
it takes an opaque as input arg which is returned from
virtqueue_get_avail_bytes(). It enables notification firstly,
then checks whether the guest has added some buffers since
last check of available buffers or not by virtio_queue_poll(),
return ture if yes.
The patch also reverts patch "06b12970174".
The case below can reproduce the stall.
Guest 0
+--------+
| iperf |
---------------> | server |
Host | +--------+
+--------+ | ...
| iperf |----
| client |---- Guest n
+--------+ | +--------+
| | iperf |
---------------> | server |
+--------+
Boot many guests from qemu with virtio network:
qemu ... -netdev tap,id=net_x \
-device virtio-net-pci-non-transitional,\
iommu_platform=on,mac=xx:xx:xx:xx:xx:xx,netdev=net_x
Each guest acts as iperf server with commands below:
iperf3 -s -D -i 10 -p 8001
iperf3 -s -D -i 10 -p 8002
The host as iperf client:
iperf3 -c guest_IP -p 8001 -i 30 -w 256k -P 20 -t 40000
iperf3 -c guest_IP -p 8002 -i 30 -w 256k -P 20 -t 40000
After some time, the host loses connection to the guest,
the guest can send packet to the host, but can't receive
packet from the host.
It's more likely to happen if SWIOTLB is enabled in the guest,
allocating and freeing bounce buffer takes some CPU ticks,
copying from/to bounce buffer takes more CPU ticks, compared
with that there is no bounce buffer in the guest.
Once the rate of producing packets from the host approximates
the rate of receiveing packets in the guest, the guest would
loop in NAPI.
receive packets ---
| |
v |
free buf virtnet_poll
| |
v |
add buf to avail ring ---
|
| need kick the host?
| NAPI continues
v
receive packets ---
| |
v |
free buf virtnet_poll
| |
v |
add buf to avail ring ---
|
v
... ...
On the other hand, the host fetches free buf from avail
ring, if the buf in the avail ring is not enough, the
host notifies the guest the event by writing the avail
idx read from avail ring to the event idx of used ring,
then the host goes to sleep, waiting for the kick signal
from the guest.
Once the guest finds the host is waiting for kick singal
(in virtqueue_kick_prepare_split()), it kicks the host.
The host may stall forever at the sequences below:
Host Guest
------------ -----------
fetch buf, send packet receive packet ---
... ... |
fetch buf, send packet add buf |
... add buf virtnet_poll
buf not enough avail idx-> add buf |
read avail idx add buf |
add buf ---
receive packet ---
write event idx ... |
wait for kick add buf virtnet_poll
... |
---
no more packet, exit NAPI
In the first loop of NAPI above, indicated in the range of
virtnet_poll above, the host is sending packets while the
guest is receiving packets and adding buffers.
step 1: The buf is not enough, for example, a big packet
needs 5 buf, but the available buf count is 3.
The host read current avail idx.
step 2: The guest adds some buf, then checks whether the
host is waiting for kick signal, not at this time.
The used ring is not empty, the guest continues
the second loop of NAPI.
step 3: The host writes the avail idx read from avail
ring to used ring as event idx via
virtio_queue_set_notification(q->rx_vq, 1).
step 4: At the end of the second loop of NAPI, recheck
whether kick is needed, as the event idx in the
used ring written by the host is beyound the
range of kick condition, the guest will not
send kick signal to the host.
Fixes: 06b12970174 ("virtio-net: fix network stall under load")
Cc: qemu-stable@nongnu.org
Signed-off-by: Wencheng Yang <east.moutain.yang@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit f937309fbdbb48c354220a3e7110c202ae4aa7fa)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fixup in include/hw/virtio/virtio.h)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f48588638d..d4b979d343 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1680,24 +1680,28 @@ static bool virtio_net_can_receive(NetClientState *nc)
static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize)
{
+ int opaque;
+ unsigned int in_bytes;
VirtIONet *n = q->n;
- if (virtio_queue_empty(q->rx_vq) ||
- (n->mergeable_rx_bufs &&
- !virtqueue_avail_bytes(q->rx_vq, bufsize, 0))) {
- virtio_queue_set_notification(q->rx_vq, 1);
-
- /* To avoid a race condition where the guest has made some buffers
- * available after the above check but before notification was
- * enabled, check for available buffers again.
- */
- if (virtio_queue_empty(q->rx_vq) ||
- (n->mergeable_rx_bufs &&
- !virtqueue_avail_bytes(q->rx_vq, bufsize, 0))) {
+
+ while (virtio_queue_empty(q->rx_vq) || n->mergeable_rx_bufs) {
+ opaque = virtqueue_get_avail_bytes(q->rx_vq, &in_bytes, NULL,
+ bufsize, 0);
+ /* Buffer is enough, disable notifiaction */
+ if (bufsize <= in_bytes) {
+ break;
+ }
+
+ if (virtio_queue_enable_notification_and_check(q->rx_vq, opaque)) {
+ /* Guest has added some buffers, try again */
+ continue;
+ } else {
return 0;
}
}
virtio_queue_set_notification(q->rx_vq, 0);
+
return 1;
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index fd2dfe3a6b..08fba6b2d8 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -743,6 +743,60 @@ int virtio_queue_empty(VirtQueue *vq)
}
}
+static bool virtio_queue_split_poll(VirtQueue *vq, unsigned shadow_idx)
+{
+ if (unlikely(!vq->vring.avail)) {
+ return false;
+ }
+
+ return (uint16_t)shadow_idx != vring_avail_idx(vq);
+}
+
+static bool virtio_queue_packed_poll(VirtQueue *vq, unsigned shadow_idx)
+{
+ VRingPackedDesc desc;
+ VRingMemoryRegionCaches *caches;
+
+ if (unlikely(!vq->vring.desc)) {
+ return false;
+ }
+
+ caches = vring_get_region_caches(vq);
+ if (!caches) {
+ return false;
+ }
+
+ vring_packed_desc_read(vq->vdev, &desc, &caches->desc,
+ shadow_idx, true);
+
+ return is_desc_avail(desc.flags, vq->shadow_avail_wrap_counter);
+}
+
+static bool virtio_queue_poll(VirtQueue *vq, unsigned shadow_idx)
+{
+ if (virtio_device_disabled(vq->vdev)) {
+ return false;
+ }
+
+ if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
+ return virtio_queue_packed_poll(vq, shadow_idx);
+ } else {
+ return virtio_queue_split_poll(vq, shadow_idx);
+ }
+}
+
+bool virtio_queue_enable_notification_and_check(VirtQueue *vq,
+ int opaque)
+{
+ virtio_queue_set_notification(vq, 1);
+
+ if (opaque >= 0) {
+ return virtio_queue_poll(vq, (unsigned)opaque);
+ } else {
+ return false;
+ }
+}
+
static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len)
{
@@ -1330,9 +1384,9 @@ err:
goto done;
}
-void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
- unsigned int *out_bytes,
- unsigned max_in_bytes, unsigned max_out_bytes)
+int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
+ unsigned int *out_bytes, unsigned max_in_bytes,
+ unsigned max_out_bytes)
{
uint16_t desc_size;
VRingMemoryRegionCaches *caches;
@@ -1365,7 +1419,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
caches);
}
- return;
+ return (int)vq->shadow_avail_idx;
err:
if (in_bytes) {
*in_bytes = 0;
@@ -1373,6 +1427,8 @@ err:
if (out_bytes) {
*out_bytes = 0;
}
+
+ return -1;
}
int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 2eafad17b8..8b4da92889 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -271,9 +271,13 @@ void qemu_put_virtqueue_element(VirtIODevice *vdev, QEMUFile *f,
VirtQueueElement *elem);
int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
unsigned int out_bytes);
-void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
- unsigned int *out_bytes,
- unsigned max_in_bytes, unsigned max_out_bytes);
+/**
+ * Return <0 on error or an opaque >=0 to pass to
+ * virtio_queue_enable_notification_and_check on success.
+ */
+int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
+ unsigned int *out_bytes, unsigned max_in_bytes,
+ unsigned max_out_bytes);
void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq);
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
@@ -307,6 +311,17 @@ int virtio_queue_ready(VirtQueue *vq);
int virtio_queue_empty(VirtQueue *vq);
+/**
+ * Enable notification and check whether guest has added some
+ * buffers since last call to virtqueue_get_avail_bytes.
+ *
+ * @opaque: value returned from virtqueue_get_avail_bytes
+ */
+bool virtio_queue_enable_notification_and_check(VirtQueue *vq,
+ int opaque);
+
+void virtio_queue_set_shadow_avail_idx(VirtQueue *vq, uint16_t idx);
+
/* Host binding interface. */
uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 35/69] net: Reinstate '-net nic, model=help' output as documented in man page
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (33 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 34/69] virtio-net: Fix network stall at the host side waiting for kick Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 36/69] migration/multifd: Fix multifd_send_setup cleanup when channel creation fails Michael Tokarev
` (33 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, David Woodhouse, Michael Tokarev, Jason Wang
From: David Woodhouse <dwmw@amazon.co.uk>
While refactoring the NIC initialization code, I broke '-net nic,model=help'
which no longer outputs a list of available NIC models.
Fixes: 2cdeca04adab ("net: report list of available models according to platform")
Cc: qemu-stable@nongnu.org
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 64f75f57f9d2c8c12ac6d9355fa5d3a2af5879ca)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/net/net.c b/net/net.c
index a2f0c828bb..e6ca2529bb 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1150,6 +1150,21 @@ NICInfo *qemu_find_nic_info(const char *typename, bool match_default,
return NULL;
}
+static bool is_nic_model_help_option(const char *model)
+{
+ if (model && is_help_option(model)) {
+ /*
+ * Trigger the help output by instantiating the hash table which
+ * will gather tha available models as they get registered.
+ */
+ if (!nic_model_help) {
+ nic_model_help = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+ }
+ return true;
+ }
+ return false;
+}
/* "I have created a device. Please configure it if you can" */
bool qemu_configure_nic_device(DeviceState *dev, bool match_default,
@@ -1733,6 +1748,12 @@ void net_check_clients(void)
static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
{
+ const char *model = qemu_opt_get_del(opts, "model");
+
+ if (is_nic_model_help_option(model)) {
+ return 0;
+ }
+
return net_client_init(opts, false, errp);
}
@@ -1789,9 +1810,7 @@ static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
memset(ni, 0, sizeof(*ni));
ni->model = qemu_opt_get_del(opts, "model");
- if (!nic_model_help && !g_strcmp0(ni->model, "help")) {
- nic_model_help = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
+ if (is_nic_model_help_option(ni->model)) {
return 0;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 36/69] migration/multifd: Fix multifd_send_setup cleanup when channel creation fails
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (34 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 35/69] net: Reinstate '-net nic, model=help' output as documented in man page Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 37/69] linux-user/elfload: Fix pr_pid values in core files Michael Tokarev
` (32 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Fabiano Rosas, Jim Fehlig, Peter Xu, Michael Tokarev
From: Fabiano Rosas <farosas@suse.de>
When a channel fails to create, the code currently just returns. This
is wrong for two reasons:
1) Channel n+1 will not get to initialize it's semaphores, leading to
an assert when terminate_threads tries to post to it:
qemu-system-x86_64: ../util/qemu-thread-posix.c:92:
qemu_mutex_lock_impl: Assertion `mutex->initialized' failed.
2) (theoretical) If channel n-1 already started creation it will
defeat the purpose of the channels_created logic which is in place
to avoid migrate_fd_cleanup() to run while channels are still being
created.
This cannot really happen today because the current failure cases
for multifd_new_send_channel_create() are all synchronous,
resulting from qio_channel_file_new_path() getting a bad
filename. This would hit all channels equally.
But I don't want to set a trap for future people, so have all
channels try to create (even if failing), and only fail after the
channels_created semaphore has been posted.
While here, remove the error_report_err call. There's one already at
migrate_fd_cleanup later on.
Cc: qemu-stable@nongnu.org
Reported-by: Jim Fehlig <jfehlig@suse.com>
Fixes: b7b03eb614 ("migration/multifd: Add outgoing QIOChannelFile support")
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
(cherry picked from commit 0bd5b9284fa94a6242a0d27a46380d93e753488b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/migration/multifd.c b/migration/multifd.c
index 2802afe79d..fa55586f89 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1145,7 +1145,6 @@ static bool multifd_new_send_channel_create(gpointer opaque, Error **errp)
bool multifd_send_setup(void)
{
MigrationState *s = migrate_get_current();
- Error *local_err = NULL;
int thread_count, ret = 0;
uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
bool use_packets = multifd_use_packets();
@@ -1166,6 +1165,7 @@ bool multifd_send_setup(void)
for (i = 0; i < thread_count; i++) {
MultiFDSendParams *p = &multifd_send_state->params[i];
+ Error *local_err = NULL;
qemu_sem_init(&p->sem, 0);
qemu_sem_init(&p->sem_sync, 0);
@@ -1190,7 +1190,8 @@ bool multifd_send_setup(void)
p->write_flags = 0;
if (!multifd_new_send_channel_create(p, &local_err)) {
- return false;
+ migrate_set_error(s, local_err);
+ ret = -1;
}
}
@@ -1203,24 +1204,27 @@ bool multifd_send_setup(void)
qemu_sem_wait(&multifd_send_state->channels_created);
}
+ if (ret) {
+ goto err;
+ }
+
for (i = 0; i < thread_count; i++) {
MultiFDSendParams *p = &multifd_send_state->params[i];
+ Error *local_err = NULL;
ret = multifd_send_state->ops->send_setup(p, &local_err);
if (ret) {
- break;
+ migrate_set_error(s, local_err);
+ goto err;
}
}
- if (ret) {
- migrate_set_error(s, local_err);
- error_report_err(local_err);
- migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
- MIGRATION_STATUS_FAILED);
- return false;
- }
-
return true;
+
+err:
+ migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
+ MIGRATION_STATUS_FAILED);
+ return false;
}
bool multifd_recv(void)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 37/69] linux-user/elfload: Fix pr_pid values in core files
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (35 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 36/69] migration/multifd: Fix multifd_send_setup cleanup when channel creation fails Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 38/69] target/i386: Fix VSIB decode Michael Tokarev
` (31 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Ilya Leoshkevich, Richard Henderson, Michael Tokarev
From: Ilya Leoshkevich <iii@linux.ibm.com>
Analyzing qemu-produced core dumps of multi-threaded apps runs into:
(gdb) info threads
[...]
21 Thread 0x3ff83cc0740 (LWP 9295) warning: Couldn't find general-purpose registers in core file.
<unavailable> in ?? ()
The reason is that all pr_pid values are the same, because the same
TaskState is used for all CPUs when generating NT_PRSTATUS notes.
Fix by using TaskStates associated with individual CPUs.
Cc: qemu-stable@nongnu.org
Fixes: 243c47066253 ("linux-user/elfload: Write corefile elf header in one block")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20240801202340.21845-1-iii@linux.ibm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 5b0c2742c839376b7e03c4654914aaec6a8a7b09)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 60cf55b36c..0e00683dd2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -4175,8 +4175,7 @@ static void fill_elf_note_phdr(struct elf_phdr *phdr, size_t sz, off_t offset)
bswap_phdr(phdr, 1);
}
-static void fill_prstatus_note(void *data, const TaskState *ts,
- CPUState *cpu, int signr)
+static void fill_prstatus_note(void *data, CPUState *cpu, int signr)
{
/*
* Because note memory is only aligned to 4, and target_elf_prstatus
@@ -4186,7 +4185,7 @@ static void fill_prstatus_note(void *data, const TaskState *ts,
struct target_elf_prstatus prstatus = {
.pr_info.si_signo = signr,
.pr_cursig = signr,
- .pr_pid = ts->ts_tid,
+ .pr_pid = get_task_state(cpu)->ts_tid,
.pr_ppid = getppid(),
.pr_pgrp = getpgrp(),
.pr_sid = getsid(0),
@@ -4501,8 +4500,7 @@ static int elf_core_dump(int signr, const CPUArchState *env)
CPU_FOREACH(cpu_iter) {
dptr = fill_note(&hptr, NT_PRSTATUS, "CORE",
sizeof(struct target_elf_prstatus));
- fill_prstatus_note(dptr, ts, cpu_iter,
- cpu_iter == cpu ? signr : 0);
+ fill_prstatus_note(dptr, cpu_iter, cpu_iter == cpu ? signr : 0);
}
if (dump_write(fd, header, data_offset) < 0) {
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 38/69] target/i386: Fix VSIB decode
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (36 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 37/69] linux-user/elfload: Fix pr_pid values in core files Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 39/69] tcg/ppc: Sync tcg_out_test and constraints Michael Tokarev
` (30 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Paolo Bonzini, Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
With normal SIB, index == 4 indicates no index.
With VSIB, there is no exception for VR4/VR12.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2474
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Link: https://lore.kernel.org/r/20240805003130.1421051-3-richard.henderson@linaro.org
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit ac63755b20013ec6a3d2aef4538d37dc90bc3d10)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: modify the change to pre-new-decoder introduced past qemu 9.0)
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 4209d59ca8..2ca874b59d 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1135,7 +1135,8 @@ static int decode_modrm(DisasContext *s, CPUX86State *env, X86DecodedInsn *decod
} else {
op->has_ea = true;
op->n = -1;
- decode->mem = gen_lea_modrm_0(env, s, get_modrm(s, env));
+ decode->mem = gen_lea_modrm_0(env, s, modrm,
+ decode->e.vex_class == 12);
}
return modrm;
}
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 26ed900f34..e2e3b3d7c3 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2187,7 +2187,7 @@ typedef struct AddressParts {
} AddressParts;
static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
- int modrm)
+ int modrm, bool is_vsib)
{
int def_seg, base, index, scale, mod, rm;
target_long disp;
@@ -2216,7 +2216,7 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
int code = x86_ldub_code(env, s);
scale = (code >> 6) & 3;
index = ((code >> 3) & 7) | REX_X(s);
- if (index == 4) {
+ if (index == 4 && !is_vsib) {
index = -1; /* no index */
}
base = (code & 7) | REX_B(s);
@@ -2346,21 +2346,21 @@ static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
{
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
}
static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
{
- (void)gen_lea_modrm_0(env, s, modrm);
+ (void)gen_lea_modrm_0(env, s, modrm, false);
}
/* Used for BNDCL, BNDCU, BNDCN. */
static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
TCGCond cond, TCGv_i64 bndv)
{
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
tcg_gen_extu_tl_i64(s->tmp1_i64, ea);
@@ -4179,7 +4179,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
reg = ((modrm >> 3) & 7) | REX_R(s);
{
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
gen_lea_v_seg(s, s->aflag, ea, -1, -1);
gen_op_mov_reg_v(s, dflag, reg, s->A0);
@@ -4400,7 +4400,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
op = ((b & 7) << 3) | ((modrm >> 3) & 7);
if (mod != 3) {
/* memory op */
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
TCGv last_addr = tcg_temp_new();
bool update_fdp = true;
@@ -5348,7 +5348,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
rm = (modrm & 7) | REX_B(s);
gen_op_mov_v_reg(s, MO_32, s->T1, reg);
if (mod != 3) {
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
/* specific case: we need to add a displacement */
gen_exts(ot, s->T1);
tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
@@ -6343,7 +6343,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
} else if (mod != 3) {
/* bndldx */
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
if (reg >= 4
|| (prefixes & PREFIX_LOCK)
|| s->aflag == MO_16
@@ -6387,7 +6387,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|| s->aflag == MO_16) {
goto illegal_op;
}
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
if (a.base >= 0) {
tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
if (!CODE64(s)) {
@@ -6448,7 +6448,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
} else if (mod != 3) {
/* bndstx */
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
if (reg >= 4
|| (prefixes & PREFIX_LOCK)
|| s->aflag == MO_16
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 39/69] tcg/ppc: Sync tcg_out_test and constraints
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (37 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 38/69] target/i386: Fix VSIB decode Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 40/69] hw/sd/sdhci: Reset @data_count index on invalid ADMA transfers Michael Tokarev
` (29 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Richard Henderson, Philippe Mathieu-Daudé,
Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
Ensure the code structure is the same for matching constraints
and emitting code, lest we allow constants that cannot be
trivially tested.
Cc: qemu-stable@nongnu.org
Fixes: ad788aebbab ("tcg/ppc: Support TCG_COND_TST{EQ,NE}")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2487
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <44328324-af73-4439-9d2b-d414e0e13dd7@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 682a05280504d2fab32e16096b58d7ea068435c2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index 7f3829beeb..3553a47ba9 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -325,9 +325,11 @@ static bool tcg_target_const_match(int64_t sval, int ct,
if ((uval & ~0xffff) == 0 || (uval & ~0xffff0000ull) == 0) {
return 1;
}
- if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32
- ? mask_operand(uval, &mb, &me)
- : mask64_operand(uval << clz64(uval), &mb, &me)) {
+ if (uval == (uint32_t)uval && mask_operand(uval, &mb, &me)) {
+ return 1;
+ }
+ if (TCG_TARGET_REG_BITS == 64 &&
+ mask64_operand(uval << clz64(uval), &mb, &me)) {
return 1;
}
return 0;
@@ -1749,8 +1751,6 @@ static void tcg_out_test(TCGContext *s, TCGReg dest, TCGReg arg1, TCGArg arg2,
if (type == TCG_TYPE_I32) {
arg2 = (uint32_t)arg2;
- } else if (arg2 == (uint32_t)arg2) {
- type = TCG_TYPE_I32;
}
if ((arg2 & ~0xffff) == 0) {
@@ -1761,12 +1761,11 @@ static void tcg_out_test(TCGContext *s, TCGReg dest, TCGReg arg1, TCGArg arg2,
tcg_out32(s, ANDIS | SAI(arg1, dest, arg2 >> 16));
return;
}
- if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32) {
- if (mask_operand(arg2, &mb, &me)) {
- tcg_out_rlw_rc(s, RLWINM, dest, arg1, 0, mb, me, rc);
- return;
- }
- } else {
+ if (arg2 == (uint32_t)arg2 && mask_operand(arg2, &mb, &me)) {
+ tcg_out_rlw_rc(s, RLWINM, dest, arg1, 0, mb, me, rc);
+ return;
+ }
+ if (TCG_TARGET_REG_BITS == 64) {
int sh = clz64(arg2);
if (mask64_operand(arg2 << sh, &mb, &me)) {
tcg_out_rld_rc(s, RLDICR, dest, arg1, sh, me, rc);
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 40/69] hw/sd/sdhci: Reset @data_count index on invalid ADMA transfers
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (38 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 39/69] tcg/ppc: Sync tcg_out_test and constraints Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 41/69] vvfat: Fix bug in writing to middle of file Michael Tokarev
` (28 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Philippe Mathieu-Daudé, Zheyu Ma,
Richard Henderson, Michael Tokarev
From: Philippe Mathieu-Daudé <philmd@linaro.org>
We neglected to clear the @data_count index on ADMA error,
allowing to trigger assertion in sdhci_read_dataport() or
sdhci_write_dataport().
Cc: qemu-stable@nongnu.org
Fixes: d7dfca0807 ("hw/sdhci: introduce standard SD host controller")
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2455
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240730092138.32443-4-philmd@linaro.org>
(cherry picked from commit ed5a159c3de48a581f46de4c8c02b4b295e6c52d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 27673e1c70..8c5eab1b83 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -846,6 +846,7 @@ static void sdhci_do_adma(SDHCIState *s)
}
}
if (res != MEMTX_OK) {
+ s->data_count = 0;
if (s->errintstsen & SDHC_EISEN_ADMAERR) {
trace_sdhci_error("Set ADMA error flag");
s->errintsts |= SDHC_EIS_ADMAERR;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 41/69] vvfat: Fix bug in writing to middle of file
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (39 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 40/69] hw/sd/sdhci: Reset @data_count index on invalid ADMA transfers Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 42/69] vvfat: Fix usage of `info.file.offset` Michael Tokarev
` (27 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Amjad Alsharafi, Kevin Wolf, Michael Tokarev
From: Amjad Alsharafi <amjadsharafi10@gmail.com>
Before this commit, the behavior when calling `commit_one_file` for
example with `offset=0x2000` (second cluster), what will happen is that
we won't fetch the next cluster from the fat, and instead use the first
cluster for the read operation.
This is due to off-by-one error here, where `i=0x2000 !< offset=0x2000`,
thus not fetching the next cluster.
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <b97c1e1f1bc2f776061ae914f95d799d124fcd73.1721470238.git.amjadsharafi10@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b881cf00c99e03bc8a3648581f97736ff275b18b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/block/vvfat.c b/block/vvfat.c
index 9d050ba3ae..19da009a5b 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2525,8 +2525,9 @@ commit_one_file(BDRVVVFATState* s, int dir_index, uint32_t offset)
return -1;
}
- for (i = s->cluster_size; i < offset; i += s->cluster_size)
+ for (i = 0; i < offset; i += s->cluster_size) {
c = modified_fat_get(s, c);
+ }
fd = qemu_open_old(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
if (fd < 0) {
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 42/69] vvfat: Fix usage of `info.file.offset`
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (40 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 41/69] vvfat: Fix bug in writing to middle of file Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 43/69] vvfat: Fix wrong checks for cluster mappings invariant Michael Tokarev
` (26 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Amjad Alsharafi, Kevin Wolf, Michael Tokarev
From: Amjad Alsharafi <amjadsharafi10@gmail.com>
The field is marked as "the offset in the file (in clusters)", but it
was being used like this
`cluster_size*(nums)+mapping->info.file.offset`, which is incorrect.
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <72f19a7903886dda1aa78bcae0e17702ee939262.1721470238.git.amjadsharafi10@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 21b25a0e466a5bba0a45600bb8100ab564202ed1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/block/vvfat.c b/block/vvfat.c
index 19da009a5b..247b232608 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1408,7 +1408,9 @@ read_cluster_directory:
assert(s->current_fd);
- offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
+ offset = s->cluster_size *
+ ((cluster_num - s->current_mapping->begin)
+ + s->current_mapping->info.file.offset);
if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
return -3;
s->cluster=s->cluster_buffer;
@@ -1929,8 +1931,9 @@ get_cluster_count_for_direntry(BDRVVVFATState* s, direntry_t* direntry, const ch
(mapping->mode & MODE_DIRECTORY) == 0) {
/* was modified in qcow */
- if (offset != mapping->info.file.offset + s->cluster_size
- * (cluster_num - mapping->begin)) {
+ if (offset != s->cluster_size
+ * ((cluster_num - mapping->begin)
+ + mapping->info.file.offset)) {
/* offset of this cluster in file chain has changed */
abort();
copy_it = 1;
@@ -2404,7 +2407,7 @@ static int commit_mappings(BDRVVVFATState* s,
(mapping->end - mapping->begin);
} else
next_mapping->info.file.offset = mapping->info.file.offset +
- mapping->end - mapping->begin;
+ (mapping->end - mapping->begin);
mapping = next_mapping;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 43/69] vvfat: Fix wrong checks for cluster mappings invariant
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (41 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 42/69] vvfat: Fix usage of `info.file.offset` Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 44/69] vvfat: Fix reading files with non-continuous clusters Michael Tokarev
` (25 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Amjad Alsharafi, Kevin Wolf, Michael Tokarev
From: Amjad Alsharafi <amjadsharafi10@gmail.com>
How this `abort` was intended to check for was:
- if the `mapping->first_mapping_index` is not the same as
`first_mapping_index`, which **should** happen only in one case,
when we are handling the first mapping, in that case
`mapping->first_mapping_index == -1`, in all other cases, the other
mappings after the first should have the condition `true`.
- From above, we know that this is the first mapping, so if the offset
is not `0`, then abort, since this is an invalid state.
The issue was that `first_mapping_index` is not set if we are
checking from the middle, the variable `first_mapping_index` is
only set if we passed through the check `cluster_was_modified` with the
first mapping, and in the same function call we checked the other
mappings.
One approach is to go into the loop even if `cluster_was_modified`
is not true so that we will be able to set `first_mapping_index` for the
first mapping, but since `first_mapping_index` is only used here,
another approach is to just check manually for the
`mapping->first_mapping_index != -1` since we know that this is the
value for the only entry where `offset == 0` (i.e. first mapping).
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <b0fbca3ee208c565885838f6a7deeaeb23f4f9c2.1721470238.git.amjadsharafi10@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f60a6f7e17bf2a2a0f0a08265ac9b077fce42858)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/block/vvfat.c b/block/vvfat.c
index 247b232608..b63ac5d045 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1880,7 +1880,6 @@ get_cluster_count_for_direntry(BDRVVVFATState* s, direntry_t* direntry, const ch
uint32_t cluster_num = begin_of_direntry(direntry);
uint32_t offset = 0;
- int first_mapping_index = -1;
mapping_t* mapping = NULL;
const char* basename2 = NULL;
@@ -1942,14 +1941,9 @@ get_cluster_count_for_direntry(BDRVVVFATState* s, direntry_t* direntry, const ch
if (strcmp(basename, basename2))
copy_it = 1;
- first_mapping_index = array_index(&(s->mapping), mapping);
- }
-
- if (mapping->first_mapping_index != first_mapping_index
- && mapping->info.file.offset > 0) {
- abort();
- copy_it = 1;
}
+ assert(mapping->first_mapping_index == -1
+ || mapping->info.file.offset > 0);
/* need to write out? */
if (!was_modified && is_file(direntry)) {
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 44/69] vvfat: Fix reading files with non-continuous clusters
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (42 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 43/69] vvfat: Fix wrong checks for cluster mappings invariant Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 45/69] iotests: Add `vvfat` tests Michael Tokarev
` (24 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Amjad Alsharafi, Kevin Wolf, Michael Tokarev
From: Amjad Alsharafi <amjadsharafi10@gmail.com>
When reading with `read_cluster` we get the `mapping` with
`find_mapping_for_cluster` and then we call `open_file` for this
mapping.
The issue appear when its the same file, but a second cluster that is
not immediately after it, imagine clusters `500 -> 503`, this will give
us 2 mappings one has the range `500..501` and another `503..504`, both
point to the same file, but different offsets.
When we don't open the file since the path is the same, we won't assign
`s->current_mapping` and thus accessing way out of bound of the file.
From our example above, after `open_file` (that didn't open anything) we
will get the offset into the file with
`s->cluster_size*(cluster_num-s->current_mapping->begin)`, which will
give us `0x2000 * (504-500)`, which is out of bound for this mapping and
will produce some issues.
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
Message-ID: <1f3ea115779abab62ba32c788073cdc99f9ad5dd.1721470238.git.amjadsharafi10@gmail.com>
[kwolf: Simplified the patch based on Amjad's analysis and input]
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 5eed3db336506b529b927ba221fe0d836e5b8819)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/block/vvfat.c b/block/vvfat.c
index b63ac5d045..213d7989e4 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1369,8 +1369,9 @@ static int open_file(BDRVVVFATState* s,mapping_t* mapping)
return -1;
vvfat_close_current_file(s);
s->current_fd = fd;
- s->current_mapping = mapping;
}
+
+ s->current_mapping = mapping;
return 0;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 45/69] iotests: Add `vvfat` tests
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (43 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 44/69] vvfat: Fix reading files with non-continuous clusters Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 46/69] nbd/server: Plumb in new args to nbd_client_add() Michael Tokarev
` (23 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Amjad Alsharafi, Kevin Wolf, Michael Tokarev
From: Amjad Alsharafi <amjadsharafi10@gmail.com>
Added several tests to verify the implementation of the vvfat driver.
We needed a way to interact with it, so created a basic `fat16.py` driver
that handled writing correct sectors for us.
Added `vvfat` to the non-generic formats, as its not a normal image format.
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <bb8149c945301aefbdf470a0924c07f69f9c087d.1721470238.git.amjadsharafi10@gmail.com>
[kwolf: Made mypy and pylint happy to unbreak 297]
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit c8f60bfb4345ea8343a53eaefe88d47b44c53f24)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 56d88ca423..545f9ec7bd 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -84,7 +84,7 @@ def make_argparser() -> argparse.ArgumentParser:
p.set_defaults(imgfmt='raw', imgproto='file')
format_list = ['raw', 'bochs', 'cloop', 'parallels', 'qcow', 'qcow2',
- 'qed', 'vdi', 'vpc', 'vhdx', 'vmdk', 'luks', 'dmg']
+ 'qed', 'vdi', 'vpc', 'vhdx', 'vmdk', 'luks', 'dmg', 'vvfat']
g_fmt = p.add_argument_group(
' image format options',
'The following options set the IMGFMT environment variable. '
diff --git a/tests/qemu-iotests/fat16.py b/tests/qemu-iotests/fat16.py
new file mode 100644
index 0000000000..7d2d052413
--- /dev/null
+++ b/tests/qemu-iotests/fat16.py
@@ -0,0 +1,690 @@
+# A simple FAT16 driver that is used to test the `vvfat` driver in QEMU.
+#
+# Copyright (C) 2024 Amjad Alsharafi <amjadsharafi10@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from typing import Callable, List, Optional, Protocol, Set
+import string
+
+SECTOR_SIZE = 512
+DIRENTRY_SIZE = 32
+ALLOWED_FILE_CHARS = set(
+ "!#$%&'()-@^_`{}~" + string.digits + string.ascii_uppercase
+)
+
+
+class MBR:
+ def __init__(self, data: bytes):
+ assert len(data) == 512
+ self.partition_table = []
+ for i in range(4):
+ partition = data[446 + i * 16 : 446 + (i + 1) * 16]
+ self.partition_table.append(
+ {
+ "status": partition[0],
+ "start_head": partition[1],
+ "start_sector": partition[2] & 0x3F,
+ "start_cylinder": ((partition[2] & 0xC0) << 2)
+ | partition[3],
+ "type": partition[4],
+ "end_head": partition[5],
+ "end_sector": partition[6] & 0x3F,
+ "end_cylinder": ((partition[6] & 0xC0) << 2)
+ | partition[7],
+ "start_lba": int.from_bytes(partition[8:12], "little"),
+ "size": int.from_bytes(partition[12:16], "little"),
+ }
+ )
+
+ def __str__(self):
+ return "\n".join(
+ [
+ f"{i}: {partition}"
+ for i, partition in enumerate(self.partition_table)
+ ]
+ )
+
+
+class FatBootSector:
+ # pylint: disable=too-many-instance-attributes
+ def __init__(self, data: bytes):
+ assert len(data) == 512
+ self.bytes_per_sector = int.from_bytes(data[11:13], "little")
+ self.sectors_per_cluster = data[13]
+ self.reserved_sectors = int.from_bytes(data[14:16], "little")
+ self.fat_count = data[16]
+ self.root_entries = int.from_bytes(data[17:19], "little")
+ total_sectors_16 = int.from_bytes(data[19:21], "little")
+ self.media_descriptor = data[21]
+ self.sectors_per_fat = int.from_bytes(data[22:24], "little")
+ self.sectors_per_track = int.from_bytes(data[24:26], "little")
+ self.heads = int.from_bytes(data[26:28], "little")
+ self.hidden_sectors = int.from_bytes(data[28:32], "little")
+ total_sectors_32 = int.from_bytes(data[32:36], "little")
+ assert (
+ total_sectors_16 == 0 or total_sectors_32 == 0
+ ), "Both total sectors (16 and 32) fields are non-zero"
+ self.total_sectors = total_sectors_16 or total_sectors_32
+ self.drive_number = data[36]
+ self.volume_id = int.from_bytes(data[39:43], "little")
+ self.volume_label = data[43:54].decode("ascii").strip()
+ self.fs_type = data[54:62].decode("ascii").strip()
+
+ def root_dir_start(self):
+ """
+ Calculate the start sector of the root directory.
+ """
+ return self.reserved_sectors + self.fat_count * self.sectors_per_fat
+
+ def root_dir_size(self):
+ """
+ Calculate the size of the root directory in sectors.
+ """
+ return (
+ self.root_entries * DIRENTRY_SIZE + self.bytes_per_sector - 1
+ ) // self.bytes_per_sector
+
+ def data_sector_start(self):
+ """
+ Calculate the start sector of the data region.
+ """
+ return self.root_dir_start() + self.root_dir_size()
+
+ def first_sector_of_cluster(self, cluster: int) -> int:
+ """
+ Calculate the first sector of the given cluster.
+ """
+ return (
+ self.data_sector_start() + (cluster - 2) * self.sectors_per_cluster
+ )
+
+ def cluster_bytes(self):
+ """
+ Calculate the number of bytes in a cluster.
+ """
+ return self.bytes_per_sector * self.sectors_per_cluster
+
+ def __str__(self):
+ return (
+ f"Bytes per sector: {self.bytes_per_sector}\n"
+ f"Sectors per cluster: {self.sectors_per_cluster}\n"
+ f"Reserved sectors: {self.reserved_sectors}\n"
+ f"FAT count: {self.fat_count}\n"
+ f"Root entries: {self.root_entries}\n"
+ f"Total sectors: {self.total_sectors}\n"
+ f"Media descriptor: {self.media_descriptor}\n"
+ f"Sectors per FAT: {self.sectors_per_fat}\n"
+ f"Sectors per track: {self.sectors_per_track}\n"
+ f"Heads: {self.heads}\n"
+ f"Hidden sectors: {self.hidden_sectors}\n"
+ f"Drive number: {self.drive_number}\n"
+ f"Volume ID: {self.volume_id}\n"
+ f"Volume label: {self.volume_label}\n"
+ f"FS type: {self.fs_type}\n"
+ )
+
+
+class FatDirectoryEntry:
+ # pylint: disable=too-many-instance-attributes
+ def __init__(self, data: bytes, sector: int, offset: int):
+ self.name = data[0:8].decode("ascii").strip()
+ self.ext = data[8:11].decode("ascii").strip()
+ self.attributes = data[11]
+ self.reserved = data[12]
+ self.create_time_tenth = data[13]
+ self.create_time = int.from_bytes(data[14:16], "little")
+ self.create_date = int.from_bytes(data[16:18], "little")
+ self.last_access_date = int.from_bytes(data[18:20], "little")
+ high_cluster = int.from_bytes(data[20:22], "little")
+ self.last_mod_time = int.from_bytes(data[22:24], "little")
+ self.last_mod_date = int.from_bytes(data[24:26], "little")
+ low_cluster = int.from_bytes(data[26:28], "little")
+ self.cluster = (high_cluster << 16) | low_cluster
+ self.size_bytes = int.from_bytes(data[28:32], "little")
+
+ # extra (to help write back to disk)
+ self.sector = sector
+ self.offset = offset
+
+ def as_bytes(self) -> bytes:
+ return (
+ self.name.ljust(8, " ").encode("ascii")
+ + self.ext.ljust(3, " ").encode("ascii")
+ + self.attributes.to_bytes(1, "little")
+ + self.reserved.to_bytes(1, "little")
+ + self.create_time_tenth.to_bytes(1, "little")
+ + self.create_time.to_bytes(2, "little")
+ + self.create_date.to_bytes(2, "little")
+ + self.last_access_date.to_bytes(2, "little")
+ + (self.cluster >> 16).to_bytes(2, "little")
+ + self.last_mod_time.to_bytes(2, "little")
+ + self.last_mod_date.to_bytes(2, "little")
+ + (self.cluster & 0xFFFF).to_bytes(2, "little")
+ + self.size_bytes.to_bytes(4, "little")
+ )
+
+ def whole_name(self):
+ if self.ext:
+ return f"{self.name}.{self.ext}"
+ else:
+ return self.name
+
+ def __str__(self):
+ return (
+ f"Name: {self.name}\n"
+ f"Ext: {self.ext}\n"
+ f"Attributes: {self.attributes}\n"
+ f"Reserved: {self.reserved}\n"
+ f"Create time tenth: {self.create_time_tenth}\n"
+ f"Create time: {self.create_time}\n"
+ f"Create date: {self.create_date}\n"
+ f"Last access date: {self.last_access_date}\n"
+ f"Last mod time: {self.last_mod_time}\n"
+ f"Last mod date: {self.last_mod_date}\n"
+ f"Cluster: {self.cluster}\n"
+ f"Size: {self.size_bytes}\n"
+ )
+
+ def __repr__(self):
+ # convert to dict
+ return str(vars(self))
+
+
+class SectorReader(Protocol):
+ def __call__(self, start_sector: int, num_sectors: int = 1) -> bytes: ...
+
+# pylint: disable=broad-exception-raised
+class Fat16:
+ def __init__(
+ self,
+ start_sector: int,
+ size: int,
+ sector_reader: SectorReader,
+ sector_writer: Callable[[int, bytes], None]
+ ):
+ self.start_sector = start_sector
+ self.size_in_sectors = size
+ self.sector_reader = sector_reader
+ self.sector_writer = sector_writer
+
+ self.boot_sector = FatBootSector(self.sector_reader(start_sector, 1))
+
+ fat_size_in_sectors = (
+ self.boot_sector.sectors_per_fat * self.boot_sector.fat_count
+ )
+ self.fats = self.read_sectors(
+ self.boot_sector.reserved_sectors, fat_size_in_sectors
+ )
+ self.fats_dirty_sectors: Set[int] = set()
+
+ def read_sectors(self, start_sector: int, num_sectors: int) -> bytes:
+ return self.sector_reader(start_sector + self.start_sector,
+ num_sectors)
+
+ def write_sectors(self, start_sector: int, data: bytes) -> None:
+ return self.sector_writer(start_sector + self.start_sector, data)
+
+ def directory_from_bytes(
+ self, data: bytes, start_sector: int
+ ) -> List[FatDirectoryEntry]:
+ """
+ Convert `bytes` into a list of `FatDirectoryEntry` objects.
+ Will ignore long file names.
+ Will stop when it encounters a 0x00 byte.
+ """
+
+ entries = []
+ for i in range(0, len(data), DIRENTRY_SIZE):
+ entry = data[i : i + DIRENTRY_SIZE]
+
+ current_sector = start_sector + (i // SECTOR_SIZE)
+ current_offset = i % SECTOR_SIZE
+
+ if entry[0] == 0:
+ break
+
+ if entry[0] == 0xE5:
+ # Deleted file
+ continue
+
+ if entry[11] & 0xF == 0xF:
+ # Long file name
+ continue
+
+ entries.append(
+ FatDirectoryEntry(entry, current_sector, current_offset)
+ )
+ return entries
+
+ def read_root_directory(self) -> List[FatDirectoryEntry]:
+ root_dir = self.read_sectors(
+ self.boot_sector.root_dir_start(), self.boot_sector.root_dir_size()
+ )
+ return self.directory_from_bytes(
+ root_dir, self.boot_sector.root_dir_start()
+ )
+
+ def read_fat_entry(self, cluster: int) -> int:
+ """
+ Read the FAT entry for the given cluster.
+ """
+ fat_offset = cluster * 2 # FAT16
+ return int.from_bytes(self.fats[fat_offset : fat_offset + 2], "little")
+
+ def write_fat_entry(self, cluster: int, value: int) -> None:
+ """
+ Write the FAT entry for the given cluster.
+ """
+ fat_offset = cluster * 2
+ self.fats = (
+ self.fats[:fat_offset]
+ + value.to_bytes(2, "little")
+ + self.fats[fat_offset + 2 :]
+ )
+ self.fats_dirty_sectors.add(fat_offset // SECTOR_SIZE)
+
+ def flush_fats(self) -> None:
+ """
+ Write the FATs back to the disk.
+ """
+ for sector in self.fats_dirty_sectors:
+ data = self.fats[sector * SECTOR_SIZE : (sector + 1) * SECTOR_SIZE]
+ sector = self.boot_sector.reserved_sectors + sector
+ self.write_sectors(sector, data)
+ self.fats_dirty_sectors = set()
+
+ def next_cluster(self, cluster: int) -> Optional[int]:
+ """
+ Get the next cluster in the chain.
+ If its `None`, then its the last cluster.
+ The function will crash if the next cluster
+ is `FREE` (unexpected) or invalid entry.
+ """
+ fat_entry = self.read_fat_entry(cluster)
+ if fat_entry == 0:
+ raise Exception("Unexpected: FREE cluster")
+ if fat_entry == 1:
+ raise Exception("Unexpected: RESERVED cluster")
+ if fat_entry >= 0xFFF8:
+ return None
+ if fat_entry >= 0xFFF7:
+ raise Exception("Invalid FAT entry")
+
+ return fat_entry
+
+ def next_free_cluster(self) -> int:
+ """
+ Find the next free cluster.
+ """
+ # simple linear search
+ for i in range(2, 0xFFFF):
+ if self.read_fat_entry(i) == 0:
+ return i
+ raise Exception("No free clusters")
+
+ def next_free_cluster_non_continuous(self) -> int:
+ """
+ Find the next free cluster, but makes sure
+ that the cluster before and after it are not allocated.
+ """
+ # simple linear search
+ before = False
+ for i in range(2, 0xFFFF):
+ if self.read_fat_entry(i) == 0:
+ if before and self.read_fat_entry(i + 1) == 0:
+ return i
+ else:
+ before = True
+ else:
+ before = False
+
+ raise Exception("No free clusters")
+
+ def read_cluster(self, cluster: int) -> bytes:
+ """
+ Read the cluster at the given cluster.
+ """
+ return self.read_sectors(
+ self.boot_sector.first_sector_of_cluster(cluster),
+ self.boot_sector.sectors_per_cluster,
+ )
+
+ def write_cluster(self, cluster: int, data: bytes) -> None:
+ """
+ Write the cluster at the given cluster.
+ """
+ assert len(data) == self.boot_sector.cluster_bytes()
+ self.write_sectors(
+ self.boot_sector.first_sector_of_cluster(cluster),
+ data,
+ )
+
+ def read_directory(
+ self, cluster: Optional[int]
+ ) -> List[FatDirectoryEntry]:
+ """
+ Read the directory at the given cluster.
+ """
+ entries = []
+ while cluster is not None:
+ data = self.read_cluster(cluster)
+ entries.extend(
+ self.directory_from_bytes(
+ data, self.boot_sector.first_sector_of_cluster(cluster)
+ )
+ )
+ cluster = self.next_cluster(cluster)
+ return entries
+
+ def add_direntry(
+ self, cluster: Optional[int], name: str, ext: str, attributes: int
+ ) -> FatDirectoryEntry:
+ """
+ Add a new directory entry to the given cluster.
+ If the cluster is `None`, then it will be added to the root directory.
+ """
+
+ def find_free_entry(data: bytes) -> Optional[int]:
+ for i in range(0, len(data), DIRENTRY_SIZE):
+ entry = data[i : i + DIRENTRY_SIZE]
+ if entry[0] == 0 or entry[0] == 0xE5:
+ return i
+ return None
+
+ assert len(name) <= 8, "Name must be 8 characters or less"
+ assert len(ext) <= 3, "Ext must be 3 characters or less"
+ assert attributes % 0x15 != 0x15, "Invalid attributes"
+
+ # initial dummy data
+ new_entry = FatDirectoryEntry(b"\0" * 32, 0, 0)
+ new_entry.name = name.ljust(8, " ")
+ new_entry.ext = ext.ljust(3, " ")
+ new_entry.attributes = attributes
+ new_entry.reserved = 0
+ new_entry.create_time_tenth = 0
+ new_entry.create_time = 0
+ new_entry.create_date = 0
+ new_entry.last_access_date = 0
+ new_entry.last_mod_time = 0
+ new_entry.last_mod_date = 0
+ new_entry.cluster = self.next_free_cluster()
+ new_entry.size_bytes = 0
+
+ # mark as EOF
+ self.write_fat_entry(new_entry.cluster, 0xFFFF)
+
+ if cluster is None:
+ for i in range(self.boot_sector.root_dir_size()):
+ sector_data = self.read_sectors(
+ self.boot_sector.root_dir_start() + i, 1
+ )
+ offset = find_free_entry(sector_data)
+ if offset is not None:
+ new_entry.sector = self.boot_sector.root_dir_start() + i
+ new_entry.offset = offset
+ self.update_direntry(new_entry)
+ return new_entry
+ else:
+ while cluster is not None:
+ data = self.read_cluster(cluster)
+ offset = find_free_entry(data)
+ if offset is not None:
+ new_entry.sector = (
+ self.boot_sector.first_sector_of_cluster(cluster)
+ + (offset // SECTOR_SIZE))
+ new_entry.offset = offset % SECTOR_SIZE
+ self.update_direntry(new_entry)
+ return new_entry
+ cluster = self.next_cluster(cluster)
+
+ raise Exception("No free directory entries")
+
+ def update_direntry(self, entry: FatDirectoryEntry) -> None:
+ """
+ Write the directory entry back to the disk.
+ """
+ sector = self.read_sectors(entry.sector, 1)
+ sector = (
+ sector[: entry.offset]
+ + entry.as_bytes()
+ + sector[entry.offset + DIRENTRY_SIZE :]
+ )
+ self.write_sectors(entry.sector, sector)
+
+ def find_direntry(self, path: str) -> Optional[FatDirectoryEntry]:
+ """
+ Find the directory entry for the given path.
+ """
+ assert path[0] == "/", "Path must start with /"
+
+ path = path[1:] # remove the leading /
+ parts = path.split("/")
+ directory = self.read_root_directory()
+
+ current_entry = None
+
+ for i, part in enumerate(parts):
+ is_last = i == len(parts) - 1
+
+ for entry in directory:
+ if entry.whole_name() == part:
+ current_entry = entry
+ break
+ if current_entry is None:
+ return None
+
+ if is_last:
+ return current_entry
+
+ if current_entry.attributes & 0x10 == 0:
+ raise Exception(
+ f"{current_entry.whole_name()} is not a directory"
+ )
+
+ directory = self.read_directory(current_entry.cluster)
+
+ assert False, "Exited loop with is_last == False"
+
+ def read_file(self, entry: Optional[FatDirectoryEntry]) -> Optional[bytes]:
+ """
+ Read the content of the file at the given path.
+ """
+ if entry is None:
+ return None
+ if entry.attributes & 0x10 != 0:
+ raise Exception(f"{entry.whole_name()} is a directory")
+
+ data = b""
+ cluster: Optional[int] = entry.cluster
+ while cluster is not None and len(data) <= entry.size_bytes:
+ data += self.read_cluster(cluster)
+ cluster = self.next_cluster(cluster)
+ return data[: entry.size_bytes]
+
+ def truncate_file(
+ self,
+ entry: FatDirectoryEntry,
+ new_size: int,
+ allocate_non_continuous: bool = False,
+ ) -> None:
+ """
+ Truncate the file at the given path to the new size.
+ """
+ if entry is None:
+ raise Exception("entry is None")
+ if entry.attributes & 0x10 != 0:
+ raise Exception(f"{entry.whole_name()} is a directory")
+
+ def clusters_from_size(size: int) -> int:
+ return (
+ size + self.boot_sector.cluster_bytes() - 1
+ ) // self.boot_sector.cluster_bytes()
+
+ # First, allocate new FATs if we need to
+ required_clusters = clusters_from_size(new_size)
+ current_clusters = clusters_from_size(entry.size_bytes)
+
+ affected_clusters = set()
+
+ # Keep at least one cluster, easier to manage this way
+ if required_clusters == 0:
+ required_clusters = 1
+ if current_clusters == 0:
+ current_clusters = 1
+
+ cluster: Optional[int]
+
+ if required_clusters > current_clusters:
+ # Allocate new clusters
+ cluster = entry.cluster
+ to_add = required_clusters
+ for _ in range(current_clusters - 1):
+ to_add -= 1
+ assert cluster is not None, "Cluster is None"
+ affected_clusters.add(cluster)
+ cluster = self.next_cluster(cluster)
+ assert required_clusters > 0, "No new clusters to allocate"
+ assert cluster is not None, "Cluster is None"
+ assert (
+ self.next_cluster(cluster) is None
+ ), "Cluster is not the last cluster"
+
+ # Allocate new clusters
+ for _ in range(to_add - 1):
+ if allocate_non_continuous:
+ new_cluster = self.next_free_cluster_non_continuous()
+ else:
+ new_cluster = self.next_free_cluster()
+ self.write_fat_entry(cluster, new_cluster)
+ self.write_fat_entry(new_cluster, 0xFFFF)
+ cluster = new_cluster
+
+ elif required_clusters < current_clusters:
+ # Truncate the file
+ cluster = entry.cluster
+ for _ in range(required_clusters - 1):
+ assert cluster is not None, "Cluster is None"
+ cluster = self.next_cluster(cluster)
+ assert cluster is not None, "Cluster is None"
+
+ next_cluster = self.next_cluster(cluster)
+ # mark last as EOF
+ self.write_fat_entry(cluster, 0xFFFF)
+ # free the rest
+ while next_cluster is not None:
+ cluster = next_cluster
+ next_cluster = self.next_cluster(next_cluster)
+ self.write_fat_entry(cluster, 0)
+
+ self.flush_fats()
+
+ # verify number of clusters
+ cluster = entry.cluster
+ count = 0
+ while cluster is not None:
+ count += 1
+ affected_clusters.add(cluster)
+ cluster = self.next_cluster(cluster)
+ assert (
+ count == required_clusters
+ ), f"Expected {required_clusters} clusters, got {count}"
+
+ # update the size
+ entry.size_bytes = new_size
+ self.update_direntry(entry)
+
+ # trigger every affected cluster
+ for cluster in affected_clusters:
+ first_sector = self.boot_sector.first_sector_of_cluster(cluster)
+ first_sector_data = self.read_sectors(first_sector, 1)
+ self.write_sectors(first_sector, first_sector_data)
+
+ def write_file(self, entry: FatDirectoryEntry, data: bytes) -> None:
+ """
+ Write the content of the file at the given path.
+ """
+ if entry is None:
+ raise Exception("entry is None")
+ if entry.attributes & 0x10 != 0:
+ raise Exception(f"{entry.whole_name()} is a directory")
+
+ data_len = len(data)
+
+ self.truncate_file(entry, data_len)
+
+ cluster: Optional[int] = entry.cluster
+ while cluster is not None:
+ data_to_write = data[: self.boot_sector.cluster_bytes()]
+ if len(data_to_write) < self.boot_sector.cluster_bytes():
+ old_data = self.read_cluster(cluster)
+ data_to_write += old_data[len(data_to_write) :]
+
+ self.write_cluster(cluster, data_to_write)
+ data = data[self.boot_sector.cluster_bytes() :]
+ if len(data) == 0:
+ break
+ cluster = self.next_cluster(cluster)
+
+ assert (
+ len(data) == 0
+ ), "Data was not written completely, clusters missing"
+
+ def create_file(self, path: str) -> Optional[FatDirectoryEntry]:
+ """
+ Create a new file at the given path.
+ """
+ assert path[0] == "/", "Path must start with /"
+
+ path = path[1:] # remove the leading /
+
+ parts = path.split("/")
+
+ directory_cluster = None
+ directory = self.read_root_directory()
+
+ parts, filename = parts[:-1], parts[-1]
+
+ for _, part in enumerate(parts):
+ current_entry = None
+ for entry in directory:
+ if entry.whole_name() == part:
+ current_entry = entry
+ break
+ if current_entry is None:
+ return None
+
+ if current_entry.attributes & 0x10 == 0:
+ raise Exception(
+ f"{current_entry.whole_name()} is not a directory"
+ )
+
+ directory = self.read_directory(current_entry.cluster)
+ directory_cluster = current_entry.cluster
+
+ # add new entry to the directory
+
+ filename, ext = filename.split(".")
+
+ if len(ext) > 3:
+ raise Exception("Ext must be 3 characters or less")
+ if len(filename) > 8:
+ raise Exception("Name must be 8 characters or less")
+
+ for c in filename + ext:
+
+ if c not in ALLOWED_FILE_CHARS:
+ raise Exception("Invalid character in filename")
+
+ return self.add_direntry(directory_cluster, filename, ext, 0)
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 588f30a4f1..4053d29de4 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -250,7 +250,7 @@ def __init__(self, source_dir: str, build_dir: str,
self.qemu_img_options = os.getenv('QEMU_IMG_OPTIONS')
self.qemu_nbd_options = os.getenv('QEMU_NBD_OPTIONS')
- is_generic = self.imgfmt not in ['bochs', 'cloop', 'dmg']
+ is_generic = self.imgfmt not in ['bochs', 'cloop', 'dmg', 'vvfat']
self.imgfmt_generic = 'true' if is_generic else 'false'
self.qemu_io_options = f'--cache {self.cachemode} --aio {self.aiomode}'
diff --git a/tests/qemu-iotests/tests/vvfat b/tests/qemu-iotests/tests/vvfat
new file mode 100755
index 0000000000..acdc6ce8ff
--- /dev/null
+++ b/tests/qemu-iotests/tests/vvfat
@@ -0,0 +1,485 @@
+#!/usr/bin/env python3
+# group: rw vvfat
+#
+# Test vvfat driver implementation
+# Here, we use a simple FAT16 implementation and check the behavior of
+# the vvfat driver.
+#
+# Copyright (C) 2024 Amjad Alsharafi <amjadsharafi10@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import shutil
+import iotests
+from iotests import imgfmt, QMPTestCase
+from fat16 import MBR, Fat16, DIRENTRY_SIZE
+
+filesystem = os.path.join(iotests.test_dir, "filesystem")
+
+nbd_sock = iotests.file_path("nbd.sock", base_dir=iotests.sock_dir)
+nbd_uri = "nbd+unix:///disk?socket=" + nbd_sock
+
+SECTOR_SIZE = 512
+
+
+class TestVVFatDriver(QMPTestCase):
+ # pylint: disable=broad-exception-raised
+ def setUp(self) -> None:
+ if os.path.exists(filesystem):
+ if os.path.isdir(filesystem):
+ shutil.rmtree(filesystem)
+ else:
+ raise Exception(f"{filesystem} exists and is not a directory")
+
+ os.mkdir(filesystem)
+
+ # Add some text files to the filesystem
+ for i in range(10):
+ with open(os.path.join(filesystem, f"file{i}.txt"),
+ "w", encoding="ascii") as f:
+ f.write(f"Hello, world! {i}\n")
+
+ # Add 2 large files, above the cluster size (8KB)
+ with open(os.path.join(filesystem, "large1.txt"), "wb") as f:
+ # write 'A' * 1KB, 'B' * 1KB, 'C' * 1KB, ...
+ for i in range(8 * 2): # two clusters
+ f.write(bytes([0x41 + i] * 1024))
+
+ with open(os.path.join(filesystem, "large2.txt"), "wb") as f:
+ # write 'A' * 1KB, 'B' * 1KB, 'C' * 1KB, ...
+ for i in range(8 * 3): # 3 clusters
+ f.write(bytes([0x41 + i] * 1024))
+
+ self.vm = iotests.VM()
+
+ self.vm.add_blockdev(
+ self.vm.qmp_to_opts(
+ {
+ "driver": imgfmt,
+ "node-name": "disk",
+ "rw": "true",
+ "fat-type": "16",
+ "dir": filesystem,
+ }
+ )
+ )
+
+ self.vm.launch()
+
+ self.vm.qmp_log("block-dirty-bitmap-add", **{
+ "node": "disk",
+ "name": "bitmap0",
+ })
+
+ # attach nbd server
+ self.vm.qmp_log(
+ "nbd-server-start",
+ **{"addr": {"type": "unix", "data": {"path": nbd_sock}}},
+ filters=[],
+ )
+
+ self.vm.qmp_log(
+ "nbd-server-add",
+ **{"device": "disk", "writable": True, "bitmap": "bitmap0"},
+ )
+
+ self.qio = iotests.QemuIoInteractive("-f", "raw", nbd_uri)
+
+ def tearDown(self) -> None:
+ self.qio.close()
+ self.vm.shutdown()
+ # print(self.vm.get_log())
+ shutil.rmtree(filesystem)
+
+ def read_sectors(self, sector: int, num: int = 1) -> bytes:
+ """
+ Read `num` sectors starting from `sector` from the `disk`.
+ This uses `QemuIoInteractive` to read the sectors into `stdout` and
+ then parse the output.
+ """
+ self.assertGreater(num, 0)
+
+ # The output contains the content of the sector in hex dump format
+ # We need to extract the content from it
+ output = self.qio.cmd(
+ f"read -v {sector * SECTOR_SIZE} {num * SECTOR_SIZE}")
+
+ # Each row is 16 bytes long, and we are writing `num` sectors
+ rows = num * SECTOR_SIZE // 16
+ output_rows = output.split("\n")[:rows]
+
+ hex_content = "".join(
+ [(row.split(": ")[1]).split(" ")[0] for row in output_rows]
+ )
+ bytes_content = bytes.fromhex(hex_content)
+
+ self.assertEqual(len(bytes_content), num * SECTOR_SIZE)
+
+ return bytes_content
+
+ def write_sectors(self, sector: int, data: bytes) -> None:
+ """
+ Write `data` to the `disk` starting from `sector`.
+ This uses `QemuIoInteractive` to write the data into the disk.
+ """
+
+ self.assertGreater(len(data), 0)
+ self.assertEqual(len(data) % SECTOR_SIZE, 0)
+
+ temp_file = os.path.join(iotests.test_dir, "temp.bin")
+ with open(temp_file, "wb") as f:
+ f.write(data)
+
+ self.qio.cmd(
+ f"write -s {temp_file} {sector * SECTOR_SIZE} {len(data)}"
+ )
+
+ os.remove(temp_file)
+
+ def init_fat16(self):
+ mbr = MBR(self.read_sectors(0))
+ return Fat16(
+ mbr.partition_table[0]["start_lba"],
+ mbr.partition_table[0]["size"],
+ self.read_sectors,
+ self.write_sectors,
+ )
+
+ # Tests
+
+ def test_fat_filesystem(self):
+ """
+ Test that vvfat produce a valid FAT16 and MBR sectors
+ """
+ mbr = MBR(self.read_sectors(0))
+
+ self.assertEqual(mbr.partition_table[0]["status"], 0x80)
+ self.assertEqual(mbr.partition_table[0]["type"], 6)
+
+ fat16 = Fat16(
+ mbr.partition_table[0]["start_lba"],
+ mbr.partition_table[0]["size"],
+ self.read_sectors,
+ self.write_sectors,
+ )
+ self.assertEqual(fat16.boot_sector.bytes_per_sector, 512)
+ self.assertEqual(fat16.boot_sector.volume_label, "QEMU VVFAT")
+
+ def test_read_root_directory(self):
+ """
+ Test the content of the root directory
+ """
+ fat16 = self.init_fat16()
+
+ root_dir = fat16.read_root_directory()
+
+ self.assertEqual(len(root_dir), 13) # 12 + 1 special file
+
+ files = {
+ "QEMU VVF.AT": 0, # special empty file
+ "FILE0.TXT": 16,
+ "FILE1.TXT": 16,
+ "FILE2.TXT": 16,
+ "FILE3.TXT": 16,
+ "FILE4.TXT": 16,
+ "FILE5.TXT": 16,
+ "FILE6.TXT": 16,
+ "FILE7.TXT": 16,
+ "FILE8.TXT": 16,
+ "FILE9.TXT": 16,
+ "LARGE1.TXT": 0x2000 * 2,
+ "LARGE2.TXT": 0x2000 * 3,
+ }
+
+ for entry in root_dir:
+ self.assertIn(entry.whole_name(), files)
+ self.assertEqual(entry.size_bytes, files[entry.whole_name()])
+
+ def test_direntry_as_bytes(self):
+ """
+ Test if we can convert Direntry back to bytes, so that we can write it
+ back to the disk safely.
+ """
+ fat16 = self.init_fat16()
+
+ root_dir = fat16.read_root_directory()
+ first_entry_bytes = fat16.read_sectors(
+ fat16.boot_sector.root_dir_start(), 1)
+
+ # The first entry won't be deleted, so we can compare it with the first
+ # entry in the root directory
+ self.assertEqual(root_dir[0].as_bytes(),
+ first_entry_bytes[:DIRENTRY_SIZE])
+
+ def test_read_files(self):
+ """
+ Test reading the content of the files
+ """
+ fat16 = self.init_fat16()
+
+ for i in range(10):
+ file = fat16.find_direntry(f"/FILE{i}.TXT")
+ self.assertIsNotNone(file)
+ self.assertEqual(
+ fat16.read_file(file), f"Hello, world! {i}\n".encode("ascii")
+ )
+
+ # test large files
+ large1 = fat16.find_direntry("/LARGE1.TXT")
+ with open(os.path.join(filesystem, "large1.txt"), "rb") as f:
+ self.assertEqual(fat16.read_file(large1), f.read())
+
+ large2 = fat16.find_direntry("/LARGE2.TXT")
+ self.assertIsNotNone(large2)
+ with open(os.path.join(filesystem, "large2.txt"), "rb") as f:
+ self.assertEqual(fat16.read_file(large2), f.read())
+
+ def test_write_file_same_content_direct(self):
+ """
+ Similar to `test_write_file_in_same_content`, but we write the file
+ directly clusters and thus we don't go through the modification of
+ direntry.
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/FILE0.TXT")
+ self.assertIsNotNone(file)
+
+ data = fat16.read_cluster(file.cluster)
+ fat16.write_cluster(file.cluster, data)
+
+ with open(os.path.join(filesystem, "file0.txt"), "rb") as f:
+ self.assertEqual(fat16.read_file(file), f.read())
+
+ def test_write_file_in_same_content(self):
+ """
+ Test writing the same content to the file back to it
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/FILE0.TXT")
+ self.assertIsNotNone(file)
+
+ self.assertEqual(fat16.read_file(file), b"Hello, world! 0\n")
+
+ fat16.write_file(file, b"Hello, world! 0\n")
+ self.assertEqual(fat16.read_file(file), b"Hello, world! 0\n")
+
+ with open(os.path.join(filesystem, "file0.txt"), "rb") as f:
+ self.assertEqual(f.read(), b"Hello, world! 0\n")
+
+ def test_modify_content_same_clusters(self):
+ """
+ Test modifying the content of the file without changing the number of
+ clusters
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/FILE0.TXT")
+ self.assertIsNotNone(file)
+
+ new_content = b"Hello, world! Modified\n"
+ self.assertEqual(fat16.read_file(file), b"Hello, world! 0\n")
+
+ fat16.write_file(file, new_content)
+ self.assertEqual(fat16.read_file(file), new_content)
+
+ with open(os.path.join(filesystem, "file0.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_truncate_file_same_clusters_less(self):
+ """
+ Test truncating the file without changing number of clusters
+ Test decreasing the file size
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/FILE0.TXT")
+ self.assertIsNotNone(file)
+
+ self.assertEqual(fat16.read_file(file), b"Hello, world! 0\n")
+
+ fat16.truncate_file(file, 5)
+ new_content = fat16.read_file(file)
+ self.assertEqual(new_content, b"Hello")
+
+ with open(os.path.join(filesystem, "file0.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_truncate_file_same_clusters_more(self):
+ """
+ Test truncating the file without changing number of clusters
+ Test increase the file size
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/FILE0.TXT")
+ self.assertIsNotNone(file)
+
+ self.assertEqual(fat16.read_file(file), b"Hello, world! 0\n")
+
+ fat16.truncate_file(file, 20)
+ new_content = fat16.read_file(file)
+ self.assertIsNotNone(new_content)
+
+ # random pattern will be appended to the file, and its not always the
+ # same
+ self.assertEqual(new_content[:16], b"Hello, world! 0\n")
+ self.assertEqual(len(new_content), 20)
+
+ with open(os.path.join(filesystem, "file0.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_write_large_file(self):
+ """
+ Test writing a large file
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/LARGE1.TXT")
+ self.assertIsNotNone(file)
+
+ # The content of LARGE1 is A * 1KB, B * 1KB, C * 1KB, ..., P * 1KB
+ # Lets change it to be Z * 1KB, Y * 1KB, X * 1KB, ..., K * 1KB
+ # without changing the number of clusters or filesize
+ new_content = b"".join([bytes([0x5A - i] * 1024) for i in range(16)])
+ fat16.write_file(file, new_content)
+ self.assertEqual(fat16.read_file(file), new_content)
+
+ with open(os.path.join(filesystem, "large1.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_truncate_file_change_clusters_less(self):
+ """
+ Test truncating a file by reducing the number of clusters
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/LARGE1.TXT")
+ self.assertIsNotNone(file)
+
+ fat16.truncate_file(file, 1)
+ self.assertEqual(fat16.read_file(file), b"A")
+
+ with open(os.path.join(filesystem, "large1.txt"), "rb") as f:
+ self.assertEqual(f.read(), b"A")
+
+ def test_write_file_change_clusters_less(self):
+ """
+ Test truncating a file by reducing the number of clusters
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/LARGE2.TXT")
+ self.assertIsNotNone(file)
+
+ new_content = b"X" * 8 * 1024 + b"Y" * 8 * 1024
+ fat16.write_file(file, new_content)
+ self.assertEqual(fat16.read_file(file), new_content)
+
+ with open(os.path.join(filesystem, "large2.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_write_file_change_clusters_more(self):
+ """
+ Test truncating a file by increasing the number of clusters
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/LARGE2.TXT")
+ self.assertIsNotNone(file)
+
+ # from 3 clusters to 4 clusters
+ new_content = (
+ b"W" * 8 * 1024 +
+ b"X" * 8 * 1024 +
+ b"Y" * 8 * 1024 +
+ b"Z" * 8 * 1024
+ )
+ fat16.write_file(file, new_content)
+ self.assertEqual(fat16.read_file(file), new_content)
+
+ with open(os.path.join(filesystem, "large2.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_write_file_change_clusters_more_non_contiguous_2_mappings(self):
+ """
+ Test truncating a file by increasing the number of clusters Here we
+ allocate the new clusters in a way that makes them non-contiguous so
+ that we will get 2 cluster mappings for the file
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/LARGE1.TXT")
+ self.assertIsNotNone(file)
+
+ # from 2 clusters to 3 clusters with non-contiguous allocation
+ fat16.truncate_file(file, 3 * 0x2000, allocate_non_continuous=True)
+ new_content = b"X" * 8 * 1024 + b"Y" * 8 * 1024 + b"Z" * 8 * 1024
+ fat16.write_file(file, new_content)
+ self.assertEqual(fat16.read_file(file), new_content)
+
+ with open(os.path.join(filesystem, "large1.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_write_file_change_clusters_more_non_contiguous_3_mappings(self):
+ """
+ Test truncating a file by increasing the number of clusters Here we
+ allocate the new clusters in a way that makes them non-contiguous so
+ that we will get 3 cluster mappings for the file
+ """
+ fat16 = self.init_fat16()
+
+ file = fat16.find_direntry("/LARGE1.TXT")
+ self.assertIsNotNone(file)
+
+ # from 2 clusters to 4 clusters with non-contiguous allocation
+ fat16.truncate_file(file, 4 * 0x2000, allocate_non_continuous=True)
+ new_content = (
+ b"W" * 8 * 1024 +
+ b"X" * 8 * 1024 +
+ b"Y" * 8 * 1024 +
+ b"Z" * 8 * 1024
+ )
+ fat16.write_file(file, new_content)
+ self.assertEqual(fat16.read_file(file), new_content)
+
+ with open(os.path.join(filesystem, "large1.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ def test_create_file(self):
+ """
+ Test creating a new file
+ """
+ fat16 = self.init_fat16()
+
+ new_file = fat16.create_file("/NEWFILE.TXT")
+
+ self.assertIsNotNone(new_file)
+ self.assertEqual(new_file.size_bytes, 0)
+
+ new_content = b"Hello, world! New file\n"
+ fat16.write_file(new_file, new_content)
+ self.assertEqual(fat16.read_file(new_file), new_content)
+
+ with open(os.path.join(filesystem, "newfile.txt"), "rb") as f:
+ self.assertEqual(f.read(), new_content)
+
+ # TODO: support deleting files
+
+
+if __name__ == "__main__":
+ # This is a specific test for vvfat driver
+ iotests.main(supported_fmts=["vvfat"], supported_protocols=["file"])
diff --git a/tests/qemu-iotests/tests/vvfat.out b/tests/qemu-iotests/tests/vvfat.out
new file mode 100755
index 0000000000..b6f257674e
--- /dev/null
+++ b/tests/qemu-iotests/tests/vvfat.out
@@ -0,0 +1,5 @@
+................
+----------------------------------------------------------------------
+Ran 16 tests
+
+OK
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 46/69] nbd/server: Plumb in new args to nbd_client_add()
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (44 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 45/69] iotests: Add `vvfat` tests Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 47/69] nbd/server: CVE-2024-7409: Cap default max-connections to 100 Michael Tokarev
` (22 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Eric Blake, Vladimir Sementsov-Ogievskiy,
Daniel P . Berrangé, Michael Tokarev
From: Eric Blake <eblake@redhat.com>
Upcoming patches to fix a CVE need to track an opaque pointer passed
in by the owner of a client object, as well as request for a time
limit on how fast negotiation must complete. Prepare for that by
changing the signature of nbd_client_new() and adding an accessor to
get at the opaque pointer, although for now the two servers
(qemu-nbd.c and blockdev-nbd.c) do not change behavior even though
they pass in a new default timeout value.
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-11-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[eblake: s/LIMIT/MAX_SECS/ as suggested by Dan]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit fb1c2aaa981e0a2fa6362c9985f1296b74f055ac)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 213012435f..267a1de903 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -64,8 +64,10 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
nbd_update_server_watch(nbd_server);
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
- nbd_client_new(cioc, nbd_server->tlscreds, nbd_server->tlsauthz,
- nbd_blockdev_client_closed);
+ /* TODO - expose handshake timeout as QMP option */
+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
+ nbd_server->tlscreds, nbd_server->tlsauthz,
+ nbd_blockdev_client_closed, NULL);
}
static void nbd_update_server_watch(NBDServerData *s)
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4e7bd6342f..1d4d65922d 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -33,6 +33,12 @@ typedef struct NBDMetaContexts NBDMetaContexts;
extern const BlockExportDriver blk_exp_nbd;
+/*
+ * NBD_DEFAULT_HANDSHAKE_MAX_SECS: Number of seconds in which client must
+ * succeed at NBD_OPT_GO before being forcefully dropped as too slow.
+ */
+#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10
+
/* Handshake phase structs - this struct is passed on the wire */
typedef struct NBDOption {
@@ -403,9 +409,12 @@ AioContext *nbd_export_aio_context(NBDExport *exp);
NBDExport *nbd_export_find(const char *name);
void nbd_client_new(QIOChannelSocket *sioc,
+ uint32_t handshake_max_secs,
QCryptoTLSCreds *tlscreds,
const char *tlsauthz,
- void (*close_fn)(NBDClient *, bool));
+ void (*close_fn)(NBDClient *, bool),
+ void *owner);
+void *nbd_client_owner(NBDClient *client);
void nbd_client_get(NBDClient *client);
void nbd_client_put(NBDClient *client);
diff --git a/nbd/server.c b/nbd/server.c
index 892797bb11..e50012499f 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -124,12 +124,14 @@ struct NBDMetaContexts {
struct NBDClient {
int refcount; /* atomic */
void (*close_fn)(NBDClient *client, bool negotiated);
+ void *owner;
QemuMutex lock;
NBDExport *exp;
QCryptoTLSCreds *tlscreds;
char *tlsauthz;
+ uint32_t handshake_max_secs;
QIOChannelSocket *sioc; /* The underlying data channel */
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
@@ -3191,6 +3193,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
qemu_co_mutex_init(&client->send_lock);
+ /* TODO - utilize client->handshake_max_secs */
if (nbd_negotiate(client, &local_err)) {
if (local_err) {
error_report_err(local_err);
@@ -3205,14 +3208,17 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
}
/*
- * Create a new client listener using the given channel @sioc.
+ * Create a new client listener using the given channel @sioc and @owner.
* Begin servicing it in a coroutine. When the connection closes, call
- * @close_fn with an indication of whether the client completed negotiation.
+ * @close_fn with an indication of whether the client completed negotiation
+ * within @handshake_max_secs seconds (0 for unbounded).
*/
void nbd_client_new(QIOChannelSocket *sioc,
+ uint32_t handshake_max_secs,
QCryptoTLSCreds *tlscreds,
const char *tlsauthz,
- void (*close_fn)(NBDClient *, bool))
+ void (*close_fn)(NBDClient *, bool),
+ void *owner)
{
NBDClient *client;
Coroutine *co;
@@ -3225,13 +3231,21 @@ void nbd_client_new(QIOChannelSocket *sioc,
object_ref(OBJECT(client->tlscreds));
}
client->tlsauthz = g_strdup(tlsauthz);
+ client->handshake_max_secs = handshake_max_secs;
client->sioc = sioc;
qio_channel_set_delay(QIO_CHANNEL(sioc), false);
object_ref(OBJECT(client->sioc));
client->ioc = QIO_CHANNEL(sioc);
object_ref(OBJECT(client->ioc));
client->close_fn = close_fn;
+ client->owner = owner;
co = qemu_coroutine_create(nbd_co_client_start, client);
qemu_coroutine_enter(co);
}
+
+void *
+nbd_client_owner(NBDClient *client)
+{
+ return client->owner;
+}
diff --git a/qemu-nbd.c b/qemu-nbd.c
index d7b3ccab21..48e2fa5858 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -390,7 +390,9 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
nb_fds++;
nbd_update_server_watch();
- nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed);
+ /* TODO - expose handshake timeout as command line option */
+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
+ tlscreds, tlsauthz, nbd_client_closed, NULL);
}
static void nbd_update_server_watch(void)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 47/69] nbd/server: CVE-2024-7409: Cap default max-connections to 100
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (45 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 46/69] nbd/server: Plumb in new args to nbd_client_add() Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 48/69] nbd/server: CVE-2024-7409: Drop non-negotiating clients Michael Tokarev
` (21 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Eric Blake, Daniel P . Berrangé,
Michael Tokarev
From: Eric Blake <eblake@redhat.com>
Allowing an unlimited number of clients to any web service is a recipe
for a rudimentary denial of service attack: the client merely needs to
open lots of sockets without closing them, until qemu no longer has
any more fds available to allocate.
For qemu-nbd, we default to allowing only 1 connection unless more are
explicitly asked for (-e or --shared); this was historically picked as
a nice default (without an explicit -t, a non-persistent qemu-nbd goes
away after a client disconnects, without needing any additional
follow-up commands), and we are not going to change that interface now
(besides, someday we want to point people towards qemu-storage-daemon
instead of qemu-nbd).
But for qemu proper, and the newer qemu-storage-daemon, the QMP
nbd-server-start command has historically had a default of unlimited
number of connections, in part because unlike qemu-nbd it is
inherently persistent until nbd-server-stop. Allowing multiple client
sockets is particularly useful for clients that can take advantage of
MULTI_CONN (creating parallel sockets to increase throughput),
although known clients that do so (such as libnbd's nbdcopy) typically
use only 8 or 16 connections (the benefits of scaling diminish once
more sockets are competing for kernel attention). Picking a number
large enough for typical use cases, but not unlimited, makes it
slightly harder for a malicious client to perform a denial of service
merely by opening lots of connections withot progressing through the
handshake.
This change does not eliminate CVE-2024-7409 on its own, but reduces
the chance for fd exhaustion or unlimited memory usage as an attack
surface. On the other hand, by itself, it makes it more obvious that
with a finite limit, we have the problem of an unauthenticated client
holding 100 fds opened as a way to block out a legitimate client from
being able to connect; thus, later patches will further add timeouts
to reject clients that are not making progress.
This is an INTENTIONAL change in behavior, and will break any client
of nbd-server-start that was not passing an explicit max-connections
parameter, yet expects more than 100 simultaneous connections. We are
not aware of any such client (as stated above, most clients aware of
MULTI_CONN get by just fine on 8 or 16 connections, and probably cope
with later connections failing by relying on the earlier connections;
libvirt has not yet been passing max-connections, but generally
creates NBD servers with the intent for a single client for the sake
of live storage migration; meanwhile, the KubeSAN project anticipates
a large cluster sharing multiple clients [up to 8 per node, and up to
100 nodes in a cluster], but it currently uses qemu-nbd with an
explicit --shared=0 rather than qemu-storage-daemon with
nbd-server-start).
We considered using a deprecation period (declare that omitting
max-parameters is deprecated, and make it mandatory in 3 releases -
then we don't need to pick an arbitrary default); that has zero risk
of breaking any apps that accidentally depended on more than 100
connections, and where such breakage might not be noticed under unit
testing but only under the larger loads of production usage. But it
does not close the denial-of-service hole until far into the future,
and requires all apps to change to add the parameter even if 100 was
good enough. It also has a drawback that any app (like libvirt) that
is accidentally relying on an unlimited default should seriously
consider their own CVE now, at which point they are going to change to
pass explicit max-connections sooner than waiting for 3 qemu releases.
Finally, if our changed default breaks an app, that app can always
pass in an explicit max-parameters with a larger value.
It is also intentional that the HMP interface to nbd-server-start is
not changed to expose max-connections (any client needing to fine-tune
things should be using QMP).
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-12-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[ericb: Expand commit message to summarize Dan's argument for why we
break corner-case back-compat behavior without a deprecation period]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit c8a76dbd90c2f48df89b75bef74917f90a59b623)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index d954bec6f1..bdf2eb50b6 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -402,7 +402,8 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
goto exit;
}
- nbd_server_start(addr, NULL, NULL, 0, &local_err);
+ nbd_server_start(addr, NULL, NULL, NBD_DEFAULT_MAX_CONNECTIONS,
+ &local_err);
qapi_free_SocketAddress(addr);
if (local_err != NULL) {
goto exit;
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 267a1de903..24ba5382db 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -170,6 +170,10 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
void nbd_server_start_options(NbdServerOptions *arg, Error **errp)
{
+ if (!arg->has_max_connections) {
+ arg->max_connections = NBD_DEFAULT_MAX_CONNECTIONS;
+ }
+
nbd_server_start(arg->addr, arg->tls_creds, arg->tls_authz,
arg->max_connections, errp);
}
@@ -182,6 +186,10 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr,
{
SocketAddress *addr_flat = socket_address_flatten(addr);
+ if (!has_max_connections) {
+ max_connections = NBD_DEFAULT_MAX_CONNECTIONS;
+ }
+
nbd_server_start(addr_flat, tls_creds, tls_authz, max_connections, errp);
qapi_free_SocketAddress(addr_flat);
}
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 1d4d65922d..d4f8b21aec 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -39,6 +39,13 @@ extern const BlockExportDriver blk_exp_nbd;
*/
#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10
+/*
+ * NBD_DEFAULT_MAX_CONNECTIONS: Number of client sockets to allow at
+ * once; must be large enough to allow a MULTI_CONN-aware client like
+ * nbdcopy to create its typical number of 8-16 sockets.
+ */
+#define NBD_DEFAULT_MAX_CONNECTIONS 100
+
/* Handshake phase structs - this struct is passed on the wire */
typedef struct NBDOption {
diff --git a/qapi/block-export.json b/qapi/block-export.json
index 3919a2d5b9..f45e4fd481 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -28,7 +28,7 @@
# @max-connections: The maximum number of connections to allow at the
# same time, 0 for unlimited. Setting this to 1 also stops the
# server from advertising multiple client support (since 5.2;
-# default: 0)
+# default: 100)
#
# Since: 4.2
##
@@ -63,7 +63,7 @@
# @max-connections: The maximum number of connections to allow at the
# same time, 0 for unlimited. Setting this to 1 also stops the
# server from advertising multiple client support (since 5.2;
-# default: 0).
+# default: 100).
#
# Errors:
# - if the server is already running
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 48/69] nbd/server: CVE-2024-7409: Drop non-negotiating clients
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (46 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 47/69] nbd/server: CVE-2024-7409: Cap default max-connections to 100 Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 49/69] nbd/server: CVE-2024-7409: Close stray clients at server-stop Michael Tokarev
` (20 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Eric Blake, Daniel P . Berrangé,
Michael Tokarev
From: Eric Blake <eblake@redhat.com>
A client that opens a socket but does not negotiate is merely hogging
qemu's resources (an open fd and a small amount of memory); and a
malicious client that can access the port where NBD is listening can
attempt a denial of service attack by intentionally opening and
abandoning lots of unfinished connections. The previous patch put a
default bound on the number of such ongoing connections, but once that
limit is hit, no more clients can connect (including legitimate ones).
The solution is to insist that clients complete handshake within a
reasonable time limit, defaulting to 10 seconds. A client that has
not successfully completed NBD_OPT_GO by then (including the case of
where the client didn't know TLS credentials to even reach the point
of NBD_OPT_GO) is wasting our time and does not deserve to stay
connected. Later patches will allow fine-tuning the limit away from
the default value (including disabling it for doing integration
testing of the handshake process itself).
Note that this patch in isolation actually makes it more likely to see
qemu SEGV after nbd-server-stop, as any client socket still connected
when the server shuts down will now be closed after 10 seconds rather
than at the client's whims. That will be addressed in the next patch.
For a demo of this patch in action:
$ qemu-nbd -f raw -r -t -e 10 file &
$ nbdsh --opt-mode -c '
H = list()
for i in range(20):
print(i)
H.insert(i, nbd.NBD())
H[i].set_opt_mode(True)
H[i].connect_uri("nbd://localhost")
'
$ kill $!
where later connections get to start progressing once earlier ones are
forcefully dropped for taking too long, rather than hanging.
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-13-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[eblake: rebase to changes earlier in series, reduce scope of timer]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit b9b72cb3ce15b693148bd09cef7e50110566d8a0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/nbd/server.c b/nbd/server.c
index e50012499f..39285cc971 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -3186,22 +3186,48 @@ static void nbd_client_receive_next_request(NBDClient *client)
}
}
+static void nbd_handshake_timer_cb(void *opaque)
+{
+ QIOChannel *ioc = opaque;
+
+ trace_nbd_handshake_timer_cb();
+ qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+}
+
static coroutine_fn void nbd_co_client_start(void *opaque)
{
NBDClient *client = opaque;
Error *local_err = NULL;
+ QEMUTimer *handshake_timer = NULL;
qemu_co_mutex_init(&client->send_lock);
- /* TODO - utilize client->handshake_max_secs */
+ /*
+ * Create a timer to bound the time spent in negotiation. If the
+ * timer expires, it is likely nbd_negotiate will fail because the
+ * socket was shutdown.
+ */
+ if (client->handshake_max_secs > 0) {
+ handshake_timer = aio_timer_new(qemu_get_aio_context(),
+ QEMU_CLOCK_REALTIME,
+ SCALE_NS,
+ nbd_handshake_timer_cb,
+ client->sioc);
+ timer_mod(handshake_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +
+ client->handshake_max_secs * NANOSECONDS_PER_SECOND);
+ }
+
if (nbd_negotiate(client, &local_err)) {
if (local_err) {
error_report_err(local_err);
}
+ timer_free(handshake_timer);
client_close(client, false);
return;
}
+ timer_free(handshake_timer);
WITH_QEMU_LOCK_GUARD(&client->lock) {
nbd_client_receive_next_request(client);
}
diff --git a/nbd/trace-events b/nbd/trace-events
index 00ae3216a1..cbd0a4ab7e 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -76,6 +76,7 @@ nbd_co_receive_request_payload_received(uint64_t cookie, uint64_t len) "Payload
nbd_co_receive_ext_payload_compliance(uint64_t from, uint64_t len) "client sent non-compliant write without payload flag: from=0x%" PRIx64 ", len=0x%" PRIx64
nbd_co_receive_align_compliance(const char *op, uint64_t from, uint64_t len, uint32_t align) "client sent non-compliant unaligned %s request: from=0x%" PRIx64 ", len=0x%" PRIx64 ", align=0x%" PRIx32
nbd_trip(void) "Reading request"
+nbd_handshake_timer_cb(void) "client took too long to negotiate"
# client-connection.c
nbd_connect_thread_sleep(uint64_t timeout) "timeout %" PRIu64
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 49/69] nbd/server: CVE-2024-7409: Close stray clients at server-stop
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (47 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 48/69] nbd/server: CVE-2024-7409: Drop non-negotiating clients Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 50/69] nbd/server: CVE-2024-7409: Avoid use-after-free when closing server Michael Tokarev
` (19 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Eric Blake, Alexander Ivanov,
Daniel P . Berrangé, Michael Tokarev
From: Eric Blake <eblake@redhat.com>
A malicious client can attempt to connect to an NBD server, and then
intentionally delay progress in the handshake, including if it does
not know the TLS secrets. Although the previous two patches reduce
this behavior by capping the default max-connections parameter and
killing slow clients, they did not eliminate the possibility of a
client waiting to close the socket until after the QMP nbd-server-stop
command is executed, at which point qemu would SEGV when trying to
dereference the NULL nbd_server global which is no longer present.
This amounts to a denial of service attack. Worse, if another NBD
server is started before the malicious client disconnects, I cannot
rule out additional adverse effects when the old client interferes
with the connection count of the new server (although the most likely
is a crash due to an assertion failure when checking
nbd_server->connections > 0).
For environments without this patch, the CVE can be mitigated by
ensuring (such as via a firewall) that only trusted clients can
connect to an NBD server. Note that using frameworks like libvirt
that ensure that TLS is used and that nbd-server-stop is not executed
while any trusted clients are still connected will only help if there
is also no possibility for an untrusted client to open a connection
but then stall on the NBD handshake.
Given the previous patches, it would be possible to guarantee that no
clients remain connected by having nbd-server-stop sleep for longer
than the default handshake deadline before finally freeing the global
nbd_server object, but that could make QMP non-responsive for a long
time. So intead, this patch fixes the problem by tracking all client
sockets opened while the server is running, and forcefully closing any
such sockets remaining without a completed handshake at the time of
nbd-server-stop, then waiting until the coroutines servicing those
sockets notice the state change. nbd-server-stop now has a second
AIO_WAIT_WHILE_UNLOCKED (the first is indirectly through the
blk_exp_close_all_type() that disconnects all clients that completed
handshakes), but forced socket shutdown is enough to progress the
coroutines and quickly tear down all clients before the server is
freed, thus finally fixing the CVE.
This patch relies heavily on the fact that nbd/server.c guarantees
that it only calls nbd_blockdev_client_closed() from the main loop
(see the assertion in nbd_client_put() and the hoops used in
nbd_client_put_nonzero() to achieve that); if we did not have that
guarantee, we would also need a mutex protecting our accesses of the
list of connections to survive re-entrancy from independent iothreads.
Although I did not actually try to test old builds, it looks like this
problem has existed since at least commit 862172f45c (v2.12.0, 2017) -
even back when that patch started using a QIONetListener to handle
listening on multiple sockets, nbd_server_free() was already unaware
that the nbd_blockdev_client_closed callback can be reached later by a
client thread that has not completed handshakes (and therefore the
client's socket never got added to the list closed in
nbd_export_close_all), despite that patch intentionally tearing down
the QIONetListener to prevent new clients.
Reported-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
Fixes: CVE-2024-7409
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-14-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 3e7ef738c8462c45043a1d39f702a0990406a3b3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 24ba5382db..f73409ae49 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -21,12 +21,18 @@
#include "io/channel-socket.h"
#include "io/net-listener.h"
+typedef struct NBDConn {
+ QIOChannelSocket *cioc;
+ QLIST_ENTRY(NBDConn) next;
+} NBDConn;
+
typedef struct NBDServerData {
QIONetListener *listener;
QCryptoTLSCreds *tlscreds;
char *tlsauthz;
uint32_t max_connections;
uint32_t connections;
+ QLIST_HEAD(, NBDConn) conns;
} NBDServerData;
static NBDServerData *nbd_server;
@@ -51,6 +57,14 @@ int nbd_server_max_connections(void)
static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
{
+ NBDConn *conn = nbd_client_owner(client);
+
+ assert(qemu_in_main_thread() && nbd_server);
+
+ object_unref(OBJECT(conn->cioc));
+ QLIST_REMOVE(conn, next);
+ g_free(conn);
+
nbd_client_put(client);
assert(nbd_server->connections > 0);
nbd_server->connections--;
@@ -60,14 +74,20 @@ static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
gpointer opaque)
{
+ NBDConn *conn = g_new0(NBDConn, 1);
+
+ assert(qemu_in_main_thread() && nbd_server);
nbd_server->connections++;
+ object_ref(OBJECT(cioc));
+ conn->cioc = cioc;
+ QLIST_INSERT_HEAD(&nbd_server->conns, conn, next);
nbd_update_server_watch(nbd_server);
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
/* TODO - expose handshake timeout as QMP option */
nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
nbd_server->tlscreds, nbd_server->tlsauthz,
- nbd_blockdev_client_closed, NULL);
+ nbd_blockdev_client_closed, conn);
}
static void nbd_update_server_watch(NBDServerData *s)
@@ -81,12 +101,25 @@ static void nbd_update_server_watch(NBDServerData *s)
static void nbd_server_free(NBDServerData *server)
{
+ NBDConn *conn, *tmp;
+
if (!server) {
return;
}
+ /*
+ * Forcefully close the listener socket, and any clients that have
+ * not yet disconnected on their own.
+ */
qio_net_listener_disconnect(server->listener);
object_unref(OBJECT(server->listener));
+ QLIST_FOREACH_SAFE(conn, &server->conns, next, tmp) {
+ qio_channel_shutdown(QIO_CHANNEL(conn->cioc), QIO_CHANNEL_SHUTDOWN_BOTH,
+ NULL);
+ }
+
+ AIO_WAIT_WHILE_UNLOCKED(NULL, server->connections > 0);
+
if (server->tlscreds) {
object_unref(OBJECT(server->tlscreds));
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 50/69] nbd/server: CVE-2024-7409: Avoid use-after-free when closing server
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (48 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 49/69] nbd/server: CVE-2024-7409: Close stray clients at server-stop Michael Tokarev
@ 2024-09-06 11:12 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 51/69] net: Fix '-net nic, model=' for non-help arguments Michael Tokarev
` (18 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:12 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Eric Blake, Andrey Drobyshev, Stefan Hajnoczi,
Michael Tokarev
From: Eric Blake <eblake@redhat.com>
Commit 3e7ef738 plugged the use-after-free of the global nbd_server
object, but overlooked a use-after-free of nbd_server->listener.
Although this race is harder to hit, notice that our shutdown path
first drops the reference count of nbd_server->listener, then triggers
actions that can result in a pending client reaching the
nbd_blockdev_client_closed() callback, which in turn calls
qio_net_listener_set_client_func on a potentially stale object.
If we know we don't want any more clients to connect, and have already
told the listener socket to shut down, then we should not be trying to
update the listener socket's associated function.
Reproducer:
> #!/usr/bin/python3
>
> import os
> from threading import Thread
>
> def start_stop():
> while 1:
> os.system('virsh qemu-monitor-command VM \'{"execute": "nbd-server-start",
+"arguments":{"addr":{"type":"unix","data":{"path":"/tmp/nbd-sock"}}}}\'')
> os.system('virsh qemu-monitor-command VM \'{"execute": "nbd-server-stop"}\'')
>
> def nbd_list():
> while 1:
> os.system('/path/to/build/qemu-nbd -L -k /tmp/nbd-sock')
>
> def test():
> sst = Thread(target=start_stop)
> sst.start()
> nlt = Thread(target=nbd_list)
> nlt.start()
>
> sst.join()
> nlt.join()
>
> test()
Fixes: CVE-2024-7409
Fixes: 3e7ef738c8 ("nbd/server: CVE-2024-7409: Close stray clients at server-stop")
CC: qemu-stable@nongnu.org
Reported-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240822143617.800419-2-eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 3874f5f73c441c52f1c699c848d463b0eda01e4c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index f73409ae49..b36f41b7c5 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -92,10 +92,13 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
static void nbd_update_server_watch(NBDServerData *s)
{
- if (!s->max_connections || s->connections < s->max_connections) {
- qio_net_listener_set_client_func(s->listener, nbd_accept, NULL, NULL);
- } else {
- qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
+ if (s->listener) {
+ if (!s->max_connections || s->connections < s->max_connections) {
+ qio_net_listener_set_client_func(s->listener, nbd_accept, NULL,
+ NULL);
+ } else {
+ qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
+ }
}
}
@@ -113,6 +116,7 @@ static void nbd_server_free(NBDServerData *server)
*/
qio_net_listener_disconnect(server->listener);
object_unref(OBJECT(server->listener));
+ server->listener = NULL;
QLIST_FOREACH_SAFE(conn, &server->conns, next, tmp) {
qio_channel_shutdown(QIO_CHANNEL(conn->cioc), QIO_CHANNEL_SHUTDOWN_BOTH,
NULL);
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 51/69] net: Fix '-net nic, model=' for non-help arguments
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (49 preceding siblings ...)
2024-09-06 11:12 ` [Stable-9.0.3 50/69] nbd/server: CVE-2024-7409: Avoid use-after-free when closing server Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 52/69] hw/core/ptimer: fix timer zero period condition for freq > 1GHz Michael Tokarev
` (17 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, David Woodhouse, Hans, Michael Tokarev, Jason Wang
From: David Woodhouse <dwmw@amazon.co.uk>
Oops, don't *delete* the model option when checking for 'help'.
Fixes: 64f75f57f9d2 ("net: Reinstate '-net nic, model=help' output as documented in man page")
Reported-by: Hans <sungdgdhtryrt@gmail.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Cc: qemu-stable@nongnu.org
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit fa62cb989a9146c82f8f172715042852f5d36200)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/net/net.c b/net/net.c
index e6ca2529bb..897bb936cf 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1748,7 +1748,7 @@ void net_check_clients(void)
static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
{
- const char *model = qemu_opt_get_del(opts, "model");
+ const char *model = qemu_opt_get(opts, "model");
if (is_nic_model_help_option(model)) {
return 0;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 52/69] hw/core/ptimer: fix timer zero period condition for freq > 1GHz
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (50 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 51/69] net: Fix '-net nic, model=' for non-help arguments Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 53/69] block/blkio: use FUA flag on write zeroes only if supported Michael Tokarev
` (16 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Jianzhou Yue, Peter Maydell, Michael Tokarev
From: Jianzhou Yue <JianZhou.Yue@verisilicon.com>
The real period is zero when both period and period_frac are zero.
Check the method ptimer_set_freq, if freq is larger than 1000 MHz,
the period is zero, but the period_frac is not, in this case, the
ptimer will work but the current code incorrectly recognizes that
the ptimer is disabled.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2306
Signed-off-by: JianZhou Yue <JianZhou.Yue@verisilicon.com>
Message-id: 3DA024AEA8B57545AF1B3CAA37077D0FB75E82C8@SHASXM03.verisilicon.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 446e5e8b4515e9a7be69ef6a29852975289bb6f0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
index b1517592c6..1d8964d804 100644
--- a/hw/core/ptimer.c
+++ b/hw/core/ptimer.c
@@ -83,7 +83,7 @@ static void ptimer_reload(ptimer_state *s, int delta_adjust)
delta = s->delta = s->limit;
}
- if (s->period == 0) {
+ if (s->period == 0 && s->period_frac == 0) {
if (!qtest_enabled()) {
fprintf(stderr, "Timer with period zero, disabling\n");
}
@@ -309,7 +309,7 @@ void ptimer_run(ptimer_state *s, int oneshot)
assert(s->in_transaction);
- if (was_disabled && s->period == 0) {
+ if (was_disabled && s->period == 0 && s->period_frac == 0) {
if (!qtest_enabled()) {
fprintf(stderr, "Timer with period zero, disabling\n");
}
diff --git a/tests/unit/ptimer-test.c b/tests/unit/ptimer-test.c
index 04b5f4e3d0..08240594bb 100644
--- a/tests/unit/ptimer-test.c
+++ b/tests/unit/ptimer-test.c
@@ -763,6 +763,33 @@ static void check_oneshot_with_load_0(gconstpointer arg)
ptimer_free(ptimer);
}
+static void check_freq_more_than_1000M(gconstpointer arg)
+{
+ const uint8_t *policy = arg;
+ ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
+ bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
+
+ triggered = false;
+
+ ptimer_transaction_begin(ptimer);
+ ptimer_set_freq(ptimer, 2000000000);
+ ptimer_set_limit(ptimer, 8, 1);
+ ptimer_run(ptimer, 1);
+ ptimer_transaction_commit(ptimer);
+
+ qemu_clock_step(3);
+
+ g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
+ g_assert_false(triggered);
+
+ qemu_clock_step(1);
+
+ g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
+ g_assert_true(triggered);
+
+ ptimer_free(ptimer);
+}
+
static void add_ptimer_tests(uint8_t policy)
{
char policy_name[256] = "";
@@ -857,6 +884,12 @@ static void add_ptimer_tests(uint8_t policy)
policy_name),
g_memdup2(&policy, 1), check_oneshot_with_load_0, g_free);
g_free(tmp);
+
+ g_test_add_data_func_full(
+ tmp = g_strdup_printf("/ptimer/freq_more_than_1000M policy=%s",
+ policy_name),
+ g_memdup2(&policy, 1), check_freq_more_than_1000M, g_free);
+ g_free(tmp);
}
static void add_all_ptimer_policies_comb_tests(void)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 53/69] block/blkio: use FUA flag on write zeroes only if supported
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (51 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 52/69] hw/core/ptimer: fix timer zero period condition for freq > 1GHz Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 54/69] target/i386: Do not apply REX to MMX operands Michael Tokarev
` (15 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Stefano Garzarella, Eric Blake,
Philippe Mathieu-Daudé, Stefan Hajnoczi, Michael Tokarev
From: Stefano Garzarella <sgarzare@redhat.com>
libblkio supports BLKIO_REQ_FUA with write zeros requests only since
version 1.4.0, so let's inform the block layer that the blkio driver
supports it only in this case. Otherwise we can have runtime errors
as reported in https://issues.redhat.com/browse/RHEL-32878
Fixes: fd66dbd424 ("blkio: add libblkio block driver")
Cc: qemu-stable@nongnu.org
Buglink: https://issues.redhat.com/browse/RHEL-32878
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240808080545.40744-1-sgarzare@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 547c4e50929ec6c091d9c16a7b280e829b12b463)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/block/blkio.c b/block/blkio.c
index 882e1c297b..52ac94527f 100644
--- a/block/blkio.c
+++ b/block/blkio.c
@@ -899,8 +899,10 @@ static int blkio_file_open(BlockDriverState *bs, QDict *options, int flags,
}
bs->supported_write_flags = BDRV_REQ_FUA | BDRV_REQ_REGISTERED_BUF;
- bs->supported_zero_flags = BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP |
- BDRV_REQ_NO_FALLBACK;
+ bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
+#ifdef CONFIG_BLKIO_WRITE_ZEROS_FUA
+ bs->supported_zero_flags |= BDRV_REQ_FUA;
+#endif
qemu_mutex_init(&s->blkio_lock);
qemu_co_mutex_init(&s->bounce_lock);
diff --git a/meson.build b/meson.build
index 91a0aa64c6..7a56772136 100644
--- a/meson.build
+++ b/meson.build
@@ -2211,6 +2211,8 @@ config_host_data.set('CONFIG_BLKIO', blkio.found())
if blkio.found()
config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
blkio.version().version_compare('>=1.3.0'))
+ config_host_data.set('CONFIG_BLKIO_WRITE_ZEROS_FUA',
+ blkio.version().version_compare('>=1.4.0'))
endif
config_host_data.set('CONFIG_CURL', curl.found())
config_host_data.set('CONFIG_CURSES', curses.found())
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 54/69] target/i386: Do not apply REX to MMX operands
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (52 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 53/69] block/blkio: use FUA flag on write zeroes only if supported Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 55/69] target/arm: Clear high SVE elements in handle_vec_simd_wshli Michael Tokarev
` (14 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Paolo Bonzini, Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-stable@nongnu.org
Fixes: b3e22b2318a ("target/i386: add core of new i386 decoder")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2495
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Link: https://lore.kernel.org/r/20240812025844.58956-2-richard.henderson@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 416f2b16c02c618c0f233372ebfe343f9ee667d4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 2ca874b59d..27e1666f5d 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1272,7 +1272,10 @@ static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode,
op->unit = X86_OP_SSE;
}
get_reg:
- op->n = ((get_modrm(s, env) >> 3) & 7) | REX_R(s);
+ op->n = ((get_modrm(s, env) >> 3) & 7);
+ if (op->unit != X86_OP_MMX) {
+ op->n |= REX_R(s);
+ }
break;
case X86_TYPE_E: /* ALU modrm operand */
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 55/69] target/arm: Clear high SVE elements in handle_vec_simd_wshli
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (53 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 54/69] target/i386: Do not apply REX to MMX operands Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 56/69] target/arm: Update translation regime comment for new features Michael Tokarev
` (13 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Peter Maydell, Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
AdvSIMD instructions are supposed to zero bits beyond 128.
Affects SSHLL, USHLL, SSHLL2, USHLL2.
Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240717060903.205098-15-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 8e0c9a9efa21a16190cbac288e414bbf1d80f639)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 922a16e5d4..7d620ef109 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -10263,6 +10263,7 @@ static void handle_vec_simd_wshli(DisasContext *s, bool is_q, bool is_u,
tcg_gen_shli_i64(tcg_rd, tcg_rd, shift);
write_vec_element(s, tcg_rd, rd, i, size + 1);
}
+ clear_vec_high(s, true, rd);
}
/* SHRN/RSHRN - Shift right with narrowing (and potential rounding) */
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 56/69] target/arm: Update translation regime comment for new features
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (54 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 55/69] target/arm: Clear high SVE elements in handle_vec_simd_wshli Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 57/69] target/arm: Fix usage of MMU indexes when EL3 is AArch32 Michael Tokarev
` (12 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Bernhard Beschow, Richard Henderson,
Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
We have a long comment describing the Arm architectural translation
regimes and how we map them to QEMU MMU indexes. This comment has
got a bit out of date:
* FEAT_SEL2 allows Secure EL2 and corresponding new regimes
* FEAT_RME introduces Realm state and its translation regimes
* We now model the Cortex-R52 so that is no longer a hypothetical
* We separated Secure Stage 2 and NonSecure Stage 2 MMU indexes
* We have an MMU index per physical address spacea
Add the missing pieces so that the list of architectural translation
regimes matches the Arm ARM, and the list and count of QEMU MMU
indexes in the comment matches the enum.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240809160430.1144805-2-peter.maydell@linaro.org
(cherry picked from commit 150c24f34e9c3388c0f0ad04ddd997e5559db800)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: pick this one for stable-9.0 so the next commit applies cleanly)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bc0c84873f..7c721f22bd 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2687,8 +2687,14 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
* + NonSecure EL1 & 0 stage 2
* + NonSecure EL2
* + NonSecure EL2 & 0 (ARMv8.1-VHE)
- * + Secure EL1 & 0
- * + Secure EL3
+ * + Secure EL1 & 0 stage 1
+ * + Secure EL1 & 0 stage 2 (FEAT_SEL2)
+ * + Secure EL2 (FEAT_SEL2)
+ * + Secure EL2 & 0 (FEAT_SEL2)
+ * + Realm EL1 & 0 stage 1 (FEAT_RME)
+ * + Realm EL1 & 0 stage 2 (FEAT_RME)
+ * + Realm EL2 (FEAT_RME)
+ * + EL3
* If EL3 is 32-bit:
* + NonSecure PL1 & 0 stage 1
* + NonSecure PL1 & 0 stage 2
@@ -2720,10 +2726,12 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
* table over and over.
* 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
* Never (PAN) bit within PSTATE.
- * 7. we fold together the secure and non-secure regimes for A-profile,
+ * 7. we fold together most secure and non-secure regimes for A-profile,
* because there are no banked system registers for aarch64, so the
* process of switching between secure and non-secure is
* already heavyweight.
+ * 8. we cannot fold together Stage 2 Secure and Stage 2 NonSecure,
+ * because both are in use simultaneously for Secure EL2.
*
* This gives us the following list of cases:
*
@@ -2735,14 +2743,15 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
* EL2 EL2&0 +PAN
* EL2 (aka NS PL2)
* EL3 (aka S PL1)
- * Physical (NS & S)
- * Stage2 (NS & S)
+ * Stage2 Secure
+ * Stage2 NonSecure
+ * plus one TLB per Physical address space: S, NS, Realm, Root
*
- * for a total of 12 different mmu_idx.
+ * for a total of 14 different mmu_idx.
*
* R profile CPUs have an MPU, but can use the same set of MMU indexes
* as A profile. They only need to distinguish EL0 and EL1 (and
- * EL2 if we ever model a Cortex-R52).
+ * EL2 for cores like the Cortex-R52).
*
* M profile CPUs are rather different as they do not have a true MMU.
* They have the following different MMU indexes:
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 57/69] target/arm: Fix usage of MMU indexes when EL3 is AArch32
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (55 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 56/69] target/arm: Update translation regime comment for new features Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 58/69] module: Prevent crash by resetting local_err in module_load_qom_all() Michael Tokarev
` (11 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Bernhard Beschow, Richard Henderson,
Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
Our current usage of MMU indexes when EL3 is AArch32 is confused.
Architecturally, when EL3 is AArch32, all Secure code runs under the
Secure PL1&0 translation regime:
* code at EL3, which might be Mon, or SVC, or any of the
other privileged modes (PL1)
* code at EL0 (Secure PL0)
This is different from when EL3 is AArch64, in which case EL3 is its
own translation regime, and EL1 and EL0 (whether AArch32 or AArch64)
have their own regime.
We claimed to be mapping Secure PL1 to our ARMMMUIdx_EL3, but didn't
do anything special about Secure PL0, which meant it used the same
ARMMMUIdx_EL10_0 that NonSecure PL0 does. This resulted in a bug
where arm_sctlr() incorrectly picked the NonSecure SCTLR as the
controlling register when in Secure PL0, which meant we were
spuriously generating alignment faults because we were looking at the
wrong SCTLR control bits.
The use of ARMMMUIdx_EL3 for Secure PL1 also resulted in the bug that
we wouldn't honour the PAN bit for Secure PL1, because there's no
equivalent _PAN mmu index for it.
We could fix this in one of two ways:
* The most straightforward is to add new MMU indexes EL30_0,
EL30_3, EL30_3_PAN to correspond to "Secure PL1&0 at PL0",
"Secure PL1&0 at PL1", and "Secure PL1&0 at PL1 with PAN".
This matches how we use indexes for the AArch64 regimes, and
preserves propirties like being able to determine the privilege
level from an MMU index without any other information. However
it would add two MMU indexes (we can share one with ARMMMUIdx_EL3),
and we are already using 14 of the 16 the core TLB code permits.
* The more complicated approach is the one we take here. We use
the same MMU indexes (E10_0, E10_1, E10_1_PAN) for Secure PL1&0
than we do for NonSecure PL1&0. This saves on MMU indexes, but
means we need to check in some places whether we're in the
Secure PL1&0 regime or not before we interpret an MMU index.
The changes in this commit were created by auditing all the places
where we use specific ARMMMUIdx_ values, and checking whether they
needed to be changed to handle the new index value usage.
Note for potential stable backports: taking also the previous
(comment-change-only) commit might make the backport easier.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2326
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240809160430.1144805-3-peter.maydell@linaro.org
(cherry picked from commit 4c2c0474693229c1f533239bb983495c5427784d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 7c721f22bd..dfd877cd03 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2699,8 +2699,7 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
* + NonSecure PL1 & 0 stage 1
* + NonSecure PL1 & 0 stage 2
* + NonSecure PL2
- * + Secure PL0
- * + Secure PL1
+ * + Secure PL1 & 0
* (reminder: for 32 bit EL3, Secure PL1 is *EL3*, not EL1.)
*
* For QEMU, an mmu_idx is not quite the same as a translation regime because:
@@ -2718,37 +2717,39 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
* The only use of stage 2 translations is either as part of an s1+2
* lookup or when loading the descriptors during a stage 1 page table walk,
* and in both those cases we don't use the TLB.
- * 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
- * translation regimes, because they map reasonably well to each other
- * and they can't both be active at the same time.
- * 5. we want to be able to use the TLB for accesses done as part of a
+ * 4. we want to be able to use the TLB for accesses done as part of a
* stage1 page table walk, rather than having to walk the stage2 page
* table over and over.
- * 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
+ * 5. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
* Never (PAN) bit within PSTATE.
- * 7. we fold together most secure and non-secure regimes for A-profile,
+ * 6. we fold together most secure and non-secure regimes for A-profile,
* because there are no banked system registers for aarch64, so the
* process of switching between secure and non-secure is
* already heavyweight.
- * 8. we cannot fold together Stage 2 Secure and Stage 2 NonSecure,
+ * 7. we cannot fold together Stage 2 Secure and Stage 2 NonSecure,
* because both are in use simultaneously for Secure EL2.
*
* This gives us the following list of cases:
*
- * EL0 EL1&0 stage 1+2 (aka NS PL0)
- * EL1 EL1&0 stage 1+2 (aka NS PL1)
- * EL1 EL1&0 stage 1+2 +PAN
+ * EL0 EL1&0 stage 1+2 (or AArch32 PL0 PL1&0 stage 1+2)
+ * EL1 EL1&0 stage 1+2 (or AArch32 PL1 PL1&0 stage 1+2)
+ * EL1 EL1&0 stage 1+2 +PAN (or AArch32 PL1 PL1&0 stage 1+2 +PAN)
* EL0 EL2&0
* EL2 EL2&0
* EL2 EL2&0 +PAN
* EL2 (aka NS PL2)
- * EL3 (aka S PL1)
+ * EL3 (not used when EL3 is AArch32)
* Stage2 Secure
* Stage2 NonSecure
* plus one TLB per Physical address space: S, NS, Realm, Root
*
* for a total of 14 different mmu_idx.
*
+ * Note that when EL3 is AArch32, the usage is potentially confusing
+ * because the MMU indexes are named for their AArch64 use, so code
+ * using the ARMMMUIdx_E10_1 might be at EL3, not EL1. This is because
+ * Secure PL1 is always at EL3.
+ *
* R profile CPUs have an MPU, but can use the same set of MMU indexes
* as A profile. They only need to distinguish EL0 and EL1 (and
* EL2 for cores like the Cortex-R52).
@@ -3041,6 +3042,10 @@ FIELD(TBFLAG_A32, NS, 10, 1)
* This requires an SME trap from AArch32 mode when using NEON.
*/
FIELD(TBFLAG_A32, SME_TRAP_NONSTREAMING, 11, 1)
+/*
+ * Indicates whether we are in the Secure PL1&0 translation regime
+ */
+FIELD(TBFLAG_A32, S_PL1_0, 12, 1)
/*
* Bit usage when in AArch32 state, for M-profile only.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 42044ae14b..f5cfae3654 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3687,7 +3687,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
*/
format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
- if (arm_feature(env, ARM_FEATURE_EL2)) {
+ if (arm_feature(env, ARM_FEATURE_EL2) && !arm_aa32_secure_pl1_0(env)) {
if (mmu_idx == ARMMMUIdx_E10_0 ||
mmu_idx == ARMMMUIdx_E10_1 ||
mmu_idx == ARMMMUIdx_E10_1_PAN) {
@@ -3761,13 +3761,11 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
case 0:
/* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */
switch (el) {
- case 3:
- mmu_idx = ARMMMUIdx_E3;
- break;
case 2:
g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */
/* fall through */
case 1:
+ case 3:
if (ri->crm == 9 && arm_pan_enabled(env)) {
mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
} else {
@@ -11768,8 +11766,11 @@ void arm_cpu_do_interrupt(CPUState *cs)
uint64_t arm_sctlr(CPUARMState *env, int el)
{
- /* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
- if (el == 0) {
+ if (arm_aa32_secure_pl1_0(env)) {
+ /* In Secure PL1&0 SCTLR_S is always controlling */
+ el = 3;
+ } else if (el == 0) {
+ /* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
el = mmu_idx == ARMMMUIdx_E20_0 ? 2 : 1;
}
@@ -12429,8 +12430,12 @@ int fp_exception_el(CPUARMState *env, int cur_el)
return 0;
}
-/* Return the exception level we're running at if this is our mmu_idx */
-int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
+/*
+ * Return the exception level we're running at if this is our mmu_idx.
+ * s_pl1_0 should be true if this is the AArch32 Secure PL1&0 translation
+ * regime.
+ */
+int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx, bool s_pl1_0)
{
if (mmu_idx & ARM_MMU_IDX_M) {
return mmu_idx & ARM_MMU_IDX_M_PRIV;
@@ -12442,7 +12447,7 @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
return 0;
case ARMMMUIdx_E10_1:
case ARMMMUIdx_E10_1_PAN:
- return 1;
+ return s_pl1_0 ? 3 : 1;
case ARMMMUIdx_E2:
case ARMMMUIdx_E20_2:
case ARMMMUIdx_E20_2_PAN:
@@ -12480,6 +12485,15 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
idx = ARMMMUIdx_E10_0;
}
break;
+ case 3:
+ /*
+ * AArch64 EL3 has its own translation regime; AArch32 EL3
+ * uses the Secure PL1&0 translation regime.
+ */
+ if (arm_el_is_aa64(env, 3)) {
+ return ARMMMUIdx_E3;
+ }
+ /* fall through */
case 1:
if (arm_pan_enabled(env)) {
idx = ARMMMUIdx_E10_1_PAN;
@@ -12499,8 +12513,6 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
idx = ARMMMUIdx_E2;
}
break;
- case 3:
- return ARMMMUIdx_E3;
default:
g_assert_not_reached();
}
diff --git a/target/arm/internals.h b/target/arm/internals.h
index dd3da211a3..810b85a409 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -265,6 +265,20 @@ FIELD(CNTHCTL, CNTPMASK, 19, 1)
#define M_FAKE_FSR_NSC_EXEC 0xf /* NS executing in S&NSC memory */
#define M_FAKE_FSR_SFAULT 0xe /* SecureFault INVTRAN, INVEP or AUVIOL */
+/**
+ * arm_aa32_secure_pl1_0(): Return true if in Secure PL1&0 regime
+ *
+ * Return true if the CPU is in the Secure PL1&0 translation regime.
+ * This requires that EL3 exists and is AArch32 and we are currently
+ * Secure. If this is the case then the ARMMMUIdx_E10* apply and
+ * mean we are in EL3, not EL1.
+ */
+static inline bool arm_aa32_secure_pl1_0(CPUARMState *env)
+{
+ return arm_feature(env, ARM_FEATURE_EL3) &&
+ !arm_el_is_aa64(env, 3) && arm_is_secure(env);
+}
+
/**
* raise_exception: Raise the specified exception.
* Raise a guest exception with the specified value, syndrome register
@@ -791,7 +805,12 @@ static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
return mmu_idx | ARM_MMU_IDX_A;
}
-int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
+/**
+ * Return the exception level we're running at if our current MMU index
+ * is @mmu_idx. @s_pl1_0 should be true if this is the AArch32
+ * Secure PL1&0 translation regime.
+ */
+int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx, bool s_pl1_0);
/* Return the MMU index for a v7M CPU in the specified security state */
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
@@ -886,11 +905,11 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
return 3;
case ARMMMUIdx_E10_0:
case ARMMMUIdx_Stage1_E0:
- return arm_el_is_aa64(env, 3) || !arm_is_secure_below_el3(env) ? 1 : 3;
- case ARMMMUIdx_Stage1_E1:
- case ARMMMUIdx_Stage1_E1_PAN:
case ARMMMUIdx_E10_1:
case ARMMMUIdx_E10_1_PAN:
+ case ARMMMUIdx_Stage1_E1:
+ case ARMMMUIdx_Stage1_E1_PAN:
+ return arm_el_is_aa64(env, 3) || !arm_is_secure_below_el3(env) ? 1 : 3;
case ARMMMUIdx_MPrivNegPri:
case ARMMMUIdx_MUserNegPri:
case ARMMMUIdx_MPriv:
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 31ae43f60e..2cb0e981a5 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -3575,7 +3575,11 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
case ARMMMUIdx_Stage1_E1:
case ARMMMUIdx_Stage1_E1_PAN:
case ARMMMUIdx_E2:
- ss = arm_security_space_below_el3(env);
+ if (arm_aa32_secure_pl1_0(env)) {
+ ss = ARMSS_Secure;
+ } else {
+ ss = arm_security_space_below_el3(env);
+ }
break;
case ARMMMUIdx_Stage2:
/*
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
index f03977b4b0..bab7822ef6 100644
--- a/target/arm/tcg/hflags.c
+++ b/target/arm/tcg/hflags.c
@@ -198,6 +198,10 @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1);
}
+ if (arm_aa32_secure_pl1_0(env)) {
+ DP_TBFLAG_A32(flags, S_PL1_0, 1);
+ }
+
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
}
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 7d620ef109..396ddfefb0 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -14093,7 +14093,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->tbii = EX_TBFLAG_A64(tb_flags, TBII);
dc->tbid = EX_TBFLAG_A64(tb_flags, TBID);
dc->tcma = EX_TBFLAG_A64(tb_flags, TCMA);
- dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
+ dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx, false);
#if !defined(CONFIG_USER_ONLY)
dc->user = (dc->current_el == 0);
#endif
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index dc49a8d806..d4b79c08cb 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -9135,10 +9135,6 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
- dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
-#if !defined(CONFIG_USER_ONLY)
- dc->user = (dc->current_el == 0);
-#endif
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
@@ -9169,7 +9165,12 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
}
dc->sme_trap_nonstreaming =
EX_TBFLAG_A32(tb_flags, SME_TRAP_NONSTREAMING);
+ dc->s_pl1_0 = EX_TBFLAG_A32(tb_flags, S_PL1_0);
}
+ dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx, dc->s_pl1_0);
+#if !defined(CONFIG_USER_ONLY)
+ dc->user = (dc->current_el == 0);
+#endif
dc->lse2 = false; /* applies only to aarch64 */
dc->cp_regs = cpu->cp_regs;
dc->features = env->features;
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index dc66ff2190..f8dd23ec41 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -167,6 +167,8 @@ typedef struct DisasContext {
bool guarded_page;
/* True if the current insn_start has been updated. */
bool insn_start_updated;
+ /* True if this is the AArch32 Secure PL1&0 translation regime */
+ bool s_pl1_0;
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
int c15_cpar;
/* Offset from VNCR_EL2 when FEAT_NV2 redirects this reg to memory */
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 58/69] module: Prevent crash by resetting local_err in module_load_qom_all()
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (56 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 57/69] target/arm: Fix usage of MMU indexes when EL3 is AArch32 Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 59/69] target/hexagon: don't look for static glib Michael Tokarev
` (10 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Alexander Ivanov, Claudio Fontana, Denis V . Lunev,
Paolo Bonzini, Michael Tokarev
From: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
Set local_err to NULL after it has been freed in error_report_err(). This
avoids triggering assert(*errp == NULL) failure in error_setv() when
local_err is reused in the loop.
Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
Reviewed-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Link: https://lore.kernel.org/r/20240809121340.992049-2-alexander.ivanov@virtuozzo.com
[Do the same by moving the declaration instead. - Paolo]
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 940d802b24e63650e0eacad3714e2ce171cba17c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/util/module.c b/util/module.c
index 32e263163c..3eb0f06df1 100644
--- a/util/module.c
+++ b/util/module.c
@@ -354,13 +354,13 @@ int module_load_qom(const char *type, Error **errp)
void module_load_qom_all(void)
{
const QemuModinfo *modinfo;
- Error *local_err = NULL;
if (module_loaded_qom_all) {
return;
}
for (modinfo = module_info; modinfo->name != NULL; modinfo++) {
+ Error *local_err = NULL;
if (!modinfo->objs) {
continue;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 59/69] target/hexagon: don't look for static glib
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (57 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 58/69] module: Prevent crash by resetting local_err in module_load_qom_all() Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 60/69] linux-user: Preserve NULL hit in target_mmap subroutines Michael Tokarev
` (9 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Alyssa Ross, Paolo Bonzini, Michael Tokarev
From: Alyssa Ross <hi@alyssa.is>
When cross compiling QEMU configured with --static, I've been getting
configure errors like the following:
Build-time dependency glib-2.0 found: NO
../target/hexagon/meson.build:303:15: ERROR: Dependency lookup for glib-2.0 with method 'pkgconfig' failed: Could not generate libs for glib-2.0:
Package libpcre2-8 was not found in the pkg-config search path.
Perhaps you should add the directory containing `libpcre2-8.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libpcre2-8', required by 'glib-2.0', not found
This happens because --static sets the prefer_static Meson option, but
my build machine doesn't have a static libpcre2. I don't think it
makes sense to insist that native dependencies are static, just
because I want the non-native QEMU binaries to be static.
Signed-off-by: Alyssa Ross <hi@alyssa.is>
Link: https://lore.kernel.org/r/20240805104921.4035256-1-hi@alyssa.is
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit fe68cc0923ebfa0c12e4176f61ec9b363a07a73a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index fb480afc03..940110c055 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -321,7 +321,7 @@ if idef_parser_enabled and 'hexagon-linux-user' in target_dirs
arguments: ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@']
)
- glib_dep = dependency('glib-2.0', native: true)
+ glib_dep = dependency('glib-2.0', native: true, static: false)
idef_parser = executable(
'idef-parser',
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 60/69] linux-user: Preserve NULL hit in target_mmap subroutines
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (58 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 59/69] target/hexagon: don't look for static glib Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 61/69] target/sparc: Restrict STQF to sparcv9 Michael Tokarev
` (8 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Richard Henderson, Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
Do not pass guest_base to the host mmap instead of zero hint.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2353
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 3aefee3ec01e607529a9918e2978f365c5c3b5e9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index be3b9a68eb..2a11d921ab 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -559,9 +559,13 @@ static abi_long mmap_h_eq_g(abi_ulong start, abi_ulong len,
int host_prot, int flags, int page_flags,
int fd, off_t offset)
{
- void *p, *want_p = g2h_untagged(start);
+ void *p, *want_p = NULL;
abi_ulong last;
+ if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
+ want_p = g2h_untagged(start);
+ }
+
p = mmap(want_p, len, host_prot, flags, fd, offset);
if (p == MAP_FAILED) {
return -1;
@@ -609,11 +613,15 @@ static abi_long mmap_h_lt_g(abi_ulong start, abi_ulong len, int host_prot,
int mmap_flags, int page_flags, int fd,
off_t offset, int host_page_size)
{
- void *p, *want_p = g2h_untagged(start);
+ void *p, *want_p = NULL;
off_t fileend_adj = 0;
int flags = mmap_flags;
abi_ulong last, pass_last;
+ if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
+ want_p = g2h_untagged(start);
+ }
+
if (!(flags & MAP_ANONYMOUS)) {
struct stat sb;
@@ -739,12 +747,16 @@ static abi_long mmap_h_gt_g(abi_ulong start, abi_ulong len,
int flags, int page_flags, int fd,
off_t offset, int host_page_size)
{
- void *p, *want_p = g2h_untagged(start);
+ void *p, *want_p = NULL;
off_t host_offset = offset & -host_page_size;
abi_ulong last, real_start, real_last;
bool misaligned_offset = false;
size_t host_len;
+ if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
+ want_p = g2h_untagged(start);
+ }
+
if (!(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
/*
* Adjust the offset to something representable on the host.
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 61/69] target/sparc: Restrict STQF to sparcv9
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (59 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 60/69] linux-user: Preserve NULL hit in target_mmap subroutines Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 62/69] crypto/tlscredspsk: Free username on finalize Michael Tokarev
` (7 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Richard Henderson, Philippe Mathieu-Daudé,
Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
Prior to sparcv9, the same encoding was STDFQ.
Cc: qemu-stable@nongnu.org
Fixes: 06c060d9e5b ("target/sparc: Move simple fp load/store to decodetree")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240816072311.353234-2-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 12d36294a2d978faf893101862118d1ac1815e85)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index e2d8a07dc4..d2b29de084 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -484,7 +484,7 @@ STF 11 ..... 100100 ..... . ............. @r_r_ri_na
STFSR 11 00000 100101 ..... . ............. @n_r_ri
STXFSR 11 00001 100101 ..... . ............. @n_r_ri
{
- STQF 11 ..... 100110 ..... . ............. @q_r_ri_na
+ STQF 11 ..... 100110 ..... . ............. @q_r_ri_na # v9
STDFQ 11 ----- 100110 ----- - -------------
}
STDF 11 ..... 100111 ..... . ............. @d_r_ri_na
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 99c6f3cc72..9d5d0ae47c 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4151,7 +4151,7 @@ static bool do_st_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp sz)
TRANS(STF, ALL, do_st_fpr, a, MO_32)
TRANS(STDF, ALL, do_st_fpr, a, MO_64)
-TRANS(STQF, ALL, do_st_fpr, a, MO_128)
+TRANS(STQF, 64, do_st_fpr, a, MO_128)
TRANS(STFA, 64, do_st_fpr, a, MO_32)
TRANS(STDFA, 64, do_st_fpr, a, MO_64)
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 62/69] crypto/tlscredspsk: Free username on finalize
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (60 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 61/69] target/sparc: Restrict STQF to sparcv9 Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 63/69] hw/nvme: fix leak of uninitialized memory in io_mgmt_recv Michael Tokarev
` (6 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Peter Maydell, Daniel P . Berrangé,
Philippe Mathieu-Daudé, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
When the creds->username property is set we allocate memory
for it in qcrypto_tls_creds_psk_prop_set_username(), but
we never free this when the QCryptoTLSCredsPSK is destroyed.
Free the memory in finalize.
This fixes a LeakSanitizer complaint in migration-test:
$ (cd build/asan; ASAN_OPTIONS="fast_unwind_on_malloc=0" QTEST_QEMU_BINARY=./qemu-system-x86_64 ./tests/qtest/migration-test --tap -k -p /x86_64/migration/precopy/unix/tls/psk)
=================================================================
==3867512==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 5 byte(s) in 1 object(s) allocated from:
#0 0x5624e5c99dee in malloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/qemu-system-x86_64+0x218edee) (BuildId: a9e623fa1009a9435c0142c037cd7b8c1ad04ce3)
#1 0x7fb199ae9738 in g_malloc debian/build/deb/../../../glib/gmem.c:128:13
#2 0x7fb199afe583 in g_strdup debian/build/deb/../../../glib/gstrfuncs.c:361:17
#3 0x5624e82ea919 in qcrypto_tls_creds_psk_prop_set_username /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../crypto/tlscredspsk.c:255:23
#4 0x5624e812c6b5 in property_set_str /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../qom/object.c:2277:5
#5 0x5624e8125ce5 in object_property_set /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../qom/object.c:1463:5
#6 0x5624e8136e7c in object_set_properties_from_qdict /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../qom/object_interfaces.c:55:14
#7 0x5624e81372d2 in user_creatable_add_type /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../qom/object_interfaces.c:112:5
#8 0x5624e8137964 in user_creatable_add_qapi /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../qom/object_interfaces.c:157:11
#9 0x5624e891ba3c in qmp_object_add /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../qom/qom-qmp-cmds.c:227:5
#10 0x5624e8af9118 in qmp_marshal_object_add /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/qapi/qapi-commands-qom.c:337:5
#11 0x5624e8bd1d49 in do_qmp_dispatch_bh /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../qapi/qmp-dispatch.c:128:5
#12 0x5624e8cb2531 in aio_bh_call /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../util/async.c:171:5
#13 0x5624e8cb340c in aio_bh_poll /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../util/async.c:218:13
#14 0x5624e8c0be98 in aio_dispatch /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../util/aio-posix.c:423:5
#15 0x5624e8cba3ce in aio_ctx_dispatch /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../util/async.c:360:5
#16 0x7fb199ae0d3a in g_main_dispatch debian/build/deb/../../../glib/gmain.c:3419:28
#17 0x7fb199ae0d3a in g_main_context_dispatch debian/build/deb/../../../glib/gmain.c:4137:7
#18 0x5624e8cbe1d9 in glib_pollfds_poll /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../util/main-loop.c:287:9
#19 0x5624e8cbcb13 in os_host_main_loop_wait /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../util/main-loop.c:310:5
#20 0x5624e8cbc6dc in main_loop_wait /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../util/main-loop.c:589:11
#21 0x5624e6f3f917 in qemu_main_loop /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../system/runstate.c:801:9
#22 0x5624e893379c in qemu_default_main /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../system/main.c:37:14
#23 0x5624e89337e7 in main /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../system/main.c:48:12
#24 0x7fb197972d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#25 0x7fb197972e3f in __libc_start_main csu/../csu/libc-start.c:392:3
#26 0x5624e5c16fa4 in _start (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/qemu-system-x86_64+0x210bfa4) (BuildId: a9e623fa1009a9435c0142c037cd7b8c1ad04ce3)
SUMMARY: AddressSanitizer: 5 byte(s) leaked in 1 allocation(s).
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20240819145021.38524-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 87e012f29f2e47dcd8c385ff8bb8188f9e06d4ea)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/crypto/tlscredspsk.c b/crypto/tlscredspsk.c
index 546cad1c5a..0d6b71a37c 100644
--- a/crypto/tlscredspsk.c
+++ b/crypto/tlscredspsk.c
@@ -243,6 +243,7 @@ qcrypto_tls_creds_psk_finalize(Object *obj)
QCryptoTLSCredsPSK *creds = QCRYPTO_TLS_CREDS_PSK(obj);
qcrypto_tls_creds_psk_unload(creds);
+ g_free(creds->username);
}
static void
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 63/69] hw/nvme: fix leak of uninitialized memory in io_mgmt_recv
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (61 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 62/69] crypto/tlscredspsk: Free username on finalize Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 64/69] virtio-pci: Fix the use of an uninitialized irqfd Michael Tokarev
` (5 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Klaus Jensen, Yutaro Shimizu, Michael Tokarev
From: Klaus Jensen <k.jensen@samsung.com>
Yutaro Shimizu from the Cyber Defense Institute discovered a bug in the
NVMe emulation that leaks contents of an uninitialized heap buffer if
subsystem and FDP emulation are enabled.
Cc: qemu-stable@nongnu.org
Reported-by: Yutaro Shimizu <shimizu@cyberdefense.jp>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit 6a22121c4f25b181e99479f65958ecde65da1c92)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 652116085e..659332db0a 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -4302,7 +4302,7 @@ static uint16_t nvme_io_mgmt_recv_ruhs(NvmeCtrl *n, NvmeRequest *req,
nruhsd = ns->fdp.nphs * endgrp->fdp.nrg;
trans_len = sizeof(NvmeRuhStatus) + nruhsd * sizeof(NvmeRuhStatusDescr);
- buf = g_malloc(trans_len);
+ buf = g_malloc0(trans_len);
trans_len = MIN(trans_len, len);
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 64/69] virtio-pci: Fix the use of an uninitialized irqfd
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (62 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 63/69] hw/nvme: fix leak of uninitialized memory in io_mgmt_recv Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 65/69] migration/multifd: Free MultiFDRecvParams::data Michael Tokarev
` (4 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Cindy Lu, Jason Wang, Michael S . Tsirkin,
Michael Tokarev
From: Cindy Lu <lulu@redhat.com>
The crash was reported in MAC OS and NixOS, here is the link for this bug
https://gitlab.com/qemu-project/qemu/-/issues/2334
https://gitlab.com/qemu-project/qemu/-/issues/2321
In this bug, they are using the virtio_input device. The guest notifier was
not supported for this device, The function virtio_pci_set_guest_notifiers()
was not called, and the vector_irqfd was not initialized.
So the fix is adding the check for vector_irqfd in virtio_pci_get_notifier()
The function virtio_pci_get_notifier() can be used in various devices.
It could also be called when VIRTIO_CONFIG_S_DRIVER_OK is not set. In this situation,
the vector_irqfd being NULL is acceptable. We can allow the device continue to boot
If the vector_irqfd still hasn't been initialized after VIRTIO_CONFIG_S_DRIVER_OK
is set, it means that the function set_guest_notifiers was not called before the
driver started. This indicates that the device is not using the notifier.
At this point, we will let the check fail.
This fix is verified in vyatta,MacOS,NixOS,fedora system.
The bt tree for this bug is:
Thread 6 "CPU 0/KVM" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7c817be006c0 (LWP 1269146)]
kvm_virtio_pci_vq_vector_use () at ../qemu-9.0.0/hw/virtio/virtio-pci.c:817
817 if (irqfd->users == 0) {
(gdb) thread apply all bt
...
Thread 6 (Thread 0x7c817be006c0 (LWP 1269146) "CPU 0/KVM"):
0 kvm_virtio_pci_vq_vector_use () at ../qemu-9.0.0/hw/virtio/virtio-pci.c:817
1 kvm_virtio_pci_vector_use_one () at ../qemu-9.0.0/hw/virtio/virtio-pci.c:893
2 0x00005983657045e2 in memory_region_write_accessor () at ../qemu-9.0.0/system/memory.c:497
3 0x0000598365704ba6 in access_with_adjusted_size () at ../qemu-9.0.0/system/memory.c:573
4 0x0000598365705059 in memory_region_dispatch_write () at ../qemu-9.0.0/system/memory.c:1528
5 0x00005983659b8e1f in flatview_write_continue_step.isra.0 () at ../qemu-9.0.0/system/physmem.c:2713
6 0x000059836570ba7d in flatview_write_continue () at ../qemu-9.0.0/system/physmem.c:2743
7 flatview_write () at ../qemu-9.0.0/system/physmem.c:2774
8 0x000059836570bb76 in address_space_write () at ../qemu-9.0.0/system/physmem.c:2894
9 0x0000598365763afe in address_space_rw () at ../qemu-9.0.0/system/physmem.c:2904
10 kvm_cpu_exec () at ../qemu-9.0.0/accel/kvm/kvm-all.c:2917
11 0x000059836576656e in kvm_vcpu_thread_fn () at ../qemu-9.0.0/accel/kvm/kvm-accel-ops.c:50
12 0x0000598365926ca8 in qemu_thread_start () at ../qemu-9.0.0/util/qemu-thread-posix.c:541
13 0x00007c8185bcd1cf in ??? () at /usr/lib/libc.so.6
14 0x00007c8185c4e504 in clone () at /usr/lib/libc.so.6
Fixes: 2ce6cff94d ("virtio-pci: fix use of a released vector")
Cc: qemu-stable@nongnu.org
Signed-off-by: Cindy Lu <lulu@redhat.com>
Message-Id: <20240806093715.65105-1-lulu@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a8e63ff289d137197ad7a701a587cc432872d798)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e04218a9fb..389bab003f 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -860,6 +860,9 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
VirtQueue *vq;
+ if (!proxy->vector_irqfd && vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)
+ return -1;
+
if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
*n = virtio_config_get_guest_notifier(vdev);
*vector = vdev->config_vector;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 65/69] migration/multifd: Free MultiFDRecvParams::data
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (63 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 64/69] virtio-pci: Fix the use of an uninitialized irqfd Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 66/69] linux-user: Handle short reads in mmap_h_gt_g Michael Tokarev
` (3 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Peter Maydell, Fabiano Rosas, Michael Tokarev
From: Peter Maydell <peter.maydell@linaro.org>
In multifd_recv_setup() we allocate (among other things)
* a MultiFDRecvData struct to multifd_recv_state::data
* a MultiFDRecvData struct to each multfd_recv_state->params[i].data
(Then during execution we might swap these pointers around.)
But in multifd_recv_cleanup() we free multifd_recv_state->data
in multifd_recv_cleanup_state() but we don't ever free the
multifd_recv_state->params[i].data. This results in a memory
leak reported by LeakSanitizer:
(cd build/asan && \
ASAN_OPTIONS="fast_unwind_on_malloc=0:strip_path_prefix=/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/../../" \
QTEST_QEMU_BINARY=./qemu-system-x86_64 \
./tests/qtest/migration-test --tap -k -p /x86_64/migration/multifd/file/mapped-ram )
[...]
Direct leak of 72 byte(s) in 3 object(s) allocated from:
#0 0x561cc0afcfd8 in __interceptor_calloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/qemu-system-x86_64+0x218efd8) (BuildId: be72e086d4e47b172b0a72779972213fd9916466)
#1 0x7f89d37acc50 in g_malloc0 debian/build/deb/../../../glib/gmem.c:161:13
#2 0x561cc1e9c83c in multifd_recv_setup migration/multifd.c:1606:19
#3 0x561cc1e68618 in migration_ioc_process_incoming migration/migration.c:972:9
#4 0x561cc1e3ac59 in migration_channel_process_incoming migration/channel.c:45:9
#5 0x561cc1e4fa0b in file_accept_incoming_migration migration/file.c:132:5
#6 0x561cc30f2c0c in qio_channel_fd_source_dispatch io/channel-watch.c:84:12
#7 0x7f89d37a3c43 in g_main_dispatch debian/build/deb/../../../glib/gmain.c:3419:28
#8 0x7f89d37a3c43 in g_main_context_dispatch debian/build/deb/../../../glib/gmain.c:4137:7
#9 0x561cc3b21659 in glib_pollfds_poll util/main-loop.c:287:9
#10 0x561cc3b1ff93 in os_host_main_loop_wait util/main-loop.c:310:5
#11 0x561cc3b1fb5c in main_loop_wait util/main-loop.c:589:11
#12 0x561cc1da2917 in qemu_main_loop system/runstate.c:801:9
#13 0x561cc3796c1c in qemu_default_main system/main.c:37:14
#14 0x561cc3796c67 in main system/main.c:48:12
#15 0x7f89d163bd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#16 0x7f89d163be3f in __libc_start_main csu/../csu/libc-start.c:392:3
#17 0x561cc0a79fa4 in _start (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/qemu-system-x86_64+0x210bfa4) (BuildId: be72e086d4e47b172b0a72779972213fd9916466)
Direct leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x561cc0afcfd8 in __interceptor_calloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/qemu-system-x86_64+0x218efd8) (BuildId: be72e086d4e47b172b0a72779972213fd9916466)
#1 0x7f89d37acc50 in g_malloc0 debian/build/deb/../../../glib/gmem.c:161:13
#2 0x561cc1e9bed9 in multifd_recv_setup migration/multifd.c:1588:32
#3 0x561cc1e68618 in migration_ioc_process_incoming migration/migration.c:972:9
#4 0x561cc1e3ac59 in migration_channel_process_incoming migration/channel.c:45:9
#5 0x561cc1e4fa0b in file_accept_incoming_migration migration/file.c:132:5
#6 0x561cc30f2c0c in qio_channel_fd_source_dispatch io/channel-watch.c:84:12
#7 0x7f89d37a3c43 in g_main_dispatch debian/build/deb/../../../glib/gmain.c:3419:28
#8 0x7f89d37a3c43 in g_main_context_dispatch debian/build/deb/../../../glib/gmain.c:4137:7
#9 0x561cc3b21659 in glib_pollfds_poll util/main-loop.c:287:9
#10 0x561cc3b1ff93 in os_host_main_loop_wait util/main-loop.c:310:5
#11 0x561cc3b1fb5c in main_loop_wait util/main-loop.c:589:11
#12 0x561cc1da2917 in qemu_main_loop system/runstate.c:801:9
#13 0x561cc3796c1c in qemu_default_main system/main.c:37:14
#14 0x561cc3796c67 in main system/main.c:48:12
#15 0x7f89d163bd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#16 0x7f89d163be3f in __libc_start_main csu/../csu/libc-start.c:392:3
#17 0x561cc0a79fa4 in _start (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/asan/qemu-system-x86_64+0x210bfa4) (BuildId: be72e086d4e47b172b0a72779972213fd9916466)
SUMMARY: AddressSanitizer: 96 byte(s) leaked in 4 allocation(s).
Free the params[i].data too.
Cc: qemu-stable@nongnu.org
Fixes: d117ed0699d41 ("migration/multifd: Allow receiving pages without packets")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
(cherry picked from commit 4c107870e8b2ba3951ee0c46123f1c3b5d3a19d3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/migration/multifd.c b/migration/multifd.c
index fa55586f89..ac3742343f 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1351,6 +1351,8 @@ static void multifd_recv_cleanup_channel(MultiFDRecvParams *p)
qemu_mutex_destroy(&p->mutex);
qemu_sem_destroy(&p->sem_sync);
qemu_sem_destroy(&p->sem);
+ g_free(p->data);
+ p->data = NULL;
g_free(p->name);
p->name = NULL;
p->packet_len = 0;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 66/69] linux-user: Handle short reads in mmap_h_gt_g
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (64 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 65/69] migration/multifd: Free MultiFDRecvParams::data Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 67/69] Revert "replay: stop us hanging in rr_wait_io_event" Michael Tokarev
` (2 subsequent siblings)
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Richard Henderson, Philippe Mathieu-Daudé,
Michael Tokarev
From: Richard Henderson <richard.henderson@linaro.org>
In particular, if an image has a large bss, we can hit
EOF before reading all host_len bytes of the mapping.
Create a helper, mmap_pread to handle the job for both
the larger block in mmap_h_gt_g itself, as well as the
smaller block in mmap_frag.
Cc: qemu-stable@nongnu.org
Fixes: eb5027ac618 ("linux-user: Split out mmap_h_gt_g")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2504
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240820050848.165253-2-richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit a4ad4a9d98f7fbde806f07da21e69f39e134cdf1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 2a11d921ab..9e94f36ba2 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -282,6 +282,40 @@ static int do_munmap(void *addr, size_t len)
return munmap(addr, len);
}
+/*
+ * Perform a pread on behalf of target_mmap. We can reach EOF, we can be
+ * interrupted by signals, and in general there's no good error return path.
+ * If @zero, zero the rest of the block at EOF.
+ * Return true on success.
+ */
+static bool mmap_pread(int fd, void *p, size_t len, off_t offset, bool zero)
+{
+ while (1) {
+ ssize_t r = pread(fd, p, len, offset);
+
+ if (likely(r == len)) {
+ /* Complete */
+ return true;
+ }
+ if (r == 0) {
+ /* EOF */
+ if (zero) {
+ memset(p, 0, len);
+ }
+ return true;
+ }
+ if (r > 0) {
+ /* Short read */
+ p += r;
+ len -= r;
+ offset += r;
+ } else if (errno != EINTR) {
+ /* Error */
+ return false;
+ }
+ }
+}
+
/*
* Map an incomplete host page.
*
@@ -356,10 +390,9 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
/* Read or zero the new guest pages. */
if (flags & MAP_ANONYMOUS) {
memset(g2h_untagged(start), 0, last - start + 1);
- } else {
- if (pread(fd, g2h_untagged(start), last - start + 1, offset) == -1) {
- return false;
- }
+ } else if (!mmap_pread(fd, g2h_untagged(start), last - start + 1,
+ offset, true)) {
+ return false;
}
/* Put final protection */
@@ -852,8 +885,7 @@ static abi_long mmap_h_gt_g(abi_ulong start, abi_ulong len,
}
if (misaligned_offset) {
- /* TODO: The read could be short. */
- if (pread(fd, p, host_len, offset + real_start - start) != host_len) {
+ if (!mmap_pread(fd, p, host_len, offset + real_start - start, false)) {
do_munmap(p, host_len);
return -1;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 67/69] Revert "replay: stop us hanging in rr_wait_io_event"
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (65 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 66/69] linux-user: Handle short reads in mmap_h_gt_g Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 68/69] hw/audio/virtio-snd: fix invalid param check Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 69/69] target/hppa: Fix PSW V-bit packaging in cpu_hppa_get for hppa64 Michael Tokarev
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Nicholas Piggin, Alex Bennée, Michael Tokarev
From: Nicholas Piggin <npiggin@gmail.com>
This reverts commit 1f881ea4a444ef36a8b6907b0b82be4b3af253a2.
That commit causes reverse_debugging.py test failures, and does
not seem to solve the root cause of the problem x86-64 still
hangs in record/replay tests.
The problem with short-cutting the iowait that was taken during
record phase is that related events will not get consumed at the
same points (e.g., reading the clock).
A hang with zero icount always seems to be a symptom of an earlier
problem that has caused the recording to become out of synch with
the execution and consumption of events by replay.
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20240813050638.446172-6-npiggin@gmail.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20240813202329.1237572-14-alex.bennee@linaro.org>
(cherry picked from commit 94962ff00d09674047aed896e87ba09736cd6941)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2524
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
index 894e73e52c..a942442a33 100644
--- a/accel/tcg/tcg-accel-ops-rr.c
+++ b/accel/tcg/tcg-accel-ops-rr.c
@@ -109,7 +109,7 @@ static void rr_wait_io_event(void)
{
CPUState *cpu;
- while (all_cpu_threads_idle() && replay_can_wait()) {
+ while (all_cpu_threads_idle()) {
rr_stop_kick_timer();
qemu_cond_wait_bql(first_cpu->halt_cond);
}
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index f229b2109c..8102fa54f0 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -73,11 +73,6 @@ int replay_get_instructions(void);
/*! Updates instructions counter in replay mode. */
void replay_account_executed_instructions(void);
-/**
- * replay_can_wait: check if we should pause for wait-io
- */
-bool replay_can_wait(void);
-
/* Processing clocks and other time sources */
/*! Save the specified clock */
diff --git a/replay/replay.c b/replay/replay.c
index a2c576c16e..325e275756 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -449,27 +449,6 @@ void replay_start(void)
replay_enable_events();
}
-/*
- * For none/record the answer is yes.
- */
-bool replay_can_wait(void)
-{
- if (replay_mode == REPLAY_MODE_PLAY) {
- /*
- * For playback we shouldn't ever be at a point we wait. If
- * the instruction count has reached zero and we have an
- * unconsumed event we should go around again and consume it.
- */
- if (replay_state.instruction_count == 0 && replay_state.has_unread_data) {
- return false;
- } else {
- replay_sync_error("Playback shouldn't have to iowait");
- }
- }
- return true;
-}
-
-
void replay_finish(void)
{
if (replay_mode == REPLAY_MODE_NONE) {
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 68/69] hw/audio/virtio-snd: fix invalid param check
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (66 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 67/69] Revert "replay: stop us hanging in rr_wait_io_event" Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 69/69] target/hppa: Fix PSW V-bit packaging in cpu_hppa_get for hppa64 Michael Tokarev
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Volker Rümelin, Manos Pitsidianakis,
Michael S . Tsirkin, Michael Tokarev
From: Volker Rümelin <vr_qemu@t-online.de>
Commit 9b6083465f ("virtio-snd: check for invalid param shift
operands") tries to prevent invalid parameters specified by the
guest. However, the code is not correct.
Change the code so that the parameters format and rate, which are
a bit numbers, are compared with the bit size of the data type.
Fixes: 9b6083465f ("virtio-snd: check for invalid param shift operands")
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20240802071805.7123-1-vr_qemu@t-online.de>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 7d14471a121878602cb4e748c4707f9ab9a9e3e2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 2b80072b04..95f55a02f1 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -282,12 +282,12 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
error_report("Number of channels is not supported.");
return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
}
- if (BIT(params->format) > sizeof(supported_formats) ||
+ if (params->format >= sizeof(supported_formats) * BITS_PER_BYTE ||
!(supported_formats & BIT(params->format))) {
error_report("Stream format is not supported.");
return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
}
- if (BIT(params->rate) > sizeof(supported_rates) ||
+ if (params->rate >= sizeof(supported_rates) * BITS_PER_BYTE ||
!(supported_rates & BIT(params->rate))) {
error_report("Stream rate is not supported.");
return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [Stable-9.0.3 69/69] target/hppa: Fix PSW V-bit packaging in cpu_hppa_get for hppa64
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
` (67 preceding siblings ...)
2024-09-06 11:13 ` [Stable-9.0.3 68/69] hw/audio/virtio-snd: fix invalid param check Michael Tokarev
@ 2024-09-06 11:13 ` Michael Tokarev
68 siblings, 0 replies; 70+ messages in thread
From: Michael Tokarev @ 2024-09-06 11:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-stable, Helge Deller, Guenter Roeck, Richard Henderson,
Michael Tokarev
From: Helge Deller <deller@gmx.de>
While adding hppa64 support, the psw_v variable got extended from 32 to 64
bits. So, when packaging the PSW-V bit from the psw_v variable for interrupt
processing, check bit 31 instead the 63th (sign) bit.
This fixes a hard to find Linux kernel boot issue where the loss of the PSW-V
bit due to an ITLB interruption in the middle of a series of ds/addc
instructions (from the divU milicode library) generated the wrong division
result and thus triggered a Linux kernel crash.
Link: https://lore.kernel.org/lkml/718b8afe-222f-4b3a-96d3-93af0e4ceff1@roeck-us.net/
Reported-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Helge Deller <deller@gmx.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Fixes: 931adff31478 ("target/hppa: Update cpu_hppa_get/put_psw for hppa64")
Cc: qemu-stable@nongnu.org # v8.2+
(cherry picked from commit ead5078cf1a5f11d16e3e8462154c859620bcc7e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fixup in target/hppa/helper.c due to lack of
v9.0.0-688-gebc9401a4067 "target/hppa: Split PSW X and B into their own field")
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a072d0bb63..9c42431d72 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -188,7 +188,7 @@ typedef struct CPUArchState {
target_ulong psw; /* All psw bits except the following: */
target_ulong psw_n; /* boolean */
- target_long psw_v; /* in most significant bit */
+ target_long psw_v; /* in bit 31 */
/* Splitting the carry-borrow field into the MSB and "the rest", allows
* for "the rest" to be deleted when it is unused, but the MSB is in use.
diff --git a/target/hppa/helper.c b/target/hppa/helper.c
index 9d217d051c..6c14994921 100644
--- a/target/hppa/helper.c
+++ b/target/hppa/helper.c
@@ -53,7 +53,7 @@ target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
}
psw |= env->psw_n * PSW_N;
- psw |= (env->psw_v < 0) * PSW_V;
+ psw |= ((env->psw_v >> 31) & 1) * PSW_V;
psw |= env->psw;
return psw;
--
2.39.2
^ permalink raw reply related [flat|nested] 70+ messages in thread
end of thread, other threads:[~2024-09-06 11:28 UTC | newest]
Thread overview: 70+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-06 11:12 [Stable-9.0.3 00/69] Patch Round-up for stable 9.0.3, freeze on 2024-09-16 Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 01/69] hw/scsi/lsi53c895a: bump instruction limit in scripts processing to fix regression Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 02/69] scsi: fix regression and honor bootindex again for legacy drives Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 03/69] qapi/qom: Document feature unstable of @x-vfio-user-server Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 04/69] target/arm: Fix handling of LDAPR/STLR with negative offset Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 05/69] target/arm: LDAPR should honour SCTLR_ELx.nAA Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 06/69] target/arm: Use float_status copy in sme_fmopa_s Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 07/69] target/arm: Use FPST_F16 for SME FMOPA (widening) Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 08/69] hvf: arm: Do not advance PC when raising an exception Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 09/69] hw/nvme: fix memory leak in nvme_dsm Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 10/69] hw/cxl/cxl-host: Fix segmentation fault when getting cxl-fmw property Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 11/69] virtio-snd: add max size bounds check in input cb Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 12/69] virtio-snd: check for invalid param shift operands Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 13/69] intel_iommu: fix FRCD construction macro Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 14/69] target/i386: do not crash if microvm guest uses SGX CPUID leaves Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 15/69] chardev/char-win-stdio.c: restore old console mode Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 16/69] hw/intc/loongson_ipi: Access memory in little endian Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 17/69] hw/intc/loongson_ipi: Fix resource leak Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 18/69] target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 19/69] util/async.c: Forbid negative min/max in aio_context_set_thread_pool_params() Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 20/69] Revert "qemu-char: do not operate on sources from finalize callbacks" Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 21/69] hw/virtio: Fix the de-initialization of vhost-user devices Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 22/69] target/rx: Use target_ulong for address in LI Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 23/69] hw/char/bcm2835_aux: Fix assert when receive FIFO fills up Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 24/69] hw/misc/bcm2835_property: Fix handling of FRAMEBUFFER_SET_PALETTE Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 25/69] target/arm: Don't assert for 128-bit tile accesses when SVL is 128 Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 26/69] target/arm: Fix UMOPA/UMOPS of 16-bit values Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 27/69] target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl() Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 28/69] target/arm: Ignore SMCR_EL2.LEN and SVCR_EL2.LEN if EL2 is not enabled Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 29/69] docs/sphinx/depfile.py: Handle env.doc2path() returning a Path not a str Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 30/69] hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb() Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 31/69] hw/arm/mps2-tz.c: fix RX/TX interrupts order Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 32/69] target/arm: Handle denormals correctly for FMOPA (widening) Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 33/69] virtio-net: Ensure queue index fits with RSS Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 34/69] virtio-net: Fix network stall at the host side waiting for kick Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 35/69] net: Reinstate '-net nic, model=help' output as documented in man page Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 36/69] migration/multifd: Fix multifd_send_setup cleanup when channel creation fails Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 37/69] linux-user/elfload: Fix pr_pid values in core files Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 38/69] target/i386: Fix VSIB decode Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 39/69] tcg/ppc: Sync tcg_out_test and constraints Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 40/69] hw/sd/sdhci: Reset @data_count index on invalid ADMA transfers Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 41/69] vvfat: Fix bug in writing to middle of file Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 42/69] vvfat: Fix usage of `info.file.offset` Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 43/69] vvfat: Fix wrong checks for cluster mappings invariant Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 44/69] vvfat: Fix reading files with non-continuous clusters Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 45/69] iotests: Add `vvfat` tests Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 46/69] nbd/server: Plumb in new args to nbd_client_add() Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 47/69] nbd/server: CVE-2024-7409: Cap default max-connections to 100 Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 48/69] nbd/server: CVE-2024-7409: Drop non-negotiating clients Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 49/69] nbd/server: CVE-2024-7409: Close stray clients at server-stop Michael Tokarev
2024-09-06 11:12 ` [Stable-9.0.3 50/69] nbd/server: CVE-2024-7409: Avoid use-after-free when closing server Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 51/69] net: Fix '-net nic, model=' for non-help arguments Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 52/69] hw/core/ptimer: fix timer zero period condition for freq > 1GHz Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 53/69] block/blkio: use FUA flag on write zeroes only if supported Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 54/69] target/i386: Do not apply REX to MMX operands Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 55/69] target/arm: Clear high SVE elements in handle_vec_simd_wshli Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 56/69] target/arm: Update translation regime comment for new features Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 57/69] target/arm: Fix usage of MMU indexes when EL3 is AArch32 Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 58/69] module: Prevent crash by resetting local_err in module_load_qom_all() Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 59/69] target/hexagon: don't look for static glib Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 60/69] linux-user: Preserve NULL hit in target_mmap subroutines Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 61/69] target/sparc: Restrict STQF to sparcv9 Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 62/69] crypto/tlscredspsk: Free username on finalize Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 63/69] hw/nvme: fix leak of uninitialized memory in io_mgmt_recv Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 64/69] virtio-pci: Fix the use of an uninitialized irqfd Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 65/69] migration/multifd: Free MultiFDRecvParams::data Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 66/69] linux-user: Handle short reads in mmap_h_gt_g Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 67/69] Revert "replay: stop us hanging in rr_wait_io_event" Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 68/69] hw/audio/virtio-snd: fix invalid param check Michael Tokarev
2024-09-06 11:13 ` [Stable-9.0.3 69/69] target/hppa: Fix PSW V-bit packaging in cpu_hppa_get for hppa64 Michael Tokarev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).