Compare commits

...

250 Commits

Author SHA1 Message Date
Michael Tokarev
20a1b341a0 Update version for 8.1.5 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-29 14:20:00 +03:00
Peter Maydell
ccdb4cc209 target/arm: Fix A64 scalar SQSHRN and SQRSHRN
In commit 1b7bc9b5c8 we changed handle_vec_simd_sqshrn() so
that instead of starting with a 0 value and depositing in each new
element from the narrowing operation, it instead started with the raw
result of the narrowing operation of the first element.

This is fine in the vector case, because the deposit operations for
the second and subsequent elements will always overwrite any higher
bits that might have been in the first element's result value in
tcg_rd.  However in the scalar case we only go through this loop
once.  The effect is that for a signed narrowing operation, if the
result is negative then we will now return a value where the bits
above the first element are incorrectly 1 (because the narrowfn
returns a sign-extended result, not one that is truncated to the
element size).

Fix this by using an extract operation to get exactly the correct
bits of the output of the narrowfn for element 1, instead of a
plain move.

Cc: qemu-stable@nongnu.org
Fixes: 1b7bc9b5c8 ("target/arm: Avoid tcg_const_ptr in handle_vec_simd_sqshrn")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2089
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240123153416.877308-1-peter.maydell@linaro.org
(cherry picked from commit 6fffc83785)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-27 18:10:41 +03:00
Max Filippov
b86fa3a4f2 target/xtensa: fix OOB TLB entry access
r[id]tlb[01], [iw][id]tlb opcodes use TLB way index passed in a register
by the guest. The host uses 3 bits of the index for ITLB indexing and 4
bits for DTLB, but there's only 7 entries in the ITLB array and 10 in
the DTLB array, so a malicious guest may trigger out-of-bound access to
these arrays.

Change split_tlb_entry_spec return type to bool to indicate whether TLB
way passed to it is valid. Change get_tlb_entry to return NULL in case
invalid TLB way is requested. Add assertion to xtensa_tlb_get_entry that
requested TLB way and entry indices are valid. Add checks to the
[rwi]tlb helpers that requested TLB way is valid and return 0 or do
nothing when it's not.

Cc: qemu-stable@nongnu.org
Fixes: b67ea0cd74 ("target-xtensa: implement memory protection options")
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20231215120307.545381-1-jcmvbkbc@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 604927e357)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-27 18:05:25 +03:00
Daniel P. Berrangé
d24dd10143 qtest: bump aspeed_smc-test timeout to 6 minutes
On a loaded system with --enable-debug, this test can take longer than
5 minutes. Raising the timeout to 6 minutes gives greater headroom for
such situations.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
[thuth: Increase the timeout to 6 minutes for very loaded systems]
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20231215070357.10888-11-thuth@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
(cherry picked from commit e8a12fe31f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fixup in tests/qtest/meson.build)
2024-01-26 19:54:36 +03:00
Stefan Hajnoczi
4b02c718b5 monitor: only run coroutine commands in qemu_aio_context
monitor_qmp_dispatcher_co() runs in the iohandler AioContext that is not
polled during nested event loops. The coroutine currently reschedules
itself in the main loop's qemu_aio_context AioContext, which is polled
during nested event loops. One known problem is that QMP device-add
calls drain_call_rcu(), which temporarily drops the BQL, leading to all
sorts of havoc like other vCPU threads re-entering device emulation code
while another vCPU thread is waiting in device emulation code with
aio_poll().

Paolo Bonzini suggested running non-coroutine QMP handlers in the
iohandler AioContext. This avoids trouble with nested event loops. His
original idea was to move coroutine rescheduling to
monitor_qmp_dispatch(), but I resorted to moving it to qmp_dispatch()
because we don't know if the QMP handler needs to run in coroutine
context in monitor_qmp_dispatch(). monitor_qmp_dispatch() would have
been nicer since it's associated with the monitor implementation and not
as general as qmp_dispatch(), which is also used by qemu-ga.

A number of qemu-iotests need updated .out files because the order of
QMP events vs QMP responses has changed.

Solves Issue #1933.

Cc: qemu-stable@nongnu.org
Fixes: 7bed89958b ("device_core: use drain_call_rcu in in qmp_device_add")
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2215192
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2214985
Buglink: https://issues.redhat.com/browse/RHEL-17369
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240118144823.1497953-4-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit effd60c878)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-26 19:31:37 +03:00
Stefan Hajnoczi
2f5e27eefa iotests: port 141 to Python for reliable QMP testing
The common.qemu bash functions allow tests to interact with the QMP
monitor of a QEMU process. I spent two days trying to update 141 when
the order of the test output changed, but found it would still fail
occassionally because printf() and QMP events race with synchronous QMP
communication.

I gave up and ported 141 to the existing Python API for QMP tests. The
Python API is less affected by the order in which QEMU prints output
because it does not print all QMP traffic by default.

The next commit changes the order in which QMP messages are received.
Make 141 reliable first.

Cc: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240118144823.1497953-3-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9ee2dd4c22)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-26 19:31:37 +03:00
Stefan Hajnoczi
03bc938fbf iotests: add filter_qmp_generated_node_ids()
Add a filter function for QMP responses that contain QEMU's
automatically generated node ids. The ids change between runs and must
be masked in the reference output.

The next commit will use this new function.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240118144823.1497953-2-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit da62b507a2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-26 19:31:37 +03:00
Ari Sundholm
23a512f418 block/blklogwrites: Fix a bug when logging "write zeroes" operations.
There is a bug in the blklogwrites driver pertaining to logging "write
zeroes" operations, causing log corruption. This can be easily observed
by setting detect-zeroes to something other than "off" for the driver.

The issue is caused by a concurrency bug pertaining to the fact that
"write zeroes" operations have to be logged in two parts: first the log
entry metadata, then the zeroed-out region. While the log entry
metadata is being written by bdrv_co_pwritev(), another operation may
begin in the meanwhile and modify the state of the blklogwrites driver.
This is as intended by the coroutine-driven I/O model in QEMU, of
course.

Unfortunately, this specific scenario is mishandled. A short example:
    1. Initially, in the current operation (#1), the current log sector
number in the driver state is only incremented by the number of sectors
taken by the log entry metadata, after which the log entry metadata is
written. The current operation yields.
    2. Another operation (#2) may start while the log entry metadata is
being written. It uses the current log position as the start offset for
its log entry. This is in the sector right after the operation #1 log
entry metadata, which is bad!
    3. After bdrv_co_pwritev() returns (#1), the current log sector
number is reread from the driver state in order to find out the start
offset for bdrv_co_pwrite_zeroes(). This is an obvious blunder, as the
offset will be the sector right after the (misplaced) operation #2 log
entry, which means that the zeroed-out region begins at the wrong
offset.
    4. As a result of the above, the log is corrupt.

Fix this by only reading the driver metadata once, computing the
offsets and sizes in one go (including the optional zeroed-out region)
and setting the log sector number to the appropriate value for the next
operation in line.

Signed-off-by: Ari Sundholm <ari@tuxera.com>
Cc: qemu-stable@nongnu.org
Message-ID: <20240109184646.1128475-1-megari@gmx.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit a9c8ea9547)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-26 18:35:56 +03:00
Jason Wang
dd1d3c8c29 virtio-net: correctly copy vnet header when flushing TX
When HASH_REPORT is negotiated, the guest_hdr_len might be larger than
the size of the mergeable rx buffer header. Using
virtio_net_hdr_mrg_rxbuf during the header swap might lead a stack
overflow in this case. Fixing this by using virtio_net_hdr_v1_hash
instead.

Reported-by: Xiao Lei <leixiao.nop@zju.edu.cn>
Cc: Yuri Benditovich <yuri.benditovich@daynix.com>
Cc: qemu-stable@nongnu.org
Cc: Mauro Matteo Cascella <mcascell@redhat.com>
Fixes: CVE-2023-6693
Fixes: e22f0603fb ("virtio-net: reference implementation of hash report")
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 2220e8189f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-26 16:20:04 +03:00
Joseph Burt
c173670033 tcg/arm: Fix SIGILL in tcg_out_qemu_st_direct
When tcg_out_qemu_st_{index,direct} were merged, the direct case for
MO_64 was omitted, causing qemu_st_i64 to be encoded as 0xffffffff due
to underflow when adding h.base and h.index.

Fixes: 1df6d611bd ("tcg/arm: Introduce HostAddress")
Signed-off-by: Joseph Burt <caseorum@gmail.com>
Message-Id: <20240121211439.100829-1-caseorum@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 9f6523e8e4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-25 19:14:05 +03:00
Fiona Ebner
76a9da39d4 block/io: clear BDRV_BLOCK_RECURSE flag after recursing in bdrv_co_block_status
Using fleecing backup like in [0] on a qcow2 image (with metadata
preallocation) can lead to the following assertion failure:

> bdrv_co_do_block_status: Assertion `!(ret & BDRV_BLOCK_ZERO)' failed.

In the reproducer [0], it happens because the BDRV_BLOCK_RECURSE flag
will be set by the qcow2 driver, so the caller will recursively check
the file child. Then the BDRV_BLOCK_ZERO set too. Later up the call
chain, in bdrv_co_do_block_status() for the snapshot-access driver,
the assertion failure will happen, because both flags are set.

To fix it, clear the recurse flag after the recursive check was done.

In detail:

> #0  qcow2_co_block_status

Returns 0x45 = BDRV_BLOCK_RECURSE | BDRV_BLOCK_DATA |
BDRV_BLOCK_OFFSET_VALID.

> #1  bdrv_co_do_block_status

Because of the data flag, bdrv_co_do_block_status() will now also set
BDRV_BLOCK_ALLOCATED. Because of the recurse flag,
bdrv_co_do_block_status() for the bdrv_file child will be called,
which returns 0x16 = BDRV_BLOCK_ALLOCATED | BDRV_BLOCK_OFFSET_VALID |
BDRV_BLOCK_ZERO. Now the return value inherits the zero flag.

Returns 0x57 = BDRV_BLOCK_RECURSE | BDRV_BLOCK_DATA |
BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_ALLOCATED | BDRV_BLOCK_ZERO.

> #2  bdrv_co_common_block_status_above
> #3  bdrv_co_block_status_above
> #4  bdrv_co_block_status
> #5  cbw_co_snapshot_block_status
> #6  bdrv_co_snapshot_block_status
> #7  snapshot_access_co_block_status
> #8  bdrv_co_do_block_status

Return value is propagated all the way up to here, where the assertion
failure happens, because BDRV_BLOCK_RECURSE and BDRV_BLOCK_ZERO are
both set.

> #9  bdrv_co_common_block_status_above
> #10 bdrv_co_block_status_above
> #11 block_copy_block_status
> #12 block_copy_dirty_clusters
> #13 block_copy_common
> #14 block_copy_async_co_entry
> #15 coroutine_trampoline

[0]:

> #!/bin/bash
> rm /tmp/disk.qcow2
> ./qemu-img create /tmp/disk.qcow2 -o preallocation=metadata -f qcow2 1G
> ./qemu-img create /tmp/fleecing.qcow2 -f qcow2 1G
> ./qemu-img create /tmp/backup.qcow2 -f qcow2 1G
> ./qemu-system-x86_64 --qmp stdio \
> --blockdev qcow2,node-name=node0,file.driver=file,file.filename=/tmp/disk.qcow2 \
> --blockdev qcow2,node-name=node1,file.driver=file,file.filename=/tmp/fleecing.qcow2 \
> --blockdev qcow2,node-name=node2,file.driver=file,file.filename=/tmp/backup.qcow2 \
> <<EOF
> {"execute": "qmp_capabilities"}
> {"execute": "blockdev-add", "arguments": { "driver": "copy-before-write", "file": "node0", "target": "node1", "node-name": "node3" } }
> {"execute": "blockdev-add", "arguments": { "driver": "snapshot-access", "file": "node3", "node-name": "snap0" } }
> {"execute": "blockdev-backup", "arguments": { "device": "snap0", "target": "node1", "sync": "full", "job-id": "backup0" } }
> EOF

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-id: 20240116154839.401030-1-f.ebner@proxmox.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 8a9be79924)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-25 19:14:05 +03:00
Paolo Bonzini
4b06bb5826 accel/tcg: Revert mapping of PCREL translation block to multiple virtual addresses
This is causing regressions that have not been analyzed yet.  Revert the
change on stable branches.

Cc: qemu-stable@nongnu.org
Cc: Michael Tokarev <mjt@tls.msk.ru>
Related: https://gitlab.com/qemu-project/qemu/-/issues/2092
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-25 19:14:05 +03:00
Alex Bennée
25ff741fe8 readthodocs: fully specify a build environment
This is now expected by rtd so I've expanded using their example as
22.04 is one of our supported platforms. I tried to work out if there
was an easy way to re-generate a requirements.txt from our
pythondeps.toml but in the end went for the easier solution.

Cc:  <qemu-stable@nongnu.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231221174200.2693694-1-alex.bennee@linaro.org>
(cherry picked from commit b16a45bc5e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-23 18:48:41 +03:00
Mark Cave-Ayland
72694a69c9 hw/scsi/esp-pci: set DMA_STAT_BCMBLT when BLAST command issued
Even though the BLAST command isn't fully implemented in QEMU, the DMA_STAT_BCMBLT
bit should be set after the command has been issued to indicate that the command
has completed.

This fixes an issue with the DC390 DOS driver which issues the BLAST command as
part of its normal error recovery routine at startup, and otherwise sits in a
tight loop waiting for DMA_STAT_BCMBLT to be set before continuing.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-ID: <20240112131529.515642-5-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit c2d7de557d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 18:25:50 +03:00
Mark Cave-Ayland
01db312e3b hw/scsi/esp-pci: synchronise setting of DMA_STAT_DONE with ESP completion interrupt
The setting of DMA_STAT_DONE at the end of a DMA transfer can be configured to
generate an interrupt, however the Linux driver manually checks for DMA_STAT_DONE
being set and if it is, considers that a DMA transfer has completed.

If DMA_STAT_DONE is set but the ESP device isn't indicating an interrupt then
the Linux driver considers this to be a spurious interrupt. However this can
occur in QEMU as there is a delay between the end of DMA transfer where
DMA_STAT_DONE is set, and the ESP device raising its completion interrupt.

This appears to be an incorrect assumption in the Linux driver as the ESP and
PCI DMA interrupt sources are separate (and may not be raised exactly
together), however we can work around this by synchronising the setting of
DMA_STAT_DONE at the end of a DMA transfer with the ESP completion interrupt.

In conjunction with the previous commit Linux is now able to correctly boot
from an am53c974 PCI SCSI device on the hppa C3700 machine without emitting
"iget: checksum invalid" and "Spurious irq, sreg=10" errors.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-ID: <20240112131529.515642-4-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 1e8e6644e0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 18:25:50 +03:00
Mark Cave-Ayland
e8cb126075 hw/scsi/esp-pci: generate PCI interrupt from separate ESP and PCI sources
The am53c974/dc390 PCI interrupt has two separate sources: the first is from the
internal ESP device, and the second is from the PCI DMA transfer logic.

Update the ESP interrupt handler so that it sets DMA_STAT_SCSIINT rather than
driving the PCI IRQ directly, and introduce a new esp_pci_update_irq() function
to generate the correct PCI IRQ level. In particular this fixes spurious interrupts
being generated by setting DMA_STAT_DONE at the end of a transfer if DMA_CMD_INTE_D
isn't set in the DMA_CMD register.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-ID: <20240112131529.515642-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 6b41417d93)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 18:25:50 +03:00
Mark Cave-Ayland
2cd67d013d hw/scsi/esp-pci: use correct address register for PCI DMA transfers
The current code in esp_pci_dma_memory_rw() sets the DMA address to the value
of the DMA_SPA (Starting Physical Address) register which is incorrect: this
means that for each callback from the SCSI layer the DMA address is set back
to the starting address.

In the case where only a single SCSI callback occurs (currently for transfer
lengths < 128kB) this works fine, however for larger transfers the DMA address
wraps back to the initial starting address, corrupting the buffer holding the
data transferred to the guest.

Fix esp_pci_dma_memory_rw() to use the DMA_WAC (Working Address Counter) for
the DMA address which is correctly incremented across multiple SCSI layer
transfers.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-ID: <20240112131529.515642-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 84a6835e00)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 18:25:50 +03:00
Nick Briggs
2472f8467d migration/rdma: define htonll/ntohll only if not predefined
Solaris has #defines for htonll and ntohll which cause syntax errors
when compiling code that attempts to (re)define these functions..

Signed-off-by: Nick Briggs <nicholas.h.briggs@gmail.com>
Link: https://lore.kernel.org/r/65a04a7d.497ab3.3e7bef1f@gateway.sonic.net
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 44ce1b5d2f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 17:57:17 +03:00
Gerd Hoffmann
fcc79f2e09 hw/pflash: implement update buffer for block writes
Add an update buffer where all block updates are staged.
Flush or discard updates properly, so we should never see
half-completed block writes in pflash storage.

Drop a bunch of FIXME comments ;)

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240108160900.104835-4-kraxel@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 284a7ee2e2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: drop const in hw/block/pflash_cfi01.c for before
 v8.2.0-220-g7d5dc0a367 "hw/block: Constify VMState")
2024-01-20 13:44:00 +03:00
Gerd Hoffmann
dd25df302e hw/pflash: use ldn_{be,le}_p and stn_{be,le}_p
Use the helper functions we have to read/write multi-byte values
in correct byte order.

Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240108160900.104835-3-kraxel@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 5dd58358a5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 13:29:58 +03:00
Gerd Hoffmann
d83b0f64aa hw/pflash: refactor pflash_data_write()
Move the offset calculation, do it once at the start of the function and
let the 'p' variable point directly to the memory location which should
be updated.  This makes it simpler to update other buffers than
pfl->storage in an upcoming patch.  No functional change.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240108160900.104835-2-kraxel@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 3b14a555fd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 13:29:58 +03:00
Philippe Mathieu-Daudé
a8988972cd backends/cryptodev: Do not ignore throttle/backends Errors
Both cryptodev_backend_set_throttle() and CryptoDevBackendClass::init()
can set their Error** argument. Do not ignore them, return early
on failure. Without that, running into another failure trips
error_setv()'s assertion. Use the ERRP_GUARD() macro as suggested
in commit ae7c80a7bd ("error: New macro ERRP_GUARD()").

Cc: qemu-stable@nongnu.org
Fixes: e7a775fd9f ("cryptodev: Account statistics")
Fixes: 2580b452ff ("cryptodev: support QoS")
Reviewed-by: zhenwei pi <pizhenwei@bytedance.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20231120150418.93443-1-philmd@linaro.org>
(cherry picked from commit 484aecf2d3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 13:00:20 +03:00
Paolo Bonzini
7b03b125ee target/i386: pcrel: store low bits of physical address in data[0]
For PC-relative translation blocks, env->eip changes during the
execution of a translation block, Therefore, QEMU must be able to
recover an instruction's PC just from the TranslationBlock struct and
the instruction data with.  Because a TB will not span two pages, QEMU
stores all the low bits of EIP in the instruction data and replaces them
in x86_restore_state_to_opc.  Bits 12 and higher (which may vary between
executions of a PCREL TB, since these only use the physical address in
the hash key) are kept unmodified from env->eip.  The assumption is that
these bits of EIP, unlike bits 0-11, will not change as the translation
block executes.

Unfortunately, this is incorrect when the CS base is not aligned to a page.
Then the linear address of the instructions (i.e. the one with the
CS base addred) indeed will never span two pages, but bits 12+ of EIP
can actually change.  For example, if CS base is 0x80262200 and EIP =
0x6FF4, the first instruction in the translation block will be at linear
address 0x802691F4.  Even a very small TB will cross to EIP = 0x7xxx,
while the linear addresses will remain comfortably within a single page.

The fix is simply to use the low bits of the linear address for data[0],
since those don't change.  Then x86_restore_state_to_opc uses tb->cs_base
to compute a temporary linear address (referring to some unknown
instruction in the TB, but with the correct values of bits 12 and higher);
the low bits are replaced with data[0], and EIP is obtained by subtracting
again the CS base.

Huge thanks to Mark Cave-Ayland for the image and initial debugging,
and to Gitlab user @kjliew for help with bisecting another occurrence
of (hopefully!) the same bug.

It should be relatively easy to write a testcase that performs MMIO on
an EIP with different bits 12+ than the first instruction of the translation
block; any help is welcome.

Fixes: e3a79e0e87 ("target/i386: Enable TARGET_TB_PCREL", 2022-10-11)
Cc: qemu-stable@nongnu.org
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Richard Henderson <richard.henderson@linaro.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1759
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1964
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2012
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 729ba8e933)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 12:25:07 +03:00
guoguangyao
5707858602 target/i386: fix incorrect EIP in PC-relative translation blocks
The PCREL patches introduced a bug when updating EIP in the !CF_PCREL case.
Using s->pc in func gen_update_eip_next() solves the problem.

Cc: qemu-stable@nongnu.org
Fixes: b5e0d5d22f ("target/i386: Fix 32-bit wrapping of pc/eip computation")
Fixes: 5b2fd6cf37 (b5e0d5d22f in 8.1.4)
Signed-off-by: guoguangyao <guoguangyao18@mails.ucas.ac.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20240115020804.30272-1-guoguangyao18@mails.ucas.ac.cn>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2926eab896)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 12:24:19 +03:00
Richard Henderson
99e32260ac target/i386: Do not re-compute new pc with CF_PCREL
With PCREL, we have a page-relative view of EIP, and an
approximation of PC = EIP+CSBASE that is good enough to
detect page crossings.  If we try to recompute PC after
masking EIP, we will mess up that approximation and write
a corrupt value to EIP.

We already handled masking properly for PCREL, so the
fix in b5e0d5d2 was only needed for the !PCREL path.

Cc: qemu-stable@nongnu.org
Fixes: b5e0d5d22f ("target/i386: Fix 32-bit wrapping of pc/eip computation")
Fixes: 5b2fd6cf37 (b5e0d5d22f in 8.1.4)
Reported-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20240101230617.129349-1-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a58506b748)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-20 12:24:14 +03:00
Anastasia Belova
357b599028 load_elf: fix iterator's type for elf file processing
j is used while loading an ELF file to byteswap segments'
data. If data is larger than 2GB an overflow may happen.
So j should be elf_word.

This commit fixes a minor bug: it's unlikely anybody is trying to
load ELF files with 2GB+ segments for wrong-endianness targets,
but if they did, it wouldn't work correctly.

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

Cc: qemu-stable@nongnu.org
Fixes: 7ef295ea5b ("loader: Add data swap option to load-elf")
Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 410c2a4d75)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-19 13:41:10 +03:00
Peter Maydell
d6488e5186 .gitlab-ci.d/buildtest.yml: Work around htags bug when environment is large
Sometimes the CI "pages" job fails with a message like this from
htags:

$ htags -anT --tree-view=filetree -m qemu_init -t "Welcome to the QEMU sourcecode"
htags: Negative exec line limit = -371

This is due to a bug in hflags where if the environment is too large it
falls over:
https://lists.gnu.org/archive/html/bug-global/2024-01/msg00000.html

This happens to us because GitLab CI puts the commit message of the
commit under test into the CI_COMMIT_MESSAGE and/or CI_COMMIT_TAG_MESSAGE
environment variables, so the job will fail if the commit happens to
have a verbose commit message.

Work around the htags bug by unsetting these variables while running
htags.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2080
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240111125543.1573473-1-peter.maydell@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 52a21689cd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-13 11:30:08 +03:00
Ilya Leoshkevich
5e190ed415 target/s390x: Fix LAE setting a wrong access register
LAE should set the access register corresponding to the first operand,
instead, it always modifies access register 1.

Co-developed-by: Ido Plat <Ido.Plat@ibm.com>
Cc: qemu-stable@nongnu.org
Fixes: a1c7610a68 ("target-s390x: implement LAY and LAEY instructions")
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-ID: <20240111092328.929421-2-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit e358a25a97)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: target/s390x/tcg/translate.c: fixup for
 v8.1.0-1189-gad75a51e84 "tcg: Rename cpu_env to tcg_env")
2024-01-13 11:28:25 +03:00
Samuel Tardieu
f62b55da87 tests/qtest/virtio-ccw: Fix device presence checking
An apparent copy-paste error tests for the presence of the
virtio-rng-ccw device in order to perform tests on the virtio-scsi-ccw
device.

Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
Message-ID: <20240106130121.1244993-1-sam@rfc1149.net>
Fixes: 65331bf5d1 ("tests/qtest: Check for virtio-ccw devices before  using them")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit c98873ee4a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-13 11:18:43 +03:00
Natanael Copa
074b769c0b util: fix build with musl libc on ppc64le
Use PPC_FEATURE2_ISEL and PPC_FEATURE2_VEC_CRYPTO from linux headers
instead of the GNU specific PPC_FEATURE2_HAS_ISEL and
PPC_FEATURE2_HAS_VEC_CRYPTO. This fixes build with musl libc.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1861
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Fixes: 63922f467a ("tcg/ppc: Replace HAVE_ISEL macro with a variable")
Fixes: 68f340d4cd ("tcg/ppc: Enable Altivec detection")
Message-Id: <20231219105236.7059-1-ncopa@alpinelinux.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 1d513e06d9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-11 21:09:30 +03:00
Peter Maydell
6eb6bca73f hw/intc/arm_gicv3_cpuif: handle LPIs in in the list registers
The hypervisor can deliver (virtual) LPIs to a guest by setting up a
list register to have an intid which is an LPI.  The GIC has to treat
these a little differently to standard interrupt IDs, because LPIs
have no Active state, and so the guest will only EOI them, it will
not also deactivate them.  So icv_eoir_write() must do two things:

 * if the LPI ID is not in any list register, we drop the
   priority but do not increment the EOI count
 * if the LPI ID is in a list register, we immediately deactivate
   it, regardless of the split-drop-and-deactivate control

This can be seen in the VirtualWriteEOIR0() and VirtualWriteEOIR1()
pseudocode in the GICv3 architecture specification.

Without this fix, potentially a hypervisor guest might stall because
LPIs get stuck in a bogus Active+Pending state.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Miguel Luis <miguel.luis@oracle.com>
(cherry picked from commit 82a65e3188)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-11 20:59:38 +03:00
Michael Tokarev
97d3be7bca chardev/char.c: fix "abstract device type" error message
Current error message:

 qemu-system-x86_64: -chardev spice,id=foo: Parameter 'driver' expects an abstract device type

while in fact the meaning is in reverse, -chardev expects
a non-abstract device type.

Fixes: 777357d758 ("chardev: qom-ify" 2016-12-07)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
(cherry picked from commit 4ad87cd4b2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-08 19:25:17 +03:00
Xu Lu
03382b91cb target/riscv: Fix mcycle/minstret increment behavior
The mcycle/minstret counter's stop flag is mistakenly updated on a copy
on stack. Thus the counter increments even when the CY/IR bit in the
mcountinhibit register is set. This commit corrects its behavior.

Fixes: 3780e33732 (target/riscv: Support mcycle/minstret write operation)
Signed-off-by: Xu Lu <luxu.kernel@bytedance.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 5cb0e7abe1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-08 19:24:38 +03:00
Pavel Pisa
6c5dda7850 hw/net/can/sja1000: fix bug for single acceptance filter and standard frame
A CAN sja1000 standard frame filter mask has been computed and applied
incorrectly for standard frames when single Acceptance Filter Mode
(MOD_AFM = 1) has been selected. The problem has not been found
by Linux kernel testing because it uses dual filter mode (MOD_AFM = 0)
and leaves falters fully open.

The problem has been noticed by Grant Ramsay when testing with Zephyr
RTOS which uses single filter mode.

Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Reported-by: Grant Ramsay <gramsay@enphaseenergy.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2028
Fixes: 733210e754 ("hw/net/can: SJA1000 chip register level emulation")
Message-ID: <20240103231426.5685-1-pisa@fel.cvut.cz>
(cherry picked from commit 25145a7d77)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-01-05 22:17:14 +03:00
Kevin Wolf
60472f719c iotests: Basic tests for internal snapshots
We have a few test cases that include tests for corner case aspects of
internal snapshots, but nothing that tests that they actually function
as snapshots or that involves deleting a snapshot. Add a test for this
kind of basic internal snapshot functionality.

The error cases include a regression test for the crash we just fixed
with snapshot operations on inactive images.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20231201142520.32255-4-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit bb6e2511eb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-22 22:25:28 +03:00
Kevin Wolf
4c8315ad50 vl: Improve error message for conflicting -incoming and -loadvm
Currently, the conflict between -incoming and -loadvm is only detected
when loading the snapshot fails because the image is still inactive for
the incoming migration. This results in a suboptimal error message:

$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer
qemu-system-x86_64: Device 'ide0-hd0' is writable but does not support snapshots

Catch the situation already in qemu_validate_options() to improve the
message:

$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer
qemu-system-x86_64: 'incoming' and 'loadvm' options are mutually exclusive

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20231201142520.32255-3-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 5a7f21efaf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-22 22:25:28 +03:00
Kevin Wolf
b769a8e472 block: Fix crash when loading snapshot on inactive node
bdrv_is_read_only() only checks if the node is configured to be
read-only eventually, but even if it returns false, writing to the node
may not be permitted at the moment (because it's inactive).

bdrv_is_writable() checks that the node can be written to right now, and
this is what the snapshot operations really need.

Change bdrv_can_snapshot() to use bdrv_is_writable() to fix crashes like
the following:

$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer
qemu-system-x86_64: ../block/io.c:1990: int bdrv_co_write_req_prepare(BdrvChild *, int64_t, int64_t, BdrvTrackedRequest *, int): Assertion `!(bs->open_flags & BDRV_O_INACTIVE)' failed.

The resulting error message after this patch isn't perfect yet, but at
least it doesn't crash any more:

$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer
qemu-system-x86_64: Device 'ide0-hd0' is writable but does not support snapshots

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20231201142520.32255-2-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d3007d348a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-22 22:25:28 +03:00
Michael Tokarev
c95e38d33b Update version for 8.1.4 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-22 22:10:45 +03:00
Jean-Philippe Brucker
c06aef082f target/arm/helper: Propagate MDCR_EL2.HPMN into PMCR_EL0.N
MDCR_EL2.HPMN allows an hypervisor to limit the number of PMU counters
available to EL1 and EL0 (to keep the others to itself). QEMU already
implements this split correctly, except for PMCR_EL0.N reads: the number
of counters read by EL1 or EL0 should be the one configured in
MDCR_EL2.HPMN.

Cc: qemu-stable@nongnu.org
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Message-id: 20231215144652.4193815-2-jean-philippe@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 6980c31dec)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-20 19:07:05 +03:00
Richard Henderson
5b2fd6cf37 target/i386: Fix 32-bit wrapping of pc/eip computation
In 32-bit mode, pc = eip + cs_base is also 32-bit, and must wrap.
Failure to do so results in incorrect memory exceptions to the guest.
Before 732d548732, this was implicitly done via truncation to
target_ulong but only in qemu-system-i386, not qemu-system-x86_64.

To fix this, we must add conditional zero-extensions.
Since we have to test for 32 vs 64-bit anyway, note that cs_base
is always zero in 64-bit mode.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2022
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20231212172510.103305-1-richard.henderson@linaro.org>
(cherry picked from commit b5e0d5d22f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fix in target/i386/tcg/tcg-cpu.c for v8.1.0-1190-gb77af26e97
 "accel/tcg: Replace CPUState.env_ptr with cpu_env()")
2023-12-14 11:25:31 +03:00
Kevin Wolf
b831182728 block: Fix AioContext locking in qmp_block_resize()
The AioContext must be unlocked before calling blk_co_unref(), because
it takes the AioContext lock internally in blk_unref_bh(), which is
scheduled in the main thread. If we don't unlock, the AioContext is
locked twice and nested event loops such as in bdrv_graph_wrlock() will
deadlock.

Cc:  <qemu-stable@nongnu.org>
Fixes: https://issues.redhat.com/browse/RHEL-15965
Fixes: 0c7d204f50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20231208124352.30295-1-kwolf@redhat.com>
(cherry picked from commit 755ae3811f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-14 10:11:59 +03:00
Patrick Venture
fab36df7bd system/memory: use ldn_he_p/stn_he_p
Using direct pointer dereferencing can allow for unaligned accesses,
which was seen during execution with sanitizers enabled.

Cc: qemu-stable@nongnu.org
Reviewed-by: Chris Rauer <crauer@google.com>
Reviewed-by: Peter Foley <pefoley@google.com>
Signed-off-by: Patrick Venture <venture@google.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20231116163633.276671-1-venture@google.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 2b8fe81b3c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:51:00 +03:00
Peter Maydell
25d0ca4fb0 target/arm: Disable SME if SVE is disabled
There is no architectural requirement that SME implies SVE, but
our implementation currently assumes it. (FEAT_SME_FA64 does
imply SVE.) So if you try to run a CPU with eg "-cpu max,sve=off"
you quickly run into an assert when the guest tries to write to
SMCR_EL1:

#6  0x00007ffff4b38e96 in __GI___assert_fail
    (assertion=0x5555566e69cb "sm", file=0x5555566e5b24 "../../target/arm/helper.c", line=6865, function=0x5555566e82f0 <__PRETTY_FUNCTION__.31> "sve_vqm1_for_el_sm") at ./assert/assert.c:101
#7  0x0000555555ee33aa in sve_vqm1_for_el_sm (env=0x555557d291f0, el=2, sm=false) at ../../target/arm/helper.c:6865
#8  0x0000555555ee3407 in sve_vqm1_for_el (env=0x555557d291f0, el=2) at ../../target/arm/helper.c:6871
#9  0x0000555555ee3724 in smcr_write (env=0x555557d291f0, ri=0x555557da23b0, value=2147483663) at ../../target/arm/helper.c:6995
#10 0x0000555555fd1dba in helper_set_cp_reg64 (env=0x555557d291f0, rip=0x555557da23b0, value=2147483663) at ../../target/arm/tcg/op_helper.c:839
#11 0x00007fff60056781 in code_gen_buffer ()

Avoid this unsupported and slightly odd combination by
disabling SME when SVE is not present.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2005
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20231127173318.674758-1-peter.maydell@linaro.org
(cherry picked from commit f7767ca301)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:51:00 +03:00
Fiona Ebner
4b2648356f ui/vnc-clipboard: fix inflate_buffer
Commit d921fea338 ("ui/vnc-clipboard: fix infinite loop in
inflate_buffer (CVE-2023-3255)") removed this hunk, but it is still
required, because it can happen that stream.avail_in becomes zero
before coming across a return value of Z_STREAM_END in the loop.

This fixes the host->guest direction of the clipboard with noVNC and
TigerVNC as clients.

Fixes: d921fea338 ("ui/vnc-clipboard: fix infinite loop in inflate_buffer (CVE-2023-3255)")
Reported-by: Friedrich Weber <f.weber@proxmox.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20231122125826.228189-1-f.ebner@proxmox.com>
(cherry picked from commit ebfbf39467)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:51:00 +03:00
Volker Rümelin
5133410f8b ui/gtk-egl: move function calls back to regular code path
Commit 6f189a08c1 ("ui/gtk-egl: Check EGLSurface before doing
scanout") introduced a regression when QEMU is running with a
virtio-gpu-gl-device on a host under X11. After the guest has
initialized the virtio-gpu-gl-device, the guest screen only
shows "Display output is not active.".

Commit 6f189a08c1 moved all function calls in
gd_egl_scanout_texture() to a code path which is only called
once after gd_egl_init() succeeds in gd_egl_scanout_texture().
Move all function calls in gd_egl_scanout_texture() back to
the regular code path so they get always called if one of the
gd_egl_init() calls was successful.

Fixes: 6f189a08c1 ("ui/gtk-egl: Check EGLSurface before doing scanout")
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20231111104020.26183-1-vr_qemu@t-online.de>
(cherry picked from commit 53a939f1bf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:51:00 +03:00
Antonio Caggiano
5a92f023d9 ui/gtk-egl: Check EGLSurface before doing scanout
The first time gd_egl_scanout_texture() is called, there's a possibility
that the GTK drawing area might not be realized yet, in which case its
associated GdkWindow is NULL. This means gd_egl_init() was also skipped
and the EGLContext and EGLSurface stored in the VirtualGfxConsole are
not valid yet.

Continuing with the scanout in this conditions would result in hitting
an assert in libepoxy: "Couldn't find current GLX or EGL context".

A possible workaround is to just ignore the scanout request, giving the
the GTK drawing area some time to finish its realization. At that point,
the gd_egl_init() will succeed and the EGLContext and EGLSurface stored
in the VirtualGfxConsole will be valid.

Signed-off-by: Antonio Caggiano <quic_acaggian@quicinc.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20231016123215.2699269-1-quic_acaggian@quicinc.com>
(cherry picked from commit 6f189a08c1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:51:00 +03:00
Robert Hoo
701afca639 msix: unset PCIDevice::msix_vector_poll_notifier in rollback
In the rollback in msix_set_vector_notifiers(), original patch forgot to
undo msix_vector_poll_notifier pointer.

Fixes: bbef882cc1 ("msi: add API to get notified about pending bit poll")
Signed-off-by: Robert Hoo <robert.hoo.linux@gmail.com>
Message-Id: <20231113081349.1307-1-robert.hoo.linux@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2d37fe9e5e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:51:00 +03:00
Philippe Mathieu-Daudé
5c9f464531 hw/acpi/erst: Do not ignore Error* in realize handler
erst_realizefn() passes @errp to functions without checking for
failure.  If it runs into another failure, it trips error_setv()'s
assertion.

Use the ERRP_GUARD() macro and check *errp, as suggested in commit
ae7c80a7bd ("error: New macro ERRP_GUARD()").

Cc: qemu-stable@nongnu.org
Fixes: f7e26ffa59 ("ACPI ERST: support for ACPI ERST feature")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20231120130017.81286-1-philmd@linaro.org>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 20bc50137f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:51:00 +03:00
Akihiko Odaki
ed7e167699 pcie_sriov: Remove g_new assertion
g_new() aborts if the allocation fails so it returns NULL only if the
requested allocation size is zero. register_vfs() makes such an
allocation if NumVFs is zero so it should not assert that g_new()
returns a non-NULL value.

Fixes: 7c0fa8dff8 ("pcie: Add support for Single Root I/O Virtualization (SR/IOV)")
Buglink: https://issues.redhat.com/browse/RHEL-17209
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-Id: <20231123075630.12057-1-akihiko.odaki@daynix.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Yanghang Liu<yanghliu@redhat.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 714a1415d7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-13 18:50:45 +03:00
Volker Rümelin
59de6e246f hw/audio/hda-codec: fix multiplication overflow
After a relatively short time, there is an multiplication overflow
when multiplying (now - buft_start) with hda_bytes_per_second().
While the uptime now - buft_start only overflows after 2**63 ns
= 292.27 years, this happens hda_bytes_per_second() times faster
with the multiplication. At 44100 samples/s * 2 channels
* 2 bytes/channel = 176400 bytes/s that is 14.52 hours. After the
multiplication overflow the affected audio stream stalls.

Replace the multiplication and following division with muldiv64()
to prevent a multiplication overflow.

Fixes: 280c1e1cdb ("audio/hda: create millisecond timers that handle IO")
Reported-by: M_O_Bz <m_o_bz@163.com>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20231105172552.8405-1-vr_qemu@t-online.de>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 74e8593e7e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Gihun Nam
66f14b70fe hw/avr/atmega: Fix wrong initial value of stack pointer
The current implementation initializes the stack pointer of AVR devices
to 0. Although older AVR devices used to be like that, newer ones set
it to RAMEND.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1525
Signed-off-by: Gihun Nam <gihun.nam@outlook.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <PH0P222MB0010877445B594724D40C924DEBDA@PH0P222MB0010.NAMP222.PROD.OUTLOOK.COM>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 235948bf53)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Philippe Mathieu-Daudé
fbca2cbbef hw/virtio: Add VirtioPCIDeviceTypeInfo::instance_finalize field
The VirtioPCIDeviceTypeInfo structure, added in commit a4ee4c8baa
("virtio: Helper for registering virtio device types") got extended
in commit 8ea90ee690 ("virtio: add class_size") with the @class_size
field. Do similarly with the @instance_finalize field.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231121174051.63038-2-philmd@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 837053a7f4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Philippe Mathieu-Daudé
f5584a7d8d hw/nvram/xlnx-efuse-ctrl: Free XlnxVersalEFuseCtrl[] "pg0-lock" array
Commit 0be6bfac62 ("qdev: Implement variable length array properties")
added the DEFINE_PROP_ARRAY() macro with the following comment:

  * It is the responsibility of the device deinit code to free the
  * @_arrayfield memory.

Commit 9e4aa1fafe added:

  DEFINE_PROP_ARRAY("pg0-lock",
                    XlnxVersalEFuseCtrl, extra_pg0_lock_n16,
                    extra_pg0_lock_spec, qdev_prop_uint16, uint16_t),

but forgot to free the 'extra_pg0_lock_spec' array. Do it in the
instance_finalize() handler.

Cc: qemu-stable@nongnu.org
Fixes: 9e4aa1fafe ("hw/nvram: Xilinx Versal eFuse device") # v6.2.0+
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231121174051.63038-6-philmd@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 4f10c66077)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Philippe Mathieu-Daudé
a3e46300c5 hw/nvram/xlnx-efuse: Free XlnxEFuse::ro_bits[] array on finalize()
Commit 0be6bfac62 ("qdev: Implement variable length array properties")
added the DEFINE_PROP_ARRAY() macro with the following comment:

  * It is the responsibility of the device deinit code to free the
  * @_arrayfield memory.

Commit 68fbcc344e added:

  DEFINE_PROP_ARRAY("read-only", XlnxEFuse, ro_bits_cnt, ro_bits,
                    qdev_prop_uint32, uint32_t),

but forgot to free the 'ro_bits' array. Do it in the instance_finalize
handler.

Cc: qemu-stable@nongnu.org
Fixes: 68fbcc344e ("hw/nvram: Introduce Xilinx eFuse QOM") # v6.2.0+
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231121174051.63038-5-philmd@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 49b3e28b7b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Philippe Mathieu-Daudé
48e0dfb837 hw/misc/mps2-scc: Free MPS2SCC::oscclk[] array on finalize()
Commit 0be6bfac62 ("qdev: Implement variable length array properties")
added the DEFINE_PROP_ARRAY() macro with the following comment:

  * It is the responsibility of the device deinit code to free the
  * @_arrayfield memory.

Commit 4fb013afcc added:

  DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
                    qdev_prop_uint32, uint32_t),

but forgot to free the 'oscclk_reset' array. Do it in the
instance_finalize() handler.

Cc: qemu-stable@nongnu.org
Fixes: 4fb013afcc ("hw/misc/mps2-scc: Support configurable number of OSCCLK values") # v6.0.0+
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231121174051.63038-4-philmd@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 896dd6ff7b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Philippe Mathieu-Daudé
502f15db55 hw/virtio: Free VirtIOIOMMUPCI::vdev.reserved_regions[] on finalize()
Commit 0be6bfac62 ("qdev: Implement variable length array properties")
added the DEFINE_PROP_ARRAY() macro with the following comment:

  * It is the responsibility of the device deinit code to free the
  * @_arrayfield memory.

Commit 8077b8e549 added:

  DEFINE_PROP_ARRAY("reserved-regions", VirtIOIOMMUPCI,
                    vdev.nb_reserved_regions, vdev.reserved_regions,
                    qdev_prop_reserved_region, ReservedRegion),

but forgot to free the 'vdev.reserved_regions' array. Do it in the
instance_finalize() handler.

Cc: qemu-stable@nongnu.org
Fixes: 8077b8e549 ("virtio-iommu-pci: Add array of Interval properties") # v5.1.0+
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-id: 20231121174051.63038-3-philmd@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit c9a4aa06df)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: fixup hw/virtio/virtio-iommu-pci.c for before v8.1.0-2552-g41cc70cdf5,
 "virtio-iommu: Rename reserved_regions into prop_resv_regions" -- so now
 patch subject matches actual change again)
2023-12-05 12:32:36 +03:00
Peter Maydell
49727560c7 target/arm: Handle overflow in calculation of next timer tick
In commit edac4d8a16 back in 2015 when we added support for
the virtual timer offset CNTVOFF_EL2, we didn't correctly update
the timer-recalculation code that figures out when the timer
interrupt is next going to change state. We got it wrong in
two ways:
 * for the 0->1 transition, we didn't notice that gt->cval + offset
   can overflow a uint64_t
 * for the 1->0 transition, we didn't notice that the transition
   might now happen before the count rolls over, if offset > count

In the former case, we end up trying to set the next interrupt
for a time in the past, which results in QEMU hanging as the
timer fires continuously.

In the latter case, we would fail to update the interrupt
status when we are supposed to.

Fix the calculations in both cases.

The test case is Alex Bennée's from the bug report, and tests
the 0->1 transition overflow case.

Fixes: edac4d8a16 ("target-arm: Add CNTVOFF_EL2")
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/60
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20231120173506.3729884-1-peter.maydell@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 8d37a1425b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Peter Maydell
169c593f78 target/arm: Set IL bit for pauth, SVE access, BTI trap syndromes
The syndrome register value always has an IL field at bit 25, which
is 0 for a trap on a 16 bit instruction, and 1 for a trap on a 32
bit instruction (or for exceptions which aren't traps on a known
instruction, like PC alignment faults). This means that our
syn_*() functions should always either take an is_16bit argument to
determine whether to set the IL bit, or else unconditionally set it.

We missed setting the IL bit for the syndrome for three kinds of trap:
 * an SVE access exception
 * a pointer authentication check failure
 * a BTI (branch target identification) check failure

All of these traps are AArch64 only, and so the instruction causing
the trap is always 64 bit. This means we can unconditionally set
the IL bit in the syn_*() function.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20231120150121.3458408-1-peter.maydell@linaro.org
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 11a3c4a286)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:36 +03:00
Fam Zheng
5cf2cf1f9f vmdk: Don't corrupt desc file in vmdk_write_cid
If the text description file is larger than DESC_SIZE, we force the last
byte in the buffer to be 0 and write it out.

