Compare commits

...
104 Commits
Author SHA1 Message Date
Michael Tokarev 681858ea14 Update version for 7.2.4 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-07-09 00:33:17 +03:00
Dongwon Kim 5cc60b67d3 ui/gtk: set the area of the scanout texture correctly
x and y offsets and width and height of the scanout texture
is not correctly configured in case guest scanout frame is
dmabuf.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Message-ID: <20230621213150.29573-1-dongwon.kim@intel.com>
(cherry picked from commit 37802a24eb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-07-02 07:49:18 +03:00
Shameer Kolothum 3b1b9aa4d5 vfio/pci: Call vfio_prepare_kvm_msi_virq_batch() in MSI retry path
When vfio_enable_vectors() returns with less than requested nr_vectors
we retry with what kernel reported back. But the retry path doesn't
call vfio_prepare_kvm_msi_virq_batch() and this results in,

qemu-system-aarch64: vfio: Error: Failed to enable 4 MSI vectors, retry with 1
qemu-system-aarch64: ../hw/vfio/pci.c:602: vfio_commit_kvm_msi_virq_batch: Assertion `vdev->defer_kvm_irq_routing' failed

Fixes: dc580d51f7 ("vfio: defer to commit kvm irq routing when enable msi/msix")
Reviewed-by: Longpeng <longpeng2@huawei.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit c174088923)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-30 19:02:13 +03:00
Zhenzhong Duan c7b6b705ef vfio/pci: Fix a segfault in vfio_realize
The kvm irqchip notifier is only registered if the device supports
INTx, however it's unconditionally removed in vfio realize error
path. If the assigned device does not support INTx, this will cause
QEMU to crash when vfio realize fails. Change it to conditionally
remove the notifier only if the notify hook is setup.

Before fix:
(qemu) device_add vfio-pci,host=81:11.1,id=vfio1,bus=root1,xres=1
Connection closed by foreign host.

After fix:
(qemu) device_add vfio-pci,host=81:11.1,id=vfio1,bus=root1,xres=1
Error: vfio 0000:81:11.1: xres and yres properties require display=on
(qemu)

Fixes: c5478fea27 ("vfio/pci: Respond to KVM irqchip change notifier")
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit 357bd7932a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-30 19:00:39 +03:00
Nicholas Piggin 4d8459c365 target/ppc: Fix decrementer time underflow and infinite timer loop
It is possible to store a very large value to the decrementer that it
does not raise the decrementer exception so the timer is scheduled, but
the next time value wraps and is treated as in the past.

This can occur if (u64)-1 is stored on a zero-triggered exception, or
(u64)-1 is stored twice on an underflow-triggered exception, for
example.

If such a value is set in DECAR, it gets stored to the decrementer by
the timer function, which then immediately causes another timer, which
hangs QEMU.

Clamp the decrementer to the implemented width, and use that as the
value for the timer calculation, effectively preventing this overflow.

Reported-by: sdicaro@DDCI.com
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230530131214.373524-1-npiggin@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit 09d2db9f46)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-30 09:18:28 +03:00
Eugenio Pérez 78c4994e94 vdpa: mask _F_CTRL_GUEST_OFFLOADS for vhost vdpa devices
QEMU does not emulate it so it must be disabled as long as the backend
does not support it.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230602173328.1917385-1-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
(cherry picked from commit 51e84244a7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-30 09:11:26 +03:00
Nicholas Piggin f8e3b3290c icount: don't adjust virtual time backwards after warp
The icount-based QEMU_CLOCK_VIRTUAL runs ahead of the RT clock at times.
When warping, it is possible it is still ahead at the end of the warp,
which causes icount adaptive mode to adjust it backward. This can result
in the machine observing time going backwards.

Prevent this by clamping adaptive adjustment to 0 at minimum.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-ID: <20230627061406.241847-1-npiggin@gmail.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 67f85346ca)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-29 18:17:49 +03:00
Vivek Kasireddy 44acbc7736 virtio-gpu: Make non-gl display updates work again when blob=true
In the case where the console does not have gl capability, and
if blob is set to true, make sure that the display updates still
work. Commit e86a93f554 accidentally broke this by misplacing
the return statement (in resource_flush) causing the updates to
be silently ignored.

Fixes: e86a93f554 ("virtio-gpu: splitting one extended mode guest fb into n-scanouts")
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Dongwon Kim <dongwon.kim@intel.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20230623060454.3749910-1-vivek.kasireddy@intel.com>
(cherry picked from commit 34e29d85a7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-28 18:52:17 +03:00
Ani Sinha 3d12598b74 vhost-vdpa: do not cleanup the vdpa/vhost-net structures if peer nic is present
When a peer nic is still attached to the vdpa backend, it is too early to free
up the vhost-net and vdpa structures. If these structures are freed here, then
QEMU crashes when the guest is being shut down. The following call chain
would result in an assertion failure since the pointer returned from
vhost_vdpa_get_vhost_net() would be NULL:

do_vm_stop() -> vm_state_notify() -> virtio_set_status() ->
virtio_net_vhost_status() -> get_vhost_net().

Therefore, we defer freeing up the structures until at guest shutdown
time when qemu_cleanup() calls net_cleanup() which then calls
qemu_del_net_client() which would eventually call vhost_vdpa_cleanup()
again to free up the structures. This time, the loop in net_cleanup()
ensures that vhost_vdpa_cleanup() will be called one last time when
all the peer nics are detached and freed.

All unit tests pass with this change.

CC: imammedo@redhat.com
CC: jusual@redhat.com
CC: mst@redhat.com
Fixes: CVE-2023-3301
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2128929
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Message-Id: <20230619065209.442185-1-anisinha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a0d7215e33)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context change for stable-7.2)
2023-06-26 19:35:39 +03:00
Eugenio Pérez bc1a3a1774 vdpa: fix not using CVQ buffer in case of error
Bug introducing when refactoring.  Otherway, the guest never received
the used buffer.

Fixes: be4278b65f ("vdpa: extract vhost_vdpa_net_cvq_add from vhost_vdpa_net_handle_ctrl_avail")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230602173451.1917999-1-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
(cherry picked from commit d45243bcfc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-26 19:35:39 +03:00
Prasad Pandit f3b7f02c3b vhost: release memory_listener object in error path
vhost_dev_start function does not release memory_listener object
in case of an error. This may crash the guest when vhost is unable
to set memory table:

  stack trace of thread 125653:
  Program terminated with signal SIGSEGV, Segmentation fault
  #0  memory_listener_register (qemu-kvm + 0x6cda0f)
  #1  vhost_dev_start (qemu-kvm + 0x699301)
  #2  vhost_net_start (qemu-kvm + 0x45b03f)
  #3  virtio_net_set_status (qemu-kvm + 0x665672)
  #4  qmp_set_link (qemu-kvm + 0x548fd5)
  #5  net_vhost_user_event (qemu-kvm + 0x552c45)
  #6  tcp_chr_connect (qemu-kvm + 0x88d473)
  #7  tcp_chr_new_client (qemu-kvm + 0x88cf83)
  #8  tcp_chr_accept (qemu-kvm + 0x88b429)
  #9  qio_net_listener_channel_func (qemu-kvm + 0x7ac07c)
  #10 g_main_context_dispatch (libglib-2.0.so.0 + 0x54e2f)

Release memory_listener objects in the error path.

Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
Message-Id: <20230529114333.31686-2-ppandit@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>
Fixes: c471ad0e9b ("vhost_net: device IOTLB support")
Cc: qemu-stable@nongnu.org
Acked-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 1e3ffb34f7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-26 19:35:39 +03:00
Helge Deller b3a003c890 target/hppa: Update to SeaBIOS-hppa version 8
Update SeaBIOS-hppa to version 8.

Fixes:
- boot of HP-UX with SMP, and
- reboot of Linux and HP-UX with SMP

Enhancements:
- show qemu version in boot menu
- adds exit menu entry in boot menu to quit emulation
- allow to trace PCD_CHASSIS codes & machine run status

Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 34ec3aea54)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-26 19:35:39 +03:00
Helge Deller 7b7474947f target/hppa: New SeaBIOS-hppa version 7
Update SeaBIOS-hppa to version 7 which fixes a boot problem
with Debian-12 install CD images.

The problem with Debian-12 is, that the ramdisc got bigger
than what the firmware could load in one call to the LSI
scsi driver.

Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit bb9c998ca9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: pick this one before picking next 34ec3aea54 "SeaBIOS-hppa version 8")
2023-06-26 19:35:29 +03:00
Helge Deller 51c48a919d target/hppa: Provide qemu version via fw_cfg to firmware
Give current QEMU version string to SeaBIOS-hppa via fw_cfg interface so
that the firmware can show the QEMU version in the boot menu info.

Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 069d296669)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-26 19:35:29 +03:00
Helge Deller 6331b12d60 target/hppa: Fix OS reboot issues
When the OS triggers a reboot, the reset helper function sends a
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET) together with an
EXCP_HLT exception to halt the CPUs.

So, at reboot when initializing the CPUs again, make sure to set all
instruction pointers to the firmware entry point, disable any interrupts,
disable data and instruction translations, enable PSW_Q bit  and tell qemu
to unhalt (halted=0) the CPUs again.

This fixes the various reboot issues which were seen when rebooting a
Linux VM, including the case where even the monarch CPU has been virtually
halted from the OS (e.g. via "chcpu -d 0" inside the Linux VM).

Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 50ba97e928)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-26 19:35:29 +03:00
Peter Maydell 601f084ef7 pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
The xkb official name for the Arabic keyboard layout is 'ara'.
However xkb has for at least the past 15 years also permitted it to
be named via the legacy synonym 'ar'.  In xkeyboard-config 2.39 this
synoynm was removed, which breaks compilation of QEMU:

FAILED: pc-bios/keymaps/ar
/home/fred/qemu-git/src/qemu/build-full/qemu-keymap -f pc-bios/keymaps/ar -l ar
xkbcommon: ERROR: Couldn't find file "symbols/ar" in include paths
xkbcommon: ERROR: 1 include paths searched:
xkbcommon: ERROR: 	/usr/share/X11/xkb
xkbcommon: ERROR: 3 include paths could not be added:
xkbcommon: ERROR: 	/home/fred/.config/xkb
xkbcommon: ERROR: 	/home/fred/.xkb
xkbcommon: ERROR: 	/etc/xkb
xkbcommon: ERROR: Abandoning symbols file "(unnamed)"
xkbcommon: ERROR: Failed to compile xkb_symbols
xkbcommon: ERROR: Failed to compile keymap

The upstream xkeyboard-config change removing the compat
mapping is:
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/commit/470ad2cd8fea84d7210377161d86b31999bb5ea6

Make QEMU always ask for the 'ara' xkb layout, which should work on
both older and newer xkeyboard-config.  We leave the QEMU name for
this keyboard layout as 'ar'; it is not the only one where our name
for it deviates from the xkb standard name.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-id: 20230620162024.1132013-1-peter.maydell@linaro.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1709
(cherry picked from commit 497fad3897)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-26 01:31:47 +03:00
Peter Maydell 29191ea6a5 host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
We use __builtin_subcll() to do a 64-bit subtract with borrow-in and
borrow-out when the host compiler supports it.  Unfortunately some
versions of Apple Clang have a bug in their implementation of this
intrinsic which means it returns the wrong value.  The effect is that
a QEMU built with the affected compiler will hang when emulating x86
or m68k float80 division.

The upstream LLVM issue is:
https://github.com/llvm/llvm-project/issues/55253

The commit that introduced the bug apparently never made it into an
upstream LLVM release without the subsequent fix
https://github.com/llvm/llvm-project/commit/fffb6e6afdbaba563189c1f715058ed401fbc88d
but unfortunately it did make it into Apple Clang 14.0, as shipped
in Xcode 14.3 (14.2 is reported to be OK). The Apple bug number is
FB12210478.

Add ifdefs to avoid use of __builtin_subcll() on Apple Clang version
14 or greater.  There is not currently a version of Apple Clang which
has the bug fix -- when one appears we should be able to add an upper
bound to the ifdef condition so we can start using the builtin again.
We make the lower bound a conservative "any Apple clang with major
version 14 or greater" because the consequences of incorrectly
disabling the builtin when it would work are pretty small and the
consequences of not disabling it when we should are pretty bad.

Many thanks to those users who both reported this bug and also
did a lot of work in identifying the root cause; in particular
to Daniel Bertalan and osy.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1631
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1659
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Tested-by: Daniel Bertalan <dani@danielbertalan.dev>
Tested-by: Tested-By: Solra Bizna <solra@bizna.name>
Message-id: 20230622130823.1631719-1-peter.maydell@linaro.org
(cherry picked from commit b0438861ef)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-26 01:31:07 +03:00
Peter Maydell 04de6cb002 hw/timer/nrf51_timer: Don't lose time when timer is queried in tight loop
The nrf51_timer has a free-running counter which we implement using
the pattern of using two fields (update_counter_ns, counter) to track
the last point at which we calculated the counter value, and the
counter value at that time.  Then we can find the current counter
value by converting the difference in wall-clock time between then
and now to a tick count that we need to add to the counter value.

Unfortunately the nrf51_timer's implementation of this has a bug
which means it loses time every time update_counter() is called.
After updating s->counter it always sets s->update_counter_ns to
'now', even though the actual point when s->counter hit the new value
will be some point in the past (half a tick, say).  In the worst case
(guest code in a tight loop reading the counter, icount mode) the
counter is continually queried less than a tick after it was last
read, so s->counter never advances but s->update_counter_ns does, and
the guest never makes forward progress.

The fix for this is to only advance update_counter_ns to the
timestamp of the last tick, not all the way to 'now'.  (This is the
pattern used in hw/misc/mps2-fpgaio.c's counter.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Message-id: 20230606134917.3782215-1-peter.maydell@linaro.org
(cherry picked from commit d2f9a79a8c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-22 10:38:38 +03:00
Peter Maydell 09dd3f2cae hw/intc/allwinner-a10-pic: Handle IRQ levels other than 0 or 1
In commit 2c5fa0778c we fixed an endianness bug in the Allwinner
A10 PIC model; however in the process we introduced a regression.
This is because the old code was robust against the incoming 'level'
argument being something other than 0 or 1, whereas the new code was
not.

In particular, the allwinner-sdhost code treats its IRQ line
as 0-vs-non-0 rather than 0-vs-1, so when the SD controller
set its IRQ line for any reason other than transmit the
interrupt controller would ignore it. The observed effect
was a guest timeout when rebooting the guest kernel.

Handle level values other than 0 or 1, to restore the old
behaviour.

Fixes: 2c5fa0778c ("hw/intc/allwinner-a10-pic: Don't use set_bit()/clear_bit()")
(Mjt:  5eb742fce5 in stable-7.2)
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-id: 20230606104609.3692557-2-peter.maydell@linaro.org
(cherry picked from commit f837b468cd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-22 10:38:09 +03:00
Peter Maydell d0040c60f7 target/arm: Return correct result for LDG when ATA=0
The LDG instruction loads the tag from a memory address (identified
by [Xn + offset]), and then merges that tag into the destination
register Xt. We implemented this correctly for the case when
allocation tags are enabled, but didn't get it right when ATA=0:
instead of merging the tag bits into Xt, we merged them into the
memory address [Xn + offset] and then set Xt to that.

Merge the tag bits into the old Xt value, as they should be.

Cc: qemu-stable@nongnu.org
Fixes: c15294c1e3 ("target/arm: Implement LDG, STG, ST2G instructions")
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 7e2788471f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-22 10:35:22 +03:00
Peter Maydell 1bc596d079 target/arm: Fix return value from LDSMIN/LDSMAX 8/16 bit atomics
The atomic memory operations are supposed to return the old memory
data value in the destination register.  This value is not
sign-extended, even if the operation is the signed minimum or
maximum.  (In the pseudocode for the instructions the returned data
value is passed to ZeroExtend() to create the value in the register.)

We got this wrong because we were doing a 32-to-64 zero extend on the
result for 8 and 16 bit data values, rather than the correct amount
of zero extension.

Fix the bug by using ext8u and ext16u for the MO_8 and MO_16 data
sizes rather than ext32u.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230602155223.2040685-2-peter.maydell@linaro.org
(cherry picked from commit 243705aa6e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-22 10:34:30 +03:00
Cédric Le Goater 23315ad0b8 aspeed/hace: Initialize g_autofree pointer
As mentioned in docs/devel/style.rst "Automatic memory deallocation":

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

This avoids QEMU to coredump when running the "hash test" command
under Zephyr.

Cc: Steven Lee <steven_lee@aspeedtech.com>
Cc: Joel Stanley <joel@jms.id.au>
Cc: qemu-stable@nongnu.org
Fixes: c5475b3f9a ("hw: Model ASPEED's Hash and Crypto Engine")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Message-Id: <20230421131547.2177449-1-clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit c8f48b120b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-16 16:15:56 +03:00
Yin Wang 4fc28bf08a hw/riscv: qemu crash when NUMA nodes exceed available CPUs
Command "qemu-system-riscv64 -machine virt
-m 2G -smp 1 -numa node,mem=1G -numa node,mem=1G"
would trigger this problem.Backtrace with:
 #0  0x0000555555b5b1a4 in riscv_numa_get_default_cpu_node_id  at ../hw/riscv/numa.c:211
 #1  0x00005555558ce510 in machine_numa_finish_cpu_init  at ../hw/core/machine.c:1230
 #2  0x00005555558ce9d3 in machine_run_board_init  at ../hw/core/machine.c:1346
 #3  0x0000555555aaedc3 in qemu_init_board  at ../softmmu/vl.c:2513
 #4  0x0000555555aaf064 in qmp_x_exit_preconfig  at ../softmmu/vl.c:2609
 #5  0x0000555555ab1916 in qemu_init  at ../softmmu/vl.c:3617
 #6  0x000055555585463b in main  at ../softmmu/main.c:47
This commit fixes the issue by adding parameter checks.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Yin Wang <yin.wang@intel.com>
Message-Id: <20230519023758.1759434-1-yin.wang@intel.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit b9cedbf19c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-14 13:02:36 +03:00
Nicholas Piggin 6e979dba56 target/ppc: Fix PMU hflags calculation
Some of the PMU hflags bits can go out of synch, for example a store to
MMCR0 with PMCjCE=1 fails to update hflags correctly and results in
hflags mismatch:

  qemu: fatal: TCG hflags mismatch (current:0x2408003d rebuilt:0x240a003d)

This can be reproduced by running perf on a recent machine.

Some of the fragility here is the duplication of PMU hflags calculations.
This change consolidates that in a single place to update pmu-related
hflags, to be called after a well defined state changes.

The post-load PMU update is pulled out of the MSR update because it does
not depend on the MSR value.

Fixes: 8b3d1c49a9 ("target/ppc: Add new PMC HFLAGS")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230530130447.372617-1-npiggin@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit 6494d2c1fd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-11 11:15:29 +03:00
Nicholas Piggin 8e57e02ff8 target/ppc: Fix nested-hv HEAI delivery
ppc hypervisors turn HEAI interrupts into program interrupts injected
into the guest that executed the illegal instruction, if the hypervisor
doesn't handle it some other way.

The nested-hv implementation failed to account for this HEAI->program
conversion. The virtual hypervisor wants to see the HEAI when running
a nested guest, so that interrupt type can be returned to its KVM
caller.

Fixes: 7cebc5db2e ("target/ppc: Introduce a vhyp framework for nested HV support")
Cc: balaton@eik.bme.hu
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20230530132127.385001-1-npiggin@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit 6c242e79b8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-11 11:14:51 +03:00
Nicholas Piggin d31e0a3843 target/ppc: Fix lqarx to set cpu_reserve
lqarx does not set cpu_reserve, which causes stqcx. to never succeed.

Cc: qemu-stable@nongnu.org
Fixes: 94bf265867 ("target/ppc: Use atomic load for LQ and LQARX")
Fixes: 57b38ffd0c ("target/ppc: Use tcg_gen_qemu_{ld,st}_i128 for LQARX, LQ, STQ")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230605025445.161932-1-npiggin@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit e025e8f5a8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-11 11:07:26 +03:00
Anastasia Belova 9b55660e4a vnc: move assert in vnc_worker_thread_loop
job may be NULL if queue->exit is true. Check
it before dereference job.

Fixes: f31f9c1080 ("vnc: add magic cookie to VncState")
Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit bdfca8a22f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-11 11:03:26 +03:00
Mattias Nissler 8eb73afedc hw/remote: Fix vfu_cfg trace offset format
The printed offset value is prefixed with 0x, but was actually printed
in decimal. To spare others the confusion, adjust the format specifier
to hexadecimal.

Signed-off-by: Mattias Nissler <mnissler@rivosinc.com>
Reviewed-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 5fb9e82955)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-11 11:02:28 +03:00
Christian Schoenebeck 10fad73a2b 9pfs: prevent opening special files (CVE-2023-2861)
The 9p protocol does not specifically define how server shall behave when
client tries to open a special file, however from security POV it does
make sense for 9p server to prohibit opening any special file on host side
in general. A sane Linux 9p client for instance would never attempt to
open a special file on host side, it would always handle those exclusively
on its guest side. A malicious client however could potentially escape
from the exported 9p tree by creating and opening a device file on host
side.

With QEMU this could only be exploited in the following unsafe setups:

  - Running QEMU binary as root AND 9p 'local' fs driver AND 'passthrough'
    security model.

or

  - Using 9p 'proxy' fs driver (which is running its helper daemon as
    root).

These setups were already discouraged for safety reasons before,
however for obvious reasons we are now tightening behaviour on this.

Fixes: CVE-2023-2861
Reported-by: Yanwu Shen <ywsPlz@gmail.com>
Reported-by: Jietao Xiao <shawtao1125@gmail.com>
Reported-by: Jinku Li <jkli@xidian.edu.cn>
Reported-by: Wenbo Shen <shenwenbo@zju.edu.cn>
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Message-Id: <E1q6w7r-0000Q0-NM@lizzy.crudebyte.com>
(cherry picked from commit f6b0de53fb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: drop adding qemu_fstat wrapper for 7.2 where wrappers aren't used)
2023-06-08 23:52:29 +03:00
Mark Somerville 07e7102b8e qga: Fix suspend on Linux guests without systemd
Allow the Linux guest agent to attempt each of the suspend methods
(systemctl, pm-* and writing to /sys) in turn.

Prior to this guests without systemd failed to suspend due to
`guest_suspend` returning early regardless of the return value of
`systemd_supports_mode`.

Signed-off-by: Mark Somerville <mark@qpok.net>
Reviewed-by: Konstantin Kostiuk <kkostiuk@redhat.com>
Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
(cherry picked from commit 86dcb6ab9b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-08 13:30:56 +03:00
Jagannathan Raman 8e84a20705 docs: fix multi-process QEMU documentation
Fix a typo in the system documentation for multi-process QEMU.

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 7771e8b863)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 22:49:05 +03:00
Ilya Leoshkevich 03727054dc s390x/tcg: Fix CPU address returned by STIDP
In qemu-user-s390x, /proc/cpuinfo contains:

	processor 0: version = 00,  identification = 000000,  machine = 8561
	processor 1: version = 00,  identification = 400000,  machine = 8561

The highest nibble is supposed to contain the CPU address, but it's off
by 2 bits. Fix the shift value and provide a symbolic constant for it.

With the fix we get:

	processor 0: version = 00,  identification = 000000,  machine = 8561
	processor 1: version = 00,  identification = 100000,  machine = 8561

Fixes: 076d4d39b6 ("s390x/cpumodel: wire up cpu type + id for TCG")
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230605113950.1169228-2-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 71b11cbe1c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 12:04:45 +03:00
Ilya Leoshkevich c06ca3aa33 tests/tcg/s390x: Test single-stepping SVC
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230510230213.330134-3-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit be4a4cb429)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 11:55:33 +03:00
Ilya Leoshkevich 5502e5ca33 linux-user/s390x: Fix single-stepping SVC
Currently single-stepping SVC executes two instructions. The reason is
that EXCP_DEBUG for the SVC instruction itself is masked by EXCP_SVC.
Fix by re-raising EXCP_DEBUG.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230510230213.330134-2-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 01b9990a3f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 11:55:26 +03:00
Ilya Leoshkevich 82fc148344 tests/tcg/s390x: Test LOCFHR
Add a small test to prevent regressions.

Cc: qemu-stable@nongnu.org
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230526181240.1425579-5-iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 230976232f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 11:52:33 +03:00
Ilya Leoshkevich cc271aa410 target/s390x: Fix LOCFHR taking the wrong half of R2
LOCFHR should write top-to-top, but QEMU erroneously writes
bottom-to-top.

Fixes: 45aa9aa3b7 ("target/s390x: Implement load-on-condition-2 insns")
Cc: qemu-stable@nongnu.org
Reported-by: Mikhail Mitskevich <mitskevichmn@gmail.com>
Closes: https://gitlab.com/qemu-project/qemu/-/issues/1668
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230526181240.1425579-4-iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 3180b17362)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 11:52:26 +03:00
Ilya Leoshkevich 242efaca9e tests/tcg/s390x: Test LCBB
Add a test to prevent regressions.

Cc: qemu-stable@nongnu.org
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230526181240.1425579-3-iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 05d000fb4d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 11:52:17 +03:00
Ilya Leoshkevich 347714a28c target/s390x: Fix LCBB overwriting the top 32 bits
LCBB is supposed to overwrite only the bottom 32 bits, but QEMU
erroneously overwrites the entire register.

Fixes: 6d9303322e ("s390x/tcg: Implement LOAD COUNT TO BLOCK BOUNDARY")
Cc: qemu-stable@nongnu.org
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230526181240.1425579-2-iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 079181b9bc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-07 11:52:08 +03:00
Peter Maydell 7cba3a05b5 target/arm: Explicitly select short-format FSR for M-profile
For M-profile, there is no guest-facing A-profile format FSR, but we
still use the env->exception.fsr field to pass fault information from
the point where a fault is raised to the code in
arm_v7m_cpu_do_interrupt() which interprets it and sets the M-profile
specific fault status registers.  So it doesn't matter whether we
fill in env->exception.fsr in the short format or the LPAE format, as
long as both sides agree.  As it happens arm_v7m_cpu_do_interrupt()
assumes short-form.

In compute_fsr_fsc() we weren't explicitly choosing short-form for
M-profile, but instead relied on it falling out in the wash because
arm_s1_regime_using_lpae_format() would be false.  This was broken in
commit 452c67a4 when we added v8R support, because we said "PMSAv8 is
always LPAE format" (as it is for v8R), forgetting that we were
implicitly using this code path on M-profile. At that point we would
hit a g_assert_not_reached():
 ERROR:../../target/arm/internals.h:549:arm_fi_to_lfsc: code should not be reached

#7  0x0000555555e055f7 in arm_fi_to_lfsc (fi=0x7fffecff9a90) at ../../target/arm/internals.h:549
#8  0x0000555555e05a27 in compute_fsr_fsc (env=0x555557356670, fi=0x7fffecff9a90, target_el=1, mmu_idx=1, ret_fsc=0x7fffecff9a1c)
    at ../../target/arm/tlb_helper.c:95
#9  0x0000555555e05b62 in arm_deliver_fault (cpu=0x555557354800, addr=268961344, access_type=MMU_INST_FETCH, mmu_idx=1, fi=0x7fffecff9a90)
    at ../../target/arm/tlb_helper.c:132
#10 0x0000555555e06095 in arm_cpu_tlb_fill (cs=0x555557354800, address=268961344, size=1, access_type=MMU_INST_FETCH, mmu_idx=1, probe=false, retaddr=0)
    at ../../target/arm/tlb_helper.c:260

The specific assertion changed when commit fcc7404eff added
"assert not M-profile" to arm_is_secure_below_el3(), because the
conditions being checked in compute_fsr_fsc() include
arm_el_is_aa64(), which will end up calling arm_is_secure_below_el3()
and asserting before we try to call arm_fi_to_lfsc():

#7  0x0000555555efaf43 in arm_is_secure_below_el3 (env=0x5555574665a0) at ../../target/arm/cpu.h:2396
#8  0x0000555555efb103 in arm_is_el2_enabled (env=0x5555574665a0) at ../../target/arm/cpu.h:2448
#9  0x0000555555efb204 in arm_el_is_aa64 (env=0x5555574665a0, el=1) at ../../target/arm/cpu.h:2509
#10 0x0000555555efbdfd in compute_fsr_fsc (env=0x5555574665a0, fi=0x7fffecff99e0, target_el=1, mmu_idx=1, ret_fsc=0x7fffecff996c)

Avoid the assertion and the incorrect FSR format selection by
explicitly making M-profile use the short-format in this function.

Fixes: 452c67a427 ("target/arm: Enable TTBCR_EAE for ARMv8-R AArch32")a
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1658
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230523131726.866635-1-peter.maydell@linaro.org
(cherry picked from commit d7fe699be5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Clément Chigot f82dcd73e8 hw/arm/xlnx-zynqmp: fix unsigned error when checking the RPUs number
When passing --smp with a number lower than XLNX_ZYNQMP_NUM_APU_CPUS,
the expression (ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS) will result
in a positive number as ms->smp.cpus is a unsigned int.
This will raise the following error afterwards, as Qemu will try to
instantiate some additional RPUs.
  | $ qemu-system-aarch64 --smp 1 -M xlnx-zcu102
  | **
  | ERROR:../src/tcg/tcg.c:777:tcg_register_thread:
  |   assertion failed: (n < tcg_max_ctxs)

Signed-off-by: Clément Chigot <chigot@adacore.com>
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Message-id: 20230524143714.565792-1-chigot@adacore.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit c9ba1c9f02)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Tommy Wu fee86f6c5b hw/dma/xilinx_axidma: Check DMASR.HALTED to prevent infinite loop.
When we receive a packet from the xilinx_axienet and then try to s2mem
through the xilinx_axidma, if the descriptor ring buffer is full in the
xilinx axidma driver, we’ll assert the DMASR.HALTED in the
function : stream_process_s2mem and return 0. In the end, we’ll be stuck in
an infinite loop in axienet_eth_rx_notify.

This patch checks the DMASR.HALTED state when we try to push data
from xilinx axi-enet to xilinx axi-dma. When the DMASR.HALTED is asserted,
we will not keep pushing the data and then prevent the infinte loop.

Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Message-id: 20230519062137.1251741-1-tommy.wu@sifive.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 31afe04586)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Volker Rümelin 22048b1bff ui/sdl2: disable SDL_HINT_GRAB_KEYBOARD on Windows
Windows sends an extra left control key up/down input event for
every right alt key up/down input event for keyboards with
international layout. Since commit 830473455f ("ui/sdl2: fix
handling of AltGr key on Windows") QEMU uses a Windows low level
keyboard hook procedure to reliably filter out the special left
control key and to grab the keyboard on Windows.

The SDL2 version 2.0.16 introduced its own Windows low level
keyboard hook procedure to grab the keyboard. Windows calls this
callback before the QEMU keyboard hook procedure. This disables
the special left control key filter when the keyboard is grabbed.

To fix the problem, disable the SDL2 Windows low level keyboard
hook procedure.

Reported-by: Bernhard Beschow <shentey@gmail.com>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Bernhard Beschow <shentey@gmail.com>
Message-Id: <20230418062823.5683-1-vr_qemu@t-online.de>
(cherry picked from commit 1dfea3f212)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Bernhard Beschow 70237e2159 ui/sdl2: Grab Alt+F4 also under Windows
SDL doesn't grab Alt+F4 under Windows by default. Pressing Alt+F4 thus closes
the VM immediately without confirmation, possibly leading to data loss. Fix
this by always grabbing Alt+F4 on Windows hosts, too.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20230417192139.43263-3-shentey@gmail.com>
(cherry picked from commit 083db9db44)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Bernhard Beschow 6520bf66f4 ui/sdl2: Grab Alt+Tab also in fullscreen mode
By default, SDL grabs Alt+Tab only in non-fullscreen mode. This causes Alt+Tab
to switch tasks on the host rather than in the VM in fullscreen mode while it
switches tasks in non-fullscreen mode in the VM. Fix this confusing behavior
by grabbing Alt+Tab in fullscreen mode, always causing tasks to be switched in
the VM.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20230417192139.43263-2-shentey@gmail.com>
(cherry picked from commit efc00a3709)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Marc-André Lureau d4d91ae902 ui/sdl2: fix surface_gl_update_texture: Assertion 'gls' failed
Before sdl2_gl_update() is called, sdl2_gl_switch() may decide to
destroy the console window and its associated shaders.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1644
Fixes: c84ab0a500 ("ui/console: optionally update after gfx switch")

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Message-Id: <20230511074217.4171842-1-marcandre.lureau@redhat.com>
(cherry picked from commit b3a654d82e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Erico Nunes b15e44adeb ui/gtk-egl: fix scaling for cursor position in scanout mode
vc->gfx.w and vc->gfx.h are not updated appropriately in this code path,
which leads to a different scaling factor for rendering the cursor on
some edge cases (e.g. the focus has left and re-entered the gtk window).
This can be reproduced using vhost-user-gpu with the gtk ui on the x11
backend.
Use the surface dimensions which are already updated accordingly.

Signed-off-by: Erico Nunes <ernunes@redhat.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230320160856.364319-2-ernunes@redhat.com>
(cherry picked from commit f8a951bb95)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Erico Nunes 95c9059e66 ui/gtk: use widget size for cursor motion event
The gd_motion_event size has some calculations for the cursor position,
which also take into account things like different size of the
framebuffer compared to the window size.
The use of window size makes things more difficult though, as at least
in the case of Wayland includes the size of ui elements like a menu bar
at the top of the window. This leads to a wrong position calculation by
a few pixels.
Fix it by using the size of the widget, which already returns the size
of the actual space to render the framebuffer.

Signed-off-by: Erico Nunes <ernunes@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20230320160856.364319-1-ernunes@redhat.com>
(cherry picked from commit 2f31663ed4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Erico Nunes b201fb8c5a ui/gtk: fix passing y0_top parameter to scanout
The dmabuf->y0_top flag is passed to .dpy_gl_scanout_dmabuf(), however
in the gtk ui both implementations dropped it when doing the next
scanout_texture call.

Fixes flipped linux console using vhost-user-gpu with the gtk ui
display.

Signed-off-by: Erico Nunes <ernunes@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230220175605.43759-1-ernunes@redhat.com>
(cherry picked from commit 94400fa53f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Bernhard Beschow 834fc12721 hw/ppc/prep: Fix wiring of PIC -> CPU interrupt
Commit cef2e7148e ("hw/isa/i82378: Remove intermediate IRQ forwarder")
passes s->cpu_intr to i8259_init() in i82378_realize() directly. However, s-
>cpu_intr isn't initialized yet since that happens after the south bridge's
pci_realize_and_unref() in board code. Fix this by initializing s->cpu_intr
before realizing the south bridge.

Fixes: cef2e7148e ("hw/isa/i82378: Remove intermediate IRQ forwarder")
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230304114043.121024-4-shentey@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit 2237af5e60)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:56 +03:00
Thomas Huth 369e2c4e2d scripts/device-crash-test: Add a parameter to run with TCG only
We're currently facing the problem that the device-crash-test script
runs twice as long in the CI when a runner supports KVM - which sometimes
results in a timeout of the CI job. To get a more deterministic runtime
here, add an option to the script that allows to run it with TCG only.

Reported-by: Eldon Stegall <eldon-qemu@eldondev.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20230414145845.456145-3-thuth@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230424092249.58552-6-alex.bennee@linaro.org>
(cherry picked from commit 8b869aa591)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:50 +03:00
Thomas Huth 509c444bac gitlab-ci: Avoid to re-run "configure" in the device-crash-test jobs
After "make check-venv" had been added to these jobs, they started
to re-run "configure" each time since our logic in the makefile
thinks that some files are out of date here. Avoid it with the same
trick that we are using in buildtest-template.yml already by disabling
the up-to-date check via NINJA=":".

Fixes: 1d8cf47e5b ("tests: run 'device-crash-test' from tests/venv")
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20230414145845.456145-2-thuth@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230424092249.58552-5-alex.bennee@linaro.org>
(cherry picked from commit 4d3bd91b26)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-31 09:43:25 +03:00
Michael Tokarev a8f7a3504d Update version for 7.2.3 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-29 18:17:39 +03:00
Igor Mammedov 9d52aaa92b machine: do not crash if default RAM backend name has been stolen
QEMU aborts when default RAM backend should be used (i.e. no
explicit '-machine memory-backend=' specified) but user
has created an object which 'id' equals to default RAM backend
name used by board.

 $QEMU -machine pc \
       -object memory-backend-ram,id=pc.ram,size=4294967296

 Actual results:
 QEMU 7.2.0 monitor - type 'help' for more information
 (qemu) Unexpected error in object_property_try_add() at ../qom/object.c:1239:
 qemu-kvm: attempt to add duplicate property 'pc.ram' to object (type 'container')
 Aborted (core dumped)

Instead of abort, check for the conflicting 'id' and exit with
an error, suggesting how to remedy the issue.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2207886
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20230522131717.3780533-1-imammedo@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit a37531f238)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-28 12:02:26 +03:00
Thomas Huth 9fe6e8139d hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI controller (CVE-2023-0330)
We cannot use the generic reentrancy guard in the LSI code, so
we have to manually prevent endless reentrancy here. The problematic
lsi_execute_script() function has already a way to detect whether
too many instructions have been executed - we just have to slightly
change the logic here that it also takes into account if the function
has been called too often in a reentrant way.

The code in fuzz-lsi53c895a-test.c has been taken from an earlier
patch by Mauro Matteo Cascella.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1563
Message-Id: <20230522091011.1082574-1-thuth@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit b987718bbb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-28 12:02:26 +03:00
Paolo Bonzini 49d5fc4cfc usb/ohci: Set pad to 0 after frame update
When the OHCI controller's framenumber is incremented, HccaPad1 register
should be set to zero (Ref OHCI Spec 4.4)

ReactOS uses hccaPad1 to determine if the OHCI hardware is running,
consequently it fails this check in current qemu master.

Signed-off-by: Ryan Wendland <wendland@live.com.au>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1048
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 6301460ce9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-28 12:02:26 +03:00
Akihiko Odaki 12f0e61758 util/vfio-helpers: Use g_file_read_link()
When _FORTIFY_SOURCE=2, glibc version is 2.35, and GCC version is
12.1.0, the compiler complains as follows:

In file included from /usr/include/features.h:490,
                 from /usr/include/bits/libc-header-start.h:33,
                 from /usr/include/stdint.h:26,
                 from /usr/lib/gcc/aarch64-unknown-linux-gnu/12.1.0/include/stdint.h:9,
                 from /home/alarm/q/var/qemu/include/qemu/osdep.h:94,
                 from ../util/vfio-helpers.c:13:
In function 'readlink',
    inlined from 'sysfs_find_group_file' at ../util/vfio-helpers.c:116:9,
    inlined from 'qemu_vfio_init_pci' at ../util/vfio-helpers.c:326:18,
    inlined from 'qemu_vfio_open_pci' at ../util/vfio-helpers.c:517:9:
/usr/include/bits/unistd.h:119:10: error: argument 2 is null but the corresponding size argument 3 value is 4095 [-Werror=nonnull]
  119 |   return __glibc_fortify (readlink, __len, sizeof (char),
      |          ^~~~~~~~~~~~~~~

This error implies the allocated buffer can be NULL. Use
g_file_read_link(), which allocates buffer automatically to avoid the
error.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit dbdea0dbfe)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-28 12:02:26 +03:00
Stefan Hajnoczi 859759ee39 rtl8139: fix large_send_mss divide-by-zero
If the driver sets large_send_mss to 0 then a divide-by-zero occurs.
Even if the division wasn't a problem, the for loop that emits MSS-sized
packets would never terminate.

Solve these issues by skipping offloading when large_send_mss=0.

This issue was found by OSS-Fuzz as part of Alexander Bulekov's device
fuzzing work. The reproducer is:

  $ cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, -m \
  512M,slots=1,maxmem=0xffff000000000000 -machine q35 -nodefaults -device \
  rtl8139,netdev=net0 -netdev user,id=net0 -device \
  pc-dimm,id=nv1,memdev=mem1,addr=0xb800a64602800000 -object \
  memory-backend-ram,id=mem1,size=2M  -qtest stdio
  outl 0xcf8 0x80000814
  outl 0xcfc 0xe0000000
  outl 0xcf8 0x80000804
  outw 0xcfc 0x06
  write 0xe0000037 0x1 0x04
  write 0xe00000e0 0x2 0x01
  write 0x1 0x1 0x04
  write 0x3 0x1 0x98
  write 0xa 0x1 0x8c
  write 0xb 0x1 0x02
  write 0xc 0x1 0x46
  write 0xd 0x1 0xa6
  write 0xf 0x1 0xb8
  write 0xb800a646028c000c 0x1 0x08
  write 0xb800a646028c000e 0x1 0x47
  write 0xb800a646028c0010 0x1 0x02
  write 0xb800a646028c0017 0x1 0x06
  write 0xb800a646028c0036 0x1 0x80
  write 0xe00000d9 0x1 0x40
  EOF

Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1582
Closes: https://gitlab.com/qemu-project/qemu/-/issues/1582
Cc: qemu-stable@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>
Fixes: 6d71357a3b ("rtl8139: honor large send MSS value")
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 792676c165)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-28 12:02:26 +03:00
timothee.cocault@gmail.com b121ebe143 e1000e: Fix tx/rx counters
The bytes and packets counter registers are cleared on read.

Copying the "total counter" registers to the "good counter" registers has
side effects.
If the "total" register is never read by the OS, it only gets incremented.
This leads to exponential growth of the "good" register.

This commit increments the counters individually to avoid this.

Signed-off-by: Timothée Cocault <timothee.cocault@gmail.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 8d689f6aae)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: removed hw/net/igb_core.c part: igb introduced in 8.0)
2023-05-23 23:16:42 +03:00
Akihiko Odaki f9f42e708f e1000: Count CRC in Tx statistics
The Software Developer's Manual 13.7.4.5 "Packets Transmitted (64 Bytes)
Count" says:
> This register counts the number of packets transmitted that are
> exactly 64 bytes (from <Destination Address> through <CRC>,
> inclusively) in length.

It also says similar for the other Tx statistics registers. Add the
number of bytes for CRC to those registers.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit c50b152485)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: pick this for 7.2 too: a fix by its own and makes next patch to apply cleanly)
2023-05-23 23:15:45 +03:00
Mauro Matteo Cascella 926a8380f2 virtio-crypto: fix NULL pointer dereference in virtio_crypto_free_request
Ensure op_info is not NULL in case of QCRYPTODEV_BACKEND_ALG_SYM algtype.

Fixes: 0e660a6f90 ("crypto: Introduce RSA algorithm")
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Reported-by: Yiming Tao <taoym@zju.edu.cn>
Message-Id: <20230509075317.1132301-1-mcascell@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: zhenwei pi<pizhenwei@bytedance.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 3e69908907)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context tweak after 999c789f00 cryptodev: Introduce cryptodev alg type in QAPI)
2023-05-22 19:39:33 +03:00
Eugenio Pérez dd63d3a5b8 virtio-net: not enable vq reset feature unconditionally
The commit 93a97dc520 ("virtio-net: enable vq reset feature") enables
unconditionally vq reset feature as long as the device is emulated.
This makes impossible to actually disable the feature, and it causes
migration problems from qemu version previous than 7.2.

The entire final commit is unneeded as device system already enable or
disable the feature properly.

This reverts commit 93a97dc520.
Fixes: 93a97dc520 ("virtio-net: enable vq reset feature")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>

Message-Id: <20230504101447.389398-1-eperezma@redhat.com>
Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 1fac00f70b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-22 19:39:33 +03:00
Hawkins Jiawei 6f4dc62715 vhost: fix possible wrap in SVQ descriptor ring
QEMU invokes vhost_svq_add() when adding a guest's element
into SVQ. In vhost_svq_add(), it uses vhost_svq_available_slots()
to check whether QEMU can add the element into SVQ. If there is
enough space, then QEMU combines some out descriptors and some
in descriptors into one descriptor chain, and adds it into
`svq->vring.desc` by vhost_svq_vring_write_descs().

Yet the problem is that, `svq->shadow_avail_idx - svq->shadow_used_idx`
in vhost_svq_available_slots() returns the number of occupied elements,
or the number of descriptor chains, instead of the number of occupied
descriptors, which may cause wrapping in SVQ descriptor ring.

Here is an example. In vhost_handle_guest_kick(), QEMU forwards
as many available buffers to device by virtqueue_pop() and
vhost_svq_add_element(). virtqueue_pop() returns a guest's element,
and then this element is added into SVQ by vhost_svq_add_element(),
a wrapper to vhost_svq_add(). If QEMU invokes virtqueue_pop() and
vhost_svq_add_element() `svq->vring.num` times,
vhost_svq_available_slots() thinks QEMU just ran out of slots and
everything should work fine. But in fact, virtqueue_pop() returns
`svq->vring.num` elements or descriptor chains, more than
`svq->vring.num` descriptors due to guest memory fragmentation,
and this causes wrapping in SVQ descriptor ring.

This bug is valid even before marking the descriptors used.
If the guest memory is fragmented, SVQ must add chains
so it can try to add more descriptors than possible.

This patch solves it by adding `num_free` field in
VhostShadowVirtqueue structure and updating this field
in vhost_svq_add() and vhost_svq_get_buf(), to record
the number of free descriptors.

Fixes: 100890f7ca ("vhost: Shadow virtqueue buffers forwarding")
Signed-off-by: Hawkins Jiawei <yin31149@gmail.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230509084817.3973-1-yin31149@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
(cherry picked from commit 5d410557de)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-19 23:23:50 +03:00
Xinyu Li 48b60eb6c9 target/i386: fix avx2 instructions vzeroall and vpermdq
vzeroall: xmm_regs should be used instead of xmm_t0
vpermdq: bit 3 and 7 of imm should be considered

Signed-off-by: Xinyu Li <lixinyu20s@ict.ac.cn>
Message-Id: <20230510145222.586487-1-lixinyu20s@ict.ac.cn>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 056d649007)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:10:00 +03:00
Paolo Bonzini eee0666a50 target/i386: fix operand size for VCOMI/VUCOMI instructions
Compared to other SSE instructions, VUCOMISx and VCOMISx are different:
the single and double precision versions are distinguished through a
prefix, however they use no-prefix and 0x66 for SS and SD respectively.
Scalar values usually are associated with 0xF2 and 0xF3.

Because of these, they incorrectly perform a 128-bit memory load instead
of a 32- or 64-bit load.  Fix this by writing a custom decoding function.

I tested that the reproducer is fixed and the test-avx output does not
change.

Reported-by: Gabriele Svelto <gsvelto@mozilla.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1637
Fixes: f8d19eec0d ("target/i386: reimplement 0x0f 0x28-0x2f, add AVX", 2022-10-18)
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2b55e479e6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:10:00 +03:00
Paolo Bonzini 61f6b12cf3 scsi-generic: fix buffer overflow on block limits inquiry
Using linux 6.x guest, at boot time, an inquiry on a scsi-generic
device makes qemu crash.  This is caused by a buffer overflow when
scsi-generic patches the block limits VPD page.

Do the operations on a temporary on-stack buffer that is guaranteed
to be large enough.

Reported-by: Théo Maillart <tmaillart@freebox.fr>
Analyzed-by: Théo Maillart <tmaillart@freebox.fr>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9bd634b2f5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:10:00 +03:00
Richard Henderson d68a13c672 target/arm: Fix vd == vm overlap in sve_ldff1_z
If vd == vm, copy vm to scratch, so that we can pre-zero
the output and still access the gather indicies.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1612
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230504104232.1877774-1-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit a6771f2f5c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:10:00 +03:00
Eric Blake 7405624def migration: Attempt disk reactivation in more failure scenarios
Commit fe904ea824 added a fail_inactivate label, which tries to
reactivate disks on the source after a failure while s->state ==
MIGRATION_STATUS_ACTIVE, but didn't actually use the label if
qemu_savevm_state_complete_precopy() failed.  This failure to
reactivate is also present in commit 6039dd5b1c (also covering the new
s->state == MIGRATION_STATUS_DEVICE state) and 403d18ae (ensuring
s->block_inactive is set more reliably).

Consolidate the two labels back into one - no matter HOW migration is
failed, if there is any chance we can reach vm_start() after having
attempted inactivation, it is essential that we have tried to restart
disks before then.  This also makes the cleanup more like
migrate_fd_cancel().

Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20230502205212.134680-1-eblake@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6dab4c93ec)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: minor context tweak near added comment in migration/migration.c)
2023-05-18 21:10:00 +03:00
Eric Blake b514d5a898 migration: Minor control flow simplification
No need to declare a temporary variable.

Suggested-by: Juan Quintela <quintela@redhat.com>
Fixes: 1df36e8c6289 ("migration: Handle block device inactivation failures better")
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 5d39f44d7a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Eric Blake 08fd84005f migration: Handle block device inactivation failures better
Consider what happens when performing a migration between two host
machines connected to an NFS server serving multiple block devices to
the guest, when the NFS server becomes unavailable.  The migration
attempts to inactivate all block devices on the source (a necessary
step before the destination can take over); but if the NFS server is
non-responsive, the attempt to inactivate can itself fail.  When that
happens, the destination fails to get the migrated guest (good,
because the source wasn't able to flush everything properly):

  (qemu) qemu-kvm: load of migration failed: Input/output error

at which point, our only hope for the guest is for the source to take
back control.  With the current code base, the host outputs a message, but then appears to resume:

  (qemu) qemu-kvm: qemu_savevm_state_complete_precopy_non_iterable: bdrv_inactivate_all() failed (-1)

  (src qemu)info status
   VM status: running

but a second migration attempt now asserts:

  (src qemu) qemu-kvm: ../block.c:6738: int bdrv_inactivate_recurse(BlockDriverState *): Assertion `!(bs->open_flags & BDRV_O_INACTIVE)' failed.

Whether the guest is recoverable on the source after the first failure
is debatable, but what we do not want is to have qemu itself fail due
to an assertion.  It looks like the problem is as follows:

In migration.c:migration_completion(), the source sets 'inactivate' to
true (since COLO is not enabled), then tries
savevm.c:qemu_savevm_state_complete_precopy() with a request to
inactivate block devices.  In turn, this calls
block.c:bdrv_inactivate_all(), which fails when flushing runs up
against the non-responsive NFS server.  With savevm failing, we are
now left in a state where some, but not all, of the block devices have
been inactivated; but migration_completion() then jumps to 'fail'
rather than 'fail_invalidate' and skips an attempt to reclaim those
those disks by calling bdrv_activate_all().  Even if we do attempt to
reclaim disks, we aren't taking note of failure there, either.

Thus, we have reached a state where the migration engine has forgotten
all state about whether a block device is inactive, because we did not
set s->block_inactive in enough places; so migration allows the source
to reach vm_start() and resume execution, violating the block layer
invariant that the guest CPUs should not be restarted while a device
is inactive.  Note that the code in migration.c:migrate_fd_cancel()
will also try to reactivate all block devices if s->block_inactive was
set, but because we failed to set that flag after the first failure,
the source assumes it has reclaimed all devices, even though it still
has remaining inactivated devices and does not try again.  Normally,
qmp_cont() will also try to reactivate all disks (or correctly fail if
the disks are not reclaimable because NFS is not yet back up), but the
auto-resumption of the source after a migration failure does not go
through qmp_cont().  And because we have left the block layer in an
inconsistent state with devices still inactivated, the later migration
attempt is hitting the assertion failure.

Since it is important to not resume the source with inactive disks,
this patch marks s->block_inactive before attempting inactivation,
rather than after succeeding, in order to prevent any vm_start() until
it has successfully reactivated all devices.

See also https://bugzilla.redhat.com/show_bug.cgi?id=2058982

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Acked-by: Lukas Straub <lukasstraub2@web.de>
Tested-by: Lukas Straub <lukasstraub2@web.de>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 403d18ae38)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Michael Tokarev 89bf901afb linux-user: fix getgroups/setgroups allocations
linux-user getgroups(), setgroups(), getgroups32() and setgroups32()
used alloca() to allocate grouplist arrays, with unchecked gidsetsize
coming from the "guest".  With NGROUPS_MAX being 65536 (linux, and it
is common for an application to allocate NGROUPS_MAX for getgroups()),
this means a typical allocation is half the megabyte on the stack.
Which just overflows stack, which leads to immediate SIGSEGV in actual
system getgroups() implementation.

