Compare commits

...
204 Commits
Author SHA1 Message Date
Michael Tokarev 46300ebc38 Update version for 8.2.6 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-16 08:41:13 +03:00
Vincent Fu 57d9378af9 hw/nvme: fix number of PIDs for FDP RUH update
The number of PIDs is in the upper 16 bits of cdw10. So we need to
right-shift by 16 bits instead of only a single bit.

Fixes: 73064edfb8 ("hw/nvme: flexible data placement emulation")
Cc: qemu-stable@nongnu.org
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit 3936bbdf9a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-12 21:50:41 +03:00
Markus Armbruster 55b151b6a6 sphinx/qapidoc: Fix to generate doc for explicit, unboxed arguments
When a command's arguments are specified as an explicit type T,
generated documentation points to the members of T.

Example:

    ##
    # @announce-self:
    #
    # Trigger generation of broadcast RARP frames to update network
    [...]
    ##
    { 'command': 'announce-self', 'boxed': true,
      'data' : 'AnnounceParameters'}

generates

    "announce-self" (Command)
    -------------------------

    Trigger generation of broadcast RARP frames to update network
    [...]

    Arguments
    ~~~~~~~~~

    The members of "AnnounceParameters"

Except when the command takes its arguments unboxed , i.e. it doesn't
have 'boxed': true, we generate *nothing*.  A few commands have a
reference in their doc comment to compensate, but most don't.

Example:

    ##
    # @blockdev-snapshot-sync:
    #
    # Takes a synchronous snapshot of a block device.
    #
    # For the arguments, see the documentation of BlockdevSnapshotSync.
    [...]
    ##
    { 'command': 'blockdev-snapshot-sync',
      'data': 'BlockdevSnapshotSync',
      'allow-preconfig': true }

generates

    "blockdev-snapshot-sync" (Command)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Takes a synchronous snapshot of a block device.

    For the arguments, see the documentation of BlockdevSnapshotSync.
    [...]

Same for event data.

Fix qapidoc.py to generate the reference regardless of boxing.  Delete
now redundant references in the doc comments.

Fixes: 4078ee5469 (docs/sphinx: Add new qapi-doc Sphinx extension)
Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20240628112756.794237-1-armbru@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
(cherry picked from commit e389929d19)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fixups in qapi/block-core.json due to missing
 v8.2.0-1951-g2746f060be18 "qapi: Move error documentation to new "Errors" sections"
 v8.2.0-1952-g53d5c36d8de3 "qapi: Delete useless "Returns" sections")
2024-07-08 22:55:53 +03:00
Maxim Mikityanskiy 8f7bb1266f char-stdio: Restore blocking mode of stdout on exit
qemu_chr_open_fd() sets stdout into non-blocking mode. Restore the old
fd flags on exit to avoid breaking unsuspecting applications that run on
the same terminal after qemu and don't expect to get EAGAIN.

While at at, also ensure term_exit is called once (at the moment it's
called both from char_stdio_finalize() and as the atexit() hook.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2423
Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
Link: https://lore.kernel.org/r/20240703190812.3459514-1-maxtram95@gmail.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a0124e333e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-05 15:04:16 +03:00
Stefano Garzarella b932f9fbd4 virtio: remove virtio_tswap16s() call in vring_packed_event_read()
Commit d152cdd6f6 ("virtio: use virtio accessor to access packed event")
switched using of address_space_read_cached() to virito_lduw_phys_cached()
to access packed descriptor event.

When we used address_space_read_cached(), we needed to call
virtio_tswap16s() to handle the endianess of the field, but
virito_lduw_phys_cached() already handles it internally, so we no longer
need to call virtio_tswap16s() (as the commit had done for `off_wrap`,
but forgot for `flags`).

Fixes: d152cdd6f6 ("virtio: use virtio accessor to access packed event")
Cc: jasowang@redhat.com
Cc: qemu-stable@nongnu.org
Reported-by: Xoykie <xoykie@gmail.com>
Link: https://lore.kernel.org/qemu-devel/CAFU8RB_pjr77zMLsM0Unf9xPNxfr_--Tjr49F_eX32ZBc5o2zQ@mail.gmail.com
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Message-Id: <20240701075208.19634-1-sgarzare@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 7aa6492401)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-05 00:13:20 +03:00
Cindy Lu 0d2c267638 virtio-pci: Fix the failure process in kvm_virtio_pci_vector_use_one()
In function kvm_virtio_pci_vector_use_one(), the function will only use
the irqfd/vector for itself. Therefore, in the undo label, the failing
process is incorrect.
To fix this, we can just remove this label.

Fixes: f9a09ca3ea ("vhost: add support for configure interrupt")
Cc: qemu-stable@nongnu.org
Signed-off-by: Cindy Lu <lulu@redhat.com>
Message-Id: <20240528084840.194538-1-lulu@redhat.com>
Reviewed-by: Peter Maydell <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 a113d041e8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-05 00:13:01 +03:00
Kevin Wolf aea89f4179 block: Parse filenames only when explicitly requested
When handling image filenames from legacy options such as -drive or from
tools, these filenames are parsed for protocol prefixes, including for
the json:{} pseudo-protocol.

This behaviour is intended for filenames that come directly from the
command line and for backing files, which may come from the image file
itself. Higher level management tools generally take care to verify that
untrusted images don't contain a bad (or any) backing file reference;
'qemu-img info' is a suitable tool for this.

However, for other files that can be referenced in images, such as
qcow2 data files or VMDK extents, the string from the image file is
usually not verified by management tools - and 'qemu-img info' wouldn't
be suitable because in contrast to backing files, it already opens these
other referenced files. So here the string should be interpreted as a
literal local filename. More complex configurations need to be specified
explicitly on the command line or in QMP.

This patch changes bdrv_open_inherit() so that it only parses filenames
if a new parameter parse_filename is true. It is set for the top level
in bdrv_open(), for the file child and for the backing file child. All
other callers pass false and disable filename parsing this way.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit 7ead946998)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: backport patch to 8.2, without:
  v8.2.0-132-g6bc30f194985 "graph-lock: remove AioContext locking"
  v8.2.0-133-gb49f4755c7fa "block: remove AioContext locking")
2024-07-03 23:48:39 +03:00
Kevin Wolf 46fdbe667d iotests/270: Don't store data-file with json: prefix in image
We want to disable filename parsing for data files because it's too easy
to abuse in malicious image files. Make the test ready for the change by
passing the data file explicitly in command line options.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit 7e1110664e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-03 23:03:02 +03:00
Kevin Wolf 6a2774e8ae iotests/244: Don't store data-file with protocol in image
We want to disable filename parsing for data files because it's too easy
to abuse in malicious image files. Make the test ready for the change by
passing the data file explicitly in command line options.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit 2eb42a728d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-03 23:03:02 +03:00
Kevin Wolf d7e7f342c6 qcow2: Don't open data_file with BDRV_O_NO_IO
One use case for 'qemu-img info' is verifying that untrusted images
don't reference an unwanted external file, be it as a backing file or an
external data file. To make sure that calling 'qemu-img info' can't
already have undesired side effects with a malicious image, just don't
open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do
I/O, we don't need to have it open.

This changes the output of iotests case 061, which used 'qemu-img info'
to show that opening an image with an invalid data file fails. After
this patch, it succeeds. Replace this part of the test with a qemu-io
call, but keep the final 'qemu-img info' to show that the invalid data
file is correctly displayed in the output.

Fixes: CVE-2024-4467
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit bd385a5298)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-03 23:03:02 +03:00
Richard Henderson 38fb9d1edc target/arm: Fix FJCVTZS vs flush-to-zero
Input denormals cause the Javascript inexact bit
(output to Z) to be set.

Cc: qemu-stable@nongnu.org
Fixes: 6c1f6f2733 ("target/arm: Implement ARMv8.3-JSConv")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2375
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240625183536.1672454-4-richard.henderson@linaro.org
[PMM: fixed hardcoded tab in test case]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 7619129f0d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-02 09:49:20 +03:00
Richard Henderson 8c56d9f61a target/arm: Fix VCMLA Dd, Dn, Dm[idx]
The inner loop, bounded by eltspersegment, must not be
larger than the outer loop, bounded by elements.

Cc: qemu-stable@nongnu.org
Fixes: 18fc240578 ("target/arm: Implement SVE fp complex multiply add (indexed)")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2376
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240625183536.1672454-2-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 76bccf3cb9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-07-02 09:03:21 +03:00
Chuang Xu 40e04161b3 i386/cpu: fixup number of addressable IDs for processor cores in the physical package
When QEMU is started with:
-cpu host,host-cache-info=on,l3-cache=off \
-smp 2,sockets=1,dies=1,cores=1,threads=2
Guest can't acquire maximum number of addressable IDs for processor cores in
the physical package from CPUID[04H].

When creating a CPU topology of 1 core per package, host-cache-info only
uses the Host's addressable core IDs field (CPUID.04H.EAX[bits 31-26]),
resulting in a conflict (on the multicore Host) between the Guest core
topology information in this field and the Guest's actual cores number.

Fix it by removing the unnecessary condition to cover 1 core per package
case. This is safe because cores_per_pkg will not be 0 and will be at
least 1.

Fixes: d7caf13b5f ("x86: cpu: fixup number of addressable IDs for logical processors sharing cache")
Signed-off-by: Guixiong Wei <weiguixiong@bytedance.com>
Signed-off-by: Yipeng Yin <yinyipeng@bytedance.com>
Signed-off-by: Chuang Xu <xuchuangxclwt@bytedance.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Message-ID: <20240611032314.64076-1-xuchuangxclwt@bytedance.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 903916f0a0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: fixup for 8.2 due to other changes in this area past 9.0)
2024-07-01 09:49:12 +03:00
Thomas Huth df0e72dc86 tests: Update our CI to use CentOS Stream 9 instead of 8
RHEL 9 (and thus also the derivatives) have been available since two
years now, so according to QEMU's support policy, we can drop the active
support for the previous major version 8 now.

Another reason for doing this is that Centos Stream 8 will go EOL soon:

https://blog.centos.org/2023/04/end-dates-are-coming-for-centos-stream-8-and-centos-linux-7/

  "After May 31, 2024, CentOS Stream 8 will be archived
   and no further updates will be provided."

Thus upgrade our CentOS Stream container to major version 9 now.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20240418101056.302103-5-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 641b1efe01)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-30 15:27:33 +03:00
Fabiano Rosas 5d9f2461b4 migration: Fix file migration with fdset
When the "file:" migration support was added we missed the special
case in the qemu_open_old implementation that allows for a particular
file name format to be used to refer to a set of file descriptors that
have been previously provided to QEMU via the add-fd QMP command.

When using this fdset feature, we should not truncate the migration
file because being given an fd means that the management layer is in
control of the file and will likely already have some data written to
it. This is further indicated by the presence of the 'offset'
argument, which indicates the start of the region where QEMU is
allowed to write.

Fix the issue by replacing the O_TRUNC flag on open by an ftruncate
call, which will take the offset into consideration.

Fixes: 385f510df5 ("migration: file URI offset")
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
(cherry picked from commit 6d3279655a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fixup in migration/file.c due to missing
 v8.2.0-1958-gb7b03eb614d0 "migration/multifd: Add outgoing QIOChannelFile support")
2024-06-30 15:04:18 +03:00
Richard Henderson 1229d60714 tcg/loongarch64: Fix tcg_out_movi vs some pcrel pointers
Simplify the logic for two-part, 32-bit pc-relative addresses.
Rather than assume all such fit in int32_t, do some arithmetic
and assert a result, do some arithmetic first and then check
to see if the pieces are in range.

Cc: qemu-stable@nongnu.org
Fixes: dacc51720d ("tcg/loongarch64: Implement tcg_out_mov and tcg_out_movi")
Reviewed-by: Song Gao <gaosong@loongson.cn>
Reported-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 521d7fb3eb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-20 15:23:05 +03:00
Clément Chigot f4564fc8d2 target/sparc: use signed denominator in sdiv helper
The result has to be done with the signed denominator (b32) instead of
the unsigned value passed in argument (b).

Cc: qemu-stable@nongnu.org
Fixes: 1326010322 ("target/sparc: Remove CC_OP_DIV")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2319
Signed-off-by: Clément Chigot <chigot@adacore.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240606144331.698361-1-chigot@adacore.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 6b4965373e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-20 15:22:44 +03:00
Ilya Leoshkevich 1649e9559b linux-user: Make TARGET_NR_setgroups affect only the current thread
Like TARGET_NR_setuid, TARGET_NR_setgroups should affect only the
calling thread, and not the entire process. Therefore, implement it
using a syscall, and not a libc call.

Cc: qemu-stable@nongnu.org
Fixes: 19b84f3c35 ("added setgroups and getgroups syscalls")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240614154710.1078766-1-iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 54b2792102)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-20 15:22:26 +03:00
Anton Johansson 40682cfcea accel/tcg: Fix typo causing tb->page_addr[1] to not be recorded
For TBs crossing page boundaries, the 2nd page will never be
recorded/removed, as the index of the 2nd page is computed from the
address of the 1st page. This is due to a typo, fix it.

Cc: qemu-stable@nongnu.org
Fixes: deba78709a ("accel/tcg: Always lock pages before translation")
Signed-off-by: Anton Johansson <anjo@rev.ng>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20240612133031.15298-1-anjo@rev.ng>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 3b279f73fa)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-20 15:22:00 +03:00
Gerd Hoffmann d08c1fd6db stdvga: fix screen blanking
In case the display surface uses a shared buffer (i.e. uses vga vram
directly instead of a shadow) go unshare the buffer before clearing it.

This avoids vga memory corruption, which in turn fixes unblanking not
working properly with X11.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2067
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20240605131444.797896-2-kraxel@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit b1cf266c82)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-20 10:04:36 +03:00
Philippe Mathieu-Daudé 1798f38242 hw/audio/virtio-snd: Always use little endian audio format
The VIRTIO Sound Device conforms with the Virtio spec v1.2,
thus only use little endianness.

Remove the suspicious target_words_bigendian() noticed during
code review.

Cc: qemu-stable@nongnu.org
Fixes: eb9ad377bb ("virtio-sound: handle control messages and streams")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240422211830.25606-1-philmd@linaro.org>
(cherry picked from commit a276ec8e26)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-20 10:03:40 +03:00
Dongwon Kim fdbeeb454c ui/gtk: Draw guest frame at refresh cycle
Draw routine needs to be manually invoked in the next refresh
if there is a scanout blob from the guest. This is to prevent
a situation where there is a scheduled draw event but it won't
happen bacause the window is currently in inactive state
(minimized or tabified). If draw is not done for a long time,
gl_block timeout and/or fence timeout (on the guest) will happen
eventually.

v2: Use gd_gl_area_draw(vc) in gtk-gl-area.c

Suggested-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20240426225059.3871283-1-dongwon.kim@intel.com>
(cherry picked from commit 77bf310084)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-11 10:12:47 +03:00
Alexey Dobriyan fa275f2211 virtio-net: drop too short packets early
Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
creates small packet (1 segment, len = 10 == n->guest_hdr_len),
then destroys queue.

"if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
zero length/zero segment packet as there is nothing after guest header.

qemu_sendv_packet_async() tries to send it.

slirp discards it because it is smaller than Ethernet header,
but returns 0 because tx hooks are supposed to return total length of data.

0 is propagated upwards and is interpreted as "packet has been sent"
which is terrible because queue is being destroyed, nobody is waiting for TX
to complete and assert it triggered.

Fix is discard such empty packets instead of sending them.

Length 1 packets will go via different codepath:

	virtqueue_push(q->tx_vq, elem, 0);
	virtio_notify(vdev, q->tx_vq);
	g_free(elem);

and aren't problematic.

Signed-off-by: Alexey Dobriyan <adobriyan@yandex-team.ru>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 2c3e4e2de6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-11 10:09:45 +03:00
Mark Cave-Ayland 3e09472893 target/i386: fix size of EBP writeback in gen_enter()
The calculation of FrameTemp is done using the size indicated by mo_pushpop()
before being written back to EBP, but the final writeback to EBP is done using
the size indicated by mo_stacksize().

In the case where mo_pushpop() is MO_32 and mo_stacksize() is MO_16 then the
final writeback to EBP is done using MO_16 which can leave junk in the top
16-bits of EBP after executing ENTER.

Change the writeback of EBP to use the same size indicated by mo_pushpop() to
ensure that the full value is written back.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2198
Message-ID: <20240606095319.229650-5-mark.cave-ayland@ilande.co.uk>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3973615e7f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-11 10:02:19 +03:00
Michael Tokarev 909772f0a5 Update version for 8.2.5 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-09 00:24:07 +03:00
lanyanzhi 6feae1d0dd target/loongarch: fix a wrong print in cpu dump
description:
    loongarch_cpu_dump_state() want to dump all loongarch cpu
state registers, but there is a tiny typographical error when
printing "PRCFG2".

Cc: qemu-stable@nongnu.org
Signed-off-by: lanyanzhi <lanyanzhi22b@ict.ac.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Message-Id: <20240604073831.666690-1-lanyanzhi22b@ict.ac.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
(cherry picked from commit 78f932ea1f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-07 08:10:45 +03:00
Bernhard Beschow af008b379c ui/sdl2: Allow host to power down screen
By default, SDL disables the screen saver which prevents the host from powering
down the screen even if the screen is locked. This results in draining the
battery needlessly when the host isn't connected to a wall charger. Fix that by
enabling the screen saver.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20240512095945.1879-1-shentey@gmail.com>
(cherry picked from commit 2e701e6785)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-06 14:20:10 +03:00
Xinyu Li 276ec925a7 target/i386: fix SSE and SSE2 feature check
Features check of CPUID_SSE and CPUID_SSE2 should use cpuid_features,
rather than cpuid_ext_features.

Signed-off-by: Xinyu Li <lixinyu20s@ict.ac.cn>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Message-ID: <20240602100904.2137939-1-lixinyu20s@ict.ac.cn>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit da7c95920d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-06 14:17:00 +03:00
Paolo Bonzini d84afebcee target/i386: fix xsave.flat from kvm-unit-tests
xsave.flat checks that "executing the XSETBV instruction causes a general-
protection fault (#GP) if ECX = 0 and EAX[2:1] has the value 10b".  QEMU allows
that option, so the test fails.  Add the condition.

Cc: qemu-stable@nongnu.org
Fixes: 892544317f ("target/i386: implement XSAVE and XRSTOR of AVX registers", 2022-10-18)
Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7604bbc2d8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-06 14:14:19 +03:00
Alistair Francis 2891807479 disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
CSRs are part of the disassembly.

Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Fixes: ea10325917 ("RISC-V Disassembler")
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 915758c537)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:07:40 +03:00
Yong-Xuan Wang ae5edeb084 target/riscv/kvm.c: Fix the hart bit setting of AIA
In AIA spec, each hart (or each hart within a group) has a unique hart
number to locate the memory pages of interrupt files in the address
space. The number of bits required to represent any hart number is equal
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
groups.

However, if the largest hart number among groups is a power of 2, QEMU
will pass an inaccurate hart-index-bit setting to Linux. For example, when
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
to represent 4 harts, but we passes 3 to Linux. The code needs to be
updated to ensure accurate hart-index-bit settings.

Additionally, a Linux patch[1] is necessary to correctly recover the hart
index when the guest OS has only 1 hart, where the hart-index-bit is 0.

[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 190b867f28)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:06:26 +03:00
Alistair Francis 935be461eb target/riscv: rvzicbo: Fixup CBO extension register calculation
When running the instruction

```
    cbo.flush 0(x0)
```

QEMU would segfault.

The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
allocated.

In order to fix this let's use the existing get_address()
helper. This also has the benefit of performing pointer mask
calculations on the address specified in rs1.

The pointer masking specificiation specifically states:

"""
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
"""

So this is the correct behaviour and we previously have been incorrectly
not masking the address.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
Fixes: e05da09b7c ("target/riscv: implement Zicbom extension")
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit c5eb8d6336)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:06:15 +03:00
Alexei Filippov 37d6c6e495 target/riscv: do not set mtval2 for non guest-page faults
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
translation part, mtval2 will be set in case of successes 2 stage translation but
failed pmp check.

In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
page-fault is taken into M-mode, mtval2 is written with either zero or guest
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
is set to zero...*

Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 6c9a344247)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:05:48 +03:00
Daniel Henrique Barboza 6da92af4f9 target/riscv: prioritize pmp errors in raise_mmu_exception()
raise_mmu_exception(), as is today, is prioritizing guest page faults by
checking first if virt_enabled && !first_stage, and then considering the
regular inst/load/store faults.

There's no mention in the spec about guest page fault being a higher
priority that PMP faults. In fact, privileged spec section 3.7.1 says:

"Attempting to fetch an instruction from a PMP region that does not have
execute permissions raises an instruction access-fault exception.
Attempting to execute a load or load-reserved instruction which accesses
a physical address within a PMP region without read permissions raises a
load access-fault exception. Attempting to execute a store,
store-conditional, or AMO instruction which accesses a physical address
within a PMP region without write permissions raises a store
access-fault exception."

So, in fact, we're doing it wrong - PMP faults should always be thrown,
regardless of also being a first or second stage fault.

The way riscv_cpu_tlb_fill() and get_physical_address() work is
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
reflected in the 'pmp_violation' flag. What we need is to change
raise_mmu_exception() to prioritize it.

Reported-by: Joseph Chan <jchan@ventanamicro.com>
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 68e7c86927)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:05:38 +03:00
Max Chou 0f9578497c target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
If the checking functions check both the single and double width
operators at the same time, then the single width operator checking
functions (require_rvf[min]) will check whether the SEW is 8.

Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 93cb52b7a3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:05:10 +03:00
Max Chou c4173e4caf target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
The opfv_narrow_check needs to check the single width float operator by
require_rvf.

Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 692f33a3ab)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:05:02 +03:00
Max Chou d813f356ad target/riscv: rvv: Check single width operator for vector fp widen instructions
The require_scale_rvf function only checks the double width operator for
the vector floating point widen instructions, so most of the widen
checking functions need to add require_rvf for single width operator.

The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
integer to double width float, so the opfxv_widen_check function doesn’t
need require_rvf for the single width operator(integer).

Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 7a999d4dd7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:04:55 +03:00
Max Chou 749907f857 target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
instructions will be affected by Zvfhmin extension.
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
conversions of

* From 1*SEW(16/32) to 2*SEW(32/64)
* From 2*SEW(32/64) to 1*SEW(16/32)

Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 17b713c080)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:04:38 +03:00
Yangyu Chen 4cba687b86 target/riscv/cpu.c: fix Zvkb extension config
This code has a typo that writes zvkb to zvkg, causing users can't
enable zvkb through the config. This patch gets this fixed.

Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Fixes: ea61ef7097 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Max Chou <max.chou@sifive.com>
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit ff33b7a969)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:04:18 +03:00
Huang Tao ec182b1045 target/riscv: Fix the element agnostic function problem
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
agnostic policy.

However, this function can't deal the big endian situation. This patch fixes
the problem by adding handling of such case.

Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 75115d880c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:03:41 +03:00
Daniel Henrique Barboza cf7143fdb7 target/riscv/kvm: tolerate KVM disable ext errors
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
enabled, will fail with a kernel oops SIGILL right at the start. The
reason is that we can't expose zkr without implementing the SEED CSR.
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
allow it we'll error out and never boot.

In hindsight this is too strict. If we keep proceeding, despite not
disabling the extension in the KVM vcpu, we'll not add the extension in
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
it's ok to keep booting in this case.

Change our current logic to not error out if we fail to disable an
extension in kvm_set_one_reg(), but show a warning and keep booting. It
is important to throw a warning because we must make the user aware that
the extension is still available in the vcpu, meaning that an
ill-behaved guest can ignore the riscv,isa settings and  use the
extension.

The case we're handling happens with an EINVAL error code. If we fail to
disable the extension in KVM for any other reason, error out.

We'll also keep erroring out when we fail to enable an extension in KVM,
since adding the extension in riscv,isa at this point will cause a guest
malfunction because the extension isn't enabled in the vcpu.

Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 1215d45b2a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:02:52 +03:00
yang.zhang cd1228a80e hw/intc/riscv_aplic: APLICs should add child earlier than realize
Since only root APLICs can have hw IRQ lines, aplic->parent should
be initialized first.

Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit c76b121840)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 13:00:16 +03:00
Eric Blake b9b2f3bbab iotests: test NBD+TLS+iothread
Prevent regressions when using NBD with TLS in the presence of
iothreads, adding coverage the fix to qio channels made in the
previous patch.

The shell function pick_unused_port() was copied from
nbdkit.git/tests/functions.sh.in, where it had all authors from Red
Hat, agreeing to the resulting relicensing from 2-clause BSD to GPLv2.

CC: qemu-stable@nongnu.org
CC: "Richard W.M. Jones" <rjones@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240531180639.1392905-6-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit a73c993780)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 12:59:47 +03:00
Eric Blake 9a6143a73e qio: Inherit follow_coroutine_ctx across TLS
Since qemu 8.2, the combination of NBD + TLS + iothread crashes on an
assertion failure:

qemu-kvm: ../io/channel.c:534: void qio_channel_restart_read(void *): Assertion `qemu_get_current_aio_context() == qemu_coroutine_get_aio_context(co)' failed.

It turns out that when we removed AioContext locking, we did so by
having NBD tell its qio channels that it wanted to opt in to
qio_channel_set_follow_coroutine_ctx(); but while we opted in on the
main channel, we did not opt in on the TLS wrapper channel.
qemu-iotests has coverage of NBD+iothread and NBD+TLS, but apparently
no coverage of NBD+TLS+iothread, or we would have noticed this
regression sooner.  (I'll add that in the next patch)

But while we could manually opt in to the TLS channel in nbd/server.c
(a one-line change), it is more generic if all qio channels that wrap
other channels inherit the follow status, in the same way that they
inherit feature bits.

CC: Stefan Hajnoczi <stefanha@redhat.com>
CC: Daniel P. Berrangé <berrange@redhat.com>
CC: qemu-stable@nongnu.org
Fixes: https://issues.redhat.com/browse/RHEL-34786
Fixes: 06e0f098 ("io: follow coroutine AioContext in qio_channel_yield()", v8.2.0)
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20240518025246.791593-5-eblake@redhat.com>
(cherry picked from commit 199e84de1c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-05 12:58:16 +03:00
Marcin Juszkiewicz 71c7036b18 target/arm: Disable SVE extensions when SVE is disabled
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2304
Reported-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
Message-id: 20240526204551.553282-1-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 daf9748ac0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-06-01 07:20:15 +03:00
Andrey Shumilin 3f470980b4 hw/intc/arm_gic: Fix handling of NS view of GICC_APR<n>
In gic_cpu_read() and gic_cpu_write(), we delegate the handling of
reading and writing the Non-Secure view of the GICC_APR<n> registers
to functions gic_apr_ns_view() and gic_apr_write_ns_view().
Unfortunately we got the order of the arguments wrong, swapping the
CPU number and the register number (which the compiler doesn't catch
because they're both integers).

Most guests probably didn't notice this bug because directly
accessing the APR registers is typically something only done by
firmware when it is doing state save for going into a sleep mode.

Correct the mismatched call arguments.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Cc: qemu-stable@nongnu.org
Fixes: 51fd06e0ee ("hw/intc/arm_gic: Fix handling of GICC_APR<n>, GICC_NSAPR<n> registers")
Signed-off-by: Andrey Shumilin <shum.sdl@nppct.ru>
[PMM: Rewrote commit message]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée<alex.bennee@linaro.org>
(cherry picked from commit daafa78b29)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-30 17:13:29 +03:00
Zenghui Yu 0970313b05 hvf: arm: Fix encodings for ID_AA64PFR1_EL1 and debug System registers
We wrongly encoded ID_AA64PFR1_EL1 using {3,0,0,4,2} in hvf_sreg_match[] so
we fail to get the expected ARMCPRegInfo from cp_regs hash table with the
wrong key.

Fix it with the correct encoding {3,0,0,4,1}. With that fixed, the Linux
guest can properly detect FEAT_SSBS2 on my M1 HW.

All DBG{B,W}{V,C}R_EL1 registers are also wrongly encoded with op0 == 14.
It happens to work because HVF_SYSREG(CRn, CRm, 14, op1, op2) equals to
HVF_SYSREG(CRn, CRm, 2, op1, op2), by definition. But we shouldn't rely on
it.

Cc: qemu-stable@nongnu.org
Fixes: a1477da3dd ("hvf: Add Apple Silicon support")
Signed-off-by: Zenghui Yu <zenghui.yu@linux.dev>
Reviewed-by: Alexander Graf <agraf@csgraf.de>
Message-id: 20240503153453.54389-1-zenghui.yu@linux.dev
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 19ed42e8ad)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-30 17:11:56 +03:00
Daniel P. Berrangé 8965709b86 gitlab: use 'setarch -R' to workaround tsan bug
The TSAN job started failing when gitlab rolled out their latest
release. The root cause is a change in the Google COS version used
on shared runners. This brings a kernel running with

 vm.mmap_rnd_bits = 31

which is incompatible with TSAN in LLVM < 18, which only supports
upto '28'. LLVM 18 can support upto '30', and failing that will
re-exec itself to turn off VA randomization.

Our LLVM is too old for now, but we can run with 'setarch -R make ..'
to turn off VA randomization ourselves.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20240513111551.488088-4-berrange@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit b563959b90)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 22:05:10 +03:00
Daniel P. Berrangé 3b36dd0005 gitlab: use $MAKE instead of 'make'
The lcitool generated containers have '$MAKE' set to the path
of the right 'make' binary. Using the env variable makes it
possible to override the choice per job.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240513111551.488088-3-berrange@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit c53f7a1078)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 22:05:10 +03:00
Daniel P. Berrangé fc88204b82 dockerfiles: add 'MAKE' env variable to remaining containers
All the lcitool generated containers define a "MAKE" env. It will be
convenient for later patches if all containers do this.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240513111551.488088-2-berrange@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit bad7a2759c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 22:05:10 +03:00
Richard Henderson ca0799624e gitlab: Update msys2-64bit runner tags
Gitlab has deprecated and removed support for windows-1809
and shared-windows.  Update to saas-windows-medium-amd64 per

https://about.gitlab.com/blog/2024/01/22/windows-2022-support-for-gitlab-saas-runners/

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20240507175356.281618-1-richard.henderson@linaro.org>
(cherry picked from commit 36fa7c686e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 14:27:37 +03:00
Paolo Bonzini 52031d6be5 target/i386: no single-step exception after MOV or POP SS
Intel SDM 18.3.1.4 "If an occurrence of the MOV or POP instruction
loads the SS register executes with EFLAGS.TF = 1, no single-step debug
exception occurs following the MOV or POP instruction."

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f0f0136abb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 14:27:37 +03:00
Paolo Bonzini c6171d524d target/i386: disable jmp_opt if EFLAGS.RF is 1
If EFLAGS.RF is 1, special processing in gen_eob_worker() is needed and
therefore goto_tb cannot be used.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 8225bff7c5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 14:27:37 +03:00
Jiaxun Yang 93fa768d40 hw/loongarch/virt: Fix FDT memory node address width
Higher bits for memory nodes were omitted at qemu_fdt_setprop_cells.

Cc: qemu-stable@nongnu.org
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Message-Id: <20240520-loongarch-fdt-memnode-v1-1-5ea9be93911e@flygoat.com>
Signed-off-by: Song Gao <gaosong@loongson.cn>
(cherry picked from commit 6204af704a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:49:58 +03:00
Song Gao d679c82488 hw/loongarch: Fix fdt memory node wrong 'reg'
The right fdt memory node like [1], not [2]

  [1]
        memory@0 {
                device_type = "memory";
                reg = <0x00 0x00 0x00 0x10000000>;
        };
  [2]
        memory@0 {
                device_type = "memory";
                reg = <0x02 0x00 0x02 0x10000000>;
        };

Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-Id: <20240426091551.2397867-10-gaosong@loongson.cn>
(cherry picked from commit b11f981452)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:49:58 +03:00
Fiona Ebner e3a2aa9542 hw/core/machine: move compatibility flags for VirtIO-net USO to machine 8.1
Migration from an 8.2 or 9.0 binary to an 8.1 binary with machine
version 8.1 can fail with:

> kvm: Features 0x1c0010130afffa7 unsupported. Allowed features: 0x10179bfffe7
> kvm: Failed to load virtio-net:virtio
> kvm: error while loading state for instance 0x0 of device '0000:00:12.0/virtio-net'
> kvm: load of migration failed: Operation not permitted

The series

53da8b5a99 virtio-net: Add support for USO features
9da1684954 virtio-net: Add USO flags to vhost support.
f03e0cf63b tap: Add check for USO features
2ab0ec3121 tap: Add USO support to tap device.

only landed in QEMU 8.2, so the compatibility flags should be part of
machine version 8.1.

Moving the flags unfortunately breaks forward migration with machine
version 8.1 from a binary without this patch to a binary with this
patch.

Fixes: 53da8b5a99 ("virtio-net: Add support for USO features")
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
(cherry picked from commit 9710401276)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
donsheng 9b98ab7d3d target-i386: hyper-v: Correct kvm_hv_handle_exit return value
This bug fix addresses the incorrect return value of kvm_hv_handle_exit for
KVM_EXIT_HYPERV_SYNIC, which should be EXCP_INTERRUPT.

Handling of KVM_EXIT_HYPERV_SYNIC in QEMU needs to be synchronous.
This means that async_synic_update should run in the current QEMU vCPU
thread before returning to KVM, returning EXCP_INTERRUPT to guarantee this.
Returning 0 can cause async_synic_update to run asynchronously.

One problem (kvm-unit-tests's hyperv_synic test fails with timeout error)
caused by this bug:

When a guest VM writes to the HV_X64_MSR_SCONTROL MSR to enable Hyper-V SynIC,
a VM exit is triggered and processed by the kvm_hv_handle_exit function of the
QEMU vCPU. This function then calls the async_synic_update function to set
synic->sctl_enabled to true. A true value of synic->sctl_enabled is required
before creating SINT routes using the hyperv_sint_route_new() function.

If kvm_hv_handle_exit returns 0 for KVM_EXIT_HYPERV_SYNIC, the current QEMU
vCPU thread may return to KVM and enter the guest VM before running
async_synic_update. In such case, the hyperv_synic test’s subsequent call to
synic_ctl(HV_TEST_DEV_SINT_ROUTE_CREATE, ...) immediately after writing to
HV_X64_MSR_SCONTROL can cause QEMU’s hyperv_sint_route_new() function to return
prematurely (because synic->sctl_enabled is false).

If the SINT route is not created successfully, the SINT interrupt will not be
fired, resulting in a timeout error in the hyperv_synic test.

Fixes: 267e071bd6 (“hyperv: make overlay pages for SynIC”)
Suggested-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Dongsheng Zhang <dongsheng.x.zhang@intel.com>
Message-ID: <20240521200114.11588-1-dongsheng.x.zhang@intel.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 84d4b72854)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
Richard Henderson 90e023f2bc tcg/loongarch64: Fill out tcg_out_{ld,st} for vector regs
TCG register spill/fill uses tcg_out_ld/st with all types,
not necessarily going through INDEX_op_{ld,st}_vec.

Cc: qemu-stable@nongnu.org
Fixes: 16288ded94 ("tcg/loongarch64: Lower basic tcg vec ops to LSX")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2336
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Tested-by: Song Gao <gaosong@loongson.cn>
(cherry picked from commit c9290dfebf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
Dongwon Kim 355527b646 ui/gtk: Check if fence_fd is equal to or greater than 0
'fence_fd' needs to be validated always before being referenced
And the passing condition should include '== 0' as 0 is a valid
value for the file descriptor.

Suggested-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
Cc: Daniel P. Berrangé <berrange@redhat.com>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Message-Id: <20240508175403.3399895-2-dongwon.kim@intel.com>
(cherry picked from commit e4e62514e3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
hikalium f44d2398d8 ui/gtk: Fix mouse/motion event scaling issue with GTK display backend
Remove gtk_widget_get_scale_factor() usage from the calculation of
the motion events in the GTK backend to make it work correctly on
environments that have `gtk_widget_get_scale_factor() != 1`.

This scale factor usage had been introduced in the commit f14aab420c and
at that time the window size was used for calculating the things and it
was working correctly. However, in the commit 2f31663ed4 the logic
switched to use the widget size instead of window size and because of
the change the usage of scale factor becomes invalid (since widgets use
`vc->gfx.scale_{x, y}` for scaling).

Tested on Crostini on ChromeOS (15823.51.0) with an external display.

Fixes: 2f31663ed4 ("ui/gtk: use widget size for cursor motion event")
Fixes: f14aab420c ("ui: fix incorrect pointer position on highdpi with
gtk")

Signed-off-by: hikalium <hikalium@hikalium.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20240512111435.30121-3-hikalium@hikalium.com>
(cherry picked from commit 37e9141501)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
Thomas Huth 05bfa963df configure: Fix error message when C compiler is not working
If you try to run the configure script on a system without a working
C compiler, you get a very misleading error message:

 ERROR: Unrecognized host OS (uname -s reports 'Linux')

Some people already opened bug tickets because of this problem:

 https://gitlab.com/qemu-project/qemu/-/issues/2057
 https://gitlab.com/qemu-project/qemu/-/issues/2288

We should rather tell the user that we were not able to use the C
compiler instead, otherwise they will have a hard time to figure
out what was going wrong.

While we're at it, let's also suppress the "unrecognized host CPU"
message in this case since it is rather misleading than helpful.

Fixes: 264b803721 ("configure: remove compiler sanity check")
Message-ID: <20240513114010.51608-1-thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 371d60dfdb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
Paolo Bonzini 19a931f207 configure: quote -D options that are passed through to meson
Ensure that they go through unmodified, instead of removing one layer
of quoting.

-D is a pretty specialized option and most options that can have spaces
do not need it (for example, c_args is covered by --extra-cflags).
Therefore it's unlikely that this causes actual trouble.  However,
a somewhat realistic failure case would be with -Dpkg_config_path
and a pkg-config directory that contains spaces.

Cc: qemu-stable@nongnu.org
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 23b1f53c2c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
Paolo Bonzini 2b95625643 target/i386: fix feature dependency for WAITPKG
The VMX feature bit depends on general availability of WAITPKG,
not the other way round.

Fixes: 33cc88261c ("target/i386: add support for VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE", 2023-08-28)
Cc: qemu-stable@nongnu.org
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit fe01af5d47)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
Paolo Bonzini 1cc3cb96b8 target/i386: rdpkru/wrpkru are no-prefix instructions
Reject 0x66/0xf3/0xf2 in front of them.

Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 40a3ec7b5f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-27 07:32:40 +03:00
Paolo Bonzini eb761b4ee5 target/i386: fix operand size for DATA16 REX.W POPCNT
According to the manual, 32-bit vs 64-bit is governed by REX.W
and REX ignores the 0x66 prefix.  This can be confirmed with this
program:

    #include <stdio.h>
    int main()
    {
       int x = 0x12340000;
       int y;
       asm("popcntl %1, %0" : "=r" (y) : "r" (x)); printf("%x\n", y);
       asm("mov $-1, %0; .byte 0x66; popcntl %1, %0" : "+r" (y) : "r" (x)); printf("%x\n", y);
       asm("mov $-1, %0; .byte 0x66; popcntq %q1, %q0" : "+r" (y) : "r" (x)); printf("%x\n", y);
    }

which prints 5/ffff0000/5 on real hardware and 5/ffff0000/ffff0000
on QEMU.

Cc: qemu-stable@nongnu.org
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 41c685dc59)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: drop removal of mo_64_32() helper function in target/i386/tcg/translate.c
 due to missing-in-8.2 v9.0.0-542-gaef4f4affde2
 "target/i386: remove now-converted opcodes from old decoder"
 which removed other user of it)
2024-05-27 07:32:26 +03:00
Mattias Nissler 7d7b770bde hw/remote/vfio-user: Fix config space access byte order
PCI config space is little-endian, so on a big-endian host we need to
perform byte swaps for values as they are passed to and received from
the generic PCI config space access machinery.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jagannathan Raman <jag.raman@oracle.com>
Signed-off-by: Mattias Nissler <mnissler@rivosinc.com>
Message-ID: <20240507094210.300566-6-mnissler@rivosinc.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit e6578f1f68)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-13 09:03:37 +03:00
Song Gao 7dbebba4a5 hw/loongarch/virt: Fix memory leak
The char pointer 'ramName' point to a block of memory,
but never free it. Use 'g_autofree' to automatically free it.

Resolves: Coverity CID 1544773

Fixes: 0cf1478d6 ("hw/loongarch: Add numa support")
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240507022239.3113987-1-gaosong@loongson.cn>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 54c52ec719)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fixup in hw/loongarch/virt.c due to missing-in-8.2
      v9.0.0-266-gd771ca1c10 "hw/loongarch: Move boot functions to boot.c")
2024-05-13 09:03:37 +03:00
Richard Henderson 819f92ec3e target/sparc: Fix FMUL8x16
This instruction has f32 as source1, which alters the
decoding of the register number, which means we've been
passing the wrong data for odd register numbers.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240502165528.244004-4-richard.henderson@linaro.org>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
(cherry picked from commit 9157dccc7e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-13 09:03:37 +03:00
Richard Henderson d3da3d02a0 target/sparc: Fix FEXPAND
This is a 2-operand instruction, not 3-operand.
Worse, we took the source from the wrong operand.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240502165528.244004-3-richard.henderson@linaro.org>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
(cherry picked from commit 7b616f36de)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-13 09:03:37 +03:00
Ruihan Li 50ed4f856a target/i386: Give IRQs a chance when resetting HF_INHIBIT_IRQ_MASK
When emulated with QEMU, interrupts will never come in the following
loop. However, if the NOP instruction is uncommented, interrupts will
fire as normal.

	loop:
		cli
    		call do_sti
		jmp loop

	do_sti:
		sti
		# nop
		ret

This behavior is different from that of a real processor. For example,
if KVM is enabled, interrupts will always fire regardless of whether the
NOP instruction is commented or not. Also, the Intel Software Developer
Manual states that after the STI instruction is executed, the interrupt
inhibit should end as soon as the next instruction (e.g., the RET
instruction if the NOP instruction is commented) is executed.

This problem is caused because the previous code may choose not to end
the TB even if the HF_INHIBIT_IRQ_MASK has just been reset (e.g., in the
case where the STI instruction is immediately followed by the RET
instruction), so that IRQs may not have a change to trigger. This commit
fixes the problem by always terminating the current TB to give IRQs a
chance to trigger when HF_INHIBIT_IRQ_MASK is reset.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Ruihan Li <lrh2000@pku.edu.cn>
Message-ID: <20240415064518.4951-4-lrh2000@pku.edu.cn>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 6a5a63f74b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-13 09:03:37 +03:00
Michael Tokarev 1332b8dd43 Update version for 8.2.4 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-13 08:29:15 +03:00
Philippe Mathieu-Daudé 07d46408cb target/sh4: Fix SUBV opcode
The documentation says:

  SUBV Rm, Rn        Rn - Rm -> Rn, underflow -> T

The overflow / underflow can be calculated as:

  T = ((Rn ^ Rm) & (Result ^ Rn)) >> 31

However we were using the incorrect:

  T = ((Rn ^ Rm) & (Result ^ Rm)) >> 31

Fix by using the Rn register instead of Rm.

Add tests provided by Paul Cercueil.

Cc: qemu-stable@nongnu.org
Fixes: ad8d25a11f ("target-sh4: implement addv and subv using TCG")
Reported-by: Paul Cercueil <paul@crapouillou.net>
Suggested-by: Paul Cercueil <paul@crapouillou.net>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2318
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Message-Id: <20240430163125.77430-3-philmd@linaro.org>
(cherry picked from commit e88a856efd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-04 09:37:20 +03:00
Philippe Mathieu-Daudé dc5390a0ca target/sh4: Fix ADDV opcode
The documentation says:

  ADDV Rm, Rn        Rn + Rm -> Rn, overflow -> T

But QEMU implementation was:

  ADDV Rm, Rn        Rn + Rm -> Rm, overflow -> T

Fix by filling the correct Rm register.

Add tests provided by Paul Cercueil.

Cc: qemu-stable@nongnu.org
Fixes: ad8d25a11f ("target-sh4: implement addv and subv using TCG")
Reported-by: Paul Cercueil <paul@crapouillou.net>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2317
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Message-Id: <20240430163125.77430-2-philmd@linaro.org>
(cherry picked from commit c365e6b070)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-04 09:37:20 +03:00
Philippe Mathieu-Daudé 7b4804c965 hw/arm/npcm7xx: Store derivative OTP fuse key in little endian
Use little endian for derivative OTP fuse key.

Cc: qemu-stable@nongnu.org
Fixes: c752bb079b ("hw/nvram: NPCM7xx OTP device model")
Suggested-by: Avi Fishman <Avi.Fishman@nuvoton.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240422125813.1403-1-philmd@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit eb656a60fd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-02 13:17:18 +03:00
Alexandra Diupina dfcbb9ef24 hw/dmax/xlnx_dpdma: fix handling of address_extension descriptor fields
The DMA descriptor structures for this device have
a set of "address extension" fields which extend the 32
bit source addresses with an extra 16 bits to give a
48 bit address:
 https://docs.amd.com/r/en-US/ug1085-zynq-ultrascale-trm/ADDR_EXT-Field

However, we misimplemented this address extension in several ways:
 * we only extracted 12 bits of the extension fields, not 16
 * we didn't shift the extension field up far enough
 * we accidentally did the shift as 32-bit arithmetic, which
   meant that we would have an overflow instead of setting
   bits [47:32] of the resulting 64-bit address

Add a type cast and use extract64() instead of extract32()
to avoid integer overflow on addition. Fix bit fields
extraction according to documentation.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Cc: qemu-stable@nongnu.org
Fixes: d3c6369a96 ("introduce xlnx-dpdma")
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
Message-id: 20240428181131.23801-1-adiupina@astralinux.ru
[PMM: adjusted commit message]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 4b00855f0e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-02 13:16:29 +03:00
Jeuk Kim d5cf8bed29 hw/ufs: Fix buffer overflow bug
It fixes the buffer overflow vulnerability in the ufs device.
The bug was detected by sanitizers.

You can reproduce it by:

cat << EOF |\
qemu-system-x86_64 \
-display none -machine accel=qtest -m 512M -M q35 -nodefaults -drive \
file=null-co://,if=none,id=disk0 -device ufs,id=ufs_bus -device \
ufs-lu,drive=disk0,bus=ufs_bus -qtest stdio
outl 0xcf8 0x80000810
outl 0xcfc 0xe0000000
outl 0xcf8 0x80000804
outw 0xcfc 0x06
write 0xe0000058 0x1 0xa7
write 0xa 0x1 0x50
EOF

Resolves: #2299
Fixes: 329f166244 ("hw/ufs: Support for Query Transfer Requests")
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
Signed-off-by: Jeuk Kim <jeuk20.kim@samsung.com>
(cherry picked from commit f2c8aeb1af)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-02 13:03:01 +03:00
Thomas Huth 5479d911bc .gitlab-ci.d/cirrus.yml: Shorten the runtime of the macOS and FreeBSD jobs
Cirrus-CI introduced limitations to the free CI minutes. To avoid that
we are consuming them too fast, let's drop the usual targets that are
not that important since they are either a subset of another target
(like i386 or ppc being a subset of x86_64 or ppc64 respectively), or
since there is still a similar target with the opposite endianness
(like xtensa/xtensael, microblaze/microblazeel etc.).

Message-ID: <20240429100113.53357-1-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit a88a04906b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-01 11:10:41 +03:00
Peter Maydell 5b5655fdb7 tests/avocado: update sunxi kernel from armbian to 6.6.16
The Linux kernel 5.10.16 binary for sunxi has been removed from
apt.armbian.com. This means that the avocado tests for these machines
will be skipped (status CANCEL) if the old binary isn't present in
the avocado cache.

Update to 6.6.16, in the same way we did in commit e384db41d8
when we moved to 5.10.16 in 2021.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2284
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
Message-id: 20240415151845.1564201-1-peter.maydell@linaro.org
(cherry picked from commit dcc5c018c7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-05-01 09:01:23 +03:00
Michael Tokarev 7e5f59326d target/loongarch/cpu.c: typo fix: expection
Fixes: 1590154ee4 ("target/loongarch: Fix qemu-system-loongarch64 assert failed with the option '-d int'")
Fixes: ef9b43bb8e (in stable-8.2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 0cbb322f70)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-30 20:11:36 +03:00
Li Zhijian f6abce29cc backends/cryptodev-builtin: Fix local_error leaks
It seems that this error does not need to be propagated to the upper,
directly output the error to avoid the leaks

Closes: https://gitlab.com/qemu-project/qemu/-/issues/2283
Fixes: 2fda101de0 ("virtio-crypto: Support asynchronous mode")
Signed-off-by: Li Zhijian <lizhijian@fujitsu.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: zhenwei pi <pizhenwei@bytedance.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 06479dbf3d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-30 20:10:14 +03:00
Eric Blake 37751067b1 nbd/server: Mark negotiation functions as coroutine_fn
nbd_negotiate() is already marked coroutine_fn.  And given the fix in
the previous patch to have nbd_negotiate_handle_starttls not create
and wait on a g_main_loop (as that would violate coroutine
constraints), it is worth marking the rest of the related static
functions reachable only during option negotiation as also being
coroutine_fn.

Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240408160214.1200629-6-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
[eblake: drop one spurious coroutine_fn marking]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 4fa333e08d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-28 15:43:45 +03:00
Zhu Yangyang cb4c222add nbd/server: do not poll within a coroutine context
Coroutines are not supposed to block. Instead, they should yield.

The client performs TLS upgrade outside of an AIOContext, during
synchronous handshake; this still requires g_main_loop.  But the
server responds to TLS upgrade inside a coroutine, so a nested
g_main_loop is wrong.  Since the two callbacks no longer share more
than the setting of data.complete and data.error, it's just as easy to
use static helpers instead of trying to share a common code path.  It
is also possible to add assertions that no other code is interfering
with the eventual path to qio reaching the callback, whether or not it
required a yield or main loop.

Fixes: f95910f ("nbd: implement TLS support in the protocol negotiation")
Signed-off-by: Zhu Yangyang <zhuyangyang14@huawei.com>
[eblake: move callbacks to their use point, add assertions]
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240408160214.1200629-5-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
(cherry picked from commit ae6d91a7e9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-28 15:43:45 +03:00
Michael Tokarev 6fee9efc2e linux-user: do_setsockopt: fix SOL_ALG.ALG_SET_KEY
This setsockopt accepts zero-lengh optlen (current qemu implementation
does not allow this).  Also, there's no need to make a copy of the key,
it is enough to use lock_user() (which accepts zero length already).

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2197
Fixes: f31dddd2fc "linux-user: Add support for setsockopt() option SOL_ALG"
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-Id: <20240331100737.2724186-2-mjt@tls.msk.ru>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 04f6fb897a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-28 15:43:45 +03:00
Li Zhijian 55b88e61ed migration/colo: Fix bdrv_graph_rdlock_main_loop: Assertion `!qemu_in_coroutine()' failed.
bdrv_activate_all() should not be called from the coroutine context, move
it to the QEMU thread colo_process_incoming_thread() with the bql_lock
protected.

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

Cc: qemu-stable@nongnu.org
Cc: Fabiano Rosas <farosas@suse.de>
Closes: https://gitlab.com/qemu-project/qemu/-/issues/2277
Fixes: 2b3912f135 ("block: Mark bdrv_first_blk() and bdrv_is_root_node() GRAPH_RDLOCK")
Signed-off-by: Li Zhijian <lizhijian@fujitsu.com>
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
Tested-by: Zhang Chen <chen.zhang@intel.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20240417025634.1014582-1-lizhijian@fujitsu.com
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 2cc637f1ea)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: fixup bql_lock() => qemu_mutex_lock_iothread() for v8.2.0-444-g195801d700c0
 "system/cpus: rename qemu_mutex_lock_iothread() to bql_lock()")
2024-04-28 15:42:40 +03:00
Daniel Henrique Barboza cbae108098 target/riscv/kvm: change timer regs size to u64
KVM_REG_RISCV_TIMER regs are always u64 according to the KVM API, but at
this moment we'll return u32 regs if we're running a RISCV32 target.

Use the kvm_riscv_reg_id_u64() helper in RISCV_TIMER_REG() to fix it.

Reported-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231208183835.2411523-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 10f86d1b84)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-27 20:03:22 +03:00
Daniel Henrique Barboza 125b95d79e target/riscv/kvm: change KVM_REG_RISCV_FP_D to u64
KVM_REG_RISCV_FP_D regs are always u64 size. Using kvm_riscv_reg_id() in
RISCV_FP_D_REG() ends up encoding the wrong size if we're running with
TARGET_RISCV32.

Create a new helper that returns a KVM ID with u64 size and use it with
RISCV_FP_D_REG().

Reported-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231208183835.2411523-3-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 450bd6618f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-27 20:03:22 +03:00
Daniel Henrique Barboza bbdcc89678 target/riscv/kvm: change KVM_REG_RISCV_FP_F to u32
KVM_REG_RISCV_FP_F regs have u32 size according to the API, but by using
kvm_riscv_reg_id() in RISCV_FP_F_REG() we're returning u64 sizes when
running with TARGET_RISCV64. The most likely reason why no one noticed
this is because we're not implementing kvm_cpu_synchronize_state() in
RISC-V yet.

Create a new helper that returns a KVM ID with u32 size and use it in
RISCV_FP_F_REG().

Reported-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231208183835.2411523-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 49c211ffca)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-27 20:03:22 +03:00
Michael Tokarev 8216663a5c Update version for 8.2.3 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-24 06:03:52 +03:00
Harsh Prateek Bora 51da750063 ppc/spapr: Initialize max_cpus limit to SPAPR_IRQ_NR_IPIS.
Initialize the machine specific max_cpus limit as per the maximum range
of CPU IPIs available. Keeping between 4096 to 8192 will throw IRQ not
free error due to XIVE/XICS limitation and keeping beyond 8192 will hit
assert in tcg_region_init or spapr_xive_claim_irq.

Logs:

Without patch fix:

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

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

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

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

Reported-by: Kowshik Jois <kowsjois@linux.ibm.com>
Tested-by: Kowshik Jois <kowsjois@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
(cherry picked from commit c4f91d7b7b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-16 21:15:05 +03:00
Harsh Prateek Bora c513ee1b91 ppc/spapr: Introduce SPAPR_IRQ_NR_IPIS to refer IRQ range for CPU IPIs.
spapr_irq_init currently uses existing macro SPAPR_XIRQ_BASE to refer to
the range of CPU IPIs during initialization of nr-irqs property.
It is more appropriate to have its own define which can be further
reused as appropriate for correct interpretation.

Suggested-by: Cedric Le Goater <clg@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Tested-by: Kowshik Jois <kowsjois@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
(cherry picked from commit 2df5c1f5b0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-16 21:14:52 +03:00
BALATON Zoltan 1a78b89bcf hw/pci-host/ppc440_pcix: Do not expose a bridge device on PCI bus
Real 460EX SoC apparently does not expose a bridge device and having
it appear on PCI bus confuses an AmigaOS file system driver that uses
this to detect which machine it is running on.

Cc: qemu-stable@nongnu.org
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240411192443.B4D644E6026@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 6e4aceba20)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-16 17:27:52 +03:00
BALATON Zoltan dd784cb65d hw/isa/vt82c686: Keep track of PIRQ/PINT pins separately
Move calculation of mask after the switch which sets the function
number for PIRQ/PINT pins to make sure the state of these pins are
kept track of separately and IRQ is raised if any of them is active.

Cc: qemu-stable@nongnu.org
Fixes: 7e01bd80c1 hw/isa/vt82c686: Bring back via_isa_set_irq()
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240410222543.0EA534E6005@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit f33274265a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-16 17:27:39 +03:00
Cindy Lu fcbb086ae5 virtio-pci: fix use of a released vector
During the booting process of the non-standard image, the behavior of the
called function in qemu is as follows:

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

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

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

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

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

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

     (addr=12, value=0x7fc86b7bc628, size=4, access_size_min=1, access_size_max=4, access_fn=0x560640f26c8d <memory_region_write_accessor>, mr=0x560643c66540, attrs=...) at ../system/memory.c:573
14 0x0000560640f2a2b5 in memory_region_dispatch_write (mr=0x560643c66540, addr=12, data=0, op=MO_32, attrs=...)
    at ../system/memory.c:1521
15 0x0000560640f37bac in flatview_write_continue
    (fv=0x7fc65805e0b0, addr=4273803276, attrs=..., ptr=0x7fc871e9c028, len=4, addr1=12, l=4, mr=0x560643c66540)
    at ../system/physmem.c:2714
16 0x0000560640f37d0f in flatview_write
    (fv=0x7fc65805e0b0, addr=4273803276, attrs=..., buf=0x7fc871e9c028, len=4) at ../system/physmem.c:2756
17 0x0000560640f380bf in address_space_write
    (as=0x560642161ae0 <address_space_memory>, addr=4273803276, attrs=..., buf=0x7fc871e9c028, len=4)
    at ../system/physmem.c:2863
18 0x0000560640f3812c in address_space_rw
    (as=0x560642161ae0 <address_space_memory>, addr=4273803276, attrs=..., buf=0x7fc871e9c028, len=4, is_write=true) at ../system/physmem.c:2873
--Type <RET> for more, q to quit, c to continue without paging--
19 0x0000560640f8aa55 in kvm_cpu_exec (cpu=0x560642f205e0) at ../accel/kvm/kvm-all.c:2915
20 0x0000560640f8d731 in kvm_vcpu_thread_fn (arg=0x560642f205e0) at ../accel/kvm/kvm-accel-ops.c:51
21 0x00005606411949f4 in qemu_thread_start (args=0x560642f292b0) at ../util/qemu-thread-posix.c:541
22 0x00007fc87148cdcd in start_thread (arg=<optimized out>) at pthread_create.c:442
23 0x00007fc871512630 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
(gdb)

MST: coding style and typo fixups

Fixes: f9a09ca3ea ("vhost: add support for configure interrupt")
Cc: qemu-stable@nongnu.org
Signed-off-by: Cindy Lu <lulu@redhat.com>
Message-ID: <2321ade5f601367efe7380c04e3f61379c59b48f.1713173550.git.mst@redhat.com>
Cc: Lei Yang <leiyang@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Cindy Lu <lulu@redhat.com>
(cherry picked from commit 2ce6cff94d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-15 23:44:26 +03:00
Richard Henderson 6e29509abc linux-user/x86_64: Handle the vsyscall page in open_self_maps_{2,4}
This is the only case in which we expect to have no host memory backing
for a guest memory page, because in general linux user processes cannot
map any pages in the top half of the 64-bit address space.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2170
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 4ef1f559f2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-14 18:57:33 +03:00
Philippe Mathieu-Daudé e2dfadfd07 hw/audio/virtio-snd: Remove unused assignment
Coverity reported:

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

Simply remove the unused assignments.

Resolves: Coverity CID 1542933
Resolves: Coverity CID 1542934
Fixes: 731655f87f ("virtio-snd: rewrite invalid tx/rx message handling")
Fixes: 20cd0c8655 ("virtio-snd: rewrite invalid tx/rx message handling" in stable-8.2)
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-Id: <20240410053712.34747-1-philmd@linaro.org>
(cherry picked from commit dcb0a1ac03)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 1cfe45956e hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()
If a fragmented packet size is too short, do not try to
calculate its checksum.

Reproduced using:

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

Fixes: CVE-2024-3567
Cc: qemu-stable@nongnu.org
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
Fixes: f199b13bc1 ("igb: Implement Tx SCTP CSO")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2273
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20240410070459.49112-1-philmd@linaro.org>
(cherry picked from commit 83ddb3dbba)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 35a67d2aa8 hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set
Per "SD Host Controller Standard Specification Version 3.00":

  * 2.2.5 Transfer Mode Register (Offset 00Ch)

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

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

  $ cat << EOF | qemu-system-i386 \
                     -display none -nographic -nodefaults \
                     -machine accel=qtest -m 512M \
                     -device sdhci-pci,sd-spec-version=3 \
                     -device sd-card,drive=mydrive \
                     -drive if=none,index=0,file=null-co://,format=raw,id=mydrive \
                     -qtest stdio
  outl 0xcf8 0x80001013
  outl 0xcfc 0x91
  outl 0xcf8 0x80001001
  outl 0xcfc 0x06000000
  write 0x9100002c 0x1 0x05
  write 0x91000058 0x1 0x16
  write 0x91000005 0x1 0x04
  write 0x91000028 0x1 0x08
  write 0x16 0x1 0x21
  write 0x19 0x1 0x20
  write 0x9100000c 0x1 0x01
  write 0x9100000e 0x1 0x20
  write 0x9100000f 0x1 0x00
  write 0x9100000c 0x1 0x00
  write 0x91000020 0x1 0x00
  EOF

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

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

Fixes: CVE-2024-3447
Cc: qemu-stable@nongnu.org
Fixes: d7dfca0807 ("hw/sdhci: introduce standard SD host controller")
Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58813
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Chuhong Yuan <hslester96@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <CAFEAcA9iLiv1XGTGKeopgMa8Y9+8kvptvsb8z2OBeuy+5=NUfg@mail.gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240409145524.27913-1-philmd@linaro.org>
(cherry picked from commit 9e4b27ca6b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 9666bd2b79 hw/net/lan9118: Fix overflow in MIL TX FIFO
When the MAC Interface Layer (MIL) transmit FIFO is full,
truncate the packet, and raise the Transmitter Error (TXE)
flag.

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

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

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

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

Cc: qemu-stable@nongnu.org
Reported-by: Will Lester
Reported-by: Chuhong Yuan <hslester96@gmail.com>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2267
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20240409133801.23503-3-philmd@linaro.org>
(cherry picked from commit ad766d603f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 4e6240e184 hw/net/lan9118: Replace magic '2048' value by MIL_TXFIFO_SIZE definition
The magic 2048 is explained in the LAN9211 datasheet (DS00002414A)
in chapter 1.4, "10/100 Ethernet MAC":

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

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

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20240409133801.23503-2-philmd@linaro.org>
(cherry picked from commit a45223467e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 516bdbc234 backends/cryptodev: Do not abort for invalid session ID
Instead of aborting when a session ID is invalid,
return VIRTIO_CRYPTO_INVSESS ("Invalid session id").

Reproduced using:

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

Cc: qemu-stable@nongnu.org
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2274
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: zhenwei pi <pizhenwei@bytedance.com>
Message-Id: <20240409094757.9127-1-philmd@linaro.org>
(cherry picked from commit eaf2bd2953)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 1c5005c450 hw/misc/applesmc: Fix memory leak in reset() handler
AppleSMCData is allocated with g_new0() in applesmc_add_key():
release it with g_free().

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

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2272
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20240408095217.57239-3-philmd@linaro.org>
(cherry picked from commit fc09ff2979)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 6e7e387b79 hw/block/nand: Fix out-of-bound access in NAND block buffer
nand_command() and nand_getio() don't check @offset points
into the block, nor the available data length (s->iolen) is
not negative.

In order to fix:

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

Reproducer:

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

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

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

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

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

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1445
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1446
Reported-by: Qiang Liu <cyruscyliu@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240409135944.24997-4-philmd@linaro.org>
(cherry picked from commit d39fdfff34)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé ab995895ad hw/block/nand: Have blk_load() take unsigned offset and return boolean
Negative offset is meaningless, use unsigned type.
Return a boolean value indicating success.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240409135944.24997-3-philmd@linaro.org>
(cherry picked from commit 2e3e09b368)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 15b41461ea hw/block/nand: Factor nand_load_iolen() method out
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240409135944.24997-2-philmd@linaro.org>
(cherry picked from commit 7a86544f28)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Yuquan Wang 5d53ff200b qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo
Fix the unit typo of interleave-granularity of CXL Fixed Memory
Window in qemu-option.hx.

Fixes: 03b39fcf64 ("hw/cxl: Make the CFMW a machine parameter.")
Signed-off-by: Yuquan Wang wangyuquan1236@phytium.com.cn
Message-ID: <20240407083539.1488172-2-wangyuquan1236@phytium.com.cn>
[PMD: Reworded]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit aa88f99c87)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 4f01537ced hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs
Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.

Fixes: CVE-2024-3446
Cc: qemu-stable@nongnu.org
Suggested-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-5-philmd@linaro.org>
(cherry picked from commit f4729ec39a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé fbeb0a160c hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs
Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.

Fixes: CVE-2024-3446
Cc: qemu-stable@nongnu.org
Suggested-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-4-philmd@linaro.org>
(cherry picked from commit b4295bff25)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé 1b2a52712b hw/display/virtio-gpu: Protect from DMA re-entrancy bugs
Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed:

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

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

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

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

With this change, the same reproducer triggers:

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

Fixes: CVE-2024-3446
Cc: qemu-stable@nongnu.org
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Yongkang Jia <kangel@zju.edu.cn>
Reported-by: Xiao Lei <nop.leixiao@gmail.com>
Reported-by: Yiming Tao <taoym@zju.edu.cn>
Buglink: https://bugs.launchpad.net/qemu/+bug/1888606
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-3-philmd@linaro.org>
(cherry picked from commit ba28e0ff4d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Philippe Mathieu-Daudé eb546a3f49 hw/virtio: Introduce virtio_bh_new_guarded() helper
Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded()
but using the transport memory guard, instead of the device one
(there can only be one virtio device per virtio bus).

Inspired-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-2-philmd@linaro.org>
(cherry picked from commit ec0504b989)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Keith Packard 390da29ce5 target/m68k: Map FPU exceptions to FPSR register
Add helpers for reading/writing the 68881 FPSR register so that
changes in floating point exception state can be seen by the
application.

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

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230803035231.429697-1-keithp@keithp.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 5888357942)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Zack Buhman 0764b8a8e3 target/sh4: add missing CHECK_NOT_DELAY_SLOT
CHECK_NOT_DELAY_SLOT is correctly applied to the branch-related
instructions, but not to the PC-relative mov* instructions.

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

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

Signed-off-by: Zack Buhman <zack@buhman.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240407150705.5965-1-zack@buhman.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewd-by: Yoshinori Sato <ysato@users.sourceforge.jp>
(cherry picked from commit b754cb2dcd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Zack Buhman 733511728a target/sh4: Fix mac.w with saturation enabled
The saturation arithmetic logic in helper_macw is not correct.
I tested and verified this behavior on a SH7091.

Reviewd-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Zack Buhman <zack@buhman.org>
Message-Id: <20240405233802.29128-3-zack@buhman.org>
[rth: Reformat helper_macw, add a test case.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 7227c0cd50)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Zack Buhman 77e03229ca target/sh4: Fix mac.l with saturation enabled
The saturation arithmetic logic in helper_macl is not correct.
I tested and verified this behavior on a SH7091.

Signed-off-by: Zack Buhman <zack@buhman.org>
Message-Id: <20240404162641.27528-2-zack@buhman.org>
[rth: Reformat helper_macl, add a test case.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit c97e8977dc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Richard Henderson 7fc1bcb65f target/sh4: Merge mach and macl into a union
Allow host access to the entire 64-bit accumulator.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 7d95db5e78)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Zack Buhman be88ed87a6 target/sh4: mac.w: memory accesses are 16-bit words
Before this change, executing a code sequence such as:

           mova   tblm,r0
           mov    r0,r1
           mova   tbln,r0
           clrs
           clrmac
           mac.w  @r0+,@r1+
           mac.w  @r0+,@r1+

           .align 4
  tblm:    .word  0x1234
           .word  0x5678
  tbln:    .word  0x9abc
           .word  0xdefg

Does not result in correct behavior:

Expected behavior:
  first macw : macl = 0x1234 * 0x9abc + 0x0
               mach = 0x0

  second macw: macl = 0x5678 * 0xdefg + 0xb00a630
               mach = 0x0

Observed behavior (qemu-sh4eb, prior to this commit):

  first macw : macl = 0x5678 * 0xdefg + 0x0
               mach = 0x0

  second macw: (unaligned longword memory access, SIGBUS)

Various SH-4 ISA manuals also confirm that `mac.w` is a 16-bit word memory
access, not a 32-bit longword memory access.

Signed-off-by: Zack Buhman <zack@buhman.org>
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240402093756.27466-1-zack@buhman.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit b0f2f2976b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 20:32:12 +03:00
Richard Henderson c02844b8e8 linux-user: Fix waitid return of siginfo_t and rusage
The copy back to siginfo_t should be conditional only on arg3,
not the specific values that might have been written.
The copy back to rusage was missing entirely.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2262
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Fan <alex.fan.q@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit f0907ff4ca)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 18:54:46 +03:00
Richard Henderson 196601e759 tcg/optimize: Do not attempt to constant fold neg_vec
Split out the tail of fold_neg to fold_neg_no_const so that we
can avoid attempting to constant fold vector negate.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2150
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit e25fe886b8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-10 18:51:37 +03:00
Manos Pitsidianakis 20cd0c8655 virtio-snd: rewrite invalid tx/rx message handling
The current handling of invalid virtqueue elements inside the TX/RX virt
queue handlers is wrong.

They are added in a per-stream invalid queue to be processed after the
handler is done examining each message, but the invalid message might
not be specifying any stream_id; which means it's invalid to add it to
any stream->invalid queue since stream could be NULL at this point.

This commit moves the invalid queue to the VirtIOSound struct which
guarantees there will always be a valid temporary place to store them
inside the tx/rx handlers. The queue will be emptied before the handler
returns, so the queue must be empty at any other point of the device's
lifetime.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-Id: <virtio-snd-rewrite-invalid-tx-rx-message-handling-v1.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 731655f87f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-09 21:15:05 +03:00
Zheyu Ma 627aa460ba virtio-snd: Enhance error handling for invalid transfers
This patch improves error handling in virtio_snd_handle_tx_xfer()
and virtio_snd_handle_rx_xfer() in the VirtIO sound driver. Previously,
'goto' statements were used for error paths, leading to unnecessary
processing and potential null pointer dereferences. Now, 'continue' is
used to skip the rest of the current loop iteration for errors such as
message size discrepancies or null streams, reducing crash risks.

ASAN log illustrating the issue addressed:

ERROR: AddressSanitizer: SEGV on unknown address 0x0000000000b4
    #0 0x57cea39967b8 in qemu_mutex_lock_impl qemu/util/qemu-thread-posix.c:92:5
    #1 0x57cea128c462 in qemu_mutex_lock qemu/include/qemu/thread.h:122:5
    #2 0x57cea128d72f in qemu_lockable_lock qemu/include/qemu/lockable.h:95:5
    #3 0x57cea128c294 in qemu_lockable_auto_lock qemu/include/qemu/lockable.h:105:5
    #4 0x57cea1285eb2 in virtio_snd_handle_rx_xfer qemu/hw/audio/virtio-snd.c:1026:9
    #5 0x57cea2caebbc in virtio_queue_notify_vq qemu/hw/virtio/virtio.c:2268:9
    #6 0x57cea2cae412 in virtio_queue_host_notifier_read qemu/hw/virtio/virtio.c:3671:9
    #7 0x57cea39822f1 in aio_dispatch_handler qemu/util/aio-posix.c:372:9
    #8 0x57cea3979385 in aio_dispatch_handlers qemu/util/aio-posix.c:414:20
    #9 0x57cea3978eb1 in aio_dispatch qemu/util/aio-posix.c:424:5
    #10 0x57cea3a1eede in aio_ctx_dispatch qemu/util/async.c:360:5

Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-Id: <20240322110827.568412-1-zheyuma97@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a45f09935c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-09 21:15:00 +03:00
lyx634449800 cd461c8445 vdpa-dev: Fix the issue of device status not updating when configuration interruption is triggered
The set_config callback function vhost_vdpa_device_get_config in
vdpa-dev does not fetch the current device status from the hardware
device, causing the guest os to not receive the latest device status
information.

The hardware updates the config status of the vdpa device and then
notifies the os. The guest os receives an interrupt notification,
triggering a get_config access in the kernel, which then enters qemu
internally. Ultimately, the vhost_vdpa_device_get_config function of
vdpa-dev is called

One scenario encountered is when the device needs to bring down the
vdpa net device. After modifying the status field of virtio_net_config
in the hardware, it sends an interrupt notification. However, the guest
os always receives the STATUS field as VIRTIO_NET_S_LINK_UP.

Signed-off-by: Yuxue Liu <yuxue.liu@jaguarmicro.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20240408020003.1979-1-yuxue.liu@jaguarmicro.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 6ae72f609a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-09 20:42:59 +03:00
Wafer b57b102a81 hw/virtio: Fix packed virtqueue flush used_idx
In the event of writing many chains of descriptors, the device must
write just the id of the last buffer in the descriptor chain, skip
forward the number of descriptors in the chain, and then repeat the
operations for the rest of chains.

Current QEMU code writes all the buffer ids consecutively, and then
skips all the buffers altogether. This is a bug, and can be reproduced
with a VirtIONet device with _F_MRG_RXBUB and without
_F_INDIRECT_DESC:

If a virtio-net device has the VIRTIO_NET_F_MRG_RXBUF feature
but not the VIRTIO_RING_F_INDIRECT_DESC feature,
'VirtIONetQueue->rx_vq' will use the merge feature
to store data in multiple 'elems'.
The 'num_buffers' in the virtio header indicates how many elements are merged.
If the value of 'num_buffers' is greater than 1,
all the merged elements will be filled into the descriptor ring.
The 'idx' of the elements should be the value of 'vq->used_idx' plus 'ndescs'.

Fixes: 86044b24e8 ("virtio: basic packed virtqueue support")
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Wafer <wafer@jaguarmicro.com>
Message-Id: <20240407015451.5228-2-wafer@jaguarmicro.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2d9a31b3c2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-09 20:39:47 +03:00
Peter Maydell f7a1ff69ba target/arm: Use correct SecuritySpace for AArch64 AT ops at EL3
When we do an AT address translation operation, the page table walk
is supposed to be performed in the context of the EL we're doing the
walk for, so for instance an AT S1E2R walk is done for EL2.  In the
pseudocode an EL is passed to AArch64.AT(), which calls
SecurityStateAtEL() to find the security state that we should be
doing the walk with.

In ats_write64() we get this wrong, instead using the current
security space always.  This is fine for AT operations performed from
EL1 and EL2, because there the current security state and the
security state for the lower EL are the same.  But for AT operations
performed from EL3, the current security state is always either
Secure or Root, whereas we want to use the security state defined by
SCR_EL3.{NS,NSE} for the walk. This affects not just guests using
FEAT_RME but also ones where EL3 is Secure state and the EL3 code
is trying to do an AT for a NonSecure EL2 or EL1.

Use arm_security_space_below_el3() to get the SecuritySpace to
pass to do_ats_write() for all AT operations except the
AT S1E3* operations.

Cc: qemu-stable@nongnu.org
Fixes: e1ee56ec23 ("target/arm: Pass security space rather than flag for AT instructions")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2250
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240405180232.3570066-1-peter.maydell@linaro.org
(cherry picked from commit 19b254e86a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-09 20:19:43 +03:00
Wei Wang 6983d1657d migration/postcopy: ensure preempt channel is ready before loading states
Before loading the guest states, ensure that the preempt channel has been
ready to use, as some of the states (e.g. via virtio_load) might trigger
page faults that will be handled through the preempt channel. So yield to
the main thread in the case that the channel create event hasn't been
dispatched.

Cc: qemu-stable <qemu-stable@nongnu.org>
Fixes: 9358982744 ("migration: Send requested page directly in rp-return thread")
Originally-by: Lei Wang <lei4.wang@intel.com>
Link: https://lore.kernel.org/all/9aa5d1be-7801-40dd-83fd-f7e041ced249@intel.com/T/
Signed-off-by: Lei Wang <lei4.wang@intel.com>
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
Link: https://lore.kernel.org/r/20240405034056.23933-1-wei.w.wang@intel.com
[peterx: add a todo section, add Fixes and copy stable for 8.0+]
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 7afbdada7e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-09 20:18:26 +03:00
Zheyu Ma 46f03be3ed block/virtio-blk: Fix memory leak from virtio_blk_zone_report
This modification ensures that in scenarios where the buffer size is
insufficient for a zone report, the function will now properly set an
error status and proceed to a cleanup label, instead of merely
returning.

The following ASAN log reveals it:

==1767400==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 312 byte(s) in 1 object(s) allocated from:
    #0 0x64ac7b3280cd in malloc llvm/compiler-rt/lib/asan/asan_malloc_linux.cpp:129:3
    #1 0x735b02fb9738 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5e738)
    #2 0x64ac7d23be96 in virtqueue_split_pop hw/virtio/virtio.c:1612:12
    #3 0x64ac7d23728a in virtqueue_pop hw/virtio/virtio.c:1783:16
    #4 0x64ac7cfcaacd in virtio_blk_get_request hw/block/virtio-blk.c:228:27
    #5 0x64ac7cfca7c7 in virtio_blk_handle_vq hw/block/virtio-blk.c:1123:23
    #6 0x64ac7cfecb95 in virtio_blk_handle_output hw/block/virtio-blk.c:1157:5

Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
Message-id: 20240404120040.1951466-1-zheyuma97@gmail.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit bbdf902366)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-09 20:13:20 +03:00
Yajun Wu 9c2b8194ac hw/net/virtio-net: fix qemu set used ring flag even vhost started
When vhost-user or vhost-kernel is handling virtio net datapath,
QEMU should not touch used ring.

But with vhost-user socket reconnect scenario, in a very rare case
(has pending kick event). VRING_USED_F_NO_NOTIFY is set by QEMU in
following code path:

	#0  virtio_queue_split_set_notification (vq=0x7ff5f4c920a8, enable=0) at ../hw/virtio/virtio.c:511
	#1  0x0000559d6dbf033b in virtio_queue_set_notification (vq=0x7ff5f4c920a8, enable=0) at ../hw/virtio/virtio.c:576
	#2  0x0000559d6dbbbdbc in virtio_net_handle_tx_bh (vdev=0x559d703a6aa0, vq=0x7ff5f4c920a8) at ../hw/net/virtio-net.c:2801
	#3  0x0000559d6dbf4791 in virtio_queue_notify_vq (vq=0x7ff5f4c920a8) at ../hw/virtio/virtio.c:2248
	#4  0x0000559d6dbf79da in virtio_queue_host_notifier_read (n=0x7ff5f4c9211c) at ../hw/virtio/virtio.c:3525
	#5  0x0000559d6d9a5814 in virtio_bus_cleanup_host_notifier (bus=0x559d703a6a20, n=1) at ../hw/virtio/virtio-bus.c:321
	#6  0x0000559d6dbf83c9 in virtio_device_stop_ioeventfd_impl (vdev=0x559d703a6aa0) at ../hw/virtio/virtio.c:3774
	#7  0x0000559d6d9a55c8 in virtio_bus_stop_ioeventfd (bus=0x559d703a6a20) at ../hw/virtio/virtio-bus.c:259
	#8  0x0000559d6d9a53e8 in virtio_bus_grab_ioeventfd (bus=0x559d703a6a20) at ../hw/virtio/virtio-bus.c:199
	#9  0x0000559d6dbf841c in virtio_device_grab_ioeventfd (vdev=0x559d703a6aa0) at ../hw/virtio/virtio.c:3783
	#10 0x0000559d6d9bde18 in vhost_dev_enable_notifiers (hdev=0x559d707edd70, vdev=0x559d703a6aa0) at ../hw/virtio/vhost.c:1592
	#11 0x0000559d6d89a0b8 in vhost_net_start_one (net=0x559d707edd70, dev=0x559d703a6aa0) at ../hw/net/vhost_net.c:266
	#12 0x0000559d6d89a6df in vhost_net_start (dev=0x559d703a6aa0, ncs=0x559d7048d890, data_queue_pairs=31, cvq=0) at ../hw/net/vhost_net.c:412
	#13 0x0000559d6dbb5b89 in virtio_net_vhost_status (n=0x559d703a6aa0, status=15 '\017') at ../hw/net/virtio-net.c:311
	#14 0x0000559d6dbb5e34 in virtio_net_set_status (vdev=0x559d703a6aa0, status=15 '\017') at ../hw/net/virtio-net.c:392
	#15 0x0000559d6dbb60d8 in virtio_net_set_link_status (nc=0x559d7048d890) at ../hw/net/virtio-net.c:455
	#16 0x0000559d6da64863 in qmp_set_link (name=0x559d6f0b83d0 "hostnet1", up=true, errp=0x7ffdd76569f0) at ../net/net.c:1459
	#17 0x0000559d6da7226e in net_vhost_user_event (opaque=0x559d6f0b83d0, event=CHR_EVENT_OPENED) at ../net/vhost-user.c:301
	#18 0x0000559d6ddc7f63 in chr_be_event (s=0x559d6f2ffea0, event=CHR_EVENT_OPENED) at ../chardev/char.c:62
	#19 0x0000559d6ddc7fdc in qemu_chr_be_event (s=0x559d6f2ffea0, event=CHR_EVENT_OPENED) at ../chardev/char.c:82

This issue causes guest kernel stop kicking device and traffic stop.

Add vhost_started check in virtio_net_handle_tx_bh to fix this wrong
VRING_USED_F_NO_NOTIFY set.

Signed-off-by: Yajun Wu <yajunw@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20240402045109.97729-1-yajunw@nvidia.com>
[PMD: Use unlikely()]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 4c54f5bc8e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-03 08:10:35 +03:00
Peter Maydell e961fa43e9 target/arm: take HSTR traps of cp15 accesses to EL2, not EL1
The HSTR_EL2 register allows the hypervisor to trap AArch32 EL1 and
EL0 accesses to cp15 registers.  We incorrectly implemented this so
they trap to EL1 when we detect the need for a HSTR trap at code
generation time.  (The check in access_check_cp_reg() which we do at
runtime to catch traps from EL0 is correctly routing them to EL2.)

Use the correct target EL when generating the code to take the trap.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2226
Fixes: 049edada5e ("target/arm: Make HSTR_EL2 traps take priority over UNDEF-at-EL1")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240325133116.2075362-1-peter.maydell@linaro.org
(cherry picked from commit fbe5ac5671)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-02 19:48:17 +03:00
Peter Maydell 2702763548 hw/intc/arm_gicv3: ICC_HPPIR* return SPURIOUS if int group is disabled
If the group of the highest priority pending interrupt is disabled
via ICC_IGRPEN*, the ICC_HPPIR* registers should return
INTID_SPURIOUS, not the interrupt ID.  (See the GIC architecture
specification pseudocode functions ICC_HPPIR1_EL1[] and
HighestPriorityPendingInterrupt().)

Make HPPIR reads honour the group disable, the way we already do
when determining whether to preempt in icc_hppi_can_preempt().

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240328153333.2522667-1-peter.maydell@linaro.org
(cherry picked from commit 44e25fbc19)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-02 19:45:01 +03:00
Michael Tokarev 2befb8a9c7 gitlab-ci/cirrus: switch from 'master' to 'latest'
Commit ab72522797 "gitlab: switch from 'stable' to
'latest' docker container tags" switched most tags
to 'latest' but missed cirrus image.  Fix this now.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2256
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-id: 20240401051633.2780456-1-mjt@tls.msk.ru
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 1d2f2b35bc)
2024-04-01 19:30:40 +03:00
Avihai Horon 3168476965 migration/postcopy: Ensure postcopy_start() sets errp if it fails
There are several places where postcopy_start() fails without setting
errp. This can cause a null pointer de-reference, as in case of error,
the caller of postcopy_start() copies/prints the error set in errp.

Fix it by setting errp in all of postcopy_start() error paths.

Cc: qemu-stable <qemu-stable@nongnu.org>
Fixes: 908927db28 ("migration: Update error description whenever migration fails")
Signed-off-by: Avihai Horon <avihaih@nvidia.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240328140252.16756-3-avihaih@nvidia.com
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit d0ad271a76)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-01 19:30:21 +03:00
Richard Henderson 35fface50f target/hppa: Clear psw_n for BE on use_nullify_skip path
Along this path we have already skipped the insn to be
nullified, so the subsequent insn should be executed.

Cc: qemu-stable@nongnu.org
Reported-by: Sven Schnelle <svens@stackframe.org>
Tested-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 4a3aa11e1f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-04-01 19:23:57 +03:00
Richard Henderson 3cdfd68e4e tcg/optimize: Fix sign_mask for logical right-shift
The 'sign' computation is attempting to locate the sign bit that has
been repeated, so that we can test if that bit is known zero.  That
computation can be zero if there are no known sign repetitions.

Cc: qemu-stable@nongnu.org
Fixes: 93a967fbb5 ("tcg/optimize: Propagate sign info for shifting")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2248
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 2911e9b95f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-31 22:14:59 +03:00
Akihiko Odaki d3e9e0fb29 hw/net/net_tx_pkt: Fix virtio header without checksum offloading
It is incorrect to have the VIRTIO_NET_HDR_F_NEEDS_CSUM set when
checksum offloading is disabled so clear the bit.

TCP/UDP checksum is usually offloaded when the peer requires virtio
headers because they can instruct the peer to compute checksum. However,
igb disables TX checksum offloading when a VF is enabled whether the
peer requires virtio headers because a transmitted packet can be routed
to it and it expects the packet has a proper checksum. Therefore, it
is necessary to have a correct virtio header even when checksum
offloading is disabled.

A real TCP/UDP checksum will be computed and saved in the buffer when
checksum offloading is disabled. The virtio specification requires to
set the packet checksum stored in the buffer to the TCP/UDP pseudo
header when the VIRTIO_NET_HDR_F_NEEDS_CSUM bit is set so the bit must
be cleared in that case.

Fixes: ffbd2dbd8e ("e1000e: Perform software segmentation for loopback")
Buglink: https://issues.redhat.com/browse/RHEL-23067
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 89a8de364b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-31 22:13:04 +03:00
Akihiko Odaki 12e4886108 virtio-net: Fix vhost virtqueue notifiers for RSS
virtio_net_guest_notifier_pending() and virtio_net_guest_notifier_mask()
checked VIRTIO_NET_F_MQ to know there are multiple queues, but
VIRTIO_NET_F_RSS also enables multiple queues. Refer to n->multiqueue,
which is set to true either of VIRTIO_NET_F_MQ or VIRTIO_NET_F_RSS is
enabled.

Fixes: 68b0a6395f ("virtio-net: align ctrl_vq index for non-mq guest for vhost_vdpa")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 1c188fc8cb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-31 22:11:27 +03:00
Yong-Xuan Wang 1e4ec0958e target/riscv/kvm: fix timebase-frequency when using KVM acceleration
The timebase-frequency of guest OS should be the same with host
machine. The timebase-frequency value in DTS should be got from
hypervisor when using KVM acceleration.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Message-ID: <20240314061510.9800-1-yongxuan.wang@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 385e575cd5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fix due to missing other changes in this area in 8.2.x)
2024-03-27 13:04:06 +03:00
Irina Ryapolova 38f36fc568 target/riscv: Fix mode in riscv_tlb_fill
Need to convert mmu_idx to privilege mode for PMP function.

Signed-off-by: Irina Ryapolova <irina.ryapolova@syntacore.com>
Fixes: b297129ae1 ("target/riscv: propagate PMP permission to TLB page")
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20240320172828.23965-1-irina.ryapolova@syntacore.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit e06adebb08)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:25 +03:00
Max Chou dc2abb61af target/riscv: rvv: Remove the dependency of Zvfbfmin to Zfbfmin
According to the Zvfbfmin definition in the RISC-V BF16 extensions spec,
the Zvfbfmin extension only requires either the V extension or the
Zve32f extension.

Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240321170929.1162507-1-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit c9b07fe14d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:25 +03:00
Frank Chang 6c49ccaaba hw/intc: Update APLIC IDC after claiming iforce register
Currently, QEMU only sets the iforce register to 0 and returns early
when claiming the iforce register. However, this may leave mip.meip
remains at 1 if a spurious external interrupt triggered by iforce
register is the only pending interrupt to be claimed, and the interrupt
cannot be lowered as expected.

This commit fixes this issue by calling riscv_aplic_idc_update() to
update the IDC status after the iforce register is claimed.

Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240321104951.12104-1-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 078189b327)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:25 +03:00
Daniel Henrique Barboza b7ff2c5600 target/riscv/vector_helper.c: optimize loops in ldst helpers
Change the for loops in ldst helpers to do a single increment in the
counter, and assign it env->vstart, to avoid re-reading from vstart
every time.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20240314175704.478276-11-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 0a11629c91)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:25 +03:00
Daniel Henrique Barboza c4ed8c5610 target/riscv/vector_helpers: do early exit when vstart >= vl
We're going to make changes that will required each helper to be
responsible for the 'vstart' management, i.e. we will relieve the
'vstart < vl' assumption that helpers have today.