This results in a corruption.

Try to allocate a big buffer in this case.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1923

Signed-off-by: Fam Zheng <fam@euphon.net>
Message-ID: <20231124115654.3239137-1-fam@euphon.net>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9fb7b350ba)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-12-05 12:32:35 +03:00
Ivan Klokov
6f51114b0e target/riscv/cpu_helper.c: Fix mxr bit behavior
According to RISCV Specification sect 9.5 on two stage translation when
V=1 the vsstatus(mstatus in QEMU's terms) field MXR, which makes
execute-only pages readable, only overrides VS-stage page protection.
Setting MXR at HS-level(mstatus_hs), however, overrides both VS-stage
and G-stage execute-only permissions.

The hypervisor extension changes the behavior of MXR\MPV\MPRV bits.
Due to RISCV Specification sect. 9.4.1 when MPRV=1, explicit memory
accesses are translated and protected, and endianness is applied, as
though the current virtualization mode were set to MPV and the current
nominal privilege mode were set to MPP. vsstatus.MXR makes readable
those pages marked executable at the VS translation stage.

Fixes: 36a18664ba ("target/riscv: Implement second stage MMU")

Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20231121071757.7178-3-ivan.klokov@syntacore.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 6bca4d7d1f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-29 16:15:22 +03:00
Ivan Klokov
87ff608c6f target/riscv/cpu_helper.c: Invalid exception on MMU translation stage
According to RISCV privileged spec sect. 5.3.2 Virtual Address Translation Process
access-fault exceptions may raise only after PMA/PMP check. Current implementation
generates an access-fault for mbare mode even if there were no PMA/PMP errors.
This patch removes the erroneous MMU mode check and generates an access-fault
exception based on the pmp_violation flag only.

Fixes: 1448689c7b ("target/riscv: Allow specifying MMU stage")

Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20231121071757.7178-2-ivan.klokov@syntacore.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 82d53adfbb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-29 16:15:22 +03:00
Román Cárdenas
837148a31a riscv: Fix SiFive E CLINT clock frequency
If you check the manual of SiFive E310 (https://cdn.sparkfun.com/assets/7/f/0/2/7/fe310-g002-manual-v19p05.pdf),
you can see in Figure 1 that the CLINT is connected to the real time clock, which also feeds the AON peripheral (they share the same clock).
In page 43, the docs also say that the timer registers of the CLINT count ticks from the rtcclk.

I am currently playing with bare metal applications both in QEMU and a physical SiFive E310 board and
I confirm that the CLINT clock in the physical board runs at 32.768 kHz.
In QEMU, the same app produces a completely different outcome, as sometimes a new CLINT interrupt is triggered before finishing other tasks.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1978

Signed-off-by: Rom\ufffd\ufffdn C\ufffd\ufffdrdenas <rcardenas.rod@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20231117082840.55705-1-rcardenas.rod@gmail.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit a7472560ca)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-29 16:15:22 +03:00
Daniel Henrique Barboza
9ac76067ab hw/riscv/virt.c: do create_fdt() earlier, add finalize_fdt()
Commit 49554856f0 fixed a problem, where TPM devices were not appearing
in the FDT, by delaying the FDT creation up until virt_machine_done().
This create a side effect (see gitlab #1925) - devices that need access
to the '/chosen' FDT node during realize() stopped working because, at
that point, we don't have a FDT.

This happens because our FDT creation is monolithic, but it doesn't need
to be. We can add the needed FDT components for realize() time and, at
the same time, do another FDT round where we account for dynamic sysbus
devices.  In other words, the problem fixed by 49554856f0 could also be
fixed by postponing only create_fdt_sockets() and its dependencies,
leaving everything else from create_fdt() to be done during init().

Split the FDT creation in two parts:

- create_fdt(), now moved back to virt_machine_init(), will create FDT
  nodes that doesn't depend on additional (dynamic) devices from the
  sysbus;

- a new finalize_fdt() step is added, where create_fdt_sockets() and
  friends is executed, accounting for the dynamic sysbus devices that
  were added during realize().

This will make both use cases happy: TPM devices are still working as
intended, and devices such as 'guest-loader' have a FDT to work on
during realize().

Fixes: 49554856f0 ("riscv: Generate devicetree only after machine initialization is complete")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1925
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231110172559.73209-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 7a87ba8956)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-29 16:15:22 +03:00
Palmer Dabbelt
8d0b8fead4 linux-user/riscv: Add Zicboz block size to hwprobe
Support for probing the Zicboz block size landed in Linux 6.6, which was
released a few weeks ago.  This provides the user-configured block size
when Zicboz is enabled.

Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20231110173716.24423-1-palmer@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 301c65f49f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: fixup linux-user/syscall.c to before v8.1.0-2602-ge57039ddab
 "target/riscv: rename ext_icboz to ext_zicboz")
2023-11-29 16:14:17 +03:00
Philippe Mathieu-Daudé
8328d79621 tests/avocado: Replace assertRegexpMatches() for Python 3.12 compatibility
assertRegexpMatches() has been removed in Python 3.12 and should be replaced by
assertRegex(). See: https://docs.python.org/3.12/whatsnew/3.12.html#id3

Inspired-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20231114144832.71612-1-philmd@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit f0a663b4ce)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: adjust context for before v8.1.0-1582-g684750ab4f
 "python/qemu: rename command() to cmd()")
2023-11-29 15:35:38 +03:00
Thomas Huth
5e7f6afe98 tests/avocado: Replace assertEquals() for Python 3.12 compatibility
assertEquals() has been removed in Python 3.12 and should be replaced by
assertEqual(). See: https://docs.python.org/3.12/whatsnew/3.12.html#id3

Message-ID: <20231114134326.287242-1-thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 861f724d03)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: adjust context in pc_cpu_hotplug_props.py & cpu_queries.py for before
 v8.1.0-1582-g684750ab4f "python/qemu: rename command() to cmd()")
2023-11-29 15:35:38 +03:00
Richard Henderson
983a4a828c linux-user: Fix loaddr computation for some elf files
The file offset of the load segment is not relevant to the
low address, only the beginning of the virtual address page.

Cc: qemu-stable@nongnu.org
Fixes: a93934fecd ("elf: take phdr offset into account when calculating the program load address")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1952
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 82d70a84c8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-29 15:35:38 +03:00
Akihiko Odaki
88e79a2dfd net: Update MemReentrancyGuard for NIC
Recently MemReentrancyGuard was added to DeviceState to record that the
device is engaging in I/O. The network device backend needs to update it
when delivering a packet to a device.

This implementation follows what bottom half does, but it does not add
a tracepoint for the case that the network device backend started
delivering a packet to a device which is already engaging in I/O. This
is because such reentrancy frequently happens for
qemu_flush_queued_packets() and is insignificant.

Fixes: CVE-2023-3019
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Acked-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 9050f976e4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-29 15:35:38 +03:00
Akihiko Odaki
cc5124d979 net: Provide MemReentrancyGuard * to qemu_new_nic()
Recently MemReentrancyGuard was added to DeviceState to record that the
device is engaging in I/O. The network device backend needs to update it
when delivering a packet to a device.

In preparation for such a change, add MemReentrancyGuard * as a
parameter of qemu_new_nic().

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 7d0fefdf81)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: fixup in hw/net/xen_nic.c due to lack of v8.1.0-2771-g25967ff69f
 "hw/xen: update Xen PV NIC to XenDevice model")
2023-11-29 15:33:42 +03:00
Niklas Cassel
c6c0a1888f hw/ide/ahci: fix legacy software reset
Legacy software contains a standard mechanism for generating a reset to a
Serial ATA device - setting the SRST (software reset) bit in the Device
Control register.

Serial ATA has a more robust mechanism called COMRESET, also referred to
as port reset. A port reset is the preferred mechanism for error
recovery and should be used in place of software reset.

Commit e2a5d9b3d9 ("hw/ide/ahci: simplify and document PxCI handling")
(mjt:  16cc9594d2 in stable-8.1 series, v8.1.1)
improved the handling of PxCI, such that PxCI gets cleared after handling
a non-NCQ, or NCQ command (instead of incorrectly clearing PxCI after
receiving anything - even a FIS that failed to parse, which should NOT
clear PxCI, so that you can see which command slot that caused an error).

However, simply clearing PxCI after a non-NCQ, or NCQ command, is not
enough, we also need to clear PxCI when receiving a SRST in the Device
Control register.

A legacy software reset is performed by the host sending two H2D FISes,
the first H2D FIS asserts SRST, and the second H2D FIS deasserts SRST.

The first H2D FIS will not get a D2H reply, and requires the FIS to have
the C bit set to one, such that the HBA itself will clear the bit in PxCI.

The second H2D FIS will get a D2H reply once the diagnostic is completed.
The clearing of the bit in PxCI for this command should ideally be done
in ahci_init_d2h() (if it was a legacy software reset that caused the
reset (a COMRESET does not use a command slot)). However, since the reset
value for PxCI is 0, modify ahci_reset_port() to actually clear PxCI to 0,
that way we can avoid complex logic in ahci_init_d2h().

This fixes an issue for FreeBSD where the device would fail to reset.
The problem was not noticed in Linux, because Linux uses a COMRESET
instead of a legacy software reset by default.

Fixes: e2a5d9b3d9 ("hw/ide/ahci: simplify and document PxCI handling")
Reported-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Message-ID: <20231108222657.117984-1-nks@flawful.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit eabb921250)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(mjt: mention 16cc9594d2 for stable-8.1)
2023-11-22 14:25:22 +03:00
Richard Henderson
db8e86cc40 target/arm: Fix SME FMOPA (16-bit), BFMOPA
Perform the loop increment unconditionally, not nested
within the predication.

Cc: qemu-stable@nongnu.org
Fixes: 3916841ac7 ("target/arm: Implement FMOPA, FMOPS (widening)")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1985
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231117193135.1180657-1-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 3efd849573)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-22 14:25:22 +03:00
Max Filippov
d8ad972b2d linux-user: xtensa: fix signal delivery in FDPIC
In FDPIC signal handlers are passed around as FD pointers. Actual code
address and GOT pointer must be fetched from memory by the QEMU code
that implements kernel signal delivery functionality. This change is
equivalent to the following kernel change:
9c2cc74fb31e ("xtensa: fix signal delivery to FDPIC process")

Cc: qemu-stable@nongnu.org
Fixes: d2796be69d ("linux-user: add support for xtensa FDPIC")
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 1b173d0606)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-22 14:25:22 +03:00
Michael Tokarev
179cc58e00 Update version for 8.1.3 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-21 12:00:46 +03:00
Marc-André Lureau
d19b4a4215 hw/mips: LOONGSON3V depends on UNIMP device
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: qemu-stable@nongnu.org
Fixes: c76b409fef ("hw/mips: Add Loongson-3 machine support")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20231107140615.3034763-1-marcandre.lureau@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 52c773ce89)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Peter Maydell
b88b9585d8 target/arm: HVC at EL3 should go to EL3, not EL2
AArch64 permits code at EL3 to use the HVC instruction; however the
exception we take should go to EL3, not down to EL2 (see the pseudocode
AArch64.CallHypervisor()). Fix the target EL.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
Message-id: 20231109151917.1925107-1-peter.maydell@linaro.org
(cherry picked from commit fc58891d04)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Matthew Rosato
25f55508fc s390x/pci: only limit DMA aperture if vfio DMA limit reported
If the host kernel lacks vfio DMA limit reporting, do not attempt
to shrink the guest DMA aperture.

Fixes: df202e3ff3 ("s390x/pci: shrink DMA aperture to be bound by vfio DMA limit")
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Message-ID: <20231110175108.465851-3-mjrosato@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 8011b508cf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Daniel Henrique Barboza
150ebd076e target/riscv/kvm: support KVM_GET_REG_LIST
KVM for RISC-V started supporting KVM_GET_REG_LIST in Linux 6.6. It
consists of a KVM ioctl() that retrieves a list of all available regs
for get_one_reg/set_one_reg. Regs that aren't present in the list aren't
supported in the host.

This simplifies our lives when initing the KVM regs since we don't have
to always attempt a KVM_GET_ONE_REG for all regs QEMU knows. We'll only
attempt a get_one_reg() if we're sure the reg is supported, i.e. it was
retrieved by KVM_GET_REG_LIST. Any error in get_one_reg() will then
always considered fatal, instead of having to handle special error codes
that might indicate a non-fatal failure.

Start by moving the current kvm_riscv_init_multiext_cfg() logic into a
new kvm_riscv_read_multiext_legacy() helper. We'll prioritize using
KVM_GET_REG_LIST, so check if we have it available and, in case we
don't, use the legacy() logic.

Otherwise, retrieve the available reg list and use it to check if the
host supports our known KVM regs, doing the usual get_one_reg() for
the supported regs and setting cpu->cfg accordingly.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20231003132148.797921-3-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 608bdebb60)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: trivial context tweak in target/riscv/kvm.c)
2023-11-19 21:15:06 +03:00
Daniel Henrique Barboza
221c0e1426 target/riscv/kvm: improve 'init_multiext_cfg' error msg
Our error message is returning the value of 'ret', which will be always
-1 in case of error, and will not be that useful:

qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error -1

Improve the error message by outputting 'errno' instead of 'ret'. Use
strerrorname_np() to output the error name instead of the error code.
This will give us what we need to know right away:

qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error code: ENOENT

Given that we're going to exit(1) in this condition instead of
attempting to recover, remove the 'kvm_riscv_destroy_scratch_vcpu()'
call.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20231003132148.797921-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 082e9e4a58)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Marc-André Lureau
100feda604 tracetool: avoid invalid escape in Python string
This is an error in Python 3.12; fix it by using a raw string literal.

Cc:  <qemu-stable@nongnu.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20231108105649.60453-1-marcandre.lureau@redhat.com>
(cherry picked from commit 4d96307c5b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Ilya Leoshkevich
097c347136 tests/tcg/s390x: Test LAALG with negative cc_src
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20231106093605.1349201-5-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit ebc14107f1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Ilya Leoshkevich
a16eec9fb2 target/s390x: Fix LAALG not updating cc_src
LAALG uses op_laa() and wout_addu64(). The latter expects cc_src to be
set, but the former does not do it. This can lead to assertion failures
if something sets cc_src to neither 0 nor 1 before.

Fix by introducing op_laa_addu64(), which sets cc_src, and using it for
LAALG.

Fixes: 4dba4d6fef ("target/s390x: Use atomic operations for LOAD AND OP")
Cc: qemu-stable@nongnu.org
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20231106093605.1349201-4-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit bea402482a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Ilya Leoshkevich
255422dc75 tests/tcg/s390x: Test CLC with inaccessible second operand
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20231106093605.1349201-3-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 43fecbe7a5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Ilya Leoshkevich
88b778e4c2 target/s390x: Fix CLC corrupting cc_src
CLC updates cc_src before accessing the second operand; if the latter
is inaccessible, the former ends up containing a bogus value.

Fix by reading cc_src into a temporary first.

Fixes: 4f7403d52b ("target-s390: Convert CLC")
Closes: https://gitlab.com/qemu-project/qemu/-/issues/1865
Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20231106093605.1349201-2-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit aba2ec341c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Fiona Ebner
07c2a9c0fa tests/qtest: ahci-test: add test exposing reset issue with pending callback
Before commit "hw/ide: reset: cancel async DMA operation before
resetting state", this test would fail, because a reset with a
pending write operation would lead to an unsolicited write to the
first sector of the disk.

The test writes a pattern to the beginning of the disk and verifies
that it is still intact after a reset with a pending operation. It
also checks that the pending operation actually completes correctly.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20230906130922.142845-2-f.ebner@proxmox.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit cc610857bb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Fiona Ebner
60f7b60429 hw/ide: reset: cancel async DMA operation before resetting state
If there is a pending DMA operation during ide_bus_reset(), the fact
that the IDEState is already reset before the operation is canceled
can be problematic. In particular, ide_dma_cb() might be called and
then use the reset IDEState which contains the signature after the
reset. When used to construct the IO operation this leads to
ide_get_sector() returning 0 and nsector being 1. This is particularly
bad, because a write command will thus destroy the first sector which
often contains a partition table or similar.

Traces showing the unsolicited write happening with IDEState
0x5595af6949d0 being used after reset:

> ahci_port_write ahci(0x5595af6923f0)[0]: port write [reg:PxSCTL] @ 0x2c: 0x00000300
> ahci_reset_port ahci(0x5595af6923f0)[0]: reset port
> ide_reset IDEstate 0x5595af6949d0
> ide_reset IDEstate 0x5595af694da8
> ide_bus_reset_aio aio_cancel
> dma_aio_cancel dbs=0x7f64600089a0
> dma_blk_cb dbs=0x7f64600089a0 ret=0
> dma_complete dbs=0x7f64600089a0 ret=0 cb=0x5595acd40b30
> ahci_populate_sglist ahci(0x5595af6923f0)[0]
> ahci_dma_prepare_buf ahci(0x5595af6923f0)[0]: prepare buf limit=512 prepared=512
> ide_dma_cb IDEState 0x5595af6949d0; sector_num=0 n=1 cmd=DMA WRITE
> dma_blk_io dbs=0x7f6420802010 bs=0x5595ae2c6c30 offset=0 to_dev=1
> dma_blk_cb dbs=0x7f6420802010 ret=0

> (gdb) p *qiov
> $11 = {iov = 0x7f647c76d840, niov = 1, {{nalloc = 1, local_iov = {iov_base = 0x0,
>       iov_len = 512}}, {__pad = "\001\000\000\000\000\000\000\000\000\000\000",
>       size = 512}}}
> (gdb) bt
> #0  blk_aio_pwritev (blk=0x5595ae2c6c30, offset=0, qiov=0x7f6420802070, flags=0,
>     cb=0x5595ace6f0b0 <dma_blk_cb>, opaque=0x7f6420802010)
>     at ../block/block-backend.c:1682
> #1  0x00005595ace6f185 in dma_blk_cb (opaque=0x7f6420802010, ret=<optimized out>)
>     at ../softmmu/dma-helpers.c:179
> #2  0x00005595ace6f778 in dma_blk_io (ctx=0x5595ae0609f0,
>     sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
>     io_func=io_func@entry=0x5595ace6ee30 <dma_blk_write_io_func>,
>     io_func_opaque=io_func_opaque@entry=0x5595ae2c6c30,
>     cb=0x5595acd40b30 <ide_dma_cb>, opaque=0x5595af6949d0,
>     dir=DMA_DIRECTION_TO_DEVICE) at ../softmmu/dma-helpers.c:244
> #3  0x00005595ace6f90a in dma_blk_write (blk=0x5595ae2c6c30,
>     sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
>     cb=cb@entry=0x5595acd40b30 <ide_dma_cb>, opaque=opaque@entry=0x5595af6949d0)
>     at ../softmmu/dma-helpers.c:280
> #4  0x00005595acd40e18 in ide_dma_cb (opaque=0x5595af6949d0, ret=<optimized out>)
>     at ../hw/ide/core.c:953
> #5  0x00005595ace6f319 in dma_complete (ret=0, dbs=0x7f64600089a0)
>     at ../softmmu/dma-helpers.c:107
> #6  dma_blk_cb (opaque=0x7f64600089a0, ret=0) at ../softmmu/dma-helpers.c:127
> #7  0x00005595ad12227d in blk_aio_complete (acb=0x7f6460005b10)
>     at ../block/block-backend.c:1527
> #8  blk_aio_complete (acb=0x7f6460005b10) at ../block/block-backend.c:1524
> #9  blk_aio_write_entry (opaque=0x7f6460005b10) at ../block/block-backend.c:1594
> #10 0x00005595ad258cfb in coroutine_trampoline (i0=<optimized out>,
>     i1=<optimized out>) at ../util/coroutine-ucontext.c:177

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: simon.rowe@nutanix.com
Message-ID: <20230906130922.142845-1-f.ebner@proxmox.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 7d7512019f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Philippe Mathieu-Daudé
f15258b196 target/mips: Fix TX79 LQ/SQ opcodes
The base register address offset is *signed*.

Cc: qemu-stable@nongnu.org
Fixes: aaaa82a9f9 ("target/mips/tx79: Introduce LQ opcode (Load Quadword)")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230914090447.12557-1-philmd@linaro.org>
(cherry picked from commit 18f86aecd6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Philippe Mathieu-Daudé
f68a36b7c4 target/mips: Fix MSA BZ/BNZ opcodes displacement
The PC offset is *signed*.

Cc: qemu-stable@nongnu.org
Reported-by: Sergey Evlashev <vectorchiefrocks@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1624
Fixes: c7a9ef7517 ("target/mips: Introduce decode tree bindings for MSA ASE")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230914085807.12241-1-philmd@linaro.org>
(cherry picked from commit 04591b3ddd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-19 21:15:06 +03:00
Dongwon Kim
801b7e4390 ui/gtk-egl: apply scale factor when calculating window's dimension
Scale factor needs to be applied when calculating width/height of the
GTK windows.

Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20231012222643.13996-1-dongwon.kim@intel.com>
(cherry picked from commit 47fd6ab1e3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Marc-André Lureau
30d90aebcd ui/gtk: force realization of drawing area
Fixes the GL context creation from a widget that isn't yet realized (in
a hidden tab for example).

Resolves:
https://gitlab.com/qemu-project/qemu/-/issues/1727

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Antonio Caggiano <quic_acaggian@quicinc.com>
Message-Id: <20231017111642.1155545-1-marcandre.lureau@redhat.com>
(cherry picked from commit 565f85a9c2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
BALATON Zoltan
e301a77abb ati-vga: Implement fallback for pixman routines
Pixman routines can fail if no implementation is available and it will
become optional soon so add fallbacks when pixman does not work.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <ed0fba3f74e48143f02228b83bf8796ca49f3e7d.1698871239.git.balaton@eik.bme.hu>
(cherry picked from commit 08730ee0cc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Naohiro Aota
bcc9879c1c file-posix: fix over-writing of returning zone_append offset
raw_co_zone_append() sets "s->offset" where "BDRVRawState *s". This pointer
is used later at raw_co_prw() to save the block address where the data is
written.

When multiple IOs are on-going at the same time, a later IO's
raw_co_zone_append() call over-writes a former IO's offset address before
raw_co_prw() completes. As a result, the former zone append IO returns the
initial value (= the start address of the writing zone), instead of the
proper address.

Fix the issue by passing the offset pointer to raw_co_prw() instead of
passing it through s->offset. Also, remove "offset" from BDRVRawState as
there is no usage anymore.

Fixes: 4751d09adc ("block: introduce zone append write for zoned devices")
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Message-Id: <20231030073853.2601162-1-naohiro.aota@wdc.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit ad4feaca61)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Sam Li
a753815aa8 block/file-posix: fix update_zones_wp() caller
When the zoned request fail, it needs to update only the wp of
the target zones for not disrupting the in-flight writes on
these other zones. The wp is updated successfully after the
request completes.

Fixed the callers with right offset and nr_zones.

Signed-off-by: Sam Li <faithilikerun@gmail.com>
Message-Id: <20230825040556.4217-1-faithilikerun@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[hreitz: Rebased and fixed comment spelling]
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit 10b9e0802a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Jean-Louis Dupond
cc9f53b3ec qcow2: keep reference on zeroize with discard-no-unref enabled
When the discard-no-unref flag is enabled, we keep the reference for
normal discard requests.
But when a discard is executed on a snapshot/qcow2 image with backing,
the discards are saved as zero clusters in the snapshot image.

When committing the snapshot to the backing file, not
discard_in_l2_slice is called but zero_in_l2_slice. Which did not had
any logic to keep the reference when discard-no-unref is enabled.

Therefor we add logic in the zero_in_l2_slice call to keep the reference
on commit.

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1621
Signed-off-by: Jean-Louis Dupond <jean-louis@dupond.be>
Message-Id: <20231003125236.216473-2-jean-louis@dupond.be>
[hreitz: Made the documentation change more verbose, as discussed
         on-list]
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit b2b109041e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Peter Maydell
fe8eb3187c target/arm: Fix A64 LDRA immediate decode
In commit be23a049 in the conversion to decodetree we broke the
decoding of the immediate value in the LDRA instruction.  This should
be a 10 bit signed value that is scaled by 8, but in the conversion
we incorrectly ended up scaling it only by 2.  Fix the scaling
factor.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1970
Fixes: be23a049 ("target/arm: Convert load (pointer auth) insns to decodetree")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231106113445.1163063-1-peter.maydell@linaro.org
(cherry picked from commit 5722fc4712)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Vladimir Sementsov-Ogievskiy
1f560fa276 block/nvme: nvme_process_completion() fix bound for cid
NVMeQueuePair::reqs has length NVME_NUM_REQS, which less than
NVME_QUEUE_SIZE by 1.

Fixes: 1086e95da1 ("block/nvme: switch to a NVMeRequest freelist")
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Maksim Davydov <davydov-max@yandex-team.ru>
Message-id: 20231017125941.810461-5-vsementsov@yandex-team.ru
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit cc8fb0c3ae)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Marc-André Lureau
a89c8b96a8 virtio-gpu: block migration of VMs with blob=true
"blob" resources don't have an associated pixman image:

#0  pixman_image_get_stride (image=0x0) at ../pixman/pixman-image.c:921
#1  0x0000562327c25236 in virtio_gpu_save (f=0x56232bb13b00, opaque=0x56232b555a60, size=0, field=0x5623289ab6c8 <__compound_literal.3+104>, vmdesc=0x56232ab59fe0) at ../hw/display/virtio-gpu.c:1225

Related to:
https://bugzilla.redhat.com/show_bug.cgi?id=2236353

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 9c549ab689)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
David Woodhouse
287303495c hw/xen: use correct default protocol for xen-block on x86
Even on x86_64 the default protocol is the x86-32 one if the guest doesn't
specifically ask for x86-64.

Cc: qemu-stable@nongnu.org
Fixes: b6af8926fb ("xen: add implementations of xen-block connect and disconnect functions...")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit a1c1082908)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
David Woodhouse
30a4cc2723 hw/xen: take iothread mutex in xen_evtchn_reset_op()
The xen_evtchn_soft_reset() function requires the iothread mutex, but is
also called for the EVTCHNOP_reset hypercall. Ensure the mutex is taken
in that case.

Cc: qemu-stable@nongnu.org
Fixes: a15b10978f ("hw/xen: Implement EVTCHNOP_reset")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit debc995e88)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
David Woodhouse
b644416ec6 hw/xen: fix XenStore watch delivery to guest
When fire_watch_cb() found the response buffer empty, it would call
deliver_watch() to generate the XS_WATCH_EVENT message in the response
buffer and send an event channel notification to the guest… without
actually *copying* the response buffer into the ring. So there was
nothing for the guest to see. The pending response didn't actually get
processed into the ring until the guest next triggered some activity
from its side.

Add the missing call to put_rsp().

It might have been slightly nicer to call xen_xenstore_event() here,
which would *almost* have worked. Except for the fact that it calls
xen_be_evtchn_pending() to check that it really does have an event
pending (and clear the eventfd for next time). And under Xen it's
defined that setting that fd to O_NONBLOCK isn't guaranteed to work,
so the emu implementation follows suit.