An example of such issue is aptitude, eg
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=811087#72

Cap gidsetsize to NGROUPS_MAX (return EINVAL if it is larger than that),
and use heap allocation for grouplist instead of alloca().  While at it,
fix coding style and make all 4 implementations identical.

Try to not impose random limits - for example, allow gidsetsize to be
negative for getgroups() - just do not allocate negative-sized grouplist
in this case but still do actual getgroups() call.  But do not allow
negative gidsetsize for setgroups() since its argument is unsigned.

Capping by NGROUPS_MAX seems a bit arbitrary, - we can do more, it is
not an error if set size will be NGROUPS_MAX+1. But we should not allow
integer overflow for the array being allocated. Maybe it is enough to
just call g_try_new() and return ENOMEM if it fails.

Maybe there's also no need to convert setgroups() since this one is
usually smaller and known beforehand (KERN_NGROUPS_MAX is actually 63, -
this is apparently a kernel-imposed limit for runtime group set).

The patch fixes aptitude segfault mentioned above.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-Id: <20230409105327.1273372-1-mjt@msgid.tls.msk.ru>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit 1e35d32789)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Daniil Kovalev 95cb7a7255 linux-user: Fix mips fp64 executables loading
If a program requires fr1, we should set the FR bit of CP0 control status
register and add F64 hardware flag. The corresponding `else if` branch
statement is copied from the linux kernel sources (see `arch_check_elf` function
in linux/arch/mips/kernel/elf.c).

