Compare commits

...

69 Commits

Author SHA1 Message Date
Michael Roth 9654e55a74 Update version for 6.0.1 release
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-28 18:10:51 -05:00
Jessica Clarke db882c5c18 Partially revert "build: -no-pie is no functional linker flag"
This partially reverts commit bbd2d5a812.

This commit was misguided and broke using --disable-pie on any distro
that enables PIE by default in their compiler driver, including Debian
and its derivatives. Whilst -no-pie is not a linker flag, it is a
compiler driver flag that ensures -pie is not automatically passed by it
to the linker. Without it, all compile_prog checks will fail as any code
built with the explicit -fno-pie will fail to link with the implicit
default -pie due to trying to use position-dependent relocations. The
only bug that needed fixing was LDFLAGS_NOPIE being used as a flag for
the linker itself in pc-bios/optionrom/Makefile.

Note this does not reinstate exporting LDFLAGS_NOPIE, as it is unused,
since the only previous use was the one that should not have existed. I
have also updated the comment for the -fno-pie and -no-pie checks to
reflect what they're actually needed for.

Fixes: bbd2d5a812
Cc: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-27 12:01:30 -05:00
Helge Deller 62a012b0f4 hw/display/artist: Fix bug in coordinate extraction in artist_vram_read() and artist_vram_write()
The CDE desktop on HP-UX 10 shows wrongly rendered pixels when the local screen
menu is closed. This bug was introduced by commit c7050f3f16
("hw/display/artist: Refactor x/y coordination extraction") which converted the
coordinate extraction in artist_vram_read() and artist_vram_write() to use the
ADDR_TO_X and ADDR_TO_Y macros, but forgot to right-shift the address by 2 as
it was done before.

Signed-off-by: Helge Deller <deller@gmx.de>
Fixes: c7050f3f16 ("hw/display/artist: Refactor x/y coordination extraction")
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <YK1aPb8keur9W7h2@ls3530>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 01f750f5fe)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-27 11:57:47 -05:00
David Hildenbrand 487a0956a1 libvhost-user: fix VHOST_USER_REM_MEM_REG skipping mmap_addr
We end up not copying the mmap_addr of all existing regions, resulting
in a SEGFAULT once we actually try to map/access anything within our
memory regions.

Fixes: 875b9fd97b ("Support individual region unmap in libvhost-user")
Cc: qemu-stable@nongnu.org
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Raphael Norwitz <raphael.norwitz@nutanix.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Coiby Xu <coiby.xu@gmail.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20211011201047.62587-1-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 6889eb2d43)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-27 11:50:35 -05:00
Xueming Li c18bc855ad vhost-user: fix duplicated notifier MR init
In case of device resume after suspend, VQ notifier MR still valid.
Duplicated registrations explode memory block list and slow down device
resume.

Fixes: 44866521bd ("vhost-user: support registering external host notifiers")
Cc: tiwei.bie@intel.com
Cc: qemu-stable@nongnu.org
Cc: Yuwei Zhang <zhangyuwei.9149@bytedance.com>

Signed-off-by: Xueming Li <xuemingl@nvidia.com>
Message-Id: <20211008080215.590292-1-xuemingl@nvidia.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a1ed9ef1de)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-27 11:49:50 -05:00
Marcel Apfelbaum 27c6f20d9d pvrdma: Fix the ring init error flow (CVE-2021-3608)
Do not unmap uninitialized dma addresses.

Fixes: CVE-2021-3608
Reviewed-by: VictorV (Kunlun Lab) <vv474172261@gmail.com>
Tested-by: VictorV (Kunlun Lab) <vv474172261@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Message-Id: <20210630115246.2178219-1-marcel@redhat.com>
Tested-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Reviewed-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit 66ae37d8cc)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:27:51 -05:00
Marcel Apfelbaum 46d3c9e9f5 pvrdma: Ensure correct input on ring init (CVE-2021-3607)
Check the guest passed a non zero page count
for pvrdma device ring buffers.

Fixes: CVE-2021-3607
Reported-by: VictorV (Kunlun Lab) <vv474172261@gmail.com>
Reviewed-by: VictorV (Kunlun Lab) <vv474172261@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Message-Id: <20210630114634.2168872-1-marcel@redhat.com>
Reviewed-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Tested-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit 32e5703cfe)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:27:24 -05:00
Marcel Apfelbaum d25db58213 hw/rdma: Fix possible mremap overflow in the pvrdma device (CVE-2021-3582)
Ensure mremap boundaries not trusting the guest kernel to
pass the correct buffer length.

Fixes: CVE-2021-3582
Reported-by: VictorV (Kunlun Lab) <vv474172261@gmail.com>
Tested-by: VictorV (Kunlun Lab) <vv474172261@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Message-Id: <20210616110600.20889-1-marcel.apfelbaum@gmail.com>
Reviewed-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Tested-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit 284f191b4a)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:27:12 -05:00
Li Qiang 4787501893 vhost-user-gpu: fix OOB write in 'virgl_cmd_get_capset' (CVE-2021-3546)
If 'virgl_cmd_get_capset' set 'max_size' to 0,
the 'virgl_renderer_fill_caps' will write the data after the 'resp'.
This patch avoid this by checking the returned 'max_size'.

virtio-gpu fix: abd7f08b23 ("display: virtio-gpu-3d: check
virgl capabilities max_size")

Fixes: CVE-2021-3546
Reported-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-8-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 9f22893adc)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:26:37 -05:00
Li Qiang 07daff4a9a vhost-user-gpu: fix memory leak in 'virgl_resource_attach_backing' (CVE-2021-3544)
If 'virgl_renderer_resource_attach_iov' failed, the 'res_iovs' will
be leaked.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 33243031da ("virtio-gpu-3d: fix memory leak
in resource attach backing")

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-7-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 63736af5a6)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:26:28 -05:00
Li Qiang 4dda63d7ed vhost-user-gpu: fix memory leak in 'virgl_cmd_resource_unref' (CVE-2021-3544)
The 'res->iov' will be leaked if the guest trigger following sequences:

	virgl_cmd_create_resource_2d
	virgl_resource_attach_backing
	virgl_cmd_resource_unref

This patch fixes this.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 5e8e3c4c75 ("virtio-gpu: fix resource leak
in virgl_cmd_resource_unref"

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-6-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit f6091d86ba)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:26:15 -05:00
Li Qiang 457053998d vhost-user-gpu: fix memory leak while calling 'vg_resource_unref' (CVE-2021-3544)
If the guest trigger following sequences, the attach_backing will be leaked:

	vg_resource_create_2d
	vg_resource_attach_backing
	vg_resource_unref

This patch fix this by freeing 'res->iov' in vg_resource_destroy.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 5e8e3c4c75 ("virtio-gpu: fix resource leak
in virgl_cmd_resource_unref")

Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-5-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit b7afebcf9e)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:26:01 -05:00
Li Qiang 6ae68dfd10 vhost-user-gpu: fix memory leak in vg_resource_attach_backing (CVE-2021-3544)
Check whether the 'res' has already been attach_backing to avoid
memory leak.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 204f01b309 ("virtio-gpu: fix memory leak
in resource attach backing")

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-4-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit b9f79858a6)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:25:43 -05:00
Li Qiang c5300b8a94 vhost-user-gpu: fix resource leak in 'vg_resource_create_2d' (CVE-2021-3544)
Call 'vugbm_buffer_destroy' in error path to avoid resource leak.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-3-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 86dd8fac2a)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:25:24 -05:00
Li Qiang 168299eb7d vhost-user-gpu: fix memory disclosure in virgl_cmd_get_capset_info (CVE-2021-3545)
Otherwise some of the 'resp' will be leaked to guest.

Fixes: CVE-2021-3545
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 42a8dadc74 ("virtio-gpu: fix information leak
in getting capset info dispatch")

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-2-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 121841b25d)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:21:32 -05:00
Gerd Hoffmann e204dca909 usb: limit combined packets to 1 MiB (CVE-2021-3527)
usb-host and usb-redirect try to batch bulk transfers by combining many
small usb packets into a single, large transfer request, to reduce the
overhead and improve performance.

This patch adds a size limit of 1 MiB for those combined packets to
restrict the host resources the guest can bind that way.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20210503132915.2335822-6-kraxel@redhat.com>
(cherry picked from commit 05a40b172e)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:20:04 -05:00
Gerd Hoffmann 606f618b3c usb/redir: avoid dynamic stack allocation (CVE-2021-3527)
Use autofree heap allocation instead.

Fixes: 4f4321c11f ("usb: use iovecs in USBPacket")
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20210503132915.2335822-3-kraxel@redhat.com>
(cherry picked from commit 7ec54f9eb6)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:19:33 -05:00
Gerd Hoffmann 36403e8788 uas: add stream number sanity checks.
The device uses the guest-supplied stream number unchecked, which can
lead to guest-triggered out-of-band access to the UASDevice->data3 and
UASDevice->status3 fields.  Add the missing checks.

Fixes: CVE-2021-3713
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reported-by: Chen Zhe <chenzhe@huawei.com>
Reported-by: Tan Jingguo <tanjingguo@huawei.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20210818120505.1258262-2-kraxel@redhat.com>
(cherry picked from commit 13b250b12a)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-17 20:18:25 -05:00
David Hildenbrand 5a964fe8d9 virtio-mem-pci: Fix memory leak when creating MEMORY_DEVICE_SIZE_CHANGE event
Apparently, we don't have to duplicate the string.

Fixes: 722a3c783e ("virtio-pci: Send qapi events when the virtio-mem size changes")
Cc: qemu-stable@nongnu.org
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20210929162445.64060-2-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 75b98cb9f6)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-15 17:55:37 -05:00
Markus Armbruster f22c225e23 hmp: Unbreak "change vnc"
HMP command "change vnc" can take the password as argument, or prompt
for it:

    (qemu) change vnc password 123
    (qemu) change vnc password
    Password: ***
    (qemu)

This regressed in commit cfb5387a1d "hmp: remove "change vnc TARGET"
command", v6.0.0.

    (qemu) change vnc passwd 123
    Password: ***
    (qemu) change vnc passwd
    (qemu)

The latter passes NULL to qmp_change_vnc_password(), which is a no-no.
Looks like it puts the display into "password required, but none set"
state.

The logic error is easy to miss in review, but testing should've
caught it.

Fix the obvious way.

Fixes: cfb5387a1d
Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20210909081219.308065-2-armbru@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit 6193344f93)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-15 17:54:16 -05:00
Nir Soffer 916372e48f qemu-nbd: Change default cache mode to writeback
Both qemu and qemu-img use writeback cache mode by default, which is
already documented in qemu(1). qemu-nbd uses writethrough cache mode by
default, and the default cache mode is not documented.

According to the qemu-nbd(8):

   --cache=CACHE
          The  cache  mode  to be used with the file.  See the
          documentation of the emulator's -drive cache=... option for
          allowed values.

qemu(1) says:

    The default mode is cache=writeback.

So users have no reason to assume that qemu-nbd is using writethough
cache mode. The only hint is the painfully slow writing when using the
defaults.

Looking in git history, it seems that qemu used writethrough in the past
to support broken guests that did not flush data properly, or could not
flush due to limitations in qemu. But qemu-nbd clients can use
NBD_CMD_FLUSH to flush data, so using writethrough does not help anyone.

Change the default cache mode to writback, and document the default and
available values properly in the online help and manual.

With this change converting image via qemu-nbd is 3.5 times faster.

    $ qemu-img create dst.img 50g
    $ qemu-nbd -t -f raw -k /tmp/nbd.sock dst.img

Before this change:

    $ hyperfine -r3 "./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock"
    Benchmark #1: ./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock
      Time (mean ± σ):     83.639 s ±  5.970 s    [User: 2.733 s, System: 6.112 s]
      Range (min … max):   76.749 s … 87.245 s    3 runs

After this change:

    $ hyperfine -r3 "./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock"
    Benchmark #1: ./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock
      Time (mean ± σ):     23.522 s ±  0.433 s    [User: 2.083 s, System: 5.475 s]
      Range (min … max):   23.234 s … 24.019 s    3 runs

Users can avoid the issue by using --cache=writeback[1] but the defaults
should give good performance for the common use case.

[1] https://bugzilla.redhat.com/1990656

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
Message-Id: <20210813205519.50518-1-nsoffer@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 0961525705)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-15 17:50:57 -05:00
Jason Wang 5881d76ff4 virtio-net: fix use after unmap/free for sg
When mergeable buffer is enabled, we try to set the num_buffers after
the virtqueue elem has been unmapped. This will lead several issues,
E.g a use after free when the descriptor has an address which belongs
to the non direct access region. In this case we use bounce buffer
that is allocated during address_space_map() and freed during
address_space_unmap().

Fixing this by storing the elems temporarily in an array and delay the
unmap after we set the the num_buffers.

This addresses CVE-2021-3748.

Reported-by: Alexander Bulekov <alxndr@bu.edu>
Fixes: fbe78f4f55 ("virtio-net support")
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit bedd7e93d0)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-15 17:48:28 -05:00
Peter Maydell 2ae61d81a5 target/arm: Don't skip M-profile reset entirely in user mode
Currently all of the M-profile specific code in arm_cpu_reset() is
inside a !defined(CONFIG_USER_ONLY) ifdef block.  This is
unintentional: it happened because originally the only
M-profile-specific handling was the setup of the initial SP and PC
from the vector table, which is system-emulation only.  But then we
added a lot of other M-profile setup to the same "if (ARM_FEATURE_M)"
code block without noticing that it was all inside a not-user-mode
ifdef.  This has generally been harmless, but with the addition of
v8.1M low-overhead-loop support we ran into a problem: the reset of
FPSCR.LTPSIZE to 4 was only being done for system emulation mode, so
if a user-mode guest tried to execute the LE instruction it would
incorrectly take a UsageFault.

Adjust the ifdefs so only the really system-emulation specific parts
are covered.  Because this means we now run some reset code that sets
up initial values in the FPCCR and similar FPU related registers,
explicitly set up the registers controlling FPU context handling in
user-emulation mode so that the FPU works by design and not by
chance.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/613
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210914120725.24992-2-peter.maydell@linaro.org
(cherry picked from commit b62ceeaf80)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-15 17:44:42 -05:00
Dr. David Alan Gilbert 4fca33b4be audio: Never send migration section
The audio migration vmstate is empty, and always has been; we can't
just remove it though because an old qemu might send it us.
Changes with -audiodev now mean it's sometimes created when it didn't
used to be, and can confuse migration to old qemu.