This fixes Xen device hot-unplug.

Cc: qemu-stable@nongnu.org
Fixes: 0254c4d19d ("hw/xen: Add xenstore wire implementation and implementation stubs")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit 4a5780f520)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
David Woodhouse
0f2dd05b9f hw/xen: don't clear map_track[] in xen_gnttab_reset()
The refcounts actually correspond to 'active_ref' structures stored in a
GHashTable per "user" on the backend side (mostly, per XenDevice).

If we zero map_track[] on reset, then when the backend drivers get torn
down and release their mapping we hit the assert(s->map_track[ref] != 0)
in gnt_unref().

So leave them in place. Each backend driver will disconnect and reconnect
as the guest comes back up again and reconnects, and it all works out OK
in the end as the old refs get dropped.

Cc: qemu-stable@nongnu.org
Fixes: de26b26197 ("hw/xen: Implement soft reset for emulated gnttab")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit 3de75ed352)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
David Woodhouse
5450203719 hw/xen: select kernel mode for per-vCPU event channel upcall vector
A guest which has configured the per-vCPU upcall vector may set the
HVM_PARAM_CALLBACK_IRQ param to fairly much anything other than zero.

For example, Linux v6.0+ after commit b1c3497e604 ("x86/xen: Add support
for HVMOP_set_evtchn_upcall_vector") will just do this after setting the
vector:

       /* Trick toolstack to think we are enlightened. */
       if (!cpu)
               rc = xen_set_callback_via(1);

That's explicitly setting the delivery to GSI#1, but it's supposed to be
overridden by the per-vCPU vector setting. This mostly works in Qemu
*except* for the logic to enable the in-kernel handling of event channels,
which falsely determines that the kernel cannot accelerate GSI delivery
in this case.

Add a kvm_xen_has_vcpu_callback_vector() to report whether vCPU#0 has
the vector set, and use that in xen_evtchn_set_callback_param() to
enable the kernel acceleration features even when the param *appears*
to be set to target a GSI.

Preserve the Xen behaviour that when HVM_PARAM_CALLBACK_IRQ is set to
*zero* the event channel delivery is disabled completely. (Which is
what that bizarre guest behaviour is working round in the first place.)

Cc: qemu-stable@nongnu.org
Fixes: 91cce75617 ("hw/xen: Add xen_evtchn device for event channel emulation")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit 18e83f28bf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
David Woodhouse
91d789a891 i386/xen: fix per-vCPU upcall vector for Xen emulation
The per-vCPU upcall vector support had three problems. Firstly it was
using the wrong hypercall argument and would always return -EFAULT when
the guest tried to set it up. Secondly it was using the wrong ioctl() to
pass the vector to the kernel and thus the *kernel* would always return
-EINVAL. Finally, even when delivering the event directly from userspace
with an MSI, it put the destination CPU ID into the wrong bits of the
MSI address.

Linux doesn't (yet) use this mode so it went without decent testing
for a while.

Cc: qemu-stable@nongnu.org
Fixes: 105b47fdf2 ("i386/xen: implement HVMOP_set_evtchn_upcall_vector")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit e7dbb62ff1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
David Woodhouse
3321ec125f i386/xen: Don't advertise XENFEAT_supervisor_mode_kernel
This confuses lscpu into thinking it's running in PVH mode.

Cc: qemu-stable@nongnu.org
Fixes: bedcc13924 ("i386/xen: implement HYPERVISOR_xen_version")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit e969f992c6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Cédric Le Goater
5f0083a95d util/uuid: Remove UUID_FMT_LEN
Dangerous and now unused.

Cc: Fam Zheng <fam@euphon.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: "Denis V. Lunev" <den@openvz.org>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit 4ef9d97b1a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Cédric Le Goater
47c408b80e vfio/pci: Fix buffer overrun when writing the VF token
qemu_uuid_unparse() includes a trailing NUL when writing the uuid
string and the buffer size should be UUID_FMT_LEN + 1 bytes. Use the
recently added UUID_STR_LEN which defines the correct size.

Fixes: CID 1522913
Fixes: 2dca1b37a7 ("vfio/pci: add support for VF token")
Cc: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: "Denis V. Lunev" <den@openvz.org>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit f8d6f3b16c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Cédric Le Goater
6ede082daf util/uuid: Add UUID_STR_LEN definition
qemu_uuid_unparse() includes a trailing NUL when writing the uuid
string and the buffer size should be UUID_FMT_LEN + 1 bytes. Add a
define for this size and use it where required.

Cc: Fam Zheng <fam@euphon.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: "Denis V. Lunev" <den@openvz.org>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit 721da0396c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-09 16:39:13 +03:00
Peter Maydell
155856d890 target/arm: Correctly propagate stage 1 BTI guarded bit in a two-stage walk
In a two-stage translation, the result of the BTI guarded bit should
be the guarded bit from the first stage of translation, as there is
no BTI guard information in stage two.  Our code tried to do this,
but got it wrong, because we currently have two fields where the GP
bit information might live (ARMCacheAttrs::guarded and
CPUTLBEntryFull::extra::arm::guarded), and we were storing the GP bit
in the latter during the stage 1 walk but trying to copy the former
in combine_cacheattrs().

Remove the duplicated storage, and always use the field in
CPUTLBEntryFull; correctly propagate the stage 1 value to the output
in get_phys_addr_twostage().

Note for stable backports: in v8.0 and earlier the field is named
result->f.guarded, not result->f.extra.arm.guarded.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1950
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20231031173723.26582-1-peter.maydell@linaro.org
(cherry picked from commit 4c09abeae8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: replace f.extra.arm.guarded -> f.guarded due to v8.1.0-1179-ga81fef4b64)
2023-11-09 16:39:13 +03:00
Richard Henderson
baf28675da target/arm: Fix SVE STR increment
The previous change missed updating one of the increments and
one of the MemOps.  Add a test case for all vector lengths.

Cc: qemu-stable@nongnu.org
Fixes: e6dd5e782b ("target/arm: Use tcg_gen_qemu_{ld, st}_i128 in gen_sve_{ld, st}r")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231031143215.29764-1-richard.henderson@linaro.org
[PMM: fixed checkpatch nit]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit b11293c212)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: context fix in tests/tcg/aarch64/Makefile.target)
Tested-by: Alex Bennée <alex.bennee@linaro.org>
2023-11-09 16:38:51 +03:00
Andrey Drobyshev
b7867c8262 qemu-iotests: 024: add rebasing test case for overlay_size > backing_size
Before previous commit, rebase was getting infitely stuck in case of
rebasing within the same backing chain and when overlay_size > backing_size.
Let's add this case to the rebasing test 024 to make sure it doesn't
break again.

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Message-ID: <20230919165804.439110-3-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 827171c318)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-01 13:01:44 +03:00
Andrey Drobyshev
bd8d9c618a qemu-img: rebase: stop when reaching EOF of old backing file
In case when we're rebasing within one backing chain, and when target image
is larger than old backing file, bdrv_is_allocated_above() ends up setting
*pnum = 0.  As a result, target offset isn't getting incremented, and we
get stuck in an infinite for loop.  Let's detect this case and proceed
further down the loop body, as the offsets beyond the old backing size need
to be explicitly zeroed.

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Message-ID: <20230919165804.439110-2-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8b097fd6b0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-01 13:01:33 +03:00
Akihiko Odaki
de18cbdaf2 tests/tcg: Add -fno-stack-protector
A build of GCC 13.2 will have stack protector enabled by default if it
was configured with --enable-default-ssp option. For such a compiler,
it is necessary to explicitly disable stack protector when linking
without standard libraries.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-Id: <20230731091042.139159-3-akihiko.odaki@daynix.com>
[AJB: fix comment string typo]
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231029145033.592566-3-alex.bennee@linaro.org>
(cherry picked from commit 580731dcc8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-01 12:59:22 +03:00
Kevin Wolf
3a2d501916 block: Fix locking in media change monitor commands
blk_insert_bs() requires that the caller holds the AioContext lock for
the node to be inserted. Since commit c066e808e1, neglecting to do so
causes a crash when the child has to be moved to a different AioContext
to attach it to the BlockBackend.

This fixes qmp_blockdev_insert_anon_medium(), which is called for the
QMP commands 'blockdev-insert-medium' and 'blockdev-change-medium', to
correctly take the lock.

Cc: qemu-stable@nongnu.org
Fixes: https://issues.redhat.com/browse/RHEL-3922
Fixes: c066e808e1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20231013153302.39234-2-kwolf@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit fed8245015)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-11-01 12:51:23 +03:00
Glenn Miles
b938418f0d misc/led: LED state is set opposite of what is expected
Testing of the LED state showed that when the LED polarity was
set to GPIO_POLARITY_ACTIVE_LOW and a low logic value was set on
the input GPIO of the LED, the LED was being turn off when it was
expected to be turned on.

Fixes: ddb67f6402 ("hw/misc/led: Allow connecting from GPIO output")
Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
Message-id: 20231024191945.4135036-1-milesg@linux.vnet.ibm.com
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 6f83dc6716)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-31 20:35:06 +03:00
Peter Maydell
143352cd7d target/arm: Fix syndrome for FGT traps on ERET
In commit 442c9d682c when we converted the ERET, ERETAA, ERETAB
instructions to decodetree, the conversion accidentally lost the
correct setting of the syndrome register when taking a trap because
of the FEAT_FGT HFGITR_EL1.ERET bit.  Instead of reporting a correct
full syndrome value with the EC and IL bits, we only reported the low
two bits of the syndrome, because the call to syn_erettrap() got
dropped.

Fix the syndrome values for these traps by reinstating the
syn_erettrap() calls.

Fixes: 442c9d682c ("target/arm: Convert ERET, ERETAA, ERETAB to decodetree")
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20231024172438.2990945-1-peter.maydell@linaro.org
(cherry picked from commit 307521d6e2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-31 20:33:33 +03:00
Richard Henderson
fd4ce7455f target/sparc: Clear may_lookup for npc == DYNAMIC_PC
With pairs of jmp+rett, pc == DYNAMIC_PC_LOOKUP and
npc == DYNAMIC_PC.  Make sure that we exit for interrupts.

Cc: qemu-stable@nongnu.org
Fixes: 633c42834c ("target/sparc: Introduce DYNAMIC_PC_LOOKUP")
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 930f1865cc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-29 10:14:02 +03:00
Peter Maydell
28facf1598 hw/rdma/vmw/pvrdma_cmd: Use correct struct in query_port()
In query_port() we pass the address of a local pvrdma_port_attr
struct to the rdma_query_backend_port() function.  Unfortunately,
rdma_backend_query_port() wants a pointer to a struct ibv_port_attr,
and the two are not the same length.

Coverity spotted this (CID 1507146): pvrdma_port_attr is 48 bytes
long, and ibv_port_attr is 52 bytes, because it has a few extra
fields at the end.

Fortunately, all we do with the attrs struct after the call is to
read a few specific fields out of it which are all at the same
offsets in both structs, so we can simply make the local variable the
correct type.  This also lets us drop the cast (which should have
been a bit of a warning flag that we were doing something wrong
here).

We do however need to add extra casts for the fields of the
struct that are enums: clang will complain about the implicit
cast to a different enum type otherwise.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 4ab9a7429b)
2023-10-24 09:14:34 +03:00
Lu Gao
fdeedb886a hw/sd/sdhci: Block Size Register bits [14:12] is lost
Block Size Register bits [14:12] is SDMA Buffer Boundary, it is missed
in register write, but it is needed in SDMA transfer. e.g. it will be
used in sdhci_sdma_transfer_multi_blocks to calculate boundary_ variables.

Missing this field will cause wrong operation for different SDMA Buffer
Boundary settings.

Fixes: d7dfca0807 ("hw/sdhci: introduce standard SD host controller")
Fixes: dfba99f17f ("hw/sdhci: Fix DMA Transfer Block Size field")
Signed-off-by: Lu Gao <lu.gao@verisilicon.com>
Signed-off-by: Jianxian Wen <jianxian.wen@verisilicon.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-ID: <20220321055618.4026-1-lu.gao@verisilicon.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit ae5f70baf5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-24 09:12:45 +03:00
Michal Orzel
31c6d1d654 target/arm: Fix CNTPCT_EL0 trapping from EL0 when HCR_EL2.E2H is 0
On an attempt to access CNTPCT_EL0 from EL0 using a guest running on top
of Xen, a trap from EL2 was observed which is something not reproducible
on HW (also, Xen does not trap accesses to physical counter).

This is because gt_counter_access() checks for an incorrect bit (1
instead of 0) of CNTHCTL_EL2 if HCR_EL2.E2H is 0 and access is made to
physical counter. Refer ARM ARM DDI 0487J.a, D19.12.2:
When HCR_EL2.E2H is 0:
 - EL1PCTEN, bit [0]: refers to physical counter
 - EL1PCEN, bit [1]: refers to physical timer registers

Drop entire block "if (hcr & HCR_E2H) {...} else {...}" from EL0 case
and fall through to EL1 case, given that after fixing checking for the
correct bit, the handling is the same.

Fixes: 5bc8437136 ("target/arm: Update timer access for VHE")
Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Tested-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Message-id: 20230928094404.20802-1-michal.orzel@amd.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit d01448c79d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-21 10:24:58 +03:00
Helge Deller
59ee12a961 lasips2: LASI PS/2 devices are not user-createable
Those PS/2 ports are created with the LASI controller when
a 32-bit PA-RISC machine is created.

Mark them not user-createable to avoid showing them in
the qemu device list.

Signed-off-by: Helge Deller <deller@gmx.de>
Cc: qemu-stable@nongnu.org
(cherry picked from commit a1e6a5c462)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-21 10:22:02 +03:00
Mikulas Patocka
1e4c468ec7 linux-user/sh4: Fix crashes on signal delivery
sh4 uses gUSA (general UserSpace Atomicity) to provide atomicity on CPUs
that don't have atomic instructions. A gUSA region that adds 1 to an
atomic variable stored in @R2 looks like this:

  4004b6:       03 c7           mova    4004c4 <gusa+0x10>,r0
  4004b8:       f3 61           mov     r15,r1
  4004ba:       09 00           nop
  4004bc:       fa ef           mov     #-6,r15
  4004be:       22 63           mov.l   @r2,r3
  4004c0:       01 73           add     #1,r3
  4004c2:       32 22           mov.l   r3,@r2
  4004c4:       13 6f           mov     r1,r15

R0 contains a pointer to the end of the gUSA region
R1 contains the saved stack pointer
R15 contains negative length of the gUSA region

When this region is interrupted by a signal, the kernel detects if
R15 >= -128U. If yes, the kernel rolls back PC to the beginning of the
region and restores SP by copying R1 to R15.

The problem happens if we are interrupted by a signal at address 4004c4.
R15 still holds the value -6, but the atomic value was already written by
an instruction at address 4004c2. In this situation we can't undo the
gUSA. The function unwind_gusa does nothing, the signal handler attempts
to push a signal frame to the address -6 and crashes.

This patch fixes it, so that if we are interrupted at the last instruction
in a gUSA region, we copy R1 to R15 to restore the correct stack pointer
and avoid crashing.

There's another bug: if we are interrupted in a delay slot, we save the
address of the instruction in the delay slot. We must save the address of
the previous instruction.

Cc: qemu-stable@nongnu.org
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reviewed-by: Yoshinori Sato <ysato@users.sourcefoege.jp>
Message-Id: <b16389f7-6c62-70b7-59b3-87533c0bcc@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 3b894b699c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 21:59:58 +03:00
Mikulas Patocka
814f91d679 linux-user/mips: fix abort on integer overflow
QEMU mips userspace emulation crashes with "qemu: unhandled CPU exception
0x15 - aborting" when one of the integer arithmetic instructions detects
an overflow.

This patch fixes it so that it delivers SIGFPE with FPE_INTOVF instead.

Cc: qemu-stable@nongnu.org
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Message-Id: <3ef979a8-3ee1-eb2d-71f7-d788ff88dd11@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 6fad9b4bb9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 21:59:58 +03:00
Richard Henderson
e73f57b1b5 linux-user: Fixes for zero_bss
The previous change, 2d385be615, assumed !PAGE_VALID meant that
the page would be unmapped by the elf image.  However, since we
reserved the entire image space via mmap, PAGE_VALID will always
be set.  Instead, assume PROT_NONE for the same condition.

Furthermore, assume bss is only ever present for writable segments,
and that there is no page overlap between PT_LOAD segments.
Instead of an assert, return false to indicate failure.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1854
Fixes: 2d385be615 ("linux-user: Do not adjust zero_bss for host page size")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit e6e66b0328)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 21:58:31 +03:00
Paolo Bonzini
71452f87c9 tracetool: avoid invalid escape in Python string
This is an error in Python 3.12; fix it by using a raw string literal.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e6d8e5e6e3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Paolo Bonzini
791cbfeec2 tests/vm: avoid invalid escape in Python string
This is an error in Python 3.12; fix it by using a raw string literal
or by double-escaping the backslash.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 86a8989d45)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Paolo Bonzini
6dbb538a71 tests/avocado: avoid invalid escape in Python string
This is an error in Python 3.12; fix it by using a raw string literal.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 1b5f3f65cc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Paolo Bonzini
7a04747125 target/hexagon: avoid invalid escape in Python string
This is an error in Python 3.12; fix it by using a raw string literal.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e41c40d101)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Paolo Bonzini
23b0010786 docs/sphinx: avoid invalid escape in Python string
This is an error in Python 3.12; fix it by using a raw string literal.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e4b6532cc0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Paolo Bonzini
adbbddf90b tests/docker: avoid invalid escape in Python string
This is an error in Python 3.12; fix it by using a raw string literal.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a5e3cb3b90)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
John Snow
663aca79f9 python/qmp: remove Server.wait_closed() call for Python 3.12
This patch is a backport from
e03a3334b6

According to Guido in https://github.com/python/cpython/issues/104344 ,
this call was never meant to wait for the server to shut down - that is
handled synchronously - but instead, this waits for all connections to
close. Or, it would have, if it wasn't broken since it was introduced.

3.12 fixes the bug, which now causes a hang in our code. The fix is just
to remove the wait.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-id: 20231006195243.3131140-3-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit acf873873a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Juan Quintela
95b3854bf7 migration: Non multifd migration don't care about multifd flushes
RDMA was having trouble because
migrate_multifd_flush_after_each_section() can only be true or false,
but we don't want to send any flush when we are not in multifd
migration.

CC: Fabiano Rosas <farosas@suse.de
Fixes: 294e5a4034 ("multifd: Only flush once each full round of memory")

Reported-by: Li Zhijian <lizhijian@fujitsu.com>
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Message-ID: <20231011205548.10571-2-quintela@redhat.com>
(cherry picked from commit d4f34485ca)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Fabiano Rosas
9285589334 migration: Fix analyze-migration read operation signedness
The migration code uses unsigned values for 16, 32 and 64-bit
operations. Fix the script to do the same.

This was causing an issue when parsing the migration stream generated
on the ppc64 target because one of instance_ids was larger than the
32bit signed maximum:

Traceback (most recent call last):
  File "/home/fabiano/kvm/qemu/build/scripts/analyze-migration.py", line 658, in <module>
    dump.read(dump_memory = args.memory)
  File "/home/fabiano/kvm/qemu/build/scripts/analyze-migration.py", line 592, in read
    classdesc = self.section_classes[section_key]
KeyError: ('spapr_iommu', -2147483648)

Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Message-ID: <20231009184326.15777-6-farosas@suse.de>
(cherry picked from commit caea03279e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Yuval Shaia
af566ccb38 hw/pvrdma: Protect against buggy or malicious guest driver
Guest driver allocates and initialize page tables to be used as a ring
of descriptors for CQ and async events.
The page table that represents the ring, along with the number of pages
in the page table is passed to the device.
Currently our device supports only one page table for a ring.

Let's make sure that the number of page table entries the driver
reports, do not exceeds the one page table size.

Reported-by: Soul Chen <soulchen8650@gmail.com>
Signed-off-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Fixes: CVE-2023-1544
Message-ID: <20230301142926.18686-1-yuval.shaia.ml@gmail.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 85fc35afa9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-19 14:52:59 +03:00
Michael Tokarev
78385bc738 Update version for 8.1.2 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-16 15:33:32 +03:00
Max Chou
cc33ee45d6 target/riscv: Fix vfwmaccbf16.vf
The operator (fwmacc16) of vfwmaccbf16.vf helper function should be
replaced by fwmaccbf16.

Fixes: adf772b0f7 ("target/riscv: Add support for Zvfbfwma extension")
Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20231005095734.567575-1-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 837570cef2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-13 18:22:57 +03:00
Alvin Chang
a8c0d82f7b disas/riscv: Fix the typo of inverted order of pmpaddr13 and pmpaddr14
Fix the inverted order of pmpaddr13 and pmpaddr14 in csr_name().

Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20230907084500.328-1-alvinga@andestech.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit cffa995490)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-13 18:20:59 +03:00
Olaf Hering
2e42ba01f1 roms: use PYTHON to invoke python
python3 may not be the expected python version.
Use PYTHON to invoke python.

Fixes: 22e11539e1 ("edk2: replace build scripts")

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 17b8d8ac33)
2023-10-13 18:18:25 +03:00
Volker Rümelin
5dddba9f38 hw/audio/es1370: reset current sample counter
Reset the current sample counter when writing the Channel Sample
Count Register. The Linux ens1370 driver and the AROS sb128
driver expect the current sample counter counts down from sample
count to 0 after a write to the Channel Sample Count Register.
Currently the current sample counter starts from 0 after a reset
or the last count when the counter was stopped.

The current sample counter is used to raise an interrupt whenever
a complete buffer was transferred. When the counter starts with a
value lower than the reload value, the interrupt triggeres before
the buffer was completly transferred. This may lead to corrupted
audio streams.

Tested-by: Rene Engel <ReneEngel80@emailn.de>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-Id: <20230917065813.6692-1-vr_qemu@t-online.de>
(cherry picked from commit 00e3b29d06)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-12 01:10:13 +03:00
Peter Xu
b6170717ea migration/qmp: Fix crash on setting tls-authz with null
QEMU will crash if anyone tries to set tls-authz (which is a type
StrOrNull) with 'null' value.  Fix it in the easy way by converting it to
qstring just like the other two tls parameters.

Cc: qemu-stable@nongnu.org # v4.0+
Fixes: d2f1d29b95 ("migration: add support for a "tls-authz" migration parameter")
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Message-ID: <20230905162335.235619-2-peterx@redhat.com>
(cherry picked from commit 86dec715a7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-12 00:57:19 +03:00
Fiona Ebner
d8b9e0c8bc util/log: re-allow switching away from stderr log file
Commit 59bde21374 ("util/log: do not close and reopen log files when
flags are turned off") prevented switching away from stderr on a
subsequent invocation of qemu_set_log_internal(). This prevented
switching away from stderr with the 'logfile' monitor command as well
as an invocation like
> ./qemu-system-x86_64 -trace 'qemu_mutex_lock,file=log'
from opening the specified log file.

Fixes: 59bde21374 ("util/log: do not close and reopen log files when flags are turned off")
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20231004124446.491481-1-f.ebner@proxmox.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f05142d511)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-10 07:41:01 +03:00
Alex Williamson
0f1d63d824 vfio/display: Fix missing update to set backing fields
The below referenced commit renames scanout_width/height to
backing_width/height, but also promotes these fields in various portions
of the egl interface.  Meanwhile vfio dmabuf support has never used the
previous scanout fields and is therefore missed in the update.  This
results in a black screen when transitioning from ramfb to dmabuf display
when using Intel vGPU with these features.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1891
Link: https://lists.gnu.org/archive/html/qemu-devel/2023-08/msg02726.html
Fixes: 9ac06df8b6 ("virtio-gpu-udmabuf: correct naming of QemuDmaBuf size properties")
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit 931150e56b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-10 07:37:45 +03:00
Akihiko Odaki
2adbc3b1e5 amd_iommu: Fix APIC address check
An MSI from I/O APIC may not exactly equal to APIC_DEFAULT_ADDRESS. In
fact, Windows 17763.3650 configures I/O APIC to set the dest_mode bit.
Cover the range assigned to APIC.

Fixes: 577c470f43 ("x86_iommu/amd: Prepare for interrupt remap support")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-Id: <20230921114612.40671-1-akihiko.odaki@daynix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 0114c45130)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-06 15:36:37 +03:00
Eugenio Pérez
fe3afc06fa vdpa net: follow VirtIO initialization properly at cvq isolation probing
This patch solves a few issues.  The most obvious is that the feature
set was done previous to ACKNOWLEDGE | DRIVER status bit set.  Current
vdpa devices are permissive with this, but it is better to follow the
standard.

Fixes: 152128d646 ("vdpa: move CVQ isolation check to net_init_vhost_vdpa")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230915170836.3078172-4-eperezma@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 845ec38ae1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-06 15:35:44 +03:00
Eugenio Pérez
e6d9dd102d vdpa net: stop probing if cannot set features
Otherwise it continues the CVQ isolation probing.

Fixes: 152128d646 ("vdpa: move CVQ isolation check to net_init_vhost_vdpa")
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230915170836.3078172-3-eperezma@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit f1085882d0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-06 15:34:39 +03:00
Eugenio Pérez
197cc86a12 vdpa net: fix error message setting virtio status
It incorrectly prints "error setting features", probably because a copy
paste miss.

Fixes: 152128d646 ("vdpa: move CVQ isolation check to net_init_vhost_vdpa")
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230915170836.3078172-2-eperezma@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit cbc9ae87b5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-06 15:34:08 +03:00
Eugenio Pérez
809d5995c8 vdpa net: zero vhost_vdpa iova_tree pointer at cleanup
Not zeroing it causes a SIGSEGV if the live migration is cancelled, at
net device restart.

This is caused because CVQ tries to reuse the iova_tree that is present
in the first vhost_vdpa device at the end of vhost_vdpa_net_cvq_start.
As a consequence, it tries to access an iova_tree that has been already
free.

Fixes: 00ef422e9f ("vdpa net: move iova tree creation from init to start")
Reported-by: Yanhui Ma <yama@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230913123408.2819185-1-eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 0a7a164bc3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-06 15:32:41 +03:00
Richard Henderson
2990ba5471 linux-user/hppa: Fix struct target_sigcontext layout
Use abi_ullong not uint64_t so that the alignment of the field
and therefore the layout of the struct is correct.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 33bc4fa78b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-06 15:29:15 +03:00
Thomas Huth
19159a7f01 chardev/char-pty: Avoid losing bytes when the other side just (re-)connected
When starting a guest via libvirt with "virsh start --console ...",
the first second of the console output is missing. This is especially
annoying on s390x that only has a text console by default and no graphical
output - if the bios fails to boot here, the information about what went
wrong is completely lost.

One part of the problem (there is also some things to be done on the
libvirt side) is that QEMU only checks with a 1 second timer whether
the other side of the pty is already connected, so the first second of
the console output is always lost.

This likely used to work better in the past, since the code once checked
for a re-connection during write, but this has been removed in commit
f8278c7d74 ("char-pty: remove the check for connection on write") to avoid
some locking.

To ease the situation here at least a little bit, let's check with g_poll()
whether we could send out the data anyway, even if the connection has not
been marked as "connected" yet. The file descriptor is marked as non-blocking
anyway since commit fac6688a18 ("Do not hang on full PTY"), so this should
not cause any trouble if the other side is not ready for receiving yet.

With this patch applied, I can now successfully see the bios output of
a s390x guest when running it with "virsh start --console" (with a patched
version of virsh that fixes the remaining issues there, too).

Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20230816210743.1319018-1-thuth@redhat.com>
(cherry picked from commit 4f7689f081)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-05 08:46:05 +03:00
Laszlo Ersek
7771e35b39 hw/display/ramfb: plug slight guest-triggerable leak on mode setting
The fw_cfg DMA write callback in ramfb prepares a new display surface in
QEMU; this new surface is put to use ("swapped in") upon the next display
update. At that time, the old surface (if any) is released.

If the guest triggers the fw_cfg DMA write callback at least twice between
two adjacent display updates, then the second callback (and further such
callbacks) will leak the previously prepared (but not yet swapped in)
display surface.

The issue can be shown by:

(1) starting QEMU with "-trace displaysurface_free", and

(2) running the following program in the guest UEFI shell:

> #include <Library/ShellCEntryLib.h>           // ShellAppMain()
> #include <Library/UefiBootServicesTableLib.h> // gBS
> #include <Protocol/GraphicsOutput.h>          // EFI_GRAPHICS_OUTPUT_PROTOCOL
>
> INTN
> EFIAPI
> ShellAppMain (
>   IN UINTN   Argc,
>   IN CHAR16  **Argv
>   )
> {
>   EFI_STATUS                    Status;
>   VOID                          *Interface;
>   EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop;
>   UINT32                        Mode;
>
>   Status = gBS->LocateProtocol (
>                   &gEfiGraphicsOutputProtocolGuid,
>                   NULL,
>                   &Interface
>                   );
>   if (EFI_ERROR (Status)) {
>     return 1;
>   }
>
>   Gop = Interface;
>
>   Mode = 1;
>   for ( ; ;) {
>     Status = Gop->SetMode (Gop, Mode);
>     if (EFI_ERROR (Status)) {
>       break;
>     }
>
>     Mode = 1 - Mode;
>   }
>
>   return 1;
> }

The symptom is then that:

- only one trace message appears periodically,

- the time between adjacent messages keeps increasing -- implying that
  some list structure (containing the leaked resources) keeps growing,

- the "surface" pointer is ever different.

> 18566@1695127471.449586:displaysurface_free surface=0x7f2fcc09a7c0
> 18566@1695127471.529559:displaysurface_free surface=0x7f2fcc9dac10
> 18566@1695127471.659812:displaysurface_free surface=0x7f2fcc441dd0
> 18566@1695127471.839669:displaysurface_free surface=0x7f2fcc0363d0
> 18566@1695127472.069674:displaysurface_free surface=0x7f2fcc413a80
> 18566@1695127472.349580:displaysurface_free surface=0x7f2fcc09cd00
> 18566@1695127472.679783:displaysurface_free surface=0x7f2fcc1395f0
> 18566@1695127473.059848:displaysurface_free surface=0x7f2fcc1cae50
> 18566@1695127473.489724:displaysurface_free surface=0x7f2fcc42fc50
> 18566@1695127473.969791:displaysurface_free surface=0x7f2fcc45dcc0
> 18566@1695127474.499708:displaysurface_free surface=0x7f2fcc70b9d0
> 18566@1695127475.079769:displaysurface_free surface=0x7f2fcc82acc0
> 18566@1695127475.709941:displaysurface_free surface=0x7f2fcc369c00
> 18566@1695127476.389619:displaysurface_free surface=0x7f2fcc32b910
> 18566@1695127477.119772:displaysurface_free surface=0x7f2fcc0d5a20
> 18566@1695127477.899517:displaysurface_free surface=0x7f2fcc086c40
> 18566@1695127478.729962:displaysurface_free surface=0x7f2fccc72020
> 18566@1695127479.609839:displaysurface_free surface=0x7f2fcc185160
> 18566@1695127480.539688:displaysurface_free surface=0x7f2fcc23a7e0
> 18566@1695127481.519759:displaysurface_free surface=0x7f2fcc3ec870
> 18566@1695127482.549930:displaysurface_free surface=0x7f2fcc634960
> 18566@1695127483.629661:displaysurface_free surface=0x7f2fcc26b140
> 18566@1695127484.759987:displaysurface_free surface=0x7f2fcc321700
> 18566@1695127485.940289:displaysurface_free surface=0x7f2fccaad100

We figured this wasn't a CVE-worthy problem, as only small amounts of
memory were leaked (the framebuffer itself is mapped from guest RAM, QEMU
only allocates administrative structures), plus libvirt restricts QEMU
memory footprint anyway, thus the guest can only DoS itself.

Plug the leak, by releasing the last prepared (not yet swapped in) display
surface, if any, in the fw_cfg DMA write callback.

Regarding the "reproducer", with the fix in place, the log is flooded with
trace messages (one per fw_cfg write), *and* the trace message alternates
between just two "surface" pointer values (i.e., nothing is leaked, the
allocator flip-flops between two objects in effect).

This issue appears to date back to the introducion of ramfb (995b30179b,
"hw/display: add ramfb, a simple boot framebuffer living in guest ram",
2018-06-18).

Cc: Gerd Hoffmann <kraxel@redhat.com> (maintainer:ramfb)
Cc: qemu-stable@nongnu.org
Fixes: 995b30179b
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20230919131955.27223-1-lersek@redhat.com>
(cherry picked from commit e0288a7784)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-05 08:44:22 +03:00
Marc-André Lureau
ab6314506d win32: avoid discarding the exception handler
In all likelihood, the compiler with lto doesn't see the function being
used, from assembly macro __try1. Help it by marking the function has
being used.

Resolves:
https://gitlab.com/qemu-project/qemu/-/issues/1904

Fixes: commit d89f30b4df ("win32: wrap socket close() with an exception handler")

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 75b773d84c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(mjt: trivial context fixup in include/qemu/compiler.h)
2023-10-05 08:42:38 +03:00
Paolo Bonzini
1e5839828d target/i386: fix memory operand size for CVTPS2PD
CVTPS2PD only loads a half-register for memory, unlike the other
operations under 0x0F 0x5A.  "Unpack" the group into separate
emission functions instead of using gen_unary_fp_sse.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit abd41884c5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-04 17:34:46 +03:00
Paolo Bonzini
db2d4bcb8e target/i386: generalize operand size "ph" for use in CVTPS2PD
CVTPS2PD only loads a half-register for memory, like CVTPH2PS.  It can
reuse the "ph" packed half-precision size to load a half-register,
but rename it to "xh" because it is now a variation of "x" (it is not
used only for half-precision values).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a48b26978a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-04 17:34:30 +03:00
Thomas Huth
6831048324 subprojects/berkeley-testfloat-3: Update to fix a problem with compiler warnings
Update the berkeley-testfloat-3 wrap to include a patch provided by
Olaf Hering. This fixes a problem with "control reaches end of non-void
function [-Werror=return-type]" compiler warning/errors that are now
enabled by default in certain versions of GCC.

Reported-by: Olaf Hering <olaf@aepfle.de>
Message-Id: <20230816091522.1292029-1-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit c01196bddd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-04 11:45:08 +03:00
Mark Cave-Ayland
f9f1d0906b scsi-disk: ensure that FORMAT UNIT commands are terminated
Otherwise when a FORMAT UNIT command is issued, the SCSI layer can become
confused because it can find itself in the situation where it thinks there
is still data to be transferred which can cause the next emulated SCSI
command to fail.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: 6ab71761 ("scsi-disk: add FORMAT UNIT command")
Tested-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20230913204410.65650-4-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit be2b619a17)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 18:25:13 +03:00
Mark Cave-Ayland
e855a6ec51 esp: restrict non-DMA transfer length to that of available data
In the case where a SCSI layer transfer is incorrectly terminated, it is
possible for a TI command to cause a SCSI buffer overflow due to the
expected transfer data length being less than the available data in the
FIFO. When this occurs the unsigned async_len variable underflows and
becomes a large offset which writes past the end of the allocated SCSI
buffer.

Restrict the non-DMA transfer length to be the smallest of the expected
transfer length and the available FIFO data to ensure that it is no longer
possible for the SCSI buffer overflow to occur.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1810
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20230913204410.65650-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 77668e4b9b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 18:25:13 +03:00
Mark Cave-Ayland
8194d5827e esp: use correct type for esp_dma_enable() in sysbus_esp_gpio_demux()
The call to esp_dma_enable() was being made with the SYSBUS_ESP type instead of
the ESP type. This meant that when GPIO 1 was being used to trigger a DMA
request from an external DMA controller, the setting of ESPState's dma_enabled
field would clobber unknown memory whilst the dma_cb callback pointer would
typically return NULL so the DMA request would never start.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20230913204410.65650-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b86dc5cb0b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 18:25:13 +03:00
Fabiano Rosas
ee7ce8a949 optionrom: Remove build-id section
Our linker script for optionroms specifies only the placement of the
.text section, leaving the linker free to place the remaining sections
at arbitrary places in the file.

Since at least binutils 2.39, the .note.gnu.build-id section is now
being placed at the start of the file, which causes label addresses to
be shifted. For linuxboot_dma.bin that means that the PnP header
(among others) will not be found when determining the type of ROM at
optionrom_setup():