Signed-off-by: Daniil Kovalev <dkovalev@compiler-toolchain-for.me>
Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Message-Id: <20230404052153.16617-1-dkovalev@compiler-toolchain-for.me>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit a0f8d2701b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Alex Bennée e7f1150829 tests/docker: bump the xtensa base to debian:11-slim
Stretch is going out of support so things like security updates will
fail. As the toolchain itself is binary it hopefully won't mind the
underlying OS being updated.

Message-Id: <20230503091244.1450613-3-alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reported-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 3217b84f3c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Cédric Le Goater 273147b942 target/ppc: Fix helper_pminsn() prototype
GCC13 reports an error:

../target/ppc/excp_helper.c:2625:6: error: conflicting types for ‘helper_pminsn’ due to enum/integer mismatch; have ‘void(CPUPPCState *, powerpc_pm_insn_t)’ {aka ‘void(struct CPUArchState *, powerpc_pm_insn_t)’} [-Werror=enum-int-mismatch]
 2625 | void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
      |      ^~~~~~~~~~~~~
In file included from /home/legoater/work/qemu/qemu.git/include/qemu/osdep.h:49,
                 from ../target/ppc/excp_helper.c:19:
/home/legoater/work/qemu/qemu.git/include/exec/helper-head.h:23:27: note: previous declaration of ‘helper_pminsn’ with type ‘void(CPUArchState *, uint32_t)’ {aka ‘void(CPUArchState *, unsigned int)’}
   23 | #define HELPER(name) glue(helper_, name)
      |                           ^~~~~~~

Fixes: 7778a575c7 ("ppc: Add P7/P8 Power Management instructions")
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230321161609.716474-4-clg@kaod.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 07e4804fcd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Greg Kurz 0c6e9547ae Revert "vhost-user: Introduce nested event loop in vhost_user_read()"
This reverts commit a7f523c7d1.

The nested event loop is broken by design. It's only user was removed.
Drop the code as well so that nobody ever tries to use it again.

I had to fix a couple of trivial conflicts around return values because
of 025faa872b ("vhost-user: stick to -errno error return convention").

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <20230119172424.478268-3-groug@kaod.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Maxime Coquelin <maxime.coquelin@redhat.com>
(cherry picked from commit 4382138f64)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Greg Kurz 7620c12422 Revert "vhost-user: Monitor slave channel in vhost_user_read()"
This reverts commit db8a3772e3.

Motivation : this is breaking vhost-user with DPDK as reported in [0].

Received unexpected msg type. Expected 22 received 40
Fail to update device iotlb
Received unexpected msg type. Expected 40 received 22
Received unexpected msg type. Expected 22 received 11
Fail to update device iotlb
Received unexpected msg type. Expected 11 received 22
vhost VQ 1 ring restore failed: -71: Protocol error (71)
Received unexpected msg type. Expected 22 received 11
Fail to update device iotlb
Received unexpected msg type. Expected 11 received 22
vhost VQ 0 ring restore failed: -71: Protocol error (71)
unable to start vhost net: 71: falling back on userspace virtio

The failing sequence that leads to the first error is :
- QEMU sends a VHOST_USER_GET_STATUS (40) request to DPDK on the master
  socket
- QEMU starts a nested event loop in order to wait for the
  VHOST_USER_GET_STATUS response and to be able to process messages from
  the slave channel
- DPDK sends a couple of legitimate IOTLB miss messages on the slave
  channel
- QEMU processes each IOTLB request and sends VHOST_USER_IOTLB_MSG (22)
  updates on the master socket
- QEMU assumes to receive a response for the latest VHOST_USER_IOTLB_MSG
  but it gets the response for the VHOST_USER_GET_STATUS instead

The subsequent errors have the same root cause : the nested event loop
breaks the order by design. It lures QEMU to expect responses to the
latest message sent on the master socket to arrive first.

Since this was only needed for DAX enablement which is still not merged
upstream, just drop the code for now. A working solution will have to
be merged later on. Likely protect the master socket with a mutex
and service the slave channel with a separate thread, as discussed with
Maxime in the mail thread below.

[0] https://lore.kernel.org/qemu-devel/43145ede-89dc-280e-b953-6a2b436de395@redhat.com/

Reported-by: Yanghang Liu <yanghliu@redhat.com>
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2155173
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <20230119172424.478268-2-groug@kaod.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Acked-by: Maxime Coquelin <maxime.coquelin@redhat.com>
(cherry picked from commit f340a59d5a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Chuck Zmudzinski 6bebd3f818 xen/pt: reserve PCI slot 2 for Intel igd-passthru
Intel specifies that the Intel IGD must occupy slot 2 on the PCI bus,
as noted in docs/igd-assign.txt in the Qemu source code.

Currently, when the xl toolstack is used to configure a Xen HVM guest with
Intel IGD passthrough to the guest with the Qemu upstream device model,
a Qemu emulated PCI device will occupy slot 2 and the Intel IGD will occupy
a different slot. This problem often prevents the guest from booting.

The only available workarounds are not good: Configure Xen HVM guests to
use the old and no longer maintained Qemu traditional device model
available from xenbits.xen.org which does reserve slot 2 for the Intel
IGD or use the "pc" machine type instead of the "xenfv" machine type and
add the xen platform device at slot 3 using a command line option
instead of patching qemu to fix the "xenfv" machine type directly. The
second workaround causes some degredation in startup performance such as
a longer boot time and reduced resolution of the grub menu that is
displayed on the monitor. This patch avoids that reduced startup
performance when using the Qemu upstream device model for Xen HVM guests
configured with the igd-passthru=on option.

To implement this feature in the Qemu upstream device model for Xen HVM
guests, introduce the following new functions, types, and macros:

* XEN_PT_DEVICE_CLASS declaration, based on the existing TYPE_XEN_PT_DEVICE
* XEN_PT_DEVICE_GET_CLASS macro helper function for XEN_PT_DEVICE_CLASS
* typedef XenPTQdevRealize function pointer
* XEN_PCI_IGD_SLOT_MASK, the value of slot_reserved_mask to reserve slot 2
* xen_igd_reserve_slot and xen_igd_clear_slot functions

Michael Tsirkin:
* Introduce XEN_PCI_IGD_DOMAIN, XEN_PCI_IGD_BUS, XEN_PCI_IGD_DEV, and
  XEN_PCI_IGD_FN - use them to compute the value of XEN_PCI_IGD_SLOT_MASK

The new xen_igd_reserve_slot function uses the existing slot_reserved_mask
member of PCIBus to reserve PCI slot 2 for Xen HVM guests configured using
the xl toolstack with the gfx_passthru option enabled, which sets the
igd-passthru=on option to Qemu for the Xen HVM machine type.

The new xen_igd_reserve_slot function also needs to be implemented in
hw/xen/xen_pt_stub.c to prevent FTBFS during the link stage for the case
when Qemu is configured with --enable-xen and --disable-xen-pci-passthrough,
in which case it does nothing.

The new xen_igd_clear_slot function overrides qdev->realize of the parent
PCI device class to enable the Intel IGD to occupy slot 2 on the PCI bus
since slot 2 was reserved by xen_igd_reserve_slot when the PCI bus was
created in hw/i386/pc_piix.c for the case when igd-passthru=on.

Move the call to xen_host_pci_device_get, and the associated error
handling, from xen_pt_realize to the new xen_igd_clear_slot function to
initialize the device class and vendor values which enables the checks for
the Intel IGD to succeed. The verification that the host device is an
Intel IGD to be passed through is done by checking the domain, bus, slot,
and function values as well as by checking that gfx_passthru is enabled,
the device class is VGA, and the device vendor in Intel.

Signed-off-by: Chuck Zmudzinski <brchuckz@aol.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Message-Id: <b1b4a21fe9a600b1322742dda55a40e9961daa57.1674346505.git.brchuckz@aol.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
(cherry picked from commit 4f67543bb8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Jason Andryuk de6596aa9d 9pfs/xen: Fix segfault on shutdown
xen_9pfs_free can't use gnttabdev since it is already closed and NULL-ed
out when free is called.  Do the teardown in _disconnect().  This
matches the setup done in _connect().

trace-events are also added for the XenDevOps functions.

Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Message-Id: <20230502143722.15613-1-jandryuk@gmail.com>
[C.S.: - Remove redundant return in xen_9pfs_free().
       - Add comment to trace-events. ]
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 92e667f6fd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: minor context conflict in hw/9pfs/xen-9p-backend.c)
2023-05-18 21:09:59 +03:00
Ilya Leoshkevich 00acdd8a9f s390x/tcg: Fix LDER instruction format
It's RRE, not RXE.

Found by running valgrind's none/tests/s390x/bfp-2.

Fixes: 86b59624c4 ("s390x/tcg: Implement LOAD LENGTHENED short HFP to long HFP")
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230511134726.469651-1-iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 970641de01)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context tweak)
2023-05-18 21:09:59 +03:00
Ilya Leoshkevich 6b71859686 target/s390x: Fix EXECUTE of relative branches
Fix a problem similar to the one fixed by commit 703d03a4aa
("target/s390x: Fix EXECUTE of relative long instructions"), but now
for relative branches.

Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230426235813.198183-2-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit e8ecdfeb30)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Wang Liang b7b814cd87 block/monitor: Fix crash when executing HMP commit
hmp_commit() calls blk_is_available() from a non-coroutine context (and
in the main loop). blk_is_available() is a co_wrapper_mixed_bdrv_rdlock
function, and in the non-coroutine context it calls AIO_WAIT_WHILE(),
which crashes if the aio_context lock is not taken before.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1615
Signed-off-by: Wang Liang <wangliangzz@inspur.com>
Message-Id: <20230424103902.45265-1-wangliangzz@126.com>
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8c1e8fb2e7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Carlos López 2a0afe1bde virtio: fix reachable assertion due to stale value of cached region size
In virtqueue_{split,packed}_get_avail_bytes() descriptors are read
in a loop via MemoryRegionCache regions and calls to
vring_{split,packed}_desc_read() - these take a region cache and the
index of the descriptor to be read.

For direct descriptors we use a cache provided by the caller, whose
size matches that of the virtqueue vring. We limit the number of
descriptors we can read by the size of that vring:

    max = vq->vring.num;
    ...
    MemoryRegionCache *desc_cache = &caches->desc;

For indirect descriptors, we initialize a new cache and limit the
number of descriptors by the size of the intermediate descriptor:

    len = address_space_cache_init(&indirect_desc_cache,
                                   vdev->dma_as,
                                   desc.addr, desc.len, false);
    desc_cache = &indirect_desc_cache;
    ...
    max = desc.len / sizeof(VRingDesc);

However, the first initialization of `max` is done outside the loop
where we process guest descriptors, while the second one is done
inside. This means that a sequence of an indirect descriptor followed
by a direct one will leave a stale value in `max`. If the second
descriptor's `next` field is smaller than the stale value, but
greater than the size of the virtqueue ring (and thus the cached
region), a failed assertion will be triggered in
address_space_read_cached() down the call chain.

Fix this by initializing `max` inside the loop in both functions.

Fixes: 9796d0ac8f ("virtio: use address_space_map/unmap to access descriptors")
Signed-off-by: Carlos López <clopez@suse.de>
Message-Id: <20230302100358.3613-1-clopez@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit bbc1c327d7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Albert Esteve a641521e50 hw/virtio/vhost-user: avoid using unitialized errp
During protocol negotiation, when we the QEMU
stub does not support a backend with F_CONFIG,
it throws a warning and supresses the
VHOST_USER_PROTOCOL_F_CONFIG bit.

However, the warning uses warn_reportf_err macro
and passes an unitialized errp pointer. However,
the macro tries to edit the 'msg' member of the
unitialized Error and segfaults.

Instead, just use warn_report, which prints a
warning message directly to the output.

Fixes: 5653493 ("hw/virtio/vhost-user: don't suppress F_CONFIG when supported")
Signed-off-by: Albert Esteve <aesteve@redhat.com>
Message-Id: <20230302121719.9390-1-aesteve@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 90e31232cf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Shivaprasad G Bhat afc11df42a tcg: ppc64: Fix mask generation for vextractdm
In function do_extractm() the mask is calculated as
dup_const(1 << (element_width - 1)). '1' being signed int
works fine for MO_8,16,32. For MO_64, on PPC64 host
this ends up becoming 0 on compilation. The vextractdm
uses MO_64, and it ends up having mask as 0.

Explicitly use 1ULL instead of signed int 1 like its
used everywhere else.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1536
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Lucas Mateus Castro <lucas.araujo@eldorado.org.br>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <168319292809.1159309.5817546227121323288.stgit@ltc-boston1.aus.stglabs.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit 6a5d81b172)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Cédric Le Goater c94d55f63e async: Suppress GCC13 false positive in aio_bh_poll()
GCC13 reports an error :

../util/async.c: In function ‘aio_bh_poll’:
include/qemu/queue.h:303:22: error: storing the address of local variable ‘slice’ in ‘*ctx.bh_slice_list.sqh_last’ [-Werror=dangling-pointer=]
  303 |     (head)->sqh_last = &(elm)->field.sqe_next;                          \
      |     ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
../util/async.c:169:5: note: in expansion of macro ‘QSIMPLEQ_INSERT_TAIL’
  169 |     QSIMPLEQ_INSERT_TAIL(&ctx->bh_slice_list, &slice, next);
      |     ^~~~~~~~~~~~~~~~~~~~
../util/async.c:161:17: note: ‘slice’ declared here
  161 |     BHListSlice slice;
      |                 ^~~~~
../util/async.c:161:17: note: ‘ctx’ declared here

But the local variable 'slice' is removed from the global context list
in following loop of the same routine. Add a pragma to silent GCC.

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230420202939.1982044-1-clg@kaod.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d66ba6dc1c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: cherry-picked to stable-7.2 to eliminate CI failures on win*)
2023-05-18 21:09:59 +03:00
Peter Maydell 379a05f384 ui: Fix pixel colour channel order for PNG screenshots
When we take a PNG screenshot the ordering of the colour channels in
the data is not correct, resulting in the image having weird
colouring compared to the actual display.  (Specifically, on a
little-endian host the blue and red channels are swapped; on
big-endian everything is wrong.)

This happens because the pixman idea of the pixel data and the libpng
idea differ.  PIXMAN_a8r8g8b8 defines that pixels are 32-bit values,
with A in bits 24-31, R in bits 16-23, G in bits 8-15 and B in bits
0-7.  This means that on little-endian systems the bytes in memory
are
   B G R A
and on big-endian systems they are
   A R G B

libpng, on the other hand, thinks of pixels as being a series of
values for each channel, so its format PNG_COLOR_TYPE_RGB_ALPHA
always wants bytes in the order
   R G B A

This isn't the same as the pixman order for either big or little
endian hosts.

The alpha channel is also unnecessary bulk in the output PNG file,
because there is no alpha information in a screenshot.

To handle the endianness issue, we already define in ui/qemu-pixman.h
various PIXMAN_BE_* and PIXMAN_LE_* values that give consistent
byte-order pixel channel formats.  So we can use PIXMAN_BE_r8g8b8 and
PNG_COLOR_TYPE_RGB, which both have an in-memory byte order of
    R G B
and 3 bytes per pixel.

(PPM format screenshots get this right; they already use the
PIXMAN_BE_r8g8b8 format.)

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1622
Fixes: 9a0a119a38 ("Added parameter to take screenshot with screendump as PNG")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20230502135548.2451309-1-peter.maydell@linaro.org
(cherry picked from commit cd22a0f520)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Richard Henderson 0e262ee8e9 accel/tcg: Fix atomic_mmu_lookup for reads
A copy-paste bug had us looking at the victim cache for writes.

Cc: qemu-stable@nongnu.org
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Fixes: 08dff435e2 ("tcg: Probe the proper permissions for atomic ops")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20230505204049.352469-1-richard.henderson@linaro.org>
(cherry picked from commit 8c313254e6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
LIU Zhiwei 666e6bbf85 target/riscv: Fix itrigger when icount is used
When I boot a ubuntu image, QEMU output a "Bad icount read" message and exit.
The reason is that when execute helper_mret or helper_sret, it will
cause a call to icount_get_raw_locked (), which needs set can_do_io flag
on cpustate.

Thus we setting this flag when execute these two instructions.

Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230324064011.976-1-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit df3ac6da47)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Kevin Wolf 89640e03ec block: Fix use after free in blockdev_mark_auto_del()
job_cancel_locked() drops the job list lock temporarily and it may call
aio_poll(). We must assume that the list has changed after this call.
Also, with unlucky timing, it can end up freeing the job during
job_completed_txn_abort_locked(), making the job pointer invalid, too.

For both reasons, we can't just continue at block_job_next_locked(job).
Instead, start at the head of the list again after job_cancel_locked()
and skip those jobs that we already cancelled (or that are completing
anyway).

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20230503140142.474404-1-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e2626874a3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Paolo Bonzini e3074f666f meson: leave unnecessary modules out of the build
meson.build files choose whether to build modules based on foo.found()
expressions.  If a feature is enabled (e.g. --enable-gtk), these expressions
are true even if the code is not used by any emulator, and this results
in an unexpected difference between modular and non-modular builds.