Change it so that vmstate_audio is never sent; if it's received it
should still be accepted, and old qemu's shouldn't be too upset if it's
missing.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Tested-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20210809170956.78536-1-dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit da77adbaf6)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 21:13:02 -05:00
Philippe Mathieu-Daudé 978c11b013 hw/sd/sdcard: Fix assertion accessing out-of-range addresses with CMD30
OSS-Fuzz found sending illegal addresses when querying the write
protection bits triggers the assertion added in commit 84816fb63e
("hw/sd/sdcard: Assert if accessing an illegal group"):

  qemu-fuzz-i386-target-generic-fuzz-sdhci-v3: ../hw/sd/sd.c:824: uint32_t sd_wpbits(SDState *, uint64_t):
  Assertion `wpnum < sd->wpgrps_size' failed.
  #3 0x7f62a8b22c91 in __assert_fail
  #4 0x5569adcec405 in sd_wpbits hw/sd/sd.c:824:9
  #5 0x5569adce5f6d in sd_normal_command hw/sd/sd.c:1389:38
  #6 0x5569adce3870 in sd_do_command hw/sd/sd.c:1737:17
  #7 0x5569adcf1566 in sdbus_do_command hw/sd/core.c💯16
  #8 0x5569adcfc192 in sdhci_send_command hw/sd/sdhci.c:337:12
  #9 0x5569adcfa3a3 in sdhci_write hw/sd/sdhci.c:1186:9
  #10 0x5569adfb3447 in memory_region_write_accessor softmmu/memory.c:492:5

It is legal for the CMD30 to query for out-of-range addresses.
Such invalid addresses are simply ignored in the response (write
protection bits set to 0).

In commit 84816fb63e ("hw/sd/sdcard: Assert if accessing an illegal
group") we misplaced the assertion *before* we test the address is
in range. Move it *after*.

Include the qtest reproducer provided by Alexander Bulekov:

  $ make check-qtest-i386
  ...
  Running test qtest-i386/fuzz-sdcard-test
  qemu-system-i386: ../hw/sd/sd.c:824: sd_wpbits: Assertion `wpnum < sd->wpgrps_size' failed.

Cc: qemu-stable@nongnu.org
Reported-by: OSS-Fuzz (Issue 29225)
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: 84816fb63e ("hw/sd/sdcard: Assert if accessing an illegal group")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/495
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20210802235524.3417739-3-f4bug@amsat.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
(cherry picked from commit 4ac0b72bae)
*drop fuzz test additions, since sdcard fuzz test has functional
 dependency on guest-visible change not flagged for stable:
 59b63d78 ("hw/sd/sdcard: Check for valid address range in SEND_WRITE_PROT (CMD30)")
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 17:50:29 -05:00
Philippe Mathieu-Daudé 21611dd0a5 hw/sd/sdcard: Document out-of-range addresses for SEND_WRITE_PROT
Per the 'Physical Layer Simplified Specification Version 3.01',
Table 4-22: 'Block Oriented Write Protection Commands'

  SEND_WRITE_PROT (CMD30)

  If the card provides write protection features, this command asks
  the card to send the status of the write protection bits [1].

  [1] 32 write protection bits (representing 32 write protect groups
  starting at the specified address) [...]
  The last (least significant) bit of the protection bits corresponds
  to the first addressed group. If the addresses of the last groups
  are outside the valid range, then the corresponding write protection
  bits shall be set to 0.

Split the if() statement (without changing the behaviour of the code)
to better position the description comment.

Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20210802235524.3417739-2-f4bug@amsat.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
(cherry picked from commit 2a0396285d)
*context dependency for 4ac0b72bae ("hw/sd/sdcard: Fix assertion accessing out-of-range addresses with CMD30")
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 17:42:58 -05:00
Pavel Pisa 4d3cfb2f6b hw/net/can: sja1000 fix buff2frame_bas and buff2frame_pel when dlc is out of std CAN 8 bytes
Problem reported by openEuler fuzz-sig group.

The buff2frame_bas function (hw\net\can\can_sja1000.c)
infoleak(qemu5.x~qemu6.x) or stack-overflow(qemu 4.x).

Reported-by: Qiang Ning <ningqiang1@huawei.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 11744862f2)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 17:34:25 -05:00
David Hildenbrand 7999d5b12f virtio-balloon: don't start free page hinting if postcopy is possible
Postcopy never worked properly with 'free-page-hint=on', as there are
at least two issues:

1) With postcopy, the guest will never receive a VIRTIO_BALLOON_CMD_ID_DONE
   and consequently won't release free pages back to the OS once
   migration finishes.

   The issue is that for postcopy, we won't do a final bitmap sync while
   the guest is stopped on the source and
   virtio_balloon_free_page_hint_notify() will only call
   virtio_balloon_free_page_done() on the source during
   PRECOPY_NOTIFY_CLEANUP, after the VM state was already migrated to
   the destination.

2) Once the VM touches a page on the destination that has been excluded
   from migration on the source via qemu_guest_free_page_hint() while
   postcopy is active, that thread will stall until postcopy finishes
   and all threads are woken up. (with older Linux kernels that won't
   retry faults when woken up via userfaultfd, we might actually get a
   SEGFAULT)

   The issue is that the source will refuse to migrate any pages that
   are not marked as dirty in the dirty bmap -- for example, because the
   page might just have been sent. Consequently, the faulting thread will
   stall, waiting for the page to be migrated -- which could take quite
   a while and result in guest OS issues.

While we could fix 1) comparatively easily, 2) is harder to get right and
might require more involved RAM migration changes on source and destination
[1].

As it never worked properly, let's not start free page hinting in the
precopy notifier if the postcopy migration capability was enabled to fix
it easily. Capabilities cannot be enabled once migration is already
running.

Note 1: in the future we might either adjust migration code on the source
        to track pages that have actually been sent or adjust
        migration code on source and destination  to eventually send
        pages multiple times from the source and and deal with pages
        that are sent multiple times on the destination.

Note 2: virtio-mem has similar issues, however, access to "unplugged"
        memory by the guest is very rare and we would have to be very
        lucky for it to happen during migration. The spec states
        "The driver SHOULD NOT read from unplugged memory blocks ..."
        and "The driver MUST NOT write to unplugged memory blocks".
        virtio-mem will move away from virtio_balloon_free_page_done()
        soon and handle this case explicitly on the destination.

[1] https://lkml.kernel.org/r/e79fd18c-aa62-c1d8-c7f3-ba3fc2c25fc8@redhat.com

Fixes: c13c4153f7 ("virtio-balloon: VIRTIO_BALLOON_F_FREE_PAGE_HINT")
Cc: qemu-stable@nongnu.org
Cc: Wei Wang <wei.w.wang@intel.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Alexander Duyck <alexander.duyck@gmail.com>
Cc: Juan Quintela <quintela@redhat.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210708095339.20274-2-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit fd51e54fa1)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 17:23:06 -05:00
Klaus Jensen 6576f6ab87 hw/nvme: fix pin-based interrupt behavior (again)
Jakub noticed[1] that, when using pin-based interrupts, the device will
unconditionally deasssert when any CQEs are acknowledged. However, the
pin should not be deasserted if other completion queues still holds
unacknowledged CQEs.

The bug is an artifact of commit ca247d3509 ("hw/block/nvme: fix
pin-based interrupt behavior") which fixed one bug but introduced
another. This is the third time someone tries to fix pin-based
interrupts (see commit 5e9aa92eb1 ("hw/block: Fix pin-based interrupt
behaviour of NVMe"))...

Third time's the charm, so fix it, again, by keeping track of how many
CQs have unacknowledged CQEs and only deassert when all are cleared.

  [1]: <20210610114624.304681-1-jakub.jermar@kernkonzept.com>

Cc: qemu-stable@nongnu.org
Fixes: ca247d3509 ("hw/block/nvme: fix pin-based interrupt behavior")
Reported-by: Jakub Jermář <jakub.jermar@kernkonzept.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
(cherry picked from commit 83d7ed5c57)
*avoid dependency on 88eea45c ("hw/nvme: move nvme emulation out of hw/block")
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 17:13:53 -05:00
Klaus Jensen bef905cd8a hw/nvme: fix missing check for PMR capability
Qiang Liu reported that an access on an unknown address is triggered in
memory_region_set_enabled because a check on CAP.PMRS is missing for the
PMRCTL register write when no PMR is configured.

Cc: qemu-stable@nongnu.org
Fixes: 75c3c9de96 ("hw/block/nvme: disable PMR at boot up")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/362
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
(cherry picked from commit 2b02aabc9d)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 17:05:22 -05:00
Gollu Appalanaidu aa99651295 hw/block/nvme: align with existing style
While QEMU coding style prefers lowercase hexadecimals in constants, the
NVMe subsystem uses the format from the NVMe specifications in comments,
i.e. 'h' suffix instead of '0x' prefix.

Fix this up across the code base.

Signed-off-by: Gollu Appalanaidu <anaidu.gollu@samsung.com>
[k.jensen: updated message; added conversion in a couple of missing comments]
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit 312c3531bb)
*context dependency for 2b02aabc9d
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 17:04:59 -05:00
Igor Mammedov 765ed56e76 tests: acpi: pc: update expected DSDT blobs
@@ -930,20 +930,20 @@ DefinitionBlock ("", "DSDT", 1, "BOCHS ", "BXPC    ", 0x00000001)
             Device (S00)
             {
                 Name (_ADR, Zero)  // _ADR: Address
-                Name (_SUN, Zero)  // _SUN: Slot User Number
+                Name (ASUN, Zero)
                 Method (_DSM, 4, Serialized)  // _DSM: Device-Specific Method
                 {
-                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, _SUN))
+                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, ASUN))
                 }
             }

             Device (S10)
             {
                 Name (_ADR, 0x00020000)  // _ADR: Address
-                Name (_SUN, 0x02)  // _SUN: Slot User Number
+                Name (ASUN, 0x02)
                 Method (_DSM, 4, Serialized)  // _DSM: Device-Specific Method
                 {
-                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, _SUN))
+                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, ASUN))
                 }

                 Method (_S1D, 0, NotSerialized)  // _S1D: S1 Device State

with a hank per bridge:

@@ -965,10 +965,10 @@ DefinitionBlock ("", "DSDT", 1, "BOCHS ", "BXPC    ", 0x00000001)
             Device (S18)
             {
                 Name (_ADR, 0x00030000)  // _ADR: Address
-                Name (_SUN, 0x03)  // _SUN: Slot User Number
+                Name (ASUN, 0x03)
                 Method (_DSM, 4, Serialized)  // _DSM: Device-Specific Method
                 {
-                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, _SUN))
+                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, ASUN))
                 }
             }

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20210624204229.998824-4-imammedo@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: John Sucaet <john.sucaet@ekinops.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 40f23e4e52)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:52:00 -05:00
Igor Mammedov b989641145 acpi: pc: revert back to v5.2 PCI slot enumeration
Commit [1] moved _SUN variable from only hot-pluggable to
all devices. This made linux kernel enumerate extra slots
that weren't present before. If extra slot happens to be
be enumerated first and there is a device in th same slot
but on other bridge, linux kernel will add -N suffix to
slot name of the later, thus changing NIC name compared to
QEMU 5.2. This in some case confuses systemd, if it is
using SLOT NIC naming scheme and interface name becomes
not the same as it was under QEMU-5.2.

Reproducer QEMU CLI:
  -M pc-i440fx-5.2 -nodefaults \
  -device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x3 \
  -device virtio-net-pci,id=nic1,bus=pci.1,addr=0x1 \
  -device virtio-net-pci,id=nic2,bus=pci.1,addr=0x2 \
  -device virtio-net-pci,id=nic3,bus=pci.1,addr=0x3

with RHEL8 guest produces following results:
  v5.2:
     kernel: virtio_net virtio0 ens1: renamed from eth0
     kernel: virtio_net virtio2 ens3: renamed from eth2
     kernel: virtio_net virtio1 enp1s2: renamed from eth1
      (slot 2 is assigned to empty bus 0 slot and virtio1
       is assigned to 2-2 slot, and renaming falls back,
       for some reason, to path based naming scheme)

  v6.0:
     kernel: virtio_net virtio0 ens1: renamed from eth0
     kernel: virtio_net virtio2 ens3: renamed from eth2
     systemd-udevd[299]: Error changing net interface name 'eth1' to 'ens3': File exists
     systemd-udevd[299]: could not rename interface '3' from 'eth1' to 'ens3': File exists
      (with commit [1] kernel assigns virtio2 to 3-2 slot
       since bridge advertises _SUN=0x3 and kernel assigns
       slot 3 to bridge. Still it manages to rename virtio2
       correctly to ens3, however systemd gets confused with virtio1
       where slot allocation exactly the same (2-2) as in 5.2 case
       and tries to rename it to ens3 which is rightfully taken by
       virtio2)

I'm not sure what breaks in systemd interface renaming (it probably
should be investigated), but on QEMU side we can safely revert
_SUN to 5.2 behavior (i.e. avoid cold-plugged bridges and non
hot-pluggable device classes), without breaking acpi-index, which uses
slot numbers but it doesn't have to use _SUN, it could use an arbitrary
variable name that has the same slot value).
It will help existing VMs to keep networking with non trivial
configs in working order since systemd will do its interface
renaming magic as it used to do.

1)
Fixes: b7f23f62e4 (pci: acpi: add _DSM method to PCI devices)
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20210624204229.998824-3-imammedo@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: John Sucaet <john.sucaet@ekinops.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 7193d7cdd9)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:51:55 -05:00
Igor Mammedov e23fe27ed9 tests: acpi: prepare for changing DSDT tables
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20210624204229.998824-2-imammedo@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: John Sucaet <john.sucaet@ekinops.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a4344574fd)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:51:48 -05:00
Leonardo Bras 22de6752c1 yank: Unregister function when using TLS migration
After yank feature was introduced in migration, whenever migration
is started using TLS, the following error happens in both source and
destination hosts:

(qemu) qemu-kvm: ../util/yank.c:107: yank_unregister_instance:
Assertion `QLIST_EMPTY(&entry->yankfns)' failed.

This happens because of a missing yank_unregister_function() when using
qio-channel-tls.

Fix this by also allowing TYPE_QIO_CHANNEL_TLS object type to perform
yank_unregister_function() in channel_close() and multifd_load_cleanup().

Also, inside migration_channel_connect() and
migration_channel_process_incoming() move yank_register_function() so
it only runs once on a TLS migration.

Fixes: b5eea99ec2 ("migration: Add yank feature", 2021-01-13)
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1964326
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
Reviewed-by: Lukas Straub <lukasstraub2@web.de>
Reviewed-by: Peter Xu <peterx@redhat.com>

--
Changes since v2:
- Dropped all references to ioc->master
- yank_register_function() and yank_unregister_function() now only run
  once in a TLS migration.

Changes since v1:
- Cast p->c to QIOChannelTLS into multifd_load_cleanup()
Message-Id: <20210601054030.1153249-1-leobras.c@gmail.com>

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 7de2e85653)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:51 -05:00
Philippe Mathieu-Daudé 747fd3cb13 crypto: Make QCryptoTLSCreds* structures private
Code consuming the "crypto/tlscreds*.h" APIs doesn't need
to access its internals. Move the structure definitions to
the "tlscredspriv.h" private header (only accessible by
implementations). The public headers (in include/) still
forward-declare the structures typedef.

Note, tlscreds.c and 3 of the 5 modified source files already
include "tlscredspriv.h", so only add it to tls-cipher-suites.c
and tlssession.c.

Removing the internals from the public header solves a bug
introduced by commit 7de2e85653 ("yank: Unregister function
when using TLS migration") which made migration/qemu-file-channel.c
include "io/channel-tls.h", itself sometime depends on GNUTLS,
leading to a build failure on OSX:

  [2/35] Compiling C object libmigration.fa.p/migration_qemu-file-channel.c.o
  FAILED: libmigration.fa.p/migration_qemu-file-channel.c.o
  cc -Ilibmigration.fa.p -I. -I.. -Iqapi [ ... ] -o libmigration.fa.p/migration_qemu-file-channel.c.o -c ../migration/qemu-file-channel.c
  In file included from ../migration/qemu-file-channel.c:29:
  In file included from include/io/channel-tls.h:26:
  In file included from include/crypto/tlssession.h:24:
  include/crypto/tlscreds.h:28:10: fatal error: 'gnutls/gnutls.h' file not found
  #include <gnutls/gnutls.h>
           ^~~~~~~~~~~~~~~~~
  1 error generated.

Reported-by: Stefan Weil <sw@weilnetz.de>
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/407
Fixes: 7de2e85653 ("yank: Unregister function when using TLS migration")
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 678bcc3c2c)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:39 -05:00
Philippe Mathieu-Daudé 43844c2fb2 ui/vnc: Use qcrypto_tls_creds_check_endpoint()
Avoid accessing QCryptoTLSCreds internals by using
the qcrypto_tls_creds_check_endpoint() helper.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 3c52bf0c60)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:33 -05:00
Philippe Mathieu-Daudé a1c966bdf4 migration/tls: Use qcrypto_tls_creds_check_endpoint()
Avoid accessing QCryptoTLSCreds internals by using
the qcrypto_tls_creds_check_endpoint() helper.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 5590f65fac)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:29 -05:00
Philippe Mathieu-Daudé 0a7e2c99f9 chardev/socket: Use qcrypto_tls_creds_check_endpoint()
Avoid accessing QCryptoTLSCreds internals by using
the qcrypto_tls_creds_check_endpoint() helper.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 8612df2ebe)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:24 -05:00
Philippe Mathieu-Daudé 8d5c255a25 qemu-nbd: Use qcrypto_tls_creds_check_endpoint()
Avoid accessing QCryptoTLSCreds internals by using
the qcrypto_tls_creds_check_endpoint() helper.

Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 0279cd9535)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:19 -05:00
Philippe Mathieu-Daudé 738ff4bf07 block/nbd: Use qcrypto_tls_creds_check_endpoint()
Avoid accessing QCryptoTLSCreds internals by using
the qcrypto_tls_creds_check_endpoint() helper.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 7b3b616838)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:13 -05:00
Philippe Mathieu-Daudé 7e84d58e8b crypto/tlscreds: Introduce qcrypto_tls_creds_check_endpoint() helper
Introduce the qcrypto_tls_creds_check_endpoint() helper
to access QCryptoTLSCreds internal 'endpoint' field.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit e9ac68083f)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:27:05 -05:00
Philippe Mathieu-Daudé 072a8d3693 block/nvme: Fix VFIO_MAP_DMA failed: No space left on device
When the NVMe block driver was introduced (see commit bdd6a90a9e,
January 2018), Linux VFIO_IOMMU_MAP_DMA ioctl was only returning
-ENOMEM in case of error. The driver was correctly handling the
error path to recycle its volatile IOVA mappings.

To fix CVE-2019-3882, Linux commit 492855939bdb ("vfio/type1: Limit
DMA mappings per container", April 2019) added the -ENOSPC error to
signal the user exhausted the DMA mappings available for a container.

The block driver started to mis-behave:

  qemu-system-x86_64: VFIO_MAP_DMA failed: No space left on device
  (qemu)
  (qemu) info status
  VM status: paused (io-error)
  (qemu) c
  VFIO_MAP_DMA failed: No space left on device
  (qemu) c
  VFIO_MAP_DMA failed: No space left on device

(The VM is not resumable from here, hence stuck.)

Fix by handling the new -ENOSPC error (when DMA mappings are
exhausted) without any distinction to the current -ENOMEM error,
so we don't change the behavior on old kernels where the CVE-2019-3882
fix is not present.

An easy way to reproduce this bug is to restrict the DMA mapping
limit (65535 by default) when loading the VFIO IOMMU module:

  # modprobe vfio_iommu_type1 dma_entry_limit=666

Cc: qemu-stable@nongnu.org
Cc: Fam Zheng <fam@euphon.net>
Cc: Maxim Levitsky <mlevitsk@redhat.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Reported-by: Michal Prívozník <mprivozn@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20210723195843.1032825-1-philmd@redhat.com
Fixes: bdd6a90a9e ("block: Add VFIO based NVMe driver")
Buglink: https://bugs.launchpad.net/qemu/+bug/1863333
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/65
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 15a730e7a3)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:20:01 -05:00
Philippe Mathieu-Daudé 0a579d4389 hw/pci-host/q35: Ignore write of reserved PCIEXBAR LENGTH field
libFuzzer triggered the following assertion:

  cat << EOF | qemu-system-i386 -M pc-q35-5.0 \
    -nographic -monitor none -serial none \
    -qtest stdio -d guest_errors -trace pci\*
  outl 0xcf8 0xf2000060
  outl 0xcfc 0x8400056e
  EOF
  pci_cfg_write mch 00:0 @0x60 <- 0x8400056e
  Aborted (core dumped)

This is because guest wrote MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD
(reserved value) to the PCIE XBAR register.

There is no indication on the datasheet about what occurs when
this value is written. Simply ignore it on QEMU (and report an
guest error):

  pci_cfg_write mch 00:0 @0x60 <- 0x8400056e
  Q35: Reserved PCIEXBAR LENGTH
  pci_cfg_read mch 00:0 @0x0 -> 0x8086
  pci_cfg_read mch 00:0 @0x0 -> 0x29c08086
  ...

Cc: qemu-stable@nongnu.org
Reported-by: Alexander Bulekov <alxndr@bu.edu>
BugLink: https://bugs.launchpad.net/qemu/+bug/1878641
Fixes: df2d8b3ed4 ("q35: Introduce q35 pc based chipset emulator")
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20210526142438.281477-1-f4bug@amsat.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 9b0ca75e01)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:17:11 -05:00
Richard Henderson 059ad82f38 tcg: Allocate sufficient storage in temp_allocate_frame
This function should have been updated for vector types
when they were introduced.

Fixes: d2fd745fe8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/367
Cc: qemu-stable@nongnu.org
Tested-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit c1c091948a)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:15:27 -05:00
Richard Henderson 1a0a1c4964 tcg/sparc: Fix temp_allocate_frame vs sparc stack bias
We should not be aligning the offset in temp_allocate_frame,
because the odd offset produces an aligned address in the end.
Instead, pass the logical offset into tcg_set_frame and add
the stack bias last.

Cc: qemu-stable@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 9defd1bdfb)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:14:43 -05:00
Zhenzhong Duan cdb8a71e2e vl: Fix an assert failure in error path
Based on the description of error_setg(), the local variable err in
qemu_maybe_daemonize() should be initialized to NULL.

Without fix, the uninitialized *errp triggers assert failure which
doesn't show much valuable information.

Before the fix:
qemu-system-x86_64: ../util/error.c:59: error_setv: Assertion `*errp == NULL' failed.

After fix:
qemu-system-x86_64: cannot create PID file: Cannot open pid file: Permission denied

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Message-Id: <20210610084741.456260-1-zhenzhong.duan@intel.com>
Cc: qemu-stable@nongnu.org
Fixes: 0546c0609c ("vl: split various early command line options to a separate function", 2020-12-10)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 38f71349c7)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:04:11 -05:00
Kunkun Jiang 5b55370e28 vfio: Fix unregister SaveVMHandler in vfio_migration_finalize
In the vfio_migration_init(), the SaveVMHandler is registered for
VFIO device. But it lacks the operation of 'unregister'. It will
lead to 'Segmentation fault (core dumped)' in
qemu_savevm_state_setup(), if performing live migration after a
VFIO device is hot deleted.

Fixes: 7c2f5f75f9 (vfio: Register SaveVMHandlers for VFIO device)
Reported-by: Qixin Gan <ganqixin@huawei.com>
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
Message-Id: <20210527123101.289-1-jiangkunkun@huawei.com>
Reviewed by: Kirti Wankhede <kwankhede@nvidia.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
(cherry picked from commit 22fca190e2)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:02:34 -05:00
Peng Liang d1000ee07b runstate: Initialize Error * to NULL
Based on the description of error_setg(), the local variable err in
qemu_init_subsystems() should be initialized to NULL.

Fixes: efd7ab22fb ("vl: extract qemu_init_subsystems")
Cc: qemu-stable@nongnu.org
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Message-Id: <20210610131729.3906565-1-liangpeng10@huawei.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 6e1da3d305)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 16:01:30 -05:00
Mark Cave-Ayland b6f5c02f5f esp: only set ESP_RSEQ at the start of the select sequence
When processing a command to select a target and send a CDB, the ESP device
maintains a sequence step register so that if an error occurs the host can
determine which part of the selection/CDB submission sequence failed.

The old Linux 2.6 driver is really pedantic here: it checks the sequence step
register even if a command succeeds and complains loudly on the console if the
sequence step register doesn't match the expected bus phase and interrupt flags.

This reason this mismatch occurs is because the ESP emulation currently doesn't
update the bus phase until the next TI (Transfer Information) command and so the
cleared sequence step register is considered invalid for the stale bus phase.

Normally this isn't an issue as the host only checks the sequence step register
if an error occurs but the old Linux 2.6 driver does this in several places
causing a large stream of "esp0: STEP_ASEL for tgt 0" messages to appear on the
console during the boot process.

Fix this by not clearing the sequence step register when reading the interrupt
register and clearing the DMA status, so the guest sees a valid sequence step
and bus phase combination at the end of the command phase. No other change is
required since the sequence step register is correctly updated throughout the
selection/CDB submission sequence once one of the select commands is issued.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: 1b9e48a5bd ("esp: implement non-DMA transfers in PDMA mode")
Message-Id: <20210518212511.21688-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit af947a3d85)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:58:17 -05:00
Mark Cave-Ayland 44e5878ce3 esp: only assert INTR_DC interrupt flag if selection fails
The datasheet sequence tables confirm that when a target selection fails, only
the INTR_DC interrupt flag should be asserted.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: cf47a41e05 ("esp: latch individual bits in ESP_RINTR register")
Message-Id: <20210518212511.21688-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cf1a7a9b37)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:58:09 -05:00
Jason Wang 8d719825d9 vhost-vdpa: don't initialize backend_features
We used to initialize backend_features during vhost_vdpa_init()
regardless whether or not it was supported by vhost. This will lead
the unsupported features like VIRTIO_F_IN_ORDER to be included and set
to the vhost-vdpa during vhost_dev_start. Because the
VIRTIO_F_IN_ORDER is not supported by vhost-vdpa so it won't be
advertised to guest which will break the datapath.

Fix this by not initializing the backend_features, so the
acked_features could be built only from guest features via
vhost_net_ack_features().

Fixes: 108a64818e ("vhost-vdpa: introduce vhost-vdpa backend")
Cc: qemu-stable@nongnu.org
Cc: Gautam Dawar <gdawar@xilinx.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit c33f23a419)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:55:40 -05:00
Paolo Bonzini ad8c49081a configure: fix detection of gdbus-codegen
"pkg-config --variable=gdbus_codegen gio-2.0" returns "gdbus-codegen",
and it does not pass test -x (which does not walk the path).

Meson 0.58.0 notices that something is iffy, as the dbus_vmstate1
assignment in tests/qtest/meson.build uses an empty string as the
command, and fails very eloquently:

../tests/qtest/meson.build:92:2: ERROR: No program name specified.

Use the "has" function instead of test -x, and fix the generation
of config-host.mak since meson.build expects that GDBUS_CODEGEN
is absent, rather than empty, if the tool is unavailable.

Reported-by: Sebastian Mitterle <smitterl@redhat.com>
Fixes: #178
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5ecfb76ccc)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:50:10 -05:00
Kevin Wolf fcfe1509a1 hmp: Fix loadvm to resume the VM on success instead of failure
Commit f61fe11aa6 broke hmp_loadvm() by adding an incorrect negation
when converting from 0/-errno return values to a bool value. The result
is that loadvm resumes the VM now if it failed and keeps it stopped if
it failed. Fix it to restore the old behaviour and do it the other way
around.

Fixes: f61fe11aa6
Cc: qemu-stable@nongnu.org
Reported-by: Yanhui Ma <yama@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210511163151.45167-1-kwolf@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit c53cd04e70)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:42:34 -05:00
Stefan Hajnoczi 9b0ee423a1 sockets: update SOCKET_ADDRESS_TYPE_FD listen(2) backlog
socket_get_fd() fails with the error "socket_get_fd: too many
connections" if the given listen backlog value is not 1.

Not all callers set the backlog to 1. For example, commit
582d4210eb ("qemu-nbd: Use SOMAXCONN for
socket listen() backlog") uses SOMAXCONN. This will always fail with in
socket_get_fd().

This patch calls listen(2) on the fd to update the backlog value. The
socket may already be in the listen state. I have tested that this works
on Linux 5.10 and macOS Catalina.

As a bonus this allows us to detect when the fd cannot listen. Now we'll
be able to catch unbound or connected fds in socket_listen().

Drop the num argument from socket_get_fd() since this function is also
called by socket_connect() where a listen backlog value does not make
sense.

Fixes: e5b6353cf2 ("socket: Add backlog parameter to socket_listen")
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Cc: Juan Quintela <quintela@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20210310173004.420190-1-stefanha@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 37179e9ea4)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:37:52 -05:00
Paolo Bonzini 5b96b36a61 vl: plug -object back into -readconfig
Commit bc2f4fcb1d ("qom: move user_creatable_add_opts logic to vl.c
and QAPIfy it", 2021-03-19) switched the creation of objects from
qemu_opts_foreach to a bespoke QTAILQ in preparation for supporting JSON
syntax in -object.

Unfortunately in doing so it lost support for [object] stanzas in
configuration files and also for "-set object.ID.KEY=VAL".  The latter
is hard to re-establish and probably best solved by deprecating -set.
This patch uses the infrastructure introduced by the previous two
patches in order to parse QOM objects correctly from configuration
files.

Cc: Markus Armbruster <armbru@redhat.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20210524105752.3318299-4-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 49e987695a)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:32:42 -05:00
Paolo Bonzini c675ba821c vl: plumb keyval-based options into -readconfig
Let -readconfig support parsing command line options into QDict or
QemuOpts.  This will be used to add back support for objects in
-readconfig.

Cc: Markus Armbruster <armbru@redhat.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20210524105752.3318299-3-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c0d4aa82f8)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:32:04 -05:00
Paolo Bonzini 203f0ba144 qemu-config: parse configuration files to a QDict
Change the parser to put the values into a QDict and pass them
to a callback.  qemu_config_parse's QemuOpts creation is
itself turned into a callback function.

This is useful for -readconfig to support keyval-based options;
getting a QDict from the parser removes a roundtrip from
QDict to QemuOpts and then back to QDict.

Unfortunately there is a disadvantage in that semantic errors will
point to the last line of the group, because the entries of the QDict
do not have a location attached.

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20210524105752.3318299-2-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3770141139)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:30:01 -05:00
Paolo Bonzini 701ff59cc4 qemu-config: load modules when instantiating option groups
Right now the SPICE module is special cased to be loaded when processing
of the -spice command line option.  However, the spice option group
can also be brought in via -readconfig, in which case the module is
not loaded.

Add a generic hook to load modules that provide a QemuOpts group,
and use it for the "spice" and "iscsi" groups.

Fixes: #194
Fixes: https://bugs.launchpad.net/qemu/+bug/1910696
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 632a887350)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:29:47 -05:00
Paolo Bonzini 4e1eef8611 qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 941a4736d2)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:14:03 -05:00
Max Filippov ab33188125 target/xtensa: fix access ring in l32ex
l32ex does memory access as all regular load/store operations at CRING
level. Fix apparent pasto from l32e that caused it to use RING instead.

This is a correctness issue, not a security issue, because in the worst
case the privilege level of memory access may be lowered, resulting in
an exception when the correct implementation would've succeeded.
In no case it would allow memory access that would've raised an
exception in the correct implementation.