(0x1c is the label _pnph, where the magic "PnP" is)

$ xxd /usr/share/qemu/linuxboot_dma.bin | grep "PnP"
00000010: 0000 0000 0000 0000 0000 1c00 2450 6e50  ............$PnP

$ xxd pc-bios/optionrom/linuxboot_dma.bin | grep "PnP"
00000010: 0000 0000 0000 0000 0000 4c00 2450 6e50  ............$PnP
                                   ^bad

Using a freshly built linuxboot_dma.bin ROM results in a broken boot:

  SeaBIOS (version rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org)
  Booting from Hard Disk...
  Boot failed: could not read the boot disk

  Booting from Floppy...
  Boot failed: could not read the boot disk

  No bootable device.

We're not using the build-id section, so pass the --build-id=none
option to the linker to remove it entirely.

Note: In theory, this same issue could happen with any other
section. The ideal solution would be to have all unused sections
discarded in the linker script. However that would be a larger change,
specially for the pvh rom which uses the .bss and COMMON sections so
I'm addressing only the immediate issue here.

Reported-by: Vasiliy Ulyanov <vulyanov@suse.de>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20230926192502.15986-1-farosas@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 35ed01ba54)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(mjt: remove unrelated stable@vger)
2023-10-03 18:21:13 +03:00
Bastian Koppelmann
d1b867cca6 target/tricore: Fix RCPW/RRPW_INSERT insns for width = 0
we would crash if width was 0 for these insns, as tcg_gen_deposit() is
undefined for that case. For TriCore, width = 0 is a mov from the src reg
to the dst reg, so we special case this here.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Message-ID: <20230828112651.522058-9-kbastian@mail.uni-paderborn.de>
(cherry picked from commit 23fa6f56b3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:05:55 +03:00
Richard Henderson
9fb45b0558 accel/tcg: Always require can_do_io
Require i/o as the last insn of a TranslationBlock always,
not only with icount.  This is required for i/o that alters
the address space, such as a pci config space write.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1866
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 18a536f1f8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:01:36 +03:00
Richard Henderson
d6cca99ecd accel/tcg: Always set CF_LAST_IO with CF_NOIRQ
Without this we can get see loops through cpu_io_recompile,
in which the cpu makes no progress.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 200c1f904f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:01:36 +03:00
Richard Henderson
6c2e2e4f77 accel/tcg: Improve setting of can_do_io at start of TB
Initialize can_do_io to true if this the TB has CF_LAST_IO
and will consist of a single instruction.  This avoids a
set to 0 followed immediately by a set to 1.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit a2f99d484c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:01:36 +03:00
Richard Henderson
a98097d3a9 accel/tcg: Track current value of can_do_io in the TB
Simplify translator_io_start by recording the current
known value of can_do_io within DisasContextBase.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 0ca41ccf1c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:01:36 +03:00
Richard Henderson
de11111ee8 accel/tcg: Hoist CF_MEMI_ONLY check outside translation loop
The condition checked is loop invariant; check it only once.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 5d97e94638)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:01:36 +03:00
Richard Henderson
837ca790c6 accel/tcg: Avoid load of icount_decr if unused
With CF_NOIRQ and without !CF_USE_ICOUNT, the load isn't used.
Avoid emitting it.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit f47a90dacc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:01:36 +03:00
Richard Henderson
d9ec18a0fc softmmu: Use async_run_on_cpu in tcg_commit
After system startup, run the update to memory_dispatch
and the tlb_flush on the cpu.  This eliminates a race,
wherein a running cpu sees the memory_dispatch change
but has not yet seen the tlb_flush.

Since the update now happens on the cpu, we need not use
qatomic_rcu_read to protect the read of memory_dispatch.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1826
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1834
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1846
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 0d58c66068)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabiano Rosas
4ade907b30 migration: Move return path cleanup to main migration thread
Now that the return path thread is allowed to finish during a paused
migration, we can move the cleanup of the QEMUFiles to the main
migration thread.

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-9-farosas@suse.de>
(cherry picked from commit 36e9aab3c5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabiano Rosas
dec7785fab migration: Replace the return path retry logic
Replace the return path retry logic with finishing and restarting the
thread. This fixes a race when resuming the migration that leads to a
segfault.

Currently when doing postcopy we consider that an IO error on the
return path file could be due to a network intermittency. We then keep
the thread alive but have it do cleanup of the 'from_dst_file' and
wait on the 'postcopy_pause_rp' semaphore. When the user issues a
migrate resume, a new return path is opened and the thread is allowed
to continue.

There's a race condition in the above mechanism. It is possible for
the new return path file to be setup *before* the cleanup code in the
return path thread has had a chance to run, leading to the *new* file
being closed and the pointer set to NULL. When the thread is released
after the resume, it tries to dereference 'from_dst_file' and crashes:

Thread 7 "return path" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd1dbf700 (LWP 9611)]
0x00005555560e4893 in qemu_file_get_error_obj (f=0x0, errp=0x0) at ../migration/qemu-file.c:154
154         return f->last_error;

(gdb) bt
 #0  0x00005555560e4893 in qemu_file_get_error_obj (f=0x0, errp=0x0) at ../migration/qemu-file.c:154
 #1  0x00005555560e4983 in qemu_file_get_error (f=0x0) at ../migration/qemu-file.c:206
 #2  0x0000555555b9a1df in source_return_path_thread (opaque=0x555556e06000) at ../migration/migration.c:1876
 #3  0x000055555602e14f in qemu_thread_start (args=0x55555782e780) at ../util/qemu-thread-posix.c:541
 #4  0x00007ffff38d76ea in start_thread (arg=0x7fffd1dbf700) at pthread_create.c:477
 #5  0x00007ffff35efa6f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Here's the race (important bit is open_return_path happening before
migration_release_dst_files):

migration                 | qmp                         | return path
--------------------------+-----------------------------+---------------------------------
			    qmp_migrate_pause()
			     shutdown(ms->to_dst_file)
			      f->last_error = -EIO
migrate_detect_error()
 postcopy_pause()
  set_state(PAUSED)
  wait(postcopy_pause_sem)
			    qmp_migrate(resume)
			    migrate_fd_connect()
			     resume = state == PAUSED
			     open_return_path <-- TOO SOON!
			     set_state(RECOVER)
			     post(postcopy_pause_sem)
							(incoming closes to_src_file)
							res = qemu_file_get_error(rp)
							migration_release_dst_files()
							ms->rp_state.from_dst_file = NULL
  post(postcopy_pause_rp_sem)
							postcopy_pause_return_path_thread()
							  wait(postcopy_pause_rp_sem)
							rp = ms->rp_state.from_dst_file
							goto retry
							qemu_file_get_error(rp)
							SIGSEGV
-------------------------------------------------------------------------------------------

We can keep the retry logic without having the thread alive and
waiting. The only piece of data used by it is the 'from_dst_file' and
it is only allowed to proceed after a migrate resume is issued and the
semaphore released at migrate_fd_connect().

Move the retry logic to outside the thread by waiting for the thread
to finish before pausing the migration.

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-8-farosas@suse.de>
(cherry picked from commit ef796ee93b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabiano Rosas
1ad3fa152c migration: Consolidate return path closing code
We'll start calling the await_return_path_close_on_source() function
from other parts of the code, so move all of the related checks and
tracepoints into it.

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-7-farosas@suse.de>
(cherry picked from commit d50f5dc075)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabiano Rosas
d37260b9f0 migration: Remove redundant cleanup of postcopy_qemufile_src
This file is owned by the return path thread which is already doing
cleanup.

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-6-farosas@suse.de>
(cherry picked from commit b3b101157d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabiano Rosas
73393af917 migration: Fix possible race when shutting down to_dst_file
It's not safe to call qemu_file_shutdown() on the to_dst_file without
first checking for the file's presence under the lock. The cleanup of
this file happens at postcopy_pause() and migrate_fd_cleanup() which
are not necessarily running in the same thread as migrate_fd_cancel().

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-5-farosas@suse.de>
(cherry picked from commit 7478fb0df9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabiano Rosas
f5480c4d82 migration: Fix possible races when shutting down the return path
We cannot call qemu_file_shutdown() on the return path file without
taking the file lock. The return path thread could be running it's
cleanup code and have just cleared the from_dst_file pointer.

Checking ms->to_dst_file for errors could also race with
migrate_fd_cleanup() which clears the to_dst_file pointer.

Protect both accesses by taking the file lock.

This was caught by inspection, it should be rare, but the next patches
will start calling this code from other places, so let's do the
correct thing.

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-4-farosas@suse.de>
(cherry picked from commit 639decf529)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabiano Rosas
cc3a33400c migration: Fix possible race when setting rp_state.error
We don't need to set the rp_state.error right after a shutdown because
qemu_file_shutdown() always sets the QEMUFile error, so the return
path thread would have seen it and set the rp error itself.

Setting the error outside of the thread is also racy because the
thread could clear it after we set it.

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-3-farosas@suse.de>
(cherry picked from commit 28a8347281)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Peter Xu
0b246f8e9e migration: Fix race that dest preempt thread close too early
We hit intermit CI issue on failing at migration-test over the unit test
preempt/plain:

qemu-system-x86_64: Unable to read from socket: Connection reset by peer
Memory content inconsistency at 5b43000 first_byte = bd last_byte = bc current = 4f hit_edge = 1
**
ERROR:../tests/qtest/migration-test.c:300:check_guests_ram: assertion failed: (bad == 0)
(test program exited with status code -6)

Fabiano debugged into it and found that the preempt thread can quit even
without receiving all the pages, which can cause guest not receiving all
the pages and corrupt the guest memory.

To make sure preempt thread finished receiving all the pages, we can rely
on the page_requested_count being zero because preempt channel will only
receive requested page faults. Note, not all the faulted pages are required
to be sent via the preempt channel/thread; imagine the case when a
requested page is just queued into the background main channel for
migration, the src qemu will just still send it via the background channel.

Here instead of spinning over reading the count, we add a condvar so the
main thread can wait on it if that unusual case happened, without burning
the cpu for no good reason, even if the duration is short; so even if we
spin in this rare case is probably fine.  It's just better to not do so.

The condvar is only used when that special case is triggered.  Some memory
ordering trick is needed to guarantee it from happening (against the
preempt thread status field), so the main thread will always get a kick
when that triggers correctly.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/1886
Debugged-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230918172822.19052-2-farosas@suse.de>
(cherry picked from commit cf02f29e1e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Paolo Bonzini
3b86b92bfb ui/vnc: fix handling of VNC_FEATURE_XVP
VNC_FEATURE_XVP was not shifted left before adding it to vs->features,
so it was never enabled; but it was also checked the wrong way with
a logical AND instead of vnc_has_feature.  Fix both places.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 477b301000)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Paolo Bonzini
17f3a6221f ui/vnc: fix debug output for invalid audio message
The debug message was cut and pasted from the invalid audio format
case, but the audio message is at bytes 2-3.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 0cb9c5880e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Thomas Huth
6b7fa3cbab hw/scsi/scsi-disk: Disallow block sizes smaller than 512 [CVE-2023-42467]
We are doing things like

    nb_sectors /= (s->qdev.blocksize / BDRV_SECTOR_SIZE);

in the code here (e.g. in scsi_disk_emulate_mode_sense()), so if
the blocksize is smaller than BDRV_SECTOR_SIZE (=512), this crashes
with a division by 0 exception. Thus disallow block sizes of 256
bytes to avoid this situation.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1813
CVE: 2023-42467
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20230925091854.49198-1-thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7cfcc79b0a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Nicholas Piggin
b9b84b2d41 accel/tcg: mttcg remove false-negative halted assertion
mttcg asserts that an execution ending with EXCP_HALTED must have
cpu->halted. However between the event or instruction that sets
cpu->halted and requests exit and the assertion here, an
asynchronous event could clear cpu->halted.

This leads to crashes running AIX on ppc/pseries because it uses
H_CEDE/H_PROD hcalls, where H_CEDE sets self->halted = 1 and
H_PROD sets other cpu->halted = 0 and kicks it.

H_PROD could be turned into an interrupt to wake, but several other
places in ppc, sparc, and semihosting follow what looks like a similar
pattern setting halted = 0 directly. So remove this assertion.

Reported-by: Ivan Warren <ivan@vmfacility.fr>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20230829010658.8252-1-npiggin@gmail.com>
[rth: Keep the case label and adjust the comment.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 0e5903436d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Thomas Huth
0215e8e872 meson.build: Make keyutils independent from keyring
Commit 0db0fbb5cf ("Add conditional dependency for libkeyutils")
tried to provide a possibility for the user to disable keyutils
if not required by makeing it depend on the keyring feature. This
looked reasonable at a first glance (the unit test in tests/unit/
needs both), but the condition in meson.build fails if the feature
is meant to be detected automatically, and there is also another
spot in backends/meson.build where keyutils is used independently
from keyring. So let's remove the dependency on keyring again and
introduce a proper meson build option instead.

Cc: qemu-stable@nongnu.org
Fixes: 0db0fbb5cf ("Add conditional dependency for libkeyutils")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1842
Message-ID: <20230824094208.255279-1-thuth@redhat.com>
Reviewed-by: "Daniel P. Berrangé" <berrange@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit c64023b0ba)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Peter Maydell
7329cc1c19 target/arm: Don't skip MTE checks for LDRT/STRT at EL0
The LDRT/STRT "unprivileged load/store" instructions behave like
normal ones if executed at EL0. We handle this correctly for
the load/store semantics, but get the MTE checking wrong.

We always look at s->mte_active[is_unpriv] to see whether we should
be doing MTE checks, but in hflags.c when we set the TB flags that
will be used to fill the mte_active[] array we only set the
MTE0_ACTIVE bit if UNPRIV is true (i.e.  we are not at EL0).

This means that a LDRT at EL0 will see s->mte_active[1] as 0,
and will not do MTE checks even when MTE is enabled.

To avoid the translate-time code having to do an explicit check on
s->unpriv to see if it is OK to index into the mte_active[] array,
duplicate MTE_ACTIVE into MTE0_ACTIVE when UNPRIV is false.

(This isn't a very serious bug because generally nobody executes
LDRT/STRT at EL0, because they have no use there.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230912140434.1333369-2-peter.maydell@linaro.org
(cherry picked from commit 903dbefc2b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Fabian Vogt
d0cd94e2b6 hw/arm/boot: Set SCR_EL3.FGTEn when booting kernel
Just like d7ef5e16a1 sets SCR_EL3.HXEn for FEAT_HCX, this commit
handles SCR_EL3.FGTEn for FEAT_FGT:

When we direct boot a kernel on a CPU which emulates EL3, we need to
set up the EL3 system registers as the Linux kernel documentation
specifies:
    https://www.kernel.org/doc/Documentation/arm64/booting.rst

> For CPUs with the Fine Grained Traps (FEAT_FGT) extension present:
> - If EL3 is present and the kernel is entered at EL2:
>   - SCR_EL3.FGTEn (bit 27) must be initialised to 0b1.

Cc: qemu-stable@nongnu.org
Signed-off-by: Fabian Vogt <fvogt@suse.de>
Message-id: 4831384.GXAFRqVoOG@linux-e202.suse.de
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 32b214384e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Anton Johansson
cb6ed2f7f7 include/exec: Widen tlb_hit/tlb_hit_page()
tlb_addr is changed from target_ulong to uint64_t to match the type of
a CPUTLBEntry value, and the addressed is changed to vaddr.

Signed-off-by: Anton Johansson <anjo@rev.ng>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230807155706.9580-8-anjo@rev.ng>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit c78edb5639)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Hanna Czenczek
8a043309ad tests/file-io-error: New test
This is a regression test for
https://bugzilla.redhat.com/show_bug.cgi?id=2234374.

All this test needs to do is trigger an I/O error inside of file-posix
(specifically raw_co_prw()).  One reliable way to do this without
requiring special privileges is to use a FUSE export, which allows us to
inject any error that we want, e.g. via blkdebug.

Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230824155345.109765-6-hreitz@redhat.com>
[hreitz: Fixed test to be skipped when there is no FUSE support, to
         suppress fusermount's allow_other warning, and to be skipped
         with $IMGOPTSSYNTAX enabled]
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
(cherry picked from commit 380448464d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Hanna Czenczek
8ef6104413 file-posix: Simplify raw_co_prw's 'out' zone code
We duplicate the same condition three times here, pull it out to the top
level.

Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230824155345.109765-5-hreitz@redhat.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
(cherry picked from commit d31b50a15d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Hanna Czenczek
31a471430f file-posix: Fix zone update in I/O error path
We must check that zone information is present before running
update_zones_wp().

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2234374
Fixes: Coverity CID 1512459
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230824155345.109765-4-hreitz@redhat.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
(cherry picked from commit deab5c9a4e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Hanna Czenczek
825af96d6a file-posix: Check bs->bl.zoned for zone info
Instead of checking bs->wps or bs->bl.zone_size for whether zone
information is present, check bs->bl.zoned.  That is the flag that
raw_refresh_zoned_limits() reliably sets to indicate zone support.  If
it is set to something other than BLK_Z_NONE, other values and objects
like bs->wps and bs->bl.zone_size must be non-null/zero and valid; if it
is not, we cannot rely on their validity.

Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230824155345.109765-3-hreitz@redhat.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
(cherry picked from commit 4b5d80f3d0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Hanna Czenczek
c2e6a00b5f file-posix: Clear bs->bl.zoned on error
bs->bl.zoned is what indicates whether the zone information is present
and valid; it is the only thing that raw_refresh_zoned_limits() sets if
CONFIG_BLKZONED is not defined, and it is also the only thing that it
sets if CONFIG_BLKZONED is defined, but there are no zones.

Make sure that it is always set to BLK_Z_NONE if there is an error
anywhere in raw_refresh_zoned_limits() so that we do not accidentally
announce zones while our information is incomplete or invalid.

This also fixes a memory leak in the last error path in
raw_refresh_zoned_limits().

Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230824155345.109765-2-hreitz@redhat.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
(cherry picked from commit 56d1a022a7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Dmitry Frolov
f59caeca76 hw/cxl: Fix out of bound array access
According to cxl_interleave_ways_enc(), fw->num_targets is allowed to be up
to 16. This also corresponds to CXL r3.0 spec. So, the fw->target_hbs[]
array is iterated from 0 to 15. But it is statically declared of length 8.
Thus, out of bound array access may occur.

Fixes: c28db9e000 ("hw/pci-bridge: Make PCIe and CXL PXB Devices inherit from TYPE_PXB_DEV")
Signed-off-by: Dmitry Frolov <frolov@swemel.ru>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Link: https://lore.kernel.org/r/20230913101055.754709-1-frolov@swemel.ru
Cc: qemu-stable@nongnu.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit de5bbfc602)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Li Zhijian
6970f5ba0e hw/cxl: Fix CFMW config memory leak
Allocate targets and targets[n] resources when all sanity checks are
passed to avoid memory leaks.

Cc: qemu-stable@nongnu.org
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Fan Ni <fan.ni@samsung.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 7b165fa164)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Mikulas Patocka
fda70be0c5 linux-user/hppa: lock both words of function descriptor
The code in setup_rt_frame reads two words at haddr, but locks only one.
This patch fixes it to lock both.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Acked-by: Helge Deller <deller@gmx.de>
Cc: qemu-stable@nongnu.org
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 5b1270ef14)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Mikulas Patocka
f7f97b9ad8 linux-user/hppa: clear the PSW 'N' bit when delivering signals
qemu-hppa may crash when delivering a signal. It can be demonstrated with
this program. Compile the program with "hppa-linux-gnu-gcc -O2 signal.c"
and run it with "qemu-hppa -one-insn-per-tb a.out". It reports that the
address of the flag is 0xb4 and it crashes when attempting to touch it.

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>

sig_atomic_t flag;

void sig(int n)
{
	printf("&flag: %p\n", &flag);
	flag = 1;
}

int main(void)
{
	struct sigaction sa;
	struct itimerval it;

	sa.sa_handler = sig;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	if (sigaction(SIGALRM, &sa, NULL)) perror("sigaction"), exit(1);

	it.it_interval.tv_sec = 0;
	it.it_interval.tv_usec = 100;
	it.it_value.tv_sec = it.it_interval.tv_sec;
	it.it_value.tv_usec = it.it_interval.tv_usec;

	if (setitimer(ITIMER_REAL, &it, NULL)) perror("setitimer"), exit(1);

	while (1) {
	}
}

The reason for the crash is that the signal handling routine doesn't clear
the 'N' flag in the PSW. If the signal interrupts a thread when the 'N'
flag is set, the flag remains set at the beginning of the signal handler
and the first instruction of the signal handler is skipped.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Acked-by: Helge Deller <deller@gmx.de>
Cc: qemu-stable@nongnu.org
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 2529497cb6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03 02:00:54 +03:00
Nicholas Piggin
fb9e03529c hw/ppc: Read time only once to perform decrementer write
Reading the time more than once to perform an operation always increases
complexity and fragility due to introduced deltas. Simplify the
decrementer write by reading the clock once for the operation.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit ea62f8a517)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Nicholas Piggin
b6fa8e42d1 hw/ppc: Reset timebase facilities on machine reset
Lower interrupts, delete timers, and set time facility registers
back to initial state on machine reset.

This is not so important for record-replay since timebase and
decrementer are migrated, but it gives a cleaner reset state.

Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[ clg: checkpatch.pl fixes ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 30d0647bcf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Nicholas Piggin
1c2343cc61 hw/ppc: Always store the decrementer value
When writing a value to the decrementer that raises an exception, the
irq is raised, but the value is not stored so the store doesn't appear
to have changed the register when it is read again.

Always store the write value to the register.

Fixes: e81a982aa5 ("PPC: Clean up DECR implementation")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit febb71d543)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Nicholas Piggin
97fec8f2c4 target/ppc: Sign-extend large decrementer to 64-bits
When storing a large decrementer value with the most significant
implemented bit set, it is to be treated as a negative and sign
extended.

This isn't hit for book3s DEC because of another bug, fixing it
in the next patch exposes this one and can cause additional
problems, so fix this first. It can be hit with HDECR and other
edge triggered types.

Fixes: a8dafa5251 ("target/ppc: Implement large decrementer support for TCG")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[ clg: removed extra cpu and pcc variables shadowing local variables ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit c8fbc6b9f2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Nicholas Piggin
0e35c812b9 hw/ppc: Avoid decrementer rounding errors
The decrementer register contains a relative time in timebase units.
When writing to DECR this is converted and stored as an absolute value
in nanosecond units, reading DECR converts back to relative timebase.

The tb<->ns conversion of the relative part can cause rounding such that
a value writen to the decrementer can read back a different, with time
held constant. This is a particular problem for a deterministic icount
and record-replay trace.

Fix this by storing the absolute value in timebase units rather than
nanoseconds. The math before:
  store:  decr_next = now_ns + decr * ns_per_sec / tb_per_sec
  load:        decr = (decr_next - now_ns) * tb_per_sec / ns_per_sec
  load(store): decr = decr * ns_per_sec / tb_per_sec * tb_per_sec /
                      ns_per_sec

After:
  store:  decr_next = now_ns * tb_per_sec / ns_per_sec + decr
  load:        decr = decr_next - now_ns * tb_per_sec / ns_per_sec
  load(store): decr = decr

Fixes: 9fddaa0c0c ("PowerPC merge: real time TB and decrementer - faster and simpler exception handling (Jocelyn Mayer)")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 8e0a5ac878)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Nicholas Piggin
73b7a81107 hw/ppc: Round up the decrementer interval when converting to ns
The rule of timers is typically that they should never expire before the
timeout, but some time afterward. Rounding timer intervals up when doing
conversion is the right thing to do.

Under most circumstances it is impossible observe the decrementer
interrupt before the dec register has triggered. However with icount
timing, problems can arise. For example setting DEC to 0 can schedule
the timer for now, causing it to fire before any more instructions
have been executed and DEC is still 0.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit eab0888418)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Nicholas Piggin
4bff0a8287 host-utils: Add muldiv64_round_up
This will be used for converting time intervals in different base units
to host units, for the purpose of scheduling timers to emulate target
timers. Timers typically must not fire before their requested expiry
time but may fire some time afterward, so rounding up is the right way
to implement these.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
[ clg: renamed __muldiv64() to muldiv64_rounding() ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 47de6c4c28)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Nicholas Piggin
ded5edee00 hw/ppc: Introduce functions for conversion between timebase and nanoseconds
These calculations are repeated several times, and they will become
a little more complicated with subsequent changes.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 7798f5c576)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-25 23:44:30 +03:00
Michael Tokarev
6bb4a8a47a Update version for 8.1.1 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:36:01 +03:00
Marc-André Lureau
045fa84784 tpm: fix crash when FD >= 1024 and unnecessary errors due to EINTR
Replace select() with poll() to fix a crash when QEMU has a large number
of FDs. Also use RETRY_ON_EINTR to avoid unnecessary errors due to EINTR.

Cc: qemu-stable@nongnu.org
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2020133
Fixes: 56a3c24ffc ("tpm: Probe for connected TPM 1.2 or TPM 2")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
(cherry picked from commit 8e32ddff69)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Jonathan Perkin
56270e5d3d meson: Fix targetos match for illumos and Solaris.
qemu 8.1.0 breaks on illumos platforms due to _XOPEN_SOURCE and others no longer being set correctly, leading to breakage such as:

  https://us-central.manta.mnx.io/pkgsrc/public/reports/trunk/tools/20230908.1404/qemu-8.1.0/build.log

This is a result of meson conversion which incorrectly matches against 'solaris' instead of 'sunos' for uname.

First time submitting a patch here, hope I did it correctly.  Thanks.

Signed-off-by: Jonathan Perkin <jonathan@perkin.org.uk>
Message-ID: <ZPtdxtum9UVPy58J@perkin.org.uk>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit fb0a8b0e23)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: omit net/meson.build change before v8.1.0-279-g73258b3864, adjust context befor v8.1.0-288-g2fc36530de)
2023-09-21 19:35:19 +03:00
Janosch Frank
60da8301fe s390x/ap: fix missing subsystem reset registration
A subsystem reset contains a reset of AP resources which has been
missing.  Adding the AP bridge to the list of device types that need
reset fixes this issue.

Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Fixes: a51b3153 ("s390x/ap: base Adjunct Processor (AP) object model")
Message-ID: <20230823142219.1046522-2-seiden@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 297ec01f0b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Marc-André Lureau
8b479229ff ui: fix crash when there are no active_console
Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
0x0000555555888630 in dpy_ui_info_supported (con=0x0) at ../ui/console.c:812
812	    return con->hw_ops->ui_info != NULL;
(gdb) bt
#0  0x0000555555888630 in dpy_ui_info_supported (con=0x0) at ../ui/console.c:812
#1  0x00005555558a44b1 in protocol_client_msg (vs=0x5555578c76c0, data=0x5555581e93f0 <incomplete sequence \373>, len=24) at ../ui/vnc.c:2585
#2  0x00005555558a19ac in vnc_client_read (vs=0x5555578c76c0) at ../ui/vnc.c:1607
#3  0x00005555558a1ac2 in vnc_client_io (ioc=0x5555581eb0e0, condition=G_IO_IN, opaque=0x5555578c76c0) at ../ui/vnc.c:1635

Fixes:
https://issues.redhat.com/browse/RHEL-2600

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Albert Esteve <aesteve@redhat.com>
(cherry picked from commit 48a35e12fa)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Marc-André Lureau
d4919bbcc2 virtio-gpu/win32: set the destroy function on load
Don't forget to unmap the resource memory.

Fixes: commit 9462ff469 ("virtio-gpu/win32: allocate shareable 2d resources/images")

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit 04562ee88e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Akihiko Odaki
cae7dc1452 target/riscv: Allocate itrigger timers only once
riscv_trigger_init() had been called on reset events that can happen
several times for a CPU and it allocated timers for itrigger. If old
timers were present, they were simply overwritten by the new timers,
resulting in a memory leak.

Divide riscv_trigger_init() into two functions, namely
riscv_trigger_realize() and riscv_trigger_reset() and call them in
appropriate timing. The timer allocation will happen only once for a
CPU in riscv_trigger_realize().

Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit a7c272df82)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Leon Schuermann
7385e00665 target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
configuration lock bits must not apply. While this behavior is
implemented for the pmpcfgX CSRs, this bit is not respected for
changes to the pmpaddrX CSRs. This patch ensures that pmpaddrX CSR
writes work even on locked regions when the global rule-lock bypass is
enabled.

Signed-off-by: Leon Schuermann <leons@opentitan.org>
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 4e3adce124)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Daniel Henrique Barboza
1d4fb5815c target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
longer to boot than the 'rv64' KVM CPU.

The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
when satp_mode.supported = 0, i.e. when cpu_init() does not set
satp_mode_max_supported(). satp_mode_max_from_map(map) does:

31 - __builtin_clz(map)

This means that, if satp_mode.supported = 0, satp_mode_supported_max
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
set it to UINT_MAX (4294967295). After that, if the user didn't set a
satp_mode, set_satp_mode_default_map(cpu) will make

cfg.satp_mode.map = cfg.satp_mode.supported

So satp_mode.map = 0. And then satp_mode_map_max will be set to
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
here since both are UINT_MAX.

And finally we have 2 loops:

        for (int i = satp_mode_map_max - 1; i >= 0; --i) {

Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the
extra delay when booting the 'host' CPU is coming from.

Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0
in a different manner. We're doing the same here. If supported == 0,
interpret as 'the CPU wants the OS to handle satp mode alone' and skip
satp_mode_finalize().

We'll also put a guard in satp_mode_max_from_map() to assert out if map
is 0 since the function is not ready to deal with it.

Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 3a2fc23563)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Conor Dooley
b822207513 hw/riscv: virt: Fix riscv,pmu DT node path
On a dtb dumped from the virt machine, dt-validate complains:
soc: pmu: {'riscv,event-to-mhpmcounters': [[1, 1, 524281], [2, 2, 524284], [65561, 65561, 524280], [65563, 65563, 524280], [65569, 65569, 524280]], 'compatible': ['riscv,pmu']} should not be valid under {'type': 'object'}
        from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
That's pretty cryptic, but running the dtb back through dtc produces
something a lot more reasonable:
Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property

Moving the riscv,pmu node out of the soc bus solves the problem.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 9ff3140631)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
LIU Zhiwei
2947da750e linux-user/riscv: Use abi type for target_ucontext
We should not use types dependend on host arch for target_ucontext.
This bug is found when run rv32 applications.

Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit ae7d4d625c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Jason Chien
60a7f5c8fe hw/intc: Make rtc variable names consistent
The variables whose values are given by cpu_riscv_read_rtc() should be named
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
should be named "rtc_r".

Signed-off-by: Jason Chien <jason.chien@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 9382a9eafc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Jason Chien
566dac7127 hw/intc: Fix upper/lower mtime write calculation
When writing the upper mtime, we should keep the original lower mtime
whose value is given by cpu_riscv_read_rtc() instead of
cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime.

Signed-off-by: Jason Chien <jason.chien@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20230728082502.26439-1-jason.chien@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit e0922b73ba)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
LIU Zhiwei
8ae20123b6 target/riscv: Fix zfa fleq.d and fltq.d
Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension.
However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s
helper function.

Fixes: a47842d ("riscv: Add support for the Zfa extension")
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit eda633a534)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
LIU Zhiwei
6c24b6000b target/riscv: Fix page_check_range use in fault-only-first
Commit bef6f008b98(accel/tcg: Return bool from page_check_range) converts
integer return value to bool type. However, it wrongly converted the use
of the API in riscv fault-only-first, where page_check_range < = 0, should
be converted to !page_check_range.

Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 4cc9f284d5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Daniel Henrique Barboza
987e90cfd2 target/riscv/cpu.c: add zmmul isa string
zmmul was promoted from experimental to ratified in commit 6d00ffad4e.
Add a riscv,isa string for it.

Fixes: 6d00ffad4e ("target/riscv: move zmmul out of the experimental properties")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 50f9464962)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Thomas Huth
b9f83298b9 hw/char/riscv_htif: Fix the console syscall on big endian hosts
Values that have been read via cpu_physical_memory_read() from the
guest's memory have to be swapped in case the host endianess differs
from the guest.

Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230721094720.902454-3-thuth@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 058096f1c5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Thomas Huth
3d6251f416 hw/char/riscv_htif: Fix printing of console characters on big endian hosts
The character that should be printed is stored in the 64 bit "payload"
variable. The code currently tries to print it by taking the address
of the variable and passing this pointer to qemu_chr_fe_write(). However,
this only works on little endian hosts where the least significant bits
are stored on the lowest address. To do this in a portable way, we have
to store the value in an uint8_t variable instead.

Fixes: 5033606780 ("RISC-V HTIF Console")
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20230721094720.902454-2-thuth@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit c255946e3d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Colton Lewis
9832a670b3 arm64: Restore trapless ptimer access
Due to recent KVM changes, QEMU is setting a ptimer offset resulting
in unintended trap and emulate access and a consequent performance
hit. Filter out the PTIMER_CNT register to restore trapless ptimer
access.

Quoting Andrew Jones:

Simply reading the CNT register and writing back the same value is
enough to set an offset, since the timer will have certainly moved
past whatever value was read by the time it's written.  QEMU
frequently saves and restores all registers in the get-reg-list array,
unless they've been explicitly filtered out (with Linux commit
680232a94c12, KVM_REG_ARM_PTIMER_CNT is now in the array). So, to
restore trapless ptimer accesses, we need a QEMU patch to filter out
the register.

See
https://lore.kernel.org/kvmarm/gsntttsonus5.fsf@coltonlewis-kvm.c.googlers.com/T/#m0770023762a821db2a3f0dd0a7dc6aa54e0d0da9
for additional context.

Cc: qemu-stable@nongnu.org
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
Signed-off-by: Colton Lewis <coltonlewis@google.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Colton Lewis <coltonlewis@google.com>
Message-id: 20230831190052.129045-1-coltonlewis@google.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 682814e2a3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Kevin Wolf
df33ce9b6d virtio: Drop out of coroutine context in virtio_load()
virtio_load() as a whole should run in coroutine context because it
reads from the migration stream and we don't want this to block.

However, it calls virtio_set_features_nocheck() and devices don't
expect their .set_features callback to run in a coroutine and therefore
call functions that may not be called in coroutine context. To fix this,
drop out of coroutine context for calling virtio_set_features_nocheck().

Without this fix, the following crash was reported:

  #0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
  #1  0x00007efc738c05d3 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
  #2  0x00007efc73873d26 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
  #3  0x00007efc738477f3 in __GI_abort () at abort.c:79
  #4  0x00007efc7384771b in __assert_fail_base (fmt=0x7efc739dbcb8 "", assertion=assertion@entry=0x560aebfbf5cf "!qemu_in_coroutine()",
     file=file@entry=0x560aebfcd2d4 "../block/graph-lock.c", line=line@entry=275, function=function@entry=0x560aebfcd34d "void bdrv_graph_rdlock_main_loop(void)") at assert.c:92
  #5  0x00007efc7386ccc6 in __assert_fail (assertion=0x560aebfbf5cf "!qemu_in_coroutine()", file=0x560aebfcd2d4 "../block/graph-lock.c", line=275,
     function=0x560aebfcd34d "void bdrv_graph_rdlock_main_loop(void)") at assert.c:101
  #6  0x0000560aebcd8dd6 in bdrv_register_buf ()
  #7  0x0000560aeb97ed97 in ram_block_added.llvm ()
  #8  0x0000560aebb8303f in ram_block_add.llvm ()
  #9  0x0000560aebb834fa in qemu_ram_alloc_internal.llvm ()
  #10 0x0000560aebb2ac98 in vfio_region_mmap ()
  #11 0x0000560aebb3ea0f in vfio_bars_register ()
  #12 0x0000560aebb3c628 in vfio_realize ()
  #13 0x0000560aeb90f0c2 in pci_qdev_realize ()
  #14 0x0000560aebc40305 in device_set_realized ()
  #15 0x0000560aebc48e07 in property_set_bool.llvm ()
  #16 0x0000560aebc46582 in object_property_set ()
  #17 0x0000560aebc4cd58 in object_property_set_qobject ()
  #18 0x0000560aebc46ba7 in object_property_set_bool ()
  #19 0x0000560aeb98b3ca in qdev_device_add_from_qdict ()
  #20 0x0000560aebb1fbaf in virtio_net_set_features ()
  #21 0x0000560aebb46b51 in virtio_set_features_nocheck ()
  #22 0x0000560aebb47107 in virtio_load ()
  #23 0x0000560aeb9ae7ce in vmstate_load_state ()
  #24 0x0000560aeb9d2ee9 in qemu_loadvm_state_main ()
  #25 0x0000560aeb9d45e1 in qemu_loadvm_state ()
  #26 0x0000560aeb9bc32c in process_incoming_migration_co.llvm ()
  #27 0x0000560aebeace56 in coroutine_trampoline.llvm ()