Helpers are usually able to deal with vstart >= vl, i.e. doing nothing
aside from setting vstart = 0 at the end, but the tail update functions
will update the tail regardless of vstart being valid or not. Unifying
the tail update process in a single function that would handle the
vstart >= vl case isn't trivial (see [1] for more info).

This patch takes a blunt approach: do an early exit in every single
vector helper if vstart >= vl, unless the helper is guarded with
vstart_eq_zero in the translation. For those cases the helper is ready
to deal with cases where vl might be zero, i.e. throwing exceptions
based on it like vcpop_m() and first_m().

Helpers that weren't changed:

- vcpop_m(), vfirst_m(), vmsetm(), GEN_VEXT_VIOTA_M(): these are guarded
  directly with vstart_eq_zero;

- GEN_VEXT_VCOMPRESS_VM(): guarded with vcompress_vm_check() that checks
  vstart_eq_zero;

- GEN_VEXT_RED(): guarded with either reduction_check() or
  reduction_widen_check(), both check vstart_eq_zero;

- GEN_VEXT_FRED(): guarded with either freduction_check() or
  freduction_widen_check(), both check vstart_eq_zero.

Another exception is vext_ldst_whole(), who operates on effective vector
length regardless of the current settings in vtype and vl.

[1] https://lore.kernel.org/qemu-riscv/1590234b-0291-432a-a0fa-c5a6876097bc@linux.alibaba.com/

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240314175704.478276-7-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit df4252b2ec)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:21 +03:00
Daniel Henrique Barboza 43ca6c1a9b target/riscv: always clear vstart in whole vec move insns
These insns have 2 paths: we'll either have vstart already cleared if
vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
the 'vmvr_v' helper. The helper will clear vstart if it executes until
the end, or if vstart >= vl.

For starters, the check itself is wrong: we're checking vstart >= maxsz,
when in fact we should use vstart in bytes, or 'startb' like 'vmvr_v' is
calling, to do the comparison. But even after fixing the comparison we'll
still need to clear vstart in the end, which isn't happening too.

We want to make the helpers responsible to manage vstart, including
these corner cases, precisely to avoid these situations:

- remove the wrong vstart >= maxsz cond from the translation;
- add a 'startb >= maxsz' cond in 'vmvr_v', and clear vstart if that
  happens.

This way we're now sure that vstart is being cleared in the end of the
execution, regardless of the path taken.

Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20240314175704.478276-5-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 7e53e3ddf6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:14 +03:00
Daniel Henrique Barboza 693ceca987 target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess
vmvr_v isn't handling the case where the host might be big endian and
the bytes to be copied aren't sequential.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20240314175704.478276-4-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 768e7b329c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:14 +03:00
Daniel Henrique Barboza 9f0db88ca9 trans_rvv.c.inc: set vstart = 0 in int scalar move insns
trans_vmv_x_s, trans_vmv_s_x, trans_vfmv_f_s and trans_vfmv_s_f aren't
setting vstart = 0 after execution. This is usually done by a helper in
vector_helper.c but these functions don't use helpers.

We'll set vstart after any potential 'over' brconds, and that will also
mandate a mark_vs_dirty() too.

Fixes: dedc53cbc9 ("target/riscv: rvv-1.0: integer scalar move instructions")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240314175704.478276-3-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 0848f7c18e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:14 +03:00
Daniel Henrique Barboza bf26b6acc1 target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
The helper isn't setting env->vstart = 0 after its execution, as it is
expected from every vector instruction that completes successfully.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-ID: <20240314175704.478276-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit d3646e31ce)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 13:00:14 +03:00
Yao Xingtao 0041b5a014 monitor/hmp-cmds-target: Append a space in error message in gpa2hva()
In qemu monitor mode, when we use gpa2hva command to print the host
virtual address corresponding to a guest physical address, if the gpa is
not in RAM, the error message is below:

  (qemu) gpa2hva 0x750000000
  Memory at address 0x750000000is not RAM

A space is missed between '0x750000000' and 'is'.

Signed-off-by: Yao Xingtao <yaoxt.fnst@fujitsu.com>
Fixes: e9628441df ("hmp: gpa2hva and gpa2hpa hostaddr command")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>
Message-ID: <20240319021610.2423844-1-ruansy.fnst@fujitsu.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit a158c63b3b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:49:20 +03:00
Lorenz Brun 783b2fc0a9 hw/scsi/scsi-generic: Fix io_timeout property not applying
The io_timeout property, introduced in c9b6609 (part of 6.0) is
silently overwritten by the hardcoded default value of 30 seconds
(DEFAULT_IO_TIMEOUT) in scsi_generic_realize because that function is
being called after the properties have already been applied.

The property definition already has a default value which is applied
correctly when no value is explicitly set, so we can just remove the
code which overrides the io_timeout completely.

This has been tested by stracing SG_IO operations with the io_timeout
property set and unset and now sets the timeout field in the ioctl
request to the proper value.

Fixes: c9b6609b69 ("scsi: make io_timeout configurable")
Signed-off-by: Lorenz Brun <lorenz@brun.one>
Message-ID: <20240315145831.2531695-1-lorenz@brun.one>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 7c7a9f578e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:48:06 +03:00
Gregory Price 78bebf8692 target/i386/tcg: Enable page walking from MMIO memory
CXL emulation of interleave requires read and write hooks due to
requirement for subpage granularity. The Linux kernel stack now enables
using this memory as conventional memory in a separate NUMA node. If a
process is deliberately forced to run from that node
$ numactl --membind=1 ls
the page table walk on i386 fails.

Useful part of backtrace:

    (cpu=cpu@entry=0x555556fd9000, fmt=fmt@entry=0x555555fe3378 "cpu_io_recompile: could not find TB for pc=%p")
    at ../../cpu-target.c:359
    (retaddr=0, addr=19595792376, attrs=..., xlat=<optimized out>, cpu=0x555556fd9000, out_offset=<synthetic pointer>)
    at ../../accel/tcg/cputlb.c:1339
    (cpu=0x555556fd9000, full=0x7fffee0d96e0, ret_be=ret_be@entry=0, addr=19595792376, size=size@entry=8, mmu_idx=4, type=MMU_DATA_LOAD, ra=0) at ../../accel/tcg/cputlb.c:2030
    (cpu=cpu@entry=0x555556fd9000, p=p@entry=0x7ffff56fddc0, mmu_idx=<optimized out>, type=type@entry=MMU_DATA_LOAD, memop=<optimized out>, ra=ra@entry=0) at ../../accel/tcg/cputlb.c:2356
    (cpu=cpu@entry=0x555556fd9000, addr=addr@entry=19595792376, oi=oi@entry=52, ra=ra@entry=0, access_type=access_type@entry=MMU_DATA_LOAD) at ../../accel/tcg/cputlb.c:2439
    at ../../accel/tcg/ldst_common.c.inc:301
    at ../../target/i386/tcg/sysemu/excp_helper.c:173
    (err=0x7ffff56fdf80, out=0x7ffff56fdf70, mmu_idx=0, access_type=MMU_INST_FETCH, addr=18446744072116178925, env=0x555556fdb7c0)
    at ../../target/i386/tcg/sysemu/excp_helper.c:578
    (cs=0x555556fd9000, addr=18446744072116178925, size=<optimized out>, access_type=MMU_INST_FETCH, mmu_idx=0, probe=<optimized out>, retaddr=0) at ../../target/i386/tcg/sysemu/excp_helper.c:604

Avoid this by plumbing the address all the way down from
x86_cpu_tlb_fill() where is available as retaddr to the actual accessors
which provide it to probe_access_full() which already handles MMIO accesses.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2180
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2220
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gregory Price <gregory.price@memverge.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-ID: <20240307155304.31241-2-Jonathan.Cameron@huawei.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 9dab7bbb01)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:47:02 +03:00
Fiona Ebner eaa20895b7 iotests: add test for stream job with an unaligned prefetch read
Previously, bdrv_pad_request() could not deal with a NULL qiov when
a read needed to be aligned. During prefetch, a stream job will pass a
NULL qiov. Add a test case to cover this scenario.

By accident, also covers a previous race during shutdown, where block
graph changes during iteration in bdrv_flush_all() could lead to
unreferencing the wrong block driver state and an assertion failure
later.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20240322095009.346989-5-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 12d7b3bbd3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:43:09 +03:00
Fiona Ebner edba203229 block-backend: fix edge case in bdrv_next_cleanup() where BDS associated to BB changes
Same rationale as for commit "block-backend: fix edge case in
bdrv_next() where BDS associated to BB changes". The block graph might
change between the bdrv_next() call and the bdrv_next_cleanup() call,
so it could be that the associated BDS is not the same that was
referenced previously anymore. Instead, rely on bdrv_next() to set
it->bs to the BDS it referenced and unreference that one in any case.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20240322095009.346989-4-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit bac09b093e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:42:57 +03:00
Fiona Ebner 1652e5b97f block-backend: fix edge case in bdrv_next() where BDS associated to BB changes
The old_bs variable in bdrv_next() is currently determined by looking
at the old block backend. However, if the block graph changes before
the next bdrv_next() call, it might be that the associated BDS is not
the same that was referenced previously. In that case, the wrong BDS
is unreferenced, leading to an assertion failure later:

> bdrv_unref: Assertion `bs->refcnt > 0' failed.

In particular, this can happen in the context of bdrv_flush_all(),
when polling for bdrv_co_flush() in the generated co-wrapper leads to
a graph change (for example with a stream block job [0]).

A racy reproducer:

> #!/bin/bash
> rm -f /tmp/backing.qcow2
> rm -f /tmp/top.qcow2
> ./qemu-img create /tmp/backing.qcow2 -f qcow2 64M
> ./qemu-io -c "write -P42 0x0 0x1" /tmp/backing.qcow2
> ./qemu-img create /tmp/top.qcow2 -f qcow2 64M -b /tmp/backing.qcow2 -F qcow2
> ./qemu-system-x86_64 --qmp stdio \
> --blockdev qcow2,node-name=node0,file.driver=file,file.filename=/tmp/top.qcow2 \
> <<EOF
> {"execute": "qmp_capabilities"}
> {"execute": "block-stream", "arguments": { "job-id": "stream0", "device": "node0" } }
> {"execute": "quit"}
> EOF

[0]:

> #0  bdrv_replace_child_tran (child=..., new_bs=..., tran=...)
> #1  bdrv_replace_node_noperm (from=..., to=..., auto_skip=..., tran=..., errp=...)
> #2  bdrv_replace_node_common (from=..., to=..., auto_skip=..., detach_subchain=..., errp=...)
> #3  bdrv_drop_filter (bs=..., errp=...)
> #4  bdrv_cor_filter_drop (cor_filter_bs=...)
> #5  stream_prepare (job=...)
> #6  job_prepare_locked (job=...)
> #7  job_txn_apply_locked (fn=..., job=...)
> #8  job_do_finalize_locked (job=...)
> #9  job_exit (opaque=...)
> #10 aio_bh_poll (ctx=...)
> #11 aio_poll (ctx=..., blocking=...)
> #12 bdrv_poll_co (s=...)
> #13 bdrv_flush (bs=...)
> #14 bdrv_flush_all ()
> #15 do_vm_stop (state=..., send_stop=...)
> #16 vm_shutdown ()

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20240322095009.346989-3-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f6d38c9f6d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:41:46 +03:00
Stefan Reiter 80ccf1e485 block/io: accept NULL qiov in bdrv_pad_request
Some operations, e.g. block-stream, perform reads while discarding the
results (only copy-on-read matters). In this case, they will pass NULL
as the target QEMUIOVector, which will however trip bdrv_pad_request,
since it wants to extend its passed vector. In particular, this is the
case for the blk_co_preadv() call in stream_populate().

If there is no qiov, no operation can be done with it, but the bytes
and offset still need to be updated, so the subsequent aligned read
will actually be aligned and not run into an assertion failure.

In particular, this can happen when the request alignment of the top
node is larger than the allocated part of the bottom node, in which
case padding becomes necessary. For example:

> ./qemu-img create /tmp/backing.qcow2 -f qcow2 64M -o cluster_size=32768
> ./qemu-io -c "write -P42 0x0 0x1" /tmp/backing.qcow2
> ./qemu-img create /tmp/top.qcow2 -f qcow2 64M -b /tmp/backing.qcow2 -F qcow2
> ./qemu-system-x86_64 --qmp stdio \
> --blockdev qcow2,node-name=node0,file.driver=file,file.filename=/tmp/top.qcow2 \
> <<EOF
> {"execute": "qmp_capabilities"}
> {"execute": "blockdev-add", "arguments": { "driver": "compress", "file": "node0", "node-name": "node1" } }
> {"execute": "block-stream", "arguments": { "job-id": "stream0", "device": "node1" } }
> EOF

Originally-by: Stefan Reiter <s.reiter@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
[FE: do update bytes and offset in any case
     add reproducer to commit message]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20240322095009.346989-2-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 3f934817c8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:41:46 +03:00
Kevin Wolf 73d604a4bc vdpa-dev: Fix initialisation order to restore VDUSE compatibility
VDUSE requires that virtqueues are first enabled before the DRIVER_OK
status flag is set; with the current API of the kernel module, it is
impossible to enable the opposite order in our block export code because
userspace is not notified when a virtqueue is enabled.

This requirement also mathces the normal initialisation order as done by
the generic vhost code in QEMU. However, commit 6c482547 accidentally
changed the order for vdpa-dev and broke access to VDUSE devices with
this.

This changes vdpa-dev to use the normal order again and use the standard
vhost callback .vhost_set_vring_enable for this. VDUSE devices can be
used with vdpa-dev again after this fix.

vhost_net intentionally avoided enabling the vrings for vdpa and does
this manually later while it does enable them for other vhost backends.
Reflect this in the vhost_net code and return early for vdpa, so that
the behaviour doesn't change for this device.

Cc: qemu-stable@nongnu.org
Fixes: 6c4825476a ('vdpa: move vhost_vdpa_set_vring_ready to the caller')
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20240315155949.86066-1-kwolf@redhat.com>
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2c66de61f8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-27 09:39:28 +03:00
Ido Plat 784ebe52bd target/s390x: Use mutable temporary value for op_ts
Otherwise TCG would assume the register that holds t1 would be constant
and reuse whenever it needs the value within it.

Cc: qemu-stable@nongnu.org
Fixes: f1ea739bd5 ("target/s390x: Use tcg_constant_* in local contexts")
Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
[iii: Adjust a newline and capitalization, add tags]
Signed-off-by: Ido Plat <ido.plat@ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20240318202722.20675-1-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 272fba9779)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-25 22:13:29 +03:00
Song Gao ef9b43bb8e target/loongarch: Fix qemu-system-loongarch64 assert failed with the option '-d int'
qemu-system-loongarch64 assert failed with the option '-d int',
the helper_idle() raise an exception EXCP_HLT, but the exception name is undefined.

Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240321123606.1704900-1-gaosong@loongson.cn>
(cherry picked from commit 1590154ee4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-25 15:16:41 +03:00
Thomas Huth 358dd25fb0 docs/conf.py: Remove usage of distutils
The macOS jobs in our CI recently started failing, complaining that
the distutils module is not available anymore. And indeed, according to
https://peps.python.org/pep-0632/ it's been deprecated since a while
and now likely got removed in recent Python versions.

Fortunately, we only use it for a version check via LooseVersion here
which we don't really need anymore - according to Repology.org, these
are the versions of sphinx-rtd-theme that are currently used by the
various distros:

 centos_stream_8: 0.3.1
 centos_stream_9: 0.5.1
 fedora_38: 1.1.1
 fedora_39: 1.2.2
 freebsd: 1.0.0
 haikuports_master: 1.2.1
 openbsd: 1.2.2
 opensuse_leap_15_5: 0.5.1
 pkgsrc_current: 2.0.0
 debian_11: 0.5.1
 debian_12: 1.2.0
 ubuntu_20_04: 0.4.3
 ubuntu_22_04: 1.0.0
 ubuntu_24_04: 2.0.0

So except for CentOS 8, all distros are using a newer version of
sphinx-rtd-theme, and for CentOS 8 we don't support compiling with
the Sphinx of the distro anymore anyway, since it's based on the
Python 3.6 interpreter there. For compiling on CentOS 8, you have
to use the alternative Python 3.8 interpreter which comes without
Sphinx, so that needs the Sphinx installed via pip in the venv
instead, and that is using a newer version, too, according to our
pythondeps.toml file.

Thus we can simply drop the version check now to get rid of the
distutils dependency here.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Message-id: 20240304130403.129543-1-thuth@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit eb844330bd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 17:37:35 +03:00
Song Gao 5b51920fbd target/loongarch: Fix qemu-loongarch64 hang when executing 'll.d $t0, $t0, 0'
On gen_ll, if a->imm is zero, make_address_x return src1,
but the load to destination may clobber src1. We use a new
destination to fix this problem.

Fixes: c5af6628f4 (target/loongarch: Extract make_address_i() helper)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-Id: <20240320013955.1561311-1-gaosong@loongson.cn>
(cherry picked from commit 77642f92c0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 07:49:24 +03:00
Sven Schnelle 242370f8bd target/hppa: fix do_stdby_e()
stdby,e,m was writing data from the wrong half of the register
into memory for cases 0-3.

Fixes: 25460fc5a7 ("target/hppa: Implement STDBY")
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240319161921.487080-7-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 518d2f4300)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:56 +03:00
Sven Schnelle b0a0ec47ba target/hppa: mask privilege bits in mfia
mfia should return only the iaoq bits without privilege
bits.

Fixes: 98a9cb792c ("target-hppa: Implement system and memory-management insns")
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Message-Id: <20240319161921.487080-6-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit b5e0b3a53c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:51 +03:00
Sven Schnelle e3b3cff998 target/hppa: exit tb on flush cache instructions
When the guest modifies the tb it is currently executing from,
it executes a fic instruction. Exit the tb on such instruction,
otherwise we might execute stale code.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
Message-Id: <20240319161921.487080-5-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit ad1fdacd1b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:47 +03:00
Sven Schnelle 4dbeff3d48 target/hppa: fix access_id check
PA2.0 provides 8 instead of 4 PID registers.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240319161921.487080-4-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit ae157fc250)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:41 +03:00
Sven Schnelle ca52ee4a9b target/hppa: fix shrp for wide mode
Fixes: f7b775a9c0 ("target/hppa: Implement SHRPD")
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Message-Id: <20240319161921.487080-3-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit d37fad0ae5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:38 +03:00
Sven Schnelle 4a76c5665b target/hppa: ldcw,s uses static shift of 3
Fixes: 96d6407f36 ("target-hppa: Implement loads and stores")
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240319161921.487080-2-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit c3ea1996a1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:29 +03:00
Richard Henderson de74e73d91 target/hppa: Fix assemble_12a insns for wide mode
Tested-by: Helge Deller <deller@gmx.de>
Reported-by: Sven Schnelle <svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 46174e140d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:12 +03:00
Richard Henderson efbcf7cead target/hppa: Fix assemble_11a insns for wide mode
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Reported-by: Sven Schnelle <svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 4768c28edd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:32:00 +03:00
Richard Henderson f6f4703c5a target/hppa: Fix assemble_16 insns for wide mode
Reported-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 72bace2d13)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-22 00:31:32 +03:00
Tao Su cf794e4774 target/i386: Revert monitor_puts() in do_inject_x86_mce()
monitor_puts() doesn't check the monitor pointer, but do_inject_x86_mce()
may have a parameter with NULL monitor pointer. Revert monitor_puts() in
do_inject_x86_mce() to fix, then the fact that we send the same message to
monitor and log is again more obvious.

Fixes: bf0c50d4aa (monitor: expose monitor_puts to rest of code)
Reviwed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Message-ID: <20240320083640.523287-1-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7fd226b047)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-21 20:16:22 +03:00
Marc-André Lureau f8fb5928a8 ui: compile dbus-display1.c with -fPIC as necessary
Building dbus-display1.c explicitly as a static library drops -fPIC by
default, which may not be correct if it ends up linked to a shared
library.

Let the target decide how to build the unit, with or without -fPIC. This
makes commit 186acfbaf7 ("tests/qtest: Depend on dbus_display1_dep") no
longer relevant, as dbus-display1.c will be recompiled.

Fixes: c172136ea3 ("meson: ensure dbus-display generated code is built
before other units")

Reported-by: Olaf Hering <olaf@aepfle.de>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit d4069a84a3)
2024-03-21 20:13:44 +03:00
Daniel P. Berrangé de742b16b3 Revert "chardev/char-socket: Fix TLS io channels sending too much data to the backend"
This commit results in unexpected termination of the TLS connection.
When 'fd_can_read' returns 0, the code goes on to pass a zero length
buffer to qio_channel_read. The TLS impl calls into gnutls_recv()
with this zero length buffer, at which point GNUTLS returns an error
GNUTLS_E_INVALID_REQUEST. This is treated as fatal by QEMU's TLS code
resulting in the connection being torn down by the chardev.

Simply skipping the qio_channel_read when the buffer length is zero
is also not satisfactory, as it results in a high CPU burn busy loop
massively slowing QEMU's functionality.

The proper solution is to avoid tcp_chr_read being called at all
unless the frontend is able to accept more data. This will be done
in a followup commit.

This reverts commit 462945cd22

Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit e8ee827ffd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-21 20:00:22 +03:00
Paolo Bonzini 509525dc67 target/i386: fix direction of "32-bit MMU" test
The low bit of MMU indices for x86 TCG indicates whether the processor is
in 32-bit mode and therefore linear addresses have to be masked to 32 bits.
However, the index was computed incorrectly, leading to possible conflicts
in the TLB for any address above 4G.

Analyzed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: b1661801c1 ("target/i386: Fix physical address truncation", 2024-02-28)
Fixes: a28b6b4e74 ("target/i386: Fix physical address truncation" in stable-8.2)
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2206
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2cc68629a6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: move changes for x86_cpu_mmu_index() to cpu_mmu_index() due to missing
 v8.2.0-1030-gace0c5fe59 "target/i386: Populate CPUClass.mmu_index")
2024-03-21 19:57:05 +03:00
Paolo Bonzini 1ced8cd541 target/i386: use separate MMU indexes for 32-bit accesses
Accesses from a 32-bit environment (32-bit code segment for instruction
accesses, EFER.LMA==0 for processor accesses) have to mask away the
upper 32 bits of the address.  While a bit wasteful, the easiest way
to do so is to use separate MMU indexes.  These days, QEMU anyway is
compiled with a fixed value for NB_MMU_MODES.  Split MMU_USER_IDX,
MMU_KSMAP_IDX and MMU_KNOSMAP_IDX in two.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 90f641531c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: move changes for x86_cpu_mmu_index() to cpu_mmu_index() due to missing
 v8.2.0-1030-gace0c5fe59 "target/i386: Populate CPUClass.mmu_index")
2024-03-21 19:50:47 +03:00
Paolo Bonzini a85b8ec872 target/i386: introduce function to query MMU indices
Remove knowledge of specific MMU indexes (other than MMU_NESTED_IDX and
MMU_PHYS_IDX) from mmu_translate().  This will make it possible to split
32-bit and 64-bit MMU indexes.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5f97afe254)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fixup in target/i386/cpu.h due to other changes in that area)
2024-03-21 19:43:42 +03:00
Kevin Wolf 25bdc64b62 tests/unit: Bump test-replication timeout to 60 seconds
We're seeing timeouts for this test on CI runs (specifically for
ubuntu-20.04-s390x-all). It doesn't fail consistently, but even the
successful runs take about 27 or 28 seconds, which is not very far from
the 30 seconds timeout.

Bump the timeout a bit to make failure less likely even on this CI host.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20240125165803.48373-1-kwolf@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 63b18312d1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-20 17:33:40 +03:00
Thomas Huth 96ff214a2a tests/unit: Bump test-crypto-block test timeout to 5 minutes
When running the tests in slow mode on a very loaded system and with
--enable-debug, the test-crypto-block can take longer than 4 minutes.
Bump the timeout to 5 minutes to make sure that it also passes in
such situations.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20231215070357.10888-15-thuth@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
(cherry picked from commit e1b363e328)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-20 17:33:21 +03:00
Thomas Huth 2a1ce7c374 tests/unit: Bump test-aio-multithread test timeout to 2 minutes
When running the tests in slow mode on a very loaded system and with
--enable-debug, the test-aio-multithread can take longer than 1 minute.
Bump the timeout to two minutes to make sure that it also passes in
such situations.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20231215070357.10888-14-thuth@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
(cherry picked from commit c45f8f1aef)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-20 17:31:48 +03:00
Kevin Wolf ddf4412bf4 iotests: Add test for reset/AioContext switches with NBD exports
This replicates the scenario in which the bug was reported.
Unfortunately this relies on actually executing a guest (so that the
firmware initialises the virtio-blk device and moves it to its
configured iothread), so this can't make use of the qtest accelerator
like most other test cases. I tried to find a different easy way to
trigger the bug, but couldn't find one.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20240314165825.40261-3-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e8fce34ecc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-19 19:50:08 +03:00
Kevin Wolf a69a002dcd nbd/server: Fix race in draining the export
When draining an NBD export, nbd_drained_begin() first sets
client->quiescing so that nbd_client_receive_next_request() won't start
any new request coroutines. Then nbd_drained_poll() tries to makes sure
that we wait for any existing request coroutines by checking that
client->nb_requests has become 0.

However, there is a small window between creating a new request
coroutine and increasing client->nb_requests. If a coroutine is in this
state, it won't be waited for and drain returns too early.

In the context of switching to a different AioContext, this means that
blk_aio_attached() will see client->recv_coroutine != NULL and fail its
assertion.

Fix this by increasing client->nb_requests immediately when starting the
coroutine. Doing this after the checks if we should create a new
coroutine is okay because client->lock is held.

Cc: qemu-stable@nongnu.org
Fixes: fd6afc501a ("nbd/server: Use drained block ops to quiesce the server")
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20240314165825.40261-2-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9c707525cb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-19 19:45:55 +03:00
Stefan Hajnoczi 13fc21ae3d nbd/server: introduce NBDClient->lock to protect fields
NBDClient has a number of fields that are accessed by both the export
AioContext and the main loop thread. When the AioContext lock is removed
these fields will need another form of protection.

Add NBDClient->lock and protect fields that are accessed by both
threads. Also add assertions where possible and otherwise add doc
comments stating assumptions about which thread and lock holding.

Note this patch moves the client->recv_coroutine assertion from
nbd_co_receive_request() to nbd_trip() where client->lock is held.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20231221192452.1785567-7-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 7075d23511)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-19 19:45:50 +03:00
Stefan Hajnoczi aee1039c61 nbd/server: only traverse NBDExport->clients from main loop thread
The NBD clients list is currently accessed from both the export
AioContext and the main loop thread. When the AioContext lock is removed
there will be nothing protecting the clients list.

Adding a lock around the clients list is tricky because NBDClient
structs are refcounted and may be freed from the export AioContext or
the main loop thread. nbd_export_request_shutdown() -> client_close() ->
nbd_client_put() is also tricky because the list lock would be held
while indirectly dropping references to NDBClients.

A simpler approach is to only allow nbd_client_put() and client_close()
calls from the main loop thread. Then the NBD clients list is only
accessed from the main loop thread and no fancy locking is needed.

nbd_trip() just needs to reschedule itself in the main loop AioContext
before calling nbd_client_put() and client_close(). This costs more CPU
cycles per NBD request so add nbd_client_put_nonzero() to optimize the
common case where more references to NBDClient remain.

Note that nbd_client_get() can still be called from either thread, so
make NBDClient->refcount atomic.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20231221192452.1785567-6-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f816310d0c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-19 19:41:38 +03:00
Kevin Wolf 0d835791f0 mirror: Don't call job_pause_point() under graph lock
Calling job_pause_point() while holding the graph reader lock
potentially results in a deadlock: bdrv_graph_wrlock() first drains
everything, including the mirror job, which pauses it. The job is only
unpaused at the end of the drain section, which is when the graph writer
lock has been successfully taken. However, if the job happens to be
paused at a pause point where it still holds the reader lock, the writer
lock can't be taken as long as the job is still paused.

Mark job_pause_point() as GRAPH_UNLOCKED and fix mirror accordingly.

Cc: qemu-stable@nongnu.org
Buglink: https://issues.redhat.com/browse/RHEL-28125
Fixes: 004915a96a ("block: Protect bs->backing with graph_lock")
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20240313153000.33121-1-kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit ae5a40e858)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-19 19:24:17 +03:00
Cédric Le Goater 8996768ebc migration: Skip only empty block devices
The block .save_setup() handler calls a helper routine
init_blk_migration() which builds a list of block devices to take into
account for migration. When one device is found to be empty (sectors
== 0), the loop exits and all the remaining devices are ignored. This
is a regression introduced when bdrv_iterate() was removed.

Change that by skipping only empty devices.

Cc: Markus Armbruster <armbru@redhat.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Suggested-by: Kevin Wolf <kwolf@redhat.com>
Fixes: fea68bb6e9 ("block: Eliminate bdrv_iterate(), use bdrv_next()")
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Link: https://lore.kernel.org/r/20240312120431.550054-1-clg@redhat.com
[peterx: fix "Suggested-by:"]
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 2e128776dc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-19 19:22:46 +03:00
Volker Rümelin 7820b9b7a0 hw/audio/virtio-sound: return correct command response size
The payload size returned by command VIRTIO_SND_R_PCM_INFO is
wrong. The code in process_cmd() assumes that all commands
return only a virtio_snd_hdr payload, but some commands like
VIRTIO_SND_R_PCM_INFO may return an additional payload.

Add a zero initialized payload_size variable to struct
virtio_snd_ctrl_command to allow for additional payloads.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20240218083351.8524-1-vr_qemu@t-online.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 633487df8d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 21:52:34 +03:00
Jonathan Cameron b5c6660ea6 hmat acpi: Fix out of bounds access due to missing use of indirection
With a numa set up such as

-numa nodeid=0,cpus=0 \
-numa nodeid=1,memdev=mem \
-numa nodeid=2,cpus=1

and appropriate hmat_lb entries the initiator list is correctly
computed and writen to HMAT as 0,2 but then the LB data is accessed
using the node id (here 2), landing outside the entry_list array.

Stash the reverse lookup when writing the initiator list and use
it to get the correct array index index.

Fixes: 4586a2cb83 ("hmat acpi: Build System Locality Latency and Bandwidth Information Structure(s)")
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20240307160326.31570-3-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 74e2845c5f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 21:52:34 +03:00
Akihiko Odaki 313e746958 pcie_sriov: Validate NumVFs
The guest may write NumVFs greater than TotalVFs and that can lead
to buffer overflow in VF implementations.

Cc: qemu-stable@nongnu.org
Fixes: CVE-2024-26327
Fixes: 7c0fa8dff8 ("pcie: Add support for Single Root I/O Virtualization (SR/IOV)")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-Id: <20240228-reuse-v8-2-282660281e60@daynix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Sriram Yagnaraman <sriram.yagnaraman@ericsson.com>
(cherry picked from commit 6081b4243c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 21:52:34 +03:00
Akihiko Odaki 98f3488c1b hw/nvme: Use pcie_sriov_num_vfs()
nvme_sriov_pre_write_ctrl() used to directly inspect SR-IOV
configurations to know the number of VFs being disabled due to SR-IOV
configuration writes, but the logic was flawed and resulted in
out-of-bound memory access.

It assumed PCI_SRIOV_NUM_VF always has the number of currently enabled
VFs, but it actually doesn't in the following cases:
- PCI_SRIOV_NUM_VF has been set but PCI_SRIOV_CTRL_VFE has never been.
- PCI_SRIOV_NUM_VF was written after PCI_SRIOV_CTRL_VFE was set.
- VFs were only partially enabled because of realization failure.

It is a responsibility of pcie_sriov to interpret SR-IOV configurations
and pcie_sriov does it correctly, so use pcie_sriov_num_vfs(), which it
provides, to get the number of enabled VFs before and after SR-IOV
configuration writes.

Cc: qemu-stable@nongnu.org
Fixes: CVE-2024-26328
Fixes: 11871f53ef ("hw/nvme: Add support for the Virtualization Management command")
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-Id: <20240228-reuse-v8-1-282660281e60@daynix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 91bb64a8d2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 21:52:34 +03:00
Klaus Jensen 3097bcbf37 hw/nvme: add machine compatibility parameter to enable msix exclusive bar
Commit 1901b4967c ("hw/block/nvme: move msix table and pba to BAR 0")
moved the MSI-X table and PBA to BAR 0 to make room for enabling CMR and
PMR at the same time. As reported by Julien Grall in #2184, this breaks
migration through system hibernation.

Add a machine compatibility parameter and set it on machines pre 6.0 to
enable the old behavior automatically, restoring the hibernation
migration support.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2184
Fixes: 1901b4967c ("hw/block/nvme: move msix table and pba to BAR 0")
Reported-by: Julien Grall julien@xen.org
Tested-by: Julien Grall julien@xen.org
Reviewed-by: Jesper Wendel Devantier <foss@defmacro.it>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit fa905f65c5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 20:36:57 +03:00
Klaus Jensen 273111ca71 hw/nvme: generalize the mbar size helper
Generalize the mbar size helper such that it can handle cases where the
MSI-X table and PBA are expected to be in an exclusive bar.

Cc: qemu-stable@nongnu.org
Reviewed-by: Jesper Wendel Devantier <foss@defmacro.it>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit ee7bda4d38)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 20:36:57 +03:00
Klaus Jensen 389f6655ca hw/nvme: fix invalid check on mcl
The number of logical blocks within a source range is converted into a
1s based number at the time of parsing. However, when verifying the copy
length we add one again, causing the check against MCL to fail in error.

Cc: qemu-stable@nongnu.org
Fixes: 381ab99d85 ("hw/nvme: check maximum copy length (MCL) for COPY")
Reviewed-by: Minwoo Im <minwoo.im@samsung.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit 8c78015a55)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 20:35:36 +03:00
Minwoo Im 2d281e030d hw/nvme: separate 'serial' property for VFs
Currently, when a VF is created, it uses the 'params' object of the PF
as it is. In other words, the 'params.serial' string memory area is also
shared. In this situation, if the VF is removed from the system, the
PF's 'params.serial' object is released with object_finalize() followed
by object_property_del_all() which release the memory for 'serial'
property. If that happens, the next VF created will inherit a serial
from a corrupted memory area.

If this happens, an error will occur when comparing subsys->serial and
n->params.serial in the nvme_subsys_register_ctrl() function.

Cc: qemu-stable@nongnu.org
Fixes: 44c2c09488 ("hw/nvme: Add support for SR-IOV")
Signed-off-by: Minwoo Im <minwoo.im@samsung.com>
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit 4f0a4a3d58)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 20:34:30 +03:00
Peng Fan 35ca0f7cbc xen: Drop out of coroutine context xen_invalidate_map_cache_entry
xen_invalidate_map_cache_entry is not expected to run in a
coroutine. Without this, there is crash:

    signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
    threadid=<optimized out>) at pthread_kill.c:78
    at /usr/src/debug/glibc/2.38+git-r0/sysdeps/posix/raise.c:26
    fmt=0xffff9e1ca8a8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
    assertion=assertion@entry=0xaaaae0d25740 "!qemu_in_coroutine()",
    file=file@entry=0xaaaae0d301a8 "../qemu-xen-dir-remote/block/graph-lock.c", line=line@entry=260,
    function=function@entry=0xaaaae0e522c0 <__PRETTY_FUNCTION__.3> "bdrv_graph_rdlock_main_loop") at assert.c:92
    assertion=assertion@entry=0xaaaae0d25740 "!qemu_in_coroutine()",
    file=file@entry=0xaaaae0d301a8 "../qemu-xen-dir-remote/block/graph-lock.c", line=line@entry=260,
    function=function@entry=0xaaaae0e522c0 <__PRETTY_FUNCTION__.3> "bdrv_graph_rdlock_main_loop") at assert.c:101
    at ../qemu-xen-dir-remote/block/graph-lock.c:260
    at /home/Freenix/work/sw-stash/xen/upstream/tools/qemu-xen-dir-remote/include/block/graph-lock.h:259
    host=host@entry=0xffff742c8000, size=size@entry=2097152)
    at ../qemu-xen-dir-remote/block/io.c:3362
    host=0xffff742c8000, size=2097152)
    at ../qemu-xen-dir-remote/block/block-backend.c:2859
    host=<optimized out>, size=<optimized out>, max_size=<optimized out>)
    at ../qemu-xen-dir-remote/block/block-ram-registrar.c:33
    size=2097152, max_size=2097152)
    at ../qemu-xen-dir-remote/hw/core/numa.c:883
    buffer=buffer@entry=0xffff743c5000 "")
    at ../qemu-xen-dir-remote/hw/xen/xen-mapcache.c:475
    buffer=buffer@entry=0xffff743c5000 "")
    at ../qemu-xen-dir-remote/hw/xen/xen-mapcache.c:487
    as=as@entry=0xaaaae1ca3ae8 <address_space_memory>, buffer=0xffff743c5000,
    len=<optimized out>, is_write=is_write@entry=true,
    access_len=access_len@entry=32768)
    at ../qemu-xen-dir-remote/system/physmem.c:3199
    dir=DMA_DIRECTION_FROM_DEVICE, len=<optimized out>,
    buffer=<optimized out>, as=0xaaaae1ca3ae8 <address_space_memory>)
    at /home/Freenix/work/sw-stash/xen/upstream/tools/qemu-xen-dir-remote/include/sysemu/dma.h:236
    elem=elem@entry=0xaaaaf620aa30, len=len@entry=32769)
    at ../qemu-xen-dir-remote/hw/virtio/virtio.c:758
    elem=elem@entry=0xaaaaf620aa30, len=len@entry=32769, idx=idx@entry=0)
    at ../qemu-xen-dir-remote/hw/virtio/virtio.c:919
    elem=elem@entry=0xaaaaf620aa30, len=32769)
    at ../qemu-xen-dir-remote/hw/virtio/virtio.c:994
    req=req@entry=0xaaaaf620aa30, status=status@entry=0 '\000')
    at ../qemu-xen-dir-remote/hw/block/virtio-blk.c:67
    ret=0) at ../qemu-xen-dir-remote/hw/block/virtio-blk.c:136
    at ../qemu-xen-dir-remote/block/block-backend.c:1559
--Type <RET> for more, q to quit, c to continue without paging--
    at ../qemu-xen-dir-remote/block/block-backend.c:1614
    i1=<optimized out>) at ../qemu-xen-dir-remote/util/coroutine-ucontext.c:177
    at ../sysdeps/unix/sysv/linux/aarch64/setcontext.S:123

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Message-Id: <20240124021450.21656-1-peng.fan@oss.nxp.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
(cherry picked from commit 9253d83062)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-13 20:15:59 +03:00
Nick Briggs 31e20693ea Avoid unaligned fetch in ladr_match()
There is no guarantee that the PCNetState is allocated such that
csr[8] is allocated on an 8-byte boundary.  Since not all hosts are
capable of unaligned fetches the 16-bit elements need to be fetched
individually to avoid a potential fault.  Closes issue #2143

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2143
Signed-off-by: Nick Briggs <nicholas.h.briggs@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 6a5287ce80)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-12 20:51:32 +03:00
Laurent Vivier 0ba8be81f8 e1000e: fix link state on resume
On resume e1000e_vm_state_change() always calls e1000e_autoneg_resume()
that sets link_down to false, and thus activates the link even
if we have disabled it.

The problem can be reproduced starting qemu in paused state (-S) and
then set the link to down. When we resume the machine the link appears
to be up.

Reproducer:

   # qemu-system-x86_64 ... -device e1000e,netdev=netdev0,id=net0 -S

   {"execute": "qmp_capabilities" }
   {"execute": "set_link", "arguments": {"name": "net0", "up": false}}
   {"execute": "cont" }

To fix the problem, merge the content of e1000e_vm_state_change()
into e1000e_core_post_load() as e1000 does.

Buglink: https://issues.redhat.com/browse/RHEL-21867
Fixes: 6f3fbe4ed0 ("net: Introduce e1000e device emulation")
Suggested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 4cadf10234)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-12 20:50:43 +03:00
Laurent Vivier c440c89ecb igb: fix link state on resume
On resume igb_vm_state_change() always calls igb_autoneg_resume()
that sets link_down to false, and thus activates the link even
if we have disabled it.

The problem can be reproduced starting qemu in paused state (-S) and
then set the link to down. When we resume the machine the link appears
to be up.

Reproducer:

   # qemu-system-x86_64 ... -device igb,netdev=netdev0,id=net0 -S

   {"execute": "qmp_capabilities" }
   {"execute": "set_link", "arguments": {"name": "net0", "up": false}}
   {"execute": "cont" }

To fix the problem, merge the content of igb_vm_state_change()
into igb_core_post_load() as e1000 does.

Buglink: https://issues.redhat.com/browse/RHEL-21867
Fixes: 3a977deebe ("Intrdocue igb device emulation")
Cc: akihiko.odaki@daynix.com
Suggested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 65c2ab8085)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-12 20:50:43 +03:00
Yu Zhang 6ad78a085e migration/rdma: Fix a memory issue for migration
In commit 3fa9642ff7 change was made to convert the RDMA backend to
accept MigrateAddress struct. However, the assignment of "host" leads
to data corruption on the target host and the failure of migration.

    isock->host = rdma->host;

By allocating the memory explicitly for it with g_strdup_printf(), the
issue is fixed and the migration doesn't fail any more.

Fixes: 3fa9642ff7 ("migration: convert rdma backend to accept MigrateAddress")
Cc: qemu-stable <qemu-stable@nongnu.org>
Cc: Li Zhijian <lizhijian@fujitsu.com>
Link: https://lore.kernel.org/r/CAHEcVy4L_D6tuhJ8h=xLR4WaPaprJE3nnxZAEyUnoTrxQ6CF5w@mail.gmail.com
Signed-off-by: Yu Zhang <yu.zhang@ionos.com>
[peterx: use g_strdup() instead of g_strdup_printf(), per Zhijian]
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 69f7b00d05)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-12 20:43:32 +03:00
Michael Tokarev 8f1eb52422 make-release: switch to .xz format by default
For a long time, we provide two compression formats in the
download area, .bz2 and .xz.  There's absolutely no reason
to provide two in parallel, .xz compresses better, and all
the links we use points to .xz.  Downstream distributions
mostly use .xz too.

For the release maintenance providing two formats is definitely
extra burden too.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 9bc9e95119)
2024-03-10 18:37:11 +03:00
Sven Schnelle 5ae5473e2e hw/scsi/lsi53c895a: add timer to scripts processing
HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
under certain circumstances. As the SCSI controller and CPU are not
running at the same time this loop will never finish. After some
time, the check loop interrupts with a unexpected device disconnect.
This works, but is slow because the kernel resets the scsi controller.
Instead of signaling UDC, start a timer and exit the loop. Until the
timer fires, the CPU can process instructions which might changes the
memory location.

The limit of instructions is also reduced because scripts running on
the SCSI processor are usually very short. This keeps the time until
the loop is exit short.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Message-ID: <20240229204407.1699260-1-svens@stackframe.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9876359990)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-10 18:29:04 +03:00
Sven Schnelle 37a8b9205f hw/scsi/lsi53c895a: stop script on phase mismatch
Netbsd isn't happy with qemu lsi53c895a emulation:

cd0(esiop0:0:2:0): command with tag id 0 reset
esiop0: autoconfiguration error: phase mismatch without command
esiop0: autoconfiguration error: unhandled scsi interrupt, sist=0x80 sstat1=0x0 DSA=0x23a64b1 DSP=0x50

This is because lsi_bad_phase() triggers a phase mismatch, which
stops SCRIPT processing. However, after returning to
lsi_command_complete(), SCRIPT is restarted with lsi_resume_script().
Fix this by adding a return value to lsi_bad_phase(), and only resume
script processing when lsi_bad_phase() didn't trigger a host interrupt.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
Tested-by: Helge Deller <deller@gmx.de>
Message-ID: <20240302214453.2071388-1-svens@stackframe.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a9198b3132)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-10 12:29:44 +03:00
Dmitrii Gavrilov 5dc46b3ff8 system/qdev-monitor: move drain_call_rcu call under if (!dev) in qmp_device_add()
Original goal of addition of drain_call_rcu to qmp_device_add was to cover
the failure case of qdev_device_add. It seems call of drain_call_rcu was
misplaced in 7bed89958b what led to waiting for pending RCU callbacks
under happy path too. What led to overall performance degradation of
qmp_device_add.

In this patch call of drain_call_rcu moved under handling of failure of
qdev_device_add.

Signed-off-by: Dmitrii Gavrilov <ds-gavr@yandex-team.ru>
Message-ID: <20231103105602.90475-1-ds-gavr@yandex-team.ru>
Fixes: 7bed89958b ("device_core: use drain_call_rcu in in qmp_device_add", 2020-10-12)
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 012b170173)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-10 12:25:05 +03:00
Peter Maydell 4db93405e5 hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
The sun4v RTC device model added under commit a0e893039c in 2016
was unfortunately added with a license of GPL-v3-or-later, which is
not compatible with other QEMU code which has a GPL-v2-only license.

Relicense the code in the .c and the .h file to GPL-v2-or-later,
to make it compatible with the rest of QEMU.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini (for Red Hat) <pbonzini@redhat.com>
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20240223161300.938542-1-peter.maydell@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit fd7f95f23d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-09 21:42:00 +03:00
Richard Henderson f0ae5d6d5f target/arm: Fix 32-bit SMOPA
While the 8-bit input elements are sequential in the input vector,
the 32-bit output elements are not sequential in the output matrix.
Do not attempt to compute 2 32-bit outputs at the same time.

Cc: qemu-stable@nongnu.org
Fixes: 23a5e3859f ("target/arm: Implement SME integer outer product")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2083
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240305163931.242795-1-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit d572bcb222)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-09 19:01:05 +03:00
David Parsons 81c0ebf107 ui/cocoa: Fix window clipping on macOS 14
macOS Sonoma changes the NSView.clipsToBounds to false by default
where it was true in earlier version of macOS. This causes the window
contents to be occluded by the frame at the top of the window. This
fixes the issue by conditionally compiling the clipping on Sonoma to
true. NSView only exposes the clipToBounds in macOS 14 and so has
to be fixed via conditional compilation.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1994
Signed-off-by: David Parsons <dave@daveparsons.net>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20240224140620.39200-1-dave@daveparsons.net>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit f5af80271a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-09 18:59:33 +03:00
Daniel P. Berrangé 94b544f127 gitlab: update FreeBSD Cirrus CI image to 13.3
The 13.2 images have been deleted from gcloud

Cc: qemu-stable@nongnu.org
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20240304144456.3825935-3-berrange@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 9ea920dc28)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-05 17:46:29 +03:00
Richard Henderson 420a8d8735 linux-user: Remove pgb_dynamic alignment assertion
The assertion was never correct, because the alignment is a composite
of the image alignment and SHMLBA.  Even if the image alignment didn't
match the image address, an assertion would not be correct -- more
appropriate would be an error message about an ill formed image.  But
the image cannot be held to SHMLBA under any circumstances.

Fixes: ee94743034 ("linux-user: completely re-write init_guest_space")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2157
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reported-by: Alexey Sheplyakov <asheplyakov@yandex.ru>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit b816e1b5ba)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-05 17:41:31 +03:00
Richard Henderson 151d593c7d tcg/aarch64: Apple does not align __int128_t in even registers
From https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms

  When passing an argument with 16-byte alignment in integer registers,
  Apple platforms allow the argument to start in an odd-numbered xN
  register. The standard ABI requires it to begin in an even-numbered
  xN register.

Cc: qemu-stable@nongnu.org
Fixes: 5427a9a760 ("tcg: Add TCG_TARGET_CALL_{RET,ARG}_I128")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2169
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <9fc0c2c7-dd57-459e-aecb-528edb74b4a7@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 7f89fdf8eb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-05 17:38:26 +03:00
Paolo Bonzini 16f1f95ebd configure: run plugin TCG tests again
Commit 39fb3cfc28 ("configure: clean up plugin option handling", 2023-10-18)
dropped the CONFIG_PLUGIN line from tests/tcg/config-host.mak, due to confusion
caused by the shadowing of $config_host_mak.  However, TCG tests were still
expecting it.  Oops.

Put it back, in the meanwhile the shadowing is gone so it's clear that it goes
in the tests/tcg configuration.

Cc:  <alex.bennee@linaro.org>
Fixes: 39fb3cfc28 ("configure: clean up plugin option handling", 2023-10-18)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20240124115332.612162-1-pbonzini@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20240207163812.3231697-4-alex.bennee@linaro.org>
(cherry picked from commit 15cc103362)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: fixup for 8.2.x - $config_host_mak without tests/tcg/ prefix -
 for before v8.2.0-142-g606c3ba7a2 "configure: remove unnecessary subshell")
2024-03-05 00:44:20 +03:00
Michael Tokarev eae7509be9 Revert "configure: run plugin TCG tests again"
This reverts commit 6eeeb87331.

This commit has been wrongly back-ported to 8.2.x, $config_host_mak
in master didn't include the tests/tcg/ prefix, while 8.2.0 did it.
The result of this "backport" is this message during configure:

 ../configure: 1679: cannot create tests/tcg/tests/tcg/config-host.mak: Directory nonexistent

Let's revert the change and try again.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-03-05 00:42:22 +03:00
182 changed files with 3095 additions and 1206 deletions
+3 -3
View File
@@ -25,10 +25,10 @@
then
pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
fi || exit 1;
- make -j"$JOBS"
- $MAKE -j"$JOBS"
- if test -n "$MAKE_CHECK_ARGS";
then
make -j"$JOBS" $MAKE_CHECK_ARGS ;
$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
fi
- ccache --show-stats
@@ -59,7 +59,7 @@
- cd build
- find . -type f -exec touch {} +
# Avoid recompiling by hiding ninja with NINJA=":"
- make NINJA=":" $MAKE_CHECK_ARGS
- $MAKE NINJA=":" $MAKE_CHECK_ARGS
.native_test_job_template:
extends: .common_test_job_template
+11 -8
View File
@@ -158,9 +158,9 @@ build-system-centos:
- .native_build_job_template
- .native_build_artifact_template
needs:
job: amd64-centos8-container
job: amd64-centos9-container
variables:
IMAGE: centos8
IMAGE: centos9
CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-vfio-user-server
--enable-modules --enable-trace-backends=dtrace --enable-docs
TARGETS: ppc64-softmmu or1k-softmmu s390x-softmmu
@@ -173,7 +173,7 @@ check-system-centos:
- job: build-system-centos
artifacts: true
variables:
IMAGE: centos8
IMAGE: centos9
MAKE_CHECK_ARGS: check
avocado-system-centos:
@@ -182,7 +182,7 @@ avocado-system-centos:
- job: build-system-centos
artifacts: true
variables:
IMAGE: centos8
IMAGE: centos9
MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:ppc64 arch:or1k arch:390x arch:x86_64 arch:rx
arch:sh4 arch:nios2
@@ -258,9 +258,9 @@ avocado-system-flaky:
build-tcg-disabled:
extends: .native_build_job_template
needs:
job: amd64-centos8-container
job: amd64-centos9-container
variables:
IMAGE: centos8
IMAGE: centos9
script:
- mkdir build
- cd build
@@ -506,6 +506,9 @@ tsan-build:
CONFIGURE_ARGS: --enable-tsan --cc=clang --cxx=clang++
--enable-trace-backends=ust --disable-slirp
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
# Remove when we switch to a distro with clang >= 18
# https://github.com/google/sanitizers/issues/1716
MAKE: setarch -R make
# gcov is a GCC features
gcov:
@@ -582,9 +585,9 @@ build-tci:
build-without-defaults:
extends: .native_build_job_template
needs:
job: amd64-centos8-container
job: amd64-centos9-container
variables:
IMAGE: centos8
IMAGE: centos9
CONFIGURE_ARGS:
--without-default-devices
--without-default-features
+4 -2
View File
@@ -13,7 +13,7 @@
.cirrus_build_job:
extends: .base_job_template
stage: build
image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:master
image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:latest
needs: []
# 20 mins larger than "timeout_in" in cirrus/build.yml
# as there's often a 5-10 minute delay before Cirrus CI
@@ -52,11 +52,12 @@ x64-freebsd-13-build:
NAME: freebsd-13
CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
CIRRUS_VM_IMAGE_SELECTOR: image_family
CIRRUS_VM_IMAGE_NAME: freebsd-13-2
CIRRUS_VM_IMAGE_NAME: freebsd-13-3
CIRRUS_VM_CPUS: 8
CIRRUS_VM_RAM: 8G
UPDATE_COMMAND: pkg update; pkg upgrade -y
INSTALL_COMMAND: pkg install -y
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblaze-softmmu,mips64el-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4eb-softmmu,xtensa-softmmu
TEST_TARGETS: check
aarch64-macos-13-base-build:
@@ -72,6 +73,7 @@ aarch64-macos-13-base-build:
INSTALL_COMMAND: brew install
PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblazeel-softmmu,mips64-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4-softmmu,xtensaeb-softmmu
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
aarch64-macos-14-base-build:
+2 -2
View File
@@ -1,10 +1,10 @@
include:
- local: '/.gitlab-ci.d/container-template.yml'
amd64-centos8-container:
amd64-centos9-container:
extends: .container_job_template
variables:
NAME: centos8
NAME: centos9
amd64-fedora-container:
extends: .container_job_template
+1 -3
View File
@@ -1,9 +1,7 @@
.shared_msys2_builder:
extends: .base_job_template
tags:
- shared-windows
- windows
- windows-1809
- saas-windows-medium-amd64
cache:
key: "$CI_JOB_NAME"
paths:
+1 -1
View File
@@ -1 +1 @@
8.2.2
8.2.6
+2 -2
View File
@@ -712,7 +712,7 @@ static void tb_record(TranslationBlock *tb)
tb_page_addr_t paddr0 = tb_page_addr0(tb);
tb_page_addr_t paddr1 = tb_page_addr1(tb);
tb_page_addr_t pindex0 = paddr0 >> TARGET_PAGE_BITS;
tb_page_addr_t pindex1 = paddr0 >> TARGET_PAGE_BITS;
tb_page_addr_t pindex1 = paddr1 >> TARGET_PAGE_BITS;
assert(paddr0 != -1);
if (unlikely(paddr1 != -1) && pindex0 != pindex1) {
@@ -744,7 +744,7 @@ static void tb_remove(TranslationBlock *tb)
tb_page_addr_t paddr0 = tb_page_addr0(tb);
tb_page_addr_t paddr1 = tb_page_addr1(tb);
tb_page_addr_t pindex0 = paddr0 >> TARGET_PAGE_BITS;
tb_page_addr_t pindex1 = paddr0 >> TARGET_PAGE_BITS;
tb_page_addr_t pindex1 = paddr1 >> TARGET_PAGE_BITS;
assert(paddr0 != -1);
if (unlikely(paddr1 != -1) && pindex0 != pindex1) {
+8 -5
View File
@@ -23,6 +23,7 @@
#include "qemu/osdep.h"
#include "sysemu/cryptodev.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "standard-headers/linux/virtio_crypto.h"
#include "crypto/cipher.h"
@@ -396,8 +397,8 @@ static int cryptodev_builtin_create_session(
case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
default:
error_setg(&local_error, "Unsupported opcode :%" PRIu32 "",
sess_info->op_code);
error_report("Unsupported opcode :%" PRIu32 "",
sess_info->op_code);
return -VIRTIO_CRYPTO_NOTSUPP;
}
@@ -427,7 +428,9 @@ static int cryptodev_builtin_close_session(
CRYPTODEV_BACKEND_BUILTIN(backend);
CryptoDevBackendBuiltinSession *session;
assert(session_id < MAX_NUM_SESSIONS && builtin->sessions[session_id]);
if (session_id >= MAX_NUM_SESSIONS || !builtin->sessions[session_id]) {
return -VIRTIO_CRYPTO_INVSESS;
}
session = builtin->sessions[session_id];
if (session->cipher) {
@@ -552,8 +555,8 @@ static int cryptodev_builtin_operation(
if (op_info->session_id >= MAX_NUM_SESSIONS ||
builtin->sessions[op_info->session_id] == NULL) {
error_setg(&local_error, "Cannot find a valid session id: %" PRIu64 "",
op_info->session_id);
error_report("Cannot find a valid session id: %" PRIu64 "",
op_info->session_id);
return -VIRTIO_CRYPTO_INVSESS;
}
+61 -37
View File
@@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
BlockDriverState *parent,
const BdrvChildClass *child_class,
BdrvChildRole child_role,
bool parse_filename,
Error **errp);
static bool bdrv_recurse_has_child(BlockDriverState *bs,
@@ -2047,7 +2048,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
* block driver has been specified explicitly.
*/
static int bdrv_fill_options(QDict **options, const char *filename,
int *flags, Error **errp)
int *flags, bool allow_parse_filename,
Error **errp)
{
const char *drvname;
bool protocol = *flags & BDRV_O_PROTOCOL;
@@ -2089,7 +2091,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
if (protocol && filename) {
if (!qdict_haskey(*options, "filename")) {
qdict_put_str(*options, "filename", filename);
parse_filename = true;
parse_filename = allow_parse_filename;
} else {
error_setg(errp, "Can't specify 'file' and 'filename' options at "
"the same time");
@@ -3675,7 +3677,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
}
backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
&child_of_bds, bdrv_backing_role(bs), errp);
&child_of_bds, bdrv_backing_role(bs), true,
errp);
if (!backing_hd) {
bs->open_flags |= BDRV_O_NO_BACKING;
error_prepend(errp, "Could not open backing file: ");
@@ -3712,7 +3715,8 @@ free_exit:
static BlockDriverState *
bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
BlockDriverState *parent, const BdrvChildClass *child_class,
BdrvChildRole child_role, bool allow_none, Error **errp)
BdrvChildRole child_role, bool allow_none,
bool parse_filename, Error **errp)
{
BlockDriverState *bs = NULL;
QDict *image_options;
@@ -3743,7 +3747,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
}
bs = bdrv_open_inherit(filename, reference, image_options, 0,
parent, child_class, child_role, errp);
parent, child_class, child_role, parse_filename,
errp);
if (!bs) {
goto done;
}
@@ -3753,6 +3758,37 @@ done:
return bs;
}
static BdrvChild *bdrv_open_child_common(const char *filename,
QDict *options, const char *bdref_key,
BlockDriverState *parent,
const BdrvChildClass *child_class,
BdrvChildRole child_role,
bool allow_none, bool parse_filename,
Error **errp)
{
BlockDriverState *bs;
BdrvChild *child;
AioContext *ctx;
GLOBAL_STATE_CODE();
bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
child_role, allow_none, parse_filename, errp);
if (bs == NULL) {
return NULL;
}
bdrv_graph_wrlock(NULL);
ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
errp);
aio_context_release(ctx);
bdrv_graph_wrunlock(NULL);
return child;
}
/*
* Opens a disk image whose options are given as BlockdevRef in another block
* device's options.
@@ -3778,31 +3814,15 @@ BdrvChild *bdrv_open_child(const char *filename,
BdrvChildRole child_role,
bool allow_none, Error **errp)
{
BlockDriverState *bs;
BdrvChild *child;
AioContext *ctx;
GLOBAL_STATE_CODE();
bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
child_role, allow_none, errp);
if (bs == NULL) {
return NULL;
}
bdrv_graph_wrlock(NULL);
ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
errp);
aio_context_release(ctx);
bdrv_graph_wrunlock(NULL);
return child;
return bdrv_open_child_common(filename, options, bdref_key, parent,
child_class, child_role, allow_none, false,
errp);
}
/*
* Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
* This does mostly the same as bdrv_open_child(), but for opening the primary
* child of a node. A notable difference from bdrv_open_child() is that it
* enables filename parsing for protocol names (including json:).
*
* The caller must hold the lock of the main AioContext and no other AioContext.
* @parent can move to a different AioContext in this function. Callers must
@@ -3819,8 +3839,8 @@ int bdrv_open_file_child(const char *filename,
role = parent->drv->is_filter ?
(BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
if (!bdrv_open_child(filename, options, bdref_key, parent,
&child_of_bds, role, false, errp))
if (!bdrv_open_child_common(filename, options, bdref_key, parent,
&child_of_bds, role, false, true, errp))
{
return -EINVAL;
}
@@ -3865,7 +3885,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
}
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp);
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false,
errp);
obj = NULL;
qobject_unref(obj);
visit_free(v);
@@ -3962,7 +3983,7 @@ static BlockDriverState * no_coroutine_fn
bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
int flags, BlockDriverState *parent,
const BdrvChildClass *child_class, BdrvChildRole child_role,
Error **errp)
bool parse_filename, Error **errp)
{
int ret;
BlockBackend *file = NULL;
@@ -4011,9 +4032,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
}
/* json: syntax counts as explicit options, as if in the QDict */
parse_json_protocol(options, &filename, &local_err);
if (local_err) {
goto fail;
if (parse_filename) {
parse_json_protocol(options, &filename, &local_err);
if (local_err) {
goto fail;
}
}
bs->explicit_options = qdict_clone_shallow(options);
@@ -4038,7 +4061,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
parent->open_flags, parent->options);
}
ret = bdrv_fill_options(&options, filename, &flags, &local_err);
ret = bdrv_fill_options(&options, filename, &flags, parse_filename,
&local_err);
if (ret < 0) {
goto fail;
}
@@ -4107,7 +4131,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
file_bs = bdrv_open_child_bs(filename, options, "file", bs,
&child_of_bds, BDRV_CHILD_IMAGE,
true, &local_err);
true, true, &local_err);
if (local_err) {
goto fail;
}
@@ -4270,7 +4294,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
GLOBAL_STATE_CODE();
return bdrv_open_inherit(filename, reference, options, flags, NULL,
NULL, 0, errp);
NULL, 0, true, errp);
}
/* Return true if the NULL-terminated @list contains @str */
+7 -11
View File
@@ -613,14 +613,14 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it)
/* Must be called from the main loop */
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
old_bs = it->bs;
/* First, return all root nodes of BlockBackends. In order to avoid
* returning a BDS twice when multiple BBs refer to it, we only return it
* if the BB is the first one in the parent list of the BDS. */
if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
BlockBackend *old_blk = it->blk;
old_bs = old_blk ? blk_bs(old_blk) : NULL;
do {
it->blk = blk_all_next(it->blk);
bs = it->blk ? blk_bs(it->blk) : NULL;
@@ -634,11 +634,10 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it)
if (bs) {
bdrv_ref(bs);
bdrv_unref(old_bs);
it->bs = bs;
return bs;
}
it->phase = BDRV_NEXT_MONITOR_OWNED;
} else {
old_bs = it->bs;
}
/* Then return the monitor-owned BDSes without a BB attached. Ignore all
@@ -678,13 +677,10 @@ void bdrv_next_cleanup(BdrvNextIterator *it)
/* Must be called from the main loop */
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
if (it->blk) {
bdrv_unref(blk_bs(it->blk));
blk_unref(it->blk);
}
} else {
bdrv_unref(it->bs);
bdrv_unref(it->bs);
if (it->phase == BDRV_NEXT_BACKEND_ROOTS && it->blk) {
blk_unref(it->blk);
}
bdrv_next_reset(it);
+19 -12
View File
@@ -1756,22 +1756,29 @@ static int bdrv_pad_request(BlockDriverState *bs,
return 0;
}
sliced_iov = qemu_iovec_slice(*qiov, *qiov_offset, *bytes,
&sliced_head, &sliced_tail,
&sliced_niov);
/*
* For prefetching in stream_populate(), no qiov is passed along, because
* only copy-on-read matters.
*/
if (qiov && *qiov) {
sliced_iov = qemu_iovec_slice(*qiov, *qiov_offset, *bytes,
&sliced_head, &sliced_tail,
&sliced_niov);
/* Guaranteed by bdrv_check_request32() */
assert(*bytes <= SIZE_MAX);
ret = bdrv_create_padded_qiov(bs, pad, sliced_iov, sliced_niov,
sliced_head, *bytes);
if (ret < 0) {
bdrv_padding_finalize(pad);
return ret;
/* Guaranteed by bdrv_check_request32() */
assert(*bytes <= SIZE_MAX);
ret = bdrv_create_padded_qiov(bs, pad, sliced_iov, sliced_niov,
sliced_head, *bytes);
if (ret < 0) {
bdrv_padding_finalize(pad);
return ret;
}
*qiov = &pad->local_qiov;
*qiov_offset = 0;
}
*bytes += pad->head + pad->tail;
*offset -= pad->head;
*qiov = &pad->local_qiov;
*qiov_offset = 0;
if (padded) {
*padded = true;
}
+6 -4
View File
@@ -479,9 +479,9 @@ static unsigned mirror_perform(MirrorBlockJob *s, int64_t offset,
return bytes_handled;
}
static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s)
static void coroutine_fn GRAPH_UNLOCKED mirror_iteration(MirrorBlockJob *s)
{
BlockDriverState *source = s->mirror_top_bs->backing->bs;
BlockDriverState *source;
MirrorOp *pseudo_op;
int64_t offset;
/* At least the first dirty chunk is mirrored in one iteration. */
@@ -489,6 +489,10 @@ static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s)
bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target));
int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
bdrv_graph_co_rdlock();
source = s->mirror_top_bs->backing->bs;
bdrv_graph_co_rdunlock();
bdrv_dirty_bitmap_lock(s->dirty_bitmap);
offset = bdrv_dirty_iter_next(s->dbi);
if (offset < 0) {
@@ -1078,9 +1082,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
mirror_wait_for_free_in_flight_slot(s);
continue;
} else if (cnt != 0) {
bdrv_graph_co_rdlock();
mirror_iteration(s);
bdrv_graph_co_rdunlock();
}
}
+16 -1
View File
@@ -1636,7 +1636,22 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
if (open_data_file) {
if (open_data_file && (flags & BDRV_O_NO_IO)) {
/*
* Don't open the data file for 'qemu-img info' so that it can be used
* to verify that an untrusted qcow2 image doesn't refer to external
* files.
*
* Note: This still makes has_data_file() return true.
*/
if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
s->data_file = NULL;
} else {
s->data_file = bs->file;
}
qdict_extract_subqdict(options, NULL, "data-file.");
qdict_del(options, "data-file");
} else if (open_data_file) {
/* Open external data file */
bdrv_graph_co_rdunlock();
s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs,
+3 -3
View File
@@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
s->max_size <= 0) {
return TRUE;
}
len = tcp_chr_read_poll(opaque);
if (len > sizeof(buf)) {
len = sizeof(buf);
len = sizeof(buf);
if (len > s->max_size) {
len = s->max_size;
}
size = tcp_chr_recv(chr, (void *)buf, len);
if (size == 0 || (size == -1 && errno != EAGAIN)) {
+4
View File
@@ -41,6 +41,7 @@
/* init terminal so that we can grab keys */
static struct termios oldtty;
static int old_fd0_flags;
static int old_fd1_flags;
static bool stdio_in_use;
static bool stdio_allow_signal;
static bool stdio_echo_state;
@@ -50,6 +51,8 @@ static void term_exit(void)
if (stdio_in_use) {
tcsetattr(0, TCSANOW, &oldtty);
fcntl(0, F_SETFL, old_fd0_flags);
fcntl(1, F_SETFL, old_fd1_flags);
stdio_in_use = false;
}
}
@@ -102,6 +105,7 @@ static void qemu_chr_open_stdio(Chardev *chr,
stdio_in_use = true;
old_fd0_flags = fcntl(0, F_GETFL);
old_fd1_flags = fcntl(1, F_GETFL);
tcgetattr(0, &oldtty);
if (!g_unix_set_fd_nonblocking(0, true, NULL)) {
error_setg_errno(errp, errno, "Failed to set FD nonblocking");
Vendored
+12 -3
View File
@@ -411,7 +411,9 @@ else
# Using uname is really broken, but it is just a fallback for architectures
# that are going to use TCI anyway
cpu=$(uname -m)
echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output '$cpu'"
if test "$host_os" != "bogus"; then
echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output '$cpu'"
fi
fi
# Normalise host CPU name to the values used by Meson cross files and in source
@@ -761,7 +763,7 @@ for opt do
--*) meson_option_parse "$opt" "$optarg"
;;
# Pass through -Dxxxx options to meson
-D*) meson_options="$meson_options $opt"
-D*) meson_option_add "$opt"
;;
esac
done
@@ -893,6 +895,13 @@ EOF
exit 0
fi
# Now that we are sure that the user did not only want to print the --help
# information, we should double-check that the C compiler really works:
write_c_skeleton
if ! compile_object ; then
error_exit "C compiler \"$cc\" either does not exist or does not work."
fi
# Remove old dependency files to make sure that they get properly regenerated
rm -f ./*/config-devices.mak.d
@@ -1676,7 +1685,7 @@ mkdir -p tests/tcg
echo "# Automatically generated by configure - do not modify" > $config_host_mak
echo "SRC_PATH=$source_path" >> $config_host_mak
if test "$plugins" = "yes" ; then
echo "CONFIG_PLUGIN=y" >> tests/tcg/$config_host_mak
echo "CONFIG_PLUGIN=y" >> $config_host_mak
fi
tcg_tests_targets=
+64 -1
View File
@@ -2184,7 +2184,22 @@ static const char *csr_name(int csrno)
case 0x0383: return "mibound";
case 0x0384: return "mdbase";
case 0x0385: return "mdbound";
case 0x03a0: return "pmpcfg3";
case 0x03a0: return "pmpcfg0";
case 0x03a1: return "pmpcfg1";
case 0x03a2: return "pmpcfg2";
case 0x03a3: return "pmpcfg3";
case 0x03a4: return "pmpcfg4";
case 0x03a5: return "pmpcfg5";
case 0x03a6: return "pmpcfg6";
case 0x03a7: return "pmpcfg7";
case 0x03a8: return "pmpcfg8";
case 0x03a9: return "pmpcfg9";
case 0x03aa: return "pmpcfg10";
case 0x03ab: return "pmpcfg11";
case 0x03ac: return "pmpcfg12";
case 0x03ad: return "pmpcfg13";
case 0x03ae: return "pmpcfg14";
case 0x03af: return "pmpcfg15";
case 0x03b0: return "pmpaddr0";
case 0x03b1: return "pmpaddr1";
case 0x03b2: return "pmpaddr2";
@@ -2201,6 +2216,54 @@ static const char *csr_name(int csrno)
case 0x03bd: return "pmpaddr13";
case 0x03be: return "pmpaddr14";
case 0x03bf: return "pmpaddr15";
case 0x03c0: return "pmpaddr16";
case 0x03c1: return "pmpaddr17";
case 0x03c2: return "pmpaddr18";
case 0x03c3: return "pmpaddr19";
case 0x03c4: return "pmpaddr20";
case 0x03c5: return "pmpaddr21";
case 0x03c6: return "pmpaddr22";
case 0x03c7: return "pmpaddr23";
case 0x03c8: return "pmpaddr24";
case 0x03c9: return "pmpaddr25";
case 0x03ca: return "pmpaddr26";
case 0x03cb: return "pmpaddr27";
case 0x03cc: return "pmpaddr28";
case 0x03cd: return "pmpaddr29";
case 0x03ce: return "pmpaddr30";
case 0x03cf: return "pmpaddr31";
case 0x03d0: return "pmpaddr32";
case 0x03d1: return "pmpaddr33";
case 0x03d2: return "pmpaddr34";
case 0x03d3: return "pmpaddr35";
case 0x03d4: return "pmpaddr36";
case 0x03d5: return "pmpaddr37";
case 0x03d6: return "pmpaddr38";
case 0x03d7: return "pmpaddr39";
case 0x03d8: return "pmpaddr40";
case 0x03d9: return "pmpaddr41";
case 0x03da: return "pmpaddr42";
case 0x03db: return "pmpaddr43";
case 0x03dc: return "pmpaddr44";
case 0x03dd: return "pmpaddr45";
case 0x03de: return "pmpaddr46";
case 0x03df: return "pmpaddr47";
case 0x03e0: return "pmpaddr48";
case 0x03e1: return "pmpaddr49";
case 0x03e2: return "pmpaddr50";
case 0x03e3: return "pmpaddr51";
case 0x03e4: return "pmpaddr52";
case 0x03e5: return "pmpaddr53";
case 0x03e6: return "pmpaddr54";
case 0x03e7: return "pmpaddr55";
case 0x03e8: return "pmpaddr56";
case 0x03e9: return "pmpaddr57";
case 0x03ea: return "pmpaddr58";
case 0x03eb: return "pmpaddr59";
case 0x03ec: return "pmpaddr60";
case 0x03ed: return "pmpaddr61";
case 0x03ee: return "pmpaddr62";
case 0x03ef: return "pmpaddr63";
case 0x0780: return "mtohost";
case 0x0781: return "mfromhost";
case 0x0782: return "mreset";
+4 -6
View File
@@ -29,7 +29,6 @@
import os
import sys
import sphinx
from distutils.version import LooseVersion
from sphinx.errors import ConfigError
# The per-manual conf.py will set qemu_docdir for a single-manual build;
@@ -165,11 +164,10 @@ html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
if LooseVersion(sphinx_rtd_theme.__version__) >= LooseVersion("0.4.3"):
html_theme_options = {
"style_nav_header_background": "#802400",
"navigation_with_keys": True,
}
html_theme_options = {
"style_nav_header_background": "#802400",
"navigation_with_keys": True,
}
html_logo = os.path.join(qemu_docdir, "../ui/icons/qemu_128x128.png")
+5 -7
View File
@@ -229,15 +229,15 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor):
section += dlnode
return [section]
def _nodes_for_arguments(self, doc, boxed_arg_type):
def _nodes_for_arguments(self, doc, arg_type):
"""Return list of doctree nodes for the arguments section"""
if boxed_arg_type:
if arg_type and not arg_type.is_implicit():
assert not doc.args
section = self._make_section('Arguments')
dlnode = nodes.definition_list()
dlnode += self._make_dlitem(
[nodes.Text('The members of '),
nodes.literal('', boxed_arg_type.name)],
nodes.literal('', arg_type.name)],
None)
section += dlnode
return [section]
@@ -341,8 +341,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor):
allow_preconfig, coroutine):
doc = self._cur_doc
self._add_doc('Command',
self._nodes_for_arguments(doc,
arg_type if boxed else None)
self._nodes_for_arguments(doc, arg_type)
+ self._nodes_for_features(doc)
+ self._nodes_for_sections(doc)
+ self._nodes_for_if_section(ifcond))
@@ -350,8 +349,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor):
def visit_event(self, name, info, ifcond, features, arg_type, boxed):
doc = self._cur_doc
self._add_doc('Event',
self._nodes_for_arguments(doc,
arg_type if boxed else None)
self._nodes_for_arguments(doc, arg_type)
+ self._nodes_for_features(doc)
+ self._nodes_for_sections(doc)
+ self._nodes_for_if_section(ifcond))
+5 -1
View File
@@ -78,6 +78,7 @@ static void build_hmat_lb(GArray *table_data, HMAT_LB_Info *hmat_lb,
uint32_t *initiator_list)
{
int i, index;
uint32_t initiator_to_index[MAX_NODES] = {};
HMAT_LB_Data *lb_data;
uint16_t *entry_list;
uint32_t base;
@@ -121,6 +122,8 @@ static void build_hmat_lb(GArray *table_data, HMAT_LB_Info *hmat_lb,
/* Initiator Proximity Domain List */
for (i = 0; i < num_initiator; i++) {
build_append_int_noprefix(table_data, initiator_list[i], 4);
/* Reverse mapping for array possitions */
initiator_to_index[initiator_list[i]] = i;
}
/* Target Proximity Domain List */
@@ -132,7 +135,8 @@ static void build_hmat_lb(GArray *table_data, HMAT_LB_Info *hmat_lb,
entry_list = g_new0(uint16_t, num_initiator * num_target);
for (i = 0; i < hmat_lb->list->len; i++) {
lb_data = &g_array_index(hmat_lb->list, HMAT_LB_Data, i);
index = lb_data->initiator * num_target + lb_data->target;
index = initiator_to_index[lb_data->initiator] * num_target +
lb_data->target;
entry_list[index] = (uint16_t)(lb_data->data / hmat_lb->base);
}
+2 -1
View File
@@ -24,6 +24,7 @@
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/bswap.h"
#include "qemu/units.h"
#include "sysemu/sysemu.h"
@@ -377,7 +378,7 @@ static void npcm7xx_init_fuses(NPCM7xxState *s)
* The initial mask of disabled modules indicates the chip derivative (e.g.
* NPCM750 or NPCM730).
*/
value = tswap32(nc->disabled_modules);
value = cpu_to_le32(nc->disabled_modules);
npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
sizeof(value));
}
+66 -72
View File
@@ -243,12 +243,13 @@ static void virtio_snd_handle_pcm_info(VirtIOSound *s,
memset(&pcm_info[i].padding, 0, 5);
}
cmd->payload_size = sizeof(virtio_snd_pcm_info) * count;
cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_OK);
iov_from_buf(cmd->elem->in_sg,
cmd->elem->in_num,
sizeof(virtio_snd_hdr),
pcm_info,
sizeof(virtio_snd_pcm_info) * count);
cmd->payload_size);
}
/*
@@ -400,7 +401,7 @@ static void virtio_snd_get_qemu_audsettings(audsettings *as,
as->nchannels = MIN(AUDIO_MAX_CHANNELS, params->channels);
as->fmt = virtio_snd_get_qemu_format(params->format);
as->freq = virtio_snd_get_qemu_freq(params->rate);
as->endianness = target_words_bigendian() ? 1 : 0;
as->endianness = 0; /* Conforming to VIRTIO 1.0: always little endian. */
}
/*
@@ -455,7 +456,6 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
stream->s = s;
qemu_mutex_init(&stream->queue_mutex);
QSIMPLEQ_INIT(&stream->queue);
QSIMPLEQ_INIT(&stream->invalid);
/*
* stream_id >= s->snd_conf.streams was checked before so this is
@@ -610,9 +610,6 @@ static size_t virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream *stream)
QSIMPLEQ_FOREACH_SAFE(buffer, &stream->queue, entry, next) {
count += 1;
}
QSIMPLEQ_FOREACH_SAFE(buffer, &stream->invalid, entry, next) {
count += 1;
}
}
return count;
}
@@ -749,7 +746,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd)
0,
&cmd->resp,
sizeof(virtio_snd_hdr));
virtqueue_push(cmd->vq, cmd->elem, sizeof(virtio_snd_hdr));
virtqueue_push(cmd->vq, cmd->elem,
sizeof(virtio_snd_hdr) + cmd->payload_size);
virtio_notify(VIRTIO_DEVICE(s), cmd->vq);
}
@@ -808,6 +806,7 @@ static void virtio_snd_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
cmd->elem = elem;
cmd->vq = vq;
cmd->resp.code = cpu_to_le32(VIRTIO_SND_S_OK);
/* implicit cmd->payload_size = 0; */
QTAILQ_INSERT_TAIL(&s->cmdq, cmd, next);
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
}
@@ -828,47 +827,36 @@ static void virtio_snd_handle_event(VirtIODevice *vdev, VirtQueue *vq)
trace_virtio_snd_handle_event();
}
/*
* Must only be called if vsnd->invalid is not empty.
*/
static inline void empty_invalid_queue(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSoundPCMBuffer *buffer = NULL;
VirtIOSoundPCMStream *stream = NULL;
virtio_snd_pcm_status resp = { 0 };
VirtIOSound *vsnd = VIRTIO_SND(vdev);
bool any = false;
for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
stream = vsnd->pcm->streams[i];
if (stream) {
any = false;
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
while (!QSIMPLEQ_EMPTY(&stream->invalid)) {
buffer = QSIMPLEQ_FIRST(&stream->invalid);
if (buffer->vq != vq) {
break;
}
any = true;
resp.status = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
iov_from_buf(buffer->elem->in_sg,
buffer->elem->in_num,
0,
&resp,
sizeof(virtio_snd_pcm_status));
virtqueue_push(vq,
buffer->elem,
sizeof(virtio_snd_pcm_status));
QSIMPLEQ_REMOVE_HEAD(&stream->invalid, entry);
virtio_snd_pcm_buffer_free(buffer);
}
if (any) {
/*
* Notify vq about virtio_snd_pcm_status responses.
* Buffer responses must be notified separately later.
*/
virtio_notify(vdev, vq);
}
}
}
g_assert(!QSIMPLEQ_EMPTY(&vsnd->invalid));
while (!QSIMPLEQ_EMPTY(&vsnd->invalid)) {
buffer = QSIMPLEQ_FIRST(&vsnd->invalid);
/* If buffer->vq != vq, our logic is fundamentally wrong, so bail out */
g_assert(buffer->vq == vq);
resp.status = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
iov_from_buf(buffer->elem->in_sg,
buffer->elem->in_num,
0,
&resp,
sizeof(virtio_snd_pcm_status));
virtqueue_push(vq,
buffer->elem,
sizeof(virtio_snd_pcm_status));
QSIMPLEQ_REMOVE_HEAD(&vsnd->invalid, entry);
virtio_snd_pcm_buffer_free(buffer);
}
/* Notify vq about virtio_snd_pcm_status responses. */
virtio_notify(vdev, vq);
}
/*
@@ -880,15 +868,14 @@ static inline void empty_invalid_queue(VirtIODevice *vdev, VirtQueue *vq)
*/
static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSound *s = VIRTIO_SND(vdev);
VirtIOSoundPCMStream *stream = NULL;
VirtIOSound *vsnd = VIRTIO_SND(vdev);
VirtIOSoundPCMBuffer *buffer;
VirtQueueElement *elem;
size_t msg_sz, size;
virtio_snd_pcm_xfer hdr;
uint32_t stream_id;
/*
* If any of the I/O messages are invalid, put them in stream->invalid and
* If any of the I/O messages are invalid, put them in vsnd->invalid and
* return them after the for loop.
*/
bool must_empty_invalid_queue = false;
@@ -899,6 +886,8 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
trace_virtio_snd_handle_tx_xfer();
for (;;) {
VirtIOSoundPCMStream *stream;
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
if (!elem) {
break;
@@ -914,12 +903,12 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
}
stream_id = le32_to_cpu(hdr.stream_id);
if (stream_id >= s->snd_conf.streams
|| s->pcm->streams[stream_id] == NULL) {
if (stream_id >= vsnd->snd_conf.streams
|| vsnd->pcm->streams[stream_id] == NULL) {
goto tx_err;
}
stream = s->pcm->streams[stream_id];
stream = vsnd->pcm->streams[stream_id];
if (stream->info.direction != VIRTIO_SND_D_OUTPUT) {
goto tx_err;
}
@@ -939,13 +928,11 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
continue;
tx_err:
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
must_empty_invalid_queue = true;
buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
buffer->elem = elem;
buffer->vq = vq;
QSIMPLEQ_INSERT_TAIL(&stream->invalid, buffer, entry);
}
must_empty_invalid_queue = true;
buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
buffer->elem = elem;
buffer->vq = vq;
QSIMPLEQ_INSERT_TAIL(&vsnd->invalid, buffer, entry);
}
if (must_empty_invalid_queue) {
@@ -962,15 +949,14 @@ tx_err:
*/
static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSound *s = VIRTIO_SND(vdev);
VirtIOSoundPCMStream *stream = NULL;
VirtIOSound *vsnd = VIRTIO_SND(vdev);
VirtIOSoundPCMBuffer *buffer;
VirtQueueElement *elem;
size_t msg_sz, size;
virtio_snd_pcm_xfer hdr;
uint32_t stream_id;
/*
* if any of the I/O messages are invalid, put them in stream->invalid and
* if any of the I/O messages are invalid, put them in vsnd->invalid and
* return them after the for loop.
*/
bool must_empty_invalid_queue = false;
@@ -981,6 +967,8 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
trace_virtio_snd_handle_rx_xfer();
for (;;) {
VirtIOSoundPCMStream *stream;
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
if (!elem) {
break;
@@ -996,12 +984,12 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
}
stream_id = le32_to_cpu(hdr.stream_id);
if (stream_id >= s->snd_conf.streams
|| !s->pcm->streams[stream_id]) {
if (stream_id >= vsnd->snd_conf.streams
|| !vsnd->pcm->streams[stream_id]) {
goto rx_err;
}
stream = s->pcm->streams[stream_id];
stream = vsnd->pcm->streams[stream_id];
if (stream == NULL || stream->info.direction != VIRTIO_SND_D_INPUT) {
goto rx_err;
}
@@ -1018,13 +1006,11 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
continue;
rx_err:
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
must_empty_invalid_queue = true;
buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
buffer->elem = elem;
buffer->vq = vq;
QSIMPLEQ_INSERT_TAIL(&stream->invalid, buffer, entry);
}
must_empty_invalid_queue = true;
buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
buffer->elem = elem;
buffer->vq = vq;
QSIMPLEQ_INSERT_TAIL(&vsnd->invalid, buffer, entry);
}
if (must_empty_invalid_queue) {
@@ -1124,6 +1110,7 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
virtio_add_queue(vdev, 64, virtio_snd_handle_rx_xfer);
qemu_mutex_init(&vsnd->cmdq_mutex);
QTAILQ_INIT(&vsnd->cmdq);
QSIMPLEQ_INIT(&vsnd->invalid);
for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
status = virtio_snd_set_pcm_params(vsnd, i, &default_params);
@@ -1373,13 +1360,20 @@ static void virtio_snd_unrealize(DeviceState *dev)
static void virtio_snd_reset(VirtIODevice *vdev)
{
VirtIOSound *s = VIRTIO_SND(vdev);
VirtIOSound *vsnd = VIRTIO_SND(vdev);
virtio_snd_ctrl_command *cmd;
WITH_QEMU_LOCK_GUARD(&s->cmdq_mutex) {
while (!QTAILQ_EMPTY(&s->cmdq)) {
cmd = QTAILQ_FIRST(&s->cmdq);
QTAILQ_REMOVE(&s->cmdq, cmd, next);
/*
* Sanity check that the invalid buffer message queue is emptied at the end
* of every virtio_snd_handle_tx_xfer/virtio_snd_handle_rx_xfer call, and
* must be empty otherwise.
*/
g_assert(QSIMPLEQ_EMPTY(&vsnd->invalid));
WITH_QEMU_LOCK_GUARD(&vsnd->cmdq_mutex) {
while (!QTAILQ_EMPTY(&vsnd->cmdq)) {
cmd = QTAILQ_FIRST(&vsnd->cmdq);
QTAILQ_REMOVE(&vsnd->cmdq, cmd, next);
virtio_snd_ctrl_cmd_free(cmd);
}
}
+38 -17
View File
@@ -84,7 +84,11 @@ struct NANDFlashState {
void (*blk_write)(NANDFlashState *s);
void (*blk_erase)(NANDFlashState *s);
void (*blk_load)(NANDFlashState *s, uint64_t addr, int offset);
/*
* Returns %true when block containing (@addr + @offset) is
* successfully loaded, otherwise %false.
*/
bool (*blk_load)(NANDFlashState *s, uint64_t addr, unsigned offset);
uint32_t ioaddr_vmstate;
};
@@ -243,9 +247,30 @@ static inline void nand_pushio_byte(NANDFlashState *s, uint8_t value)
}
}
/*
* nand_load_block: Load block containing (s->addr + @offset).
* Returns length of data available at @offset in this block.
*/
static unsigned nand_load_block(NANDFlashState *s, unsigned offset)
{
unsigned iolen;
if (!s->blk_load(s, s->addr, offset)) {
return 0;
}
iolen = (1 << s->page_shift);
if (s->gnd) {
iolen += 1 << s->oob_shift;
}
assert(offset <= iolen);
iolen -= offset;
return iolen;
}
static void nand_command(NANDFlashState *s)
{
unsigned int offset;
switch (s->cmd) {
case NAND_CMD_READ0:
s->iolen = 0;
@@ -271,12 +296,7 @@ static void nand_command(NANDFlashState *s)
case NAND_CMD_NOSERIALREAD2:
if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))
break;
offset = s->addr & ((1 << s->addr_shift) - 1);
s->blk_load(s, s->addr, offset);
if (s->gnd)
s->iolen = (1 << s->page_shift) - offset;
else
s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
s->iolen = nand_load_block(s, s->addr & ((1 << s->addr_shift) - 1));
break;
case NAND_CMD_RESET:
@@ -597,12 +617,7 @@ uint32_t nand_getio(DeviceState *dev)
if (!s->iolen && s->cmd == NAND_CMD_READ0) {
offset = (int) (s->addr & ((1 << s->addr_shift) - 1)) + s->offset;
s->offset = 0;
s->blk_load(s, s->addr, offset);
if (s->gnd)
s->iolen = (1 << s->page_shift) - offset;
else
s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;
s->iolen = nand_load_block(s, offset);
}
if (s->ce || s->iolen <= 0) {
@@ -763,11 +778,15 @@ static void glue(nand_blk_erase_, NAND_PAGE_SIZE)(NANDFlashState *s)
}
}
static void glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s,
uint64_t addr, int offset)
static bool glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s,
uint64_t addr, unsigned offset)
{
if (PAGE(addr) >= s->pages) {
return;
return false;
}
if (offset > NAND_PAGE_SIZE + OOB_SIZE) {
return false;
}
if (s->blk) {
@@ -795,6 +814,8 @@ static void glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s,
offset, NAND_PAGE_SIZE + OOB_SIZE - offset);
s->ioaddr = s->io;
}
return true;
}
static void glue(nand_init_, NAND_PAGE_SIZE)(NANDFlashState *s)
+2 -1
View File
@@ -783,7 +783,8 @@ static void virtio_blk_handle_zone_report(VirtIOBlockReq *req,
sizeof(struct virtio_blk_zone_report) +
sizeof(struct virtio_blk_zone_descriptor)) {
virtio_error(vdev, "in buffer too small for zone report");
return;
err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
goto out;
}
/* start byte offset of the zone report */
+1 -2
View File
@@ -985,8 +985,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
return;
}
port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port,
&dev->mem_reentrancy_guard);
port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port);
port->elem = NULL;
}
+4 -3
View File
@@ -37,15 +37,15 @@ GlobalProperty hw_compat_8_1[] = {
{ "ramfb", "x-migrate", "off" },
{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" },
{ "igb", "x-pcie-flr-init", "off" },
{ TYPE_VIRTIO_NET, "host_uso", "off"},
{ TYPE_VIRTIO_NET, "guest_uso4", "off"},
{ TYPE_VIRTIO_NET, "guest_uso6", "off"},
};
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
GlobalProperty hw_compat_8_0[] = {
{ "migration", "multifd-flush-after-each-section", "on"},
{ TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
{ TYPE_VIRTIO_NET, "host_uso", "off"},
{ TYPE_VIRTIO_NET, "guest_uso4", "off"},
{ TYPE_VIRTIO_NET, "guest_uso6", "off"},
};
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
@@ -97,6 +97,7 @@ GlobalProperty hw_compat_5_2[] = {
{ "PIIX4_PM", "smm-compat", "on"},
{ "virtio-blk-device", "report-discard-granularity", "off" },
{ "virtio-net-pci-base", "vectors", "3"},
{ "nvme", "msix-exclusive-bar", "on"},
};
const size_t hw_compat_5_2_len = G_N_ELEMENTS(hw_compat_5_2);
+7
View File
@@ -1748,6 +1748,13 @@ static void vga_draw_blank(VGACommonState *s, int full_update)
if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
return;
if (is_buffer_shared(surface)) {
/* unshare buffer, otherwise the blanking corrupts vga vram */
surface = qemu_create_displaysurface(s->last_scr_width,
s->last_scr_height);
dpy_gfx_replace_surface(s->con, surface);
}
w = s->last_scr_width * surface_bytes_per_pixel(surface);
d = surface_data(surface);
for(i = 0; i < s->last_scr_height; i++) {
+2 -4
View File
@@ -1463,10 +1463,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
g->ctrl_vq = virtio_get_queue(vdev, 0);
g->cursor_vq = virtio_get_queue(vdev, 1);
g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g,
&qdev->mem_reentrancy_guard);
g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g,
&qdev->mem_reentrancy_guard);
g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g);
g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g);
g->reset_bh = qemu_bh_new(virtio_gpu_reset_bh, g);
qemu_cond_init(&g->reset_cond);
QTAILQ_INIT(&g->reslist);
+10 -10
View File
@@ -175,24 +175,24 @@ static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
switch (frag) {
case 0:
addr = desc->source_address
+ (extract32(desc->address_extension, 16, 12) << 20);
addr = (uint64_t)desc->source_address
+ (extract64(desc->address_extension, 16, 16) << 32);
break;
case 1:
addr = desc->source_address2
+ (extract32(desc->address_extension_23, 0, 12) << 8);
addr = (uint64_t)desc->source_address2
+ (extract64(desc->address_extension_23, 0, 16) << 32);
break;
case 2:
addr = desc->source_address3
+ (extract32(desc->address_extension_23, 16, 12) << 20);
addr = (uint64_t)desc->source_address3
+ (extract64(desc->address_extension_23, 16, 16) << 32);
break;
case 3:
addr = desc->source_address4
+ (extract32(desc->address_extension_45, 0, 12) << 8);
addr = (uint64_t)desc->source_address4
+ (extract64(desc->address_extension_45, 0, 16) << 32);
break;
case 4:
addr = desc->source_address5
+ (extract32(desc->address_extension_45, 16, 12) << 20);
addr = (uint64_t)desc->source_address5
+ (extract64(desc->address_extension_45, 16, 16) << 32);
break;
default:
addr = 0;
+2 -2
View File
@@ -1658,7 +1658,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
*data = s->h_apr[gic_get_vcpu_real_id(cpu)];
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
*data = gic_apr_ns_view(s, regno, cpu);
*data = gic_apr_ns_view(s, cpu, regno);
} else {
*data = s->apr[regno][cpu];
}
@@ -1746,7 +1746,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
s->h_apr[gic_get_vcpu_real_id(cpu)] = value;
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
gic_apr_write_ns_view(s, regno, cpu, value);
gic_apr_write_ns_view(s, cpu, regno, value);
} else {
s->apr[regno][cpu] = value;
}
+2 -2
View File
@@ -1067,7 +1067,7 @@ static uint64_t icc_hppir0_value(GICv3CPUState *cs, CPUARMState *env)
*/
bool irq_is_secure;
if (cs->hppi.prio == 0xff) {
if (icc_no_enabled_hppi(cs)) {
return INTID_SPURIOUS;
}
@@ -1104,7 +1104,7 @@ static uint64_t icc_hppir1_value(GICv3CPUState *cs, CPUARMState *env)
*/
bool irq_is_secure;
if (cs->hppi.prio == 0xff) {
if (icc_no_enabled_hppi(cs)) {
return INTID_SPURIOUS;
}
+5 -4
View File
@@ -463,6 +463,7 @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
if (!topi) {
aplic->iforce[idc] = 0;
riscv_aplic_idc_update(aplic, idc);
return 0;
}
@@ -974,16 +975,16 @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
qdev_prop_set_bit(dev, "msimode", msimode);
qdev_prop_set_bit(dev, "mmode", mmode);
if (parent) {
riscv_aplic_add_child(parent, dev);
}
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
if (!is_kvm_aia(msimode)) {
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
}
if (parent) {
riscv_aplic_add_child(parent, dev);
}
if (!msimode) {
for (i = 0; i < num_harts; i++) {
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
+2 -1
View File
@@ -613,7 +613,7 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
ViaISAState *s = VIA_ISA(pci_get_function_0(d));
uint8_t irq = d->config[PCI_INTERRUPT_LINE], max_irq = 15;
int f = PCI_FUNC(d->devfn);
uint16_t mask = BIT(f);
uint16_t mask;
switch (f) {
case 0: /* PIRQ/PINT inputs */
@@ -628,6 +628,7 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
}
/* Keep track of the state of all sources */
mask = BIT(f);
if (level) {
s->irq_state[0] |= mask;
} else {
+3 -3
View File
@@ -298,7 +298,8 @@ static void fdt_add_memory_node(MachineState *ms,
char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
qemu_fdt_add_subnode(ms->fdt, nodename);
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", base >> 32, base,
size >> 32, size);
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
if (ms->numa_state && ms->numa_state->num_nodes) {
@@ -749,7 +750,6 @@ static void loongarch_init(MachineState *machine)
const CPUArchIdList *possible_cpus;
MachineClass *mc = MACHINE_GET_CLASS(machine);
CPUState *cpu;
char *ramName = NULL;
struct loaderparams loaderparams = { };
if (!cpu_model) {
@@ -800,7 +800,7 @@ static void loongarch_init(MachineState *machine)
for (i = 1; i < nb_numa_nodes; i++) {
MemoryRegion *nodemem = g_new(MemoryRegion, 1);
ramName = g_strdup_printf("loongarch.node%d.ram", i);
g_autofree char *ramName = g_strdup_printf("loongarch.node%d.ram", i);
memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
offset, numa_info[i].node_mem);
memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
+1
View File
@@ -274,6 +274,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
/* Remove existing entries */
QLIST_FOREACH_SAFE(d, &s->data_def, node, next) {
QLIST_REMOVE(d, node);
g_free(d);
}
s->status = 0x00;
s->status_1e = 0x00;
+7 -53
View File
@@ -123,14 +123,6 @@ e1000e_intmgr_timer_resume(E1000IntrDelayTimer *timer)
}
}
static void
e1000e_intmgr_timer_pause(E1000IntrDelayTimer *timer)
{
if (timer->running) {
timer_del(timer->timer);
}
}
static inline void
e1000e_intrmgr_stop_timer(E1000IntrDelayTimer *timer)
{
@@ -398,24 +390,6 @@ e1000e_intrmgr_resume(E1000ECore *core)
}
}
static void
e1000e_intrmgr_pause(E1000ECore *core)
{
int i;
e1000e_intmgr_timer_pause(&core->radv);
e1000e_intmgr_timer_pause(&core->rdtr);
e1000e_intmgr_timer_pause(&core->raid);
e1000e_intmgr_timer_pause(&core->tidv);
e1000e_intmgr_timer_pause(&core->tadv);
e1000e_intmgr_timer_pause(&core->itr);
for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
e1000e_intmgr_timer_pause(&core->eitr[i]);
}
}
static void
e1000e_intrmgr_reset(E1000ECore *core)
{
@@ -3334,12 +3308,6 @@ e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size)
return 0;
}
static inline void
e1000e_autoneg_pause(E1000ECore *core)
{
timer_del(core->autoneg_timer);
}
static void
e1000e_autoneg_resume(E1000ECore *core)
{
@@ -3351,22 +3319,6 @@ e1000e_autoneg_resume(E1000ECore *core)
}
}
static void
e1000e_vm_state_change(void *opaque, bool running, RunState state)
{
E1000ECore *core = opaque;
if (running) {
trace_e1000e_vm_state_running();
e1000e_intrmgr_resume(core);
e1000e_autoneg_resume(core);
} else {
trace_e1000e_vm_state_stopped();
e1000e_autoneg_pause(core);
e1000e_intrmgr_pause(core);
}
}
void
e1000e_core_pci_realize(E1000ECore *core,
const uint16_t *eeprom_templ,
@@ -3379,9 +3331,6 @@ e1000e_core_pci_realize(E1000ECore *core,
e1000e_autoneg_timer, core);
e1000e_intrmgr_pci_realize(core);
core->vmstate =
qemu_add_vm_change_state_handler(e1000e_vm_state_change, core);
for (i = 0; i < E1000E_NUM_QUEUES; i++) {
net_tx_pkt_init(&core->tx[i].tx_pkt, E1000E_MAX_TX_FRAGS);
}
@@ -3405,8 +3354,6 @@ e1000e_core_pci_uninit(E1000ECore *core)
e1000e_intrmgr_pci_unint(core);
qemu_del_vm_change_state_handler(core->vmstate);
for (i = 0; i < E1000E_NUM_QUEUES; i++) {
net_tx_pkt_uninit(core->tx[i].tx_pkt);
}
@@ -3576,5 +3523,12 @@ e1000e_core_post_load(E1000ECore *core)
*/
nc->link_down = (core->mac[STATUS] & E1000_STATUS_LU) == 0;
/*
* we need to restart intrmgr timers, as an older version of
* QEMU can have stopped them before migration
*/
e1000e_intrmgr_resume(core);
e1000e_autoneg_resume(core);
return 0;
}
-2
View File
@@ -98,8 +98,6 @@ struct E1000Core {
E1000IntrDelayTimer eitr[E1000E_MSIX_VEC_NUM];
VMChangeStateEntry *vmstate;
uint32_t itr_guest_value;
uint32_t eitr_guest_value[E1000E_MSIX_VEC_NUM];
+7 -44
View File
@@ -160,14 +160,6 @@ igb_intmgr_timer_resume(IGBIntrDelayTimer *timer)
}
}
static void
igb_intmgr_timer_pause(IGBIntrDelayTimer *timer)
{
if (timer->running) {
timer_del(timer->timer);
}
}
static void
igb_intrmgr_on_msix_throttling_timer(void *opaque)
{
@@ -212,16 +204,6 @@ igb_intrmgr_resume(IGBCore *core)
}
}
static void
igb_intrmgr_pause(IGBCore *core)
{
int i;
for (i = 0; i < IGB_INTR_NUM; i++) {
igb_intmgr_timer_pause(&core->eitr[i]);
}
}
static void
igb_intrmgr_reset(IGBCore *core)
{
@@ -4290,12 +4272,6 @@ igb_core_read(IGBCore *core, hwaddr addr, unsigned size)
return 0;
}
static inline void
igb_autoneg_pause(IGBCore *core)
{
timer_del(core->autoneg_timer);
}
static void
igb_autoneg_resume(IGBCore *core)
{
@@ -4307,22 +4283,6 @@ igb_autoneg_resume(IGBCore *core)
}
}
static void
igb_vm_state_change(void *opaque, bool running, RunState state)
{
IGBCore *core = opaque;
if (running) {
trace_e1000e_vm_state_running();
igb_intrmgr_resume(core);
igb_autoneg_resume(core);
} else {
trace_e1000e_vm_state_stopped();
igb_autoneg_pause(core);
igb_intrmgr_pause(core);
}
}
void
igb_core_pci_realize(IGBCore *core,
const uint16_t *eeprom_templ,
@@ -4335,8 +4295,6 @@ igb_core_pci_realize(IGBCore *core,
igb_autoneg_timer, core);
igb_intrmgr_pci_realize(core);
core->vmstate = qemu_add_vm_change_state_handler(igb_vm_state_change, core);
for (i = 0; i < IGB_NUM_QUEUES; i++) {
net_tx_pkt_init(&core->tx[i].tx_pkt, E1000E_MAX_TX_FRAGS);
}
@@ -4360,8 +4318,6 @@ igb_core_pci_uninit(IGBCore *core)
igb_intrmgr_pci_unint(core);
qemu_del_vm_change_state_handler(core->vmstate);
for (i = 0; i < IGB_NUM_QUEUES; i++) {
net_tx_pkt_uninit(core->tx[i].tx_pkt);
}
@@ -4586,5 +4542,12 @@ igb_core_post_load(IGBCore *core)
*/
nc->link_down = (core->mac[STATUS] & E1000_STATUS_LU) == 0;
/*
* we need to restart intrmgr timers, as an older version of
* QEMU can have stopped them before migration
*/
igb_intrmgr_resume(core);
igb_autoneg_resume(core);
return 0;
}
-2
View File
@@ -90,8 +90,6 @@ struct IGBCore {
IGBIntrDelayTimer eitr[IGB_INTR_NUM];
VMChangeStateEntry *vmstate;
uint32_t eitr_guest_value[IGB_INTR_NUM];
uint8_t permanent_mac[ETH_ALEN];
+24 -4
View File
@@ -150,6 +150,12 @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
#define GPT_TIMER_EN 0x20000000
/*
* The MAC Interface Layer (MIL), within the MAC, contains a 2K Byte transmit
* and a 128 Byte receive FIFO which is separate from the TX and RX FIFOs.
*/
#define MIL_TXFIFO_SIZE 2048
enum tx_state {
TX_IDLE,
TX_B,
@@ -166,7 +172,7 @@ typedef struct {
int32_t pad;
int32_t fifo_used;
int32_t len;
uint8_t data[2048];
uint8_t data[MIL_TXFIFO_SIZE];
} LAN9118Packet;
static const VMStateDescription vmstate_lan9118_packet = {
@@ -182,7 +188,7 @@ static const VMStateDescription vmstate_lan9118_packet = {
VMSTATE_INT32(pad, LAN9118Packet),
VMSTATE_INT32(fifo_used, LAN9118Packet),
VMSTATE_INT32(len, LAN9118Packet),
VMSTATE_UINT8_ARRAY(data, LAN9118Packet, 2048),
VMSTATE_UINT8_ARRAY(data, LAN9118Packet, MIL_TXFIFO_SIZE),
VMSTATE_END_OF_LIST()
}
};
@@ -544,7 +550,7 @@ static ssize_t lan9118_receive(NetClientState *nc, const uint8_t *buf,
return -1;
}
if (size >= 2048 || size < 14) {
if (size >= MIL_TXFIFO_SIZE || size < 14) {
return -1;
}
@@ -793,8 +799,22 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
/* Documentation is somewhat unclear on the ordering of bytes
in FIFO words. Empirical results show it to be little-endian.
*/
/* TODO: FIFO overflow checking. */
while (n--) {
if (s->txp->len == MIL_TXFIFO_SIZE) {
/*
* No more space in the FIFO. The datasheet is not
* precise about this case. We choose what is easiest
* to model: the packet is truncated, and TXE is raised.
*
* Note, it could be a fragmented packet, but we currently
* do not handle that (see earlier TX_B case).
*/
qemu_log_mask(LOG_GUEST_ERROR,
"MIL TX FIFO overrun, discarding %u byte%s\n",
n, n > 1 ? "s" : "");
s->int_sts |= TXE_INT;
break;
}
s->txp->data[s->txp->len] = val & 0xff;
s->txp->len++;
val >>= 8;
+5
View File
@@ -141,6 +141,10 @@ bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt)
uint32_t csum = 0;
struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG;
if (iov_size(pl_start_frag, pkt->payload_frags) < 8 + sizeof(csum)) {
return false;
}
if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) {
return false;
}
@@ -833,6 +837,7 @@ bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
if (offload || gso_type == VIRTIO_NET_HDR_GSO_NONE) {
if (!offload && pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
pkt->virt_hdr.flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
net_tx_pkt_do_sw_csum(pkt, &pkt->vec[NET_TX_PKT_L2HDR_FRAG],
pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1,
pkt->payload_len);
+1 -1
View File
@@ -632,7 +632,7 @@ static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
{
struct qemu_ether_header *hdr = (void *)buf;
if ((*(hdr->ether_dhost)&0x01) &&
((uint64_t *)&s->csr[8])[0] != 0LL) {
(s->csr[8] | s->csr[9] | s->csr[10] | s->csr[11]) != 0) {
uint8_t ladr[8] = {
s->csr[8] & 0xff, s->csr[8] >> 8,
s->csr[9] & 0xff, s->csr[9] >> 8,
+10
View File
@@ -541,6 +541,16 @@ int vhost_set_vring_enable(NetClientState *nc, int enable)
VHostNetState *net = get_vhost_net(nc);
const VhostOps *vhost_ops = net->dev.vhost_ops;
/*
* vhost-vdpa network devices need to enable dataplane virtqueues after
* DRIVER_OK, so they can recover device state before starting dataplane.
* Because of that, we don't enable virtqueues here and leave it to
* net/vhost-vdpa.c.
*/
if (nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
return 0;
}
nc->vring_enable = enable;
if (vhost_ops && vhost_ops->vhost_set_vring_enable) {
+18 -8
View File
@@ -2709,18 +2709,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
out_sg = elem->out_sg;
if (out_num < 1) {
virtio_error(vdev, "virtio-net header not in first element");
virtqueue_detach_element(q->tx_vq, elem, 0);
g_free(elem);
return -EINVAL;
goto detach;
}
if (n->has_vnet_hdr) {
if (iov_to_buf(out_sg, out_num, 0, &vhdr, n->guest_hdr_len) <
n->guest_hdr_len) {
virtio_error(vdev, "virtio-net header incorrect");
virtqueue_detach_element(q->tx_vq, elem, 0);
g_free(elem);
return -EINVAL;
goto detach;
}
if (n->needs_vnet_hdr_swap) {
virtio_net_hdr_swap(vdev, (void *) &vhdr);
@@ -2751,6 +2747,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
n->guest_hdr_len, -1);
out_num = sg_num;
out_sg = sg;
if (out_num < 1) {
virtio_error(vdev, "virtio-net nothing to send");
goto detach;
}
}
ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),
@@ -2771,6 +2772,11 @@ drop:
}
}
return num_packets;
detach:
virtqueue_detach_element(q->tx_vq, elem, 0);
g_free(elem);
return -EINVAL;
}
static void virtio_net_tx_timer(void *opaque);
@@ -2809,6 +2815,10 @@ static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq)
VirtIONet *n = VIRTIO_NET(vdev);
VirtIONetQueue *q = &n->vqs[vq2q(virtio_get_queue_index(vq))];
if (unlikely(n->vhost_started)) {
return;
}
if (unlikely((n->status & VIRTIO_NET_S_LINK_UP) == 0)) {
virtio_net_drop_tx_queue_data(vdev, vq);
return;
@@ -3370,7 +3380,7 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc;
assert(n->vhost_started);
if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_MQ) && idx == 2) {
if (!n->multiqueue && idx == 2) {
/* Must guard against invalid features and bogus queue index
* from being set by malicious guest, or penetrated through
* buggy migration stream.
@@ -3402,7 +3412,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc;
assert(n->vhost_started);
if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_MQ) && idx == 2) {
if (!n->multiqueue && idx == 2) {
/* Must guard against invalid features and bogus queue index
* from being set by malicious guest, or penetrated through
* buggy migration stream.
+68 -47
View File
@@ -2855,7 +2855,7 @@ static inline uint16_t nvme_check_copy_mcl(NvmeNamespace *ns,
uint32_t nlb;
nvme_copy_source_range_parse(iocb->ranges, idx, iocb->format, NULL,
&nlb, NULL, NULL, NULL);
copy_len += nlb + 1;
copy_len += nlb;
}
if (copy_len > ns->id_ns.mcl) {
@@ -4352,7 +4352,7 @@ static uint16_t nvme_io_mgmt_send_ruh_update(NvmeCtrl *n, NvmeRequest *req)
NvmeNamespace *ns = req->ns;
uint32_t cdw10 = le32_to_cpu(cmd->cdw10);
uint16_t ret = NVME_SUCCESS;
uint32_t npid = (cdw10 >> 1) + 1;
uint32_t npid = (cdw10 >> 16) + 1;
unsigned int i = 0;
g_autofree uint16_t *pids = NULL;
uint32_t maxnpid;
@@ -7798,6 +7798,11 @@ static bool nvme_check_params(NvmeCtrl *n, Error **errp)
}
if (n->pmr.dev) {
if (params->msix_exclusive_bar) {
error_setg(errp, "not enough BARs available to enable PMR");
return false;
}
if (host_memory_backend_is_mapped(n->pmr.dev)) {
error_setg(errp, "can't use already busy memdev: %s",
object_get_canonical_path_component(OBJECT(n->pmr.dev)));
@@ -8003,13 +8008,18 @@ static void nvme_init_pmr(NvmeCtrl *n, PCIDevice *pci_dev)
memory_region_set_enabled(&n->pmr.dev->mr, false);
}
static uint64_t nvme_bar_size(unsigned total_queues, unsigned total_irqs,
unsigned *msix_table_offset,
unsigned *msix_pba_offset)
static uint64_t nvme_mbar_size(unsigned total_queues, unsigned total_irqs,
unsigned *msix_table_offset,
unsigned *msix_pba_offset)
{
uint64_t bar_size, msix_table_size, msix_pba_size;
uint64_t bar_size, msix_table_size;
bar_size = sizeof(NvmeBar) + 2 * total_queues * NVME_DB_SIZE;
if (total_irqs == 0) {
goto out;
}
bar_size = QEMU_ALIGN_UP(bar_size, 4 * KiB);
if (msix_table_offset) {
@@ -8024,11 +8034,10 @@ static uint64_t nvme_bar_size(unsigned total_queues, unsigned total_irqs,
*msix_pba_offset = bar_size;
}
msix_pba_size = QEMU_ALIGN_UP(total_irqs, 64) / 8;
bar_size += msix_pba_size;
bar_size += QEMU_ALIGN_UP(total_irqs, 64) / 8;
bar_size = pow2ceil(bar_size);
return bar_size;
out:
return pow2ceil(bar_size);
}
static void nvme_init_sriov(NvmeCtrl *n, PCIDevice *pci_dev, uint16_t offset)
@@ -8036,7 +8045,7 @@ static void nvme_init_sriov(NvmeCtrl *n, PCIDevice *pci_dev, uint16_t offset)
uint16_t vf_dev_id = n->params.use_intel_id ?
PCI_DEVICE_ID_INTEL_NVME : PCI_DEVICE_ID_REDHAT_NVME;
NvmePriCtrlCap *cap = &n->pri_ctrl_cap;
uint64_t bar_size = nvme_bar_size(le16_to_cpu(cap->vqfrsm),
uint64_t bar_size = nvme_mbar_size(le16_to_cpu(cap->vqfrsm),
le16_to_cpu(cap->vifrsm),
NULL, NULL);
@@ -8075,7 +8084,7 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp)
ERRP_GUARD();
uint8_t *pci_conf = pci_dev->config;
uint64_t bar_size;
unsigned msix_table_offset, msix_pba_offset;
unsigned msix_table_offset = 0, msix_pba_offset = 0;
int ret;
pci_conf[PCI_INTERRUPT_PIN] = 1;
@@ -8097,24 +8106,38 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp)
pcie_ari_init(pci_dev, 0x100);
}
/* add one to max_ioqpairs to account for the admin queue pair */
bar_size = nvme_bar_size(n->params.max_ioqpairs + 1, n->params.msix_qsize,
&msix_table_offset, &msix_pba_offset);
memory_region_init(&n->bar0, OBJECT(n), "nvme-bar0", bar_size);
memory_region_init_io(&n->iomem, OBJECT(n), &nvme_mmio_ops, n, "nvme",
msix_table_offset);
memory_region_add_subregion(&n->bar0, 0, &n->iomem);
if (pci_is_vf(pci_dev)) {
pcie_sriov_vf_register_bar(pci_dev, 0, &n->bar0);
} else {
if (n->params.msix_exclusive_bar && !pci_is_vf(pci_dev)) {
bar_size = nvme_mbar_size(n->params.max_ioqpairs + 1, 0, NULL, NULL);
memory_region_init_io(&n->iomem, OBJECT(n), &nvme_mmio_ops, n, "nvme",
bar_size);
pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64, &n->bar0);
PCI_BASE_ADDRESS_MEM_TYPE_64, &n->iomem);
ret = msix_init_exclusive_bar(pci_dev, n->params.msix_qsize, 4, errp);
} else {
assert(n->params.msix_qsize >= 1);
/* add one to max_ioqpairs to account for the admin queue pair */
bar_size = nvme_mbar_size(n->params.max_ioqpairs + 1,
n->params.msix_qsize, &msix_table_offset,
&msix_pba_offset);
memory_region_init(&n->bar0, OBJECT(n), "nvme-bar0", bar_size);
memory_region_init_io(&n->iomem, OBJECT(n), &nvme_mmio_ops, n, "nvme",
msix_table_offset);
memory_region_add_subregion(&n->bar0, 0, &n->iomem);
if (pci_is_vf(pci_dev)) {
pcie_sriov_vf_register_bar(pci_dev, 0, &n->bar0);
} else {
pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64, &n->bar0);
}
ret = msix_init(pci_dev, n->params.msix_qsize,
&n->bar0, 0, msix_table_offset,
&n->bar0, 0, msix_pba_offset, 0, errp);
}
ret = msix_init(pci_dev, n->params.msix_qsize,
&n->bar0, 0, msix_table_offset,
&n->bar0, 0, msix_pba_offset, 0, errp);
if (ret == -ENOTSUP) {
/* report that msix is not supported, but do not error out */
warn_report_err(*errp);
@@ -8309,9 +8332,15 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
if (pci_is_vf(pci_dev)) {
/*
* VFs derive settings from the parent. PF's lifespan exceeds
* that of VF's, so it's safe to share params.serial.
* that of VF's.
*/
memcpy(&n->params, &pn->params, sizeof(NvmeParams));
/*
* Set PF's serial value to a new string memory to prevent 'serial'
* property object release of PF when a VF is removed from the system.
*/
n->params.serial = g_strdup(pn->params.serial);
n->subsys = pn->subsys;
}
@@ -8412,6 +8441,8 @@ static Property nvme_props[] = {
params.sriov_max_vi_per_vf, 0),
DEFINE_PROP_UINT8("sriov_max_vq_per_vf", NvmeCtrl,
params.sriov_max_vq_per_vf, 0),
DEFINE_PROP_BOOL("msix-exclusive-bar", NvmeCtrl, params.msix_exclusive_bar,
false),
DEFINE_PROP_END_OF_LIST(),
};
@@ -8466,36 +8497,26 @@ static void nvme_pci_reset(DeviceState *qdev)
nvme_ctrl_reset(n, NVME_RESET_FUNCTION);
}
static void nvme_sriov_pre_write_ctrl(PCIDevice *dev, uint32_t address,
uint32_t val, int len)
static void nvme_sriov_post_write_config(PCIDevice *dev, uint16_t old_num_vfs)
{
NvmeCtrl *n = NVME(dev);
NvmeSecCtrlEntry *sctrl;
uint16_t sriov_cap = dev->exp.sriov_cap;
uint32_t off = address - sriov_cap;
int i, num_vfs;
int i;
if (!sriov_cap) {
return;
}
if (range_covers_byte(off, len, PCI_SRIOV_CTRL)) {
if (!(val & PCI_SRIOV_CTRL_VFE)) {
num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
for (i = 0; i < num_vfs; i++) {
sctrl = &n->sec_ctrl_list.sec[i];
nvme_virt_set_state(n, le16_to_cpu(sctrl->scid), false);
}
}
for (i = pcie_sriov_num_vfs(dev); i < old_num_vfs; i++) {
sctrl = &n->sec_ctrl_list.sec[i];
nvme_virt_set_state(n, le16_to_cpu(sctrl->scid), false);
}
}
static void nvme_pci_write_config(PCIDevice *dev, uint32_t address,
uint32_t val, int len)
{
nvme_sriov_pre_write_ctrl(dev, address, val, len);
uint16_t old_num_vfs = pcie_sriov_num_vfs(dev);
pci_default_write_config(dev, address, val, len);
pcie_cap_flr_write_config(dev, address, val, len);
nvme_sriov_post_write_config(dev, old_num_vfs);
}
static const VMStateDescription nvme_vmstate = {
+1
View File
@@ -522,6 +522,7 @@ typedef struct NvmeParams {
uint16_t sriov_vi_flexible;
uint8_t sriov_max_vq_per_vf;
uint8_t sriov_max_vi_per_vf;
bool msix_exclusive_bar;
} NvmeParams;
typedef struct NvmeCtrl {
+3
View File
@@ -176,6 +176,9 @@ static void register_vfs(PCIDevice *dev)
assert(sriov_cap > 0);
num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
if (num_vfs > pci_get_word(dev->config + sriov_cap + PCI_SRIOV_TOTAL_VF)) {
return;
}
dev->exp.sriov_pf.vf = g_new(PCIDevice *, num_vfs);
+4 -7
View File
@@ -53,7 +53,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PPC440PCIXState, PPC440_PCIX_HOST)
struct PPC440PCIXState {
PCIHostState parent_obj;
PCIDevice *dev;
uint8_t config[PCI_CONFIG_SPACE_SIZE];
struct PLBOutMap pom[PPC440_PCIX_NR_POMS];
struct PLBInMap pim[PPC440_PCIX_NR_PIMS];
uint32_t sts;
@@ -172,7 +172,7 @@ static void ppc440_pcix_reg_write4(void *opaque, hwaddr addr,
trace_ppc440_pcix_reg_write(addr, val, size);
switch (addr) {
case PCI_VENDOR_ID ... PCI_MAX_LAT:
stl_le_p(s->dev->config + addr, val);
stl_le_p(s->config + addr, val);
break;
case PCIX0_POM0LAL:
@@ -303,7 +303,7 @@ static uint64_t ppc440_pcix_reg_read4(void *opaque, hwaddr addr,
switch (addr) {
case PCI_VENDOR_ID ... PCI_MAX_LAT:
val = ldl_le_p(s->dev->config + addr);
val = ldl_le_p(s->config + addr);
break;
case PCIX0_POM0LAL:
@@ -499,10 +499,7 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp)
memory_region_init(&s->iomem, OBJECT(dev), "pci-io", 64 * KiB);
h->bus = pci_register_root_bus(dev, NULL, ppc440_pcix_set_irq,
ppc440_pcix_map_irq, &s->irq, &s->busmem, &s->iomem,
PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS);
s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0),
TYPE_PPC4xx_HOST_BRIDGE);
PCI_DEVFN(1, 0), 1, TYPE_PCI_BUS);
memory_region_init(&s->bm, OBJECT(s), "bm-ppc440-pcix", UINT64_MAX);
memory_region_add_subregion(&s->bm, 0x0, &s->busmem);
+3 -6
View File
@@ -4647,13 +4647,10 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
mc->block_default_type = IF_SCSI;
/*
* Setting max_cpus to INT32_MAX. Both KVM and TCG max_cpus values
* should be limited by the host capability instead of hardcoded.
* max_cpus for KVM guests will be checked in kvm_init(), and TCG
* guests are welcome to have as many CPUs as the host are capable
* of emulate.
* While KVM determines max cpus in kvm_init() using kvm_max_vcpus(),
* In TCG the limit is restricted by the range of CPU IPIs available.
*/
mc->max_cpus = INT32_MAX;
mc->max_cpus = SPAPR_IRQ_NR_IPIS;
mc->no_parallel = 1;
mc->default_boot_order = "";
+4 -2
View File
@@ -23,6 +23,8 @@
#include "trace.h"
QEMU_BUILD_BUG_ON(SPAPR_IRQ_NR_IPIS > SPAPR_XIRQ_BASE);
static const TypeInfo spapr_intc_info = {
.name = TYPE_SPAPR_INTC,
.parent = TYPE_INTERFACE,
@@ -329,7 +331,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
int i;
dev = qdev_new(TYPE_SPAPR_XIVE);
qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_IRQ_NR_IPIS);
/*
* 8 XIVE END structures per CPU. One for each available
* priority
@@ -356,7 +358,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
}
spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
smc->nr_xirqs + SPAPR_XIRQ_BASE);
smc->nr_xirqs + SPAPR_IRQ_NR_IPIS);
/*
* Mostly we don't actually need this until reset, except that not
+2 -2
View File
@@ -281,7 +281,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf,
while (bytes > 0) {
len = (bytes > pci_access_width) ? pci_access_width : bytes;
if (is_write) {
memcpy(&val, ptr, len);
val = ldn_le_p(ptr, len);
pci_host_config_write_common(o->pci_dev, offset,
pci_config_size(o->pci_dev),
val, len);
@@ -289,7 +289,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf,
} else {
val = pci_host_config_read_common(o->pci_dev, offset,
pci_config_size(o->pci_dev), len);
memcpy(ptr, &val, len);
stn_le_p(ptr, len, val);
trace_vfu_cfg_read(offset, val);
}
offset += len;
+2
View File
@@ -743,6 +743,8 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
qemu_fdt_add_subnode(ms->fdt, "/cpus");
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
kvm_enabled() ?
kvm_riscv_get_timebase_frequency(first_cpu) :
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
+1 -1
View File
@@ -5,7 +5,7 @@
*
* Copyright (c) 2016 Artyom Tarasenko
*
* This code is licensed under the GNU GPL v3 or (at your option) any later
* This code is licensed under the GNU GPL v2 or (at your option) any later
* version.
*/
+45 -14
View File
@@ -188,7 +188,7 @@ static const char *names[] = {
#define LSI_TAG_VALID (1 << 16)
/* Maximum instructions to process. */
#define LSI_MAX_INSN 10000
#define LSI_MAX_INSN 100
typedef struct lsi_request {
SCSIRequest *req;
@@ -205,6 +205,7 @@ enum {
LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
LSI_WAIT_SCRIPTS, /* SCRIPTS stopped because of instruction count limit */
};
enum {
@@ -224,6 +225,7 @@ struct LSIState {
MemoryRegion ram_io;
MemoryRegion io_io;
AddressSpace pci_io_as;
QEMUTimer *scripts_timer;
int carry; /* ??? Should this be an a visible register somewhere? */
int status;
@@ -415,6 +417,7 @@ static void lsi_soft_reset(LSIState *s)
s->sbr = 0;
assert(QTAILQ_EMPTY(&s->queue));
assert(!s->current);
timer_del(s->scripts_timer);
}
static int lsi_dma_40bit(LSIState *s)
@@ -570,8 +573,9 @@ static inline void lsi_set_phase(LSIState *s, int phase)
s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
}
static void lsi_bad_phase(LSIState *s, int out, int new_phase)
static int lsi_bad_phase(LSIState *s, int out, int new_phase)
{
int ret = 0;
/* Trigger a phase mismatch. */
if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
if ((s->ccntl0 & LSI_CCNTL0_PMJCTL)) {
@@ -584,8 +588,10 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase)
trace_lsi_bad_phase_interrupt();
lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
lsi_stop_script(s);
ret = 1;
}
lsi_set_phase(s, new_phase);
return ret;
}
@@ -789,7 +795,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
static void lsi_command_complete(SCSIRequest *req, size_t resid)
{
LSIState *s = LSI53C895A(req->bus->qbus.parent);
int out;
int out, stop = 0;
out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
trace_lsi_command_complete(req->status);
@@ -797,7 +803,10 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid)
s->command_complete = 2;
if (s->waiting && s->dbc != 0) {
/* Raise phase mismatch for short transfers. */
lsi_bad_phase(s, out, PHASE_ST);
stop = lsi_bad_phase(s, out, PHASE_ST);
if (stop) {
s->waiting = 0;
}
} else {
lsi_set_phase(s, PHASE_ST);
}
@@ -807,7 +816,9 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid)
lsi_request_free(s, s->current);
scsi_req_unref(req);
}
lsi_resume_script(s);
if (!stop) {
lsi_resume_script(s);
}
}
/* Callback to indicate that the SCSI layer has completed a transfer. */
@@ -1127,6 +1138,12 @@ static void lsi_wait_reselect(LSIState *s)
}
}
static void lsi_scripts_timer_start(LSIState *s)
{
trace_lsi_scripts_timer_start();
timer_mod(s->scripts_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);
}
static void lsi_execute_script(LSIState *s)
{
PCIDevice *pci_dev = PCI_DEVICE(s);
@@ -1136,6 +1153,11 @@ static void lsi_execute_script(LSIState *s)
int insn_processed = 0;
static int reentrancy_level;
if (s->waiting == LSI_WAIT_SCRIPTS) {
timer_del(s->scripts_timer);
s->waiting = LSI_NOWAIT;
}
reentrancy_level++;
s->istat1 |= LSI_ISTAT1_SRUN;
@@ -1143,8 +1165,8 @@ again:
/*
* Some windows drivers make the device spin waiting for a memory location
* to change. If we have executed more than LSI_MAX_INSN instructions then
* assume this is the case and force an unexpected device disconnect. This
* is apparently sufficient to beat the drivers into submission.
* assume this is the case and start a timer. Until the timer fires, the
* host CPU has a chance to run and change the memory location.
*
* Another issue (CVE-2023-0330) can occur if the script is programmed to
* trigger itself again and again. Avoid this problem by stopping after
@@ -1152,13 +1174,8 @@ again:
* which should be enough for all valid use cases).
*/
if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
if (!(s->sien0 & LSI_SIST0_UDC)) {
qemu_log_mask(LOG_GUEST_ERROR,
"lsi_scsi: inf. loop with UDC masked");
}
lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
lsi_disconnect(s);
trace_lsi_execute_script_stop();
s->waiting = LSI_WAIT_SCRIPTS;
lsi_scripts_timer_start(s);
reentrancy_level--;
return;
}
@@ -2197,6 +2214,9 @@ static int lsi_post_load(void *opaque, int version_id)
return -EINVAL;
}
if (s->waiting == LSI_WAIT_SCRIPTS) {
lsi_scripts_timer_start(s);
}
return 0;
}
@@ -2294,6 +2314,15 @@ static const struct SCSIBusInfo lsi_scsi_info = {
.cancel = lsi_request_cancelled
};
static void scripts_timer_cb(void *opaque)
{
LSIState *s = opaque;
trace_lsi_scripts_timer_triggered();
s->waiting = LSI_NOWAIT;
lsi_execute_script(s);
}
static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
{
LSIState *s = LSI53C895A(dev);
@@ -2313,6 +2342,7 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
"lsi-ram", 0x2000);
memory_region_init_io(&s->io_io, OBJECT(s), &lsi_io_ops, s,
"lsi-io", 256);
s->scripts_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, scripts_timer_cb, s);
/*
* Since we use the address-space API to interact with ram_io, disable the
@@ -2337,6 +2367,7 @@ static void lsi_scsi_exit(PCIDevice *dev)
LSIState *s = LSI53C895A(dev);
address_space_destroy(&s->pci_io_as);
timer_del(s->scripts_timer);
}
static void lsi_class_init(ObjectClass *klass, void *data)
-1
View File
@@ -766,7 +766,6 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
/* Only used by scsi-block, but initialize it nevertheless to be clean. */
s->default_scsi_version = -1;
s->io_timeout = DEFAULT_IO_TIMEOUT;
scsi_generic_read_device_inquiry(s);
}
+2
View File
@@ -301,6 +301,8 @@ lsi_execute_script_stop(void) "SCRIPTS execution stopped"
lsi_awoken(void) "Woken by SIGP"
lsi_reg_read(const char *name, int offset, uint8_t ret) "Read reg %s 0x%x = 0x%02x"
lsi_reg_write(const char *name, int offset, uint8_t val) "Write reg %s 0x%x = 0x%02x"
lsi_scripts_timer_triggered(void) "SCRIPTS timer triggered"
lsi_scripts_timer_start(void) "SCRIPTS timer started"
# virtio-scsi.c
virtio_scsi_cmd_req(int lun, uint32_t tag, uint8_t cmd) "virtio_scsi_cmd_req lun=%u tag=0x%x cmd=0x%x"
+8
View File
@@ -473,6 +473,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
}
for (i = 0; i < size; i++) {
assert(s->data_count < s->buf_maxsz);
value |= s->fifo_buffer[s->data_count] << i * 8;
s->data_count++;
/* check if we've read all valid data (blksize bytes) from buffer */
@@ -561,6 +562,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
}
for (i = 0; i < size; i++) {
assert(s->data_count < s->buf_maxsz);
s->fifo_buffer[s->data_count] = value & 0xFF;
s->data_count++;
value >>= 8;
@@ -1208,6 +1210,12 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) {
value &= ~SDHC_TRNS_DMA;
}
/* TRNMOD writes are inhibited while Command Inhibit (DAT) is true */
if (s->prnsts & SDHC_DATA_INHIBIT) {
mask |= 0xffff;
}
MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK);
MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
+8
View File
@@ -126,6 +126,10 @@ static MemTxResult ufs_dma_read_req_upiu(UfsRequest *req)
copy_size = sizeof(UtpUpiuHeader) + UFS_TRANSACTION_SPECIFIC_FIELD_SIZE +
data_segment_length;
if (copy_size > sizeof(req->req_upiu)) {
copy_size = sizeof(req->req_upiu);
}
ret = ufs_addr_read(u, req_upiu_base_addr, &req->req_upiu, copy_size);
if (ret) {
trace_ufs_err_dma_read_req_upiu(req->slot, req_upiu_base_addr);
@@ -225,6 +229,10 @@ static MemTxResult ufs_dma_write_rsp_upiu(UfsRequest *req)
copy_size = rsp_upiu_byte_len;
}
if (copy_size > sizeof(req->rsp_upiu)) {
copy_size = sizeof(req->rsp_upiu);
}
ret = ufs_addr_write(u, rsp_upiu_base_addr, &req->rsp_upiu, copy_size);
if (ret) {
trace_ufs_err_dma_write_rsp_upiu(req->slot, rsp_upiu_base_addr);
+1 -1
View File
@@ -48,7 +48,7 @@ vhost_vdpa_set_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI
vhost_vdpa_get_device_id(void *dev, uint32_t device_id) "dev: %p device_id %"PRIu32
vhost_vdpa_reset_device(void *dev) "dev: %p"
vhost_vdpa_get_vq_index(void *dev, int idx, int vq_idx) "dev: %p idx: %d vq idx: %d"
vhost_vdpa_set_vring_ready(void *dev, unsigned i, int r) "dev: %p, idx: %u, r: %d"
vhost_vdpa_set_vring_enable_one(void *dev, unsigned i, int enable, int r) "dev: %p, idx: %u, enable: %u, r: %d"
vhost_vdpa_dump_config(void *dev, const char *line) "dev: %p %s"
vhost_vdpa_set_config(void *dev, uint32_t offset, uint32_t size, uint32_t flags) "dev: %p offset: %"PRIu32" size: %"PRIu32" flags: 0x%"PRIx32
vhost_vdpa_get_config(void *dev, void *config, uint32_t config_len) "dev: %p config: %p config_len: %"PRIu32
+8 -4
View File
@@ -192,7 +192,14 @@ static void
vhost_vdpa_device_get_config(VirtIODevice *vdev, uint8_t *config)
{
VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
int ret;
ret = vhost_dev_get_config(&s->dev, s->config, s->config_size,
NULL);
if (ret < 0) {
error_report("get device config space failed");
return;
}
memcpy(config, s->config, s->config_size);
}
@@ -250,14 +257,11 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp)
s->dev.acked_features = vdev->guest_features;
ret = vhost_dev_start(&s->dev, vdev, false);
ret = vhost_dev_start(&s->dev, vdev, true);
if (ret < 0) {
error_setg_errno(errp, -ret, "Error starting vhost");
goto err_guest_notifiers;
}
for (i = 0; i < s->dev.nvqs; ++i) {
vhost_vdpa_set_vring_ready(&s->vdpa, i);
}
s->started = true;
/*
+26 -3
View File
@@ -882,19 +882,41 @@ static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
return idx;
}
int vhost_vdpa_set_vring_ready(struct vhost_vdpa *v, unsigned idx)
static int vhost_vdpa_set_vring_enable_one(struct vhost_vdpa *v, unsigned idx,
int enable)
{
struct vhost_dev *dev = v->dev;
struct vhost_vring_state state = {
.index = idx,
.num = 1,
.num = enable,
};
int r = vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, &state);
trace_vhost_vdpa_set_vring_ready(dev, idx, r);
trace_vhost_vdpa_set_vring_enable_one(dev, idx, enable, r);
return r;
}
static int vhost_vdpa_set_vring_enable(struct vhost_dev *dev, int enable)
{
struct vhost_vdpa *v = dev->opaque;
unsigned int i;
int ret;
for (i = 0; i < dev->nvqs; ++i) {
ret = vhost_vdpa_set_vring_enable_one(v, i, enable);
if (ret < 0) {
return ret;
}
}
return 0;
}
int vhost_vdpa_set_vring_ready(struct vhost_vdpa *v, unsigned idx)
{
return vhost_vdpa_set_vring_enable_one(v, idx, 1);
}
static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
int fd)
{
@@ -1508,6 +1530,7 @@ const VhostOps vdpa_ops = {
.vhost_set_features = vhost_vdpa_set_features,
.vhost_reset_device = vhost_vdpa_reset_device,
.vhost_get_vq_index = vhost_vdpa_get_vq_index,
.vhost_set_vring_enable = vhost_vdpa_set_vring_enable,
.vhost_get_config = vhost_vdpa_get_config,
.vhost_set_config = vhost_vdpa_set_config,
.vhost_requires_shm_log = NULL,
+7 -1
View File
@@ -1984,7 +1984,13 @@ static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
return hdev->vhost_ops->vhost_set_vring_enable(hdev, enable);
}
/* Host notifiers must be enabled at this point. */
/*
* Host notifiers must be enabled at this point.
*
* If @vrings is true, this function will enable all vrings before starting the
* device. If it is false, the vring initialization is left to be done by the
* caller.
*/
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
{
int i, r;
+2 -2
View File
@@ -1080,8 +1080,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
vcrypto->vqs[i].dataq =
virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
vcrypto->vqs[i].dataq_bh =
qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i],
&dev->mem_reentrancy_guard);
virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh,
&vcrypto->vqs[i]);
vcrypto->vqs[i].vcrypto = vcrypto;
}
+37 -18
View File
@@ -892,7 +892,7 @@ static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no)
}
ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
if (ret < 0) {
goto undo;
return ret;
}
/*
* If guest supports masking, set up irqfd now.
@@ -902,25 +902,11 @@ static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no)
ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
if (ret < 0) {
kvm_virtio_pci_vq_vector_release(proxy, vector);
goto undo;
return ret;
}
}
return 0;
undo:
vector = virtio_queue_vector(vdev, queue_no);
if (vector >= msix_nr_vectors_allocated(dev)) {
return ret;
}
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
if (ret < 0) {
return ret;
}
kvm_virtio_pci_irqfd_release(proxy, n, vector);
}
return ret;
}
static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs)
{
@@ -1424,6 +1410,38 @@ static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
return offset;
}
static void virtio_pci_set_vector(VirtIODevice *vdev,
VirtIOPCIProxy *proxy,
int queue_no, uint16_t old_vector,
uint16_t new_vector)
{
bool kvm_irqfd = (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
msix_enabled(&proxy->pci_dev) && kvm_msi_via_irqfd_enabled();
if (new_vector == old_vector) {
return;
}
/*
* If the device uses irqfd and the vector changes after DRIVER_OK is
* set, we need to release the old vector and set up the new one.
* Otherwise just need to set the new vector on the device.
*/
if (kvm_irqfd && old_vector != VIRTIO_NO_VECTOR) {
kvm_virtio_pci_vector_release_one(proxy, queue_no);
}
/* Set the new vector on the device. */
if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
vdev->config_vector = new_vector;
} else {
virtio_queue_set_vector(vdev, queue_no, new_vector);
}
/* If the new vector changed need to set it up. */
if (kvm_irqfd && new_vector != VIRTIO_NO_VECTOR) {
kvm_virtio_pci_vector_use_one(proxy, queue_no);
}
}
int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy,
uint8_t bar, uint64_t offset, uint64_t length,
uint8_t id)
@@ -1570,7 +1588,8 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
} else {
val = VIRTIO_NO_VECTOR;
}
vdev->config_vector = val;
virtio_pci_set_vector(vdev, proxy, VIRTIO_CONFIG_IRQ_IDX,
vdev->config_vector, val);
break;
case VIRTIO_PCI_COMMON_STATUS:
if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
@@ -1610,7 +1629,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
} else {
val = VIRTIO_NO_VECTOR;
}
virtio_queue_set_vector(vdev, vdev->queue_sel, val);
virtio_pci_set_vector(vdev, proxy, vdev->queue_sel, vector, val);
break;
case VIRTIO_PCI_COMMON_Q_ENABLE:
if (val == 1) {
+20 -3
View File
@@ -322,7 +322,6 @@ static void vring_packed_event_read(VirtIODevice *vdev,
/* Make sure flags is seen before off_wrap */
smp_rmb();
e->off_wrap = virtio_lduw_phys_cached(vdev, cache, off_off);
virtio_tswap16s(vdev, &e->flags);
}
static void vring_packed_off_wrap_write(VirtIODevice *vdev,
@@ -957,12 +956,20 @@ static void virtqueue_packed_flush(VirtQueue *vq, unsigned int count)
return;
}
/*
* For indirect element's 'ndescs' is 1.
* For all other elemment's 'ndescs' is the
* number of descriptors chained by NEXT (as set in virtqueue_packed_pop).
* So When the 'elem' be filled into the descriptor ring,
* The 'idx' of this 'elem' shall be
* the value of 'vq->used_idx' plus the 'ndescs'.
*/
ndescs += vq->used_elems[0].ndescs;
for (i = 1; i < count; i++) {
virtqueue_packed_fill_desc(vq, &vq->used_elems[i], i, false);
virtqueue_packed_fill_desc(vq, &vq->used_elems[i], ndescs, false);
ndescs += vq->used_elems[i].ndescs;
}
virtqueue_packed_fill_desc(vq, &vq->used_elems[0], 0, true);
ndescs += vq->used_elems[0].ndescs;
vq->inuse -= ndescs;
vq->used_idx += ndescs;
@@ -4137,3 +4144,13 @@ static void virtio_register_types(void)
}
type_init(virtio_register_types)
QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
QEMUBHFunc *cb, void *opaque,
const char *name)
{
DeviceState *transport = qdev_get_parent_bus(dev)->parent;
return qemu_bh_new_full(cb, opaque, name,
&transport->mem_reentrancy_guard);
}
+28 -2
View File
@@ -481,11 +481,37 @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
g_free(entry);
}
void xen_invalidate_map_cache_entry(uint8_t *buffer)
typedef struct XenMapCacheData {
Coroutine *co;
uint8_t *buffer;
} XenMapCacheData;
static void xen_invalidate_map_cache_entry_bh(void *opaque)
{
XenMapCacheData *data = opaque;
mapcache_lock();
xen_invalidate_map_cache_entry_unlocked(buffer);
xen_invalidate_map_cache_entry_unlocked(data->buffer);
mapcache_unlock();
aio_co_wake(data->co);
}
void coroutine_mixed_fn xen_invalidate_map_cache_entry(uint8_t *buffer)
{
if (qemu_in_coroutine()) {
XenMapCacheData data = {
.co = qemu_coroutine_self(),
.buffer = buffer,
};
aio_bh_schedule_oneshot(qemu_get_current_aio_context(),
xen_invalidate_map_cache_entry_bh, &data);
qemu_coroutine_yield();
} else {
mapcache_lock();
xen_invalidate_map_cache_entry_unlocked(buffer);
mapcache_unlock();
}
}
void xen_invalidate_map_cache(void)
+16 -1
View File
@@ -151,7 +151,6 @@ struct VirtIOSoundPCMStream {
QemuMutex queue_mutex;
bool active;
QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) queue;
QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) invalid;
};
/*
@@ -223,6 +222,21 @@ struct VirtIOSound {
QemuMutex cmdq_mutex;
QTAILQ_HEAD(, virtio_snd_ctrl_command) cmdq;
bool processing_cmdq;
/*
* Convenience queue to keep track of invalid tx/rx queue messages inside
* the tx/rx callbacks.
*
* In the callbacks as a first step we are emptying the virtqueue to handle
* each message and we cannot add an invalid message back to the queue: we
* would re-process it in subsequent loop iterations.
*
* Instead, we add them to this queue and after finishing examining every
* virtqueue element, we inform the guest for each invalid message.
*
* This queue must be empty at all times except for inside the tx/rx
* callbacks.
*/
QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) invalid;
};
struct virtio_snd_ctrl_command {
@@ -230,6 +244,7 @@ struct virtio_snd_ctrl_command {
VirtQueue *vq;
virtio_snd_hdr ctrl;
virtio_snd_hdr resp;
size_t payload_size;
QTAILQ_ENTRY(virtio_snd_ctrl_command) next;
};
#endif
+13 -1
View File
@@ -14,9 +14,21 @@
#include "qom/object.h"
/*
* IRQ range offsets per device type
* The XIVE IRQ backend uses the same layout as the XICS backend but
* covers the full range of the IRQ number space. The IRQ numbers for
* the CPU IPIs are allocated at the bottom of this space, below 4K,
* to preserve compatibility with XICS which does not use that range.
*/
/*
* CPU IPI range (XIVE only)
*/
#define SPAPR_IRQ_IPI 0x0
#define SPAPR_IRQ_NR_IPIS 0x1000
/*
* IRQ range offsets per device type
*/
#define SPAPR_XIRQ_BASE XICS_IRQ_BASE /* 0x1000 */
#define SPAPR_IRQ_EPOW (SPAPR_XIRQ_BASE + 0x0000)
+1 -1
View File
@@ -5,7 +5,7 @@
*
* Copyright (c) 2016 Artyom Tarasenko
*
* This code is licensed under the GNU GPL v3 or (at your option) any later
* This code is licensed under the GNU GPL v2 or (at your option) any later
* version.
*/
+7
View File
@@ -22,6 +22,7 @@
#include "standard-headers/linux/virtio_config.h"
#include "standard-headers/linux/virtio_ring.h"
#include "qom/object.h"
#include "block/aio.h"
/*
* A guest should never accept this. It implies negotiation is broken
@@ -508,4 +509,10 @@ static inline bool virtio_device_disabled(VirtIODevice *vdev)
bool virtio_legacy_allowed(VirtIODevice *vdev);
bool virtio_legacy_check_disabled(VirtIODevice *vdev);
QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
QEMUBHFunc *cb, void *opaque,
const char *name);
#define virtio_bh_new_guarded(dev, cb, opaque) \
virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb)))
#endif
+1 -1
View File
@@ -503,7 +503,7 @@ void job_enter(Job *job);
*
* Called with job_mutex *not* held.
*/
void coroutine_fn job_pause_point(Job *job);
void coroutine_fn GRAPH_UNLOCKED job_pause_point(Job *job);
/**
* @job: The job that calls the function.
+15 -11
View File
@@ -69,37 +69,40 @@ qio_channel_tls_new_server(QIOChannel *master,
const char *aclname,
Error **errp)
{
QIOChannelTLS *ioc;
QIOChannelTLS *tioc;
QIOChannel *ioc;
ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
ioc = QIO_CHANNEL(tioc);
ioc->master = master;
tioc->master = master;
ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN);
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
}
object_ref(OBJECT(master));
ioc->session = qcrypto_tls_session_new(
tioc->session = qcrypto_tls_session_new(
creds,
NULL,
aclname,
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
errp);
if (!ioc->session) {
if (!tioc->session) {
goto error;
}
qcrypto_tls_session_set_callbacks(
ioc->session,
tioc->session,
qio_channel_tls_write_handler,
qio_channel_tls_read_handler,
ioc);
tioc);
trace_qio_channel_tls_new_server(ioc, master, creds, aclname);
return ioc;
trace_qio_channel_tls_new_server(tioc, master, creds, aclname);
return tioc;
error:
object_unref(OBJECT(ioc));
object_unref(OBJECT(tioc));
return NULL;
}
@@ -116,6 +119,7 @@ qio_channel_tls_new_client(QIOChannel *master,
ioc = QIO_CHANNEL(tioc);
tioc->master = master;
ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
}
+1
View File
@@ -883,6 +883,7 @@ qio_channel_websock_new_server(QIOChannel *master)
ioc = QIO_CHANNEL(wioc);
wioc->master = master;
ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
}
-2
View File
@@ -3016,8 +3016,6 @@ static void pgb_dynamic(const char *image_name, uintptr_t guest_loaddr,
uintptr_t brk, ret;
PGBAddrs ga;
assert(QEMU_IS_ALIGNED(guest_loaddr, align));
/* Try the identity map first. */
if (pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, true)) {
brk = (uintptr_t)sbrk(0);
+42 -15
View File
@@ -2277,18 +2277,13 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
switch (optname) {
case ALG_SET_KEY:
{
char *alg_key = g_malloc(optlen);
char *alg_key = lock_user(VERIFY_READ, optval_addr, optlen, 1);
if (!alg_key) {
return -TARGET_ENOMEM;
}
if (copy_from_user(alg_key, optval_addr, optlen)) {
g_free(alg_key);
return -TARGET_EFAULT;
}
ret = get_errno(setsockopt(sockfd, level, optname,
alg_key, optlen));
g_free(alg_key);
unlock_user(alg_key, optval_addr, optlen);
break;
}
case ALG_SET_AEAD_AUTHSIZE:
@@ -7203,11 +7198,17 @@ static inline int tswapid(int id)
#else
#define __NR_sys_setresgid __NR_setresgid
#endif
#ifdef __NR_setgroups32
#define __NR_sys_setgroups __NR_setgroups32
#else
#define __NR_sys_setgroups __NR_setgroups
#endif
_syscall1(int, sys_setuid, uid_t, uid)
_syscall1(int, sys_setgid, gid_t, gid)
_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
_syscall2(int, sys_setgroups, int, size, gid_t *, grouplist)
void syscall_init(void)
{
@@ -7994,6 +7995,10 @@ static void open_self_maps_4(const struct open_self_maps_data *d,
path = "[heap]";
} else if (start == info->vdso) {
path = "[vdso]";
#ifdef TARGET_X86_64
} else if (start == TARGET_VSYSCALL_PAGE) {
path = "[vsyscall]";
#endif
}
/* Except null device (MAP_ANON), adjust offset for this fragment. */
@@ -8082,6 +8087,18 @@ static int open_self_maps_2(void *opaque, target_ulong guest_start,
uintptr_t host_start = (uintptr_t)g2h_untagged(guest_start);
uintptr_t host_last = (uintptr_t)g2h_untagged(guest_end - 1);
#ifdef TARGET_X86_64
/*
* Because of the extremely high position of the page within the guest
* virtual address space, this is not backed by host memory at all.
* Therefore the loop below would fail. This is the only instance
* of not having host backing memory.
*/
if (guest_start == TARGET_VSYSCALL_PAGE) {
return open_self_maps_3(opaque, guest_start, guest_end, flags);
}
#endif
while (1) {
IntervalTreeNode *n =
interval_tree_iter_first(d->host_maps, host_start, host_start);
@@ -9154,14 +9171,24 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_waitid
case TARGET_NR_waitid:
{
struct rusage ru;
siginfo_t info;
info.si_pid = 0;
ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
if (!is_error(ret) && arg3 && info.si_pid != 0) {
if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
ret = get_errno(safe_waitid(arg1, arg2, (arg3 ? &info : NULL),
arg4, (arg5 ? &ru : NULL)));
if (!is_error(ret)) {
if (arg3) {
p = lock_user(VERIFY_WRITE, arg3,
sizeof(target_siginfo_t), 0);
if (!p) {
return -TARGET_EFAULT;
}
host_to_target_siginfo(p, &info);
unlock_user(p, arg3, sizeof(target_siginfo_t));
}
if (arg5 && host_to_target_rusage(arg5, &ru)) {
return -TARGET_EFAULT;
host_to_target_siginfo(p, &info);
unlock_user(p, arg3, sizeof(target_siginfo_t));
}
}
}
return ret;
@@ -11769,7 +11796,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
unlock_user(target_grouplist, arg2,
gidsetsize * sizeof(target_id));
}
return get_errno(setgroups(gidsetsize, grouplist));
return get_errno(sys_setgroups(gidsetsize, grouplist));
}
case TARGET_NR_fchown:
return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
@@ -12105,7 +12132,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
}
unlock_user(target_grouplist, arg2, 0);
}
return get_errno(setgroups(gidsetsize, grouplist));
return get_errno(sys_setgroups(gidsetsize, grouplist));
}
#endif
#ifdef TARGET_NR_fchown32
+4 -1
View File
@@ -409,7 +409,10 @@ static int init_blk_migration(QEMUFile *f)
}
sectors = bdrv_nb_sectors(bs);
if (sectors <= 0) {
if (sectors == 0) {
continue;
}
if (sectors < 0) {
ret = sectors;
bdrv_next_cleanup(&it);
goto out;
+10 -8
View File
@@ -830,6 +830,16 @@ static void *colo_process_incoming_thread(void *opaque)
return NULL;
}
/* Make sure all file formats throw away their mutable metadata */
qemu_mutex_lock_iothread();
bdrv_activate_all(&local_err);
if (local_err) {
qemu_mutex_unlock_iothread();
error_report_err(local_err);
return NULL;
}
qemu_mutex_unlock_iothread();
failover_init_state();
mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
@@ -917,7 +927,6 @@ out:
int coroutine_fn colo_incoming_co(void)
{
MigrationIncomingState *mis = migration_incoming_get_current();
Error *local_err = NULL;
QemuThread th;
assert(qemu_mutex_iothread_locked());
@@ -926,13 +935,6 @@ int coroutine_fn colo_incoming_co(void)
return 0;
}
/* Make sure all file formats throw away their mutable metadata */
bdrv_activate_all(&local_err);
if (local_err) {
error_report_err(local_err);
return -EINVAL;
}
qemu_thread_create(&th, "COLO incoming", colo_process_incoming_thread,
mis, QEMU_THREAD_JOINABLE);
+9 -2
View File
@@ -46,12 +46,19 @@ void file_start_outgoing_migration(MigrationState *s,
trace_migration_file_outgoing(filename);
fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC,
0600, errp);
fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY, 0600, errp);
if (!fioc) {
return;
}
if (ftruncate(fioc->fd, offset)) {
error_setg_errno(errp, errno,
"failed to truncate migration file to offset %" PRIx64,
offset);
object_unref(OBJECT(fioc));
return;
}
ioc = QIO_CHANNEL(fioc);
if (offset && qio_channel_io_seek(ioc, offset, SEEK_SET, errp) < 0) {
return;
+8
View File
@@ -2408,6 +2408,8 @@ static int postcopy_start(MigrationState *ms, Error **errp)
migration_wait_main_channel(ms);
if (postcopy_preempt_establish_channel(ms)) {
migrate_set_state(&ms->state, ms->state, MIGRATION_STATUS_FAILED);
error_setg(errp, "%s: Failed to establish preempt channel",
__func__);
return -1;
}
}
@@ -2427,17 +2429,22 @@ static int postcopy_start(MigrationState *ms, Error **errp)
global_state_store();
ret = migration_stop_vm(RUN_STATE_FINISH_MIGRATE);
if (ret < 0) {
error_setg_errno(errp, -ret, "%s: Failed to stop the VM", __func__);
goto fail;
}
ret = migration_maybe_pause(ms, &cur_state,
MIGRATION_STATUS_POSTCOPY_ACTIVE);
if (ret < 0) {
error_setg_errno(errp, -ret, "%s: Failed in migration_maybe_pause()",
__func__);
goto fail;
}
ret = bdrv_inactivate_all();
if (ret < 0) {
error_setg_errno(errp, -ret, "%s: Failed in bdrv_inactivate_all()",
__func__);
goto fail;
}
restart_block = true;
@@ -2514,6 +2521,7 @@ static int postcopy_start(MigrationState *ms, Error **errp)
/* Now send that blob */
if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) {
error_setg(errp, "%s: Failed to send packaged data", __func__);
goto fail_closefb;
}
qemu_fclose(fb);
+1 -1
View File
@@ -3357,7 +3357,7 @@ static int qemu_rdma_accept(RDMAContext *rdma)
goto err_rdma_dest_wait;
}
isock->host = rdma->host;
isock->host = g_strdup(rdma->host);
isock->port = g_strdup_printf("%d", rdma->port);
/*
+21
View File
@@ -2343,6 +2343,27 @@ static int loadvm_handle_cmd_packaged(MigrationIncomingState *mis)
QEMUFile *packf = qemu_file_new_input(QIO_CHANNEL(bioc));
/*
* Before loading the guest states, ensure that the preempt channel has
* been ready to use, as some of the states (e.g. via virtio_load) might
* trigger page faults that will be handled through the preempt channel.
* So yield to the main thread in the case that the channel create event
* hasn't been dispatched.
*
* TODO: if we can move migration loadvm out of main thread, then we
* won't block main thread from polling the accept() fds. We can drop
* this as a whole when that is done.
*/
do {
if (!migrate_postcopy_preempt() || !qemu_in_coroutine() ||
mis->postcopy_qemufile_dst) {
break;
}
aio_co_schedule(qemu_get_current_aio_context(), qemu_coroutine_self());
qemu_coroutine_yield();
} while (1);
ret = qemu_loadvm_state_main(packf, mis);
trace_loadvm_handle_cmd_packaged_main(ret);
qemu_fclose(packf);
+1 -1
View File
@@ -260,7 +260,7 @@ void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
}
if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
error_setg(errp, "Memory at address 0x%" HWADDR_PRIx "is not RAM", addr);
error_setg(errp, "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr);
memory_region_unref(mrs.mr);
return NULL;
}
+24 -4
View File
@@ -596,13 +596,31 @@ static int nbd_request_simple_option(QIOChannel *ioc, int opt, bool strict,
return 1;
}
/* Callback to learn when QIO TLS upgrade is complete */
struct NBDTLSClientHandshakeData {
bool complete;
Error *error;
GMainLoop *loop;
};
static void nbd_client_tls_handshake(QIOTask *task, void *opaque)
{
struct NBDTLSClientHandshakeData *data = opaque;
qio_task_propagate_error(task, &data->error);
data->complete = true;
if (data->loop) {
g_main_loop_quit(data->loop);
}
}
static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
QCryptoTLSCreds *tlscreds,
const char *hostname, Error **errp)
{
int ret;
QIOChannelTLS *tioc;
struct NBDTLSHandshakeData data = { 0 };
struct NBDTLSClientHandshakeData data = { 0 };
ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp);
if (ret <= 0) {
@@ -619,18 +637,20 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
return NULL;
}
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls");
data.loop = g_main_loop_new(g_main_context_default(), FALSE);
trace_nbd_receive_starttls_tls_handshake();
qio_channel_tls_handshake(tioc,
nbd_tls_handshake,
nbd_client_tls_handshake,
&data,
NULL,
NULL);
if (!data.complete) {
data.loop = g_main_loop_new(g_main_context_default(), FALSE);
g_main_loop_run(data.loop);
assert(data.complete);
g_main_loop_unref(data.loop);
}
g_main_loop_unref(data.loop);
if (data.error) {
error_propagate(errp, data.error);
object_unref(OBJECT(tioc));
-11
View File
@@ -47,17 +47,6 @@ int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
}
void nbd_tls_handshake(QIOTask *task,
void *opaque)
{
struct NBDTLSHandshakeData *data = opaque;
qio_task_propagate_error(task, &data->error);
data->complete = true;
g_main_loop_quit(data->loop);
}
const char *nbd_opt_lookup(uint32_t opt)
{
switch (opt) {
-10
View File
@@ -72,16 +72,6 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size,
return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
}
struct NBDTLSHandshakeData {
GMainLoop *loop;
bool complete;
Error *error;
};
void nbd_tls_handshake(QIOTask *task,
void *opaque);
int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);
#endif
+245 -93
View File
@@ -122,26 +122,28 @@ struct NBDMetaContexts {
};
struct NBDClient {
int refcount;
int refcount; /* atomic */
void (*close_fn)(NBDClient *client, bool negotiated);
QemuMutex lock;
NBDExport *exp;
QCryptoTLSCreds *tlscreds;
char *tlsauthz;
QIOChannelSocket *sioc; /* The underlying data channel */
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
Coroutine *recv_coroutine;
Coroutine *recv_coroutine; /* protected by lock */
CoMutex send_lock;
Coroutine *send_coroutine;
bool read_yielding;
bool quiescing;
bool read_yielding; /* protected by lock */
bool quiescing; /* protected by lock */
QTAILQ_ENTRY(NBDClient) next;
int nb_requests;
bool closing;
int nb_requests; /* protected by lock */
bool closing; /* protected by lock */
uint32_t check_align; /* If non-zero, check for aligned client requests */
@@ -193,8 +195,9 @@ static inline void set_be_option_rep(NBDOptionReply *rep, uint32_t option,
/* Send a reply header, including length, but no payload.
* Return -errno on error, 0 on success. */
static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
uint32_t len, Error **errp)
static coroutine_fn int
nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
uint32_t len, Error **errp)
{
NBDOptionReply rep;
@@ -209,15 +212,15 @@ static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
/* Send a reply header with default 0 length.
* Return -errno on error, 0 on success. */
static int nbd_negotiate_send_rep(NBDClient *client, uint32_t type,
Error **errp)
static coroutine_fn int
nbd_negotiate_send_rep(NBDClient *client, uint32_t type, Error **errp)
{
return nbd_negotiate_send_rep_len(client, type, 0, errp);
}
/* Send an error reply.
* Return -errno on error, 0 on success. */
static int G_GNUC_PRINTF(4, 0)
static coroutine_fn int G_GNUC_PRINTF(4, 0)
nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
Error **errp, const char *fmt, va_list va)
{
@@ -257,7 +260,7 @@ nbd_sanitize_name(const char *name)
/* Send an error reply.
* Return -errno on error, 0 on success. */
static int G_GNUC_PRINTF(4, 5)
static coroutine_fn int G_GNUC_PRINTF(4, 5)
nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
Error **errp, const char *fmt, ...)
{
@@ -273,7 +276,7 @@ nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
/* Drop remainder of the current option, and send a reply with the
* given error type and message. Return -errno on read or write
* failure; or 0 if connection is still live. */
static int G_GNUC_PRINTF(4, 0)
static coroutine_fn int G_GNUC_PRINTF(4, 0)
nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
const char *fmt, va_list va)
{
@@ -286,7 +289,7 @@ nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
return ret;
}
static int G_GNUC_PRINTF(4, 5)
static coroutine_fn int G_GNUC_PRINTF(4, 5)
nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
const char *fmt, ...)
{
@@ -300,7 +303,7 @@ nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
return ret;
}
static int G_GNUC_PRINTF(3, 4)
static coroutine_fn int G_GNUC_PRINTF(3, 4)
nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
{
int ret;
@@ -317,8 +320,9 @@ nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
* If @check_nul, require that no NUL bytes appear in buffer.
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success. */
static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
bool check_nul, Error **errp)
static coroutine_fn int
nbd_opt_read(NBDClient *client, void *buffer, size_t size,
bool check_nul, Error **errp)
{
if (size > client->optlen) {
return nbd_opt_invalid(client, errp,
@@ -341,7 +345,8 @@ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
/* Drop size bytes from the unparsed payload of the current option.
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success. */
static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
static coroutine_fn int
nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
{
if (size > client->optlen) {
return nbd_opt_invalid(client, errp,
@@ -364,8 +369,9 @@ static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success.
*/
static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
Error **errp)
static coroutine_fn int
nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
Error **errp)
{
int ret;
uint32_t len;
@@ -400,8 +406,8 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
/* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload.
* Return -errno on error, 0 on success. */
static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
Error **errp)
static coroutine_fn int
nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, Error **errp)
{
ERRP_GUARD();
size_t name_len, desc_len;
@@ -442,7 +448,8 @@ static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
/* Process the NBD_OPT_LIST command, with a potential series of replies.
* Return -errno on error, 0 on success. */
static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
static coroutine_fn int
nbd_negotiate_handle_list(NBDClient *client, Error **errp)
{
NBDExport *exp;
assert(client->opt == NBD_OPT_LIST);
@@ -457,7 +464,8 @@ static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
}
static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
static coroutine_fn void
nbd_check_meta_export(NBDClient *client, NBDExport *exp)
{
if (exp != client->contexts.exp) {
client->contexts.count = 0;
@@ -466,8 +474,9 @@ static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
/* Send a reply to NBD_OPT_EXPORT_NAME.
* Return -errno on error, 0 on success. */
static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
Error **errp)
static coroutine_fn int
nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
Error **errp)
{
ERRP_GUARD();
g_autofree char *name = NULL;
@@ -534,9 +543,9 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
/* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes.
* The buffer does NOT include the info type prefix.
* Return -errno on error, 0 if ready to send more. */
static int nbd_negotiate_send_info(NBDClient *client,
uint16_t info, uint32_t length, void *buf,
Error **errp)
static coroutine_fn int
nbd_negotiate_send_info(NBDClient *client, uint16_t info, uint32_t length,
void *buf, Error **errp)
{
int rc;
@@ -563,7 +572,8 @@ static int nbd_negotiate_send_info(NBDClient *client,
* -errno transmission error occurred or @fatal was requested, errp is set
* 0 error message successfully sent to client, errp is not set
*/
static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
static coroutine_fn int
nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
{
int ret;
@@ -581,7 +591,8 @@ static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
/* Handle NBD_OPT_INFO and NBD_OPT_GO.
* Return -errno on error, 0 if ready for next option, and 1 to move
* into transmission phase. */
static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
static coroutine_fn int
nbd_negotiate_handle_info(NBDClient *client, Error **errp)
{
int rc;
g_autofree char *name = NULL;
@@ -746,15 +757,33 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
return rc;
}
/* Callback to learn when QIO TLS upgrade is complete */
struct NBDTLSServerHandshakeData {
bool complete;
Error *error;
Coroutine *co;
};
static void
nbd_server_tls_handshake(QIOTask *task, void *opaque)
{
struct NBDTLSServerHandshakeData *data = opaque;
qio_task_propagate_error(task, &data->error);
data->complete = true;
if (!qemu_coroutine_entered(data->co)) {
aio_co_wake(data->co);
}
}
/* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the
* new channel for all further (now-encrypted) communication. */
static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
Error **errp)
static coroutine_fn QIOChannel *
nbd_negotiate_handle_starttls(NBDClient *client, Error **errp)
{
QIOChannel *ioc;
QIOChannelTLS *tioc;
struct NBDTLSHandshakeData data = { 0 };
struct NBDTLSServerHandshakeData data = { 0 };
assert(client->opt == NBD_OPT_STARTTLS);
@@ -775,17 +804,18 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls");
trace_nbd_negotiate_handle_starttls_handshake();
data.loop = g_main_loop_new(g_main_context_default(), FALSE);
data.co = qemu_coroutine_self();
qio_channel_tls_handshake(tioc,
nbd_tls_handshake,
nbd_server_tls_handshake,
&data,
NULL,
NULL);
if (!data.complete) {
g_main_loop_run(data.loop);
qemu_coroutine_yield();
assert(data.complete);
}
g_main_loop_unref(data.loop);
if (data.error) {
object_unref(OBJECT(tioc));
error_propagate(errp, data.error);
@@ -801,10 +831,9 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
*
* For NBD_OPT_LIST_META_CONTEXT @context_id is ignored, 0 is used instead.
*/
static int nbd_negotiate_send_meta_context(NBDClient *client,
const char *context,
uint32_t context_id,
Error **errp)
static coroutine_fn int
nbd_negotiate_send_meta_context(NBDClient *client, const char *context,
uint32_t context_id, Error **errp)
{
NBDOptionReplyMetaContext opt;
struct iovec iov[] = {
@@ -829,8 +858,9 @@ static int nbd_negotiate_send_meta_context(NBDClient *client,
* Return true if @query matches @pattern, or if @query is empty when
* the @client is performing _LIST_.
*/
static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
const char *query)
static coroutine_fn bool
nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
const char *query)
{
if (!*query) {
trace_nbd_negotiate_meta_query_parse("empty");
@@ -847,7 +877,8 @@ static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
/*
* Return true and adjust @str in place if it begins with @prefix.
*/
static bool nbd_strshift(const char **str, const char *prefix)
static coroutine_fn bool
nbd_strshift(const char **str, const char *prefix)
{
size_t len = strlen(prefix);
@@ -863,8 +894,9 @@ static bool nbd_strshift(const char **str, const char *prefix)
* Handle queries to 'base' namespace. For now, only the base:allocation
* context is available. Return true if @query has been handled.
*/
static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
const char *query)
static coroutine_fn bool
nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
const char *query)
{
if (!nbd_strshift(&query, "base:")) {
return false;
@@ -883,8 +915,9 @@ static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
* and qemu:allocation-depth contexts are available. Return true if @query
* has been handled.
*/
static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
const char *query)
static coroutine_fn bool
nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
const char *query)
{
size_t i;
@@ -948,8 +981,9 @@ static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
*
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success. */
static int nbd_negotiate_meta_query(NBDClient *client,
NBDMetaContexts *meta, Error **errp)
static coroutine_fn int
nbd_negotiate_meta_query(NBDClient *client,
NBDMetaContexts *meta, Error **errp)
{
int ret;
g_autofree char *query = NULL;
@@ -988,7 +1022,8 @@ static int nbd_negotiate_meta_query(NBDClient *client,
* Handle NBD_OPT_LIST_META_CONTEXT and NBD_OPT_SET_META_CONTEXT
*
* Return -errno on I/O error, or 0 if option was completely handled. */
static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
static coroutine_fn int
nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
{
int ret;
g_autofree char *export_name = NULL;
@@ -1116,7 +1151,8 @@ static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
* 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect,
* errp is not set
*/
static int nbd_negotiate_options(NBDClient *client, Error **errp)
static coroutine_fn int
nbd_negotiate_options(NBDClient *client, Error **errp)
{
uint32_t flags;
bool fixedNewstyle = false;
@@ -1415,11 +1451,18 @@ nbd_read_eof(NBDClient *client, void *buffer, size_t size, Error **errp)
len = qio_channel_readv(client->ioc, &iov, 1, errp);
if (len == QIO_CHANNEL_ERR_BLOCK) {
client->read_yielding = true;
WITH_QEMU_LOCK_GUARD(&client->lock) {
client->read_yielding = true;
/* Prompt main loop thread to re-run nbd_drained_poll() */
aio_wait_kick();
}
qio_channel_yield(client->ioc, G_IO_IN);
client->read_yielding = false;
if (client->quiescing) {
return -EAGAIN;
WITH_QEMU_LOCK_GUARD(&client->lock) {
client->read_yielding = false;
if (client->quiescing) {
return -EAGAIN;
}
}
continue;
} else if (len < 0) {
@@ -1501,14 +1544,17 @@ static int coroutine_fn nbd_receive_request(NBDClient *client, NBDRequest *reque
#define MAX_NBD_REQUESTS 16
/* Runs in export AioContext and main loop thread */
void nbd_client_get(NBDClient *client)
{
client->refcount++;
qatomic_inc(&client->refcount);
}
void nbd_client_put(NBDClient *client)
{
if (--client->refcount == 0) {
assert(qemu_in_main_thread());
if (qatomic_fetch_dec(&client->refcount) == 1) {
/* The last reference should be dropped by client->close,
* which is called by client_close.
*/
@@ -1525,17 +1571,47 @@ void nbd_client_put(NBDClient *client)
blk_exp_unref(&client->exp->common);
}
g_free(client->contexts.bitmaps);
qemu_mutex_destroy(&client->lock);
g_free(client);
}
}
/*
* Tries to release the reference to @client, but only if other references
* remain. This is an optimization for the common case where we want to avoid
* the expense of scheduling nbd_client_put() in the main loop thread.
*
* Returns true upon success or false if the reference was not released because
* it is the last reference.
*/
static bool nbd_client_put_nonzero(NBDClient *client)
{
int old = qatomic_read(&client->refcount);
int expected;
do {
if (old == 1) {
return false;
}
expected = old;
old = qatomic_cmpxchg(&client->refcount, expected, expected - 1);
} while (old != expected);
return true;
}
static void client_close(NBDClient *client, bool negotiated)
{
if (client->closing) {
return;
}
assert(qemu_in_main_thread());
client->closing = true;
WITH_QEMU_LOCK_GUARD(&client->lock) {
if (client->closing) {
return;
}
client->closing = true;
}
/* Force requests to finish. They will drop their own references,
* then we'll close the socket and free the NBDClient.
@@ -1549,6 +1625,7 @@ static void client_close(NBDClient *client, bool negotiated)
}
}
/* Runs in export AioContext with client->lock held */
static NBDRequestData *nbd_request_get(NBDClient *client)
{
NBDRequestData *req;
@@ -1562,6 +1639,7 @@ static NBDRequestData *nbd_request_get(NBDClient *client)
return req;
}
/* Runs in export AioContext with client->lock held */
static void nbd_request_put(NBDRequestData *req)
{
NBDClient *client = req->client;
@@ -1587,14 +1665,18 @@ static void blk_aio_attached(AioContext *ctx, void *opaque)
NBDExport *exp = opaque;
NBDClient *client;
assert(qemu_in_main_thread());
trace_nbd_blk_aio_attached(exp->name, ctx);
exp->common.ctx = ctx;
QTAILQ_FOREACH(client, &exp->clients, next) {
assert(client->nb_requests == 0);
assert(client->recv_coroutine == NULL);
assert(client->send_coroutine == NULL);
WITH_QEMU_LOCK_GUARD(&client->lock) {
assert(client->nb_requests == 0);
assert(client->recv_coroutine == NULL);
assert(client->send_coroutine == NULL);
}
}
}
@@ -1602,6 +1684,8 @@ static void blk_aio_detach(void *opaque)
{
NBDExport *exp = opaque;
assert(qemu_in_main_thread());
trace_nbd_blk_aio_detach(exp->name, exp->common.ctx);
exp->common.ctx = NULL;
@@ -1612,8 +1696,12 @@ static void nbd_drained_begin(void *opaque)
NBDExport *exp = opaque;
NBDClient *client;
assert(qemu_in_main_thread());
QTAILQ_FOREACH(client, &exp->clients, next) {
client->quiescing = true;
WITH_QEMU_LOCK_GUARD(&client->lock) {
client->quiescing = true;
}
}
}
@@ -1622,28 +1710,48 @@ static void nbd_drained_end(void *opaque)
NBDExport *exp = opaque;
NBDClient *client;
assert(qemu_in_main_thread());
QTAILQ_FOREACH(client, &exp->clients, next) {
client->quiescing = false;
nbd_client_receive_next_request(client);
WITH_QEMU_LOCK_GUARD(&client->lock) {
client->quiescing = false;
nbd_client_receive_next_request(client);
}
}
}
/* Runs in export AioContext */
static void nbd_wake_read_bh(void *opaque)
{
NBDClient *client = opaque;
qio_channel_wake_read(client->ioc);
}
static bool nbd_drained_poll(void *opaque)
{
NBDExport *exp = opaque;
NBDClient *client;
QTAILQ_FOREACH(client, &exp->clients, next) {
if (client->nb_requests != 0) {
/*
* If there's a coroutine waiting for a request on nbd_read_eof()
* enter it here so we don't depend on the client to wake it up.
*/
if (client->recv_coroutine != NULL && client->read_yielding) {
qio_channel_wake_read(client->ioc);
}
assert(qemu_in_main_thread());
return true;
QTAILQ_FOREACH(client, &exp->clients, next) {
WITH_QEMU_LOCK_GUARD(&client->lock) {
if (client->nb_requests != 0) {
/*
* If there's a coroutine waiting for a request on nbd_read_eof()
* enter it here so we don't depend on the client to wake it up.
*
* Schedule a BH in the export AioContext to avoid missing the
* wake up due to the race between qio_channel_wake_read() and
* qio_channel_yield().
*/
if (client->recv_coroutine != NULL && client->read_yielding) {
aio_bh_schedule_oneshot(nbd_export_aio_context(client->exp),
nbd_wake_read_bh, client);
}
return true;
}
}
}
@@ -1654,6 +1762,8 @@ static void nbd_eject_notifier(Notifier *n, void *data)
{
NBDExport *exp = container_of(n, NBDExport, eject_notifier);
assert(qemu_in_main_thread());
blk_exp_request_shutdown(&exp->common);
}
@@ -2539,7 +2649,6 @@ static int coroutine_fn nbd_co_receive_request(NBDRequestData *req,
int ret;
g_assert(qemu_in_coroutine());
assert(client->recv_coroutine == qemu_coroutine_self());
ret = nbd_receive_request(client, request, errp);
if (ret < 0) {
return ret;
@@ -2935,16 +3044,24 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
/* Owns a reference to the NBDClient passed as opaque. */
static coroutine_fn void nbd_trip(void *opaque)
{
NBDClient *client = opaque;
NBDRequestData *req;
NBDRequestData *req = opaque;
NBDClient *client = req->client;
NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */
int ret;
Error *local_err = NULL;
/*
* Note that nbd_client_put() and client_close() must be called from the
* main loop thread. Use aio_co_reschedule_self() to switch AioContext
* before calling these functions.
*/
trace_nbd_trip();
qemu_mutex_lock(&client->lock);
if (client->closing) {
nbd_client_put(client);
return;
goto done;
}
if (client->quiescing) {
@@ -2952,14 +3069,25 @@ static coroutine_fn void nbd_trip(void *opaque)
* We're switching between AIO contexts. Don't attempt to receive a new
* request and kick the main context which may be waiting for us.
*/
nbd_client_put(client);
client->recv_coroutine = NULL;
aio_wait_kick();
return;
goto done;
}
req = nbd_request_get(client);
ret = nbd_co_receive_request(req, &request, &local_err);
/*
* nbd_co_receive_request() returns -EAGAIN when nbd_drained_begin() has
* set client->quiescing but by the time we get back nbd_drained_end() may
* have already cleared client->quiescing. In that case we try again
* because nothing else will spawn an nbd_trip() coroutine until we set
* client->recv_coroutine = NULL further down.
*/
do {
assert(client->recv_coroutine == qemu_coroutine_self());
qemu_mutex_unlock(&client->lock);
ret = nbd_co_receive_request(req, &request, &local_err);
qemu_mutex_lock(&client->lock);
} while (ret == -EAGAIN && !client->quiescing);
client->recv_coroutine = NULL;
if (client->closing) {
@@ -2971,15 +3099,16 @@ static coroutine_fn void nbd_trip(void *opaque)
}
if (ret == -EAGAIN) {
assert(client->quiescing);
goto done;
}
nbd_client_receive_next_request(client);
if (ret == -EIO) {
goto disconnect;
}
qemu_mutex_unlock(&client->lock);
qio_channel_set_cork(client->ioc, true);
if (ret < 0) {
@@ -2999,6 +3128,10 @@ static coroutine_fn void nbd_trip(void *opaque)
g_free(request.contexts->bitmaps);
g_free(request.contexts);
}
qio_channel_set_cork(client->ioc, false);
qemu_mutex_lock(&client->lock);
if (ret < 0) {
error_prepend(&local_err, "Failed to send reply: ");
goto disconnect;
@@ -3013,27 +3146,43 @@ static coroutine_fn void nbd_trip(void *opaque)
goto disconnect;
}
qio_channel_set_cork(client->ioc, false);
done:
nbd_request_put(req);
nbd_client_put(client);
qemu_mutex_unlock(&client->lock);
if (!nbd_client_put_nonzero(client)) {
aio_co_reschedule_self(qemu_get_aio_context());
nbd_client_put(client);
}
return;
disconnect:
if (local_err) {
error_reportf_err(local_err, "Disconnect client, due to: ");
}
nbd_request_put(req);
qemu_mutex_unlock(&client->lock);
aio_co_reschedule_self(qemu_get_aio_context());
client_close(client, true);
nbd_client_put(client);
}
/*
* Runs in export AioContext and main loop thread. Caller must hold
* client->lock.
*/
static void nbd_client_receive_next_request(NBDClient *client)
{
NBDRequestData *req;
if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS &&
!client->quiescing) {
nbd_client_get(client);
client->recv_coroutine = qemu_coroutine_create(nbd_trip, client);
req = nbd_request_get(client);
client->recv_coroutine = qemu_coroutine_create(nbd_trip, req);
aio_co_schedule(client->exp->common.ctx, client->recv_coroutine);
}
}
@@ -3053,7 +3202,9 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
return;
}
nbd_client_receive_next_request(client);
WITH_QEMU_LOCK_GUARD(&client->lock) {
nbd_client_receive_next_request(client);
}
}
/*
@@ -3070,6 +3221,7 @@ void nbd_client_new(QIOChannelSocket *sioc,
Coroutine *co;
client = g_new0(NBDClient, 1);
qemu_mutex_init(&client->lock);
client->refcount = 1;
client->tlscreds = tlscreds;
if (tlscreds) {
-7
View File
@@ -1660,8 +1660,6 @@
#
# Takes a synchronous snapshot of a block device.
#
# For the arguments, see the documentation of BlockdevSnapshotSync.
#
# Returns:
# - nothing on success
# - If @device is not a valid block device, DeviceNotFound
@@ -1691,8 +1689,6 @@
# device, the block device changes to using 'overlay' as its new
# active image.
#
# For the arguments, see the documentation of BlockdevSnapshot.
#
# Features:
#
# @allow-write-only-overlay: If present, the check whether this
@@ -6029,9 +6025,6 @@
# string, or a snapshot with name already exists, the operation will
# fail.
#
# For the arguments, see the documentation of
# BlockdevSnapshotInternal.
#
# Returns:
# - nothing on success
# - If @device is not a valid block device, GenericError
+3 -3
View File
@@ -149,14 +149,14 @@ SRST
platform and configuration dependent.
``interleave-granularity=granularity`` sets the granularity of
interleave. Default 256KiB. Only 256KiB, 512KiB, 1024KiB, 2048KiB
4096KiB, 8192KiB and 16384KiB granularities supported.
interleave. Default 256 (bytes). Only 256, 512, 1k, 2k,
4k, 8k and 16k granularities supported.
Example:
::
-machine cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512k
-machine cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512
ERST
DEF("M", HAS_ARG, QEMU_OPTION_M,
+1 -1
View File
@@ -47,5 +47,5 @@ meson subprojects download $SUBPROJECTS
CryptoPkg/Library/OpensslLib/openssl \
MdeModulePkg/Library/BrotliCustomDecompressLib/brotli)
popd
tar --exclude=.git -cjf ${destination}.tar.bz2 ${destination}
tar --exclude=.git -cJf ${destination}.tar.xz ${destination}
rm -rf ${destination}
+11 -12
View File
@@ -858,19 +858,18 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
return;
}
dev = qdev_device_add(opts, errp);
/*
* Drain all pending RCU callbacks. This is done because
* some bus related operations can delay a device removal
* (in this case this can happen if device is added and then
* removed due to a configuration error)
* to a RCU callback, but user might expect that this interface
* will finish its job completely once qmp command returns result
* to the user
*/
drain_call_rcu();
if (!dev) {
/*
* Drain all pending RCU callbacks. This is done because
* some bus related operations can delay a device removal
* (in this case this can happen if device is added and then
* removed due to a configuration error)
* to a RCU callback, but user might expect that this interface
* will finish its job completely once qmp command returns result
* to the user
*/
drain_call_rcu();
qemu_opts_del(opts);
return;
}
+5 -1
View File
@@ -109,7 +109,11 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
* No explicit bits enabled, and no implicit bits from sve-max-vq.
*/
if (!cpu_isar_feature(aa64_sve, cpu)) {
/* SVE is disabled and so are all vector lengths. Good. */
/*
* SVE is disabled and so are all vector lengths. Good.
* Disable all SVE extensions as well.
*/
cpu->isar.id_aa64zfr0 = 0;
return;
}
+5 -2
View File
@@ -3703,6 +3703,8 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
ARMMMUIdx mmu_idx;
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE);
bool for_el3 = false;
ARMSecuritySpace ss;
switch (ri->opc2 & 6) {
case 0:
@@ -3720,6 +3722,7 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
break;
case 6: /* AT S1E3R, AT S1E3W */
mmu_idx = ARMMMUIdx_E3;
for_el3 = true;
break;
default:
g_assert_not_reached();
@@ -3738,8 +3741,8 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
g_assert_not_reached();
}
env->cp15.par_el[1] = do_ats_write(env, value, access_type,
mmu_idx, arm_security_space(env));
ss = for_el3 ? arm_security_space(env) : arm_security_space_below_el3(env);
env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx, ss);
#else
/* Handled by hardware accelerator. */
g_assert_not_reached();
+65 -65
View File
@@ -392,85 +392,85 @@ struct hvf_sreg_match {
};
static struct hvf_sreg_match hvf_sreg_match[] = {
{ HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 7) },
{ HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 4) },
{ HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 5) },
{ HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 6) },
{ HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 7) },
{ HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 4) },
{ HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 5) },
{ HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 6) },
{ HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 7) },
#ifdef SYNC_NO_RAW_REGS
/*
@@ -482,7 +482,7 @@ static struct hvf_sreg_match hvf_sreg_match[] = {
{ HV_SYS_REG_MPIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 5) },
{ HV_SYS_REG_ID_AA64PFR0_EL1, HVF_SYSREG(0, 4, 3, 0, 0) },
#endif
{ HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 2) },
{ HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 1) },
{ HV_SYS_REG_ID_AA64DFR0_EL1, HVF_SYSREG(0, 5, 3, 0, 0) },
{ HV_SYS_REG_ID_AA64DFR1_EL1, HVF_SYSREG(0, 5, 3, 0, 1) },
{ HV_SYS_REG_ID_AA64ISAR0_EL1, HVF_SYSREG(0, 6, 3, 0, 0) },
+45 -32
View File
@@ -1083,11 +1083,32 @@ void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
}
}
typedef uint64_t IMOPFn(uint64_t, uint64_t, uint64_t, uint8_t, bool);
typedef uint32_t IMOPFn32(uint32_t, uint32_t, uint32_t, uint8_t, bool);
static inline void do_imopa_s(uint32_t *za, uint32_t *zn, uint32_t *zm,
uint8_t *pn, uint8_t *pm,
uint32_t desc, IMOPFn32 *fn)
{
intptr_t row, col, oprsz = simd_oprsz(desc) / 4;
bool neg = simd_data(desc);
static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
uint8_t *pn, uint8_t *pm,
uint32_t desc, IMOPFn *fn)
for (row = 0; row < oprsz; ++row) {
uint8_t pa = (pn[H1(row >> 1)] >> ((row & 1) * 4)) & 0xf;
uint32_t *za_row = &za[tile_vslice_index(row)];
uint32_t n = zn[H4(row)];
for (col = 0; col < oprsz; ++col) {
uint8_t pb = pm[H1(col >> 1)] >> ((col & 1) * 4);
uint32_t *a = &za_row[H4(col)];
*a = fn(n, zm[H4(col)], *a, pa & pb, neg);
}
}
}
typedef uint64_t IMOPFn64(uint64_t, uint64_t, uint64_t, uint8_t, bool);
static inline void do_imopa_d(uint64_t *za, uint64_t *zn, uint64_t *zm,
uint8_t *pn, uint8_t *pm,
uint32_t desc, IMOPFn64 *fn)
{
intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
bool neg = simd_data(desc);
@@ -1107,25 +1128,16 @@ static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
}
#define DEF_IMOP_32(NAME, NTYPE, MTYPE) \
static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
static uint32_t NAME(uint32_t n, uint32_t m, uint32_t a, uint8_t p, bool neg) \
{ \
uint32_t sum0 = 0, sum1 = 0; \
uint32_t sum = 0; \
/* Apply P to N as a mask, making the inactive elements 0. */ \
n &= expand_pred_b(p); \
sum0 += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
sum0 += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
sum0 += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
sum0 += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
sum1 += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
sum1 += (NTYPE)(n >> 40) * (MTYPE)(m >> 40); \
sum1 += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
sum1 += (NTYPE)(n >> 56) * (MTYPE)(m >> 56); \
if (neg) { \
sum0 = (uint32_t)a - sum0, sum1 = (uint32_t)(a >> 32) - sum1; \
} else { \
sum0 = (uint32_t)a + sum0, sum1 = (uint32_t)(a >> 32) + sum1; \
} \
return ((uint64_t)sum1 << 32) | sum0; \
sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
sum += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
sum += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
return neg ? a - sum : a + sum; \
}
#define DEF_IMOP_64(NAME, NTYPE, MTYPE) \
@@ -1151,16 +1163,17 @@ DEF_IMOP_64(umopa_d, uint16_t, uint16_t)
DEF_IMOP_64(sumopa_d, int16_t, uint16_t)
DEF_IMOP_64(usmopa_d, uint16_t, int16_t)
#define DEF_IMOPH(NAME) \
void HELPER(sme_##NAME)(void *vza, void *vzn, void *vzm, void *vpn, \
void *vpm, uint32_t desc) \
{ do_imopa(vza, vzn, vzm, vpn, vpm, desc, NAME); }
#define DEF_IMOPH(NAME, S) \
void HELPER(sme_##NAME##_##S)(void *vza, void *vzn, void *vzm, \
void *vpn, void *vpm, uint32_t desc) \
{ do_imopa_##S(vza, vzn, vzm, vpn, vpm, desc, NAME##_##S); }
DEF_IMOPH(smopa_s)
DEF_IMOPH(umopa_s)
DEF_IMOPH(sumopa_s)
DEF_IMOPH(usmopa_s)
DEF_IMOPH(smopa_d)
DEF_IMOPH(umopa_d)
DEF_IMOPH(sumopa_d)
DEF_IMOPH(usmopa_d)
DEF_IMOPH(smopa, s)
DEF_IMOPH(umopa, s)
DEF_IMOPH(sumopa, s)
DEF_IMOPH(usmopa, s)
DEF_IMOPH(smopa, d)
DEF_IMOPH(umopa, d)
DEF_IMOPH(sumopa, d)
DEF_IMOPH(usmopa, d)
+1 -1
View File
@@ -4584,7 +4584,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
tcg_gen_andi_i32(t, t, 1u << maskbit);
tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, over.label);
gen_exception_insn(s, 0, EXCP_UDEF, syndrome);
gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
/*
* gen_exception_insn() will set is_jmp to DISAS_NORETURN,
* but since we're conditionally branching over it, we want
+2 -2
View File
@@ -843,7 +843,7 @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm, void *va,
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
uint32_t neg_real = flip ^ neg_imag;
intptr_t elements = opr_sz / sizeof(float16);
intptr_t eltspersegment = 16 / sizeof(float16);
intptr_t eltspersegment = MIN(16 / sizeof(float16), elements);
intptr_t i, j;
/* Shift boolean to the sign bit so we can xor to negate. */
@@ -905,7 +905,7 @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm, void *va,
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
uint32_t neg_real = flip ^ neg_imag;
intptr_t elements = opr_sz / sizeof(float32);
intptr_t eltspersegment = 16 / sizeof(float32);
intptr_t eltspersegment = MIN(16 / sizeof(float32), elements);
intptr_t i, j;
/* Shift boolean to the sign bit so we can xor to negate. */
+9 -9
View File
@@ -1121,8 +1121,8 @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
{
float_status *status = vstatus;
uint32_t inexact, frac;
uint32_t e_old, e_new;
uint32_t frac, e_old, e_new;
bool inexact;
e_old = get_float_exception_flags(status);
set_float_exception_flags(0, status);
@@ -1130,13 +1130,13 @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
e_new = get_float_exception_flags(status);
set_float_exception_flags(e_old | e_new, status);
if (value == float64_chs(float64_zero)) {
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
inexact = 1;
} else {
/* Normal inexact or overflow or NaN */
inexact = e_new & (float_flag_inexact | float_flag_invalid);
}
/* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
inexact = e_new & (float_flag_inexact |
float_flag_input_denormal |
float_flag_invalid);
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
inexact |= value == float64_chs(float64_zero);
/* Pack the result and the env->ZF representation of Z together. */
return deposit64(frac, 32, 32, inexact);
+32 -23
View File
@@ -24,16 +24,17 @@
%assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x
%assemble_11a 0:s1 4:10 !function=expand_shl3
%assemble_11a 4:12 0:1 !function=expand_11a
%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
%assemble_12a 0:s1 3:11 !function=expand_shl2
%assemble_12a 3:13 0:1 !function=expand_12a
%assemble_16 0:16 !function=expand_16
%assemble_17 0:s1 16:5 2:1 3:10 !function=expand_shl2
%assemble_22 0:s1 16:10 2:1 3:10 !function=expand_shl2
%assemble_sp 14:2 !function=sp0_if_wide
%assemble_21 0:s1 1:11 14:2 16:5 12:2 !function=expand_shl11
%lowsign_11 0:s1 1:10
%lowsign_14 0:s1 1:13
%sm_imm 16:10 !function=expand_sm_imm
@@ -143,9 +144,9 @@ getshadowregs 1111 1111 1111 1101 1110 1010 1101 0010
nop 000001 ----- ----- -- 11001010 0 ----- # fdc, disp
nop_addrx 000001 ..... ..... -- 01001010 . ----- @addrx # fdc, index
nop_addrx 000001 ..... ..... -- 01001011 . ----- @addrx # fdce
nop_addrx 000001 ..... ..... --- 0001010 . ----- @addrx # fic 0x0a
nop_addrx 000001 ..... ..... -- 01001111 . 00000 @addrx # fic 0x4f
nop_addrx 000001 ..... ..... --- 0001011 . ----- @addrx # fice
fic 000001 ..... ..... --- 0001010 . ----- @addrx # fic 0x0a
fic 000001 ..... ..... -- 01001111 . 00000 @addrx # fic 0x4f
fic 000001 ..... ..... --- 0001011 . ----- @addrx # fice
nop_addrx 000001 ..... ..... -- 01001110 . 00000 @addrx # pdc
probe 000001 b:5 ri:5 sp:2 imm:1 100011 write:1 0 t:5
@@ -221,7 +222,7 @@ sub_b_tsv 000010 ..... ..... .... 110100 . ..... @rrr_cf_d
ldil 001000 t:5 ..................... i=%assemble_21
addil 001010 r:5 ..................... i=%assemble_21
ldo 001101 b:5 t:5 -- .............. i=%lowsign_14
ldo 001101 b:5 t:5 ................ i=%assemble_16
addi 101101 ..... ..... .... 0 ........... @rri_cf
addi_tsv 101101 ..... ..... .... 1 ........... @rri_cf
@@ -304,14 +305,18 @@ fstd 001011 ..... ..... .. . 1 -- 100 0 . ..... @fldstdi
# Offset Mem
####
@ldstim11 ...... b:5 t:5 sp:2 .............. \
&ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
@ldstim14 ...... b:5 t:5 sp:2 .............. \
&ldst disp=%lowsign_14 x=0 scale=0 m=0
@ldstim14m ...... b:5 t:5 sp:2 .............. \
&ldst disp=%lowsign_14 x=0 scale=0 m=%neg_to_m
@ldstim12m ...... b:5 t:5 sp:2 .............. \
&ldst disp=%assemble_12a x=0 scale=0 m=%pos_to_m
@ldstim11 ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_11a \
m=%ma2_to_m x=0 scale=0 size=3
@ldstim14 ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_16 \
x=0 scale=0 m=0
@ldstim14m ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_16 \
x=0 scale=0 m=%neg_to_m
@ldstim12m ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_12a \
x=0 scale=0 m=%pos_to_m
# LDB, LDH, LDW, LDWM
ld 010000 ..... ..... .. .............. @ldstim14 size=0
@@ -327,15 +332,19 @@ st 011010 ..... ..... .. .............. @ldstim14 size=2
st 011011 ..... ..... .. .............. @ldstim14m size=2
st 011111 ..... ..... .. ...........10. @ldstim12m size=2
fldw 010110 b:5 ..... sp:2 .............. \
&ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
fldw 010111 b:5 ..... sp:2 ...........0.. \
&ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
fldw 010110 b:5 ..... ................ \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=%a_to_m x=0 scale=0 size=2
fldw 010111 b:5 ..... .............0.. \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=0 x=0 scale=0 size=2
fstw 011110 b:5 ..... sp:2 .............. \
&ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
fstw 011111 b:5 ..... sp:2 ...........0.. \
&ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
fstw 011110 b:5 ..... ................ \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=%a_to_m x=0 scale=0 size=2
fstw 011111 b:5 ..... .............0.. \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=0 x=0 scale=0 size=2
ld 010100 ..... ..... .. ............0. @ldstim11
fldd 010100 ..... ..... .. ............1. @ldstim11
+62 -18
View File
@@ -152,6 +152,49 @@ static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
return ent;
}
#define ACCESS_ID_MASK 0xffff
/* Return the set of protections allowed by a PID match. */
static int match_prot_id_1(uint32_t access_id, uint32_t prot_id)
{
if (((access_id ^ (prot_id >> 1)) & ACCESS_ID_MASK) == 0) {
return (prot_id & 1
? PAGE_EXEC | PAGE_READ
: PAGE_EXEC | PAGE_READ | PAGE_WRITE);
}
return 0;
}
static int match_prot_id32(CPUHPPAState *env, uint32_t access_id)
{
int r, i;
for (i = CR_PID1; i <= CR_PID4; ++i) {
r = match_prot_id_1(access_id, env->cr[i]);
if (r) {
return r;
}
}
return 0;
}
static int match_prot_id64(CPUHPPAState *env, uint32_t access_id)
{
int r, i;
for (i = CR_PID1; i <= CR_PID4; ++i) {
r = match_prot_id_1(access_id, env->cr[i]);
if (r) {
return r;
}
r = match_prot_id_1(access_id, env->cr[i] >> 32);
if (r) {
return r;
}
}
return 0;
}
int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
int type, hwaddr *pphys, int *pprot,
HPPATLBEntry **tlb_entry)
@@ -224,29 +267,30 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
break;
}
/* access_id == 0 means public page and no check is performed */
if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
/* If bits [31:1] match, and bit 0 is set, suppress write. */
int match = ent->access_id * 2 + 1;
if (match == env->cr[CR_PID1] || match == env->cr[CR_PID2] ||
match == env->cr[CR_PID3] || match == env->cr[CR_PID4]) {
prot &= PAGE_READ | PAGE_EXEC;
if (type == PAGE_WRITE) {
ret = EXCP_DMPI;
goto egress;
}
}
}
/* No guest access type indicates a non-architectural access from
within QEMU. Bypass checks for access, D, B and T bits. */
/*
* No guest access type indicates a non-architectural access from
* within QEMU. Bypass checks for access, D, B, P and T bits.
*/
if (type == 0) {
goto egress;
}
/* access_id == 0 means public page and no check is performed */
if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
int access_prot = (hppa_is_pa20(env)
? match_prot_id64(env, ent->access_id)
: match_prot_id32(env, ent->access_id));
if (unlikely(!(type & access_prot))) {
/* Not allowed -- Inst/Data Memory Protection Id Fault. */
ret = type & PAGE_EXEC ? EXCP_IMP : EXCP_DMPI;
goto egress;
}
/* Otherwise exclude permissions not allowed (i.e WD). */
prot &= access_prot;
}
if (unlikely(!(prot & type))) {
/* The access isn't allowed -- Inst/Data Memory Protection Fault. */
/* Not allowed -- Inst/Data Memory Access Rights Fault. */
ret = (type & PAGE_EXEC) ? EXCP_IMP : EXCP_DMAR;
goto egress;
}
+5 -5
View File
@@ -281,17 +281,17 @@ static void do_stdby_e(CPUHPPAState *env, target_ulong addr, uint64_t val,
case 3:
/* The 3 byte store must appear atomic. */
if (parallel) {
atomic_store_mask32(env, addr - 3, val, 0xffffff00u, ra);
atomic_store_mask32(env, addr - 3, val >> 32, 0xffffff00u, ra);
} else {
cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
cpu_stw_data_ra(env, addr - 3, val >> 48, ra);
cpu_stb_data_ra(env, addr - 1, val >> 40, ra);
}
break;
case 2:
cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
cpu_stw_data_ra(env, addr - 2, val >> 48, ra);
break;
case 1:
cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
cpu_stb_data_ra(env, addr - 1, val >> 56, ra);
break;
default:
/* Nothing is stored, but protection is checked and the

Some files were not shown because too many files have changed in this diff Show More