Cc: qemu-stable@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 735aa900e4)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:12:35 -05:00
Paolo Bonzini b20eff3ba4 vl: allow not specifying size in -m when using -M memory-backend
Starting in QEMU 6.0's commit f5c9fcb82d ("vl: separate
qemu_create_machine", 2020-12-10), a function have_custom_ram_size()
replaced the return value of set_memory_options().

The purpose of the return value was to record the presence of
"-m size", and if it was not there, change the default RAM
size to the size of the memory backend passed with "-M
memory-backend".

With that commit, however, have_custom_ram_size() is now queried only
after set_memory_options has stored the fixed-up RAM size in QemuOpts for
"future use".  This was actually the only future use of the fixed-up RAM
size, so remove that code and fix the bug.

Cc: qemu-stable@nongnu.org
Fixes: f5c9fcb82d ("vl: separate qemu_create_machine", 2020-12-10)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d349f92f78)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:10:19 -05:00
Giuseppe Musacchio 59ac5e6d61 target/ppc: Fix load endianness for lxvwsx/lxvdsx
TARGET_WORDS_BIGENDIAN may not match the machine endianness if that's a
runtime-configurable parameter.

Fixes: bcb0b7b1a1
Fixes: afae37d98a
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/212

Signed-off-by: Giuseppe Musacchio <thatlemon@gmail.com>
Message-Id: <20210518133020.58927-1-thatlemon@gmail.com>
Tested-by: Paul A. Clarke <pc@us.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 861f10fd52)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:09:27 -05:00
Richard Henderson e2258e5279 target/i386: Exit tb after wrmsr
At minimum, wrmsr can change efer, which affects HF_LMA.

Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20210514151342.384376-46-richard.henderson@linaro.org>
(cherry picked from commit 244843b757)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:07:16 -05:00
Li Zhijian fdf58b451b migration/rdma: Fix cm_event used before being initialized
A segmentation fault was triggered when i try to abort a postcopy + rdma
migration.

since rdma_ack_cm_event releases a uninitialized cm_event in these case.

like below:
2496     ret = rdma_get_cm_event(rdma->channel, &cm_event);
2497     if (ret) {
2498         perror("rdma_get_cm_event after rdma_connect");
2499         ERROR(errp, "connecting to destination!");
2500         rdma_ack_cm_event(cm_event); <<<< cause segmentation fault
2501         goto err_rdma_source_connect;
2502     }

Refer to the rdma_get_cm_event() code, cm_event will be
updated/changed only if rdma_get_cm_event() returns 0. So it's okey to
remove the ack in error patch.

Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>

Message-Id: <20210519064740.10828-1-lizhijian@cn.fujitsu.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit efb208dc9c)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 15:03:11 -05:00
Stefan Reiter 318b076356 monitor/qmp: fix race on CHR_EVENT_CLOSED without OOB
The QMP dispatcher coroutine holds the qmp_queue_lock over a yield
point, where it expects to be rescheduled from the main context. If a
CHR_EVENT_CLOSED event is received just then, it can race and block the
main thread on the mutex in monitor_qmp_cleanup_queue_and_resume.

monitor_resume does not need to be called from main context, so we can
call it immediately after popping a request from the queue, which allows
us to drop the qmp_queue_lock mutex before yielding.

Suggested-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
Message-Id: <20210322154024.15011-1-s.reiter@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit a67b996e78)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-14 14:49:46 -05:00
Greg Kurz c1d1c0b4c3 docs/system: Document the removal of "compat" property for POWER CPUs
This is just an oversight.

Fixes: f518be3aa3 ("target/ppc: Remove "compat" property of server class POWER CPUs")
Cc: groug@kaod.org
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <161399328834.51902.14269239378658110394.stgit@bahia.lan>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit a058b89507)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-13 11:22:35 -05:00
Richard Henderson 5d0c78455e linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
These three features are already enabled by TCG, but are missing
their hwcap bits.  Update HWCAP2 from linux v5.12.

Cc: qemu-stable@nongnu.org (for 6.0.1)
Buglink: https://bugs.launchpad.net/bugs/1926044
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210427214108.88503-1-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 68948d1822)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-13 11:21:27 -05:00
Zenghui Yu 1513997aa2 multi-process: Initialize variables declared with g_auto*
Quote docs/devel/style.rst (section "Automatic memory deallocation"):

* Variables declared with g_auto* MUST always be initialized,
  otherwise the cleanup function will use uninitialized stack memory

Initialize @name properly to get rid of the compilation error (using
gcc-7.3.0 on CentOS):

../hw/remote/proxy.c: In function 'pci_proxy_dev_realize':
/usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: error: 'name' may be used uninitialized in this function [-Werror=maybe-uninitialized]
   g_free (*pp);
   ^~~~~~~~~~~~
../hw/remote/proxy.c:350:30: note: 'name' was declared here
             g_autofree char *name;
                              ^~~~

Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Reviewed-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Miroslav Rezanina <mrezanin@redhat.com>
Message-id: 20210312112143.1369-1-yuzenghui@huawei.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit d90226808b)
Signed-off-by: Michael Roth <michael.roth@amd.com>
2021-10-13 11:13:38 -05:00
84 changed files with 698 additions and 309 deletions

View File

@ -1 +1 @@
6.0.0
6.0.1

View File

@ -1621,10 +1621,20 @@ void audio_cleanup(void)
}
}
static bool vmstate_audio_needed(void *opaque)
{
/*
* Never needed, this vmstate only exists in case
* an old qemu sends it to us.
*/
return false;
}
static const VMStateDescription vmstate_audio = {
.name = "audio",
.version_id = 1,
.minimum_version_id = 1,
.needed = vmstate_audio_needed,
.fields = (VMStateField[]) {
VMSTATE_END_OF_LIST()
}

View File

@ -2163,9 +2163,9 @@ static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, Error **errp)
return NULL;
}
if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
error_setg(errp,
"Expecting TLS credentials with a client endpoint");
if (!qcrypto_tls_creds_check_endpoint(creds,
QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
errp)) {
return NULL;
}
object_ref(obj);

View File

@ -1030,7 +1030,29 @@ try_map:
r = qemu_vfio_dma_map(s->vfio,
qiov->iov[i].iov_base,
len, true, &iova);
if (r == -ENOSPC) {
/*
* In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA
* ioctl returns -ENOSPC to signal the user exhausted the DMA
* mappings available for a container since Linux kernel commit
* 492855939bdb ("vfio/type1: Limit DMA mappings per container",
* April 2019, see CVE-2019-3882).
*
* This block driver already handles this error path by checking
* for the -ENOMEM error, so we directly replace -ENOSPC by
* -ENOMEM. Beside, -ENOSPC has a specific meaning for blockdev
* coroutines: it triggers BLOCKDEV_ON_ERROR_ENOSPC and
* BLOCK_ERROR_ACTION_STOP which stops the VM, asking the operator
* to add more storage to the blockdev. Not something we can do
* easily with an IOMMU :)
*/
r = -ENOMEM;
}
if (r == -ENOMEM && retry) {
/*
* We exhausted the DMA mappings available for our container:
* recycle the volatile IOVA mappings.
*/
retry = false;
trace_nvme_dma_flush_queue_wait(s);
if (s->dma_map_count) {

View File

@ -108,9 +108,9 @@ static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, Error **errp)
return NULL;
}
if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
error_setg(errp,
"Expecting TLS credentials with a server endpoint");
if (!qcrypto_tls_creds_check_endpoint(creds,
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
errp)) {
return NULL;
}
object_ref(obj);

View File

@ -1402,18 +1402,12 @@ static void qmp_chardev_open_socket(Chardev *chr,
return;
}
object_ref(OBJECT(s->tls_creds));
if (is_listen) {
if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
error_setg(errp, "%s",
"Expected TLS credentials for server endpoint");
return;
}
} else {
if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
error_setg(errp, "%s",
"Expected TLS credentials for client endpoint");
return;
}
if (!qcrypto_tls_creds_check_endpoint(s->tls_creds,
is_listen
? QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
: QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
errp)) {
return;
}
}
s->tls_authz = g_strdup(sock->tls_authz);

9
configure vendored
View File

@ -2192,9 +2192,11 @@ static THREAD int tls_var;
int main(void) { return tls_var; }
EOF
# Check we support --no-pie first; we will need this for building ROMs.
# Check we support -fno-pie and -no-pie first; we will need the former for
# building ROMs, and both for everything if --disable-pie is passed.
if compile_prog "-Werror -fno-pie" "-no-pie"; then
CFLAGS_NOPIE="-fno-pie"
LDFLAGS_NOPIE="-no-pie"
fi
if test "$static" = "yes"; then
@ -2210,6 +2212,7 @@ if test "$static" = "yes"; then
fi
elif test "$pie" = "no"; then
CONFIGURE_CFLAGS="$CFLAGS_NOPIE $CONFIGURE_CFLAGS"
CONFIGURE_LDFLAGS="$LDFLAGS_NOPIE $CONFIGURE_LDFLAGS"
elif compile_prog "-Werror -fPIE -DPIE" "-pie"; then
CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS"
CONFIGURE_LDFLAGS="-pie $CONFIGURE_LDFLAGS"
@ -3331,7 +3334,7 @@ if ! test "$gio" = "no"; then
gio_cflags=$($pkg_config --cflags gio-2.0)
gio_libs=$($pkg_config --libs gio-2.0)
gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
if [ ! -x "$gdbus_codegen" ]; then
if ! has "$gdbus_codegen"; then
gdbus_codegen=
fi
# Check that the libraries actually work -- Ubuntu 18.04 ships
@ -5678,6 +5681,8 @@ if test "$gio" = "yes" ; then
echo "CONFIG_GIO=y" >> $config_host_mak
echo "GIO_CFLAGS=$gio_cflags" >> $config_host_mak
echo "GIO_LIBS=$gio_libs" >> $config_host_mak
fi
if test "$gdbus_codegen" != "" ; then
echo "GDBUS_CODEGEN=$gdbus_codegen" >> $config_host_mak
fi
echo "CONFIG_TLS_PRIORITY=\"$tls_priority\"" >> $config_host_mak

View File

@ -349,6 +349,7 @@ vg_resource_create_2d(VuGpu *g,
g_critical("%s: resource creation failed %d %d %d",
__func__, c2d.resource_id, c2d.width, c2d.height);
g_free(res);
vugbm_buffer_destroy(&res->buffer);
cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
return;
}
@ -399,6 +400,7 @@ vg_resource_destroy(VuGpu *g,
}
vugbm_buffer_destroy(&res->buffer);
g_free(res->iov);
pixman_image_unref(res->image);
QTAILQ_REMOVE(&g->reslist, res, next);
g_free(res);
@ -488,6 +490,11 @@ vg_resource_attach_backing(VuGpu *g,
return;
}
if (res->iov) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
return;
}
ret = vg_create_mapping_iov(g, &ab, cmd, &res->iov);
if (ret != 0) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;

View File