For non-modular builds, the files are not included in any binary, and
therefore the source files are never processed.  For modular builds,
however, all .so files are unconditionally built by default, and therefore
a normal "make" tries to build them.  However, the corresponding trace-*.h
files are absent due to this conditional:

if have_system
  trace_events_subdirs += [
    ...
    'ui',
    ...
  ]
endif

which was added to avoid wasting time running tracetool on unused trace-events
files.  This causes a compilation failure; fix it by skipping module builds
entirely if (depending on the module directory) have_block or have_system
are false.

Reported-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit ef709860ea)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Shivaprasad G Bhat 9b300a100c softfloat: Fix the incorrect computation in float32_exp2
The float32_exp2 function is computing wrong exponent of 2.

For example, with the following set of values {0.1, 2.0, 2.0, -1.0},
the expected output would be {1.071773, 4.000000, 4.000000, 0.500000}.
Instead, the function is computing {1.119102, 3.382044, 3.382044, -0.191022}

Looking at the code, the float32_exp2() attempts to do this

                  2     3     4     5           n
  x        x     x     x     x     x           x
 e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
           1!    2!    3!    4!    5!          n!

But because of the typo it ends up doing

  x        x     x     x     x     x           x
 e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
           1!    2!    3!    4!    5!          n!

This is because instead of the xnp which holds the numerator, parts_muladd
is using the xp which is just 'x'.  Commit '572c4d862ff2' refactored this
function, and mistakenly used xp instead of xnp.