Cc: qemu-stable@nongnu.org
Buglink: https://issues.redhat.com/browse/RHEL-832
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20230905145002.46391-3-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 92e2e6a867)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Marc-André Lureau
eeee989f72 qxl: don't assert() if device isn't yet initialized
If the PCI BAR isn't yet mapped or was unmapped, QXL_IO_SET_MODE will
assert(). Instead, report a guest bug and keep going.

This can be reproduced with:

cat << EOF | ./qemu-system-x86_64 -vga qxl -m 2048 -nodefaults -qtest stdio
outl 0xcf8 0x8000101c
outl 0xcfc 0xc000
outl 0xcf8 0x80001001
outl 0xcfc 0x01000000
outl 0xc006 0x00
EOF

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1829

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 95bef686e4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Thomas Huth
93d4107937 hw/net/vmxnet3: Fix guest-triggerable assert()
The assert() that checks for valid MTU sizes can be triggered by
the guest (e.g. with the reproducer code from the bug ticket
https://gitlab.com/qemu-project/qemu/-/issues/517 ). Let's avoid
this problem by simply logging the error and refusing to activate
the device instead.

Fixes: d05dcd94ae ("net: vmxnet3: validate configuration values during activate")
Signed-off-by: Thomas Huth <thuth@redhat.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
[Mjt: change format specifier from %d to %u for uint32_t argument]
(cherry picked from commit 90a0778421)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Markus Armbruster
6356785daa docs tests: Fix use of migrate_set_parameter
docs/multi-thread-compression.txt uses parameter names with
underscores instead of dashes.  Wrong since day one.

docs/rdma.txt, tests/qemu-iotests/181, and tests/qtest/test-hmp.c are
wrong the same way since commit cbde7be900 (v6.0.0).  Hard to see,
as test-hmp doesn't check whether the commands work, and iotest 181
appears to be unaffected.

Fixes: 263170e679 (docs: Add a doc about multiple thread compression)
Fixes: cbde7be900 (migrate: remove QMP/HMP commands for speed, downtime and cache size)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit b21a6e31a1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Thomas Huth
01bf87c8e3 qemu-options.hx: Rephrase the descriptions of the -hd* and -cdrom options
The current description says that these options will create a device
on the IDE bus, which is only true on x86. So rephrase these sentences
a little bit to speak of "default bus" instead.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit bcd8e24308)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Hang Yu
25ec23ab3f hw/i2c/aspeed: Fix TXBUF transmission start position error
According to the ast2600 datasheet and the linux aspeed i2c driver,
the TXBUF transmission start position should be TXBUF[0] instead
of TXBUF[1],so the arg pool_start is useless,and the address is not
included in TXBUF.So even if Tx Count equals zero,there is at least
1 byte data needs to be transmitted,and M_TX_CMD should not be cleared
at this condition.The driver url is:
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v5.15/drivers/i2c/busses/i2c-ast2600.c

Signed-off-by: Hang Yu <francis_yuu@stu.pku.edu.cn>
Fixes: 6054fc73e8 ("aspeed/i2c: Add support for pool buffer transfers")
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 961faf3ddb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Hang Yu
9dc6f05cc8 hw/i2c/aspeed: Fix Tx count and Rx size error in buffer pool mode
Fixed inconsistency between the regisiter bit field definition header file
and the ast2600 datasheet. The reg name is I2CD1C:Pool Buffer Control
Register in old register mode and  I2CC0C: Master/Slave Pool Buffer Control
Register in new register mode. They share bit field
[12:8]:Transmit Data Byte Count and bit field
[29:24]:Actual Received Pool Buffer Size according to the datasheet.
According to the ast2600 datasheet,the actual Tx count is
Transmit Data Byte Count plus 1, and the max Rx size is
Receive Pool Buffer Size plus 1, both in Pool Buffer Control Register.
The version before forgot to plus 1, and mistake Rx count for Rx size.

Signed-off-by: Hang Yu <francis_yuu@stu.pku.edu.cn>
Fixes: 3be3d6ccf2 ("aspeed: i2c: Migrate to registerfields API")
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 97b8aa5ae9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Niklas Cassel
d5361580ac hw/ide/ahci: fix broken SError handling
When encountering an NCQ error, you should not write the NCQ tag to the
SError register. This is completely wrong.

The SError register has a clear definition, where each bit represents a
different error, see PxSERR definition in AHCI 1.3.1.

If we write a random value (like the NCQ tag) in SError, e.g. Linux will
read SError, and will trigger arbitrary error handling depending on the
NCQ tag that happened to be executing.

In case of success, ncq_cb() will call ncq_finish().
In case of error, ncq_cb() will call ncq_err() (which will clear
ncq_tfs->used), and then call ncq_finish(), thus using ncq_tfs->used is
sufficient to tell if finished should get set or not.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230609140844.202795-9-nks@flawful.org
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 9f89423537)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Niklas Cassel
e8f5ca57e4 hw/ide/ahci: fix ahci_write_fis_sdb()
When there is an error, we need to raise a TFES error irq, see AHCI 1.3.1,
5.3.13.1 SDB:Entry.

If ERR_STAT is set, we jump to state ERR:FatalTaskfile, which will raise
a TFES IRQ unconditionally, regardless if the I bit is set in the FIS or
not.

Thus, we should never raise a normal IRQ after having sent an error IRQ.

It is valid to signal successfully completed commands as finished in the
same SDB FIS that generates the error IRQ. The important thing is that
commands that did not complete successfully (e.g. commands that were
aborted, do not get the finished bit set).

Before this commit, there was never a TFES IRQ raised on NCQ error.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230609140844.202795-8-nks@flawful.org
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 7e85cb0db4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Niklas Cassel
4448c345bc hw/ide/ahci: PxCI should not get cleared when ERR_STAT is set
For NCQ, PxCI is cleared on command queued successfully.
For non-NCQ, PxCI is cleared on command completed successfully.
Successfully means ERR_STAT, BUSY and DRQ are all cleared.

A command that has ERR_STAT set, does not get to clear PxCI.
See AHCI 1.3.1, section 5.3.8, states RegFIS:Entry and RegFIS:ClearCI,
and 5.3.16.5 ERR:FatalTaskfile.

In the case of non-NCQ commands, not clearing PxCI is needed in order
for host software to be able to see which command slot that failed.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Message-id: 20230609140844.202795-7-nks@flawful.org
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 1a16ce64fd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Niklas Cassel
4fbd5a5202 hw/ide/ahci: PxSACT and PxCI is cleared when PxCMD.ST is cleared
According to AHCI 1.3.1 definition of PxSACT:
This field is cleared when PxCMD.ST is written from a '1' to a '0' by
software. This field is not cleared by a COMRESET or a software reset.

According to AHCI 1.3.1 definition of PxCI:
This field is also cleared when PxCMD.ST is written from a '1' to a '0'
by software.

Clearing PxCMD.ST is part of the error recovery procedure, see
AHCI 1.3.1, section "6.2 Error Recovery".

If we don't clear PxCI on error recovery, the previous command will
incorrectly still be marked as pending after error recovery.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230609140844.202795-6-nks@flawful.org
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit d73b84d0b6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Niklas Cassel
16cc9594d2 hw/ide/ahci: simplify and document PxCI handling
The AHCI spec states that:
For NCQ, PxCI is cleared on command queued successfully.

For non-NCQ, PxCI is cleared on command completed successfully.
(A non-NCQ command that completes with error does not clear PxCI.)

The current QEMU implementation either clears PxCI in check_cmd(),
or in ahci_cmd_done().

check_cmd() will clear PxCI for a command if handle_cmd() returns 0.
handle_cmd() will return -1 if BUSY or DRQ is set.

The QEMU implementation for NCQ commands will currently not set BUSY
or DRQ, so they will always have PxCI cleared by handle_cmd().
ahci_cmd_done() will never even get called for NCQ commands.

Non-NCQ commands are executed by ide_bus_exec_cmd().
Non-NCQ commands in QEMU are implemented either in a sync or in an async
way.

For non-NCQ commands implemented in a sync way, the command handler will
return true, and when ide_bus_exec_cmd() sees that a command handler
returns true, it will call ide_cmd_done() (which will call
ahci_cmd_done()). For a command implemented in a sync way,
ahci_cmd_done() will do nothing (since busy_slot is not set). Instead,
after ide_bus_exec_cmd() has finished, check_cmd() will clear PxCI for
these commands.

For non-NCQ commands implemented in an async way (using either aiocb or
pio_aiocb), the command handler will return false, ide_bus_exec_cmd()
will not call ide_cmd_done(), instead it is expected that the async
callback function will call ide_cmd_done() once the async command is
done. handle_cmd() will set busy_slot, if and only if BUSY or DRQ is
set, and this is checked _after_ ide_bus_exec_cmd() has returned.
handle_cmd() will return -1, so check_cmd() will not clear PxCI.
When the async callback calls ide_cmd_done() (which will call
ahci_cmd_done()), it will see that busy_slot is set, and
ahci_cmd_done() will clear PxCI.

This seems racy, since busy_slot is set _after_ ide_bus_exec_cmd() has
returned. The callback might come before busy_slot gets set. And it is
quite confusing that ahci_cmd_done() will be called for all non-NCQ
commands when the command is done, but will only clear PxCI in certain
cases, even though it will always write a D2H FIS and raise an IRQ.

Even worse, in the case where ahci_cmd_done() does not clear PxCI, it
still raises an IRQ. Host software might thus read an old PxCI value,
since PxCI is cleared (by check_cmd()) after the IRQ has been raised.

Try to simplify this by always setting busy_slot for non-NCQ commands,
such that ahci_cmd_done() will always be responsible for clearing PxCI
for non-NCQ commands.

For NCQ commands, clear PxCI when we receive the D2H FIS, but before
raising the IRQ, see AHCI 1.3.1, section 5.3.8, states RegFIS:Entry and
RegFIS:ClearCI.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Message-id: 20230609140844.202795-5-nks@flawful.org
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit e2a5d9b3d9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Niklas Cassel
1efefd13ca hw/ide/ahci: write D2H FIS when processing NCQ command
The way that BUSY + PxCI is cleared for NCQ (FPDMA QUEUED) commands is
described in SATA 3.5a Gold:

11.15 FPDMA QUEUED command protocol
DFPDMAQ2: ClearInterfaceBsy
"Transmit Register Device to Host FIS with the BSY bit cleared to zero
and the DRQ bit cleared to zero and Interrupt bit cleared to zero to
mark interface ready for the next command."

PxCI is currently cleared by handle_cmd(), but we don't write the D2H
FIS to the FIS Receive Area that actually caused PxCI to be cleared.

Similar to how ahci_pio_transfer() calls ahci_write_fis_pio() with an
additional parameter to write a PIO Setup FIS without raising an IRQ,
add a parameter to ahci_write_fis_d2h() so that ahci_write_fis_d2h()
also can write the FIS to the FIS Receive Area without raising an IRQ.

Change process_ncq_command() to call ahci_write_fis_d2h() without
raising an IRQ (similar to ahci_pio_transfer()), such that the FIS
Receive Area is in sync with the PxTFD shadow register.

E.g. Linux reads status and error fields from the FIS Receive Area
directly, so it is wise to keep the FIS Receive Area and the PxTFD
shadow register in sync.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Message-id: 20230609140844.202795-4-nks@flawful.org
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 2967dc8209)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Niklas Cassel
c2e0495e3c hw/ide/core: set ERR_STAT in unsupported command completion
Currently, the first time sending an unsupported command
(e.g. READ LOG DMA EXT) will not have ERR_STAT set in the completion.
Sending the unsupported command again, will correctly have ERR_STAT set.

When ide_cmd_permitted() returns false, it calls ide_abort_command().
ide_abort_command() first calls ide_transfer_stop(), which will call
ide_transfer_halt() and ide_cmd_done(), after that ide_abort_command()
sets ERR_STAT in status.

ide_cmd_done() for AHCI will call ahci_write_fis_d2h() which writes the
current status in the FIS, and raises an IRQ. (The status here will not
have ERR_STAT set!).

Thus, we cannot call ide_transfer_stop() before setting ERR_STAT, as
ide_transfer_stop() will result in the FIS being written and an IRQ
being raised.

The reason why it works the second time, is that ERR_STAT will still
be set from the previous command, so when writing the FIS, the
completion will correctly have ERR_STAT set.

Set ERR_STAT before writing the FIS (calling cmd_done), so that we will
raise an error IRQ correctly when receiving an unsupported command.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230609140844.202795-3-nks@flawful.org
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit c3461c6264)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Nicholas Piggin
f64f1f8704 target/ppc: Fix LQ, STQ register-pair order for big-endian
LQ, STQ have the same register-pair ordering as LQARX/STQARX., which is
the even (lower) register contains the most significant bits. This is
not implemented correctly for big-endian.

do_ldst_quad() has variables low_addr_gpr and high_addr_gpr which is
confusing because they are low and high addresses, whereas LQARX/STQARX.
and most such things use the low and high values for lo/hi variables.
The conversion to native 128-bit memory access functions missed this
strangeness.

Fix this by changing the if condition, and change the variable names to
hi/lo to match convention.

Cc: qemu-stable@nongnu.org
Reported-by: Ivan Warren <ivan@vmfacility.fr>
Fixes: 57b38ffd0c ("target/ppc: Use tcg_gen_qemu_{ld,st}_i128 for LQARX, LQ, STQ")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1836
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 718209358f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Richard Henderson
9f54fef2c0 target/ppc: Flush inputs to zero with NJ in ppc_store_vscr
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1779
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit af03aeb631)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Maksim Kostin
5358980d33 hw/ppc/e500: fix broken snapshot replay
ppce500_reset_device_tree is registered for system reset, but after
c4b075318e this function rerandomizes rng-seed via
qemu_guest_getrandom_nofail. And when loading a snapshot, it tries to read
EVENT_RANDOM that doesn't exist, so we have an error:

  qemu-system-ppc: Missing random event in the replay log

To fix this, use qemu_register_reset_nosnapshotload instead of
qemu_register_reset.

Reported-by: Vitaly Cheptsov <cheptsov@ispras.ru>
Fixes: c4b075318e ("hw/ppc: pass random seed to fdt ")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1634
Signed-off-by: Maksim Kostin <maksim.kostin@ispras.ru>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 6ec65b69ba)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Nicholas Piggin
6864f05cb1 ppc/vof: Fix missed fields in VOF cleanup
Failing to reset the of_instance_last makes ihandle allocation continue
to increase, which causes record-replay replay fail to match the
recorded trace.

Not resetting claimed_base makes VOF eventually run out of memory after
some resets.

Cc: Alexey Kardashevskiy <aik@ozlabs.ru>
Fixes: fc8c745d50 ("spapr: Implement Open Firmware client interface")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 7b8589d7ce)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Bilal Elmoussaoui
0175121c6c ui/dbus: Properly dispose touch/mouse dbus objects
Fixes: 142ca628a7 ("ui: add a D-Bus display backend")
Fixes: de9f844ce2 ("ui/dbus: Expose a touch device interface")

Signed-off-by: Bilal Elmoussaoui <belmouss@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230901124507.94087-1-belmouss@redhat.com>
(cherry picked from commit cb6ccdc9ca)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Paolo Bonzini
e975434d62 target/i386: raise FERR interrupt with iothread locked
Otherwise tcg_handle_interrupt() triggers an assertion failure:

  #5  0x0000555555c97369 in tcg_handle_interrupt (cpu=0x555557434cb0, mask=2) at ../accel/tcg/tcg-accel-ops.c:83
  #6  tcg_handle_interrupt (cpu=0x555557434cb0, mask=2) at ../accel/tcg/tcg-accel-ops.c:81
  #7  0x0000555555b4d58b in pic_irq_request (opaque=<optimized out>, irq=<optimized out>, level=1) at ../hw/i386/x86.c:555
  #8  0x0000555555b4f218 in gsi_handler (opaque=0x5555579423d0, n=13, level=1) at ../hw/i386/x86.c:611
  #9  0x00007fffa42bde14 in code_gen_buffer ()
  #10 0x0000555555c724bb in cpu_tb_exec (cpu=cpu@entry=0x555557434cb0, itb=<optimized out>, tb_exit=tb_exit@entry=0x7fffe9bfd658) at ../accel/tcg/cpu-exec.c:457

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1808
Reported-by: NyanCatTW1 <https://gitlab.com/a0939712328>
Co-developed-by: Richard Henderson <richard.henderson@linaro.org>'
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c1f27a0c6a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Richard Henderson
e5e77f256f linux-user: Adjust brk for load_bias
PIE executables are usually linked at offset 0 and are
relocated somewhere during load.  The hiaddr needs to
be adjusted to keep the brk next to the executable.

Cc: qemu-stable@nongnu.org
Fixes: 1f356e8c01 ("linux-user: Adjust initial brk when interpreter is close to executable")
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit aec338d63b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Alex Bennée
645b87f650 target/arm: properly document FEAT_CRC32
This is a mandatory feature for Armv8.1 architectures but we don't
state the feature clearly in our emulation list. Also include
FEAT_CRC32 comment in aarch64_max_tcg_initfn for ease of grepping.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20230824075406.1515566-1-alex.bennee@linaro.org
Cc: qemu-stable@nongnu.org
Message-Id: <20230222110104.3996971-1-alex.bennee@linaro.org>
[PMM: pluralize 'instructions' in docs]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 9e771a2fc6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Fabiano Rosas
86d7b08d71 block-migration: Ensure we don't crash during migration cleanup
We can fail the blk_insert_bs() at init_blk_migration(), leaving the
BlkMigDevState without a dirty_bitmap and BlockDriverState. Account
for the possibly missing elements when doing cleanup.

Fix the following crashes:

Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
0x0000555555ec83ef in bdrv_release_dirty_bitmap (bitmap=0x0) at ../block/dirty-bitmap.c:359
359         BlockDriverState *bs = bitmap->bs;
 #0  0x0000555555ec83ef in bdrv_release_dirty_bitmap (bitmap=0x0) at ../block/dirty-bitmap.c:359
 #1  0x0000555555bba331 in unset_dirty_tracking () at ../migration/block.c:371
 #2  0x0000555555bbad98 in block_migration_cleanup_bmds () at ../migration/block.c:681

Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
0x0000555555e971ff in bdrv_op_unblock (bs=0x0, op=BLOCK_OP_TYPE_BACKUP_SOURCE, reason=0x0) at ../block.c:7073
7073        QLIST_FOREACH_SAFE(blocker, &bs->op_blockers[op], list, next) {
 #0  0x0000555555e971ff in bdrv_op_unblock (bs=0x0, op=BLOCK_OP_TYPE_BACKUP_SOURCE, reason=0x0) at ../block.c:7073
 #1  0x0000555555e9734a in bdrv_op_unblock_all (bs=0x0, reason=0x0) at ../block.c:7095
 #2  0x0000555555bbae13 in block_migration_cleanup_bmds () at ../migration/block.c:690

Signed-off-by: Fabiano Rosas <farosas@suse.de>
Message-id: 20230731203338.27581-1-farosas@suse.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit f187609f27)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-09-21 19:35:19 +03:00
Richard Henderson
5691fbf440 softmmu: Assert data in bounds in iotlb_to_section
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Suggested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 86e4f93d82)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-30 19:38:00 +03:00
Philippe Mathieu-Daudé
441106eebb docs/about/license: Update LICENSE URL
In early 2021 (see commit 2ad784339e "docs: update README to use
GitLab repo URLs") almost all of the code base was converted to
point to GitLab instead of git.qemu.org. During 2023, git.qemu.org
switched from a git mirror to a http redirect to GitLab (see [1]).

Update the LICENSE URL to match its previous content, displaying
the file raw content similarly to gitweb 'blob_plain' format ([2]).

[1] https://lore.kernel.org/qemu-devel/CABgObfZu3mFc8tM20K-yXdt7F-7eV-uKZN4sKDarSeu7DYoRbA@mail.gmail.com/
[2] https://git-scm.com/docs/gitweb#Documentation/gitweb.txt-blobplain

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230822125716.55295-1-philmd@linaro.org>
(cherry picked from commit 09a3fffae0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-24 18:52:48 +03:00
Richard Henderson
63188a00bb target/arm: Fix 64-bit SSRA
Typo applied byte-wise shift instead of double-word shift.

Cc: qemu-stable@nongnu.org
Fixes: 631e565450 ("target/arm: Create gen_gvec_[us]sra")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1737
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230821022025.397682-1-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit cd1e4db736)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-24 18:49:15 +03:00
Richard Henderson
7012e20b2d target/arm: Fix SME ST1Q
A typo, noted in the bug report, resulting in an
incorrect write offset.

Cc: qemu-stable@nongnu.org
Fixes: 7390e0e9ab ("target/arm: Implement SME LD1, ST1")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1833
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20230818214255.146905-1-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 4b3520fd93)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-24 18:48:49 +03:00
Akihiko Odaki
c8e381d672 accel/kvm: Specify default IPA size for arm64
Before this change, the default KVM type, which is used for non-virt
machine models, was 0.

The kernel documentation says:
> On arm64, the physical address size for a VM (IPA Size limit) is
> limited to 40bits by default. The limit can be configured if the host
> supports the extension KVM_CAP_ARM_VM_IPA_SIZE. When supported, use
> KVM_VM_TYPE_ARM_IPA_SIZE(IPA_Bits) to set the size in the machine type
> identifier, where IPA_Bits is the maximum width of any physical
> address used by the VM. The IPA_Bits is encoded in bits[7-0] of the
> machine type identifier.
>
> e.g, to configure a guest to use 48bit physical address size::
>
>     vm_fd = ioctl(dev_fd, KVM_CREATE_VM, KVM_VM_TYPE_ARM_IPA_SIZE(48));
>
> The requested size (IPA_Bits) must be:
>
>  ==   =========================================================
>   0   Implies default size, 40bits (for backward compatibility)
>   N   Implies N bits, where N is a positive integer such that,
>       32 <= N <= Host_IPA_Limit
>  ==   =========================================================

> Host_IPA_Limit is the maximum possible value for IPA_Bits on the host
> and is dependent on the CPU capability and the kernel configuration.
> The limit can be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the
> KVM_CHECK_EXTENSION ioctl() at run-time.
>
> Creation of the VM will fail if the requested IPA size (whether it is
> implicit or explicit) is unsupported on the host.
https://docs.kernel.org/virt/kvm/api.html#kvm-create-vm

So if Host_IPA_Limit < 40, specifying 0 as the type will fail. This
actually confused libvirt, which uses "none" machine model to probe the
KVM availability, on M2 MacBook Air.

Fix this by using Host_IPA_Limit as the default type when
KVM_CAP_ARM_VM_IPA_SIZE is available.

Cc: qemu-stable@nongnu.org
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-id: 20230727073134.134102-3-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 1ab445af8c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-24 18:45:44 +03:00
Akihiko Odaki
34808d041c kvm: Introduce kvm_arch_get_default_type hook
kvm_arch_get_default_type() returns the default KVM type. This hook is
particularly useful to derive a KVM type that is valid for "none"
machine model, which is used by libvirt to probe the availability of
KVM.

For MIPS, the existing mips_kvm_type() is reused. This function ensures
the availability of VZ which is mandatory to use KVM on the current
QEMU.

Cc: qemu-stable@nongnu.org
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-id: 20230727073134.134102-2-akihiko.odaki@daynix.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[PMM: added doc comment for new function]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 5e0d65909c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-24 18:43:47 +03:00
Thomas Huth
01f6417f15 include/hw/virtio/virtio-gpu: Fix virtio-gpu with blob on big endian hosts
Using "-device virtio-gpu,blob=true" currently does not work on big
endian hosts (like s390x). The guest kernel prints an error message
like:

 [drm:virtio_gpu_dequeue_ctrl_func [virtio_gpu]] *ERROR* response 0x1200 (command 0x10c)

and the display stays black. When running QEMU with "-d guest_errors",
it shows an error message like this:

 virtio_gpu_create_mapping_iov: nr_entries is too big (83886080 > 16384)

which indicates that this value has not been properly byte-swapped.
And indeed, the virtio_gpu_create_blob_bswap() function (that should
swap the fields in the related structure) fails to swap some of the
entries. After correctly swapping all missing values here, too, the
virtio-gpu device is now also working with blob=true on s390x hosts.

Fixes: e0933d91b1 ("virtio-gpu: Add virtio_gpu_resource_create_blob")
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2230469
Message-Id: <20230815122007.928049-1-thuth@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit d194362910)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-23 16:58:41 +03:00
Ilya Leoshkevich
14a8213b75 target/s390x: Check reserved bits of VFMIN/VFMAX's M5
VFMIN and VFMAX should raise a specification exceptions when bits 1-3
of M5 are set.

Cc: qemu-stable@nongnu.org
Fixes: da4807527f ("s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM)")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230804234621.252522-1-iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 6a2ea61518)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-23 16:58:41 +03:00
Ilya Leoshkevich
c12eddbd48 target/s390x: Fix VSTL with a large length
The length is always truncated to 16 bytes. Do not probe more than
that.

Cc: qemu-stable@nongnu.org
Fixes: 0e0a5b49ad ("s390x/tcg: Implement VECTOR STORE WITH LENGTH")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230804235624.263260-1-iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 6db3518ba4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-23 16:58:41 +03:00
Ilya Leoshkevich
880e82ed78 target/s390x: Use a 16-bit immediate in VREP
Unlike most other instructions that contain an immediate element index,
VREP's one is 16-bit, and not 4-bit. The code uses only 8 bits, so
using, e.g., 0x101 does not lead to a specification exception.

Fix by checking all 16 bits.

Cc: qemu-stable@nongnu.org
Fixes: 28d08731b1 ("s390x/tcg: Implement VECTOR REPLICATE")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230807163459.849766-1-iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 23e87d419f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-23 16:58:41 +03:00
Ilya Leoshkevich
5980189e96 target/s390x: Fix the "ignored match" case in VSTRS
Currently the emulation of VSTRS recognizes partial matches in presence
of \0 in the haystack, which, according to PoP, is not correct:

    If the ZS flag is one and a zero byte was detected
    in the second operand, then there can not be a
    partial match ...

Add a check for this. While at it, fold a number of explicitly handled
special cases into the generic logic.

Cc: qemu-stable@nongnu.org
Reported-by: Claudio Fontana <cfontana@suse.de>
Closes: https://lists.gnu.org/archive/html/qemu-devel/2023-08/msg00633.html
Fixes: 1d706f3141 ("target/s390x: vxeh2: vector string search")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230804233748.218935-3-iii@linux.ibm.com>
Tested-by: Claudio Fontana <cfontana@suse.de>
Acked-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 791b2b6a93)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-08-23 16:55:40 +03:00
320 changed files with 3437 additions and 1654 deletions

View File

@ -584,7 +584,10 @@ pages:
- mkdir -p public - mkdir -p public
# HTML-ised source tree # HTML-ised source tree
- make gtags - make gtags
- htags -anT --tree-view=filetree -m qemu_init # We unset variables to work around a bug in some htags versions
# which causes it to fail when the environment is large
- CI_COMMIT_MESSAGE= CI_COMMIT_TAG_MESSAGE= htags
-anT --tree-view=filetree -m qemu_init
-t "Welcome to the QEMU sourcecode" -t "Welcome to the QEMU sourcecode"
- mv HTML public/src - mv HTML public/src
# Project documentation # Project documentation

View File

@ -5,16 +5,21 @@
# Required # Required
version: 2 version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the docs/ directory with Sphinx # Build documentation in the docs/ directory with Sphinx
sphinx: sphinx:
configuration: docs/conf.py configuration: docs/conf.py
# We recommend specifying your dependencies to enable reproducible builds:
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: docs/requirements.txt
# We want all the document formats # We want all the document formats
formats: all formats: all
# For consistency, we require that QEMU's Sphinx extensions
# run with at least the same minimum version of Python that
# we require for other Python in our codebase (our conf.py
# enforces this, and some code needs it.)
python:
version: 3.6

View File

@ -1 +1 @@
8.1.0 8.1.5

View File

@ -2458,7 +2458,7 @@ static int kvm_init(MachineState *ms)
KVMState *s; KVMState *s;
const KVMCapabilityInfo *missing_cap; const KVMCapabilityInfo *missing_cap;
int ret; int ret;
int type = 0; int type;
uint64_t dirty_log_manual_caps; uint64_t dirty_log_manual_caps;
qemu_mutex_init(&kml_slots_lock); qemu_mutex_init(&kml_slots_lock);
@ -2523,6 +2523,8 @@ static int kvm_init(MachineState *ms)
type = mc->kvm_type(ms, kvm_type); type = mc->kvm_type(ms, kvm_type);
} else if (mc->kvm_type) { } else if (mc->kvm_type) {
type = mc->kvm_type(ms, NULL); type = mc->kvm_type(ms, NULL);
} else {
type = kvm_arch_get_default_type(ms);
} }
do { do {

View File

@ -33,36 +33,6 @@ void cpu_loop_exit_noexc(CPUState *cpu)
cpu_loop_exit(cpu); cpu_loop_exit(cpu);
} }
#if defined(CONFIG_SOFTMMU)
void cpu_reloading_memory_map(void)
{
if (qemu_in_vcpu_thread() && current_cpu->running) {
/* The guest can in theory prolong the RCU critical section as long
* as it feels like. The major problem with this is that because it
* can do multiple reconfigurations of the memory map within the
* critical section, we could potentially accumulate an unbounded
* collection of memory data structures awaiting reclamation.
*
* Because the only thing we're currently protecting with RCU is the
* memory data structures, it's sufficient to break the critical section
* in this callback, which we know will get called every time the
* memory map is rearranged.
*
* (If we add anything else in the system that uses RCU to protect
* its data structures, we will need to implement some other mechanism
* to force TCG CPUs to exit the critical section, at which point this
* part of this callback might become unnecessary.)
*
* This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
* only protects cpu->as->dispatch. Since we know our caller is about
* to reload it, it's safe to split the critical section.
*/
rcu_read_unlock();
rcu_read_lock();
}
}
#endif
void cpu_loop_exit(CPUState *cpu) void cpu_loop_exit(CPUState *cpu)
{ {
/* Undo the setting in cpu_tb_exec. */ /* Undo the setting in cpu_tb_exec. */

View File

@ -182,7 +182,7 @@ static bool tb_lookup_cmp(const void *p, const void *d)
const TranslationBlock *tb = p; const TranslationBlock *tb = p;
const struct tb_desc *desc = d; const struct tb_desc *desc = d;
if ((tb_cflags(tb) & CF_PCREL || tb->pc == desc->pc) && if (tb->pc == desc->pc &&
tb_page_addr0(tb) == desc->page_addr0 && tb_page_addr0(tb) == desc->page_addr0 &&
tb->cs_base == desc->cs_base && tb->cs_base == desc->cs_base &&
tb->flags == desc->flags && tb->flags == desc->flags &&
@ -232,7 +232,7 @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, vaddr pc,
return NULL; return NULL;
} }
desc.page_addr0 = phys_pc; desc.page_addr0 = phys_pc;
h = tb_hash_func(phys_pc, (cflags & CF_PCREL ? 0 : pc), h = tb_hash_func(phys_pc, pc,
flags, cs_base, cflags); flags, cs_base, cflags);
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp); return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
} }
@ -720,7 +720,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
&& cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra == 0) { && cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra == 0) {
/* Execute just one insn to trigger exception pending in the log */ /* Execute just one insn to trigger exception pending in the log */
cpu->cflags_next_tb = (curr_cflags(cpu) & ~CF_USE_ICOUNT) cpu->cflags_next_tb = (curr_cflags(cpu) & ~CF_USE_ICOUNT)
| CF_NOIRQ | 1; | CF_LAST_IO | CF_NOIRQ | 1;
} }
#endif #endif
return false; return false;

View File

@ -46,7 +46,7 @@ static bool tb_cmp(const void *ap, const void *bp)
const TranslationBlock *a = ap; const TranslationBlock *a = ap;
const TranslationBlock *b = bp; const TranslationBlock *b = bp;
return ((tb_cflags(a) & CF_PCREL || a->pc == b->pc) && return (a->pc == b->pc &&
a->cs_base == b->cs_base && a->cs_base == b->cs_base &&
a->flags == b->flags && a->flags == b->flags &&
(tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) && (tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
@ -916,7 +916,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
/* remove the TB from the hash list */ /* remove the TB from the hash list */
phys_pc = tb_page_addr0(tb); phys_pc = tb_page_addr0(tb);
h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb->pc), h = tb_hash_func(phys_pc, tb->pc,
tb->flags, tb->cs_base, orig_cflags); tb->flags, tb->cs_base, orig_cflags);
if (!qht_remove(&tb_ctx.htable, tb, h)) { if (!qht_remove(&tb_ctx.htable, tb, h)) {
return; return;
@ -983,7 +983,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb)
tb_record(tb); tb_record(tb);
/* add in the hash table */ /* add in the hash table */
h = tb_hash_func(tb_page_addr0(tb), (tb->cflags & CF_PCREL ? 0 : tb->pc), h = tb_hash_func(tb_page_addr0(tb), tb->pc,
tb->flags, tb->cs_base, tb->cflags); tb->flags, tb->cs_base, tb->cflags);
qht_insert(&tb_ctx.htable, tb, h, &existing_tb); qht_insert(&tb_ctx.htable, tb, h, &existing_tb);
@ -1083,7 +1083,8 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc)
if (current_tb_modified) { if (current_tb_modified) {
/* Force execution of one insn next time. */ /* Force execution of one insn next time. */
CPUState *cpu = current_cpu; CPUState *cpu = current_cpu;
cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu); cpu->cflags_next_tb =
1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(current_cpu);
return true; return true;
} }
return false; return false;
@ -1153,7 +1154,8 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
if (current_tb_modified) { if (current_tb_modified) {
page_collection_unlock(pages); page_collection_unlock(pages);
/* Force execution of one insn next time. */ /* Force execution of one insn next time. */
current_cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu); current_cpu->cflags_next_tb =
1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(current_cpu);
mmap_unlock(); mmap_unlock();
cpu_loop_exit_noexc(current_cpu); cpu_loop_exit_noexc(current_cpu);
} }

View File

@ -100,14 +100,9 @@ static void *mttcg_cpu_thread_fn(void *arg)
break; break;
case EXCP_HALTED: case EXCP_HALTED:
/* /*
* during start-up the vCPU is reset and the thread is * Usually cpu->halted is set, but may have already been
* kicked several times. If we don't ensure we go back * reset by another thread by the time we arrive here.
* to sleep in the halted state we won't cleanly
* start-up when the vCPU is enabled.
*
* cpu->halted should ensure we sleep in wait_io_event
*/ */
g_assert(cpu->halted);
break; break;
case EXCP_ATOMIC: case EXCP_ATOMIC:
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();

View File

@ -326,9 +326,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
gen_code_buf = tcg_ctx->code_gen_ptr; gen_code_buf = tcg_ctx->code_gen_ptr;
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf); tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
if (!(cflags & CF_PCREL)) { tb->pc = pc;
tb->pc = pc;
}
tb->cs_base = cs_base; tb->cs_base = cs_base;
tb->flags = flags; tb->flags = flags;
tb->cflags = cflags; tb->cflags = cflags;

View File