@ -108,9 +108,16 @@ virgl_cmd_resource_unref(VuGpu *g,
struct virtio_gpu_ctrl_command *cmd)
{
struct virtio_gpu_resource_unref unref;
struct iovec *res_iovs = NULL;
int num_iovs = 0;
VUGPU_FILL_CMD(unref);
virgl_renderer_resource_detach_iov(unref.resource_id,
&res_iovs,
&num_iovs);
g_free(res_iovs);
virgl_renderer_resource_unref(unref.resource_id);
}
@ -128,6 +135,7 @@ virgl_cmd_get_capset_info(VuGpu *g,
VUGPU_FILL_CMD(info);
memset(&resp, 0, sizeof(resp));
if (info.capset_index == 0) {
resp.capset_id = VIRTIO_GPU_CAPSET_VIRGL;
virgl_renderer_get_cap_set(resp.capset_id,
@ -169,6 +177,10 @@ virgl_cmd_get_capset(VuGpu *g,
virgl_renderer_get_cap_set(gc.capset_id, &max_ver,
&max_size);
if (!max_size) {
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
return;
}
resp = g_malloc0(sizeof(*resp) + max_size);
resp->hdr.type = VIRTIO_GPU_RESP_OK_CAPSET;
@ -279,8 +291,11 @@ virgl_resource_attach_backing(VuGpu *g,
return;
}
virgl_renderer_resource_attach_iov(att_rb.resource_id,
ret = virgl_renderer_resource_attach_iov(att_rb.resource_id,
res_iovs, att_rb.nr_entries);
if (ret != 0) {
g_free(res_iovs);
}
}
static void

View File

@ -14,8 +14,15 @@
#include "crypto/tlscreds.h"
#include "crypto/tls-cipher-suites.h"
#include "hw/nvram/fw_cfg.h"
#include "tlscredspriv.h"
#include "trace.h"
struct QCryptoTLSCipherSuites {
/* <private> */
QCryptoTLSCreds parent_obj;
/* <public> */
};
/*
* IANA registered TLS ciphers:
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4

View File

@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi-types-crypto.h"
#include "qemu/module.h"
#include "tlscredspriv.h"
#include "trace.h"
@ -259,6 +260,17 @@ qcrypto_tls_creds_finalize(Object *obj)
g_free(creds->priority);
}
bool qcrypto_tls_creds_check_endpoint(QCryptoTLSCreds *creds,
QCryptoTLSCredsEndpoint endpoint,
Error **errp)
{
if (creds->endpoint != endpoint) {
error_setg(errp, "Expected TLS credentials for a %s endpoint",
QCryptoTLSCredsEndpoint_str(endpoint));
return false;
}
return true;
}
static const TypeInfo qcrypto_tls_creds_info = {
.parent = TYPE_OBJECT,

View File

@ -29,6 +29,8 @@
#ifdef CONFIG_GNUTLS
#include <gnutls/gnutls.h>
static int
qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds,

View File

@ -23,6 +23,51 @@
#include "crypto/tlscreds.h"
#ifdef CONFIG_GNUTLS
#include <gnutls/gnutls.h>
#endif
struct QCryptoTLSCreds {
Object parent_obj;
char *dir;
QCryptoTLSCredsEndpoint endpoint;
#ifdef CONFIG_GNUTLS
gnutls_dh_params_t dh_params;
#endif
bool verifyPeer;
char *priority;
};
struct QCryptoTLSCredsAnon {
QCryptoTLSCreds parent_obj;
#ifdef CONFIG_GNUTLS
union {
gnutls_anon_server_credentials_t server;
gnutls_anon_client_credentials_t client;
} data;
#endif
};
struct QCryptoTLSCredsPSK {
QCryptoTLSCreds parent_obj;
char *username;
#ifdef CONFIG_GNUTLS
union {
gnutls_psk_server_credentials_t server;
gnutls_psk_client_credentials_t client;
} data;
#endif
};
struct QCryptoTLSCredsX509 {
QCryptoTLSCreds parent_obj;
#ifdef CONFIG_GNUTLS
gnutls_certificate_credentials_t data;
#endif
bool sanityCheck;
char *passwordid;
};
#ifdef CONFIG_GNUTLS
int qcrypto_tls_creds_get_path(QCryptoTLSCreds *creds,

View File

@ -29,6 +29,8 @@
#ifdef CONFIG_GNUTLS
#include <gnutls/gnutls.h>
static int
lookup_key(const char *pskfile, const char *username, gnutls_datum_t *key,
Error **errp)

View File

@ -30,6 +30,7 @@
#ifdef CONFIG_GNUTLS
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>

View File

@ -25,6 +25,7 @@
#include "crypto/tlscredsx509.h"
#include "qapi/error.h"
#include "authz/base.h"
#include "tlscredspriv.h"
#include "trace.h"
#ifdef CONFIG_GNUTLS

View File

@ -285,6 +285,12 @@ The RISC-V no MMU cpus have been removed. The two CPUs: ``rv32imacu-nommu`` and
``rv64imacu-nommu`` can no longer be used. Instead the MMU status can be specified
via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
``compat`` property of server class POWER CPUs (removed in 6.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``max-cpu-compat`` property of the ``pseries`` machine type should be used
instead.
System emulator machines
------------------------

View File

@ -98,8 +98,10 @@ driver options if ``--image-opts`` is specified.
.. option:: --cache=CACHE
The cache mode to be used with the file. See the documentation of
the emulator's ``-drive cache=...`` option for allowed values.
The cache mode to be used with the file. Valid values are:
``none``, ``writeback`` (the default), ``writethrough``,
``directsync`` and ``unsafe``. See the documentation of
the emulator's ``-drive cache=...`` option for more info.
.. option:: -n, --nocache

View File

@ -303,7 +303,7 @@ static void nvme_ns_init_zoned(NvmeNamespace *ns)
id_ns_z = g_malloc0(sizeof(NvmeIdNsZoned));
/* MAR/MOR are zeroes-based, 0xffffffff means no limit */
/* MAR/MOR are zeroes-based, FFFFFFFFFh means no limit */
id_ns_z->mar = cpu_to_le32(ns->params.max_active_zones - 1);
id_ns_z->mor = cpu_to_le32(ns->params.max_open_zones - 1);
id_ns_z->zoc = 0;

View File

@ -12,10 +12,19 @@
* Reference Specs: http://www.nvmexpress.org, 1.4, 1.3, 1.2, 1.1, 1.0e
*
* https://nvmexpress.org/developers/nvme-specification/
*/
/**
* Usage: add options:
*
*
* Notes on coding style
* ---------------------
* While QEMU coding style prefers lowercase hexadecimals in constants, the
* NVMe subsystem use thes format from the NVMe specifications in the comments
* (i.e. 'h' suffix instead of '0x' prefix).
*
* Usage
* -----
* See docs/system/nvme.rst for extensive documentation.
*
* Add options:
* -drive file=<file>,if=none,id=<drive_id>
* -device nvme-subsys,id=<subsys_id>,nqn=<nqn_id>
* -device nvme,serial=<serial>,id=<bus_name>, \
@ -460,7 +469,9 @@ static void nvme_irq_deassert(NvmeCtrl *n, NvmeCQueue *cq)
return;
} else {
assert(cq->vector < 32);
n->irq_status &= ~(1 << cq->vector);
if (!n->cq_pending) {
n->irq_status &= ~(1 << cq->vector);
}
nvme_irq_check(n);
}
}
@ -1253,6 +1264,7 @@ static void nvme_post_cqes(void *opaque)
NvmeCQueue *cq = opaque;
NvmeCtrl *n = cq->ctrl;
NvmeRequest *req, *next;
bool pending = cq->head != cq->tail;
int ret;
QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) {
@ -1282,6 +1294,10 @@ static void nvme_post_cqes(void *opaque)
QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
}
if (cq->tail != cq->head) {
if (cq->irq_enabled && !pending) {
n->cq_pending++;
}
nvme_irq_assert(n, cq);
}
}
@ -3607,18 +3623,18 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req)
/*
* In the base NVM command set, Flush may apply to all namespaces
* (indicated by NSID being set to 0xFFFFFFFF). But if that feature is used
* (indicated by NSID being set to FFFFFFFFh). But if that feature is used
* along with TP 4056 (Namespace Types), it may be pretty screwed up.
*
* If NSID is indeed set to 0xFFFFFFFF, we simply cannot associate the
* If NSID is indeed set to FFFFFFFFh, we simply cannot associate the
* opcode with a specific command since we cannot determine a unique I/O
* command set. Opcode 0x0 could have any other meaning than something
* command set. Opcode 0h could have any other meaning than something
* equivalent to flushing and say it DOES have completely different
* semantics in some other command set - does an NSID of 0xFFFFFFFF then
* semantics in some other command set - does an NSID of FFFFFFFFh then
* mean "for all namespaces, apply whatever command set specific command
* that uses the 0x0 opcode?" Or does it mean "for all namespaces, apply
* whatever command that uses the 0x0 opcode if, and only if, it allows
* NSID to be 0xFFFFFFFF"?
* that uses the 0h opcode?" Or does it mean "for all namespaces, apply
* whatever command that uses the 0h opcode if, and only if, it allows NSID
* to be FFFFFFFFh"?
*
* Anyway (and luckily), for now, we do not care about this since the
* device only supports namespace types that includes the NVM Flush command
@ -3934,7 +3950,7 @@ static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
NVME_CHANGED_NSID_SIZE) {
/*
* If more than 1024 namespaces, the first entry in the log page should
* be set to 0xffffffff and the others to 0 as spec.
* be set to FFFFFFFFh and the others to 0 as spec.
*/
if (i == ARRAY_SIZE(nslist)) {
memset(nslist, 0x0, sizeof(nslist));
@ -4082,6 +4098,11 @@ static uint16_t nvme_del_cq(NvmeCtrl *n, NvmeRequest *req)
trace_pci_nvme_err_invalid_del_cq_notempty(qid);
return NVME_INVALID_QUEUE_DEL;
}
if (cq->irq_enabled && cq->tail != cq->head) {
n->cq_pending--;
}
nvme_irq_deassert(n, cq);
trace_pci_nvme_del_cq(qid);
nvme_free_cq(cq, n);
@ -4332,7 +4353,7 @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeRequest *req,
trace_pci_nvme_identify_nslist(min_nsid);
/*
* Both 0xffffffff (NVME_NSID_BROADCAST) and 0xfffffffe are invalid values
* Both FFFFFFFFh (NVME_NSID_BROADCAST) and FFFFFFFFEh are invalid values
* since the Active Namespace ID List should return namespaces with ids
* *higher* than the NSID specified in the command. This is also specified
* in the spec (NVM Express v1.3d, Section 5.15.4).
@ -4379,7 +4400,7 @@ static uint16_t nvme_identify_nslist_csi(NvmeCtrl *n, NvmeRequest *req,
trace_pci_nvme_identify_nslist_csi(min_nsid, c->csi);
/*
* Same as in nvme_identify_nslist(), 0xffffffff/0xfffffffe are invalid.
* Same as in nvme_identify_nslist(), FFFFFFFFh/FFFFFFFFEh are invalid.
*/
if (min_nsid >= NVME_NSID_BROADCAST - 1) {
return NVME_INVALID_NSID | NVME_DNR;
@ -4446,7 +4467,7 @@ static uint16_t nvme_identify_ns_descr_list(NvmeCtrl *n, NvmeRequest *req)
/*
* Because the NGUID and EUI64 fields are 0 in the Identify Namespace data
* structure, a Namespace UUID (nidt = 0x3) must be reported in the
* structure, a Namespace UUID (nidt = 3h) must be reported in the
* Namespace Identification Descriptor. Add the namespace UUID here.
*/
ns_descrs->uuid.hdr.nidt = NVME_NIDT_UUID;
@ -4595,7 +4616,7 @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeRequest *req)
/*
* The Reservation Notification Mask and Reservation Persistence
* features require a status code of Invalid Field in Command when
* NSID is 0xFFFFFFFF. Since the device does not support those
* NSID is FFFFFFFFh. Since the device does not support those
* features we can always return Invalid Namespace or Format as we
* should do for all other features.
*/
@ -4847,15 +4868,15 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeRequest *req)
}
/*
* NVMe v1.3, Section 5.21.1.7: 0xffff is not an allowed value for NCQR
* NVMe v1.3, Section 5.21.1.7: FFFFh is not an allowed value for NCQR
* and NSQR.
*/
if ((dw11 & 0xffff) == 0xffff || ((dw11 >> 16) & 0xffff) == 0xffff) {
return NVME_INVALID_FIELD | NVME_DNR;
}
trace_pci_nvme_setfeat_numq((dw11 & 0xFFFF) + 1,
((dw11 >> 16) & 0xFFFF) + 1,
trace_pci_nvme_setfeat_numq((dw11 & 0xffff) + 1,
((dw11 >> 16) & 0xffff) + 1,
n->params.max_ioqpairs,
n->params.max_ioqpairs);
req->cqe.result = cpu_to_le32((n->params.max_ioqpairs - 1) |
@ -5493,7 +5514,7 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
n->bar.cc = data;
}
break;
case 0x1C: /* CSTS */
case 0x1c: /* CSTS */
if (data & (1 << 4)) {
NVME_GUEST_ERR(pci_nvme_ub_mmiowr_ssreset_w1c_unsupported,
"attempted to W1C CSTS.NSSRO"
@ -5505,7 +5526,7 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
}
break;
case 0x20: /* NSSR */
if (data == 0x4E564D65) {
if (data == 0x4e564d65) {
trace_pci_nvme_ub_mmiowr_ssreset_unsupported();
} else {
/* The spec says that writes of other values have no effect */
@ -5575,11 +5596,15 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
n->bar.cmbmsc = (n->bar.cmbmsc & 0xffffffff) | (data << 32);
return;
case 0xE00: /* PMRCAP */
case 0xe00: /* PMRCAP */
NVME_GUEST_ERR(pci_nvme_ub_mmiowr_pmrcap_readonly,
"invalid write to PMRCAP register, ignored");
return;
case 0xE04: /* PMRCTL */
case 0xe04: /* PMRCTL */
if (!NVME_CAP_PMRS(n->bar.cap)) {
return;
}
n->bar.pmrctl = data;
if (NVME_PMRCTL_EN(data)) {
memory_region_set_enabled(&n->pmr.dev->mr, true);
@ -5590,19 +5615,19 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
n->pmr.cmse = false;
}
return;
case 0xE08: /* PMRSTS */
case 0xe08: /* PMRSTS */
NVME_GUEST_ERR(pci_nvme_ub_mmiowr_pmrsts_readonly,
"invalid write to PMRSTS register, ignored");
return;
case 0xE0C: /* PMREBS */
case 0xe0C: /* PMREBS */
NVME_GUEST_ERR(pci_nvme_ub_mmiowr_pmrebs_readonly,
"invalid write to PMREBS register, ignored");
return;
case 0xE10: /* PMRSWTP */
case 0xe10: /* PMRSWTP */
NVME_GUEST_ERR(pci_nvme_ub_mmiowr_pmrswtp_readonly,
"invalid write to PMRSWTP register, ignored");
return;
case 0xE14: /* PMRMSCL */
case 0xe14: /* PMRMSCL */
if (!NVME_CAP_PMRS(n->bar.cap)) {
return;
}
@ -5622,7 +5647,7 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
}
return;
case 0xE18: /* PMRMSCU */
case 0xe18: /* PMRMSCU */
if (!NVME_CAP_PMRS(n->bar.cap)) {
return;
}
@ -5664,7 +5689,7 @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
* from PMRSTS should ensure prior writes
* made it to persistent media
*/
if (addr == 0xE08 &&
if (addr == 0xe08 &&
(NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
memory_region_msync(&n->pmr.dev->mr, 0, n->pmr.dev->size);
}
@ -5755,6 +5780,10 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
}
if (cq->tail == cq->head) {
if (cq->irq_enabled) {
n->cq_pending--;
}
nvme_irq_deassert(n, cq);
}
} else {

View File

@ -171,6 +171,7 @@ typedef struct NvmeCtrl {
uint32_t max_q_ents;
uint8_t outstanding_aers;
uint32_t irq_status;
int cq_pending;
uint64_t host_timestamp; /* Timestamp sent by the host */
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
uint64_t starttime_ms;

View File

@ -1170,8 +1170,8 @@ static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
}
buf = vram_write_buffer(s);
posy = ADDR_TO_Y(addr);
posx = ADDR_TO_X(addr);
posy = ADDR_TO_Y(addr >> 2);
posx = ADDR_TO_X(addr >> 2);
if (!buf->size) {
return;
@ -1232,8 +1232,8 @@ static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size)
return 0;
}
posy = ADDR_TO_Y(addr);
posx = ADDR_TO_X(addr);
posy = ADDR_TO_Y(addr >> 2);
posx = ADDR_TO_X(addr >> 2);
if (posy > buf->height || posx > buf->width) {
return 0;

View File

@ -432,11 +432,15 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
aml_append(dev, aml_name_decl("_ADR", aml_int(slot << 16)));
if (bsel) {
aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
/*
* Can't declare _SUN here for every device as it changes 'slot'
* enumeration order in linux kernel, so use another variable for it
*/
aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
method = aml_method("_DSM", 4, AML_SERIALIZED);
aml_append(method, aml_return(
aml_call6("PDSM", aml_arg(0), aml_arg(1), aml_arg(2),
aml_arg(3), aml_name("BSEL"), aml_name("_SUN"))
aml_arg(3), aml_name("BSEL"), aml_name("ASUN"))
));
aml_append(dev, method);
}
@ -463,6 +467,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
aml_append(method, aml_return(aml_int(s3d)));
aml_append(dev, method);
} else if (hotplug_enabled_dev) {
aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
/* add _EJ0 to make slot hotpluggable */
method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
aml_append(method,

View File

@ -275,6 +275,10 @@ static void buff2frame_pel(const uint8_t *buff, qemu_can_frame *frame)
}
frame->can_dlc = buff[0] & 0x0f;
if (frame->can_dlc > 8) {
frame->can_dlc = 8;
}
if (buff[0] & 0x80) { /* Extended */
frame->can_id |= QEMU_CAN_EFF_FLAG;
frame->can_id |= buff[1] << 21; /* ID.28~ID.21 */
@ -311,6 +315,10 @@ static void buff2frame_bas(const uint8_t *buff, qemu_can_frame *frame)
}
frame->can_dlc = buff[1] & 0x0f;
if (frame->can_dlc > 8) {
frame->can_dlc = 8;
}
for (i = 0; i < frame->can_dlc; i++) {
frame->data[i] = buff[2 + i];
}

View File

@ -1659,10 +1659,13 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
VirtIONet *n = qemu_get_nic_opaque(nc);
VirtIONetQueue *q = virtio_net_get_subqueue(nc);
VirtIODevice *vdev = VIRTIO_DEVICE(n);
VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE];
size_t lens[VIRTQUEUE_MAX_SIZE];
struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE];
struct virtio_net_hdr_mrg_rxbuf mhdr;
unsigned mhdr_cnt = 0;
size_t offset, i, guest_offset;
size_t offset, i, guest_offset, j;
ssize_t err;
if (!virtio_net_can_receive(nc)) {
return -1;
@ -1693,6 +1696,12 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
total = 0;
if (i == VIRTQUEUE_MAX_SIZE) {
virtio_error(vdev, "virtio-net unexpected long buffer chain");
err = size;
goto err;
}
elem = virtqueue_pop(q->rx_vq, sizeof(VirtQueueElement));
if (!elem) {
if (i) {
@ -1704,7 +1713,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
n->guest_hdr_len, n->host_hdr_len,
vdev->guest_features);
}
return -1;
err = -1;
goto err;
}
if (elem->in_num < 1) {
@ -1712,7 +1722,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
"virtio-net receive queue contains no in buffers");
virtqueue_detach_element(q->rx_vq, elem, 0);
g_free(elem);
return -1;
err = -1;
goto err;
}
sg = elem->in_sg;
@ -1749,12 +1760,13 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
if (!n->mergeable_rx_bufs && offset < size) {
virtqueue_unpop(q->rx_vq, elem, total);
g_free(elem);
return size;
err = size;
goto err;
}
/* signal other side */
virtqueue_fill(q->rx_vq, elem, total, i++);
g_free(elem);
elems[i] = elem;
lens[i] = total;
i++;
}
if (mhdr_cnt) {
@ -1764,10 +1776,23 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
&mhdr.num_buffers, sizeof mhdr.num_buffers);
}
for (j = 0; j < i; j++) {
/* signal other side */
virtqueue_fill(q->rx_vq, elems[j], lens[j], j);
g_free(elems[j]);
}
virtqueue_flush(q->rx_vq, i);
virtio_notify(vdev, q->rx_vq);
return size;
err:
for (j = 0; j < i; j++) {
g_free(elems[j]);
}
return err;
}
static ssize_t virtio_net_do_receive(NetClientState *nc, const uint8_t *buf,

View File

@ -29,6 +29,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/i386/pc.h"
#include "hw/pci-host/q35.h"
#include "hw/qdev-properties.h"
@ -318,6 +319,8 @@ static void mch_update_pciexbar(MCHPCIState *mch)
addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;
break;
case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:
qemu_log_mask(LOG_GUEST_ERROR, "Q35: Reserved PCIEXBAR LENGTH\n");
return;
default:
abort();
}