Cc: qemu-stable@nongnu.org
Fixes: 572c4d862f "softfloat: Convert float32_exp2 to FloatParts"
Partially-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1623
Reported-By: Luca Barbato (https://gitlab.com/lu-zero)
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Message-Id: <168304110865.537992.13059030916325018670.stgit@localhost.localdomain>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 1098cc3fcf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Peter Maydell ec979ff52c hw/net/allwinner-sun8i-emac: Correctly byteswap descriptor fields
In allwinner-sun8i-emac we just read directly from guest memory into
a host FrameDescriptor struct and back.  This only works on
little-endian hosts.  Reading and writing of descriptors is already
abstracted into functions; make those functions also handle the
byte-swapping so that TransferDescriptor structs as seen by the rest
of the code are always in host-order, and fix two places that were
doing ad-hoc descriptor reading without using the functions.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230424165053.1428857-3-peter.maydell@linaro.org
(cherry picked from commit a4ae17e5ec)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Peter Maydell 4b02ac725a hw/sd/allwinner-sdhost: Correctly byteswap descriptor fields
In allwinner_sdhost_process_desc() we just read directly from
guest memory into a host TransferDescriptor struct and back.
This only works on little-endian hosts. Abstract the reading
and writing of descriptors into functions that handle the
byte-swapping so that TransferDescriptor structs as seen by
the rest of the code are always in host-order.

This fixes a failure of one of the avocado tests on s390.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230424165053.1428857-2-peter.maydell@linaro.org
(cherry picked from commit 3e20d90824)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Peter Maydell e4e79c8e00 target/arm: Define and use new load_cpu_field_low32()
In several places in the 32-bit Arm translate.c, we try to use
load_cpu_field() to load from a CPUARMState field into a TCGv_i32
where the field is actually 64-bit. This works on little-endian
hosts, but gives the wrong half of the register on big-endian.

Add a new load_cpu_field_low32() which loads the low 32 bits
of a 64-bit field into a TCGv_i32. The new macro includes a
compile-time check against accidentally using it on a field
of the wrong size. Use it to fix the two places in the code
where we were using load_cpu_field() on a 64-bit field.

This fixes a bug where on big-endian hosts the guest would
crash after executing an ERET instruction, and a more corner
case one where some UNDEFs for attempted accesses to MSR
banked registers from Secure EL1 might go to the wrong EL.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230424153909.1419369-2-peter.maydell@linaro.org
(cherry picked from commit 7f3a3d3dc4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Peter Maydell 5eb742fce5 hw/intc/allwinner-a10-pic: Don't use set_bit()/clear_bit()
The Allwinner PIC model uses set_bit() and clear_bit() to update the
values in its irq_pending[] array when an interrupt arrives.  However
it is using these functions wrongly: they work on an array of type
'long', and it is passing an array of type 'uint32_t'.  Because the
code manually figures out the right array element, this works on
little-endian hosts and on 32-bit big-endian hosts, where bits 0..31
in a 'long' are in the same place as they are in a 'uint32_t'.
However it breaks on 64-bit big-endian hosts.

Remove the use of set_bit() and clear_bit() in favour of using
deposit32() on the array element.  This fixes a bug where on
big-endian 64-bit hosts the guest kernel would hang early on in
bootup.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230424152833.1334136-1-peter.maydell@linaro.org
(cherry picked from commit 2c5fa0778c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Peter Maydell d46d403616 hw/arm/raspi: Use arm_write_bootloader() to write boot code
When writing the secondary-CPU stub boot loader code to the guest,
use arm_write_bootloader() instead of directly calling
rom_add_blob_fixed().  This fixes a bug on big-endian hosts, because
arm_write_bootloader() will correctly byte-swap the host-byte-order
array values into the guest-byte-order to write into the guest
memory.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230424152717.1333930-4-peter.maydell@linaro.org
(cherry picked from commit 0acbdb4c4a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Cédric Le Goater 5ebe440c2b hw/arm/aspeed: Use arm_write_bootloader() to write the bootloader
When writing the secondary-CPU stub boot loader code to the guest,
use arm_write_bootloader() instead of directly calling
rom_add_blob_fixed().  This fixes a bug on big-endian hosts, because
arm_write_bootloader() will correctly byte-swap the host-byte-order
array values into the guest-byte-order to write into the guest
memory.

Cc: qemu-stable@nongnu.org
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Tested-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20230424152717.1333930-3-peter.maydell@linaro.org
[PMM: Moved the "make arm_write_bootloader() function public" part
 to its own patch; updated commit message to note that this fixes
 an actual bug; adjust to the API changes noted in previous commit]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 902bba549f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Cédric Le Goater 8e9c265f14 hw/arm/boot: Make write_bootloader() public as arm_write_bootloader()
The arm boot.c code includes a utility function write_bootloader()
which assists in writing a boot-code fragment into guest memory,
including handling endianness and fixing it up with entry point
addresses and similar things.  This is useful not just for the boot.c
code but also in board model code, so rename it to
arm_write_bootloader() and make it globally visible.

Since we are making it public, make its API a little neater: move the
AddressSpace* argument to be next to the hwaddr argument, and allow
the fixupcontext array to be const, since we never modify it in this
function.

Cc: qemu-stable@nongnu.org
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Tested-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20230424152717.1333930-2-peter.maydell@linaro.org
[PMM: Split out from another patch by Cédric, added doc comment]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 0fe43f0abf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Peter Maydell e96dc26e89 hw/net/msf2-emac: Don't modify descriptor in-place in emac_store_desc()
The msf2-emac ethernet controller has functions emac_load_desc() and
emac_store_desc() which read and write the in-memory descriptor
blocks and handle conversion between guest and host endianness.

As currently written, emac_store_desc() does the endianness
conversion in-place; this means that it effectively consumes the
input EmacDesc struct, because on a big-endian host the fields will
be overwritten with the little-endian versions of their values.
Unfortunately, in all the callsites the code continues to access
fields in the EmacDesc struct after it has called emac_store_desc()
-- specifically, it looks at the d.next field.

The effect of this is that on a big-endian host networking doesn't
work because the address of the next descriptor is corrupted.

We could fix this by making the callsite avoid using the struct; but
it's more robust to have emac_store_desc() leave its input alone.

(emac_load_desc() also does an in-place conversion, but here this is
fine, because the function is supposed to be initializing the
struct.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-id: 20230424151919.1333299-1-peter.maydell@linaro.org
(cherry picked from commit d565f58b38)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Akihiko Odaki 32900bff70 target/arm: Initialize debug capabilities only once
kvm_arm_init_debug() used to be called several times on a SMP system as
kvm_arch_init_vcpu() calls it. Move the call to kvm_arch_init() to make
sure it will be called only once; otherwise it will overwrite pointers
to memory allocated with the previous call and leak it.

Fixes: e4482ab7e3 ("target-arm: kvm - add support for HW assisted debug")
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-id: 20230405153644.25300-1-akihiko.odaki@daynix.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit ad5c6ddea3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Peter Maydell 0a65c4588c docs/about/deprecated.rst: Add "since 7.1" tag to dtb-kaslr-seed deprecation
In commit 5242876f37 we deprecated the dtb-kaslr-seed property of
the virt board, but forgot the "since n.n" tag in the documentation
of this in deprecated.rst.

This deprecation note first appeared in the 7.1 release, so
retrospectively add the correct "since 7.1" annotation to it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20230420122256.1023709-1-peter.maydell@linaro.org
(cherry picked from commit ac64ebbecf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Alex Bennée 4e35bd88a5 qemu-options: finesse the recommendations around -blockdev
We are a bit premature in recommending -blockdev/-device as the best
way to configure block devices. It seems there are times the more
human friendly -drive still makes sense especially when -snapshot is
involved.

Improve the language to hopefully make things clearer.

Suggested-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20230424092249.58552-7-alex.bennee@linaro.org>
(cherry picked from commit c1654c3e37)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:59 +03:00
Igor Mammedov e557055653 acpi: pcihp: allow repeating hot-unplug requests
with Q35 using ACPI PCI hotplug by default, user's request to unplug
device is ignored when it's issued before guest OS has been booted.
And any additional attempt to request device hot-unplug afterwards
results in following error:

  "Device XYZ is already in the process of unplug"

arguably it can be considered as a regression introduced by [2],
before which it was possible to issue unplug request multiple
times.

Accept new uplug requests after timeout (1ms). This brings ACPI PCI
hotplug on par with native PCIe unplug behavior [1] and allows user
to repeat unplug requests at propper times.
Set expire timeout to arbitrary 1msec so user won't be able to
flood guest with SCI interrupts by calling device_del in tight loop.

PS:
ACPI spec doesn't mandate what OSPM can do with GPEx.status
bits set before it's booted => it's impl. depended.
Status bits may be retained (I tested with one Windows version)
or cleared (Linux since 2.6 kernel times) during guest's ACPI
subsystem initialization.
Clearing status bits (though not wrong per se) hides the unplug
event from guest, and it's upto user to repeat device_del later
when guest is able to handle unplug requests.

1) 18416c62e3 ("pcie: expire pending delete")
2)
Fixes: cce8944cc9 ("qdev-monitor: Forbid repeated device_del")
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
CC: mst@redhat.com
CC: anisinha@redhat.com
CC: jusual@redhat.com
CC: kraxel@redhat.com
Message-Id: <20230418090449.2155757-1-imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 0f689cf5ad)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-18 21:09:41 +03:00
Yang Zhong 84d5232d9d target/i386: Change wrong XFRM value in SGX CPUID leaf
The previous patch wrongly replaced FEAT_XSAVE_XCR0_{LO|HI} with
FEAT_XSAVE_XSS_{LO|HI} in CPUID(EAX=12,ECX=1):{ECX,EDX}.  As a result,
SGX enclaves only supported SSE and x87 feature (xfrm=0x3).

Fixes: 301e90675c ("target/i386: Enable support for XSAVES based features")
Signed-off-by: Yang Zhong <yang.zhong@linux.intel.com>
Reviewed-by: Yang Weijiang <weijiang.yang@intel.com>
Reviewed-by: Kai Huang <kai.huang@intel.com>
Message-Id: <20230406064041.420039-1-yang.zhong@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 72497cff89)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-04-27 08:53:10 +03:00
Paolo Bonzini bfc532703f vnc: avoid underflow when accessing user-provided address
If hostlen is zero, there is a possibility that addrstr[hostlen - 1]
underflows and, if a closing bracked is there, hostlen - 2 is passed
to g_strndup() on the next line.  If websocket==false then
addrstr[0] would be a colon, but if websocket==true this could in
principle happen.

Fix it by checking hostlen.

Reported by Coverity.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3f9c41c5df)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-04-27 08:52:57 +03:00
109 changed files with 1203 additions and 476 deletions
+3 -3
View File
@@ -109,8 +109,8 @@ crash-test-debian:
IMAGE: debian-amd64
script:
- cd build
- make check-venv
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-i386
- make NINJA=":" check-venv
- tests/venv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
build-system-fedora:
extends: .native_build_job_template
@@ -155,7 +155,7 @@ crash-test-fedora:
IMAGE: fedora
script:
- cd build
- make check-venv
- make NINJA=":" check-venv
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
+1 -1
View File
@@ -1 +1 @@
7.2.2
7.2.4
+1 -1
View File
@@ -1817,7 +1817,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
} else /* if (prot & PAGE_READ) */ {
tlb_addr = tlbe->addr_read;
if (!tlb_hit(tlb_addr, addr)) {
if (!VICTIM_TLB_HIT(addr_write, addr)) {
if (!VICTIM_TLB_HIT(addr_read, addr)) {
tlb_fill(env_cpu(env), addr, size,
MMU_DATA_LOAD, mmu_idx, retaddr);
index = tlb_index(env, mmu_idx, addr);
+6 -4
View File
@@ -213,15 +213,17 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
error_report("Device '%s' not found", device);
return;
}
if (!blk_is_available(blk)) {
error_report("Device '%s' has no medium", device);
return;
}
bs = bdrv_skip_implicit_filters(blk_bs(blk));
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (!blk_is_available(blk)) {
error_report("Device '%s' has no medium", device);
aio_context_release(aio_context);
return;
}
ret = bdrv_commit(bs);
aio_context_release(aio_context);
+14 -4
View File
@@ -152,12 +152,22 @@ void blockdev_mark_auto_del(BlockBackend *blk)
JOB_LOCK_GUARD();
for (job = block_job_next_locked(NULL); job;
job = block_job_next_locked(job)) {
if (block_job_has_bdrv(job, blk_bs(blk))) {
do {
job = block_job_next_locked(NULL);
while (job && (job->job.cancelled ||
job->job.deferred_to_main_loop ||
!block_job_has_bdrv(job, blk_bs(blk))))
{
job = block_job_next_locked(job);
}
if (job) {
/*
* This drops the job lock temporarily and polls, so we need to
* restart processing the list from the start after this.
*/
job_cancel_locked(&job->job, false);
}
}
} while (job);
dinfo->auto_del = 1;
}
+2 -2
View File
@@ -233,8 +233,8 @@ Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
System emulator machines
------------------------
Arm ``virt`` machine ``dtb-kaslr-seed`` property
''''''''''''''''''''''''''''''''''''''''''''''''
Arm ``virt`` machine ``dtb-kaslr-seed`` property (since 7.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``dtb-kaslr-seed`` property on the ``virt`` board has been
deprecated; use the new name ``dtb-randomness`` instead. The new name
+1 -1
View File
@@ -2,7 +2,7 @@ Multi-process QEMU
==================
This document describes how to configure and use multi-process qemu.
For the design document refer to docs/devel/qemu-multiprocess.
For the design document refer to docs/devel/multi-process.rst.
1) Configuration
----------------
+1 -1
View File
@@ -5135,7 +5135,7 @@ float32 float32_exp2(float32 a, float_status *status)
float64_unpack_canonical(&rp, float64_one, status);
for (i = 0 ; i < 15 ; i++) {
float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
rp = *parts_muladd(&tp, &xp, &rp, 0, status);
rp = *parts_muladd(&tp, &xnp, &rp, 0, status);
xnp = *parts_mul(&xnp, &xp, status);
}
+25 -2
View File
@@ -26,6 +26,7 @@
#include "qemu/xattr.h"
#include "9p-iov-marshal.h"
#include "hw/9pfs/9p-proxy.h"
#include "hw/9pfs/9p-util.h"
#include "fsdev/9p-iov-marshal.h"
#define PROGNAME "virtfs-proxy-helper"
@@ -338,6 +339,28 @@ static void resetugid(int suid, int sgid)
}
}
/*
* Open regular file or directory. Attempts to open any special file are
* rejected.
*
* returns file descriptor or -1 on error
*/
static int open_regular(const char *pathname, int flags, mode_t mode)
{
int fd;
fd = open(pathname, flags, mode);
if (fd < 0) {
return fd;
}
if (close_if_special_file(fd) < 0) {
return -1;
}
return fd;
}
/*
* send response in two parts
* 1) ProxyHeader
@@ -682,7 +705,7 @@ static int do_create(struct iovec *iovec)
if (ret < 0) {
goto unmarshal_err_out;
}
ret = open(path.data, flags, mode);
ret = open_regular(path.data, flags, mode);
if (ret < 0) {
ret = -errno;
}
@@ -707,7 +730,7 @@ static int do_open(struct iovec *iovec)
if (ret < 0) {
goto err_out;
}
ret = open(path.data, flags);
ret = open_regular(path.data, flags, 0);
if (ret < 0) {
ret = -errno;
}
+38
View File
@@ -13,6 +13,8 @@
#ifndef QEMU_9P_UTIL_H
#define QEMU_9P_UTIL_H
#include "qemu/error-report.h"
#ifdef O_PATH
#define O_PATH_9P_UTIL O_PATH
#else
@@ -112,6 +114,38 @@ static inline void close_preserve_errno(int fd)
errno = serrno;
}
/**
* close_if_special_file() - Close @fd if neither regular file nor directory.
*
* @fd: file descriptor of open file
* Return: 0 on regular file or directory, -1 otherwise
*
* CVE-2023-2861: Prohibit opening any special file directly on host
* (especially device files), as a compromised client could potentially gain
* access outside exported tree under certain, unsafe setups. We expect
* client to handle I/O on special files exclusively on guest side.
*/
static inline int close_if_special_file(int fd)
{
struct stat stbuf;
if (fstat(fd, &stbuf) < 0) {
close_preserve_errno(fd);
return -1;
}
if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)) {
error_report_once(
"9p: broken or compromised client detected; attempt to open "
"special file (i.e. neither regular file, nor directory)"
);
close(fd);
errno = ENXIO;
return -1;
}
return 0;
}
static inline int openat_dir(int dirfd, const char *name)
{
return openat(dirfd, name,
@@ -146,6 +180,10 @@ again:
return -1;
}
if (close_if_special_file(fd) < 0) {
return -1;
}
serrno = errno;
/* O_NONBLOCK was only needed to open the file. Let's drop it. We don't
* do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat()
+6
View File
@@ -48,3 +48,9 @@ v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name %s"
v9fs_setattr(uint16_t tag, uint8_t id, int32_t fid, int32_t valid, int32_t mode, int32_t uid, int32_t gid, int64_t size, int64_t atime_sec, int64_t mtime_sec) "tag %u id %u fid %d iattr={valid %d mode %d uid %d gid %d size %"PRId64" atime=%"PRId64" mtime=%"PRId64" }"
v9fs_setattr_return(uint16_t tag, uint8_t id) "tag %u id %u"
# xen-9p-backend.c
xen_9pfs_alloc(char *name) "name %s"
xen_9pfs_connect(char *name) "name %s"
xen_9pfs_disconnect(char *name) "name %s"
xen_9pfs_free(char *name) "name %s"
+22 -13
View File
@@ -24,6 +24,8 @@
#include "qemu/option.h"
#include "fsdev/qemu-fsdev.h"
#include "trace.h"
#define VERSIONS "1"
#define MAX_RINGS 8
#define MAX_RING_ORDER 9
@@ -335,6 +337,8 @@ static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
int i;
trace_xen_9pfs_disconnect(xendev->name);
for (i = 0; i < xen_9pdev->num_rings; i++) {
if (xen_9pdev->rings[i].evtchndev != NULL) {
qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev),
@@ -343,39 +347,40 @@ static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
xen_9pdev->rings[i].local_port);
xen_9pdev->rings[i].evtchndev = NULL;
}
}
}
static int xen_9pfs_free(struct XenLegacyDevice *xendev)
{
Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
int i;
if (xen_9pdev->rings[0].evtchndev != NULL) {
xen_9pfs_disconnect(xendev);
}
for (i = 0; i < xen_9pdev->num_rings; i++) {
if (xen_9pdev->rings[i].data != NULL) {
xen_be_unmap_grant_refs(&xen_9pdev->xendev,
xen_9pdev->rings[i].data,
(1 << xen_9pdev->rings[i].ring_order));
xen_9pdev->rings[i].data = NULL;
}
if (xen_9pdev->rings[i].intf != NULL) {
xen_be_unmap_grant_refs(&xen_9pdev->xendev,
xen_9pdev->rings[i].intf,
1);
xen_9pdev->rings[i].intf = NULL;
}
if (xen_9pdev->rings[i].bh != NULL) {
qemu_bh_delete(xen_9pdev->rings[i].bh);
xen_9pdev->rings[i].bh = NULL;
}
}
g_free(xen_9pdev->id);
xen_9pdev->id = NULL;
g_free(xen_9pdev->tag);
xen_9pdev->tag = NULL;
g_free(xen_9pdev->path);
xen_9pdev->path = NULL;
g_free(xen_9pdev->security_model);
xen_9pdev->security_model = NULL;
g_free(xen_9pdev->rings);
xen_9pdev->rings = NULL;
}
static int xen_9pfs_free(struct XenLegacyDevice *xendev)
{
trace_xen_9pfs_free(xendev->name);
return 0;
}
@@ -387,6 +392,8 @@ static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
V9fsState *s = &xen_9pdev->state;
QemuOpts *fsdev;
trace_xen_9pfs_connect(xendev->name);
if (xenstore_read_fe_int(&xen_9pdev->xendev, "num-rings",
&xen_9pdev->num_rings) == -1 ||
xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) {
@@ -494,6 +501,8 @@ out:
static void xen_9pfs_alloc(struct XenLegacyDevice *xendev)
{
trace_xen_9pfs_alloc(xendev->name);
xenstore_write_be_str(xendev, "versions", VERSIONS);
xenstore_write_be_int(xendev, "max-rings", MAX_RINGS);
xenstore_write_be_int(xendev, "max-ring-page-order", MAX_RING_ORDER);
+10
View File
@@ -429,6 +429,16 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
* acpi_pcihp_eject_slot() when the operation is completed.
*/
pdev->qdev.pending_deleted_event = true;
/* if unplug was requested before OSPM is initialized,
* linux kernel will clear GPE0.sts[] bits during boot, which effectively
* hides unplug event. And than followup qmp_device_del() calls remain
* blocked by above flag permanently.
* Unblock qmp_device_del() by setting expire limit, so user can
* repeat unplug request later when OSPM has been booted.
*/
pdev->qdev.pending_deleted_expires_ms =
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); /* 1 msec */
s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
}
+20 -18
View File
@@ -188,33 +188,35 @@ struct AspeedMachineState {
static void aspeed_write_smpboot(ARMCPU *cpu,
const struct arm_boot_info *info)
{
static const uint32_t poll_mailbox_ready[] = {
AddressSpace *as = arm_boot_address_space(cpu, info);
static const ARMInsnFixup poll_mailbox_ready[] = {
/*
* r2 = per-cpu go sign value
* r1 = AST_SMP_MBOX_FIELD_ENTRY
* r0 = AST_SMP_MBOX_FIELD_GOSIGN
*/
0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5 */
0xe21000ff, /* ands r0, r0, #255 */
0xe59f201c, /* ldr r2, [pc, #28] */
0xe1822000, /* orr r2, r2, r0 */
{ 0xee100fb0 }, /* mrc p15, 0, r0, c0, c0, 5 */
{ 0xe21000ff }, /* ands r0, r0, #255 */
{ 0xe59f201c }, /* ldr r2, [pc, #28] */
{ 0xe1822000 }, /* orr r2, r2, r0 */
0xe59f1018, /* ldr r1, [pc, #24] */
0xe59f0018, /* ldr r0, [pc, #24] */
{ 0xe59f1018 }, /* ldr r1, [pc, #24] */
{ 0xe59f0018 }, /* ldr r0, [pc, #24] */
0xe320f002, /* wfe */
0xe5904000, /* ldr r4, [r0] */
0xe1520004, /* cmp r2, r4 */
0x1afffffb, /* bne <wfe> */
0xe591f000, /* ldr pc, [r1] */
AST_SMP_MBOX_GOSIGN,
AST_SMP_MBOX_FIELD_ENTRY,
AST_SMP_MBOX_FIELD_GOSIGN,
{ 0xe320f002 }, /* wfe */
{ 0xe5904000 }, /* ldr r4, [r0] */
{ 0xe1520004 }, /* cmp r2, r4 */
{ 0x1afffffb }, /* bne <wfe> */
{ 0xe591f000 }, /* ldr pc, [r1] */
{ AST_SMP_MBOX_GOSIGN },
{ AST_SMP_MBOX_FIELD_ENTRY },
{ AST_SMP_MBOX_FIELD_GOSIGN },
{ 0, FIXUP_TERMINATOR }
};
static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
rom_add_blob_fixed("aspeed.smpboot", poll_mailbox_ready,
sizeof(poll_mailbox_ready),
info->smp_loader_start);
arm_write_bootloader("aspeed.smpboot", as, info->smp_loader_start,
poll_mailbox_ready, fixupcontext);
}
static void aspeed_reset_secondary(ARMCPU *cpu,
+8 -27
View File
@@ -59,26 +59,6 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu,
return cpu_get_address_space(cs, asidx);
}
typedef enum {
FIXUP_NONE = 0, /* do nothing */
FIXUP_TERMINATOR, /* end of insns */
FIXUP_BOARDID, /* overwrite with board ID number */
FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
FIXUP_BOOTREG, /* overwrite with boot register address */
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
FIXUP_MAX,
} FixupType;
typedef struct ARMInsnFixup {
uint32_t insn;
FixupType fixup;
} ARMInsnFixup;
static const ARMInsnFixup bootloader_aarch64[] = {
{ 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
{ 0xaa1f03e1 }, /* mov x1, xzr */
@@ -149,9 +129,10 @@ static const ARMInsnFixup smpboot[] = {
{ 0, FIXUP_TERMINATOR }
};
static void write_bootloader(const char *name, hwaddr addr,
const ARMInsnFixup *insns, uint32_t *fixupcontext,
AddressSpace *as)
void arm_write_bootloader(const char *name,
AddressSpace *as, hwaddr addr,
const ARMInsnFixup *insns,
const uint32_t *fixupcontext)
{
/* Fix up the specified bootloader fragment and write it into
* guest memory using rom_add_blob_fixed(). fixupcontext is
@@ -213,8 +194,8 @@ static void default_write_secondary(ARMCPU *cpu,
fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
}
write_bootloader("smpboot", info->smp_loader_start,
smpboot, fixupcontext, as);
arm_write_bootloader("smpboot", as, info->smp_loader_start,
smpboot, fixupcontext);
}
void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
@@ -1174,8 +1155,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
write_bootloader("bootloader", info->loader_start,
primary_loader, fixupcontext, as);
arm_write_bootloader("bootloader", as, info->loader_start,
primary_loader, fixupcontext);
if (info->write_board_setup) {
info->write_board_setup(cpu, info);
+34 -30
View File
@@ -16,6 +16,7 @@
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "hw/arm/boot.h"
#include "hw/arm/bcm2836.h"
#include "hw/registerfields.h"
#include "qemu/error-report.h"
@@ -124,20 +125,22 @@ static const char *board_type(uint32_t board_rev)
static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
{
static const uint32_t smpboot[] = {
0xe1a0e00f, /* mov lr, pc */
0xe3a0fe00 + (BOARDSETUP_ADDR >> 4), /* mov pc, BOARDSETUP_ADDR */
0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
0xe7e10050, /* ubfx r0, r0, #0, #2 ;extract LSB */
0xe59f5014, /* ldr r5, =0x400000CC ;load mbox base */
0xe320f001, /* 1: yield */
0xe7953200, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core*/
0xe3530000, /* cmp r3, #0 ;spin while zero */
0x0afffffb, /* beq 1b */
0xe7853200, /* str r3, [r5, r0, lsl #4] ;clear mbox */
0xe12fff13, /* bx r3 ;jump to target */
0x400000cc, /* (constant: mailbox 3 read/clear base) */
static const ARMInsnFixup smpboot[] = {
{ 0xe1a0e00f }, /* mov lr, pc */
{ 0xe3a0fe00 + (BOARDSETUP_ADDR >> 4) }, /* mov pc, BOARDSETUP_ADDR */
{ 0xee100fb0 }, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
{ 0xe7e10050 }, /* ubfx r0, r0, #0, #2 ;extract LSB */
{ 0xe59f5014 }, /* ldr r5, =0x400000CC ;load mbox base */
{ 0xe320f001 }, /* 1: yield */
{ 0xe7953200 }, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core */
{ 0xe3530000 }, /* cmp r3, #0 ;spin while zero */
{ 0x0afffffb }, /* beq 1b */
{ 0xe7853200 }, /* str r3, [r5, r0, lsl #4] ;clear mbox */
{ 0xe12fff13 }, /* bx r3 ;jump to target */
{ 0x400000cc }, /* (constant: mailbox 3 read/clear base) */
{ 0, FIXUP_TERMINATOR }
};
static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
/* check that we don't overrun board setup vectors */
QEMU_BUILD_BUG_ON(SMPBOOT_ADDR + sizeof(smpboot) > MVBAR_ADDR);
@@ -145,9 +148,8 @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
QEMU_BUILD_BUG_ON((BOARDSETUP_ADDR & 0xf) != 0
|| (BOARDSETUP_ADDR >> 4) >= 0x100);
rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
info->smp_loader_start,
arm_boot_address_space(cpu, info));
arm_write_bootloader("raspi_smpboot", arm_boot_address_space(cpu, info),
info->smp_loader_start, smpboot, fixupcontext);
}
static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
@@ -161,26 +163,28 @@ static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
* the primary CPU goes into the kernel. We put these variables inside
* a rom blob, so that the reset for ROM contents zeroes them for us.
*/
static const uint32_t smpboot[] = {
0xd2801b05, /* mov x5, 0xd8 */
0xd53800a6, /* mrs x6, mpidr_el1 */
0x924004c6, /* and x6, x6, #0x3 */
0xd503205f, /* spin: wfe */
0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
0xb4ffffc4, /* cbz x4, spin */
0xd2800000, /* mov x0, #0x0 */
0xd2800001, /* mov x1, #0x0 */
0xd2800002, /* mov x2, #0x0 */
0xd2800003, /* mov x3, #0x0 */
0xd61f0080, /* br x4 */
static const ARMInsnFixup smpboot[] = {
{ 0xd2801b05 }, /* mov x5, 0xd8 */
{ 0xd53800a6 }, /* mrs x6, mpidr_el1 */
{ 0x924004c6 }, /* and x6, x6, #0x3 */
{ 0xd503205f }, /* spin: wfe */
{ 0xf86678a4 }, /* ldr x4, [x5,x6,lsl #3] */
{ 0xb4ffffc4 }, /* cbz x4, spin */
{ 0xd2800000 }, /* mov x0, #0x0 */
{ 0xd2800001 }, /* mov x1, #0x0 */
{ 0xd2800002 }, /* mov x2, #0x0 */
{ 0xd2800003 }, /* mov x3, #0x0 */
{ 0xd61f0080 }, /* br x4 */
{ 0, FIXUP_TERMINATOR }
};
static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
static const uint64_t spintables[] = {
0, 0, 0, 0
};
rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
info->smp_loader_start, as);
arm_write_bootloader("raspi_smpboot", as, info->smp_loader_start,
smpboot, fixupcontext);
rom_add_blob_fixed_as("raspi_spintables", spintables, sizeof(spintables),
SPINTABLE_ADDR, as);
}
+1 -1
View File
@@ -213,7 +213,7 @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s,
const char *boot_cpu, Error **errp)
{
int i;
int num_rpus = MIN(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS,
int num_rpus = MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS),
XLNX_ZYNQMP_NUM_RPU_CPUS);
if (num_rpus <= 0) {
+8
View File
@@ -1329,6 +1329,14 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error *
}
} else if (machine_class->default_ram_id && machine->ram_size &&
numa_uses_legacy_mem()) {
if (object_property_find(object_get_objects_root(),
machine_class->default_ram_id)) {
error_setg(errp, "object name '%s' is reserved for the default"
" RAM backend, it can't be used for any other purposes."
" Change the object's 'id' to something else",
machine_class->default_ram_id);
return;
}
if (!create_default_memdev(current_machine, mem_path, errp)) {
return;
}
+22 -5
View File
@@ -498,6 +498,8 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
struct virtio_gpu_resource_flush rf;
struct virtio_gpu_scanout *scanout;
pixman_region16_t flush_region;
bool within_bounds = false;
bool update_submitted = false;
int i;
VIRTIO_GPU_FILL_CMD(rf);
@@ -518,13 +520,28 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
rf.r.x < scanout->x + scanout->width &&
rf.r.x + rf.r.width >= scanout->x &&
rf.r.y < scanout->y + scanout->height &&
rf.r.y + rf.r.height >= scanout->y &&
console_has_gl(scanout->con)) {
dpy_gl_update(scanout->con, 0, 0, scanout->width,
scanout->height);
rf.r.y + rf.r.height >= scanout->y) {
within_bounds = true;
if (console_has_gl(scanout->con)) {
dpy_gl_update(scanout->con, 0, 0, scanout->width,
scanout->height);
update_submitted = true;
}
}
}
return;
if (update_submitted) {
return;
}
if (!within_bounds) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: flush bounds outside scanouts"
" bounds for flush %d: %d %d %d %d\n",
__func__, rf.resource_id, rf.r.x, rf.r.y,
rf.r.width, rf.r.height);
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
return;
}
}
if (!res->blob &&
+8 -3
View File
@@ -168,6 +168,11 @@ static inline int stream_idle(struct Stream *s)
return !!(s->regs[R_DMASR] & DMASR_IDLE);
}
static inline int stream_halted(struct Stream *s)
{
return !!(s->regs[R_DMASR] & DMASR_HALTED);
}
static void stream_reset(struct Stream *s)
{
s->regs[R_DMASR] = DMASR_HALTED; /* starts up halted. */
@@ -269,7 +274,7 @@ static void stream_process_mem2s(struct Stream *s, StreamSink *tx_data_dev,
uint64_t addr;
bool eop;
if (!stream_running(s) || stream_idle(s)) {
if (!stream_running(s) || stream_idle(s) || stream_halted(s)) {
return;
}
@@ -326,7 +331,7 @@ static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
unsigned int rxlen;
size_t pos = 0;
if (!stream_running(s) || stream_idle(s)) {
if (!stream_running(s) || stream_idle(s) || stream_halted(s)) {
return 0;
}
@@ -407,7 +412,7 @@ xilinx_axidma_data_stream_can_push(StreamSink *obj,
XilinxAXIDMAStreamSink *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
struct Stream *s = &ds->dma->streams[1];
if (!stream_running(s) || stream_idle(s)) {
if (!stream_running(s) || stream_idle(s) || stream_halted(s)) {
ds->dma->notify = notify;
ds->dma->notify_opaque = notify_opaque;
return false;
+13 -2
View File
@@ -123,6 +123,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
{
FWCfgState *fw_cfg;
uint64_t val;
const char qemu_version[] = QEMU_VERSION;
fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4);
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus);
@@ -148,6 +149,10 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]);
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
fw_cfg_add_file(fw_cfg, "/etc/qemu-version",
g_memdup(qemu_version, sizeof(qemu_version)),
sizeof(qemu_version));
return fw_cfg;
}
@@ -418,10 +423,16 @@ static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
/* Start all CPUs at the firmware entry point.
* Monarch CPU will initialize firmware, secondary CPUs
* will enter a small idle look and wait for rendevouz. */
* will enter a small idle loop and wait for rendevouz. */
for (i = 0; i < smp_cpus; i++) {
cpu_set_pc(CPU(cpu[i]), firmware_entry);
CPUState *cs = CPU(cpu[i]);
cpu_set_pc(cs, firmware_entry);
cpu[i]->env.psw = PSW_Q;
cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000;
cs->exception_index = -1;
cs->halted = 0;
}
/* already initialized by machine_hppa_init()? */
+1
View File
@@ -405,6 +405,7 @@ static void pc_xen_hvm_init(MachineState *machine)
}
pc_xen_hvm_init_pci(machine);
xen_igd_reserve_slot(pcms->bus);
pci_create_simple(pcms->bus, -1, "xen-platform");
}
#endif
+2 -5
View File
@@ -49,12 +49,9 @@ static void aw_a10_pic_update(AwA10PICState *s)
static void aw_a10_pic_set_irq(void *opaque, int irq, int level)
{
AwA10PICState *s = opaque;
uint32_t *pending_reg = &s->irq_pending[irq / 32];
if (level) {
set_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
} else {
clear_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
}
*pending_reg = deposit32(*pending_reg, irq % 32, 1, !!level);
aw_a10_pic_update(s);
}
+1 -1
View File
@@ -189,7 +189,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
bool acc_mode)
{
struct iovec iov[ASPEED_HACE_MAX_SG];
g_autofree uint8_t *digest_buf;
g_autofree uint8_t *digest_buf = NULL;
size_t digest_len = 0;
int niov = 0;
int i;
+15 -7
View File
@@ -350,8 +350,13 @@ static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
FrameDescriptor *desc,
uint32_t phys_addr)
{
dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc),
uint32_t desc_words[4];
dma_memory_read(&s->dma_as, phys_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
desc->status = le32_to_cpu(desc_words[0]);
desc->status2 = le32_to_cpu(desc_words[1]);
desc->addr = le32_to_cpu(desc_words[2]);
desc->next = le32_to_cpu(desc_words[3]);
}
static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
@@ -400,10 +405,15 @@ static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
}
static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
FrameDescriptor *desc,
const FrameDescriptor *desc,
uint32_t phys_addr)
{
dma_memory_write(&s->dma_as, phys_addr, desc, sizeof(*desc),
uint32_t desc_words[4];
desc_words[0] = cpu_to_le32(desc->status);
desc_words[1] = cpu_to_le32(desc->status2);
desc_words[2] = cpu_to_le32(desc->addr);
desc_words[3] = cpu_to_le32(desc->next);
dma_memory_write(&s->dma_as, phys_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
}
@@ -638,8 +648,7 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
break;
case REG_TX_CUR_BUF: /* Transmit Current Buffer */
if (s->tx_desc_curr != 0) {
dma_memory_read(&s->dma_as, s->tx_desc_curr, &desc, sizeof(desc),
MEMTXATTRS_UNSPECIFIED);
allwinner_sun8i_emac_get_desc(s, &desc, s->tx_desc_curr);
value = desc.addr;
} else {
value = 0;
@@ -652,8 +661,7 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
break;
case REG_RX_CUR_BUF: /* Receive Current Buffer */
if (s->rx_desc_curr != 0) {
dma_memory_read(&s->dma_as, s->rx_desc_curr, &desc, sizeof(desc),
MEMTXATTRS_UNSPECIFIED);
allwinner_sun8i_emac_get_desc(s, &desc, s->rx_desc_curr);
value = desc.addr;
} else {
value = 0;
+4 -5
View File
@@ -567,7 +567,7 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
qemu_send_packet(nc, buf, size);
}
inc_tx_bcast_or_mcast_count(s, buf);
e1000x_increase_size_stats(s->mac_reg, PTCregs, size);
e1000x_increase_size_stats(s->mac_reg, PTCregs, size + 4);
}
static void
@@ -631,10 +631,9 @@ xmit_seg(E1000State *s)
}
e1000x_inc_reg_if_not_full(s->mac_reg, TPT);
e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size);
s->mac_reg[GPTC] = s->mac_reg[TPT];
s->mac_reg[GOTCL] = s->mac_reg[TOTL];
s->mac_reg[GOTCH] = s->mac_reg[TOTH];
e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size + 4);
e1000x_inc_reg_if_not_full(s->mac_reg, GPTC);
e1000x_grow_8reg_if_not_full(s->mac_reg, GOTCL, s->tx.size + 4);
}
static void
+2 -3
View File
@@ -687,9 +687,8 @@ e1000e_on_tx_done_update_stats(E1000ECore *core, struct NetTxPkt *tx_pkt)
g_assert_not_reached();
}
core->mac[GPTC] = core->mac[TPT];
core->mac[GOTCL] = core->mac[TOTL];
core->mac[GOTCH] = core->mac[TOTH];
e1000x_inc_reg_if_not_full(core->mac, GPTC);
e1000x_grow_8reg_if_not_full(core->mac, GOTCL, tot_len);
}
static void
+2 -3
View File
@@ -217,15 +217,14 @@ e1000x_update_rx_total_stats(uint32_t *mac,
e1000x_increase_size_stats(mac, PRCregs, data_fcs_size);
e1000x_inc_reg_if_not_full(mac, TPR);
mac[GPRC] = mac[TPR];
e1000x_inc_reg_if_not_full(mac, GPRC);
/* TOR - Total Octets Received:
* This register includes bytes received in a packet from the <Destination
* Address> field through the <CRC> field, inclusively.
* Always include FCS length (4) in size.
*/
e1000x_grow_8reg_if_not_full(mac, TORL, data_size + 4);
mac[GORCL] = mac[TORL];
mac[GORCH] = mac[TORH];
e1000x_grow_8reg_if_not_full(mac, GORCL, data_size + 4);
}
void
+10 -6
View File
@@ -118,14 +118,18 @@ static void emac_load_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
d->next = le32_to_cpu(d->next);
}
static void emac_store_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
static void emac_store_desc(MSF2EmacState *s, const EmacDesc *d, hwaddr desc)
{
/* Convert from host endianness into LE. */
d->pktaddr = cpu_to_le32(d->pktaddr);
d->pktsize = cpu_to_le32(d->pktsize);
d->next = cpu_to_le32(d->next);
EmacDesc outd;
/*
* Convert from host endianness into LE. We use a local struct because
* calling code may still want to look at the fields afterwards.
*/
outd.pktaddr = cpu_to_le32(d->pktaddr);
outd.pktsize = cpu_to_le32(d->pktsize);
outd.next = cpu_to_le32(d->next);
address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, &outd, sizeof outd);
}
static void msf2_dma_tx(MSF2EmacState *s)
+3
View File
@@ -2154,6 +2154,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
int large_send_mss = (txdw0 >> CP_TC_LGSEN_MSS_SHIFT) &
CP_TC_LGSEN_MSS_MASK;
if (large_send_mss == 0) {
goto skip_offload;
}
DPRINTF("+++ C+ mode offloaded task TSO IP data %d "
"frame data %d specified MSS=%d\n",
-1
View File
@@ -802,7 +802,6 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
}
if (!get_vhost_net(nc->peer)) {
virtio_add_feature(&features, VIRTIO_F_RING_RESET);
return features;
}
+2
View File
@@ -806,6 +806,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
int64_t signed_decr;
/* Truncate value to decr_width and sign extend for simplicity */
value = extract64(value, 0, nr_bits);
decr = extract64(decr, 0, nr_bits);
signed_value = sextract64(value, 0, nr_bits);
signed_decr = sextract64(decr, 0, nr_bits);
+3 -1
View File
@@ -271,9 +271,11 @@ static void ibm_40p_init(MachineState *machine)
}
/* PCI -> ISA bridge */
i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378"));
i82378_dev = DEVICE(pci_new(PCI_DEVFN(11, 0), "i82378"));
qdev_connect_gpio_out(i82378_dev, 0,
qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT));
qdev_realize_and_unref(i82378_dev, BUS(pci_bus), &error_fatal);
sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(i82378_dev, 15));
isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0"));
+2 -2
View File
@@ -5,8 +5,8 @@ mpqemu_recv_io_error(int cmd, int size, int nfds) "failed to receive %d size %d,
# vfio-user-obj.c
vfu_prop(const char *prop, const char *val) "vfu: setting %s as %s"
vfu_cfg_read(uint32_t offset, uint32_t val) "vfu: cfg: 0x%u -> 0x%x"
vfu_cfg_write(uint32_t offset, uint32_t val) "vfu: cfg: 0x%u <- 0x%x"
vfu_cfg_read(uint32_t offset, uint32_t val) "vfu: cfg: 0x%x -> 0x%x"
vfu_cfg_write(uint32_t offset, uint32_t val) "vfu: cfg: 0x%x <- 0x%x"
vfu_dma_register(uint64_t gpa, size_t len) "vfu: registering GPA 0x%"PRIx64", %zu bytes"
vfu_dma_unregister(uint64_t gpa) "vfu: unregistering GPA 0x%"PRIx64""
vfu_bar_register(int i, uint64_t addr, uint64_t size) "vfu: BAR %d: addr 0x%"PRIx64" size 0x%"PRIx64""
+6
View File
@@ -207,6 +207,12 @@ int64_t riscv_numa_get_default_cpu_node_id(const MachineState *ms, int idx)
{
int64_t nidx = 0;
if (ms->numa_state->num_nodes > ms->smp.cpus) {
error_report("Number of NUMA nodes (%d)"
" cannot exceed the number of available CPUs (%d).",
ms->numa_state->num_nodes, ms->smp.max_cpus);
exit(EXIT_FAILURE);
}
if (ms->numa_state->num_nodes) {
nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
if (ms->numa_state->num_nodes <= nidx) {
+17 -6
View File
@@ -1134,15 +1134,24 @@ static void lsi_execute_script(LSIState *s)
uint32_t addr, addr_high;
int opcode;
int insn_processed = 0;
static int reentrancy_level;
reentrancy_level++;
s->istat1 |= LSI_ISTAT1_SRUN;
again:
if (++insn_processed > LSI_MAX_INSN) {
/* Some windows drivers make the device spin waiting for a memory
location to change. If we have been executed a lot of code then
assume this is the case and force an unexpected device disconnect.
This is apparently sufficient to beat the drivers into submission.
*/
/*
* Some windows drivers make the device spin waiting for a memory location
* to change. If we have executed more than LSI_MAX_INSN instructions then
* assume this is the case and force an unexpected device disconnect. This
* is apparently sufficient to beat the drivers into submission.
*
* Another issue (CVE-2023-0330) can occur if the script is programmed to
* trigger itself again and again. Avoid this problem by stopping after
* being called multiple times in a reentrant way (8 is an arbitrary value
* which should be enough for all valid use cases).
*/
if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
if (!(s->sien0 & LSI_SIST0_UDC)) {
qemu_log_mask(LOG_GUEST_ERROR,
"lsi_scsi: inf. loop with UDC masked");
@@ -1596,6 +1605,8 @@ again:
}
}
trace_lsi_execute_script_stop();
reentrancy_level--;
}
static uint8_t lsi_reg_readb(LSIState *s, int offset)
+9 -5
View File
@@ -190,12 +190,16 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
if ((s->type == TYPE_DISK || s->type == TYPE_ZBC) &&
(r->req.cmd.buf[1] & 0x01)) {
page = r->req.cmd.buf[2];
if (page == 0xb0) {
if (page == 0xb0 && r->buflen >= 8) {
uint8_t buf[16] = {};
uint8_t buf_used = MIN(r->buflen, 16);
uint64_t max_transfer = calculate_max_transfer(s);
stl_be_p(&r->buf[8], max_transfer);
/* Also take care of the opt xfer len. */
stl_be_p(&r->buf[12],
MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
memcpy(buf, r->buf, buf_used);
stl_be_p(&buf[8], max_transfer);
stl_be_p(&buf[12], MIN_NON_ZERO(max_transfer, ldl_be_p(&buf[12])));
memcpy(r->buf + 8, buf + 8, buf_used - 8);
} else if (s->needs_vpd_bl_emulation && page == 0x00 && r->buflen >= 4) {
/*
* Now we're capable of supplying the VPD Block Limits
+26 -5
View File
@@ -302,6 +302,30 @@ static void allwinner_sdhost_auto_stop(AwSdHostState *s)
}
}
static void read_descriptor(AwSdHostState *s, hwaddr desc_addr,
TransferDescriptor *desc)
{
uint32_t desc_words[4];
dma_memory_read(&s->dma_as, desc_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
desc->status = le32_to_cpu(desc_words[0]);
desc->size = le32_to_cpu(desc_words[1]);
desc->addr = le32_to_cpu(desc_words[2]);
desc->next = le32_to_cpu(desc_words[3]);
}
static void write_descriptor(AwSdHostState *s, hwaddr desc_addr,
const TransferDescriptor *desc)
{
uint32_t desc_words[4];
desc_words[0] = cpu_to_le32(desc->status);
desc_words[1] = cpu_to_le32(desc->size);
desc_words[2] = cpu_to_le32(desc->addr);
desc_words[3] = cpu_to_le32(desc->next);
dma_memory_write(&s->dma_as, desc_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
}
static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
hwaddr desc_addr,
TransferDescriptor *desc,
@@ -312,9 +336,7 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
uint32_t num_bytes = max_bytes;
uint8_t buf[1024];
/* Read descriptor */
dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc),
MEMTXATTRS_UNSPECIFIED);
read_descriptor(s, desc_addr, desc);
if (desc->size == 0) {
desc->size = klass->max_desc_size;
} else if (desc->size > klass->max_desc_size) {
@@ -356,8 +378,7 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
/* Clear hold flag and flush descriptor */
desc->status &= ~DESC_STATUS_HOLD;
dma_memory_write(&s->dma_as, desc_addr, desc, sizeof(*desc),
MEMTXATTRS_UNSPECIFIED);
write_descriptor(s, desc_addr, desc);
return num_done;
}
+6 -1
View File
@@ -45,7 +45,12 @@ static uint32_t update_counter(NRF51TimerState *s, int64_t now)
uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns);
s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]);
s->update_counter_ns = now;
/*
* Only advance the sync time to the timestamp of the last tick,
* not all the way to 'now', so we don't lose time if we do
* multiple resyncs in a single tick.
*/
s->update_counter_ns += ticks_to_ns(s, ticks);
return ticks;
}
+2
View File
@@ -1210,6 +1210,8 @@ static void ohci_frame_boundary(void *opaque)
/* Increment frame number and take care of endianness. */
ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
hcca.frame = cpu_to_le16(ohci->frame_number);
/* When the HC updates frame number, set pad to 0. Ref OHCI Spec 4.4.1*/
hcca.pad = 0;
if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
if (!ohci->done)
+5 -3
View File
@@ -663,6 +663,8 @@ static void vfio_msi_enable(VFIOPCIDevice *vdev)
vfio_disable_interrupts(vdev);
vdev->nr_vectors = msi_nr_vectors_allocated(&vdev->pdev);
retry:
/*
* Setting vector notifiers needs to enable route for each vector.
* Deferring to commit the KVM routes once rather than per vector
@@ -670,8 +672,6 @@ static void vfio_msi_enable(VFIOPCIDevice *vdev)
*/
vfio_prepare_kvm_msi_virq_batch(vdev);
vdev->nr_vectors = msi_nr_vectors_allocated(&vdev->pdev);
retry:
vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->nr_vectors);
for (i = 0; i < vdev->nr_vectors; i++) {
@@ -3159,7 +3159,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
out_deregister:
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier);
if (vdev->irqchip_change_notifier.notify) {
kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier);
}
out_teardown:
vfio_teardown_msi(vdev);
vfio_bars_exit(vdev);
+4 -1
View File
@@ -68,7 +68,7 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp)
*/
static uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq)
{
return svq->vring.num - (svq->shadow_avail_idx - svq->shadow_used_idx);
return svq->num_free;
}
/**
@@ -263,6 +263,7 @@ int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg,
return -EINVAL;
}
svq->num_free -= ndescs;
svq->desc_state[qemu_head].elem = elem;
svq->desc_state[qemu_head].ndescs = ndescs;
vhost_svq_kick(svq);
@@ -449,6 +450,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id);
svq->desc_next[last_used_chain] = svq->free_head;
svq->free_head = used_elem.id;
svq->num_free += num;
*len = used_elem.len;
return g_steal_pointer(&svq->desc_state[used_elem.id].elem);
@@ -656,6 +658,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
svq->vq = vq;
svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq));
svq->num_free = svq->vring.num;
driver_size = vhost_svq_driver_area_size(svq);
device_size = vhost_svq_device_area_size(svq);
svq->vring.desc = qemu_memalign(qemu_real_host_page_size(), driver_size);
+3
View File
@@ -107,6 +107,9 @@ typedef struct VhostShadowVirtqueue {
/* Next head to consume from the device */
uint16_t last_used_idx;
/* Size of SVQ vring free descriptors */
uint16_t num_free;
} VhostShadowVirtqueue;
bool vhost_svq_valid_features(uint64_t features, Error **errp);
+10 -94
View File
@@ -305,19 +305,8 @@ static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg)
return 0;
}
struct vhost_user_read_cb_data {
struct vhost_dev *dev;
VhostUserMsg *msg;
GMainLoop *loop;
int ret;
};
static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
gpointer opaque)
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
{
struct vhost_user_read_cb_data *data = opaque;
struct vhost_dev *dev = data->dev;
VhostUserMsg *msg = data->msg;
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
uint8_t *p = (uint8_t *) msg;
@@ -325,8 +314,7 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
r = vhost_user_read_header(dev, msg);
if (r < 0) {
data->ret = r;
goto end;
return r;
}
/* validate message size is sane */
@@ -334,8 +322,7 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
error_report("Failed to read msg header."
" Size %d exceeds the maximum %zu.", msg->hdr.size,
VHOST_USER_PAYLOAD_SIZE);
data->ret = -EPROTO;
goto end;
return -EPROTO;
}
if (msg->hdr.size) {
@@ -346,84 +333,11 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
int saved_errno = errno;
error_report("Failed to read msg payload."
" Read %d instead of %d.", r, msg->hdr.size);
data->ret = r < 0 ? -saved_errno : -EIO;
goto end;
return r < 0 ? -saved_errno : -EIO;
}
}
end:
g_main_loop_quit(data->loop);
return G_SOURCE_REMOVE;
}
static gboolean slave_read(QIOChannel *ioc, GIOCondition condition,
gpointer opaque);
/*
* This updates the read handler to use a new event loop context.
* Event sources are removed from the previous context : this ensures
* that events detected in the previous context are purged. They will
* be re-detected and processed in the new context.
*/
static void slave_update_read_handler(struct vhost_dev *dev,
GMainContext *ctxt)
{
struct vhost_user *u = dev->opaque;
if (!u->slave_ioc) {
return;
}
if (u->slave_src) {
g_source_destroy(u->slave_src);
g_source_unref(u->slave_src);
}
u->slave_src = qio_channel_add_watch_source(u->slave_ioc,
G_IO_IN | G_IO_HUP,
slave_read, dev, NULL,
ctxt);
}
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
{
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
GMainContext *prev_ctxt = chr->chr->gcontext;
GMainContext *ctxt = g_main_context_new();
GMainLoop *loop = g_main_loop_new(ctxt, FALSE);
struct vhost_user_read_cb_data data = {
.dev = dev,
.loop = loop,
.msg = msg,
.ret = 0
};
/*
* We want to be able to monitor the slave channel fd while waiting
* for chr I/O. This requires an event loop, but we can't nest the
* one to which chr is currently attached : its fd handlers might not
* be prepared for re-entrancy. So we create a new one and switch chr
* to use it.
*/
slave_update_read_handler(dev, ctxt);
qemu_chr_be_update_read_handlers(chr->chr, ctxt);
qemu_chr_fe_add_watch(chr, G_IO_IN | G_IO_HUP, vhost_user_read_cb, &data);
g_main_loop_run(loop);
/*
* Restore the previous event loop context. This also destroys/recreates
* event sources : this guarantees that all pending events in the original
* context that have been processed by the nested loop are purged.
*/
qemu_chr_be_update_read_handlers(chr->chr, prev_ctxt);
slave_update_read_handler(dev, NULL);
g_main_loop_unref(loop);
g_main_context_unref(ctxt);
return data.ret;
return 0;
}
static int process_message_reply(struct vhost_dev *dev,
@@ -1802,7 +1716,9 @@ static int vhost_setup_slave_channel(struct vhost_dev *dev)
return -ECONNREFUSED;
}
u->slave_ioc = ioc;
slave_update_read_handler(dev, NULL);
u->slave_src = qio_channel_add_watch_source(u->slave_ioc,
G_IO_IN | G_IO_HUP,
slave_read, dev, NULL, NULL);
if (reply_supported) {
msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
@@ -2108,8 +2024,8 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque,
} else {
if (virtio_has_feature(protocol_features,
VHOST_USER_PROTOCOL_F_CONFIG)) {
warn_reportf_err(*errp, "vhost-user backend supports "
"VHOST_USER_PROTOCOL_F_CONFIG but QEMU does not.");
warn_report("vhost-user backend supports "
"VHOST_USER_PROTOCOL_F_CONFIG but QEMU does not.");
protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIG);
}
}
+3
View File
@@ -1934,6 +1934,9 @@ fail_vq:
}
fail_mem:
if (vhost_dev_has_iommu(hdev)) {
memory_listener_unregister(&hdev->iommu_listener);
}
fail_features:
vdev->vhost_started = false;
hdev->started = false;
+10 -8
View File
@@ -476,15 +476,17 @@ static void virtio_crypto_free_request(VirtIOCryptoReq *req)
size_t max_len;
CryptoDevBackendSymOpInfo *op_info = req->op_info.u.sym_op_info;
max_len = op_info->iv_len +
op_info->aad_len +
op_info->src_len +
op_info->dst_len +
op_info->digest_result_len;
if (op_info) {
max_len = op_info->iv_len +
op_info->aad_len +
op_info->src_len +
op_info->dst_len +
op_info->digest_result_len;
/* Zeroize and free request data structure */
memset(op_info, 0, sizeof(*op_info) + max_len);
g_free(op_info);
/* Zeroize and free request data structure */
memset(op_info, 0, sizeof(*op_info) + max_len);
g_free(op_info);
}
} else if (req->flags == CRYPTODEV_BACKEND_ALG_ASYM) {
CryptoDevBackendAsymOpInfo *op_info = req->op_info.u.asym_op_info;
if (op_info) {
+5 -6
View File
@@ -1478,7 +1478,7 @@ static void virtqueue_split_get_avail_bytes(VirtQueue *vq,
VRingMemoryRegionCaches *caches)
{
VirtIODevice *vdev = vq->vdev;
unsigned int max, idx;
unsigned int idx;
unsigned int total_bufs, in_total, out_total;
MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
int64_t len = 0;
@@ -1487,13 +1487,12 @@ static void virtqueue_split_get_avail_bytes(VirtQueue *vq,
idx = vq->last_avail_idx;
total_bufs = in_total = out_total = 0;
max = vq->vring.num;
while ((rc = virtqueue_num_heads(vq, idx)) > 0) {
MemoryRegionCache *desc_cache = &caches->desc;
unsigned int num_bufs;
VRingDesc desc;
unsigned int i;
unsigned int max = vq->vring.num;
num_bufs = total_bufs;
@@ -1615,7 +1614,7 @@ static void virtqueue_packed_get_avail_bytes(VirtQueue *vq,
VRingMemoryRegionCaches *caches)
{
VirtIODevice *vdev = vq->vdev;
unsigned int max, idx;
unsigned int idx;
unsigned int total_bufs, in_total, out_total;
MemoryRegionCache *desc_cache;
MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID;
@@ -1627,14 +1626,14 @@ static void virtqueue_packed_get_avail_bytes(VirtQueue *vq,
wrap_counter = vq->last_avail_wrap_counter;
total_bufs = in_total = out_total = 0;
max = vq->vring.num;
for (;;) {
unsigned int num_bufs = total_bufs;
unsigned int i = idx;
int rc;
unsigned int max = vq->vring.num;
desc_cache = &caches->desc;
vring_packed_desc_read(vdev, &desc, desc_cache, idx, true);
if (!is_desc_avail(desc.flags, wrap_counter)) {
break;
+53 -11
View File
@@ -57,6 +57,7 @@
#include <sys/ioctl.h>
#include "hw/pci/pci.h"
#include "hw/pci/pci_bus.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/xen/xen.h"
@@ -780,15 +781,6 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function,
s->dev.devfn);
xen_host_pci_device_get(&s->real_device,
s->hostaddr.domain, s->hostaddr.bus,
s->hostaddr.slot, s->hostaddr.function,
errp);
if (*errp) {
error_append_hint(errp, "Failed to \"open\" the real pci device");
return;
}
s->is_virtfn = s->real_device.is_virtfn;
if (s->is_virtfn) {
XEN_PT_LOG(d, "%04x:%02x:%02x.%d is a SR-IOV Virtual Function\n",
@@ -803,8 +795,10 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
s->io_listener = xen_pt_io_listener;
/* Setup VGA bios for passthrough GFX */
if ((s->real_device.domain == 0) && (s->real_device.bus == 0) &&
(s->real_device.dev == 2) && (s->real_device.func == 0)) {
if ((s->real_device.domain == XEN_PCI_IGD_DOMAIN) &&
(s->real_device.bus == XEN_PCI_IGD_BUS) &&
(s->real_device.dev == XEN_PCI_IGD_DEV) &&
(s->real_device.func == XEN_PCI_IGD_FN)) {
if (!is_igd_vga_passthrough(&s->real_device)) {
error_setg(errp, "Need to enable igd-passthru if you're trying"
" to passthrough IGD GFX");
@@ -950,11 +944,58 @@ static void xen_pci_passthrough_instance_init(Object *obj)
PCI_DEVICE(obj)->cap_present |= QEMU_PCI_CAP_EXPRESS;
}
void xen_igd_reserve_slot(PCIBus *pci_bus)
{
if (!xen_igd_gfx_pt_enabled()) {
return;
}
XEN_PT_LOG(0, "Reserving PCI slot 2 for IGD\n");
pci_bus->slot_reserved_mask |= XEN_PCI_IGD_SLOT_MASK;
}
static void xen_igd_clear_slot(DeviceState *qdev, Error **errp)
{
ERRP_GUARD();
PCIDevice *pci_dev = (PCIDevice *)qdev;
XenPCIPassthroughState *s = XEN_PT_DEVICE(pci_dev);
XenPTDeviceClass *xpdc = XEN_PT_DEVICE_GET_CLASS(s);
PCIBus *pci_bus = pci_get_bus(pci_dev);
xen_host_pci_device_get(&s->real_device,
s->hostaddr.domain, s->hostaddr.bus,
s->hostaddr.slot, s->hostaddr.function,
errp);
if (*errp) {
error_append_hint(errp, "Failed to \"open\" the real pci device");
return;
}
if (!(pci_bus->slot_reserved_mask & XEN_PCI_IGD_SLOT_MASK)) {
xpdc->pci_qdev_realize(qdev, errp);
return;
}
if (is_igd_vga_passthrough(&s->real_device) &&
s->real_device.domain == XEN_PCI_IGD_DOMAIN &&
s->real_device.bus == XEN_PCI_IGD_BUS &&
s->real_device.dev == XEN_PCI_IGD_DEV &&
s->real_device.func == XEN_PCI_IGD_FN &&
s->real_device.vendor_id == PCI_VENDOR_ID_INTEL) {
pci_bus->slot_reserved_mask &= ~XEN_PCI_IGD_SLOT_MASK;
XEN_PT_LOG(pci_dev, "Intel IGD found, using slot 2\n");
}
xpdc->pci_qdev_realize(qdev, errp);
}
static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
XenPTDeviceClass *xpdc = XEN_PT_DEVICE_CLASS(klass);
xpdc->pci_qdev_realize = dc->realize;
dc->realize = xen_igd_clear_slot;
k->realize = xen_pt_realize;
k->exit = xen_pt_unregister_device;
k->config_read = xen_pt_pci_read_config;
@@ -977,6 +1018,7 @@ static const TypeInfo xen_pci_passthrough_info = {
.instance_size = sizeof(XenPCIPassthroughState),
.instance_finalize = xen_pci_passthrough_finalize,
.class_init = xen_pci_passthrough_class_init,
.class_size = sizeof(XenPTDeviceClass),
.instance_init = xen_pci_passthrough_instance_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+20
View File
@@ -41,7 +41,20 @@ typedef struct XenPTReg XenPTReg;
#define TYPE_XEN_PT_DEVICE "xen-pci-passthrough"
OBJECT_DECLARE_SIMPLE_TYPE(XenPCIPassthroughState, XEN_PT_DEVICE)
#define XEN_PT_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(XenPTDeviceClass, klass, TYPE_XEN_PT_DEVICE)
#define XEN_PT_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(XenPTDeviceClass, obj, TYPE_XEN_PT_DEVICE)
typedef void (*XenPTQdevRealize)(DeviceState *qdev, Error **errp);
typedef struct XenPTDeviceClass {
PCIDeviceClass parent_class;
XenPTQdevRealize pci_qdev_realize;
} XenPTDeviceClass;
uint32_t igd_read_opregion(XenPCIPassthroughState *s);
void xen_igd_reserve_slot(PCIBus *pci_bus);
void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
void xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,
XenHostPCIDevice *dev);
@@ -76,6 +89,13 @@ typedef int (*xen_pt_conf_byte_read)
#define XEN_PCI_INTEL_OPREGION 0xfc
#define XEN_PCI_IGD_DOMAIN 0
#define XEN_PCI_IGD_BUS 0
#define XEN_PCI_IGD_DEV 2
#define XEN_PCI_IGD_FN 0
#define XEN_PCI_IGD_SLOT_MASK \
(1UL << PCI_SLOT(PCI_DEVFN(XEN_PCI_IGD_DEV, XEN_PCI_IGD_FN)))
typedef enum {
XEN_PT_GRP_TYPE_HARDWIRED = 0, /* 0 Hardwired reg group */
XEN_PT_GRP_TYPE_EMU, /* emul reg group */
+4
View File
@@ -20,3 +20,7 @@ void xen_igd_gfx_pt_set(bool value, Error **errp)
error_setg(errp, "Xen PCI passthrough support not built in");
}
}
void xen_igd_reserve_slot(PCIBus *pci_bus)
{
}
+49
View File
@@ -183,4 +183,53 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
const struct arm_boot_info *info,
hwaddr mvbar_addr);
typedef enum {
FIXUP_NONE = 0, /* do nothing */
FIXUP_TERMINATOR, /* end of insns */
FIXUP_BOARDID, /* overwrite with board ID number */
FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
FIXUP_BOOTREG, /* overwrite with boot register address */
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
FIXUP_MAX,
} FixupType;
typedef struct ARMInsnFixup {
uint32_t insn;
FixupType fixup;
} ARMInsnFixup;
/**
* arm_write_bootloader - write a bootloader to guest memory
* @name: name of the bootloader blob
* @as: AddressSpace to write the bootloader
* @addr: guest address to write it
* @insns: the blob to be loaded
* @fixupcontext: context to be used for any fixups in @insns
*
* Write a bootloader to guest memory at address @addr in the address
* space @as. @name is the name to use for the resulting ROM blob, so
* it should be unique in the system and reasonably identifiable for debugging.
*
* @insns must be an array of ARMInsnFixup structs, each of which has
* one 32-bit value to be written to the guest memory, and a fixup to be
* applied to the value. FIXUP_NONE (do nothing) is value 0, so effectively
* the fixup is optional when writing a struct initializer.
* The final entry in the array must be { 0, FIXUP_TERMINATOR }.
*
* All other supported fixup types have the semantics "ignore insn
* and instead use the value from the array element @fixupcontext[fixup]".
* The caller should therefore provide @fixupcontext as an array of
* size FIXUP_MAX whose elements have been initialized for at least
* the entries that @insns refers to.
*/
void arm_write_bootloader(const char *name,
AddressSpace *as, hwaddr addr,
const ARMInsnFixup *insns,
const uint32_t *fixupcontext);
#endif /* HW_ARM_BOOT_H */
+13
View File
@@ -184,4 +184,17 @@
#define QEMU_DISABLE_CFI
#endif
/*
* Apple clang version 14 has a bug in its __builtin_subcll(); define
* BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
* When a version of Apple clang which has this bug fixed is released
* we can add an upper bound to this check.
* See https://gitlab.com/qemu-project/qemu/-/issues/1631
* and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
* The bug never made it into any upstream LLVM releases, only Apple ones.
*/
#if defined(__apple_build_version__) && __clang_major__ >= 14
#define BUILTIN_SUBCLL_BROKEN
#endif
#endif /* COMPILER_H */
+1 -1
View File
@@ -596,7 +596,7 @@ static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
*/
static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
{
#if __has_builtin(__builtin_subcll)
#if __has_builtin(__builtin_subcll) && !defined(BUILTIN_SUBCLL_BROKEN)
unsigned long long b = *pborrow;
x = __builtin_subcll(x, y, b, &b);
*pborrow = b & 1;
+4 -1
View File
@@ -290,7 +290,10 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
env->CP0_Status |= (1 << CP0St_FR);
env->hflags |= MIPS_HFLAG_F64;
}
} else if (!prog_req.fre && !prog_req.frdefault &&
} else if (prog_req.fr1) {
env->CP0_Status |= (1 << CP0St_FR);
env->hflags |= MIPS_HFLAG_F64;
} else if (!prog_req.fre && !prog_req.frdefault &&
!prog_req.fr1 && !prog_req.single && !prog_req.soft) {
fprintf(stderr, "qemu: Can't find a matching FPU mode\n");
exit(1);
+9
View File
@@ -86,6 +86,15 @@ void cpu_loop(CPUS390XState *env)
} else if (ret != -QEMU_ESIGRETURN) {
env->regs[2] = ret;
}
if (unlikely(cs->singlestep_enabled)) {
/*
* cpu_tb_exec() did not raise EXCP_DEBUG, because it has seen
* that EXCP_SVC was already pending.
*/
cs->exception_index = EXCP_DEBUG;
}
break;
case EXCP_DEBUG:
+71 -34
View File
@@ -11438,39 +11438,58 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
{
int gidsetsize = arg1;
target_id *target_grouplist;
gid_t *grouplist;
g_autofree gid_t *grouplist = NULL;
int i;
grouplist = alloca(gidsetsize * sizeof(gid_t));
ret = get_errno(getgroups(gidsetsize, grouplist));
if (gidsetsize == 0)
return ret;
if (!is_error(ret)) {
target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
if (!target_grouplist)
return -TARGET_EFAULT;
for(i = 0;i < ret; i++)
target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
if (gidsetsize > NGROUPS_MAX) {
return -TARGET_EINVAL;
}
if (gidsetsize > 0) {
grouplist = g_try_new(gid_t, gidsetsize);
if (!grouplist) {
return -TARGET_ENOMEM;
}
}
ret = get_errno(getgroups(gidsetsize, grouplist));
if (!is_error(ret) && gidsetsize > 0) {
target_grouplist = lock_user(VERIFY_WRITE, arg2,
gidsetsize * sizeof(target_id), 0);
if (!target_grouplist) {
return -TARGET_EFAULT;
}
for (i = 0; i < ret; i++) {
target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
}
unlock_user(target_grouplist, arg2,
gidsetsize * sizeof(target_id));
}
return ret;
}
return ret;
case TARGET_NR_setgroups:
{
int gidsetsize = arg1;
target_id *target_grouplist;
gid_t *grouplist = NULL;
g_autofree gid_t *grouplist = NULL;
int i;
if (gidsetsize) {
grouplist = alloca(gidsetsize * sizeof(gid_t));
target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
if (gidsetsize > NGROUPS_MAX || gidsetsize < 0) {
return -TARGET_EINVAL;
}
if (gidsetsize > 0) {
grouplist = g_try_new(gid_t, gidsetsize);
if (!grouplist) {
return -TARGET_ENOMEM;
}
target_grouplist = lock_user(VERIFY_READ, arg2,
gidsetsize * sizeof(target_id), 1);
if (!target_grouplist) {
return -TARGET_EFAULT;
}
for (i = 0; i < gidsetsize; i++) {
grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
}
unlock_user(target_grouplist, arg2, 0);
unlock_user(target_grouplist, arg2,
gidsetsize * sizeof(target_id));
}
return get_errno(setgroups(gidsetsize, grouplist));
}
@@ -11755,41 +11774,59 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
{
int gidsetsize = arg1;
uint32_t *target_grouplist;
gid_t *grouplist;
g_autofree gid_t *grouplist = NULL;
int i;
grouplist = alloca(gidsetsize * sizeof(gid_t));
if (gidsetsize > NGROUPS_MAX) {
return -TARGET_EINVAL;
}
if (gidsetsize > 0) {
grouplist = g_try_new(gid_t, gidsetsize);
if (!grouplist) {
return -TARGET_ENOMEM;
}
}
ret = get_errno(getgroups(gidsetsize, grouplist));
if (gidsetsize == 0)
return ret;
if (!is_error(ret)) {
target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
if (!is_error(ret) && gidsetsize > 0) {
target_grouplist = lock_user(VERIFY_WRITE, arg2,
gidsetsize * 4, 0);
if (!target_grouplist) {
return -TARGET_EFAULT;
}
for(i = 0;i < ret; i++)
for (i = 0; i < ret; i++) {
target_grouplist[i] = tswap32(grouplist[i]);
}
unlock_user(target_grouplist, arg2, gidsetsize * 4);
}
return ret;
}
return ret;
#endif
#ifdef TARGET_NR_setgroups32
case TARGET_NR_setgroups32:
{
int gidsetsize = arg1;
uint32_t *target_grouplist;
gid_t *grouplist;
g_autofree gid_t *grouplist = NULL;
int i;
grouplist = alloca(gidsetsize * sizeof(gid_t));
target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
if (!target_grouplist) {
return -TARGET_EFAULT;
if (gidsetsize > NGROUPS_MAX || gidsetsize < 0) {
return -TARGET_EINVAL;
}
if (gidsetsize > 0) {
grouplist = g_try_new(gid_t, gidsetsize);
if (!grouplist) {
return -TARGET_ENOMEM;
}
target_grouplist = lock_user(VERIFY_READ, arg2,
gidsetsize * 4, 1);
if (!target_grouplist) {
return -TARGET_EFAULT;
}
for (i = 0; i < gidsetsize; i++) {
grouplist[i] = tswap32(target_grouplist[i]);
}
unlock_user(target_grouplist, arg2, 0);
}
for(i = 0;i < gidsetsize; i++)
grouplist[i] = tswap32(target_grouplist[i]);
unlock_user(target_grouplist, arg2, 0);
return get_errno(setgroups(gidsetsize, grouplist));
}
#endif
+4
View File
@@ -3164,6 +3164,10 @@ modinfo_files = []
block_mods = []
softmmu_mods = []
foreach d, list : modules
if not (d == 'block' ? have_block : have_system)
continue
endif
foreach m, module_ss : list
if enable_modules and targetos != 'windows'
module_ss = module_ss.apply(config_all, strict: false)
+16 -14
View File
@@ -3320,7 +3320,6 @@ static void migration_completion(MigrationState *s)
ret = global_state_store();
if (!ret) {
bool inactivate = !migrate_colo_enabled();
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
trace_migration_completion_vm_stop(ret);
if (ret >= 0) {
@@ -3328,12 +3327,15 @@ static void migration_completion(MigrationState *s)
MIGRATION_STATUS_DEVICE);
}
if (ret >= 0) {
/*
* Inactivate disks except in COLO, and track that we
* have done so in order to remember to reactivate
* them if migration fails or is cancelled.
*/
s->block_inactive = !migrate_colo_enabled();
qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
inactivate);
}
if (inactivate && ret >= 0) {
s->block_inactive = true;
s->block_inactive);
}
}
qemu_mutex_unlock_iothread();
@@ -3370,13 +3372,13 @@ static void migration_completion(MigrationState *s)
rp_error = await_return_path_close_on_source(s);
trace_migration_return_path_end_after(rp_error);
if (rp_error) {
goto fail_invalidate;
goto fail;
}
}
if (qemu_file_get_error(s->to_dst_file)) {
trace_migration_completion_file_err();
goto fail_invalidate;
goto fail;
}
if (migrate_colo_enabled() && s->state == MIGRATION_STATUS_ACTIVE) {
@@ -3390,12 +3392,13 @@ static void migration_completion(MigrationState *s)
return;
fail_invalidate:
/* If not doing postcopy, vm_start() will be called: let's regain
* control on images.
*/
if (s->state == MIGRATION_STATUS_ACTIVE ||
s->state == MIGRATION_STATUS_DEVICE) {
fail:
if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE ||
s->state == MIGRATION_STATUS_DEVICE)) {
/*
* If not doing postcopy, vm_start() will be called: let's
* regain control on images.
*/
Error *local_err = NULL;
qemu_mutex_lock_iothread();
@@ -3408,7 +3411,6 @@ fail_invalidate:
qemu_mutex_unlock_iothread();
}
fail:
migrate_set_state(&s->state, current_active_state,
MIGRATION_STATUS_FAILED);
}
+10 -1
View File
@@ -49,6 +49,7 @@ const int vdpa_feature_bits[] = {
VIRTIO_F_VERSION_1,
VIRTIO_NET_F_CSUM,
VIRTIO_NET_F_GUEST_CSUM,
VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
VIRTIO_NET_F_GSO,
VIRTIO_NET_F_GUEST_TSO4,
VIRTIO_NET_F_GUEST_TSO6,
@@ -160,6 +161,14 @@ static void vhost_vdpa_cleanup(NetClientState *nc)
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
struct vhost_dev *dev = &s->vhost_net->dev;
/*
* If a peer NIC is attached, do not cleanup anything.
* Cleanup will happen as a part of qemu_cleanup() -> net_cleanup()
* when the guest is shutting down.
*/
if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
return;
}
qemu_vfree(s->cvq_cmd_out_buffer);
qemu_vfree(s->status);
if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
@@ -500,7 +509,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
}
if (*s->status != VIRTIO_NET_OK) {
return VIRTIO_NET_ERR;
goto out;
}
status = VIRTIO_NET_ERR;
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
keymaps = {
'ar': '-l ar',
'ar': '-l ara',
'bepo': '-l fr -v dvorak',
'cz': '-l cz',
'da': '-l dk',
+22 -2
View File
@@ -1140,10 +1140,22 @@ have gone through several iterations as the feature set and complexity
of the block layer have grown. Many online guides to QEMU often
reference older and deprecated options, which can lead to confusion.
The recommended modern way to describe disks is to use a combination of
The most explicit way to describe disks is to use a combination of
``-device`` to specify the hardware device and ``-blockdev`` to
describe the backend. The device defines what the guest sees and the
backend describes how QEMU handles the data.
backend describes how QEMU handles the data. It is the only guaranteed
stable interface for describing block devices and as such is
recommended for management tools and scripting.
The ``-drive`` option combines the device and backend into a single
command line option which is a more human friendly. There is however no
interface stability guarantee although some older board models still
need updating to work with the modern blockdev forms.
Older options like ``-hda`` are essentially macros which expand into
``-drive`` options for various drive interfaces. The original forms
bake in a lot of assumptions from the days when QEMU was emulating a
legacy PC, they are not recommended for modern configurations.
ERST
@@ -1636,6 +1648,14 @@ SRST
the raw disk image you use is not written back. You can however
force the write back by pressing C-a s (see the :ref:`disk images`
chapter in the System Emulation Users Guide).
.. warning::
snapshot is incompatible with ``-blockdev`` (instead use qemu-img
to manually create snapshot images to attach to your blockdev).
If you have mixed ``-blockdev`` and ``-drive`` declarations you
can use the 'snapshot' property on your drive declarations
instead of this global option.
ERST
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
+6 -6
View File
@@ -1925,10 +1925,10 @@ static void guest_suspend(SuspendMode mode, Error **errp)
if (systemd_supports_mode(mode, &local_err)) {
mode_supported = true;
systemd_suspend(mode, &local_err);
}
if (!local_err) {
return;
if (!local_err) {
return;
}
}
error_free(local_err);
@@ -1937,10 +1937,10 @@ static void guest_suspend(SuspendMode mode, Error **errp)
if (pmutils_supports_mode(mode, &local_err)) {
mode_supported = true;
pmutils_suspend(mode, &local_err);
}
if (!local_err) {
return;
if (!local_err) {
return;
}
}
error_free(local_err);
+3 -1
View File
@@ -397,7 +397,7 @@ def binariesToTest(args, testcase):
def accelsToTest(args, testcase):
if getBinaryInfo(args, testcase['binary']).kvm_available:
if getBinaryInfo(args, testcase['binary']).kvm_available and not args.tcg_only:
yield 'kvm'
yield 'tcg'
@@ -510,6 +510,8 @@ def main():
help="Full mode: test cases that are expected to fail")
parser.add_argument('--strict', action='store_true', dest='strict',
help="Treat all warnings as fatal")
parser.add_argument('--tcg-only', action='store_true', dest='tcg_only',
help="Only test with TCG accelerator")
parser.add_argument('qemu', nargs='*', metavar='QEMU',
help='QEMU binary to run')
args = parser.parse_args()
+7 -2
View File
@@ -259,11 +259,16 @@ static void icount_warp_rt(void)
warp_delta = clock - timers_state.vm_clock_warp_start;
if (icount_enabled() == 2) {
/*
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
* far ahead of real time.
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too far
* ahead of real time (it might already be ahead so careful not
* to go backwards).
*/
int64_t cur_icount = icount_get_locked();
int64_t delta = clock - cur_icount;
if (delta < 0) {
delta = 0;
}
warp_delta = MIN(warp_delta, delta);
}
qatomic_set_i64(&timers_state.qemu_icount_bias,
+2
View File
@@ -280,6 +280,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
}
}
kvm_arm_init_debug(s);
return ret;
}
+4 -14
View File
@@ -74,24 +74,16 @@ GArray *hw_breakpoints, *hw_watchpoints;
#define get_hw_bp(i) (&g_array_index(hw_breakpoints, HWBreakpoint, i))
#define get_hw_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i))
/**
* kvm_arm_init_debug() - check for guest debug capabilities
* @cs: CPUState
*
* kvm_check_extension returns the number of debug registers we have
* or 0 if we have none.
*
*/
static void kvm_arm_init_debug(CPUState *cs)
void kvm_arm_init_debug(KVMState *s)
{
have_guest_debug = kvm_check_extension(cs->kvm_state,
have_guest_debug = kvm_check_extension(s,
KVM_CAP_SET_GUEST_DEBUG);
max_hw_wps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_WPS);
max_hw_wps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_WPS);
hw_watchpoints = g_array_sized_new(true, true,
sizeof(HWWatchpoint), max_hw_wps);
max_hw_bps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_BPS);
max_hw_bps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_BPS);
hw_breakpoints = g_array_sized_new(true, true,
sizeof(HWBreakpoint), max_hw_bps);
return;
@@ -920,8 +912,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
kvm_arm_init_debug(cs);
/* Check whether user space can specify guest syndrome value */
kvm_arm_init_serror_injection(cs);
+8
View File
@@ -18,6 +18,14 @@
#define KVM_ARM_VGIC_V2 (1 << 0)
#define KVM_ARM_VGIC_V3 (1 << 1)
/**
* kvm_arm_init_debug() - initialize guest debug capabilities
* @s: KVMState
*
* Should be called only once before using guest debug capabilities.
*/
void kvm_arm_init_debug(KVMState *s);
/**
* kvm_arm_vcpu_init:
* @cs: CPUState
+6
View File
@@ -6726,6 +6726,7 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
intptr_t reg_off;
SVEHostPage info;
target_ulong addr, in_page;
ARMVectorReg scratch;
/* Skip to the first true predicate. */
reg_off = find_next_active(vg, 0, reg_max, esz);
@@ -6735,6 +6736,11 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
return;
}
/* Protect against overlap between vd and vm. */
if (unlikely(vd == vm)) {
vm = memcpy(&scratch, vm, reg_max);
}
/*
* Probe the first element, allowing faults.
*/
+11 -2
View File
@@ -82,8 +82,17 @@ static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
uint32_t fsr, fsc;
if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
/*
* For M-profile there is no guest-facing FSR. We compute a
* short-form value for env->exception.fsr which we will then
* examine in arm_v7m_cpu_do_interrupt(). In theory we could
* use the LPAE format instead as long as both bits of code agree
* (and arm_fi_to_lfsc() handled the M-profile specific
* ARMFault_QEMU_NSCExec and ARMFault_QEMU_SFault cases).
*/
if (!arm_feature(env, ARM_FEATURE_M) &&
(target_el == 2 || arm_el_is_aa64(env, target_el) ||
arm_s1_regime_using_lpae_format(env, arm_mmu_idx))) {
/*
* LPAE format fault status register : bottom 6 bits are
* status code in the same form as needed for syndrome
+7
View File
@@ -61,6 +61,13 @@ static inline TCGv_i32 load_cpu_offset(int offset)
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
/* Load from the low half of a 64-bit field to a TCGv_i32 */
#define load_cpu_field_low32(name) \
({ \
QEMU_BUILD_BUG_ON(sizeof_field(CPUARMState, name) != 8); \
load_cpu_offset(offsetoflow32(CPUARMState, name)); \
})
void store_cpu_offset(TCGv_i32 var, int offset, int size);
#define store_cpu_field(var, name) \
+21 -3
View File
@@ -3536,8 +3536,22 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
*/
fn(tcg_rt, clean_addr, tcg_rs, get_mem_index(s), mop);
if ((mop & MO_SIGN) && size != MO_64) {
tcg_gen_ext32u_i64(tcg_rt, tcg_rt);
if (mop & MO_SIGN) {
switch (size) {
case MO_8:
tcg_gen_ext8u_i64(tcg_rt, tcg_rt);
break;
case MO_16:
tcg_gen_ext16u_i64(tcg_rt, tcg_rt);
break;
case MO_32:
tcg_gen_ext32u_i64(tcg_rt, tcg_rt);
break;
case MO_64:
break;
default:
g_assert_not_reached();
}
}
}
@@ -4176,9 +4190,13 @@ static void disas_ldst_tag(DisasContext *s, uint32_t insn)
if (s->ata) {
gen_helper_ldg(tcg_rt, cpu_env, addr, tcg_rt);
} else {
/*
* Tag access disabled: we must check for aborts on the load
* load from [rn+offset], and then insert a 0 tag into rt.
*/
clean_addr = clean_data_tbi(s, addr);
gen_probe_access(s, clean_addr, MMU_DATA_LOAD, MO_8);
gen_address_with_allocation_tag0(tcg_rt, addr);
gen_address_with_allocation_tag0(tcg_rt, tcg_rt);
}
} else {
tcg_rt = cpu_reg_sp(s, rt);
+2 -2
View File
@@ -2886,7 +2886,7 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
dc_isar_feature(aa64_sel2, s)) {
/* Target EL is EL<3 minus SCR_EL3.EEL2> */
tcg_el = load_cpu_field(cp15.scr_el3);
tcg_el = load_cpu_field_low32(cp15.scr_el3);
tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
tcg_gen_addi_i32(tcg_el, tcg_el, 3);
} else {
@@ -6558,7 +6558,7 @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
}
if (s->current_el == 2) {
/* ERET from Hyp uses ELR_Hyp, not LR */
tmp = load_cpu_field(elr_el[2]);
tmp = load_cpu_field_low32(elr_el[2]);
} else {
tmp = load_reg(s, 14);
}
+2 -2
View File
@@ -5584,8 +5584,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
} else {
*eax &= env->features[FEAT_SGX_12_1_EAX];
*ebx &= 0; /* ebx reserve */
*ecx &= env->features[FEAT_XSAVE_XSS_LO];
*edx &= env->features[FEAT_XSAVE_XSS_HI];
*ecx &= env->features[FEAT_XSAVE_XCR0_LO];
*edx &= env->features[FEAT_XSAVE_XCR0_HI];
/* FP and SSE are always allowed regardless of XSAVE/XCR0. */
*ecx |= XSTATE_FP_MASK | XSTATE_SSE_MASK;
+8
View File
@@ -2493,6 +2493,14 @@ void helper_vpermdq_ymm(Reg *d, Reg *v, Reg *s, uint32_t order)
d->Q(1) = r1;
d->Q(2) = r2;
d->Q(3) = r3;
if (order & 0x8) {
d->Q(0) = 0;
d->Q(1) = 0;
}
if (order & 0x80) {
d->Q(2) = 0;
d->Q(3) = 0;
}
}
void helper_vpermq_ymm(Reg *d, Reg *s, uint32_t order)
+13 -2
View File
@@ -782,6 +782,17 @@ static void decode_0F2D(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
*entry = *decode_by_prefix(s, opcodes_0F2D);
}
static void decode_VxCOMISx(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
{
/*
* VUCOMISx and VCOMISx are different and use no-prefix and 0x66 for SS and SD
* respectively. Scalar values usually are associated with 0xF2 and 0xF3, for
* which X86_VEX_REPScalar exists, but here it has to be decoded by hand.
*/
entry->s1 = entry->s2 = (s->prefix & PREFIX_DATA ? X86_SIZE_sd : X86_SIZE_ss);
entry->gen = (*b == 0x2E ? gen_VUCOMI : gen_VCOMI);
}
static void decode_sse_unary(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
{
if (!(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))) {
@@ -870,8 +881,8 @@ static const X86OpEntry opcodes_0F[256] = {
[0x2B] = X86_OP_GROUP0(0F2B),
[0x2C] = X86_OP_GROUP0(0F2C),
[0x2D] = X86_OP_GROUP0(0F2D),
[0x2E] = X86_OP_ENTRY3(VUCOMI, None,None, V,x, W,x, vex4 p_00_66),
[0x2F] = X86_OP_ENTRY3(VCOMI, None,None, V,x, W,x, vex4 p_00_66),
[0x2E] = X86_OP_GROUP3(VxCOMISx, None,None, V,x, W,x, vex3 p_00_66), /* VUCOMISS/SD */
[0x2F] = X86_OP_GROUP3(VxCOMISx, None,None, V,x, W,x, vex3 p_00_66), /* VCOMISS/SD */
[0x38] = X86_OP_GROUP0(0F38),
[0x3a] = X86_OP_GROUP0(0F3A),
+1 -1
View File
@@ -2288,7 +2288,7 @@ static void gen_VZEROALL(DisasContext *s, CPUX86State *env, X86DecodedInsn *deco
{
TCGv_ptr ptr = tcg_temp_new_ptr();
tcg_gen_addi_ptr(ptr, cpu_env, offsetof(CPUX86State, xmm_t0));
tcg_gen_addi_ptr(ptr, cpu_env, offsetof(CPUX86State, xmm_regs));
gen_helper_memset(ptr, ptr, tcg_constant_i32(0),
tcg_constant_ptr(CPU_NB_REGS * sizeof(ZMMReg)));
tcg_temp_free_ptr(ptr);
+1 -1
View File
@@ -7085,7 +7085,7 @@ static void ppc_cpu_reset(DeviceState *dev)
if (env->mmu_model != POWERPC_MMU_REAL) {
ppc_tlb_invalidate_all(env);
}
pmu_update_summaries(env);
pmu_mmcr01_updated(env);
}
/* clean any pending stop state */
+6 -3
View File
@@ -1358,9 +1358,12 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
/*
* We don't want to generate a Hypervisor Emulation Assistance
* Interrupt if we don't have HVB in msr_mask (PAPR mode).
* Interrupt if we don't have HVB in msr_mask (PAPR mode),
* unless running a nested-hv guest, in which case the L1
* kernel wants the interrupt.
*/
if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) {
if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB) &&
!books_vhyp_handles_hv_excp(cpu)) {
excp = POWERPC_EXCP_PROGRAM;
}
@@ -2631,7 +2634,7 @@ void helper_scv(CPUPPCState *env, uint32_t lev)
}
}
void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
void helper_pminsn(CPUPPCState *env, uint32_t insn)
{
CPUState *cs;
+55 -18
View File
@@ -46,6 +46,48 @@ void hreg_swap_gpr_tgpr(CPUPPCState *env)
env->tgpr[3] = tmp;
}
static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
{
uint32_t hflags = 0;
#if defined(TARGET_PPC64)
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC0) {
hflags |= 1 << HFLAGS_PMCC0;
}
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) {
hflags |= 1 << HFLAGS_PMCC1;
}
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) {
hflags |= 1 << HFLAGS_PMCJCE;
}
#ifndef CONFIG_USER_ONLY
if (env->pmc_ins_cnt) {
hflags |= 1 << HFLAGS_INSN_CNT;
}
if (env->pmc_ins_cnt & 0x1e) {
hflags |= 1 << HFLAGS_PMC_OTHER;
}
#endif
#endif
return hflags;
}
/* Mask of all PMU hflags */
static uint32_t hreg_compute_pmu_hflags_mask(CPUPPCState *env)
{
uint32_t hflags_mask = 0;
#if defined(TARGET_PPC64)
hflags_mask |= 1 << HFLAGS_PMCC0;
hflags_mask |= 1 << HFLAGS_PMCC1;
hflags_mask |= 1 << HFLAGS_PMCJCE;
hflags_mask |= 1 << HFLAGS_INSN_CNT;
hflags_mask |= 1 << HFLAGS_PMC_OTHER;
#endif
return hflags_mask;
}
static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
{
target_ulong msr = env->msr;
@@ -103,30 +145,12 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
if (env->spr[SPR_LPCR] & LPCR_HR) {
hflags |= 1 << HFLAGS_HR;
}
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC0) {
hflags |= 1 << HFLAGS_PMCC0;
}
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) {
hflags |= 1 << HFLAGS_PMCC1;
}
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) {
hflags |= 1 << HFLAGS_PMCJCE;
}
#ifndef CONFIG_USER_ONLY
if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) {
hflags |= 1 << HFLAGS_HV;
}
#if defined(TARGET_PPC64)
if (env->pmc_ins_cnt) {
hflags |= 1 << HFLAGS_INSN_CNT;
}
if (env->pmc_ins_cnt & 0x1e) {
hflags |= 1 << HFLAGS_PMC_OTHER;
}
#endif
/*
* This is our encoding for server processors. The architecture
* specifies that there is no such thing as userspace with
@@ -171,6 +195,8 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
hflags |= dmmu_idx << HFLAGS_DMMU_IDX;
#endif
hflags |= hreg_compute_pmu_hflags_value(env);
return hflags | (msr & msr_mask);
}
@@ -179,6 +205,17 @@ void hreg_compute_hflags(CPUPPCState *env)
env->hflags = hreg_compute_hflags_value(env);
}
/*
* This can be used as a lighter-weight alternative to hreg_compute_hflags
* when PMU MMCR0 or pmc_ins_cnt changes. pmc_ins_cnt is changed by
* pmu_update_summaries.
*/
void hreg_update_pmu_hflags(CPUPPCState *env)
{
env->hflags &= ~hreg_compute_pmu_hflags_mask(env);
env->hflags |= hreg_compute_pmu_hflags_value(env);
}
#ifdef CONFIG_DEBUG_TCG
void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *flags)
+1
View File
@@ -22,6 +22,7 @@
void hreg_swap_gpr_tgpr(CPUPPCState *env);
void hreg_compute_hflags(CPUPPCState *env);
void hreg_update_pmu_hflags(CPUPPCState *env);
void cpu_interrupt_exittb(CPUState *cs);
int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv);
+4 -4
View File
@@ -21,10 +21,6 @@ static void post_load_update_msr(CPUPPCState *env)
*/
env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB);
ppc_store_msr(env, msr);
if (tcg_enabled()) {
pmu_update_summaries(env);
}
}
static int get_avr(QEMUFile *f, void *pv, size_t size,
@@ -317,6 +313,10 @@ static int cpu_post_load(void *opaque, int version_id)
post_load_update_msr(env);
if (tcg_enabled()) {
pmu_mmcr01_updated(env);
}
return 0;
}
+22 -16
View File
@@ -31,7 +31,11 @@ static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn)
return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
}
void pmu_update_summaries(CPUPPCState *env)
/*
* Called after MMCR0 or MMCR1 changes to update pmc_ins_cnt and pmc_cyc_cnt.
* hflags must subsequently be updated.
*/
static void pmu_update_summaries(CPUPPCState *env)
{
target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
@@ -39,7 +43,7 @@ void pmu_update_summaries(CPUPPCState *env)
int cyc_cnt = 0;
if (mmcr0 & MMCR0_FC) {
goto hflags_calc;
goto out;
}
if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
@@ -73,10 +77,19 @@ void pmu_update_summaries(CPUPPCState *env)
ins_cnt |= !(mmcr0 & MMCR0_FC56) << 5;
cyc_cnt |= !(mmcr0 & MMCR0_FC56) << 6;
hflags_calc:
out:
env->pmc_ins_cnt = ins_cnt;
env->pmc_cyc_cnt = cyc_cnt;
env->hflags = deposit32(env->hflags, HFLAGS_INSN_CNT, 1, ins_cnt != 0);
}
void pmu_mmcr01_updated(CPUPPCState *env)
{
pmu_update_summaries(env);
hreg_update_pmu_hflags(env);
/*
* Should this update overflow timers (if mmcr0 is updated) so they
* get set in cpu_post_load?
*/
}
static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns)
@@ -234,18 +247,11 @@ static void pmu_delete_timers(CPUPPCState *env)
void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
{
bool hflags_pmcc0 = (value & MMCR0_PMCC0) != 0;
bool hflags_pmcc1 = (value & MMCR0_PMCC1) != 0;
pmu_update_cycles(env);
env->spr[SPR_POWER_MMCR0] = value;
/* MMCR0 writes can change HFLAGS_PMCC[01] and HFLAGS_INSN_CNT */
env->hflags = deposit32(env->hflags, HFLAGS_PMCC0, 1, hflags_pmcc0);
env->hflags = deposit32(env->hflags, HFLAGS_PMCC1, 1, hflags_pmcc1);
pmu_update_summaries(env);
pmu_mmcr01_updated(env);
/* Update cycle overflow timers with the current MMCR0 state */
pmu_update_overflow_timers(env);
@@ -257,8 +263,7 @@ void helper_store_mmcr1(CPUPPCState *env, uint64_t value)
env->spr[SPR_POWER_MMCR1] = value;
/* MMCR1 writes can change HFLAGS_INSN_CNT */
pmu_update_summaries(env);
pmu_mmcr01_updated(env);
}
target_ulong helper_read_pmc(CPUPPCState *env, uint32_t sprn)
@@ -287,8 +292,8 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu)
env->spr[SPR_POWER_MMCR0] &= ~MMCR0_FCECE;
env->spr[SPR_POWER_MMCR0] |= MMCR0_FC;
/* Changing MMCR0_FC requires a new HFLAGS_INSN_CNT calc */
pmu_update_summaries(env);
/* Changing MMCR0_FC requires summaries and hflags update */
pmu_mmcr01_updated(env);
/*
* Delete all pending timers if we need to freeze
@@ -299,6 +304,7 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu)
}
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMAE) {
/* These MMCR0 bits do not require summaries or hflags update. */
env->spr[SPR_POWER_MMCR0] &= ~MMCR0_PMAE;
env->spr[SPR_POWER_MMCR0] |= MMCR0_PMAO;
}
+2 -2
View File
@@ -18,10 +18,10 @@
#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL
void cpu_ppc_pmu_init(CPUPPCState *env);
void pmu_update_summaries(CPUPPCState *env);
void pmu_mmcr01_updated(CPUPPCState *env);
#else
static inline void cpu_ppc_pmu_init(CPUPPCState *env) { }
static inline void pmu_update_summaries(CPUPPCState *env) { }
static inline void pmu_mmcr01_updated(CPUPPCState *env) { }
#endif
#endif
+1
View File
@@ -3972,6 +3972,7 @@ static void gen_lqarx(DisasContext *ctx)
}
tcg_temp_free(EA);
tcg_gen_mov_tl(cpu_reserve, EA);
tcg_gen_st_tl(hi, cpu_env, offsetof(CPUPPCState, reserve_val));
tcg_gen_st_tl(lo, cpu_env, offsetof(CPUPPCState, reserve_val2));
}
+1 -1
View File
@@ -2231,7 +2231,7 @@ static bool trans_VEXPANDQM(DisasContext *ctx, arg_VX_tb *a)
static bool do_vextractm(DisasContext *ctx, arg_VX_tb *a, unsigned vece)
{
const uint64_t elem_width = 8 << vece, elem_count_half = 8 >> vece,
mask = dup_const(vece, 1 << (elem_width - 1));
mask = dup_const(vece, 1ULL << (elem_width - 1));
uint64_t i, j;
TCGv_i64 lo, hi, t0, t1;
@@ -77,6 +77,9 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
#ifndef CONFIG_USER_ONLY
if (has_ext(ctx, RVS)) {
decode_save_opc(ctx);
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
gen_helper_sret(cpu_pc, cpu_env);
tcg_gen_exit_tb(NULL, 0); /* no chaining */
ctx->base.is_jmp = DISAS_NORETURN;
@@ -93,6 +96,9 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
{
#ifndef CONFIG_USER_ONLY
decode_save_opc(ctx);
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
gen_helper_mret(cpu_pc, cpu_env);
tcg_gen_exit_tb(NULL, 0); /* no chaining */
ctx->base.is_jmp = DISAS_NORETURN;
+2 -2
View File
@@ -604,8 +604,8 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
#if !defined(CONFIG_USER_ONLY)
cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model);
if (tcg_enabled()) {
/* basic mode, write the cpu address into the first 4 bit of the ID */
cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.core_id);
cpu->env.cpuid = deposit64(cpu->env.cpuid, CPU_PHYS_ADDR_SHIFT,
CPU_PHYS_ADDR_BITS, cpu->env.core_id);
}
#endif
}
+9 -1
View File
@@ -96,10 +96,18 @@ static inline bool s390_known_cpu_type(uint16_t type)
{
return s390_get_gen_for_cpu_type(type) != 0;
}
#define CPU_ID_SHIFT 32
#define CPU_ID_BITS 24
/*
* When cpu_id_format is 0 (basic mode), the leftmost 4 bits of cpu_id contain
* the rightmost 4 bits of the physical CPU address.
*/
#define CPU_PHYS_ADDR_BITS 4
#define CPU_PHYS_ADDR_SHIFT (CPU_ID_SHIFT + CPU_ID_BITS - CPU_PHYS_ADDR_BITS)
static inline uint64_t s390_cpuid_from_cpu_model(const S390CPUModel *model)
{
return ((uint64_t)model->cpu_ver << 56) |
((uint64_t)model->cpu_id << 32) |
((uint64_t)model->cpu_id << CPU_ID_SHIFT) |
((uint64_t)model->def->type << 16) |
(model->def->gen == 7 ? 0 : (uint64_t)model->cpu_id_format << 15);
}
+3 -3
View File
@@ -486,7 +486,7 @@
F(0xb343, LCXBR, RRE, Z, x2h, x2l, new_P, x1, negf128, f128, IF_BFP)
F(0xb373, LCDFR, RRE, FPSSH, 0, f2, new, f1, negf64, 0, IF_AFP1 | IF_AFP2)
/* LOAD COUNT TO BLOCK BOUNDARY */
C(0xe727, LCBB, RXE, V, la2, 0, r1, 0, lcbb, 0)
C(0xe727, LCBB, RXE, V, la2, 0, new, r1_32, lcbb, 0)
/* LOAD HALFWORD */
C(0xb927, LHR, RRE, EI, 0, r2_16s, 0, r1_32, mov2, 0)
C(0xb907, LGHR, RRE, EI, 0, r2_16s, 0, r1, mov2, 0)
@@ -564,7 +564,7 @@
C(0xec46, LOCGHI, RIE_g, LOC2, r1, i2, r1, 0, loc, 0)
C(0xec4e, LOCHHI, RIE_g, LOC2, r1_sr32, i2, new, r1_32h, loc, 0)
/* LOAD HIGH ON CONDITION */
C(0xb9e0, LOCFHR, RRF_c, LOC2, r1_sr32, r2, new, r1_32h, loc, 0)
C(0xb9e0, LOCFHR, RRF_c, LOC2, r1_sr32, r2_sr32, new, r1_32h, loc, 0)
C(0xebe0, LOCFH, RSY_b, LOC2, r1_sr32, m2_32u, new, r1_32h, loc, 0)
/* LOAD PAIR DISJOINT */
D(0xc804, LPD, SSF, ILA, 0, 0, new_P, r3_P32, lpd, 0, MO_TEUL)
@@ -606,7 +606,7 @@
F(0xed04, LDEB, RXE, Z, 0, m2_32u, new, f1, ldeb, 0, IF_BFP)
F(0xed05, LXDB, RXE, Z, 0, m2_64, new_P, x1, lxdb, 0, IF_BFP)
F(0xed06, LXEB, RXE, Z, 0, m2_32u, new_P, x1, lxeb, 0, IF_BFP)
F(0xb324, LDER, RXE, Z, 0, e2, new, f1, lde, 0, IF_AFP1)
F(0xb324, LDER, RRE, Z, 0, e2, new, f1, lde, 0, IF_AFP1)
F(0xed24, LDE, RXE, Z, 0, m2_32u, new, f1, lde, 0, IF_AFP1)
/* LOAD ROUNDED */
F(0xb344, LEDBR, RRF_e, Z, 0, f2, new, e1, ledb, 0, IF_BFP)
+58 -23
View File
@@ -1585,18 +1585,51 @@ static DisasJumpType op_bal(DisasContext *s, DisasOps *o)
}
}
/*
* Disassemble the target of a branch. The results are returned in a form
* suitable for passing into help_branch():
*
* - bool IS_IMM reflects whether the target is fixed or computed. Non-EXECUTEd
* branches, whose DisasContext *S contains the relative immediate field RI,
* are considered fixed. All the other branches are considered computed.
* - int IMM is the value of RI.
* - TCGv_i64 CDEST is the address of the computed target.
*/
#define disas_jdest(s, ri, is_imm, imm, cdest) do { \
if (have_field(s, ri)) { \
if (unlikely(s->ex_value)) { \
cdest = tcg_temp_new_i64(); \
tcg_gen_ld_i64(cdest, cpu_env, offsetof(CPUS390XState, ex_target));\
tcg_gen_addi_i64(cdest, cdest, (int64_t)get_field(s, ri) * 2); \
is_imm = false; \
} else { \
is_imm = true; \
} \
} else { \
is_imm = false; \
} \
imm = is_imm ? get_field(s, ri) : 0; \
} while (false)
static DisasJumpType op_basi(DisasContext *s, DisasOps *o)
{
DisasCompare c;
bool is_imm;
int imm;
pc_to_link_info(o->out, s, s->pc_tmp);
return help_goto_direct(s, s->base.pc_next + (int64_t)get_field(s, i2) * 2);
disas_jdest(s, i2, is_imm, imm, o->in2);
disas_jcc(s, &c, 0xf);
return help_branch(s, &c, is_imm, imm, o->in2);
}
static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
{
int m1 = get_field(s, m1);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
int imm;
/* BCR with R2 = 0 causes no branching */
if (have_field(s, r2) && get_field(s, r2) == 0) {
@@ -1613,6 +1646,7 @@ static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
disas_jdest(s, i2, is_imm, imm, o->in2);
disas_jcc(s, &c, m1);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1620,10 +1654,10 @@ static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
static DisasJumpType op_bct32(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
TCGv_i64 t;
int imm;
c.cond = TCG_COND_NE;
c.is_64 = false;
@@ -1638,6 +1672,7 @@ static DisasJumpType op_bct32(DisasContext *s, DisasOps *o)
tcg_gen_extrl_i64_i32(c.u.s32.a, t);
tcg_temp_free_i64(t);
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1668,9 +1703,9 @@ static DisasJumpType op_bcth(DisasContext *s, DisasOps *o)
static DisasJumpType op_bct64(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
int imm;
c.cond = TCG_COND_NE;
c.is_64 = true;
@@ -1681,6 +1716,7 @@ static DisasJumpType op_bct64(DisasContext *s, DisasOps *o)
c.u.s64.a = regs[r1];
c.u.s64.b = tcg_const_i64(0);
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1688,10 +1724,10 @@ static DisasJumpType op_bx32(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
int r3 = get_field(s, r3);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
TCGv_i64 t;
int imm;
c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
c.is_64 = false;
@@ -1707,6 +1743,7 @@ static DisasJumpType op_bx32(DisasContext *s, DisasOps *o)
store_reg32_i64(r1, t);
tcg_temp_free_i64(t);
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1714,9 +1751,9 @@ static DisasJumpType op_bx64(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
int r3 = get_field(s, r3);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
int imm;
c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
c.is_64 = true;
@@ -1733,6 +1770,7 @@ static DisasJumpType op_bx64(DisasContext *s, DisasOps *o)
c.u.s64.a = regs[r1];
c.g1 = true;
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1750,10 +1788,9 @@ static DisasJumpType op_cj(DisasContext *s, DisasOps *o)
c.u.s64.a = o->in1;
c.u.s64.b = o->in2;
is_imm = have_field(s, i4);
if (is_imm) {
imm = get_field(s, i4);
} else {
o->out = NULL;
disas_jdest(s, i4, is_imm, imm, o->out);
if (!is_imm && !o->out) {
imm = 0;
o->out = get_address(s, 0, get_field(s, b4),
get_field(s, d4));
@@ -5964,15 +6001,13 @@ static void in2_a2(DisasContext *s, DisasOps *o)
static TCGv gen_ri2(DisasContext *s)
{
int64_t delta = (int64_t)get_field(s, i2) * 2;
TCGv ri2;
TCGv ri2 = NULL;
bool is_imm;
int imm;
if (unlikely(s->ex_value)) {
ri2 = tcg_temp_new_i64();
tcg_gen_ld_i64(ri2, cpu_env, offsetof(CPUS390XState, ex_target));
tcg_gen_addi_i64(ri2, ri2, delta);
} else {
ri2 = tcg_constant_i64(s->base.pc_next + delta);
disas_jdest(s, i2, is_imm, imm, ri2);
if (is_imm) {
ri2 = tcg_constant_i64(s->base.pc_next + imm * 2);
}
return ri2;
@@ -5,7 +5,7 @@
# using a prebuilt toolchains for Xtensa cores from:
# https://github.com/foss-xtensa/toolchain/releases
#
FROM docker.io/library/debian:stretch-slim
FROM docker.io/library/debian:11-slim
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
+33
View File
@@ -8,6 +8,36 @@
#include "qemu/osdep.h"
#include "libqtest.h"
/*
* This used to trigger a DMA reentrancy issue
* leading to memory corruption bugs like stack
* overflow or use-after-free
* https://gitlab.com/qemu-project/qemu/-/issues/1563
*/
static void test_lsi_dma_reentrancy(void)
{
QTestState *s;
s = qtest_init("-M q35 -m 512M -nodefaults "
"-blockdev driver=null-co,node-name=null0 "
"-device lsi53c810 -device scsi-cd,drive=null0");
qtest_outl(s, 0xcf8, 0x80000804); /* PCI Command Register */
qtest_outw(s, 0xcfc, 0x7); /* Enables accesses */
qtest_outl(s, 0xcf8, 0x80000814); /* Memory Bar 1 */
qtest_outl(s, 0xcfc, 0xff100000); /* Set MMIO Address*/
qtest_outl(s, 0xcf8, 0x80000818); /* Memory Bar 2 */
qtest_outl(s, 0xcfc, 0xff000000); /* Set RAM Address*/
qtest_writel(s, 0xff000000, 0xc0000024);
qtest_writel(s, 0xff000114, 0x00000080);
qtest_writel(s, 0xff00012c, 0xff000000);
qtest_writel(s, 0xff000004, 0xff000114);
qtest_writel(s, 0xff000008, 0xff100014);
qtest_writel(s, 0xff10002f, 0x000000ff);
qtest_quit(s);
}
/*
* This used to trigger a UAF in lsi_do_msgout()
* https://gitlab.com/qemu-project/qemu/-/issues/972
@@ -120,5 +150,8 @@ int main(int argc, char **argv)
qtest_add_func("fuzz/lsi53c895a/lsi_do_msgout_cancel_req",
test_lsi_do_msgout_cancel_req);
qtest_add_func("fuzz/lsi53c895a/lsi_dma_reentrancy",
test_lsi_dma_reentrancy);
return g_test_run();
}
+12 -1
View File
@@ -26,6 +26,8 @@ TESTS+=branch-relative-long
TESTS+=noexec
Z13_TESTS=vistr
Z13_TESTS+=lcbb
Z13_TESTS+=locfhr
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
TESTS+=$(Z13_TESTS)
@@ -54,7 +56,16 @@ run-gdbstub-signals-s390x: signals-s390x
--bin $< --test $(S390X_SRC)/gdbstub/test-signals-s390x.py, \
mixing signals and debugging)
EXTRA_RUNS += run-gdbstub-signals-s390x
hello-s390x-asm: CFLAGS+=-nostdlib
run-gdbstub-svc: hello-s390x-asm
$(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(S390X_SRC)/gdbstub/test-svc.py, \
single-stepping svc)
EXTRA_RUNS += run-gdbstub-signals-s390x run-gdbstub-svc
endif
# MVX versions of sha512
+64
View File
@@ -0,0 +1,64 @@
"""Test single-stepping SVC.
This runs as a sourced script (via -x, via run-test.py)."""
from __future__ import print_function
import gdb
import sys
n_failures = 0
def report(cond, msg):
"""Report success/fail of a test"""
if cond:
print("PASS: {}".format(msg))
else:
print("FAIL: {}".format(msg))
global n_failures
n_failures += 1
def run_test():
"""Run through the tests one by one"""
report("lghi\t" in gdb.execute("x/i $pc", False, True), "insn #1")
gdb.execute("si")
report("larl\t" in gdb.execute("x/i $pc", False, True), "insn #2")
gdb.execute("si")
report("lghi\t" in gdb.execute("x/i $pc", False, True), "insn #3")
gdb.execute("si")
report("svc\t" in gdb.execute("x/i $pc", False, True), "insn #4")
gdb.execute("si")
report("xgr\t" in gdb.execute("x/i $pc", False, True), "insn #5")
gdb.execute("si")
report("svc\t" in gdb.execute("x/i $pc", False, True), "insn #6")
gdb.execute("si")
def main():
"""Prepare the environment and run through the tests"""
try:
inferior = gdb.selected_inferior()
print("ATTACHED: {}".format(inferior.architecture().name()))
except (gdb.error, AttributeError):
print("SKIPPING (not connected)")
exit(0)
if gdb.parse_and_eval('$pc') == 0:
print("SKIP: PC not set")
exit(0)
try:
# These are not very useful in scripts
gdb.execute("set pagination off")
gdb.execute("set confirm off")
# Run the actual tests
run_test()
except gdb.error:
report(False, "GDB Exception: {}".format(sys.exc_info()[0]))
print("All tests complete: %d failures" % n_failures)
exit(n_failures)
main()
+20
View File
@@ -0,0 +1,20 @@
/*
* Hello, World! in assembly.
*/
.globl _start
_start:
/* puts("Hello, World!"); */
lghi %r2,1
larl %r3,foo
lghi %r4,foo_end-foo
svc 4
/* exit(0); */
xgr %r2,%r2
svc 1
.align 2
foo: .asciz "Hello, World!\n"
foo_end:
+51
View File
@@ -0,0 +1,51 @@
/*
* Test the LCBB instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdlib.h>
static inline __attribute__((__always_inline__)) void
lcbb(long *r1, void *dxb2, int m3, int *cc)
{
asm("lcbb %[r1],%[dxb2],%[m3]\n"
"ipm %[cc]"
: [r1] "+r" (*r1), [cc] "=r" (*cc)
: [dxb2] "R" (*(char *)dxb2), [m3] "i" (m3)
: "cc");
*cc = (*cc >> 28) & 3;
}
static char buf[0x1000] __attribute__((aligned(0x1000)));
static inline __attribute__((__always_inline__)) void
test_lcbb(void *p, int m3, int exp_r1, int exp_cc)
{
long r1 = 0xfedcba9876543210;
int cc;
lcbb(&r1, p, m3, &cc);
assert(r1 == (0xfedcba9800000000 | exp_r1));
assert(cc == exp_cc);
}
int main(void)
{
test_lcbb(&buf[0], 0, 16, 0);
test_lcbb(&buf[63], 0, 1, 3);
test_lcbb(&buf[0], 1, 16, 0);
test_lcbb(&buf[127], 1, 1, 3);
test_lcbb(&buf[0], 2, 16, 0);
test_lcbb(&buf[255], 2, 1, 3);
test_lcbb(&buf[0], 3, 16, 0);
test_lcbb(&buf[511], 3, 1, 3);
test_lcbb(&buf[0], 4, 16, 0);
test_lcbb(&buf[1023], 4, 1, 3);
test_lcbb(&buf[0], 5, 16, 0);
test_lcbb(&buf[2047], 5, 1, 3);
test_lcbb(&buf[0], 6, 16, 0);
test_lcbb(&buf[4095], 6, 1, 3);
return EXIT_SUCCESS;
}
+29
View File
@@ -0,0 +1,29 @@
/*
* Test the LOCFHR instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdlib.h>
static inline __attribute__((__always_inline__)) long
locfhr(long r1, long r2, int m3, int cc)
{
cc <<= 28;
asm("spm %[cc]\n"
"locfhr %[r1],%[r2],%[m3]\n"
: [r1] "+r" (r1)
: [cc] "r" (cc), [r2] "r" (r2), [m3] "i" (m3)
: "cc");
return r1;
}
int main(void)
{
assert(locfhr(0x1111111122222222, 0x3333333344444444, 8, 0) ==
0x3333333322222222);
assert(locfhr(0x5555555566666666, 0x7777777788888888, 11, 1) ==
0x5555555566666666);
return EXIT_SUCCESS;
}
+2 -2
View File
@@ -307,7 +307,7 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
png_struct *png_ptr;
png_info *info_ptr;
g_autoptr(pixman_image_t) linebuf =
qemu_pixman_linebuf_create(PIXMAN_a8r8g8b8, width);
qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
uint8_t *buf = (uint8_t *)pixman_image_get_data(linebuf);
FILE *f = fdopen(fd, "wb");
int y;
@@ -337,7 +337,7 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
png_init_io(png_ptr, f);
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);

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