@ -16,26 +16,19 @@
#include "tcg/tcg-op-common.h" #include "tcg/tcg-op-common.h"
#include "internal.h" #include "internal.h"
static void gen_io_start(void) static void set_can_do_io(DisasContextBase *db, bool val)
{ {
tcg_gen_st_i32(tcg_constant_i32(1), cpu_env, if (db->saved_can_do_io != val) {
offsetof(ArchCPU, parent_obj.can_do_io) - db->saved_can_do_io = val;
offsetof(ArchCPU, env)); tcg_gen_st_i32(tcg_constant_i32(val), cpu_env,
offsetof(ArchCPU, parent_obj.can_do_io) -
offsetof(ArchCPU, env));
}
} }
bool translator_io_start(DisasContextBase *db) bool translator_io_start(DisasContextBase *db)
{ {
uint32_t cflags = tb_cflags(db->tb); set_can_do_io(db, true);
if (!(cflags & CF_USE_ICOUNT)) {
return false;
}
if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) {
/* Already started in translator_loop. */
return true;
}
gen_io_start();
/* /*
* Ensure that this instruction will be the last in the TB. * Ensure that this instruction will be the last in the TB.
@ -47,14 +40,17 @@ bool translator_io_start(DisasContextBase *db)
return true; return true;
} }
static TCGOp *gen_tb_start(uint32_t cflags) static TCGOp *gen_tb_start(DisasContextBase *db, uint32_t cflags)
{ {
TCGv_i32 count = tcg_temp_new_i32(); TCGv_i32 count = NULL;
TCGOp *icount_start_insn = NULL; TCGOp *icount_start_insn = NULL;
tcg_gen_ld_i32(count, cpu_env, if ((cflags & CF_USE_ICOUNT) || !(cflags & CF_NOIRQ)) {
offsetof(ArchCPU, neg.icount_decr.u32) - count = tcg_temp_new_i32();
offsetof(ArchCPU, env)); tcg_gen_ld_i32(count, cpu_env,
offsetof(ArchCPU, neg.icount_decr.u32) -
offsetof(ArchCPU, env));
}
if (cflags & CF_USE_ICOUNT) { if (cflags & CF_USE_ICOUNT) {
/* /*
@ -84,18 +80,15 @@ static TCGOp *gen_tb_start(uint32_t cflags)
tcg_gen_st16_i32(count, cpu_env, tcg_gen_st16_i32(count, cpu_env,
offsetof(ArchCPU, neg.icount_decr.u16.low) - offsetof(ArchCPU, neg.icount_decr.u16.low) -
offsetof(ArchCPU, env)); offsetof(ArchCPU, env));
/*
* cpu->can_do_io is cleared automatically here at the beginning of
* each translation block. The cost is minimal and only paid for
* -icount, plus it would be very easy to forget doing it in the
* translator. Doing it here means we don't need a gen_io_end() to
* go with gen_io_start().
*/
tcg_gen_st_i32(tcg_constant_i32(0), cpu_env,
offsetof(ArchCPU, parent_obj.can_do_io) -
offsetof(ArchCPU, env));
} }
/*
* cpu->can_do_io is set automatically here at the beginning of
* each translation block. The cost is minimal, plus it would be
* very easy to forget doing it in the translator.
*/
set_can_do_io(db, db->max_insns == 1 && (cflags & CF_LAST_IO));
return icount_start_insn; return icount_start_insn;
} }
@ -144,6 +137,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
db->num_insns = 0; db->num_insns = 0;
db->max_insns = *max_insns; db->max_insns = *max_insns;
db->singlestep_enabled = cflags & CF_SINGLE_STEP; db->singlestep_enabled = cflags & CF_SINGLE_STEP;
db->saved_can_do_io = -1;
db->host_addr[0] = host_pc; db->host_addr[0] = host_pc;
db->host_addr[1] = NULL; db->host_addr[1] = NULL;
@ -151,11 +145,17 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
/* Start translating. */ /* Start translating. */
icount_start_insn = gen_tb_start(cflags); icount_start_insn = gen_tb_start(db, cflags);
ops->tb_start(db, cpu); ops->tb_start(db, cpu);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
plugin_enabled = plugin_gen_tb_start(cpu, db, cflags & CF_MEMI_ONLY); if (cflags & CF_MEMI_ONLY) {
/* We should only see CF_MEMI_ONLY for io_recompile. */
assert(cflags & CF_LAST_IO);
plugin_enabled = plugin_gen_tb_start(cpu, db, true);
} else {
plugin_enabled = plugin_gen_tb_start(cpu, db, false);
}
while (true) { while (true) {
*max_insns = ++db->num_insns; *max_insns = ++db->num_insns;
@ -172,13 +172,9 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
the next instruction. */ the next instruction. */
if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) { if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) {
/* Accept I/O on the last instruction. */ /* Accept I/O on the last instruction. */
gen_io_start(); set_can_do_io(db, true);
ops->translate_insn(db, cpu);
} else {
/* we should only see CF_MEMI_ONLY for io_recompile */
tcg_debug_assert(!(cflags & CF_MEMI_ONLY));
ops->translate_insn(db, cpu);
} }
ops->translate_insn(db, cpu);
/* /*
* We can't instrument after instructions that change control * We can't instrument after instructions that change control

View File

@ -398,6 +398,7 @@ static void cryptodev_backend_set_ops(Object *obj, Visitor *v,
static void static void
cryptodev_backend_complete(UserCreatable *uc, Error **errp) cryptodev_backend_complete(UserCreatable *uc, Error **errp)
{ {
ERRP_GUARD();
CryptoDevBackend *backend = CRYPTODEV_BACKEND(uc); CryptoDevBackend *backend = CRYPTODEV_BACKEND(uc);
CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(uc); CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(uc);
uint32_t services; uint32_t services;
@ -406,11 +407,20 @@ cryptodev_backend_complete(UserCreatable *uc, Error **errp)
QTAILQ_INIT(&backend->opinfos); QTAILQ_INIT(&backend->opinfos);
value = backend->tc.buckets[THROTTLE_OPS_TOTAL].avg; value = backend->tc.buckets[THROTTLE_OPS_TOTAL].avg;
cryptodev_backend_set_throttle(backend, THROTTLE_OPS_TOTAL, value, errp); cryptodev_backend_set_throttle(backend, THROTTLE_OPS_TOTAL, value, errp);
if (*errp) {
return;
}
value = backend->tc.buckets[THROTTLE_BPS_TOTAL].avg; value = backend->tc.buckets[THROTTLE_BPS_TOTAL].avg;
cryptodev_backend_set_throttle(backend, THROTTLE_BPS_TOTAL, value, errp); cryptodev_backend_set_throttle(backend, THROTTLE_BPS_TOTAL, value, errp);
if (*errp) {
return;
}
if (bc->init) { if (bc->init) {
bc->init(backend, errp); bc->init(backend, errp);
if (*errp) {
return;
}
} }
services = backend->conf.crypto_services; services = backend->conf.crypto_services;

View File

@ -112,12 +112,8 @@ static int tpm_util_request(int fd,
void *response, void *response,
size_t responselen) size_t responselen)
{ {
fd_set readfds; GPollFD fds[1] = { {.fd = fd, .events = G_IO_IN } };
int n; int n;
struct timeval tv = {
.tv_sec = 1,
.tv_usec = 0,
};
n = write(fd, request, requestlen); n = write(fd, request, requestlen);
if (n < 0) { if (n < 0) {
@ -127,11 +123,8 @@ static int tpm_util_request(int fd,
return -EFAULT; return -EFAULT;
} }
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
/* wait for a second */ /* wait for a second */
n = select(fd + 1, &readfds, NULL, NULL, &tv); n = RETRY_ON_EINTR(g_poll(fds, 1, 1000));
if (n != 1) { if (n != 1) {
return -errno; return -errno;
} }

View File

@ -324,22 +324,39 @@ static void coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_log(BlkLogWritesLogReq *lr) blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
{ {
BDRVBlkLogWritesState *s = lr->bs->opaque; BDRVBlkLogWritesState *s = lr->bs->opaque;
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
/*
* Determine the offsets and sizes of different parts of the entry, and
* update the state of the driver.
*
* This needs to be done in one go, before any actual I/O is done, as the
* log entry may have to be written in two parts, and the state of the
* driver may be modified by other driver operations while waiting for the
* I/O to complete.
*/
const uint64_t entry_start_sector = s->cur_log_sector;
const uint64_t entry_offset = entry_start_sector << s->sectorbits;
const uint64_t qiov_aligned_size = ROUND_UP(lr->qiov->size, s->sectorsize);
const uint64_t entry_aligned_size = qiov_aligned_size +
ROUND_UP(lr->zero_size, s->sectorsize);
const uint64_t entry_nr_sectors = entry_aligned_size >> s->sectorbits;
s->nr_entries++; s->nr_entries++;
s->cur_log_sector += s->cur_log_sector += entry_nr_sectors;
ROUND_UP(lr->qiov->size, s->sectorsize) >> s->sectorbits;
lr->log_ret = bdrv_co_pwritev(s->log_file, cur_log_offset, lr->qiov->size, /*
* Write the log entry. Note that if this is a "write zeroes" operation,
* only the entry header is written here, with the zeroing being done
* separately below.
*/
lr->log_ret = bdrv_co_pwritev(s->log_file, entry_offset, lr->qiov->size,
lr->qiov, 0); lr->qiov, 0);
/* Logging for the "write zeroes" operation */ /* Logging for the "write zeroes" operation */
if (lr->log_ret == 0 && lr->zero_size) { if (lr->log_ret == 0 && lr->zero_size) {
cur_log_offset = s->cur_log_sector << s->sectorbits; const uint64_t zeroes_offset = entry_offset + qiov_aligned_size;
s->cur_log_sector +=
ROUND_UP(lr->zero_size, s->sectorsize) >> s->sectorbits;
lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, cur_log_offset, lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, zeroes_offset,
lr->zero_size, 0); lr->zero_size, 0);
} }

View File

@ -160,7 +160,6 @@ typedef struct BDRVRawState {
bool has_write_zeroes:1; bool has_write_zeroes:1;
bool use_linux_aio:1; bool use_linux_aio:1;
bool use_linux_io_uring:1; bool use_linux_io_uring:1;
int64_t *offset; /* offset of zone append operation */
int page_cache_inconsistent; /* errno from fdatasync failure */ int page_cache_inconsistent; /* errno from fdatasync failure */
bool has_fallocate; bool has_fallocate;
bool needs_alignment; bool needs_alignment;
@ -1412,11 +1411,9 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
BlockZoneModel zoned; BlockZoneModel zoned;
int ret; int ret;
bs->bl.zoned = BLK_Z_NONE;
ret = get_sysfs_zoned_model(st, &zoned); ret = get_sysfs_zoned_model(st, &zoned);
if (ret < 0 || zoned == BLK_Z_NONE) { if (ret < 0 || zoned == BLK_Z_NONE) {
return; goto no_zoned;
} }
bs->bl.zoned = zoned; bs->bl.zoned = zoned;
@ -1437,10 +1434,10 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Unable to read chunk_sectors " error_setg_errno(errp, -ret, "Unable to read chunk_sectors "
"sysfs attribute"); "sysfs attribute");
return; goto no_zoned;
} else if (!ret) { } else if (!ret) {
error_setg(errp, "Read 0 from chunk_sectors sysfs attribute"); error_setg(errp, "Read 0 from chunk_sectors sysfs attribute");
return; goto no_zoned;
} }
bs->bl.zone_size = ret << BDRV_SECTOR_BITS; bs->bl.zone_size = ret << BDRV_SECTOR_BITS;
@ -1448,10 +1445,10 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Unable to read nr_zones " error_setg_errno(errp, -ret, "Unable to read nr_zones "
"sysfs attribute"); "sysfs attribute");
return; goto no_zoned;
} else if (!ret) { } else if (!ret) {
error_setg(errp, "Read 0 from nr_zones sysfs attribute"); error_setg(errp, "Read 0 from nr_zones sysfs attribute");
return; goto no_zoned;
} }
bs->bl.nr_zones = ret; bs->bl.nr_zones = ret;
@ -1472,10 +1469,15 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
ret = get_zones_wp(bs, s->fd, 0, bs->bl.nr_zones, 0); ret = get_zones_wp(bs, s->fd, 0, bs->bl.nr_zones, 0);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "report wps failed"); error_setg_errno(errp, -ret, "report wps failed");
bs->wps = NULL; goto no_zoned;
return;
} }
qemu_co_mutex_init(&bs->wps->colock); qemu_co_mutex_init(&bs->wps->colock);
return;
no_zoned:
bs->bl.zoned = BLK_Z_NONE;
g_free(bs->wps);
bs->wps = NULL;
} }
#else /* !defined(CONFIG_BLKZONED) */ #else /* !defined(CONFIG_BLKZONED) */
static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st, static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
@ -2442,19 +2444,21 @@ static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
return true; return true;
} }
static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr,
uint64_t bytes, QEMUIOVector *qiov, int type) uint64_t bytes, QEMUIOVector *qiov, int type)
{ {
BDRVRawState *s = bs->opaque; BDRVRawState *s = bs->opaque;
RawPosixAIOData acb; RawPosixAIOData acb;
int ret; int ret;
uint64_t offset = *offset_ptr;
if (fd_open(bs) < 0) if (fd_open(bs) < 0)
return -EIO; return -EIO;
#if defined(CONFIG_BLKZONED) #if defined(CONFIG_BLKZONED)
if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) && bs->wps) { if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) &&
bs->bl.zoned != BLK_Z_NONE) {
qemu_co_mutex_lock(&bs->wps->colock); qemu_co_mutex_lock(&bs->wps->colock);
if (type & QEMU_AIO_ZONE_APPEND && bs->bl.zone_size) { if (type & QEMU_AIO_ZONE_APPEND) {
int index = offset / bs->bl.zone_size; int index = offset / bs->bl.zone_size;
offset = bs->wps->wp[index]; offset = bs->wps->wp[index];
} }
@ -2502,16 +2506,15 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
out: out:
#if defined(CONFIG_BLKZONED) #if defined(CONFIG_BLKZONED)
{ if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) &&
BlockZoneWps *wps = bs->wps; bs->bl.zoned != BLK_Z_NONE) {
if (ret == 0) { BlockZoneWps *wps = bs->wps;
if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) if (ret == 0) {
&& wps && bs->bl.zone_size) {
uint64_t *wp = &wps->wp[offset / bs->bl.zone_size]; uint64_t *wp = &wps->wp[offset / bs->bl.zone_size];
if (!BDRV_ZT_IS_CONV(*wp)) { if (!BDRV_ZT_IS_CONV(*wp)) {
if (type & QEMU_AIO_ZONE_APPEND) { if (type & QEMU_AIO_ZONE_APPEND) {
*s->offset = *wp; *offset_ptr = *wp;
trace_zbd_zone_append_complete(bs, *s->offset trace_zbd_zone_append_complete(bs, *offset_ptr
>> BDRV_SECTOR_BITS); >> BDRV_SECTOR_BITS);
} }
/* Advance the wp if needed */ /* Advance the wp if needed */
@ -2519,17 +2522,15 @@ out:
*wp = offset + bytes; *wp = offset + bytes;
} }
} }
} else {
/*
* write and append write are not allowed to cross zone boundaries
*/
update_zones_wp(bs, s->fd, offset, 1);
} }
} else {
if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
update_zones_wp(bs, s->fd, 0, 1);
}
}
if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) && wps) {
qemu_co_mutex_unlock(&wps->colock); qemu_co_mutex_unlock(&wps->colock);
} }
}
#endif #endif
return ret; return ret;
} }
@ -2538,14 +2539,14 @@ static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov, int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_READ); return raw_co_prw(bs, &offset, bytes, qiov, QEMU_AIO_READ);
} }
static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset, static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov, int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_WRITE); return raw_co_prw(bs, &offset, bytes, qiov, QEMU_AIO_WRITE);
} }
static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs) static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs)
@ -3472,7 +3473,7 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
len >> BDRV_SECTOR_BITS); len >> BDRV_SECTOR_BITS);
ret = raw_thread_pool_submit(handle_aiocb_zone_mgmt, &acb); ret = raw_thread_pool_submit(handle_aiocb_zone_mgmt, &acb);
if (ret != 0) { if (ret != 0) {
update_zones_wp(bs, s->fd, offset, i); update_zones_wp(bs, s->fd, offset, nrz);
error_report("ioctl %s failed %d", op_name, ret); error_report("ioctl %s failed %d", op_name, ret);
return ret; return ret;
} }
@ -3508,8 +3509,6 @@ static int coroutine_fn raw_co_zone_append(BlockDriverState *bs,
int64_t zone_size_mask = bs->bl.zone_size - 1; int64_t zone_size_mask = bs->bl.zone_size - 1;
int64_t iov_len = 0; int64_t iov_len = 0;
int64_t len = 0; int64_t len = 0;
BDRVRawState *s = bs->opaque;
s->offset = offset;
if (*offset & zone_size_mask) { if (*offset & zone_size_mask) {
error_report("sector offset %" PRId64 " is not aligned to zone size " error_report("sector offset %" PRId64 " is not aligned to zone size "
@ -3530,7 +3529,7 @@ static int coroutine_fn raw_co_zone_append(BlockDriverState *bs,
} }
trace_zbd_zone_append(bs, *offset >> BDRV_SECTOR_BITS); trace_zbd_zone_append(bs, *offset >> BDRV_SECTOR_BITS);
return raw_co_prw(bs, *offset, len, qiov, QEMU_AIO_ZONE_APPEND); return raw_co_prw(bs, offset, len, qiov, QEMU_AIO_ZONE_APPEND);
} }
#endif #endif

View File

@ -2585,6 +2585,16 @@ bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
ret |= (ret2 & BDRV_BLOCK_ZERO); ret |= (ret2 & BDRV_BLOCK_ZERO);
} }
} }
/*
* Now that the recursive search was done, clear the flag. Otherwise,
* with more complicated block graphs like snapshot-access ->
* copy-before-write -> qcow2, where the return value will be propagated
* further up to a parent bdrv_co_do_block_status() call, both the
* BDRV_BLOCK_RECURSE and BDRV_BLOCK_ZERO flags would be set, which is
* not allowed.
*/
ret &= ~BDRV_BLOCK_RECURSE;
} }
out: out:

View File

@ -416,9 +416,10 @@ static bool nvme_process_completion(NVMeQueuePair *q)
q->cq_phase = !q->cq_phase; q->cq_phase = !q->cq_phase;
} }
cid = le16_to_cpu(c->cid); cid = le16_to_cpu(c->cid);
if (cid == 0 || cid > NVME_QUEUE_SIZE) { if (cid == 0 || cid > NVME_NUM_REQS) {
warn_report("NVMe: Unexpected CID in completion queue: %"PRIu32", " warn_report("NVMe: Unexpected CID in completion queue: %" PRIu32
"queue size: %u", cid, NVME_QUEUE_SIZE); ", should be within: 1..%u inclusively", cid,
NVME_NUM_REQS);
continue; continue;
} }
trace_nvme_complete_command(s, q->index, cid); trace_nvme_complete_command(s, q->index, cid);

View File

@ -130,7 +130,7 @@ static BdrvDirtyBitmap *parallels_load_bitmap(BlockDriverState *bs,
g_autofree uint64_t *l1_table = NULL; g_autofree uint64_t *l1_table = NULL;
BdrvDirtyBitmap *bitmap; BdrvDirtyBitmap *bitmap;
QemuUUID uuid; QemuUUID uuid;
char uuidstr[UUID_FMT_LEN + 1]; char uuidstr[UUID_STR_LEN];
int i; int i;
if (data_size < sizeof(bf)) { if (data_size < sizeof(bf)) {

View File

@ -232,6 +232,7 @@ static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
BlockDriverState *bs, Error **errp) BlockDriverState *bs, Error **errp)
{ {
Error *local_err = NULL; Error *local_err = NULL;
AioContext *ctx;
bool has_device; bool has_device;
int ret; int ret;
@ -253,7 +254,11 @@ static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
return; return;
} }
ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
ret = blk_insert_bs(blk, bs, errp); ret = blk_insert_bs(blk, bs, errp);
aio_context_release(ctx);
if (ret < 0) { if (ret < 0) {
return; return;
} }

View File

@ -1984,7 +1984,7 @@ static int discard_in_l2_slice(BlockDriverState *bs, uint64_t offset,
/* If we keep the reference, pass on the discard still */ /* If we keep the reference, pass on the discard still */
bdrv_pdiscard(s->data_file, old_l2_entry & L2E_OFFSET_MASK, bdrv_pdiscard(s->data_file, old_l2_entry & L2E_OFFSET_MASK,
s->cluster_size); s->cluster_size);
} }
} }
qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
@ -2062,9 +2062,15 @@ zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
QCow2ClusterType type = qcow2_get_cluster_type(bs, old_l2_entry); QCow2ClusterType type = qcow2_get_cluster_type(bs, old_l2_entry);
bool unmap = (type == QCOW2_CLUSTER_COMPRESSED) || bool unmap = (type == QCOW2_CLUSTER_COMPRESSED) ||
((flags & BDRV_REQ_MAY_UNMAP) && qcow2_cluster_is_allocated(type)); ((flags & BDRV_REQ_MAY_UNMAP) && qcow2_cluster_is_allocated(type));
uint64_t new_l2_entry = unmap ? 0 : old_l2_entry; bool keep_reference =
(s->discard_no_unref && type != QCOW2_CLUSTER_COMPRESSED);
uint64_t new_l2_entry = old_l2_entry;
uint64_t new_l2_bitmap = old_l2_bitmap; uint64_t new_l2_bitmap = old_l2_bitmap;
if (unmap && !keep_reference) {
new_l2_entry = 0;
}
if (has_subclusters(s)) { if (has_subclusters(s)) {
new_l2_bitmap = QCOW_L2_BITMAP_ALL_ZEROES; new_l2_bitmap = QCOW_L2_BITMAP_ALL_ZEROES;
} else { } else {
@ -2082,9 +2088,17 @@ zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
set_l2_bitmap(s, l2_slice, l2_index + i, new_l2_bitmap); set_l2_bitmap(s, l2_slice, l2_index + i, new_l2_bitmap);
} }
/* Then decrease the refcount */
if (unmap) { if (unmap) {
qcow2_free_any_cluster(bs, old_l2_entry, QCOW2_DISCARD_REQUEST); if (!keep_reference) {
/* Then decrease the refcount */
qcow2_free_any_cluster(bs, old_l2_entry, QCOW2_DISCARD_REQUEST);
} else if (s->discard_passthrough[QCOW2_DISCARD_REQUEST] &&
(type == QCOW2_CLUSTER_NORMAL ||
type == QCOW2_CLUSTER_ZERO_ALLOC)) {
/* If we keep the reference, pass on the discard still */
bdrv_pdiscard(s->data_file, old_l2_entry & L2E_OFFSET_MASK,
s->cluster_size);
}
} }
} }

View File

@ -190,8 +190,10 @@ static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs)
int bdrv_can_snapshot(BlockDriverState *bs) int bdrv_can_snapshot(BlockDriverState *bs)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
GLOBAL_STATE_CODE(); GLOBAL_STATE_CODE();
if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
if (!drv || !bdrv_is_inserted(bs) || !bdrv_is_writable(bs)) {
return 0; return 0;
} }

View File

@ -239,7 +239,7 @@ static void vdi_header_to_le(VdiHeader *header)
static void vdi_header_print(VdiHeader *header) static void vdi_header_print(VdiHeader *header)
{ {
char uuidstr[37]; char uuidstr[UUID_STR_LEN];
QemuUUID uuid; QemuUUID uuid;
logout("text %s", header->text); logout("text %s", header->text);
logout("signature 0x%08x\n", header->signature); logout("signature 0x%08x\n", header->signature);

View File

@ -347,29 +347,41 @@ vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
BDRVVmdkState *s = bs->opaque; BDRVVmdkState *s = bs->opaque;
int ret = 0; int ret = 0;
desc = g_malloc0(DESC_SIZE); size_t desc_buf_size;
tmp_desc = g_malloc0(DESC_SIZE);
ret = bdrv_co_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0); if (s->desc_offset == 0) {
desc_buf_size = bdrv_getlength(bs->file->bs);
if (desc_buf_size > 16ULL << 20) {
error_report("VMDK description file too big");
return -EFBIG;
}
} else {
desc_buf_size = DESC_SIZE;
}
desc = g_malloc0(desc_buf_size);
tmp_desc = g_malloc0(desc_buf_size);
ret = bdrv_co_pread(bs->file, s->desc_offset, desc_buf_size, desc, 0);
if (ret < 0) { if (ret < 0) {
goto out; goto out;
} }
desc[DESC_SIZE - 1] = '\0'; desc[desc_buf_size - 1] = '\0';
tmp_str = strstr(desc, "parentCID"); tmp_str = strstr(desc, "parentCID");
if (tmp_str == NULL) { if (tmp_str == NULL) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
pstrcpy(tmp_desc, DESC_SIZE, tmp_str); pstrcpy(tmp_desc, desc_buf_size, tmp_str);
p_name = strstr(desc, "CID"); p_name = strstr(desc, "CID");
if (p_name != NULL) { if (p_name != NULL) {
p_name += sizeof("CID"); p_name += sizeof("CID");
snprintf(p_name, DESC_SIZE - (p_name - desc), "%" PRIx32 "\n", cid); snprintf(p_name, desc_buf_size - (p_name - desc), "%" PRIx32 "\n", cid);
pstrcat(desc, DESC_SIZE, tmp_desc); pstrcat(desc, desc_buf_size, tmp_desc);
} }
ret = bdrv_co_pwrite_sync(bs->file, s->desc_offset, DESC_SIZE, desc, 0); ret = bdrv_co_pwrite_sync(bs->file, s->desc_offset, desc_buf_size, desc, 0);
out: out:
g_free(desc); g_free(desc);

View File

@ -2361,8 +2361,9 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
bdrv_co_lock(bs); bdrv_co_lock(bs);
bdrv_drained_end(bs); bdrv_drained_end(bs);
blk_co_unref(blk);
bdrv_co_unlock(bs); bdrv_co_unlock(bs);
blk_co_unref(blk);
} }
void qmp_block_stream(const char *job_id, const char *device, void qmp_block_stream(const char *job_id, const char *device,

View File

@ -106,11 +106,27 @@ static void pty_chr_update_read_handler(Chardev *chr)
static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len) static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len)
{ {
PtyChardev *s = PTY_CHARDEV(chr); PtyChardev *s = PTY_CHARDEV(chr);
GPollFD pfd;
int rc;
if (!s->connected) { if (s->connected) {
return len; return io_channel_send(s->ioc, buf, len);
} }
return io_channel_send(s->ioc, buf, len);
/*
* The other side might already be re-connected, but the timer might
* not have fired yet. So let's check here whether we can write again:
*/
pfd.fd = QIO_CHANNEL_FILE(s->ioc)->fd;
pfd.events = G_IO_OUT;
pfd.revents = 0;
rc = RETRY_ON_EINTR(g_poll(&pfd, 1, 0));
g_assert(rc >= 0);
if (!(pfd.revents & G_IO_HUP) && (pfd.revents & G_IO_OUT)) {
io_channel_send(s->ioc, buf, len);
}
return len;
} }
static GSource *pty_chr_add_watch(Chardev *chr, GIOCondition cond) static GSource *pty_chr_add_watch(Chardev *chr, GIOCondition cond)

View File

@ -518,7 +518,7 @@ static const ChardevClass *char_get_class(const char *driver, Error **errp)
if (object_class_is_abstract(oc)) { if (object_class_is_abstract(oc)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver", error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
"an abstract device type"); "a non-abstract device type");
return NULL; return NULL;
} }

View File

@ -2116,8 +2116,8 @@ static const char *csr_name(int csrno)
case 0x03ba: return "pmpaddr10"; case 0x03ba: return "pmpaddr10";
case 0x03bb: return "pmpaddr11"; case 0x03bb: return "pmpaddr11";
case 0x03bc: return "pmpaddr12"; case 0x03bc: return "pmpaddr12";
case 0x03bd: return "pmpaddr14"; case 0x03bd: return "pmpaddr13";
case 0x03be: return "pmpaddr13"; case 0x03be: return "pmpaddr14";
case 0x03bf: return "pmpaddr15"; case 0x03bf: return "pmpaddr15";
case 0x0780: return "mtohost"; case 0x0780: return "mtohost";
case 0x0781: return "mfromhost"; case 0x0781: return "mfromhost";

View File

@ -8,4 +8,4 @@ QEMU is a trademark of Fabrice Bellard.
QEMU is released under the `GNU General Public QEMU is released under the `GNU General Public
License <https://www.gnu.org/licenses/gpl-2.0.txt>`__, version 2. Parts License <https://www.gnu.org/licenses/gpl-2.0.txt>`__, version 2. Parts
of QEMU have specific licenses, see file of QEMU have specific licenses, see file
`LICENSE <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=LICENSE>`__. `LICENSE <https://gitlab.com/qemu-project/qemu/-/raw/master/LICENSE>`__.

View File

@ -1016,7 +1016,7 @@ class. Here's a simple usage example:
self.vm.launch() self.vm.launch()
res = self.vm.command('human-monitor-command', res = self.vm.command('human-monitor-command',
command_line='info version') command_line='info version')
self.assertRegexpMatches(res, r'^(\d+\.\d+\.\d)') self.assertRegex(res, r'^(\d+\.\d+\.\d)')
To execute your test, run: To execute your test, run:
@ -1077,7 +1077,7 @@ and hypothetical example follows:
'human-monitor-command', 'human-monitor-command',
command_line='info version') command_line='info version')
self.assertEquals(first_res, second_res, third_res) self.assertEqual(first_res, second_res, third_res)
At test "tear down", ``avocado_qemu.Test`` handles all the QEMUMachines At test "tear down", ``avocado_qemu.Test`` handles all the QEMUMachines
shutdown. shutdown.

View File

@ -117,13 +117,13 @@ to support the multiple thread compression migration:
{qemu} migrate_set_capability compress on {qemu} migrate_set_capability compress on
3. Set the compression thread count on source: 3. Set the compression thread count on source:
{qemu} migrate_set_parameter compress_threads 12 {qemu} migrate_set_parameter compress-threads 12
4. Set the compression level on the source: 4. Set the compression level on the source:
{qemu} migrate_set_parameter compress_level 1 {qemu} migrate_set_parameter compress-level 1
5. Set the decompression thread count on destination: 5. Set the decompression thread count on destination:
{qemu} migrate_set_parameter decompress_threads 3 {qemu} migrate_set_parameter decompress-threads 3
6. Start outgoing migration: 6. Start outgoing migration:
{qemu} migrate -d tcp:destination.host:4444 {qemu} migrate -d tcp:destination.host:4444
@ -133,9 +133,9 @@ to support the multiple thread compression migration:
The following are the default settings: The following are the default settings:
compress: off compress: off
compress_threads: 8 compress-threads: 8
decompress_threads: 2 decompress-threads: 2
compress_level: 1 (which means best speed) compress-level: 1 (which means best speed)
So, only the first two steps are required to use the multiple So, only the first two steps are required to use the multiple
thread compression in migration. You can do more if the default thread compression in migration. You can do more if the default

View File

@ -89,7 +89,7 @@ RUNNING:
First, set the migration speed to match your hardware's capabilities: First, set the migration speed to match your hardware's capabilities:
QEMU Monitor Command: QEMU Monitor Command:
$ migrate_set_parameter max_bandwidth 40g # or whatever is the MAX of your RDMA device $ migrate_set_parameter max-bandwidth 40g # or whatever is the MAX of your RDMA device
Next, on the destination machine, add the following to the QEMU command line: Next, on the destination machine, add the following to the QEMU command line:

2
docs/requirements.txt Normal file
View File

@ -0,0 +1,2 @@
sphinx==5.3.0
sphinx_rtd_theme==1.1.1

View File

@ -49,7 +49,7 @@ def serror(file, lnum, errtext):
def parse_directive(line): def parse_directive(line):
"""Return first word of line, if any""" """Return first word of line, if any"""
return re.split('\W', line)[0] return re.split(r'\W', line)[0]
def parse_defheading(file, lnum, line): def parse_defheading(file, lnum, line):
"""Handle a DEFHEADING directive""" """Handle a DEFHEADING directive"""

View File

@ -14,6 +14,7 @@ the following architecture extensions:
- FEAT_BBM at level 2 (Translation table break-before-make levels) - FEAT_BBM at level 2 (Translation table break-before-make levels)
- FEAT_BF16 (AArch64 BFloat16 instructions) - FEAT_BF16 (AArch64 BFloat16 instructions)
- FEAT_BTI (Branch Target Identification) - FEAT_BTI (Branch Target Identification)
- FEAT_CRC32 (CRC32 instructions)
- FEAT_CSV2 (Cache speculation variant 2) - FEAT_CSV2 (Cache speculation variant 2)
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1) - FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2) - FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)

View File

@ -947,6 +947,7 @@ static const VMStateDescription erst_vmstate = {
static void erst_realizefn(PCIDevice *pci_dev, Error **errp) static void erst_realizefn(PCIDevice *pci_dev, Error **errp)
{ {
ERRP_GUARD();
ERSTDeviceState *s = ACPIERST(pci_dev); ERSTDeviceState *s = ACPIERST(pci_dev);
trace_acpi_erst_realizefn_in(); trace_acpi_erst_realizefn_in();
@ -964,9 +965,15 @@ static void erst_realizefn(PCIDevice *pci_dev, Error **errp)
/* HostMemoryBackend size will be multiple of PAGE_SIZE */ /* HostMemoryBackend size will be multiple of PAGE_SIZE */
s->storage_size = object_property_get_int(OBJECT(s->hostmem), "size", errp); s->storage_size = object_property_get_int(OBJECT(s->hostmem), "size", errp);
if (*errp) {
return;
}
/* Initialize backend storage and record_count */ /* Initialize backend storage and record_count */
check_erst_backend_storage(s, errp); check_erst_backend_storage(s, errp);
if (*errp) {
return;
}
/* BAR 0: Programming registers */ /* BAR 0: Programming registers */
memory_region_init_io(&s->iomem_mr, OBJECT(pci_dev), &erst_reg_ops, s, memory_region_init_io(&s->iomem_mr, OBJECT(pci_dev), &erst_reg_ops, s,
@ -977,6 +984,9 @@ static void erst_realizefn(PCIDevice *pci_dev, Error **errp)
memory_region_init_ram(&s->exchange_mr, OBJECT(pci_dev), memory_region_init_ram(&s->exchange_mr, OBJECT(pci_dev),
"erst.exchange", "erst.exchange",
le32_to_cpu(s->header->record_size), errp); le32_to_cpu(s->header->record_size), errp);
if (*errp) {
return;
}
pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
&s->exchange_mr); &s->exchange_mr);

View File

@ -761,6 +761,10 @@ static void do_cpu_reset(void *opaque)
if (cpu_isar_feature(aa64_hcx, cpu)) { if (cpu_isar_feature(aa64_hcx, cpu)) {
env->cp15.scr_el3 |= SCR_HXEN; env->cp15.scr_el3 |= SCR_HXEN;
} }
if (cpu_isar_feature(aa64_fgt, cpu)) {
env->cp15.scr_el3 |= SCR_FGTEN;
}
/* AArch64 kernels never boot in secure mode */ /* AArch64 kernels never boot in secure mode */
assert(!info->secure_boot); assert(!info->secure_boot);
/* This hook is only supported for AArch32 currently: /* This hook is only supported for AArch32 currently:

View File

@ -502,7 +502,7 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
case ES1370_REG_DAC2_SCOUNT: case ES1370_REG_DAC2_SCOUNT:
case ES1370_REG_ADC_SCOUNT: case ES1370_REG_ADC_SCOUNT:
d += (addr - ES1370_REG_DAC1_SCOUNT) >> 2; d += (addr - ES1370_REG_DAC1_SCOUNT) >> 2;
d->scount = (val & 0xffff) | (d->scount & ~0xffff); d->scount = (val & 0xffff) << 16 | (val & 0xffff);
ldebug ("chan %td CURR_SAMP_CT %d, SAMP_CT %d\n", ldebug ("chan %td CURR_SAMP_CT %d, SAMP_CT %d\n",
d - &s->chan[0], val >> 16, (val & 0xffff)); d - &s->chan[0], val >> 16, (val & 0xffff));
break; break;

View File

@ -22,6 +22,7 @@
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "intel-hda.h" #include "intel-hda.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"
#include "qemu/host-utils.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "intel-hda-defs.h" #include "intel-hda-defs.h"
#include "audio/audio.h" #include "audio/audio.h"
@ -189,9 +190,9 @@ struct HDAAudioState {
bool use_timer; bool use_timer;
}; };
static inline int64_t hda_bytes_per_second(HDAAudioStream *st) static inline uint32_t hda_bytes_per_second(HDAAudioStream *st)
{ {
return 2LL * st->as.nchannels * st->as.freq; return 2 * (uint32_t)st->as.nchannels * (uint32_t)st->as.freq;
} }
static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos) static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos)
@ -222,12 +223,18 @@ static void hda_audio_input_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t buft_start = st->buft_start; int64_t uptime = now - st->buft_start;
int64_t wpos = st->wpos; int64_t wpos = st->wpos;
int64_t rpos = st->rpos; int64_t rpos = st->rpos;
int64_t wanted_rpos;
int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start) if (uptime <= 0) {
/ NANOSECONDS_PER_SECOND; /* wanted_rpos <= 0 */
goto out_timer;
}
wanted_rpos = muldiv64(uptime, hda_bytes_per_second(st),
NANOSECONDS_PER_SECOND);
wanted_rpos &= -4; /* IMPORTANT! clip to frames */ wanted_rpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_rpos <= rpos) { if (wanted_rpos <= rpos) {
@ -286,12 +293,18 @@ static void hda_audio_output_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t buft_start = st->buft_start; int64_t uptime = now - st->buft_start;
int64_t wpos = st->wpos; int64_t wpos = st->wpos;
int64_t rpos = st->rpos; int64_t rpos = st->rpos;
int64_t wanted_wpos;
int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start) if (uptime <= 0) {
/ NANOSECONDS_PER_SECOND; /* wanted_wpos <= 0 */
goto out_timer;
}
wanted_wpos = muldiv64(uptime, hda_bytes_per_second(st),
NANOSECONDS_PER_SECOND);
wanted_wpos &= -4; /* IMPORTANT! clip to frames */ wanted_wpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_wpos <= wpos) { if (wanted_wpos <= wpos) {

View File

@ -233,6 +233,10 @@ static void atmega_realize(DeviceState *dev, Error **errp)
/* CPU */ /* CPU */
object_initialize_child(OBJECT(dev), "cpu", &s->cpu, mc->cpu_type); object_initialize_child(OBJECT(dev), "cpu", &s->cpu, mc->cpu_type);
object_property_set_uint(OBJECT(&s->cpu), "init-sp",
mc->io_size + mc->sram_size - 1, &error_abort);
qdev_realize(DEVICE(&s->cpu), NULL, &error_abort); qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
cpudev = DEVICE(&s->cpu); cpudev = DEVICE(&s->cpu);

View File

@ -80,16 +80,39 @@ struct PFlashCFI01 {
uint16_t ident3; uint16_t ident3;
uint8_t cfi_table[0x52]; uint8_t cfi_table[0x52];
uint64_t counter; uint64_t counter;
unsigned int writeblock_size; uint32_t writeblock_size;
MemoryRegion mem; MemoryRegion mem;
char *name; char *name;
void *storage; void *storage;
VMChangeStateEntry *vmstate; VMChangeStateEntry *vmstate;
bool old_multiple_chip_handling; bool old_multiple_chip_handling;
/* block update buffer */
unsigned char *blk_bytes;
uint32_t blk_offset;
}; };
static int pflash_post_load(void *opaque, int version_id); static int pflash_post_load(void *opaque, int version_id);
static bool pflash_blk_write_state_needed(void *opaque)
{
PFlashCFI01 *pfl = opaque;
return (pfl->blk_offset != -1);
}
static const VMStateDescription vmstate_pflash_blk_write = {
.name = "pflash_cfi01_blk_write",
.version_id = 1,
.minimum_version_id = 1,
.needed = pflash_blk_write_state_needed,
.fields = (const VMStateField[]) {
VMSTATE_VBUFFER_UINT32(blk_bytes, PFlashCFI01, 0, NULL, writeblock_size),
VMSTATE_UINT32(blk_offset, PFlashCFI01),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_pflash = { static const VMStateDescription vmstate_pflash = {
.name = "pflash_cfi01", .name = "pflash_cfi01",
.version_id = 1, .version_id = 1,
@ -101,6 +124,10 @@ static const VMStateDescription vmstate_pflash = {
VMSTATE_UINT8(status, PFlashCFI01), VMSTATE_UINT8(status, PFlashCFI01),
VMSTATE_UINT64(counter, PFlashCFI01), VMSTATE_UINT64(counter, PFlashCFI01),
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
&vmstate_pflash_blk_write,
NULL
} }
}; };
@ -225,34 +252,10 @@ static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset,
uint32_t ret; uint32_t ret;
p = pfl->storage; p = pfl->storage;
switch (width) { if (be) {
case 1: ret = ldn_be_p(p + offset, width);
ret = p[offset]; } else {
break; ret = ldn_le_p(p + offset, width);
case 2:
if (be) {
ret = p[offset] << 8;
ret |= p[offset + 1];
} else {
ret = p[offset];
ret |= p[offset + 1] << 8;
}
break;
case 4:
if (be) {
ret = p[offset] << 24;
ret |= p[offset + 1] << 16;
ret |= p[offset + 2] << 8;
ret |= p[offset + 3];
} else {
ret = p[offset];
ret |= p[offset + 1] << 8;
ret |= p[offset + 2] << 16;
ret |= p[offset + 3] << 24;
}
break;
default:
abort();
} }
trace_pflash_data_read(pfl->name, offset, width, ret); trace_pflash_data_read(pfl->name, offset, width, ret);
return ret; return ret;
@ -400,40 +403,61 @@ static void pflash_update(PFlashCFI01 *pfl, int offset,
} }
} }
/* copy current flash content to block update buffer */
static void pflash_blk_write_start(PFlashCFI01 *pfl, hwaddr offset)
{
hwaddr mask = ~(pfl->writeblock_size - 1);
trace_pflash_write_block_start(pfl->name, pfl->counter);
pfl->blk_offset = offset & mask;
memcpy(pfl->blk_bytes, pfl->storage + pfl->blk_offset,
pfl->writeblock_size);
}
/* commit block update buffer changes */
static void pflash_blk_write_flush(PFlashCFI01 *pfl)
{
g_assert(pfl->blk_offset != -1);
trace_pflash_write_block_flush(pfl->name);
memcpy(pfl->storage + pfl->blk_offset, pfl->blk_bytes,
pfl->writeblock_size);
pflash_update(pfl, pfl->blk_offset, pfl->writeblock_size);
pfl->blk_offset = -1;
}
/* discard block update buffer changes */
static void pflash_blk_write_abort(PFlashCFI01 *pfl)
{
trace_pflash_write_block_abort(pfl->name);
pfl->blk_offset = -1;
}
static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset, static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be) uint32_t value, int width, int be)
{ {
uint8_t *p = pfl->storage; uint8_t *p;
trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter); if (pfl->blk_offset != -1) {
switch (width) { /* block write: redirect writes to block update buffer */
case 1: if ((offset < pfl->blk_offset) ||
p[offset] = value; (offset + width > pfl->blk_offset + pfl->writeblock_size)) {
break; pfl->status |= 0x10; /* Programming error */
case 2: return;
if (be) {
p[offset] = value >> 8;
p[offset + 1] = value;
} else {
p[offset] = value;
p[offset + 1] = value >> 8;
} }
break; trace_pflash_data_write_block(pfl->name, offset, width, value,
case 4: pfl->counter);
if (be) { p = pfl->blk_bytes + (offset - pfl->blk_offset);
p[offset] = value >> 24; } else {
p[offset + 1] = value >> 16; /* write directly to storage */
p[offset + 2] = value >> 8; trace_pflash_data_write(pfl->name, offset, width, value);
p[offset + 3] = value; p = pfl->storage + offset;
} else {
p[offset] = value;
p[offset + 1] = value >> 8;
p[offset + 2] = value >> 16;
p[offset + 3] = value >> 24;
}
break;
} }
if (be) {
stn_be_p(p, width, value);
} else {
stn_le_p(p, width, value);
}
} }
static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
@ -548,9 +572,9 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
} else { } else {
value = extract32(value, 0, pfl->bank_width * 8); value = extract32(value, 0, pfl->bank_width * 8);
} }
trace_pflash_write_block(pfl->name, value);
pfl->counter = value; pfl->counter = value;
pfl->wcycle++; pfl->wcycle++;
pflash_blk_write_start(pfl, offset);
break; break;
case 0x60: case 0x60:
if (cmd == 0xd0) { if (cmd == 0xd0) {
@ -581,12 +605,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
switch (pfl->cmd) { switch (pfl->cmd) {
case 0xe8: /* Block write */ case 0xe8: /* Block write */
/* FIXME check @offset, @width */ /* FIXME check @offset, @width */
if (!pfl->ro) { if (!pfl->ro && (pfl->blk_offset != -1)) {
/*
* FIXME writing straight to memory is *wrong*. We
* should write to a buffer, and flush it to memory
* only on confirm command (see below).
*/
pflash_data_write(pfl, offset, value, width, be); pflash_data_write(pfl, offset, value, width, be);
} else { } else {
pfl->status |= 0x10; /* Programming error */ pfl->status |= 0x10; /* Programming error */
@ -595,18 +614,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
pfl->status |= 0x80; pfl->status |= 0x80;
if (!pfl->counter) { if (!pfl->counter) {
hwaddr mask = pfl->writeblock_size - 1;
mask = ~mask;
trace_pflash_write(pfl->name, "block write finished"); trace_pflash_write(pfl->name, "block write finished");
pfl->wcycle++; pfl->wcycle++;
if (!pfl->ro) {
/* Flush the entire write buffer onto backing storage. */
/* FIXME premature! */
pflash_update(pfl, offset & mask, pfl->writeblock_size);
} else {
pfl->status |= 0x10; /* Programming error */
}
} }
pfl->counter--; pfl->counter--;
@ -618,20 +627,17 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
case 3: /* Confirm mode */ case 3: /* Confirm mode */
switch (pfl->cmd) { switch (pfl->cmd) {
case 0xe8: /* Block write */ case 0xe8: /* Block write */
if (cmd == 0xd0) { if ((cmd == 0xd0) && !(pfl->status & 0x10)) {
/* FIXME this is where we should write out the buffer */ pflash_blk_write_flush(pfl);
pfl->wcycle = 0; pfl->wcycle = 0;
pfl->status |= 0x80; pfl->status |= 0x80;
} else { } else {
qemu_log_mask(LOG_UNIMP, pflash_blk_write_abort(pfl);
"%s: Aborting write to buffer not implemented,"
" the data is already written to storage!\n"
"Flash device reset into READ mode.\n",
__func__);
goto mode_read_array; goto mode_read_array;
} }
break; break;
default: default:
pflash_blk_write_abort(pfl);
goto error_flash; goto error_flash;
} }
break; break;
@ -865,6 +871,9 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
pfl->cmd = 0x00; pfl->cmd = 0x00;
pfl->status = 0x80; /* WSM ready */ pfl->status = 0x80; /* WSM ready */
pflash_cfi01_fill_cfi_table(pfl); pflash_cfi01_fill_cfi_table(pfl);
pfl->blk_bytes = g_malloc(pfl->writeblock_size);
pfl->blk_offset = -1;
} }
static void pflash_cfi01_system_reset(DeviceState *dev) static void pflash_cfi01_system_reset(DeviceState *dev)
@ -884,6 +893,8 @@ static void pflash_cfi01_system_reset(DeviceState *dev)
* This model deliberately ignores this delay. * This model deliberately ignores this delay.
*/ */
pfl->status = 0x80; pfl->status = 0x80;
pfl->blk_offset = -1;
} }
static Property pflash_cfi01_properties[] = { static Property pflash_cfi01_properties[] = {

View File

@ -546,7 +546,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
} }
goto reset_flash; goto reset_flash;
} }
trace_pflash_data_write(pfl->name, offset, width, value, 0); trace_pflash_data_write(pfl->name, offset, width, value);
if (!pfl->ro) { if (!pfl->ro) {
p = (uint8_t *)pfl->storage + offset; p = (uint8_t *)pfl->storage + offset;
if (pfl->be) { if (pfl->be) {

View File

@ -12,7 +12,8 @@ fdctrl_tc_pulse(int level) "TC pulse: %u"
pflash_chip_erase_invalid(const char *name, uint64_t offset) "%s: chip erase: invalid address 0x%" PRIx64 pflash_chip_erase_invalid(const char *name, uint64_t offset) "%s: chip erase: invalid address 0x%" PRIx64
pflash_chip_erase_start(const char *name) "%s: start chip erase" pflash_chip_erase_start(const char *name) "%s: start chip erase"
pflash_data_read(const char *name, uint64_t offset, unsigned size, uint32_t value) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x" pflash_data_read(const char *name, uint64_t offset, unsigned size, uint32_t value) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x"
pflash_data_write(const char *name, uint64_t offset, unsigned size, uint32_t value, uint64_t counter) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x counter:0x%016"PRIx64 pflash_data_write(const char *name, uint64_t offset, unsigned size, uint32_t value) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x"
pflash_data_write_block(const char *name, uint64_t offset, unsigned size, uint32_t value, uint64_t counter) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x counter:0x%016"PRIx64
pflash_device_id(const char *name, uint16_t id) "%s: read device ID: 0x%04x" pflash_device_id(const char *name, uint16_t id) "%s: read device ID: 0x%04x"
pflash_device_info(const char *name, uint64_t offset) "%s: read device information offset:0x%04" PRIx64 pflash_device_info(const char *name, uint64_t offset) "%s: read device information offset:0x%04" PRIx64
pflash_erase_complete(const char *name) "%s: sector erase complete" pflash_erase_complete(const char *name) "%s: sector erase complete"
@ -32,7 +33,9 @@ pflash_unlock0_failed(const char *name, uint64_t offset, uint8_t cmd, uint16_t a
pflash_unlock1_failed(const char *name, uint64_t offset, uint8_t cmd) "%s: unlock0 failed 0x%" PRIx64 " 0x%02x" pflash_unlock1_failed(const char *name, uint64_t offset, uint8_t cmd) "%s: unlock0 failed 0x%" PRIx64 " 0x%02x"
pflash_unsupported_device_configuration(const char *name, uint8_t width, uint8_t max) "%s: unsupported device configuration: device_width:%d max_device_width:%d" pflash_unsupported_device_configuration(const char *name, uint8_t width, uint8_t max) "%s: unsupported device configuration: device_width:%d max_device_width:%d"
pflash_write(const char *name, const char *str) "%s: %s" pflash_write(const char *name, const char *str) "%s: %s"
pflash_write_block(const char *name, uint32_t value) "%s: block write: bytes:0x%x" pflash_write_block_start(const char *name, uint32_t value) "%s: block write start: bytes:0x%x"
pflash_write_block_flush(const char *name) "%s: block write flush"
pflash_write_block_abort(const char *name) "%s: block write abort"
pflash_write_block_erase(const char *name, uint64_t offset, uint64_t len) "%s: block erase offset:0x%" PRIx64 " bytes:0x%" PRIx64 pflash_write_block_erase(const char *name, uint64_t offset, uint64_t len) "%s: block erase offset:0x%" PRIx64 " bytes:0x%" PRIx64
pflash_write_failed(const char *name, uint64_t offset, uint8_t cmd) "%s: command failed 0x%" PRIx64 " 0x%02x" pflash_write_failed(const char *name, uint64_t offset, uint8_t cmd) "%s: command failed 0x%" PRIx64 " 0x%02x"
pflash_write_invalid(const char *name, uint8_t cmd) "%s: invalid write for command 0x%02x" pflash_write_invalid(const char *name, uint8_t cmd) "%s: invalid write for command 0x%02x"

View File

@ -115,9 +115,13 @@ static void xen_block_connect(XenDevice *xendev, Error **errp)
return; return;
} }
if (xen_device_frontend_scanf(xendev, "protocol", "%ms", if (xen_device_frontend_scanf(xendev, "protocol", "%ms", &str) != 1) {
&str) != 1) { /* x86 defaults to the 32-bit protocol even for 64-bit guests. */
protocol = BLKIF_PROTOCOL_NATIVE; if (object_dynamic_cast(OBJECT(qdev_get_machine()), "x86-machine")) {
protocol = BLKIF_PROTOCOL_X86_32;
} else {
protocol = BLKIF_PROTOCOL_NATIVE;
}
} else { } else {
if (strcmp(str, XEN_IO_PROTO_ABI_X86_32) == 0) { if (strcmp(str, XEN_IO_PROTO_ABI_X86_32) == 0) {
protocol = BLKIF_PROTOCOL_X86_32; protocol = BLKIF_PROTOCOL_X86_32;

View File

@ -30,6 +30,7 @@
#include "qemu/timer.h" #include "qemu/timer.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "exec/tswap.h"
#include "sysemu/dma.h" #include "sysemu/dma.h"
#define RISCV_DEBUG_HTIF 0 #define RISCV_DEBUG_HTIF 0
@ -209,11 +210,11 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
} else { } else {
uint64_t syscall[8]; uint64_t syscall[8];
cpu_physical_memory_read(payload, syscall, sizeof(syscall)); cpu_physical_memory_read(payload, syscall, sizeof(syscall));
if (syscall[0] == PK_SYS_WRITE && if (tswap64(syscall[0]) == PK_SYS_WRITE &&
syscall[1] == HTIF_DEV_CONSOLE && tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
syscall[3] == HTIF_CONSOLE_CMD_PUTC) { tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
uint8_t ch; uint8_t ch;
cpu_physical_memory_read(syscall[2], &ch, 1); cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
qemu_chr_fe_write(&s->chr, &ch, 1); qemu_chr_fe_write(&s->chr, &ch, 1);
resp = 0x100 | (uint8_t)payload; resp = 0x100 | (uint8_t)payload;
} else { } else {
@ -232,7 +233,8 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
s->tohost = 0; /* clear to indicate we read */ s->tohost = 0; /* clear to indicate we read */
return; return;
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) { } else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1); uint8_t ch = (uint8_t)payload;
qemu_chr_fe_write(&s->chr, &ch, 1);
resp = 0x100 | (uint8_t)payload; resp = 0x100 | (uint8_t)payload;
} else { } else {
qemu_log("HTIF device %d: unknown command\n", device); qemu_log("HTIF device %d: unknown command\n", device);

View File

@ -1105,7 +1105,7 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
{ {
Property *prop = opaque; Property *prop = opaque;
QemuUUID *uuid = object_field_prop_ptr(obj, prop); QemuUUID *uuid = object_field_prop_ptr(obj, prop);
char buffer[UUID_FMT_LEN + 1]; char buffer[UUID_STR_LEN];
char *p = buffer; char *p = buffer;
qemu_uuid_unparse(uuid, buffer); qemu_uuid_unparse(uuid, buffer);

View File

@ -39,12 +39,6 @@ static void cxl_fixed_memory_window_config(CXLState *cxl_state,
return; return;
} }
fw->targets = g_malloc0_n(fw->num_targets, sizeof(*fw->targets));
for (i = 0, target = object->targets; target; i++, target = target->next) {
/* This link cannot be resolved yet, so stash the name for now */
fw->targets[i] = g_strdup(target->value);
}
if (object->size % (256 * MiB)) { if (object->size % (256 * MiB)) {
error_setg(errp, error_setg(errp,
"Size of a CXL fixed memory window must be a multiple of 256MiB"); "Size of a CXL fixed memory window must be a multiple of 256MiB");
@ -64,6 +58,12 @@ static void cxl_fixed_memory_window_config(CXLState *cxl_state,
fw->enc_int_gran = 0; fw->enc_int_gran = 0;
} }
fw->targets = g_malloc0_n(fw->num_targets, sizeof(*fw->targets));
for (i = 0, target = object->targets; target; i++, target = target->next) {
/* This link cannot be resolved yet, so stash the name for now */
fw->targets[i] = g_strdup(target->value);
}
cxl_state->fixed_windows = g_list_append(cxl_state->fixed_windows, cxl_state->fixed_windows = g_list_append(cxl_state->fixed_windows,
g_steal_pointer(&fw)); g_steal_pointer(&fw));

View File

@ -1014,6 +1014,7 @@ static Property ati_vga_properties[] = {
DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id, DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
PCI_DEVICE_ID_ATI_RAGE128_PF), PCI_DEVICE_ID_ATI_RAGE128_PF),
DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false), DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, 3),
DEFINE_PROP_END_OF_LIST() DEFINE_PROP_END_OF_LIST()
}; };
@ -1035,11 +1036,18 @@ static void ati_vga_class_init(ObjectClass *klass, void *data)
k->exit = ati_vga_exit; k->exit = ati_vga_exit;
} }
static void ati_vga_init(Object *o)
{
object_property_set_description(o, "x-pixman", "Use pixman for: "
"1: fill, 2: blit");
}
static const TypeInfo ati_vga_info = { static const TypeInfo ati_vga_info = {
.name = TYPE_ATI_VGA, .name = TYPE_ATI_VGA,
.parent = TYPE_PCI_DEVICE, .parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(ATIVGAState), .instance_size = sizeof(ATIVGAState),
.class_init = ati_vga_class_init, .class_init = ati_vga_class_init,
.instance_init = ati_vga_init,
.interfaces = (InterfaceInfo[]) { .interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ }, { },

View File

@ -92,6 +92,7 @@ void ati_2d_blt(ATIVGAState *s)
switch (s->regs.dp_mix & GMC_ROP3_MASK) { switch (s->regs.dp_mix & GMC_ROP3_MASK) {
case ROP3_SRCCOPY: case ROP3_SRCCOPY:
{ {
bool fallback = false;
unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width); s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
@ -122,27 +123,50 @@ void ati_2d_blt(ATIVGAState *s)
src_bits, dst_bits, src_stride, dst_stride, bpp, bpp, src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y, src_x, src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height); s->regs.dst_width, s->regs.dst_height);
if (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT && if ((s->use_pixman & BIT(1)) &&
s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT &&
s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) { s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits, fallback = !pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits,
src_stride, dst_stride, bpp, bpp, src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y, src_x, src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height); s->regs.dst_width, s->regs.dst_height);
} else { } else if (s->use_pixman & BIT(1)) {
/* FIXME: We only really need a temporary if src and dst overlap */ /* FIXME: We only really need a temporary if src and dst overlap */
int llb = s->regs.dst_width * (bpp / 8); int llb = s->regs.dst_width * (bpp / 8);
int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t)); int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) * uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) *
s->regs.dst_height); s->regs.dst_height);
pixman_blt((uint32_t *)src_bits, tmp, fallback = !pixman_blt((uint32_t *)src_bits, tmp,
src_stride, tmp_stride, bpp, bpp, src_stride, tmp_stride, bpp, bpp,
src_x, src_y, 0, 0, src_x, src_y, 0, 0,
s->regs.dst_width, s->regs.dst_height); s->regs.dst_width, s->regs.dst_height);
pixman_blt(tmp, (uint32_t *)dst_bits, if (!fallback) {
tmp_stride, dst_stride, bpp, bpp, fallback = !pixman_blt(tmp, (uint32_t *)dst_bits,
0, 0, dst_x, dst_y, tmp_stride, dst_stride, bpp, bpp,
s->regs.dst_width, s->regs.dst_height); 0, 0, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
}
g_free(tmp); g_free(tmp);
} else {
fallback = true;
}
if (fallback) {
unsigned int y, i, j, bypp = bpp / 8;
unsigned int src_pitch = src_stride * sizeof(uint32_t);
unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
for (y = 0; y < s->regs.dst_height; y++) {
i = dst_x * bypp;
j = src_x * bypp;
if (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
i += (dst_y + y) * dst_pitch;
j += (src_y + y) * src_pitch;
} else {
i += (dst_y + s->regs.dst_height - 1 - y) * dst_pitch;
j += (src_y + s->regs.dst_height - 1 - y) * src_pitch;
}
memmove(&dst_bits[i], &src_bits[j], s->regs.dst_width * bypp);
}
} }
if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr && if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr + dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr +
@ -180,14 +204,21 @@ void ati_2d_blt(ATIVGAState *s)
dst_stride /= sizeof(uint32_t); dst_stride /= sizeof(uint32_t);
DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n", DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
dst_bits, dst_stride, bpp, dst_bits, dst_stride, bpp, dst_x, dst_y,
dst_x, dst_y, s->regs.dst_width, s->regs.dst_height, filler);
s->regs.dst_width, s->regs.dst_height, if (!(s->use_pixman & BIT(0)) ||
filler); !pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, s->regs.dst_width, s->regs.dst_height, filler)) {
dst_x, dst_y, /* fallback when pixman failed or we don't want to call it */
s->regs.dst_width, s->regs.dst_height, unsigned int x, y, i, bypp = bpp / 8;
filler); unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
for (y = 0; y < s->regs.dst_height; y++) {
i = dst_x * bypp + (dst_y + y) * dst_pitch;
for (x = 0; x < s->regs.dst_width; x++, i += bypp) {
stn_he_p(&dst_bits[i], bypp, filler);
}
}
}
if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr && if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr + dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr +
s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) { s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) {

View File

@ -89,6 +89,7 @@ struct ATIVGAState {
char *model; char *model;
uint16_t dev_id; uint16_t dev_id;
uint8_t mode; uint8_t mode;
uint8_t use_pixman;
bool cursor_guest_mode; bool cursor_guest_mode;
uint16_t cursor_size; uint16_t cursor_size;
uint32_t cursor_offset; uint32_t cursor_offset;

View File

@ -1591,7 +1591,10 @@ static void qxl_set_mode(PCIQXLDevice *d, unsigned int modenr, int loadvm)
} }
d->guest_slots[0].slot = slot; d->guest_slots[0].slot = slot;
assert(qxl_add_memslot(d, 0, devmem, QXL_SYNC) == 0); if (qxl_add_memslot(d, 0, devmem, QXL_SYNC) != 0) {
qxl_set_guest_bug(d, "device isn't initialized yet");
return;
}
d->guest_primary.surface = surface; d->guest_primary.surface = surface;
qxl_create_guest_primary(d, 0, QXL_SYNC); qxl_create_guest_primary(d, 0, QXL_SYNC);

View File

@ -97,6 +97,7 @@ static void ramfb_fw_cfg_write(void *dev, off_t offset, size_t len)
s->width = width; s->width = width;
s->height = height; s->height = height;
qemu_free_displaysurface(s->ds);
s->ds = surface; s->ds = surface;
} }

View File

@ -26,6 +26,7 @@
#include "hw/virtio/virtio-gpu-pixman.h" #include "hw/virtio/virtio-gpu-pixman.h"
#include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-bus.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "migration/blocker.h"
#include "qemu/log.h" #include "qemu/log.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "qapi/error.h" #include "qapi/error.h"
@ -44,6 +45,8 @@ static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
struct virtio_gpu_simple_resource *res); struct virtio_gpu_simple_resource *res);
static void virtio_gpu_reset_bh(void *opaque); static void virtio_gpu_reset_bh(void *opaque);
static Error *blob_mig_blocker;
void virtio_gpu_update_cursor_data(VirtIOGPU *g, void virtio_gpu_update_cursor_data(VirtIOGPU *g,
struct virtio_gpu_scanout *s, struct virtio_gpu_scanout *s,
uint32_t resource_id) uint32_t resource_id)
@ -1283,7 +1286,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
g_free(res); g_free(res);
return -EINVAL; return -EINVAL;
} }
#ifdef WIN32
pixman_image_set_destroy_function(res->image, win32_pixman_image_destroy, res->handle);
#endif
res->addrs = g_new(uint64_t, res->iov_cnt); res->addrs = g_new(uint64_t, res->iov_cnt);
res->iov = g_new(struct iovec, res->iov_cnt); res->iov = g_new(struct iovec, res->iov_cnt);
@ -1374,6 +1379,14 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
error_setg(errp, "blobs and virgl are not compatible (yet)"); error_setg(errp, "blobs and virgl are not compatible (yet)");
return; return;
} }
if (!blob_mig_blocker) {
error_setg(&blob_mig_blocker,
"virtio-gpu blob VMs are currently not migratable.");
}
if (migrate_add_blocker(blob_mig_blocker, errp)) {
return;
}
} }
if (!virtio_gpu_base_device_realize(qdev, if (!virtio_gpu_base_device_realize(qdev,
@ -1400,6 +1413,9 @@ static void virtio_gpu_device_unrealize(DeviceState *qdev)
{ {
VirtIOGPU *g = VIRTIO_GPU(qdev); VirtIOGPU *g = VIRTIO_GPU(qdev);
if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
migrate_del_blocker(blob_mig_blocker);
}
g_clear_pointer(&g->ctrl_bh, qemu_bh_delete); g_clear_pointer(&g->ctrl_bh, qemu_bh_delete);
g_clear_pointer(&g->cursor_bh, qemu_bh_delete); g_clear_pointer(&g->cursor_bh, qemu_bh_delete);
g_clear_pointer(&g->reset_bh, qemu_bh_delete); g_clear_pointer(&g->reset_bh, qemu_bh_delete);

View File

@ -2271,7 +2271,7 @@ static void vmbus_dev_realize(DeviceState *dev, Error **errp)
VMBus *vmbus = VMBUS(qdev_get_parent_bus(dev)); VMBus *vmbus = VMBUS(qdev_get_parent_bus(dev));
BusChild *child; BusChild *child;
Error *err = NULL; Error *err = NULL;
char idstr[UUID_FMT_LEN + 1]; char idstr[UUID_STR_LEN];
assert(!qemu_uuid_is_null(&vdev->instanceid)); assert(!qemu_uuid_is_null(&vdev->instanceid));
@ -2467,7 +2467,7 @@ static char *vmbus_get_dev_path(DeviceState *dev)
static char *vmbus_get_fw_dev_path(DeviceState *dev) static char *vmbus_get_fw_dev_path(DeviceState *dev)
{ {
VMBusDevice *vdev = VMBUS_DEVICE(dev); VMBusDevice *vdev = VMBUS_DEVICE(dev);
char uuid[UUID_FMT_LEN + 1]; char uuid[UUID_STR_LEN];
qemu_uuid_unparse(&vdev->instanceid, uuid); qemu_uuid_unparse(&vdev->instanceid, uuid);
return g_strdup_printf("%s@%s", qdev_fw_name(dev), uuid); return g_strdup_printf("%s@%s", qdev_fw_name(dev), uuid);

View File

@ -226,7 +226,7 @@ static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
return 0; return 0;
} }
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start) static int aspeed_i2c_bus_send(AspeedI2CBus *bus)
{ {
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
int ret = -1; int ret = -1;
@ -236,10 +236,10 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus); uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus); uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
int pool_tx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, int pool_tx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
TX_COUNT); TX_COUNT) + 1;
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) { if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
for (i = pool_start; i < pool_tx_count; i++) { for (i = 0; i < pool_tx_count; i++) {
uint8_t *pool_base = aic->bus_pool_base(bus); uint8_t *pool_base = aic->bus_pool_base(bus);
trace_aspeed_i2c_bus_send("BUF", i + 1, pool_tx_count, trace_aspeed_i2c_bus_send("BUF", i + 1, pool_tx_count,
@ -273,7 +273,7 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
} }
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, TX_DMA_EN, 0); SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, TX_DMA_EN, 0);
} else { } else {
trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, trace_aspeed_i2c_bus_send("BYTE", 0, 1,
bus->regs[reg_byte_buf]); bus->regs[reg_byte_buf]);
ret = i2c_send(bus->bus, bus->regs[reg_byte_buf]); ret = i2c_send(bus->bus, bus->regs[reg_byte_buf]);
} }
@ -293,7 +293,7 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus); uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus); uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus);
int pool_rx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, int pool_rx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
RX_COUNT); RX_SIZE) + 1;
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) { if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) {
uint8_t *pool_base = aic->bus_pool_base(bus); uint8_t *pool_base = aic->bus_pool_base(bus);
@ -418,7 +418,7 @@ static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus); uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus); uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) { if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) {
count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT); count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT) + 1;
} else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_DMA_EN)) { } else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_DMA_EN)) {
count = bus->regs[reg_dma_len]; count = bus->regs[reg_dma_len];
} else { /* BYTE mode */ } else { /* BYTE mode */
@ -446,10 +446,8 @@ static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
*/ */
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value) static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
{ {
uint8_t pool_start = 0;
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus); uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
uint32_t reg_cmd = aspeed_i2c_bus_cmd_offset(bus); uint32_t reg_cmd = aspeed_i2c_bus_cmd_offset(bus);
uint32_t reg_pool_ctrl = aspeed_i2c_bus_pool_ctrl_offset(bus);
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus); uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
if (!aspeed_i2c_check_sram(bus)) { if (!aspeed_i2c_check_sram(bus)) {
@ -483,27 +481,11 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_START_CMD, 0); SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_START_CMD, 0);
/* if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) {
* The START command is also a TX command, as the slave
* address is sent on the bus. Drop the TX flag if nothing
* else needs to be sent in this sequence.
*/
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT)
== 1) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
} else {
/*
* Increase the start index in the TX pool buffer to
* skip the address byte.
*/
pool_start++;
}
} else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) {
if (bus->regs[reg_dma_len] == 0) { if (bus->regs[reg_dma_len] == 0) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0); SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
} }
} else { } else if (!SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0); SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
} }
@ -520,7 +502,7 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, M_TX_CMD)) { if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, M_TX_CMD)) {
aspeed_i2c_set_state(bus, I2CD_MTXD); aspeed_i2c_set_state(bus, I2CD_MTXD);
if (aspeed_i2c_bus_send(bus, pool_start)) { if (aspeed_i2c_bus_send(bus)) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, TX_NAK, 1); SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, TX_NAK, 1);
i2c_end_transfer(bus->bus); i2c_end_transfer(bus->bus);
} else { } else {

View File

@ -1246,13 +1246,8 @@ static int amdvi_int_remap_msi(AMDVIState *iommu,
return -AMDVI_IR_ERR; return -AMDVI_IR_ERR;
} }
if (origin->address & AMDVI_MSI_ADDR_HI_MASK) { if (origin->address < AMDVI_INT_ADDR_FIRST ||
trace_amdvi_err("MSI address high 32 bits non-zero when " origin->address + sizeof(origin->data) > AMDVI_INT_ADDR_LAST + 1) {
"Interrupt Remapping enabled.");
return -AMDVI_IR_ERR;
}
if ((origin->address & AMDVI_MSI_ADDR_LO_MASK) != APIC_DEFAULT_ADDRESS) {
trace_amdvi_err("MSI is not from IOAPIC."); trace_amdvi_err("MSI is not from IOAPIC.");
return -AMDVI_IR_ERR; return -AMDVI_IR_ERR;
} }

View File

@ -210,8 +210,6 @@
#define AMDVI_INT_ADDR_FIRST 0xfee00000 #define AMDVI_INT_ADDR_FIRST 0xfee00000
#define AMDVI_INT_ADDR_LAST 0xfeefffff #define AMDVI_INT_ADDR_LAST 0xfeefffff
#define AMDVI_INT_ADDR_SIZE (AMDVI_INT_ADDR_LAST - AMDVI_INT_ADDR_FIRST + 1) #define AMDVI_INT_ADDR_SIZE (AMDVI_INT_ADDR_LAST - AMDVI_INT_ADDR_FIRST + 1)
#define AMDVI_MSI_ADDR_HI_MASK (0xffffffff00000000ULL)
#define AMDVI_MSI_ADDR_LO_MASK (0x00000000ffffffffULL)
/* SB IOAPIC is always on this device in AMD systems */ /* SB IOAPIC is always on this device in AMD systems */
#define AMDVI_IOAPIC_SB_DEVID PCI_BUILD_BDF(0, PCI_DEVFN(0x14, 0)) #define AMDVI_IOAPIC_SB_DEVID PCI_BUILD_BDF(0, PCI_DEVFN(0x14, 0))

View File

@ -490,6 +490,12 @@ int xen_evtchn_set_callback_param(uint64_t param)
break; break;
} }
/* If the guest has set a per-vCPU callback vector, prefer that. */
if (gsi && kvm_xen_has_vcpu_callback_vector()) {
in_kernel = kvm_xen_has_cap(EVTCHN_SEND);
gsi = 0;
}
if (!ret) { if (!ret) {
/* If vector delivery was turned *off* then tell the kernel */ /* If vector delivery was turned *off* then tell the kernel */
if ((s->callback_param >> CALLBACK_VIA_TYPE_SHIFT) == if ((s->callback_param >> CALLBACK_VIA_TYPE_SHIFT) ==
@ -1129,6 +1135,7 @@ int xen_evtchn_reset_op(struct evtchn_reset *reset)
return -ESRCH; return -ESRCH;
} }
QEMU_IOTHREAD_LOCK_GUARD();
return xen_evtchn_soft_reset(); return xen_evtchn_soft_reset();
} }

View File

@ -541,7 +541,5 @@ int xen_gnttab_reset(void)
s->entries.v1[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access; s->entries.v1[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
s->entries.v1[GNTTAB_RESERVED_XENSTORE].frame = XEN_SPECIAL_PFN(XENSTORE); s->entries.v1[GNTTAB_RESERVED_XENSTORE].frame = XEN_SPECIAL_PFN(XENSTORE);
memset(s->map_track, 0, s->max_frames * ENTRIES_PER_FRAME_V1);
return 0; return 0;
} }

View File

@ -1357,10 +1357,12 @@ static void fire_watch_cb(void *opaque, const char *path, const char *token)
} else { } else {
deliver_watch(s, path, token); deliver_watch(s, path, token);
/* /*
* If the message was queued because there was already ring activity, * Attempt to queue the message into the actual ring, and send
* no need to wake the guest. But if not, we need to send the evtchn. * the event channel notification if any bytes are copied.
*/ */
xen_be_evtchn_notify(s->eh, s->be_port); if (s->rsp_pending && put_rsp(s) > 0) {
xen_be_evtchn_notify(s->eh, s->be_port);
}
} }
} }

View File

@ -41,9 +41,10 @@
#include "trace.h" #include "trace.h"
static void check_cmd(AHCIState *s, int port); static void check_cmd(AHCIState *s, int port);
static int handle_cmd(AHCIState *s, int port, uint8_t slot); static void handle_cmd(AHCIState *s, int port, uint8_t slot);
static void ahci_reset_port(AHCIState *s, int port); static void ahci_reset_port(AHCIState *s, int port);
static bool ahci_write_fis_d2h(AHCIDevice *ad); static bool ahci_write_fis_d2h(AHCIDevice *ad, bool d2h_fis_i);
static void ahci_clear_cmd_issue(AHCIDevice *ad, uint8_t slot);
static void ahci_init_d2h(AHCIDevice *ad); static void ahci_init_d2h(AHCIDevice *ad);
static int ahci_dma_prepare_buf(const IDEDMA *dma, int32_t limit); static int ahci_dma_prepare_buf(const IDEDMA *dma, int32_t limit);
static bool ahci_map_clb_address(AHCIDevice *ad); static bool ahci_map_clb_address(AHCIDevice *ad);
@ -328,6 +329,11 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
ahci_check_irq(s); ahci_check_irq(s);
break; break;
case AHCI_PORT_REG_CMD: case AHCI_PORT_REG_CMD:
if ((pr->cmd & PORT_CMD_START) && !(val & PORT_CMD_START)) {
pr->scr_act = 0;
pr->cmd_issue = 0;
}
/* Block any Read-only fields from being set; /* Block any Read-only fields from being set;
* including LIST_ON and FIS_ON. * including LIST_ON and FIS_ON.
* The spec requires to set ICC bits to zero after the ICC change * The spec requires to set ICC bits to zero after the ICC change
@ -591,9 +597,8 @@ static void check_cmd(AHCIState *s, int port)
if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) { if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) {
for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) { for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) {
if ((pr->cmd_issue & (1U << slot)) && if (pr->cmd_issue & (1U << slot)) {
!handle_cmd(s, port, slot)) { handle_cmd(s, port, slot);
pr->cmd_issue &= ~(1U << slot);
} }
} }
} }
@ -618,9 +623,13 @@ static void ahci_init_d2h(AHCIDevice *ad)
return; return;
} }
if (ahci_write_fis_d2h(ad)) { /*
* For simplicity, do not call ahci_clear_cmd_issue() for this
* ahci_write_fis_d2h(). (The reset value for PxCI is 0.)
*/
if (ahci_write_fis_d2h(ad, true)) {
ad->init_d2h_sent = true; ad->init_d2h_sent = true;
/* We're emulating receiving the first Reg H2D Fis from the device; /* We're emulating receiving the first Reg D2H FIS from the device;
* Update the SIG register, but otherwise proceed as normal. */ * Update the SIG register, but otherwise proceed as normal. */
pr->sig = ((uint32_t)ide_state->hcyl << 24) | pr->sig = ((uint32_t)ide_state->hcyl << 24) |
(ide_state->lcyl << 16) | (ide_state->lcyl << 16) |
@ -658,6 +667,7 @@ static void ahci_reset_port(AHCIState *s, int port)
pr->scr_act = 0; pr->scr_act = 0;
pr->tfdata = 0x7F; pr->tfdata = 0x7F;
pr->sig = 0xFFFFFFFF; pr->sig = 0xFFFFFFFF;
pr->cmd_issue = 0;
d->busy_slot = -1; d->busy_slot = -1;
d->init_d2h_sent = false; d->init_d2h_sent = false;
@ -801,8 +811,14 @@ static void ahci_write_fis_sdb(AHCIState *s, NCQTransferState *ncq_tfs)
pr->scr_act &= ~ad->finished; pr->scr_act &= ~ad->finished;
ad->finished = 0; ad->finished = 0;
/* Trigger IRQ if interrupt bit is set (which currently, it always is) */ /*
if (sdb_fis->flags & 0x40) { * TFES IRQ is always raised if ERR_STAT is set, regardless of I bit.
* If ERR_STAT is not set, trigger SDBS IRQ if interrupt bit is set
* (which currently, it always is).
*/
if (sdb_fis->status & ERR_STAT) {
ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_TFES);
} else if (sdb_fis->flags & 0x40) {
ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS); ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS);
} }
} }
@ -850,7 +866,7 @@ static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len, bool pio_fis_i)
} }
} }
static bool ahci_write_fis_d2h(AHCIDevice *ad) static bool ahci_write_fis_d2h(AHCIDevice *ad, bool d2h_fis_i)
{ {
AHCIPortRegs *pr = &ad->port_regs; AHCIPortRegs *pr = &ad->port_regs;
uint8_t *d2h_fis; uint8_t *d2h_fis;
@ -864,7 +880,7 @@ static bool ahci_write_fis_d2h(AHCIDevice *ad)
d2h_fis = &ad->res_fis[RES_FIS_RFIS]; d2h_fis = &ad->res_fis[RES_FIS_RFIS];
d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H; d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H;
d2h_fis[1] = (1 << 6); /* interrupt bit */ d2h_fis[1] = d2h_fis_i ? (1 << 6) : 0; /* interrupt bit */
d2h_fis[2] = s->status; d2h_fis[2] = s->status;
d2h_fis[3] = s->error; d2h_fis[3] = s->error;
@ -890,7 +906,10 @@ static bool ahci_write_fis_d2h(AHCIDevice *ad)
ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES); ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
} }
ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS); if (d2h_fis_i) {
ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS);
}
return true; return true;
} }
@ -998,7 +1017,6 @@ static void ncq_err(NCQTransferState *ncq_tfs)
ide_state->error = ABRT_ERR; ide_state->error = ABRT_ERR;
ide_state->status = READY_STAT | ERR_STAT; ide_state->status = READY_STAT | ERR_STAT;
ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
qemu_sglist_destroy(&ncq_tfs->sglist); qemu_sglist_destroy(&ncq_tfs->sglist);
ncq_tfs->used = 0; ncq_tfs->used = 0;
} }
@ -1008,7 +1026,7 @@ static void ncq_finish(NCQTransferState *ncq_tfs)
/* If we didn't error out, set our finished bit. Errored commands /* If we didn't error out, set our finished bit. Errored commands
* do not get a bit set for the SDB FIS ACT register, nor do they * do not get a bit set for the SDB FIS ACT register, nor do they
* clear the outstanding bit in scr_act (PxSACT). */ * clear the outstanding bit in scr_act (PxSACT). */
if (!(ncq_tfs->drive->port_regs.scr_err & (1 << ncq_tfs->tag))) { if (ncq_tfs->used) {
ncq_tfs->drive->finished |= (1 << ncq_tfs->tag); ncq_tfs->drive->finished |= (1 << ncq_tfs->tag);
} }
@ -1120,6 +1138,24 @@ static void process_ncq_command(AHCIState *s, int port, const uint8_t *cmd_fis,
return; return;
} }
/*
* A NCQ command clears the bit in PxCI after the command has been QUEUED
* successfully (ERROR not set, BUSY and DRQ cleared).
*
* For NCQ commands, PxCI will always be cleared here.
*
* (Once the NCQ command is COMPLETED, the device will send a SDB FIS with
* the interrupt bit set, which will clear PxSACT and raise an interrupt.)
*/
ahci_clear_cmd_issue(ad, slot);
/*
* In reality, for NCQ commands, PxCI is cleared after receiving a D2H FIS
* without the interrupt bit set, but since ahci_write_fis_d2h() can raise
* an IRQ on error, we need to call them in reverse order.
*/
ahci_write_fis_d2h(ad, false);
ncq_tfs->used = 1; ncq_tfs->used = 1;
ncq_tfs->drive = ad; ncq_tfs->drive = ad;
ncq_tfs->slot = slot; ncq_tfs->slot = slot;
@ -1192,6 +1228,7 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
{ {
IDEState *ide_state = &s->dev[port].port.ifs[0]; IDEState *ide_state = &s->dev[port].port.ifs[0];
AHCICmdHdr *cmd = get_cmd_header(s, port, slot); AHCICmdHdr *cmd = get_cmd_header(s, port, slot);
AHCIDevice *ad = &s->dev[port];
uint16_t opts = le16_to_cpu(cmd->opts); uint16_t opts = le16_to_cpu(cmd->opts);
if (cmd_fis[1] & 0x0F) { if (cmd_fis[1] & 0x0F) {
@ -1211,10 +1248,30 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
case STATE_RUN: case STATE_RUN:
if (cmd_fis[15] & ATA_SRST) { if (cmd_fis[15] & ATA_SRST) {
s->dev[port].port_state = STATE_RESET; s->dev[port].port_state = STATE_RESET;
/*
* When setting SRST in the first H2D FIS in the reset sequence,
* the device does not send a D2H FIS. Host software thus has to
* set the "Clear Busy upon R_OK" bit such that PxCI (and BUSY)
* gets cleared. See AHCI 1.3.1, section 10.4.1 Software Reset.
*/
if (opts & AHCI_CMD_CLR_BUSY) {
ahci_clear_cmd_issue(ad, slot);
}
} }
break; break;
case STATE_RESET: case STATE_RESET:
if (!(cmd_fis[15] & ATA_SRST)) { if (!(cmd_fis[15] & ATA_SRST)) {
/*
* When clearing SRST in the second H2D FIS in the reset
* sequence, the device will execute diagnostics. When this is
* done, the device will send a D2H FIS with the good status.
* See SATA 3.5a Gold, section 11.4 Software reset protocol.
*
* This D2H FIS is the first D2H FIS received from the device,
* and is received regardless if the reset was performed by a
* COMRESET or by setting and clearing the SRST bit. Therefore,
* the logic for this is found in ahci_init_d2h() and not here.
*/
ahci_reset_port(s, port); ahci_reset_port(s, port);
} }
break; break;
@ -1268,11 +1325,19 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
/* Reset transferred byte counter */ /* Reset transferred byte counter */
cmd->status = 0; cmd->status = 0;
/*
* A non-NCQ command clears the bit in PxCI after the command has COMPLETED
* successfully (ERROR not set, BUSY and DRQ cleared).
*
* For non-NCQ commands, PxCI will always be cleared by ahci_cmd_done().
*/
ad->busy_slot = slot;
/* We're ready to process the command in FIS byte 2. */ /* We're ready to process the command in FIS byte 2. */
ide_bus_exec_cmd(&s->dev[port].port, cmd_fis[2]); ide_bus_exec_cmd(&s->dev[port].port, cmd_fis[2]);
} }
static int handle_cmd(AHCIState *s, int port, uint8_t slot) static void handle_cmd(AHCIState *s, int port, uint8_t slot)
{ {
IDEState *ide_state; IDEState *ide_state;
uint64_t tbl_addr; uint64_t tbl_addr;
@ -1283,12 +1348,12 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) { if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
/* Engine currently busy, try again later */ /* Engine currently busy, try again later */
trace_handle_cmd_busy(s, port); trace_handle_cmd_busy(s, port);
return -1; return;
} }
if (!s->dev[port].lst) { if (!s->dev[port].lst) {
trace_handle_cmd_nolist(s, port); trace_handle_cmd_nolist(s, port);
return -1; return;
} }
cmd = get_cmd_header(s, port, slot); cmd = get_cmd_header(s, port, slot);
/* remember current slot handle for later */ /* remember current slot handle for later */
@ -1298,7 +1363,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
ide_state = &s->dev[port].port.ifs[0]; ide_state = &s->dev[port].port.ifs[0];
if (!ide_state->blk) { if (!ide_state->blk) {
trace_handle_cmd_badport(s, port); trace_handle_cmd_badport(s, port);
return -1; return;
} }
tbl_addr = le64_to_cpu(cmd->tbl_addr); tbl_addr = le64_to_cpu(cmd->tbl_addr);
@ -1307,7 +1372,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED); DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED);
if (!cmd_fis) { if (!cmd_fis) {
trace_handle_cmd_badfis(s, port); trace_handle_cmd_badfis(s, port);
return -1; return;
} else if (cmd_len != 0x80) { } else if (cmd_len != 0x80) {
ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS); ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS);
trace_handle_cmd_badmap(s, port, cmd_len); trace_handle_cmd_badmap(s, port, cmd_len);
@ -1331,15 +1396,6 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
out: out:
dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE, dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE,
cmd_len); cmd_len);
if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
/* async command, complete later */
s->dev[port].busy_slot = slot;
return -1;
}
/* done handling the command */
return 0;
} }
/* Transfer PIO data between RAM and device */ /* Transfer PIO data between RAM and device */
@ -1493,22 +1549,39 @@ static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
return 1; return 1;
} }
static void ahci_clear_cmd_issue(AHCIDevice *ad, uint8_t slot)
{
IDEState *ide_state = &ad->port.ifs[0];
if (!(ide_state->status & ERR_STAT) &&
!(ide_state->status & (BUSY_STAT | DRQ_STAT))) {
ad->port_regs.cmd_issue &= ~(1 << slot);
}
}
/* Non-NCQ command is done - This function is never called for NCQ commands. */
static void ahci_cmd_done(const IDEDMA *dma) static void ahci_cmd_done(const IDEDMA *dma)
{ {
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
IDEState *ide_state = &ad->port.ifs[0];
trace_ahci_cmd_done(ad->hba, ad->port_no); trace_ahci_cmd_done(ad->hba, ad->port_no);
/* no longer busy */ /* no longer busy */
if (ad->busy_slot != -1) { if (ad->busy_slot != -1) {
ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot); ahci_clear_cmd_issue(ad, ad->busy_slot);
ad->busy_slot = -1; ad->busy_slot = -1;
} }
/* update d2h status */ /*
ahci_write_fis_d2h(ad); * In reality, for non-NCQ commands, PxCI is cleared after receiving a D2H
* FIS with the interrupt bit set, but since ahci_write_fis_d2h() will raise
* an IRQ, we need to call them in reverse order.
*/
ahci_write_fis_d2h(ad, true);
if (ad->port_regs.cmd_issue && !ad->check_bh) { if (!(ide_state->status & ERR_STAT) &&
ad->port_regs.cmd_issue && !ad->check_bh) {
ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad, ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad,
&ad->mem_reentrancy_guard); &ad->mem_reentrancy_guard);
qemu_bh_schedule(ad->check_bh); qemu_bh_schedule(ad->check_bh);

View File

@ -533,9 +533,9 @@ BlockAIOCB *ide_issue_trim(
void ide_abort_command(IDEState *s) void ide_abort_command(IDEState *s)
{ {
ide_transfer_stop(s);
s->status = READY_STAT | ERR_STAT; s->status = READY_STAT | ERR_STAT;
s->error = ABRT_ERR; s->error = ABRT_ERR;
ide_transfer_stop(s);
} }
static void ide_set_retry(IDEState *s) static void ide_set_retry(IDEState *s)
@ -2515,19 +2515,19 @@ static void ide_dummy_transfer_stop(IDEState *s)
void ide_bus_reset(IDEBus *bus) void ide_bus_reset(IDEBus *bus)
{ {
bus->unit = 0; /* pending async DMA - needs the IDEState before it is reset */
bus->cmd = 0;
ide_reset(&bus->ifs[0]);
ide_reset(&bus->ifs[1]);
ide_clear_hob(bus);
/* pending async DMA */
if (bus->dma->aiocb) { if (bus->dma->aiocb) {
trace_ide_bus_reset_aio(); trace_ide_bus_reset_aio();
blk_aio_cancel(bus->dma->aiocb); blk_aio_cancel(bus->dma->aiocb);
bus->dma->aiocb = NULL; bus->dma->aiocb = NULL;
} }
bus->unit = 0;
bus->cmd = 0;
ide_reset(&bus->ifs[0]);
ide_reset(&bus->ifs[1]);
ide_clear_hob(bus);
/* reset dma provider too */ /* reset dma provider too */
if (bus->dma->ops->reset) { if (bus->dma->ops->reset) {
bus->dma->ops->reset(bus->dma); bus->dma->ops->reset(bus->dma);

View File

@ -351,6 +351,11 @@ static void lasips2_port_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
/*
* The PS/2 mouse port is integreal part of LASI and can not be
* created by users without LASI.
*/
dc->user_creatable = false;
dc->realize = lasips2_port_realize; dc->realize = lasips2_port_realize;
} }
@ -397,6 +402,11 @@ static void lasips2_kbd_port_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass); LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass);
/*
* The PS/2 keyboard port is integreal part of LASI and can not be
* created by users without LASI.
*/
dc->user_creatable = false;
device_class_set_parent_realize(dc, lasips2_kbd_port_realize, device_class_set_parent_realize(dc, lasips2_kbd_port_realize,
&lpdc->parent_realize); &lpdc->parent_realize);
} }

View File

@ -1434,16 +1434,25 @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
idx = icv_find_active(cs, irq); idx = icv_find_active(cs, irq);
if (idx < 0) { if (idx < 0) {
/* No valid list register corresponding to EOI ID */ /*
icv_increment_eoicount(cs); * No valid list register corresponding to EOI ID; if this is a vLPI
* not in the list regs then do nothing; otherwise increment EOI count
*/
if (irq < GICV3_LPI_INTID_START) {
icv_increment_eoicount(cs);
}
} else { } else {
uint64_t lr = cs->ich_lr_el2[idx]; uint64_t lr = cs->ich_lr_el2[idx];
int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0; int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
int lr_gprio = ich_lr_prio(lr) & icv_gprio_mask(cs, grp); int lr_gprio = ich_lr_prio(lr) & icv_gprio_mask(cs, grp);
if (thisgrp == grp && lr_gprio == dropprio) { if (thisgrp == grp && lr_gprio == dropprio) {
if (!icv_eoi_split(env, cs)) { if (!icv_eoi_split(env, cs) || irq >= GICV3_LPI_INTID_START) {
/* Priority drop and deactivate not split: deactivate irq now */ /*
* Priority drop and deactivate not split: deactivate irq now.
* LPIs always get their active state cleared immediately
* because no separate deactivate is expected.
*/
icv_deactivate_irq(cs, idx); icv_deactivate_irq(cs, idx);
} }
} }

View File

@ -64,13 +64,13 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
uint64_t next; uint64_t next;
uint64_t diff; uint64_t diff;
uint64_t rtc_r = cpu_riscv_read_rtc(mtimer); uint64_t rtc = cpu_riscv_read_rtc(mtimer);
/* Compute the relative hartid w.r.t the socket */ /* Compute the relative hartid w.r.t the socket */
hartid = hartid - mtimer->hartid_base; hartid = hartid - mtimer->hartid_base;
mtimer->timecmp[hartid] = value; mtimer->timecmp[hartid] = value;
if (mtimer->timecmp[hartid] <= rtc_r) { if (mtimer->timecmp[hartid] <= rtc) {
/* /*
* If we're setting an MTIMECMP value in the "past", * If we're setting an MTIMECMP value in the "past",
* immediately raise the timer interrupt * immediately raise the timer interrupt
@ -81,7 +81,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
/* otherwise, set up the future timer interrupt */ /* otherwise, set up the future timer interrupt */
qemu_irq_lower(mtimer->timer_irqs[hartid]); qemu_irq_lower(mtimer->timer_irqs[hartid]);
diff = mtimer->timecmp[hartid] - rtc_r; diff = mtimer->timecmp[hartid] - rtc;
/* back to ns (note args switched in muldiv64) */ /* back to ns (note args switched in muldiv64) */
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
@ -208,11 +208,12 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
return; return;
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) { } else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq); uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
uint64_t rtc = cpu_riscv_read_rtc(mtimer);
if (addr == mtimer->time_base) { if (addr == mtimer->time_base) {
if (size == 4) { if (size == 4) {
/* time_lo for RV32/RV64 */ /* time_lo for RV32/RV64 */
mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r; mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
} else { } else {
/* time for RV64 */ /* time for RV64 */
mtimer->time_delta = value - rtc_r; mtimer->time_delta = value - rtc_r;
@ -220,7 +221,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
} else { } else {
if (size == 4) { if (size == 4) {
/* time_hi for RV32/RV64 */ /* time_hi for RV32/RV64 */
mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r; mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r;
} else { } else {
qemu_log_mask(LOG_GUEST_ERROR, qemu_log_mask(LOG_GUEST_ERROR,
"aclint-mtimer: invalid time_hi write: %08x", "aclint-mtimer: invalid time_hi write: %08x",

View File

@ -45,6 +45,7 @@ config LOONGSON3V
select PCI_EXPRESS_GENERIC_BRIDGE select PCI_EXPRESS_GENERIC_BRIDGE
select MSI_NONBROKEN select MSI_NONBROKEN
select FW_CFG_MIPS select FW_CFG_MIPS
select UNIMP
config MIPS_CPS config MIPS_CPS
bool bool

View File

@ -29,7 +29,6 @@
#include "qemu/datadir.h" #include "qemu/datadir.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "elf.h" #include "elf.h"
#include "kvm_mips.h"
#include "hw/char/serial.h" #include "hw/char/serial.h"
#include "hw/intc/loongson_liointc.h" #include "hw/intc/loongson_liointc.h"
#include "hw/mips/mips.h" #include "hw/mips/mips.h"
@ -612,7 +611,6 @@ static void loongson3v_machine_class_init(ObjectClass *oc, void *data)
mc->max_cpus = LOONGSON_MAX_VCPUS; mc->max_cpus = LOONGSON_MAX_VCPUS;
mc->default_ram_id = "loongson3.highram"; mc->default_ram_id = "loongson3.highram";
mc->default_ram_size = 1600 * MiB; mc->default_ram_size = 1600 * MiB;
mc->kvm_type = mips_kvm_type;
mc->minimum_page_bits = 14; mc->minimum_page_bits = 14;
mc->default_nic = "virtio-net-pci"; mc->default_nic = "virtio-net-pci";
} }

View File

@ -63,7 +63,7 @@ static void led_set_state_gpio_handler(void *opaque, int line, int new_state)
LEDState *s = LED(opaque); LEDState *s = LED(opaque);
assert(line == 0); assert(line == 0);
led_set_state(s, !!new_state != s->gpio_active_high); led_set_state(s, !!new_state == s->gpio_active_high);
} }
static void led_reset(DeviceState *dev) static void led_reset(DeviceState *dev)

View File

@ -329,6 +329,13 @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
s->oscclk = g_new0(uint32_t, s->num_oscclk); s->oscclk = g_new0(uint32_t, s->num_oscclk);
} }
static void mps2_scc_finalize(Object *obj)
{
MPS2SCC *s = MPS2_SCC(obj);
g_free(s->oscclk_reset);
}
static const VMStateDescription mps2_scc_vmstate = { static const VMStateDescription mps2_scc_vmstate = {
.name = "mps2-scc", .name = "mps2-scc",
.version_id = 3, .version_id = 3,
@ -385,6 +392,7 @@ static const TypeInfo mps2_scc_info = {
.parent = TYPE_SYS_BUS_DEVICE, .parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MPS2SCC), .instance_size = sizeof(MPS2SCC),
.instance_init = mps2_scc_init, .instance_init = mps2_scc_init,
.instance_finalize = mps2_scc_finalize,
.class_init = mps2_scc_class_init, .class_init = mps2_scc_class_init,
}; };

View File

@ -824,7 +824,8 @@ static void allwinner_sun8i_emac_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_allwinner_sun8i_emac_info, &s->conf, s->nic = qemu_new_nic(&net_allwinner_sun8i_emac_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -453,7 +453,8 @@ static void aw_emac_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_aw_emac_info, &s->conf, s->nic = qemu_new_nic(&net_aw_emac_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
fifo8_create(&s->rx_fifo, RX_FIFO_SIZE); fifo8_create(&s->rx_fifo, RX_FIFO_SIZE);

View File

@ -1633,7 +1633,8 @@ static void gem_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_gem_info, &s->conf, s->nic = qemu_new_nic(&net_gem_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
if (s->jumbo_max_len > MAX_FRAME_SIZE) { if (s->jumbo_max_len > MAX_FRAME_SIZE) {
error_setg(errp, "jumbo-max-len is greater than %d", error_setg(errp, "jumbo-max-len is greater than %d",

View File

@ -108,7 +108,7 @@ void can_sja_single_filter(struct qemu_can_filter *filter,
} }
filter->can_mask = (uint32_t)amr[0] << 3; filter->can_mask = (uint32_t)amr[0] << 3;
filter->can_mask |= (uint32_t)amr[1] << 5; filter->can_mask |= (uint32_t)amr[1] >> 5;
filter->can_mask = ~filter->can_mask & QEMU_CAN_SFF_MASK; filter->can_mask = ~filter->can_mask & QEMU_CAN_SFF_MASK;
if (!(amr[1] & 0x10)) { if (!(amr[1] & 0x10)) {
filter->can_mask |= QEMU_CAN_RTR_FLAG; filter->can_mask |= QEMU_CAN_RTR_FLAG;

View File

@ -913,7 +913,8 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
"dp8393x-regs", SONIC_REG_COUNT << s->it_shift); "dp8393x-regs", SONIC_REG_COUNT << s->it_shift);
s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, s->nic = qemu_new_nic(&net_dp83932_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s); s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);

View File

@ -1687,7 +1687,8 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
macaddr); macaddr);
d->nic = qemu_new_nic(&net_e1000_info, &d->conf, d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
object_get_typename(OBJECT(d)), dev->id, d); object_get_typename(OBJECT(d)), dev->id,
&dev->mem_reentrancy_guard, d);
qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr); qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);

View File

@ -320,7 +320,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr)
int i; int i;
s->nic = qemu_new_nic(&net_e1000e_info, &s->conf, s->nic = qemu_new_nic(&net_e1000e_info, &s->conf,
object_get_typename(OBJECT(s)), dev->id, s); object_get_typename(OBJECT(s)), dev->id, &dev->mem_reentrancy_guard, s);
s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0; s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0;

View File

@ -1874,7 +1874,9 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
nic_reset(s); nic_reset(s);
s->nic = qemu_new_nic(&net_eepro100_info, &s->conf, s->nic = qemu_new_nic(&net_eepro100_info, &s->conf,
object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s); object_get_typename(OBJECT(pci_dev)),
pci_dev->qdev.id,
&pci_dev->qdev.mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
TRACE(OTHER, logout("%s\n", qemu_get_queue(s->nic)->info_str)); TRACE(OTHER, logout("%s\n", qemu_get_queue(s->nic)->info_str));

View File

@ -618,7 +618,8 @@ static void etraxfs_eth_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
object_get_typename(OBJECT(s)), dev->id, s); object_get_typename(OBJECT(s)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
s->phy.read = tdk_read; s->phy.read = tdk_read;

View File

@ -391,7 +391,8 @@ static void etsec_realize(DeviceState *dev, Error **errp)
eTSEC *etsec = ETSEC_COMMON(dev); eTSEC *etsec = ETSEC_COMMON(dev);
etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf, etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
object_get_typename(OBJECT(dev)), dev->id, etsec); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, etsec);
qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_LEGACY); etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_LEGACY);

View File

@ -1110,7 +1110,8 @@ static void ftgmac100_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf, s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -725,7 +725,7 @@ void i82596_common_init(DeviceState *dev, I82596State *s, NetClientInfo *info)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
} }
s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)),
dev->id, s); dev->id, &dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
if (USE_TIMER) { if (USE_TIMER) {

View File

@ -315,7 +315,7 @@ igb_init_net_peer(IGBState *s, PCIDevice *pci_dev, uint8_t *macaddr)
int i; int i;
s->nic = qemu_new_nic(&net_igb_info, &s->conf, s->nic = qemu_new_nic(&net_igb_info, &s->conf,
object_get_typename(OBJECT(s)), dev->id, s); object_get_typename(OBJECT(s)), dev->id, &dev->mem_reentrancy_guard, s);
s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0; s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0;

View File

@ -1334,7 +1334,7 @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf, s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
object_get_typename(OBJECT(dev)), object_get_typename(OBJECT(dev)),
dev->id, s); dev->id, &dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -1361,7 +1361,8 @@ static void lan9118_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_lan9118_info, &s->conf, s->nic = qemu_new_nic(&net_lan9118_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
s->eeprom[0] = 0xa5; s->eeprom[0] = 0xa5;
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {

View File

@ -643,7 +643,8 @@ static void mcf_fec_realize(DeviceState *dev, Error **errp)
mcf_fec_state *s = MCF_FEC_NET(dev); mcf_fec_state *s = MCF_FEC_NET(dev);
s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -255,7 +255,8 @@ static void mipsnet_realize(DeviceState *dev, Error **errp)
sysbus_init_irq(sbd, &s->irq); sysbus_init_irq(sbd, &s->irq);
s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -530,7 +530,8 @@ static void msf2_emac_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_msf2_emac_info, &s->conf, s->nic = qemu_new_nic(&net_msf2_emac_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -350,7 +350,8 @@ static void mv88w8618_eth_realize(DeviceState *dev, Error **errp)
address_space_init(&s->dma_as, s->dma_mr, "emac-dma"); address_space_init(&s->dma_as, s->dma_mr, "emac-dma");
s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf, s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
} }
static const VMStateDescription mv88w8618_eth_vmsd = { static const VMStateDescription mv88w8618_eth_vmsd = {

View File

@ -74,7 +74,8 @@ static void isa_ne2000_realizefn(DeviceState *dev, Error **errp)
ne2000_reset(s); ne2000_reset(s);
s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c, s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
} }

View File

@ -71,7 +71,8 @@ static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp)
s->nic = qemu_new_nic(&net_ne2000_info, &s->c, s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
object_get_typename(OBJECT(pci_dev)), object_get_typename(OBJECT(pci_dev)),
pci_dev->qdev.id, s); pci_dev->qdev.id,
&pci_dev->qdev.mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
} }

View File

@ -821,7 +821,8 @@ static void npcm7xx_emc_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&emc->conf.macaddr); qemu_macaddr_default_if_unset(&emc->conf.macaddr);
emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf, emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf,
object_get_typename(OBJECT(dev)), dev->id, emc); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, emc);
qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a);
} }

View File

@ -732,7 +732,8 @@ static void sysbus_open_eth_realize(DeviceState *dev, Error **errp)
sysbus_init_irq(sbd, &s->irq); sysbus_init_irq(sbd, &s->irq);
s->nic = qemu_new_nic(&net_open_eth_info, &s->conf, s->nic = qemu_new_nic(&net_open_eth_info, &s->conf,
object_get_typename(OBJECT(s)), dev->id, s); object_get_typename(OBJECT(s)), dev->id,
&dev->mem_reentrancy_guard, s);
} }
static void qdev_open_eth_reset(DeviceState *dev) static void qdev_open_eth_reset(DeviceState *dev)

View File

@ -1709,7 +1709,8 @@ void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s); s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s);
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s); s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)),
dev->id, &dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
/* Initialize the PROM */ /* Initialize the PROM */

View File

@ -241,8 +241,8 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name,
port->conf.bootindex = -1; port->conf.bootindex = -1;
port->conf.peers = *peers; port->conf.peers = *peers;
port->nic = qemu_new_nic(&fp_port_info, &port->conf, port->nic = qemu_new_nic(&fp_port_info, &port->conf, sw_name, NULL,
sw_name, NULL, port); &DEVICE(r)->mem_reentrancy_guard, port);
qemu_format_nic_info_str(qemu_get_queue(port->nic), qemu_format_nic_info_str(qemu_get_queue(port->nic),
port->conf.macaddr.a); port->conf.macaddr.a);

View File

@ -3388,7 +3388,8 @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp)
s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8; s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8;
s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf, s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf,
object_get_typename(OBJECT(dev)), d->id, s); object_get_typename(OBJECT(dev)), d->id,
&d->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
s->cplus_txbuffer = NULL; s->cplus_txbuffer = NULL;

View File

@ -783,7 +783,8 @@ static void smc91c111_realize(DeviceState *dev, Error **errp)
sysbus_init_irq(sbd, &s->irq); sysbus_init_irq(sbd, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf, s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
/* ??? Save/restore. */ /* ??? Save/restore. */
} }

View File

@ -325,7 +325,8 @@ static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp)
memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a)); memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a));
dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf, dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev); object_get_typename(OBJECT(sdev)), sdev->qdev.id,
&sdev->qdev.mem_reentrancy_guard, dev);
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue, dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue,

View File

@ -492,7 +492,8 @@ static void stellaris_enet_realize(DeviceState *dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf, s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -1399,7 +1399,7 @@ static void sungem_realize(PCIDevice *pci_dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_sungem_info, &s->conf, s->nic = qemu_new_nic(&net_sungem_info, &s->conf,
object_get_typename(OBJECT(dev)), object_get_typename(OBJECT(dev)),
dev->id, s); dev->id, &dev->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), qemu_format_nic_info_str(qemu_get_queue(s->nic),
s->conf.macaddr.a); s->conf.macaddr.a);
} }

View File

@ -881,7 +881,8 @@ static void sunhme_realize(PCIDevice *pci_dev, Error **errp)
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_sunhme_info, &s->conf, s->nic = qemu_new_nic(&net_sunhme_info, &s->conf,
object_get_typename(OBJECT(d)), d->id, s); object_get_typename(OBJECT(d)), d->id,
&d->mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
} }

View File

@ -983,7 +983,8 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp)
s->nic = qemu_new_nic(&net_tulip_info, &s->c, s->nic = qemu_new_nic(&net_tulip_info, &s->c,
object_get_typename(OBJECT(pci_dev)), object_get_typename(OBJECT(pci_dev)),
pci_dev->qdev.id, s); pci_dev->qdev.id,
&pci_dev->qdev.mem_reentrancy_guard, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
} }

View File

@ -667,6 +667,11 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
n->mergeable_rx_bufs = mergeable_rx_bufs; n->mergeable_rx_bufs = mergeable_rx_bufs;
/*
* Note: when extending the vnet header, please make sure to
* change the vnet header copying logic in virtio_net_flush_tx()
* as well.
*/
if (version_1) { if (version_1) {
n->guest_hdr_len = hash_report ? n->guest_hdr_len = hash_report ?
sizeof(struct virtio_net_hdr_v1_hash) : sizeof(struct virtio_net_hdr_v1_hash) :
@ -2674,7 +2679,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
ssize_t ret; ssize_t ret;
unsigned int out_num; unsigned int out_num;
struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1], *out_sg; struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1], *out_sg;
struct virtio_net_hdr_mrg_rxbuf mhdr; struct virtio_net_hdr_v1_hash vhdr;
elem = virtqueue_pop(q->tx_vq, sizeof(VirtQueueElement)); elem = virtqueue_pop(q->tx_vq, sizeof(VirtQueueElement));
if (!elem) { if (!elem) {
@ -2691,7 +2696,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
} }
if (n->has_vnet_hdr) { if (n->has_vnet_hdr) {
if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) < if (iov_to_buf(out_sg, out_num, 0, &vhdr, n->guest_hdr_len) <
n->guest_hdr_len) { n->guest_hdr_len) {
virtio_error(vdev, "virtio-net header incorrect"); virtio_error(vdev, "virtio-net header incorrect");
virtqueue_detach_element(q->tx_vq, elem, 0); virtqueue_detach_element(q->tx_vq, elem, 0);
@ -2699,8 +2704,8 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
return -EINVAL; return -EINVAL;
} }
if (n->needs_vnet_hdr_swap) { if (n->needs_vnet_hdr_swap) {
virtio_net_hdr_swap(vdev, (void *) &mhdr); virtio_net_hdr_swap(vdev, (void *) &vhdr);
sg2[0].iov_base = &mhdr; sg2[0].iov_base = &vhdr;
sg2[0].iov_len = n->guest_hdr_len; sg2[0].iov_len = n->guest_hdr_len;
out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1, out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1,
out_sg, out_num, out_sg, out_num,
@ -3695,10 +3700,12 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
* Happen when virtio_net_set_netclient_name has been called. * Happen when virtio_net_set_netclient_name has been called.
*/ */
n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
n->netclient_type, n->netclient_name, n); n->netclient_type, n->netclient_name,
&dev->mem_reentrancy_guard, n);
} else { } else {
n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
object_get_typename(OBJECT(dev)), dev->id, n); object_get_typename(OBJECT(dev)), dev->id,
&dev->mem_reentrancy_guard, n);
} }
for (i = 0; i < n->max_queue_pairs; i++) { for (i = 0; i < n->max_queue_pairs; i++) {

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