View File

@ -38,6 +38,13 @@ static void *pvrdma_map_to_pdir(PCIDevice *pdev, uint64_t pdir_dma,
return NULL;
}
length = ROUND_UP(length, TARGET_PAGE_SIZE);
if (nchunks * TARGET_PAGE_SIZE != length) {
rdma_error_report("Invalid nchunks/length (%u, %lu)", nchunks,
(unsigned long)length);
return NULL;
}
dir = rdma_pci_dma_map(pdev, pdir_dma, TARGET_PAGE_SIZE);
if (!dir) {
rdma_error_report("Failed to map to page directory");

View File

@ -41,7 +41,7 @@ int pvrdma_ring_init(PvrdmaRing *ring, const char *name, PCIDevice *dev,
qatomic_set(&ring->ring_state->cons_head, 0);
*/
ring->npages = npages;
ring->pages = g_malloc(npages * sizeof(void *));
ring->pages = g_malloc0(npages * sizeof(void *));
for (i = 0; i < npages; i++) {
if (!tbl[i]) {

View File

@ -92,6 +92,11 @@ static int init_dev_ring(PvrdmaRing *ring, PvrdmaRingState **ring_state,
uint64_t *dir, *tbl;
int rc = 0;
if (!num_pages) {
rdma_error_report("Ring pages count must be strictly positive");
return -EINVAL;
}
dir = rdma_pci_dma_map(pci_dev, dir_addr, TARGET_PAGE_SIZE);
if (!dir) {
rdma_error_report("Failed to map to page directory (ring %s)", name);

View File

@ -42,10 +42,9 @@ void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp)
remote_sysmem_reset();
for (region = 0; region < msg->num_fds; region++) {
g_autofree char *name;
for (region = 0; region < msg->num_fds; region++, suffix++) {
g_autofree char *name = g_strdup_printf("remote-mem-%u", suffix);
subregion = g_new(MemoryRegion, 1);
name = g_strdup_printf("remote-mem-%u", suffix++);
memory_region_init_ram_from_fd(subregion, NULL,
name, sysmem_info->sizes[region],
true, msg->fds[region],

View File

@ -347,13 +347,12 @@ static void probe_pci_info(PCIDevice *dev, Error **errp)
PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY;
if (size) {
g_autofree char *name;
g_autofree char *name = g_strdup_printf("bar-region-%d", i);
pdev->region[i].dev = pdev;
pdev->region[i].present = true;
if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) {
pdev->region[i].memory = true;
}
name = g_strdup_printf("bar-region-%d", i);
memory_region_init_io(&pdev->region[i].mr, OBJECT(pdev),
&proxy_mr_ops, &pdev->region[i],
name, size);

View File

@ -213,7 +213,7 @@ static int esp_select(ESPState *s)
if (!s->current_dev) {
/* No such drive */
s->rregs[ESP_RSTAT] = 0;
s->rregs[ESP_RINTR] |= INTR_DC;
s->rregs[ESP_RINTR] = INTR_DC;
s->rregs[ESP_RSEQ] = SEQ_0;
esp_raise_irq(s);
return -1;
@ -481,7 +481,6 @@ static void esp_dma_done(ESPState *s)
{
s->rregs[ESP_RSTAT] |= STAT_TC;
s->rregs[ESP_RINTR] |= INTR_BS;
s->rregs[ESP_RSEQ] = 0;
s->rregs[ESP_RFLAGS] = 0;
esp_set_tc(s, 0);
esp_raise_irq(s);
@ -917,7 +916,15 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
val = s->rregs[ESP_RINTR];
s->rregs[ESP_RINTR] = 0;
s->rregs[ESP_RSTAT] &= ~STAT_TC;
s->rregs[ESP_RSEQ] = SEQ_0;
/*
* According to the datasheet ESP_RSEQ should be cleared, but as the
* emulation currently defers information transfers to the next TI
* command leave it for now so that pedantic guests such as the old
* Linux 2.6 driver see the correct flags before the next SCSI phase
* transition.
*
* s->rregs[ESP_RSEQ] = SEQ_0;
*/
esp_lower_irq(s);
break;
case ESP_TCHI:

View File

@ -821,8 +821,15 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
wpnum = sd_addr_to_wpnum(addr);
for (i = 0; i < 32; i++, wpnum++, addr += WPGROUP_SIZE) {
if (addr >= sd->size) {
/*
* If the addresses of the last groups are outside the valid range,
* then the corresponding write protection bits shall be set to 0.
*/
continue;
}
assert(wpnum < sd->wpgrps_size);
if (addr < sd->size && test_bit(wpnum, sd->wp_groups)) {
if (test_bit(wpnum, sd->wp_groups)) {
ret |= (1 << i);
}
}

View File

@ -171,7 +171,9 @@ void usb_ep_combine_input_packets(USBEndpoint *ep)
if ((p->iov.size % ep->max_packet_size) != 0 || !p->short_not_ok ||
next == NULL ||
/* Work around for Linux usbfs bulk splitting + migration */
(totalsize == (16 * KiB - 36) && p->int_req)) {
(totalsize == (16 * KiB - 36) && p->int_req) ||
/* Next package may grow combined package over 1MiB */
totalsize > 1 * MiB - ep->max_packet_size) {
usb_device_handle_data(ep->dev, first);
assert(first->status == USB_RET_ASYNC);
if (first->combined) {

View File

@ -840,6 +840,9 @@ static void usb_uas_handle_data(USBDevice *dev, USBPacket *p)
}
break;
case UAS_PIPE_ID_STATUS:
if (p->stream > UAS_MAX_STREAMS) {
goto err_stream;
}
if (p->stream) {
QTAILQ_FOREACH(st, &uas->results, next) {
if (st->stream == p->stream) {
@ -867,6 +870,9 @@ static void usb_uas_handle_data(USBDevice *dev, USBPacket *p)
break;
case UAS_PIPE_ID_DATA_IN:
case UAS_PIPE_ID_DATA_OUT:
if (p->stream > UAS_MAX_STREAMS) {
goto err_stream;
}
if (p->stream) {
req = usb_uas_find_request(uas, p->stream);
} else {
@ -902,6 +908,11 @@ static void usb_uas_handle_data(USBDevice *dev, USBPacket *p)
p->status = USB_RET_STALL;
break;
}
err_stream:
error_report("%s: invalid stream %d", __func__, p->stream);
p->status = USB_RET_STALL;
return;
}
static void usb_uas_unrealize(USBDevice *dev)

View File

@ -620,7 +620,7 @@ static void usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
.endpoint = ep,
.length = p->iov.size
};
uint8_t buf[p->iov.size];
g_autofree uint8_t *buf = g_malloc(p->iov.size);
/* No id, we look at the ep when receiving a status back */
usb_packet_copy(p, buf, p->iov.size);
usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
@ -818,7 +818,7 @@ static void usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
usbredirparser_send_bulk_packet(dev->parser, p->id,
&bulk_packet, NULL, 0);
} else {
uint8_t buf[size];
g_autofree uint8_t *buf = g_malloc(size);
usb_packet_copy(p, buf, size);
usbredir_log_data(dev, "bulk data out:", buf, size);
usbredirparser_send_bulk_packet(dev->parser, p->id,
@ -923,7 +923,7 @@ static void usbredir_handle_interrupt_out_data(USBRedirDevice *dev,
USBPacket *p, uint8_t ep)
{
struct usb_redir_interrupt_packet_header interrupt_packet;
uint8_t buf[p->iov.size];
g_autofree uint8_t *buf = g_malloc(p->iov.size);
DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep,
p->iov.size, p->id);

View File

@ -893,6 +893,7 @@ void vfio_migration_finalize(VFIODevice *vbasedev)
remove_migration_state_change_notifier(&migration->migration_state);
qemu_del_vm_change_state_handler(migration->vm_state);
unregister_savevm(VMSTATE_IF(vbasedev->dev), "vfio", vbasedev);
vfio_migration_exit(vbasedev);
}

View File

@ -1465,8 +1465,9 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev,
name = g_strdup_printf("vhost-user/host-notifier@%p mmaps[%d]",
user, queue_idx);
memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name,
page_size, addr);
if (!n->mr.ram) /* Don't init again after suspend. */
memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name,
page_size, addr);
g_free(name);
if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) {

View File

@ -275,15 +275,12 @@ static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
{
struct vhost_vdpa *v;
uint64_t features;
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
trace_vhost_vdpa_init(dev, opaque);
v = opaque;
v->dev = dev;
dev->opaque = opaque ;
vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
dev->backend_features = features;
v->listener = vhost_vdpa_memory_listener;
v->msg_type = VHOST_IOTLB_MSG_V2;

View File

@ -30,6 +30,7 @@
#include "trace.h"
#include "qemu/error-report.h"
#include "migration/misc.h"
#include "migration/migration.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-access.h"
@ -662,6 +663,18 @@ virtio_balloon_free_page_hint_notify(NotifierWithReturn *n, void *data)
return 0;
}
/*
* Pages hinted via qemu_guest_free_page_hint() are cleared from the dirty
* bitmap and will not get migrated, especially also not when the postcopy
* destination starts using them and requests migration from the source; the
* faulting thread will stall until postcopy migration finishes and
* all threads are woken up. Let's not start free page hinting if postcopy
* is possible.
*/
if (migrate_postcopy_ram()) {
return 0;
}
switch (pnd->reason) {
case PRECOPY_NOTIFY_SETUP:
precopy_enable_free_page_optimization();

View File

@ -88,13 +88,8 @@ static void virtio_mem_pci_size_change_notify(Notifier *notifier, void *data)
size_change_notifier);
DeviceState *dev = DEVICE(pci_mem);
const uint64_t * const size_p = data;
const char *id = NULL;
if (dev->id) {
id = g_strdup(dev->id);
}
qapi_event_send_memory_device_size_change(!!id, id, *size_p);
qapi_event_send_memory_device_size_change(!!dev->id, dev->id, *size_p);
}
static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)

View File

@ -848,8 +848,8 @@ enum NvmeStatusCodes {
NVME_FW_REQ_SUSYSTEM_RESET = 0x0110,
NVME_NS_ALREADY_ATTACHED = 0x0118,
NVME_NS_PRIVATE = 0x0119,
NVME_NS_NOT_ATTACHED = 0x011A,
NVME_NS_CTRL_LIST_INVALID = 0x011C,
NVME_NS_NOT_ATTACHED = 0x011a,
NVME_NS_CTRL_LIST_INVALID = 0x011c,
NVME_CONFLICTING_ATTRS = 0x0180,
NVME_INVALID_PROT_INFO = 0x0181,
NVME_WRITE_TO_RO = 0x0182,
@ -1409,9 +1409,9 @@ typedef enum NvmeZoneState {
NVME_ZONE_STATE_IMPLICITLY_OPEN = 0x02,
NVME_ZONE_STATE_EXPLICITLY_OPEN = 0x03,
NVME_ZONE_STATE_CLOSED = 0x04,
NVME_ZONE_STATE_READ_ONLY = 0x0D,
NVME_ZONE_STATE_FULL = 0x0E,
NVME_ZONE_STATE_OFFLINE = 0x0F,
NVME_ZONE_STATE_READ_ONLY = 0x0d,
NVME_ZONE_STATE_FULL = 0x0e,
NVME_ZONE_STATE_OFFLINE = 0x0f,
} NvmeZoneState;
static inline void _nvme_check_size(void)

View File

@ -20,8 +20,6 @@ void qdict_join(QDict *dest, QDict *src, bool overwrite);
void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
void qdict_array_split(QDict *src, QList **dst);
int qdict_array_entries(QDict *src, const char *subqdict);
QObject *qdict_crumple(const QDict *src, Error **errp);
void qdict_flatten(QDict *qdict);
typedef struct QDictRenames {
const char *from;

View File

@ -19,12 +19,6 @@ typedef struct QCryptoTLSCipherSuites QCryptoTLSCipherSuites;
DECLARE_INSTANCE_CHECKER(QCryptoTLSCipherSuites, QCRYPTO_TLS_CIPHER_SUITES,
TYPE_QCRYPTO_TLS_CIPHER_SUITES)
struct QCryptoTLSCipherSuites {
/* <private> */
QCryptoTLSCreds parent_obj;
/* <public> */
};
/**
* qcrypto_tls_cipher_suites_get_data:
* @obj: pointer to a TLS cipher suites object

View File

@ -24,10 +24,6 @@
#include "qapi/qapi-types-crypto.h"
#include "qom/object.h"
#ifdef CONFIG_GNUTLS
#include <gnutls/gnutls.h>
#endif
#define TYPE_QCRYPTO_TLS_CREDS "tls-creds"
typedef struct QCryptoTLSCreds QCryptoTLSCreds;
typedef struct QCryptoTLSCredsClass QCryptoTLSCredsClass;
@ -48,22 +44,24 @@ typedef bool (*CryptoTLSCredsReload)(QCryptoTLSCreds *, Error **);
* certificate credentials.
*/
struct QCryptoTLSCreds {
Object parent_obj;
char *dir;
QCryptoTLSCredsEndpoint endpoint;
#ifdef CONFIG_GNUTLS
gnutls_dh_params_t dh_params;
#endif
bool verifyPeer;
char *priority;
};
struct QCryptoTLSCredsClass {
ObjectClass parent_class;
CryptoTLSCredsReload reload;
};
/**
* qcrypto_tls_creds_check_endpoint:
* @creds: pointer to a TLS credentials object
* @endpoint: type of network endpoint that will be using the credentials
* @errp: pointer to a NULL-initialized error object
*
* Check whether the credentials is setup according to
* the type of @endpoint argument.
*
* Returns true if the credentials is setup for the endpoint, false otherwise
*/
bool qcrypto_tls_creds_check_endpoint(QCryptoTLSCreds *creds,
QCryptoTLSCredsEndpoint endpoint,
Error **errp);
#endif /* QCRYPTO_TLSCREDS_H */

View File

@ -92,18 +92,6 @@ typedef struct QCryptoTLSCredsAnonClass QCryptoTLSCredsAnonClass;
*
*/
struct QCryptoTLSCredsAnon {
QCryptoTLSCreds parent_obj;
#ifdef CONFIG_GNUTLS
union {
gnutls_anon_server_credentials_t server;
gnutls_anon_client_credentials_t client;
} data;
#endif
};
struct QCryptoTLSCredsAnonClass {
QCryptoTLSCredsClass parent_class;
};

View File

@ -87,18 +87,6 @@ typedef struct QCryptoTLSCredsPSKClass QCryptoTLSCredsPSKClass;
* The PSK file can be created and managed using psktool.
*/
struct QCryptoTLSCredsPSK {
QCryptoTLSCreds parent_obj;
char *username;
#ifdef CONFIG_GNUTLS
union {
gnutls_psk_server_credentials_t server;
gnutls_psk_client_credentials_t client;
} data;
#endif
};
struct QCryptoTLSCredsPSKClass {
QCryptoTLSCredsClass parent_class;
};

View File

@ -96,16 +96,6 @@ typedef struct QCryptoTLSCredsX509Class QCryptoTLSCredsX509Class;
*
*/
struct QCryptoTLSCredsX509 {
QCryptoTLSCreds parent_obj;
#ifdef CONFIG_GNUTLS
gnutls_certificate_credentials_t data;
#endif
bool sanityCheck;
char *passwordid;
};
struct QCryptoTLSCredsX509Class {
QCryptoTLSCredsClass parent_class;
};

View File

@ -64,4 +64,7 @@ const char *qdict_get_try_str(const QDict *qdict, const char *key);
QDict *qdict_clone_shallow(const QDict *src);
QObject *qdict_crumple(const QDict *src, Error **errp);
void qdict_flatten(QDict *qdict);
#endif /* QDICT_H */

View File

@ -1,7 +1,9 @@
#ifndef QEMU_CONFIG_FILE_H
#define QEMU_CONFIG_FILE_H
typedef void QEMUConfigCB(const char *group, QDict *qdict, void *opaque, Error **errp);
void qemu_load_module_for_opts(const char *group);
QemuOptsList *qemu_find_opts(const char *group);
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
QemuOpts *qemu_find_opts_singleton(const char *group);
@ -14,7 +16,10 @@ void qemu_config_write(FILE *fp);
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname,
Error **errp);
int qemu_read_config_file(const char *filename, Error **errp);
/* A default callback for qemu_read_config_file(). */
void qemu_config_do_parse(const char *group, QDict *qdict, void *opaque, Error **errp);
int qemu_read_config_file(const char *filename, QEMUConfigCB *f, Error **errp);
/* Parse QDict options as a replacement for a config file (allowing multiple
enumerated (0..(n-1)) configuration "sections") */

View File

@ -586,6 +586,16 @@ enum {
ARM_HWCAP2_A64_SVESM4 = 1 << 6,
ARM_HWCAP2_A64_FLAGM2 = 1 << 7,
ARM_HWCAP2_A64_FRINT = 1 << 8,
ARM_HWCAP2_A64_SVEI8MM = 1 << 9,
ARM_HWCAP2_A64_SVEF32MM = 1 << 10,
ARM_HWCAP2_A64_SVEF64MM = 1 << 11,
ARM_HWCAP2_A64_SVEBF16 = 1 << 12,
ARM_HWCAP2_A64_I8MM = 1 << 13,
ARM_HWCAP2_A64_BF16 = 1 << 14,
ARM_HWCAP2_A64_DGH = 1 << 15,
ARM_HWCAP2_A64_RNG = 1 << 16,
ARM_HWCAP2_A64_BTI = 1 << 17,
ARM_HWCAP2_A64_MTE = 1 << 18,
};
#define ELF_HWCAP get_elf_hwcap()
@ -640,6 +650,9 @@ static uint32_t get_elf_hwcap2(void)
GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
return hwcaps;
}

View File

@ -38,18 +38,19 @@ void migration_channel_process_incoming(QIOChannel *ioc)
trace_migration_set_incoming_channel(
ioc, object_get_typename(OBJECT(ioc)));
if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET)) {
yank_register_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel,
QIO_CHANNEL(ioc));
}
if (s->parameters.tls_creds &&
*s->parameters.tls_creds &&
!object_dynamic_cast(OBJECT(ioc),
TYPE_QIO_CHANNEL_TLS)) {
migration_tls_channel_process_incoming(s, ioc, &local_err);
} else {
if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET) ||
object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_TLS)) {
yank_register_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel,
QIO_CHANNEL(ioc));
}
migration_ioc_process_incoming(ioc, &local_err);
}
@ -76,12 +77,6 @@ void migration_channel_connect(MigrationState *s,
ioc, object_get_typename(OBJECT(ioc)), hostname, error);
if (!error) {
if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET)) {
yank_register_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel,
QIO_CHANNEL(ioc));
}
if (s->parameters.tls_creds &&
*s->parameters.tls_creds &&
!object_dynamic_cast(OBJECT(ioc),
@ -99,6 +94,13 @@ void migration_channel_connect(MigrationState *s,
} else {
QEMUFile *f = qemu_fopen_channel_output(ioc);
if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET) ||
object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_TLS)) {
yank_register_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel,
QIO_CHANNEL(ioc));
}
qemu_mutex_lock(&s->qemu_file_lock);
s->to_dst_file = f;
qemu_mutex_unlock(&s->qemu_file_lock);

View File

@ -987,7 +987,8 @@ int multifd_load_cleanup(Error **errp)
for (i = 0; i < migrate_multifd_channels(); i++) {
MultiFDRecvParams *p = &multifd_recv_state->params[i];
if (object_dynamic_cast(OBJECT(p->c), TYPE_QIO_CHANNEL_SOCKET)
if ((object_dynamic_cast(OBJECT(p->c), TYPE_QIO_CHANNEL_SOCKET) ||
object_dynamic_cast(OBJECT(p->c), TYPE_QIO_CHANNEL_TLS))
&& OBJECT(p->c)->ref == 1) {
yank_unregister_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel,

View File

@ -26,6 +26,7 @@
#include "qemu-file-channel.h"
#include "qemu-file.h"
#include "io/channel-socket.h"
#include "io/channel-tls.h"
#include "qemu/iov.h"
#include "qemu/yank.h"
#include "yank_functions.h"
@ -106,7 +107,8 @@ static int channel_close(void *opaque, Error **errp)
int ret;
QIOChannel *ioc = QIO_CHANNEL(opaque);
ret = qio_channel_close(ioc, errp);
if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET)
if ((object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET) ||
object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_TLS))
&& OBJECT(ioc)->ref == 1) {
yank_unregister_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel,

View File

@ -2497,7 +2497,6 @@ static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
if (ret) {
perror("rdma_get_cm_event after rdma_connect");
ERROR(errp, "connecting to destination!");
rdma_ack_cm_event(cm_event);
goto err_rdma_source_connect;
}

View File

@ -49,11 +49,7 @@ migration_tls_get_creds(MigrationState *s,
s->parameters.tls_creds);
return NULL;
}
if (ret->endpoint != endpoint) {
error_setg(errp,
"Expected TLS credentials for a %s endpoint",
endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT ?
"client" : "server");
if (!qcrypto_tls_creds_check_endpoint(ret, endpoint, errp)) {
return NULL;
}

View File

@ -1133,7 +1133,7 @@ void hmp_loadvm(Monitor *mon, const QDict *qdict)
vm_stop(RUN_STATE_RESTORE_VM);
if (!load_snapshot(name, NULL, false, NULL, &err) && saved_vm_running) {
if (load_snapshot(name, NULL, false, NULL, &err) && saved_vm_running) {
vm_start();
}
hmp_handle_error(mon, err);
@ -1492,7 +1492,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
}
if (strcmp(target, "passwd") == 0 ||
strcmp(target, "password") == 0) {
if (arg) {
if (!arg) {
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
monitor_read_password(hmp_mon, hmp_change_read_arg, NULL);
return;

View File

@ -257,24 +257,6 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
trace_monitor_qmp_in_band_dequeue(req_obj,
req_obj->mon->qmp_requests->length);
if (qatomic_xchg(&qmp_dispatcher_co_busy, true) == true) {
/*
* Someone rescheduled us (probably because a new requests
* came in), but we didn't actually yield. Do that now,
* only to be immediately reentered and removed from the
* list of scheduled coroutines.
*/
qemu_coroutine_yield();
}
/*
* Move the coroutine from iohandler_ctx to qemu_aio_context for
* executing the command handler so that it can make progress if it
* involves an AIO_WAIT_WHILE().
*/
aio_co_schedule(qemu_get_aio_context(), qmp_dispatcher_co);
qemu_coroutine_yield();
/*
* @req_obj has a request, we hold req_obj->mon->qmp_queue_lock
*/
@ -298,8 +280,30 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
monitor_resume(&mon->common);
}
/*
* Drop the queue mutex now, before yielding, otherwise we might
* deadlock if the main thread tries to lock it.
*/
qemu_mutex_unlock(&mon->qmp_queue_lock);
if (qatomic_xchg(&qmp_dispatcher_co_busy, true) == true) {
/*
* Someone rescheduled us (probably because a new requests
* came in), but we didn't actually yield. Do that now,
* only to be immediately reentered and removed from the
* list of scheduled coroutines.
*/
qemu_coroutine_yield();
}
/*
* Move the coroutine from iohandler_ctx to qemu_aio_context for
* executing the command handler so that it can make progress if it
* involves an AIO_WAIT_WHILE().
*/
aio_co_schedule(qemu_get_aio_context(), qmp_dispatcher_co);
qemu_coroutine_yield();
/* Process request */
if (req_obj->req) {
if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_IN_BAND)) {

View File

@ -43,6 +43,7 @@
#include "io/channel-socket.h"
#include "io/net-listener.h"
#include "crypto/init.h"
#include "crypto/tlscreds.h"
#include "trace/control.h"
#include "qemu-version.h"
@ -134,7 +135,9 @@ static void usage(const char *name)
" 'snapshot.id=[ID],snapshot.name=[NAME]', or\n"
" '[ID_OR_NAME]'\n"
" -n, --nocache disable host cache\n"
" --cache=MODE set cache mode (none, writeback, ...)\n"
" --cache=MODE set cache mode used to access the disk image, the\n"
" valid options are: 'none', 'writeback' (default),\n"
" 'writethrough', 'directsync' and 'unsafe'\n"
" --aio=MODE set AIO mode (native, io_uring or threads)\n"
" --discard=MODE set discard mode (ignore, unmap)\n"
" --detect-zeroes=MODE set detect-zeroes mode (off, on, unmap)\n"
@ -422,18 +425,12 @@ static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, bool list,
return NULL;
}
if (list) {
if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
error_setg(errp,
"Expecting TLS credentials with a client endpoint");
return NULL;
}
} else {
if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
error_setg(errp,
"Expecting TLS credentials with a server endpoint");
return NULL;
}
if (!qcrypto_tls_creds_check_endpoint(creds,
list
? QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT
: QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
errp)) {
return NULL;
}
object_ref(obj);
return creds;
@ -557,7 +554,7 @@ int main(int argc, char **argv)
bool alloc_depth = false;
const char *tlscredsid = NULL;
bool imageOpts = false;
bool writethrough = true;
bool writethrough = false; /* Client will flush as needed. */
bool fork_process = false;
bool list = false;
int old_stderr = -1;

View File

@ -746,7 +746,7 @@ static void qemu_run_exit_notifiers(void)
void qemu_init_subsystems(void)
{
Error *err;
Error *err = NULL;
os_set_line_buffering();

View File

@ -122,6 +122,7 @@
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-visit-qom.h"
#include "qapi/qapi-commands-ui.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/iothread.h"
#include "qemu/guest-random.h"
@ -1708,9 +1709,15 @@ static void object_option_foreach_add(bool (*type_opt_predicate)(const char *))
}
}
static void object_option_add_visitor(Visitor *v)
{
ObjectOption *opt = g_new0(ObjectOption, 1);
visit_type_ObjectOptions(v, NULL, &opt->opts, &error_fatal);
QTAILQ_INSERT_TAIL(&object_opts, opt, next);
}
static void object_option_parse(const char *optarg)
{
ObjectOption *opt;
QemuOpts *opts;
const char *type;
Visitor *v;
@ -1738,11 +1745,8 @@ static void object_option_parse(const char *optarg)
v = opts_visitor_new(opts);
}
opt = g_new0(ObjectOption, 1);
visit_type_ObjectOptions(v, NULL, &opt->opts, &error_fatal);
object_option_add_visitor(v);
visit_free(v);
QTAILQ_INSERT_TAIL(&object_opts, opt, next);
}
/*
@ -2025,8 +2029,6 @@ static void set_memory_options(MachineClass *mc)
exit(EXIT_FAILURE);
}
/* store value for the future use */
qemu_opt_set_number(opts, "size", ram_size, &error_abort);
maxram_size = ram_size;
if (qemu_opt_get(opts, "maxmem")) {
@ -2115,13 +2117,62 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
return 0;
}
/*
* Return whether configuration group @group is stored in QemuOpts, or
* recorded as one or more QDicts by qemu_record_config_group.
*/
static bool is_qemuopts_group(const char *group)
{
if (g_str_equal(group, "object")) {
return false;
}
return true;
}
static void qemu_record_config_group(const char *group, QDict *dict,
bool from_json, Error **errp)
{
if (g_str_equal(group, "object")) {
Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
object_option_add_visitor(v);
visit_free(v);
} else {
abort();
}
}
/*
* Parse non-QemuOpts config file groups, pass the rest to
* qemu_config_do_parse.
*/
static void qemu_parse_config_group(const char *group, QDict *qdict,
void *opaque, Error **errp)
{
QObject *crumpled;
if (is_qemuopts_group(group)) {
qemu_config_do_parse(group, qdict, opaque, errp);
return;
}
crumpled = qdict_crumple(qdict, errp);
if (!crumpled) {
return;
}
if (qobject_type(crumpled) != QTYPE_QDICT) {
assert(qobject_type(crumpled) == QTYPE_QLIST);
error_setg(errp, "Lists cannot be at top level of a configuration section");
return;
}
qemu_record_config_group(group, qobject_to(QDict, crumpled), false, errp);
}
static void qemu_read_default_config_file(Error **errp)
{
ERRP_GUARD();
int ret;
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
ret = qemu_read_config_file(file, errp);
ret = qemu_read_config_file(file, qemu_parse_config_group, errp);
if (ret < 0) {
if (ret == -ENOENT) {
error_free(*errp);
@ -2130,9 +2181,8 @@ static void qemu_read_default_config_file(Error **errp)
}
}
static int qemu_set_option(const char *str)
static void qemu_set_option(const char *str, Error **errp)
{
Error *local_err = NULL;
char group[64], id[64], arg[64];
QemuOptsList *list;
QemuOpts *opts;
@ -2140,27 +2190,23 @@ static int qemu_set_option(const char *str)
rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
if (rc < 3 || str[offset] != '=') {
error_report("can't parse: \"%s\"", str);
return -1;
error_setg(errp, "can't parse: \"%s\"", str);
return;
}
list = qemu_find_opts(group);
if (list == NULL) {
return -1;
if (!is_qemuopts_group(group)) {
error_setg(errp, "-set is not supported with %s", group);
} else {
list = qemu_find_opts_err(group, errp);
if (list) {
opts = qemu_opts_find(list, id);
if (!opts) {
error_setg(errp, "there is no %s \"%s\" defined", group, id);
return;
}
qemu_opt_set(opts, arg, str + offset + 1, errp);
}
}
opts = qemu_opts_find(list, id);
if (!opts) {
error_report("there is no %s \"%s\" defined",
list->name, id);
return -1;
}
if (!qemu_opt_set(opts, arg, str + offset + 1, &local_err)) {
error_report_err(local_err);
return -1;
}
return 0;
}
static void user_register_global_props(void)
@ -2462,7 +2508,7 @@ static void qemu_process_help_options(void)
static void qemu_maybe_daemonize(const char *pid_file)
{
Error *err;
Error *err = NULL;
os_daemonize();
rcu_disable_atfork();
@ -2615,6 +2661,23 @@ void qmp_x_exit_preconfig(Error **errp)
}
}
#ifdef CONFIG_MODULES
void qemu_load_module_for_opts(const char *group)
{
static bool spice_tried;
if (g_str_equal(group, "spice") && !spice_tried) {
ui_module_load_one("spice-core");
spice_tried = true;
}
static bool iscsi_tried;
if (g_str_equal(group, "iscsi") && !iscsi_tried) {
block_module_load_one("iscsi");
iscsi_tried = true;
}
}
#endif
void qemu_init(int argc, char **argv, char **envp)
{
QemuOpts *opts;
@ -2737,8 +2800,7 @@ void qemu_init(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_set:
if (qemu_set_option(optarg) != 0)
exit(1);
qemu_set_option(optarg, &error_fatal);
break;
case QEMU_OPTION_global:
if (qemu_global_option(optarg) != 0)
@ -3370,14 +3432,10 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_plugin_opt_parse(optarg, &plugin_list);
break;
case QEMU_OPTION_readconfig:
qemu_read_config_file(optarg, &error_fatal);
qemu_read_config_file(optarg, qemu_parse_config_group, &error_fatal);
break;
case QEMU_OPTION_spice:
olist = qemu_find_opts_err("spice", NULL);
if (!olist) {
ui_module_load_one("spice-core");
olist = qemu_find_opts("spice");
}
if (!olist) {
error_report("spice support is disabled");
exit(1);

View File

@ -22,6 +22,7 @@ stub_ss.add(files('isa-bus.c'))
stub_ss.add(files('is-daemonized.c'))
stub_ss.add(when: 'CONFIG_LINUX_AIO', if_true: files('linux-aio.c'))
stub_ss.add(files('migr-blocker.c'))
stub_ss.add(files('module-opts.c'))
stub_ss.add(files('monitor.c'))
stub_ss.add(files('monitor-core.c'))
stub_ss.add(files('pci-bus.c'))

View File

@ -0,0 +1,6 @@
#include "qemu/osdep.h"
#include "qemu/config-file.h"
void qemu_load_module_for_opts(const char *group)
{
}

View File

@ -816,6 +816,7 @@ vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
shadow_regions[j].gpa = dev->regions[i].gpa;
shadow_regions[j].size = dev->regions[i].size;
shadow_regions[j].qva = dev->regions[i].qva;
shadow_regions[j].mmap_addr = dev->regions[i].mmap_addr;
shadow_regions[j].mmap_offset = dev->regions[i].mmap_offset;
j++;
} else {

View File

@ -265,12 +265,15 @@ static void arm_cpu_reset(DeviceState *dev)
env->uncached_cpsr = ARM_CPU_MODE_SVC;
}
env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
#endif
if (arm_feature(env, ARM_FEATURE_M)) {
#ifndef CONFIG_USER_ONLY
uint32_t initial_msp; /* Loaded from 0x0 */
uint32_t initial_pc; /* Loaded from 0x4 */
uint8_t *rom;
uint32_t vecbase;
#endif
if (cpu_isar_feature(aa32_lob, cpu)) {
/*
@ -324,6 +327,8 @@ static void arm_cpu_reset(DeviceState *dev)
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
}
#ifndef CONFIG_USER_ONLY
/* Unlike A/R profile, M profile defines the reset LR value */
env->regs[14] = 0xffffffff;
@ -351,8 +356,22 @@ static void arm_cpu_reset(DeviceState *dev)
env->regs[13] = initial_msp & 0xFFFFFFFC;
env->regs[15] = initial_pc & ~1;
env->thumb = initial_pc & 1;
#else
/*
* For user mode we run non-secure and with access to the FPU.
* The FPU context is active (ie does not need further setup)
* and is owned by non-secure.
*/
env->v7m.secure = false;
env->v7m.nsacr = 0xcff;
env->v7m.cpacr[M_REG_NS] = 0xf0ffff;
env->v7m.fpccr[M_REG_S] &=
~(R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK);
env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
#endif
}
#ifndef CONFIG_USER_ONLY
/* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently
* executing as AArch32 then check if highvecs are enabled and
* adjust the PC accordingly.

View File

@ -7198,6 +7198,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_helper_rdmsr(cpu_env);
} else {
gen_helper_wrmsr(cpu_env);
gen_jmp_im(s, s->pc - s->cs_base);
gen_eob(s);
}
}
break;

View File

@ -139,7 +139,7 @@ static void gen_lxvwsx(DisasContext *ctx)
gen_addr_reg_index(ctx, EA);
data = tcg_temp_new_i32();
tcg_gen_qemu_ld_i32(data, EA, ctx->mem_idx, MO_TEUL);
tcg_gen_qemu_ld_i32(data, EA, ctx->mem_idx, DEF_MEMOP(MO_UL));
tcg_gen_gvec_dup_i32(MO_UL, vsr_full_offset(xT(ctx->opcode)), 16, 16, data);
tcg_temp_free(EA);
@ -162,7 +162,7 @@ static void gen_lxvdsx(DisasContext *ctx)
gen_addr_reg_index(ctx, EA);
data = tcg_temp_new_i64();
tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, MO_TEQ);
tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
tcg_gen_gvec_dup_i64(MO_Q, vsr_full_offset(xT(ctx->opcode)), 16, 16, data);
tcg_temp_free(EA);

View File

@ -1817,7 +1817,7 @@ static void translate_l32ex(DisasContext *dc, const OpcodeArg arg[],
tcg_gen_mov_i32(addr, arg[1].in);
gen_load_store_alignment(dc, 2, addr, true);
gen_check_exclusive(dc, addr, false);
tcg_gen_qemu_ld_i32(arg[0].out, addr, dc->ring, MO_TEUL);
tcg_gen_qemu_ld_i32(arg[0].out, addr, dc->cring, MO_TEUL);
tcg_gen_mov_i32(cpu_exclusive_addr, addr);
tcg_gen_mov_i32(cpu_exclusive_val, arg[0].out);
tcg_temp_free(addr);

View File

@ -987,14 +987,18 @@ static void tcg_target_qemu_prologue(TCGContext *s)
{
int tmp_buf_size, frame_size;
/* The TCG temp buffer is at the top of the frame, immediately
below the frame pointer. */
/*
* The TCG temp buffer is at the top of the frame, immediately
* below the frame pointer. Use the logical (aligned) offset here;
* the stack bias is applied in temp_allocate_frame().
*/
tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
tmp_buf_size);
tcg_set_frame(s, TCG_REG_I6, -tmp_buf_size, tmp_buf_size);
/* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
otherwise the minimal frame usable by callees. */
/*
* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
* otherwise the minimal frame usable by callees.
*/
frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
frame_size += TCG_TARGET_STACK_ALIGN - 1;

View File

@ -3489,20 +3489,38 @@ static void check_regs(TCGContext *s)
static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
{
#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
/* Sparc64 stack is accessed with offset of 2047 */
s->current_frame_offset = (s->current_frame_offset +
(tcg_target_long)sizeof(tcg_target_long) - 1) &
~(sizeof(tcg_target_long) - 1);
#endif
if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
s->frame_end) {
tcg_abort();
intptr_t off, size, align;
switch (ts->type) {
case TCG_TYPE_I32:
size = align = 4;
break;
case TCG_TYPE_I64:
case TCG_TYPE_V64:
size = align = 8;
break;
case TCG_TYPE_V128:
size = align = 16;
break;
case TCG_TYPE_V256:
/* Note that we do not require aligned storage for V256. */
size = 32, align = 16;
break;
default:
g_assert_not_reached();
}
ts->mem_offset = s->current_frame_offset;
assert(align <= TCG_TARGET_STACK_ALIGN);
off = ROUND_UP(s->current_frame_offset, align);
assert(off + size <= s->frame_end);
s->current_frame_offset = off + size;
ts->mem_offset = off;
#if defined(__sparc__)
ts->mem_offset += TCG_TARGET_STACK_BIAS;
#endif
ts->mem_base = s->frame_temp;
ts->mem_allocated = 1;
s->current_frame_offset += sizeof(tcg_target_long);
}
static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -45,6 +45,7 @@
#include "qapi/qapi-commands-ui.h"
#include "ui/input.h"
#include "crypto/hash.h"
#include "crypto/tlscreds.h"
#include "crypto/tlscredsanon.h"
#include "crypto/tlscredsx509.h"
#include "crypto/random.h"
@ -4071,9 +4072,9 @@ void vnc_display_open(const char *id, Error **errp)
}
object_ref(OBJECT(vd->tlscreds));
if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
error_setg(errp,
"Expecting TLS credentials with a server endpoint");
if (!qcrypto_tls_creds_check_endpoint(vd->tlscreds,
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
errp)) {
goto fail;
}
}

View File

@ -2,6 +2,7 @@
#include "block/qdict.h" /* for qdict_extract_subqdict() */
#include "qapi/error.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
#include "qemu/error-report.h"
@ -16,6 +17,7 @@ static QemuOptsList *find_list(QemuOptsList **lists, const char *group,
{
int i;
qemu_load_module_for_opts(group);
for (i = 0; lists[i] != NULL; i++) {
if (strcmp(lists[i]->name, group) == 0)
break;
@ -350,19 +352,19 @@ void qemu_config_write(FILE *fp)
}
/* Returns number of config groups on success, -errno on error */
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp)
static int qemu_config_foreach(FILE *fp, QEMUConfigCB *cb, void *opaque,
const char *fname, Error **errp)
{
char line[1024], group[64], id[64], arg[64], value[1024];
char line[1024], prev_group[64], group[64], arg[64], value[1024];
Location loc;
QemuOptsList *list = NULL;
Error *local_err = NULL;
QemuOpts *opts = NULL;
QDict *qdict = NULL;
int res = -EINVAL, lno = 0;
int count = 0;
loc_push_none(&loc);
while (fgets(line, sizeof(line), fp) != NULL) {
loc_set_file(fname, ++lno);
++lno;
if (line[0] == '\n') {
/* skip empty lines */
continue;
@ -371,39 +373,39 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error *
/* comment */
continue;
}
if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
/* group with id */
list = find_list(lists, group, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto out;
if (line[0] == '[') {
QDict *prev = qdict;
if (sscanf(line, "[%63s \"%63[^\"]\"]", group, value) == 2) {
qdict = qdict_new();
qdict_put_str(qdict, "id", value);
count++;
} else if (sscanf(line, "[%63[^]]]", group) == 1) {
qdict = qdict_new();
count++;
}
opts = qemu_opts_create(list, id, 1, NULL);
count++;
continue;
}
if (sscanf(line, "[%63[^]]]", group) == 1) {
/* group without id */
list = find_list(lists, group, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto out;
if (qdict != prev) {
if (prev) {
cb(prev_group, prev, opaque, &local_err);
qobject_unref(prev);
if (local_err) {
error_propagate(errp, local_err);
goto out;
}
}
strcpy(prev_group, group);
continue;
}
opts = qemu_opts_create(list, NULL, 0, &error_abort);
count++;
continue;
}
loc_set_file(fname, lno);
value[0] = '\0';
if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2 ||
sscanf(line, " %63s = \"\"", arg) == 1) {
/* arg = value */
if (opts == NULL) {
if (qdict == NULL) {
error_setg(errp, "no group defined");
goto out;
}
if (!qemu_opt_set(opts, arg, value, errp)) {
goto out;
}
qdict_put_str(qdict, arg, value);
continue;
}
error_setg(errp, "parse error");
@ -416,11 +418,48 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error *
}
res = count;
out:
if (qdict) {
cb(group, qdict, opaque, errp);
qobject_unref(qdict);
}
loc_pop(&loc);
return res;
}
int qemu_read_config_file(const char *filename, Error **errp)
void qemu_config_do_parse(const char *group, QDict *qdict, void *opaque, Error **errp)
{
QemuOptsList **lists = opaque;
const char *id = qdict_get_try_str(qdict, "id");
QemuOptsList *list;
QemuOpts *opts;
const QDictEntry *unrecognized;
list = find_list(lists, group, errp);
if (!list) {
return;
}
opts = qemu_opts_create(list, id, 1, errp);
if (!opts) {
return;
}
if (!qemu_opts_absorb_qdict(opts, qdict, errp)) {
qemu_opts_del(opts);
return;
}
unrecognized = qdict_first(qdict);
if (unrecognized) {
error_setg(errp, QERR_INVALID_PARAMETER, unrecognized->key);
qemu_opts_del(opts);
}
}
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp)
{
return qemu_config_foreach(fp, qemu_config_do_parse, lists, fname, errp);
}
int qemu_read_config_file(const char *filename, QEMUConfigCB *cb, Error **errp)
{
FILE *f = fopen(filename, "r");
int ret;
@ -430,7 +469,7 @@ int qemu_read_config_file(const char *filename, Error **errp)
return -errno;
}
ret = qemu_config_parse(f, vm_config_groups, filename, errp);
ret = qemu_config_foreach(f, cb, vm_config_groups, filename, errp);
fclose(f);
return ret;
}

View File

@ -1056,7 +1056,8 @@ bool qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
while (entry != NULL) {
next = qdict_next(qdict, entry);
if (find_desc_by_name(opts->list->desc, entry->key)) {
if (opts_accepts_any(opts->list) ||
find_desc_by_name(opts->list->desc, entry->key)) {
if (!qemu_opts_from_qdict_entry(opts, entry, errp)) {
return false;
}

View File

@ -1116,14 +1116,10 @@ fail:
return NULL;
}
static int socket_get_fd(const char *fdstr, int num, Error **errp)
static int socket_get_fd(const char *fdstr, Error **errp)
{
Monitor *cur_mon = monitor_cur();
int fd;
if (num != 1) {
error_setg_errno(errp, EINVAL, "socket_get_fd: too many connections");
return -1;
}
if (cur_mon) {
fd = monitor_get_fd(cur_mon, fdstr, errp);
if (fd < 0) {
@ -1159,7 +1155,7 @@ int socket_connect(SocketAddress *addr, Error **errp)
break;
case SOCKET_ADDRESS_TYPE_FD:
fd = socket_get_fd(addr->u.fd.str, 1, errp);
fd = socket_get_fd(addr->u.fd.str, errp);
break;
case SOCKET_ADDRESS_TYPE_VSOCK:
@ -1187,7 +1183,26 @@ int socket_listen(SocketAddress *addr, int num, Error **errp)
break;
case SOCKET_ADDRESS_TYPE_FD:
fd = socket_get_fd(addr->u.fd.str, num, errp);
fd = socket_get_fd(addr->u.fd.str, errp);
if (fd < 0) {
return -1;
}
/*
* If the socket is not yet in the listen state, then transition it to
* the listen state now.
*
* If it's already listening then this updates the backlog value as
* requested.
*
* If this socket cannot listen because it's already in another state
* (e.g. unbound or connected) then we'll catch the error here.
*/
if (listen(fd, num) != 0) {
error_setg_errno(errp, errno, "Failed to listen on fd socket");
closesocket(fd);
return -1;
}
break;
case SOCKET_ADDRESS_TYPE_VSOCK: