Compare commits

..

39 Commits

Author SHA1 Message Date
Fabiano Rosas
9f1a8f4e85 tests/qtest/migration: Use the new migration_test_add
Replace the tests registration with the new function that prints tests
names.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:16 -03:00
Fabiano Rosas
47b2c3d4f6 tests/qtest/migration: Add a wrapper to print test names
Our usage of gtest results in us losing the very basic functionality
of "knowing which test failed". The issue is that gtest only prints
test names ("paths" in gtest parlance) once the test has finished, but
we use asserts in the tests and crash gtest itself before it can print
anything. We also use a final abort when the result of g_test_run is
not 0.

Depending on how the test failed/broke we can see the function that
trigged the abort, which may be representative of the test, but it
could also just be some generic function.

We have been relying on the primitive method of looking at the name of
the previous successful test and then looking at the code to figure
out which test should have come next.

Add a wrapper to the test registration that does the job of printing
the test name before running.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:16 -03:00
Fabiano Rosas
086d8dc142 tests/qtest: Add a test for fixed-ram with passing of fds
Add a multifd test for fixed-ram with passing of fds into QEMU. This
is how libvirt will consume the feature.

There are a couple of details to the fdset mechanism:

- multifd needs two distinct file descriptors (not duplicated with
  dup()) on the outgoing side so it can enable O_DIRECT only on the
  channels that write with alignment. The dup() system call creates
  file descriptors that share status flags, of which O_DIRECT is one.

  the incoming side doesn't set O_DIRECT, so it can dup() fds and
  therefore can receive only one in the fdset.

- the open() access mode flags used for the fds passed into QEMU need
  to match the flags QEMU uses to open the file. Currently O_WRONLY
  for src and O_RDONLY for dst.

O_DIRECT is not supported on all systems/filesystems, so run the fdset
test without O_DIRECT if that's the case. The migration code should
still work in that scenario.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:16 -03:00
Fabiano Rosas
4b6eeb2335 migration: Add support for fdset with multifd + file
Allow multifd to use an fdset when migrating to a file. This is useful
for the scenario where the management layer wants to have control over
the migration file.

By receiving the file descriptors directly, QEMU can delegate some
high level operating system operations to the management layer (such
as mandatory access control).

The management layer might also want to add its own headers before the
migration stream.

Enable the "file:/dev/fdset/#" syntax for the multifd migration with
fixed-ram. The fdset should contain two fds on the source side of
migration and 1 fd on the destination side. The two fds should not be
duplicates between themselves.

Multifd enables O_DIRECT on the source side using one of the fds and
keeps the other without the flag. None of the fds should have the
O_DIRECT flag already set.

The fdset mechanism also requires that the open() access mode flags be
the same as what QEMU uses internally: WRONLY for the source fds and
RDONLY for the destination fds.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:16 -03:00
Fabiano Rosas
2cb56cb34e monitor: fdset: Match against O_DIRECT
We're about to enable the use of O_DIRECT in the migration code and
due to the alignment restrictions imposed by filesystems we need to
make sure the flag is only used when doing aligned IO.

The migration will do parallel IO to different regions of a file, so
we need to use more than one file descriptor. Those cannot be obtained
by duplicating (dup()) since duplicated file descriptors share the
file status flags, including O_DIRECT. If one migration channel does
unaligned IO while another sets O_DIRECT to do aligned IO, the
filesystem would fail the unaligned operation.

The add-fd QMP command along with the fdset code are specifically
designed to allow the user to pass a set of file descriptors with
different access flags into QEMU to be later fetched by code that
needs to alternate between those flags when doing IO.

Extend the fdset matching function to behave the same with the
O_DIRECT flag.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:16 -03:00
Fabiano Rosas
5deb383d1a monitor: Extract fdset fd flags comparison into a function
We're about to add one more condition to the flags comparison that
requires an ifdef. Move the code into a separate function now to make
it cleaner after the next patch.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:16 -03:00
Fabiano Rosas
4478aef543 monitor: Honor QMP request for fd removal immediately
We're currently only removing an fd from the fdset if the VM is
running. This causes a QMP call to "remove-fd" to not actually remove
the fd if the VM happens to be stopped.

While the fd would eventually be removed when monitor_fdset_cleanup()
is called again, the user request should be honored and the fd
actually removed. Calling remove-fd + query-fdset shows a recently
removed fd still present.

The runstate_is_running() check was introduced by commit ebe52b592d
("monitor: Prevent removing fd from set during init"), which by the
shortlog indicates that they were trying to avoid removing an
yet-unduplicated fd too early.

I don't see why an fd explicitly removed with qmp_remove_fd() should
be under runstate_is_running(). I'm assuming this was a mistake when
adding the parenthesis around the expression.

Move the runstate_is_running() check to apply only to the
QLIST_EMPTY(dup_fds) side of the expression and ignore it when
mon_fdset_fd->removed has been explicitly set.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:15 -03:00
Fabiano Rosas
a8adda79e7 tests/qtest: Add a test for migration with direct-io and multifd
The test is only allowed to run in systems that know and in
filesystems which support O_DIRECT.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:15 -03:00
Fabiano Rosas
cf07faa04a migration: Add direct-io parameter
Add the direct-io migration parameter that tells the migration code to
use O_DIRECT when opening the migration stream file whenever possible.

This is currently only used for the secondary channels of fixed-ram
migration, which can guarantee that writes are page aligned.

However the parameter could be made to affect other types of
file-based migrations in the future.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:15 -03:00
Fabiano Rosas
b0839f1600 tests/qtest: Add a multifd + fixed-ram migration test
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:15 -03:00
Fabiano Rosas
db401f5302 migration/multifd: Support incoming fixed-ram stream format
For the incoming fixed-ram migration we need to read the ramblock
headers, get the pages bitmap and send the host address of each
non-zero page to the multifd channel thread for writing.

To read from the migration file we need a preadv function that can
read into the iovs in segments of contiguous pages because (as in the
writing case) the file offset applies to the entire iovec.

Usage on HMP is:

(qemu) migrate_set_capability multifd on
(qemu) migrate_set_capability fixed-ram on
(qemu) migrate_set_parameter max-bandwidth 0
(qemu) migrate_set_parameter multifd-channels 8
(qemu) migrate_incoming file:migfile
(qemu) info status
(qemu) c

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:15 -03:00
Fabiano Rosas
ed95cd0446 migration/multifd: Support outgoing fixed-ram stream format
The new fixed-ram stream format uses a file transport and puts ram
pages in the migration file at their respective offsets and can be
done in parallel by using the pwritev system call which takes iovecs
and an offset.

Add support to enabling the new format along with multifd to make use
of the threading and page handling already in place.

This requires multifd to stop sending headers and leaving the stream
format to the fixed-ram code. When it comes time to write the data, we
need to call a version of qio_channel_write that can take an offset.

Usage on HMP is:

(qemu) stop
(qemu) migrate_set_capability multifd on
(qemu) migrate_set_capability fixed-ram on
(qemu) migrate_set_parameter max-bandwidth 0
(qemu) migrate_set_parameter multifd-channels 8
(qemu) migrate file:migfile

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:15 -03:00
Fabiano Rosas
d5bce67e17 migration/ram: Ignore multifd flush when doing fixed-ram migration
Some functionalities of multifd are incompatible with the 'fixed-ram'
migration format.

The MULTIFD_FLUSH flag in particular is not used because in fixed-ram
there is no sinchronicity between migration source and destination so
there is not need for a sync packet. In fact, fixed-ram disables
packets in multifd as a whole.

Make sure RAM_SAVE_FLAG_MULTIFD_FLUSH is never emitted when fixed-ram
is enabled.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:14 -03:00
Fabiano Rosas
b00e0415ed migration/ram: Add a wrapper for fixed-ram shadow bitmap
We'll need to set the shadow_bmap bits from outside ram.c soon and
TARGET_PAGE_BITS is poisoned, so add a wrapper to it.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:14 -03:00
Fabiano Rosas
6822813ae9 migration/multifd: Allow receiving pages without packets
Currently multifd does not need to have knowledge of pages on the
receiving side because all the information needed is within the
packets that come in the stream.

We're about to add support to fixed-ram migration, which cannot use
packets because it expects the ramblock section in the migration file
to contain only the guest pages data.

Add a data structure to transfer pages between the ram migration code
and the multifd receiving threads.

We don't want to reuse MultiFDPages_t for two reasons:

a) multifd threads don't really need to know about the data they're
   receiving.

b) the receiving side has to be stopped to load the pages, which means
   we can experiment with larger granularities than page size when
   transferring data.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:14 -03:00
Fabiano Rosas
23e7e3fc41 migration/multifd: Decouple recv method from pages
Next patch will abstract the type of data being received by the
channels, so do some cleanup now to remove references to pages and
dependency on 'normal_num'.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:14 -03:00
Fabiano Rosas
a071d2f34e multifd: Rename MultiFDSendParams::data to compress_data
Use a more specific name for the compression data so we can use the
generic for the multifd core code.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:14 -03:00
Fabiano Rosas
ab194ba308 io: Add a pwritev/preadv version that takes a discontiguous iovec
For the upcoming support to fixed-ram migration with multifd, we need
to be able to accept an iovec array with non-contiguous data.

Add a pwritev and preadv version that splits the array into contiguous
segments before writing. With that we can have the ram code continue
to add pages in any order and the multifd code continue to send large
arrays for reading and writing.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
Since iovs can be non contiguous, we'd need a separate array on the
side to carry an extra file offset for each of them, so I'm relying on
the fact that iovs are all within a same host page and passing in an
encoded offset that takes the host page into account.
2023-11-14 13:30:14 -03:00
Fabiano Rosas
9954a41782 migration/multifd: Add incoming QIOChannelFile support
On the receiving side we don't need to differentiate between main
channel and threads, so whichever channel is defined first gets to be
the main one. And since there are no packets, use the atomic channel
count to index into the params array.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:13 -03:00
Fabiano Rosas
76798336e4 migration/multifd: Add outgoing QIOChannelFile support
Allow multifd to open file-backed channels. This will be used when
enabling the fixed-ram migration stream format which expects a
seekable transport.

The QIOChannel read and write methods will use the preadv/pwritev
versions which don't update the file offset at each call so we can
reuse the fd without re-opening for every channel.

Note that this is just setup code and multifd cannot yet make use of
the file channels.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:13 -03:00
Fabiano Rosas
ffd3e56398 migration/multifd: Allow multifd without packets
For the upcoming support to the new 'fixed-ram' migration stream
format, we cannot use multifd packets because each write into the
ramblock section in the migration file is expected to contain only the
guest pages. They are written at their respective offsets relative to
the ramblock section header.

There is no space for the packet information and the expected gains
from the new approach come partly from being able to write the pages
sequentially without extraneous data in between.

The new format also doesn't need the packets and all necessary
information can be taken from the standard migration headers with some
(future) changes to multifd code.

Use the presence of the fixed-ram capability to decide whether to send
packets. For now this has no effect as fixed-ram cannot yet be enabled
with multifd.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 13:30:13 -03:00
Nikolay Borisov
1c036fa56a tests/qtest: migration-test: Add tests for fixed-ram file-based migration
Add basic tests for 'fixed-ram' migration.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:24 -03:00
Nikolay Borisov
3eb7f2ab75 migration/ram: Add support for 'fixed-ram' migration restore
Add the necessary code to parse the format changes for the 'fixed-ram'
capability.

One of the more notable changes in behavior is that in the 'fixed-ram'
case ram pages are restored in one go rather than constantly looping
through the migration stream.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:24 -03:00
Nikolay Borisov
43ad5422c9 migration/ram: Add support for 'fixed-ram' outgoing migration
Implement the outgoing migration side for the 'fixed-ram' capability.

A bitmap is introduced to track which pages have been written in the
migration file. Pages are written at a fixed location for every
ramblock. Zero pages are ignored as they'd be zero in the destination
migration as well.

The migration stream is altered to put the dirty pages for a ramblock
after its header instead of having a sequential stream of pages that
follow the ramblock headers. Since all pages have a fixed location,
RAM_SAVE_FLAG_EOS is no longer generated on every migration iteration.

Without fixed-ram (current):        With fixed-ram (new):

 ---------------------               --------------------------------
 | ramblock 1 header |               | ramblock 1 header            |
 ---------------------               --------------------------------
 | ramblock 2 header |               | ramblock 1 fixed-ram header  |
 ---------------------               --------------------------------
 | ...               |               | padding to next 1MB boundary |
 ---------------------               | ...                          |
 | ramblock n header |               --------------------------------
 ---------------------               | ramblock 1 pages             |
 | RAM_SAVE_FLAG_EOS |               | ...                          |
 ---------------------               --------------------------------
 | stream of pages   |               | ramblock 2 header            |
 | (iter 1)          |               --------------------------------
 | ...               |               | ramblock 2 fixed-ram header  |
 ---------------------               --------------------------------
 | RAM_SAVE_FLAG_EOS |               | padding to next 1MB boundary |
 ---------------------               | ...                          |
 | stream of pages   |               --------------------------------
 | (iter 2)          |               | ramblock 2 pages             |
 | ...               |               | ...                          |
 ---------------------               --------------------------------
 | ...               |               | ...                          |
 ---------------------               --------------------------------
                                     | RAM_SAVE_FLAG_EOS            |
                                     --------------------------------
                                     | ...                          |
                                     -------------------------------

where:
 - ramblock header: the generic information for a ramblock, such as
   idstr, used_len, etc.

 - ramblock fixed-ram header: the new information added by this
   feature: bitmap of pages written, bitmap size and offset of pages
   in the migration file.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:23 -03:00
Fabiano Rosas
909f4a40f6 migration: Add fixed-ram URI compatibility check
The fixed-ram migration format needs a channel that supports seeking
to be able to write each page to an arbitrary offset in the migration
stream.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2023-11-14 09:19:23 -03:00
Fabiano Rosas
07acf019b1 migration/ram: Introduce 'fixed-ram' migration capability
Add a new migration capability 'fixed-ram'.

The core of the feature is to ensure that each RAM page has a specific
offset in the resulting migration stream. The reasons why we'd want
such behavior are:

 - The resulting file will have a bounded size, since pages which are
   dirtied multiple times will always go to a fixed location in the
   file, rather than constantly being added to a sequential
   stream. This eliminates cases where a VM with, say, 1G of RAM can
   result in a migration file that's 10s of GBs, provided that the
   workload constantly redirties memory.

 - It paves the way to implement O_DIRECT-enabled save/restore of the
   migration stream as the pages are ensured to be written at aligned
   offsets.

 - It allows the usage of multifd so we can write RAM pages to the
   migration file in parallel.

For now, enabling the capability has no effect. The next couple of
patches implement the core functionality.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:23 -03:00
Fabiano Rosas
b018f49a5b migration/ram: Initialize bitmap with used_length
We don't allow changing the size of the ramblock during migration. Use
used_length instead of max_length when initializing the bitmap.

Suggested-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:23 -03:00
Nikolay Borisov
f9c6197b58 migration/qemu-file: add utility methods for working with seekable channels
Add utility methods that will be needed when implementing 'fixed-ram'
migration capability.

qemu_file_is_seekable
qemu_put_buffer_at
qemu_get_buffer_at
qemu_set_offset
qemu_get_offset

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2023-11-14 09:19:23 -03:00
Nikolay Borisov
1b1da54c69 io: implement io_pwritev/preadv for QIOChannelFile
The upcoming 'fixed-ram' feature will require qemu to write data to
(and restore from) specific offsets of the migration file.

Add a minimal implementation of pwritev/preadv and expose them via the
io_pwritev and io_preadv interfaces.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2023-11-14 09:19:23 -03:00
Nikolay Borisov
d636220e69 io: Add generic pwritev/preadv interface
Introduce basic pwritev/preadv support in the generic channel layer.
Specific implementation will follow for the file channel as this is
required in order to support migration streams with fixed location of
each ram page.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:23 -03:00
Nikolay Borisov
5e25355c4b io: add and implement QIO_CHANNEL_FEATURE_SEEKABLE for channel file
Add a generic QIOChannel feature SEEKABLE which would be used by the
qemu_file* apis. For the time being this will be only implemented for
file channels.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2023-11-14 09:19:22 -03:00
Fabiano Rosas
f978a45734 tests/qtest: Re-enable multifd cancel test
We've found the source of flakiness in this test, so re-enable it.

Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:22 -03:00
Fabiano Rosas
d969e2d0ff migration: Report error in incoming migration
We're not currently reporting the errors set with migrate_set_error()
when incoming migration fails.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-14 09:19:22 -03:00
Fabiano Rosas
87dcefce00 migration/multifd: Allow QIOTask error reporting without an object
The only way for the channel backend to report an error to the multifd
core during creation is by setting the QIOTask error. We must allow
the channel backend to set the error even if the QIOChannel has failed
to be created, which means the QIOTask source object would be NULL.

At multifd_new_send_channel_async() move the QOM casting of the
channel until after we have checked for the QIOTask error.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
context: When doing multifd + file, it's possible that we fail to open
the file. I'll use the empty QIOTask to report the error back to
multifd.
2023-11-14 09:19:22 -03:00
Fabiano Rosas
2b12bbcfed migration/multifd: Stop setting p->ioc before connecting
This is being shadowed but the assignments at
multifd_channel_connect() and multifd_tls_channel_connect() .

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-13 10:59:23 -03:00
Fabiano Rosas
fd92544b1a migration/multifd: Fix multifd_pages_init argument
The 'size' argument is the number of pages that fit in a multifd
packet. Change it to uint32_t and rename.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-13 10:54:11 -03:00
Fabiano Rosas
19b0f579aa migration/multifd: Remove QEMUFile from where it is not needed
Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-13 10:54:11 -03:00
Fabiano Rosas
ae1ea5b13e migration/multifd: Remove MultiFDPages_t::packet_num
This was introduced by commit 34c55a94b1 ("migration: Create multipage
support") and never used.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-13 10:54:11 -03:00
Fabiano Rosas
f6a85fa7a4 tests/qtest/migration: Print migration incoming errors
We're currently just asserting when incoming migration fails. Let's
print the error message from QMP as well.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
2023-11-13 10:54:10 -03:00
520 changed files with 5130 additions and 6716 deletions

View File

@@ -41,7 +41,7 @@ build-system-ubuntu:
variables:
IMAGE: ubuntu2204
CONFIGURE_ARGS: --enable-docs
TARGETS: alpha-softmmu microblaze-softmmu mips64el-softmmu
TARGETS: alpha-softmmu microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build
check-system-ubuntu:
@@ -70,7 +70,7 @@ build-system-debian:
needs:
job: amd64-debian-container
variables:
IMAGE: debian
IMAGE: debian-amd64
CONFIGURE_ARGS: --with-coroutine=sigaltstack
TARGETS: arm-softmmu i386-softmmu riscv64-softmmu sh4eb-softmmu
sparc-softmmu xtensa-softmmu
@@ -82,7 +82,7 @@ check-system-debian:
- job: build-system-debian
artifacts: true
variables:
IMAGE: debian
IMAGE: debian-amd64
MAKE_CHECK_ARGS: check
avocado-system-debian:
@@ -91,7 +91,7 @@ avocado-system-debian:
- job: build-system-debian
artifacts: true
variables:
IMAGE: debian
IMAGE: debian-amd64
MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
@@ -101,7 +101,7 @@ crash-test-debian:
- job: build-system-debian
artifacts: true
variables:
IMAGE: debian
IMAGE: debian-amd64
script:
- cd build
- make NINJA=":" check-venv
@@ -217,36 +217,6 @@ avocado-system-opensuse:
MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64
#
# Flaky tests. We don't run these by default and they are allow fail
# but often the CI system is the only way to trigger the failures.
#
build-system-flaky:
extends:
- .native_build_job_template
- .native_build_artifact_template
needs:
job: amd64-debian-container
variables:
IMAGE: debian
QEMU_JOB_OPTIONAL: 1
TARGETS: aarch64-softmmu arm-softmmu mips64el-softmmu
ppc64-softmmu rx-softmmu s390x-softmmu sh4-softmmu x86_64-softmmu
MAKE_CHECK_ARGS: check-build
avocado-system-flaky:
extends: .avocado_test_job_template
needs:
- job: build-system-flaky
artifacts: true
allow_failure: true
variables:
IMAGE: debian
MAKE_CHECK_ARGS: check-avocado
QEMU_JOB_OPTIONAL: 1
QEMU_TEST_FLAKY_TESTS: 1
AVOCADO_TAGS: flaky
# This jobs explicitly disable TCG (--disable-tcg), KVM is detected by
# the configure script. The container doesn't contain Xen headers so
@@ -619,7 +589,7 @@ build-tools-and-docs-debian:
# when running on 'master' we use pre-existing container
optional: true
variables:
IMAGE: debian
IMAGE: debian-amd64
MAKE_CHECK_ARGS: check-unit ctags TAGS cscope
CONFIGURE_ARGS: --disable-system --disable-user --enable-docs --enable-tools
QEMU_JOB_PUBLISH: 1
@@ -639,7 +609,7 @@ build-tools-and-docs-debian:
# of what topic branch they're currently using
pages:
extends: .base_job_template
image: $CI_REGISTRY_IMAGE/qemu/debian:$QEMU_CI_CONTAINER_TAG
image: $CI_REGISTRY_IMAGE/qemu/debian-amd64:$QEMU_CI_CONTAINER_TAG
stage: test
needs:
- job: build-tools-and-docs-debian
@@ -647,10 +617,7 @@ pages:
- mkdir -p public
# HTML-ised source tree
- make gtags
# 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
- htags -anT --tree-view=filetree -m qemu_init
-t "Welcome to the QEMU sourcecode"
- mv HTML public/src
# Project documentation

View File

@@ -59,13 +59,13 @@ x64-freebsd-13-build:
INSTALL_COMMAND: pkg install -y
TEST_TARGETS: check
aarch64-macos-13-base-build:
aarch64-macos-12-base-build:
extends: .cirrus_build_job
variables:
NAME: macos-13
NAME: macos-12
CIRRUS_VM_INSTANCE_TYPE: macos_instance
CIRRUS_VM_IMAGE_SELECTOR: image
CIRRUS_VM_IMAGE_NAME: ghcr.io/cirruslabs/macos-ventura-base:latest
CIRRUS_VM_IMAGE_NAME: ghcr.io/cirruslabs/macos-monterey-base:latest
CIRRUS_VM_CPUS: 12
CIRRUS_VM_RAM: 24G
UPDATE_COMMAND: brew update
@@ -74,22 +74,6 @@ aarch64-macos-13-base-build:
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
aarch64-macos-14-base-build:
extends: .cirrus_build_job
variables:
NAME: macos-14
CIRRUS_VM_INSTANCE_TYPE: macos_instance
CIRRUS_VM_IMAGE_SELECTOR: image
CIRRUS_VM_IMAGE_NAME: ghcr.io/cirruslabs/macos-sonoma-base:latest
CIRRUS_VM_CPUS: 12
CIRRUS_VM_RAM: 24G
UPDATE_COMMAND: brew update
INSTALL_COMMAND: brew install
PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
QEMU_JOB_OPTIONAL: 1
# The following jobs run VM-based tests via KVM on a Linux-based Cirrus-CI job
.cirrus_kvm_job:

View File

@@ -21,7 +21,7 @@ build_task:
install_script:
- @UPDATE_COMMAND@
- @INSTALL_COMMAND@ @PKGS@
- if test -n "@PYPI_PKGS@" ; then PYLIB=$(@PYTHON@ -c 'import sysconfig; print(sysconfig.get_path("stdlib"))'); rm -f $PYLIB/EXTERNALLY-MANAGED; @PIP3@ install @PYPI_PKGS@ ; fi
- if test -n "@PYPI_PKGS@" ; then @PIP3@ install @PYPI_PKGS@ ; fi
clone_script:
- git clone --depth 100 "$CI_REPOSITORY_URL" .
- git fetch origin "$CI_COMMIT_REF_NAME"

View File

@@ -1,6 +1,6 @@
# THIS FILE WAS AUTO-GENERATED
#
# $ lcitool variables macos-13 qemu
# $ lcitool variables macos-12 qemu
#
# https://gitlab.com/libvirt/libvirt-ci

View File

@@ -1,16 +0,0 @@
# THIS FILE WAS AUTO-GENERATED
#
# $ lcitool variables macos-14 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
CCACHE='/opt/homebrew/bin/ccache'
CPAN_PKGS=''
CROSS_PKGS=''
MAKE='/opt/homebrew/bin/gmake'
NINJA='/opt/homebrew/bin/ninja'
PACKAGING_COMMAND='brew'
PIP3='/opt/homebrew/bin/pip3'
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
PYTHON='/opt/homebrew/bin/python3'

View File

@@ -46,12 +46,6 @@ loongarch-debian-cross-container:
variables:
NAME: debian-loongarch-cross
i686-debian-cross-container:
extends: .container_job_template
stage: containers
variables:
NAME: debian-i686-cross
mips64el-debian-cross-container:
extends: .container_job_template
stage: containers
@@ -101,6 +95,11 @@ cris-fedora-cross-container:
variables:
NAME: fedora-cris-cross
i386-fedora-cross-container:
extends: .container_job_template
variables:
NAME: fedora-i386-cross
win32-fedora-cross-container:
extends: .container_job_template
variables:

View File

@@ -11,7 +11,7 @@ amd64-debian-container:
extends: .container_job_template
stage: containers
variables:
NAME: debian
NAME: debian-amd64
amd64-ubuntu2204-container:
extends: .container_job_template

View File

@@ -37,25 +37,25 @@ cross-arm64-kvm-only:
IMAGE: debian-arm64-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg --without-default-features
cross-i686-user:
cross-i386-user:
extends:
- .cross_user_build_job
- .cross_test_artifacts
needs:
job: i686-debian-cross-container
job: i386-fedora-cross-container
variables:
IMAGE: debian-i686-cross
IMAGE: fedora-i386-cross
MAKE_CHECK_ARGS: check
cross-i686-tci:
cross-i386-tci:
extends:
- .cross_accel_build_job
- .cross_test_artifacts
timeout: 60m
needs:
job: i686-debian-cross-container
job: i386-fedora-cross-container
variables:
IMAGE: debian-i686-cross
IMAGE: fedora-i386-cross
ACCEL: tcg-interpreter
EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins
MAKE_CHECK_ARGS: check check-tcg
@@ -165,7 +165,7 @@ cross-win32-system:
job: win32-fedora-cross-container
variables:
IMAGE: fedora-win32-cross
EXTRA_CONFIGURE_OPTS: --enable-fdt=internal
EXTRA_CONFIGURE_OPTS: --enable-fdt=internal --disable-plugins
CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu m68k-softmmu
microblazeel-softmmu mips64el-softmmu nios2-softmmu
artifacts:

View File

@@ -88,6 +88,7 @@
$MINGW_TARGET-libpng
$MINGW_TARGET-libssh
$MINGW_TARGET-libtasn1
$MINGW_TARGET-libusb
$MINGW_TARGET-lzo2
$MINGW_TARGET-nettle
$MINGW_TARGET-ninja
@@ -97,8 +98,9 @@
$MINGW_TARGET-SDL2
$MINGW_TARGET-SDL2_image
$MINGW_TARGET-snappy
$MINGW_TARGET-zstd
$EXTRA_PACKAGES "
$MINGW_TARGET-spice
$MINGW_TARGET-usbredir
$MINGW_TARGET-zstd "
- Write-Output "Running build at $(Get-Date -Format u)"
- $env:CHERE_INVOKING = 'yes' # Preserve the current working directory
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
@@ -121,8 +123,6 @@ msys2-64bit:
variables:
MINGW_TARGET: mingw-w64-x86_64
MSYSTEM: MINGW64
# msys2 only ship these packages for 64-bit, not 32-bit
EXTRA_PACKAGES: $MINGW_TARGET-libusb $MINGW_TARGET-usbredir $MINGW_TARGET-spice
# do not remove "--without-default-devices"!
# commit 9f8e6cad65a6 ("gitlab-ci: Speed up the msys2-64bit job by using --without-default-devices"
# changed to compile QEMU with the --without-default-devices switch
@@ -131,3 +131,11 @@ msys2-64bit:
# qTests don't run successfully with "--without-default-devices",
# so let's exclude the qtests from CI for now.
TEST_ARGS: --no-suite qtest
msys2-32bit:
extends: .shared_msys2_builder
variables:
MINGW_TARGET: mingw-w64-i686
MSYSTEM: MINGW32
CONFIGURE_ARGS: --target-list=ppc64-softmmu -Ddebug=false -Doptimization=0
TEST_ARGS: --no-suite qtest

View File

@@ -5,21 +5,16 @@
# Required
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
sphinx:
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
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

@@ -131,17 +131,6 @@ K: ^Subject:.*(?i)mips
F: docs/system/target-mips.rst
F: configs/targets/mips*
X86 general architecture support
M: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: configs/devices/i386-softmmu/default.mak
F: configs/targets/i386-softmmu.mak
F: configs/targets/x86_64-softmmu.mak
F: docs/system/target-i386*
F: target/i386/*.[ch]
F: target/i386/Kconfig
F: target/i386/meson.build
Guest CPU cores (TCG)
---------------------
Overall TCG CPUs
@@ -174,7 +163,6 @@ F: include/hw/core/tcg-cpu-ops.h
F: host/include/*/host/cpuinfo.h
F: util/cpuinfo-*.c
F: include/tcg/
F: tests/decode/
FPU emulation
M: Aurelien Jarno <aurelien@aurel32.net>
@@ -669,7 +657,6 @@ F: include/hw/dma/pl080.h
F: hw/dma/pl330.c
F: hw/gpio/pl061.c
F: hw/input/pl050.c
F: include/hw/input/pl050.h
F: hw/intc/pl190.c
F: hw/sd/pl181.c
F: hw/ssi/pl022.c
@@ -940,7 +927,6 @@ F: hw/*/pxa2xx*
F: hw/display/tc6393xb.c
F: hw/gpio/max7310.c
F: hw/gpio/zaurus.c
F: hw/input/ads7846.c
F: hw/misc/mst_fpga.c
F: hw/adc/max111x.c
F: include/hw/adc/max111x.h
@@ -993,9 +979,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/*/stellaris*
F: hw/display/ssd03*
F: include/hw/input/gamepad.h
F: include/hw/timer/stellaris-gptm.h
F: docs/system/arm/stellaris.rst
STM32VLDISCOVERY
@@ -1010,7 +994,6 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/vexpress.c
F: hw/display/sii9022.c
F: docs/system/arm/vexpress.rst
Versatile PB
@@ -2258,7 +2241,7 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
S: Supported
F: hw/virtio/vhost-user-fs*
F: include/hw/virtio/vhost-user-fs.h
L: virtio-fs@lists.linux.dev
L: virtio-fs@redhat.com
virtio-input
M: Gerd Hoffmann <kraxel@redhat.com>

View File

@@ -1 +1 @@
8.2.2
8.1.50

View File

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

View File

@@ -1479,8 +1479,7 @@ int probe_access_full(CPUArchState *env, vaddr addr, int size,
/* Handle clean RAM pages. */
if (unlikely(flags & TLB_NOTDIRTY)) {
int dirtysize = size == 0 ? 1 : size;
notdirty_write(env_cpu(env), addr, dirtysize, *pfull, retaddr);
notdirty_write(env_cpu(env), addr, 1, *pfull, retaddr);
flags &= ~TLB_NOTDIRTY;
}
@@ -1503,8 +1502,7 @@ int probe_access_full_mmu(CPUArchState *env, vaddr addr, int size,
/* Handle clean RAM pages. */
if (unlikely(flags & TLB_NOTDIRTY)) {
int dirtysize = size == 0 ? 1 : size;
notdirty_write(env_cpu(env), addr, dirtysize, *pfull, 0);
notdirty_write(env_cpu(env), addr, 1, *pfull, 0);
flags &= ~TLB_NOTDIRTY;
}
@@ -1526,8 +1524,7 @@ int probe_access_flags(CPUArchState *env, vaddr addr, int size,
/* Handle clean RAM pages. */
if (unlikely(flags & TLB_NOTDIRTY)) {
int dirtysize = size == 0 ? 1 : size;
notdirty_write(env_cpu(env), addr, dirtysize, full, retaddr);
notdirty_write(env_cpu(env), addr, 1, full, retaddr);
flags &= ~TLB_NOTDIRTY;
}
@@ -1563,7 +1560,7 @@ void *probe_access(CPUArchState *env, vaddr addr, int size,
/* Handle clean RAM pages. */
if (flags & TLB_NOTDIRTY) {
notdirty_write(env_cpu(env), addr, size, full, retaddr);
notdirty_write(env_cpu(env), addr, 1, full, retaddr);
}
}

View File

@@ -47,7 +47,7 @@ static bool tb_cmp(const void *ap, const void *bp)
const TranslationBlock *a = ap;
const TranslationBlock *b = bp;
return (a->pc == b->pc &&
return ((tb_cflags(a) & CF_PCREL || a->pc == b->pc) &&
a->cs_base == b->cs_base &&
a->flags == b->flags &&
(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 */
phys_pc = tb_page_addr0(tb);
h = tb_hash_func(phys_pc, tb->pc,
h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb->pc),
tb->flags, tb->cs_base, orig_cflags);
if (!qht_remove(&tb_ctx.htable, tb, h)) {
return;
@@ -983,7 +983,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb)
tb_record(tb);
/* add in the hash table */
h = tb_hash_func(tb_page_addr0(tb), tb->pc,
h = tb_hash_func(tb_page_addr0(tb), (tb->cflags & CF_PCREL ? 0 : tb->pc),
tb->flags, tb->cs_base, tb->cflags);
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) {
/* Force execution of one insn next time. */
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 false;
@@ -1153,7 +1154,8 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
if (current_tb_modified) {
page_collection_unlock(pages);
/* 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();
cpu_loop_exit_noexc(current_cpu);
}

View File

@@ -304,7 +304,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
if (phys_pc == -1) {
/* Generate a one-shot TB with 1 insn in it */
cflags = (cflags & ~CF_COUNT_MASK) | 1;
cflags = (cflags & ~CF_COUNT_MASK) | CF_LAST_IO | 1;
}
max_insns = cflags & CF_COUNT_MASK;
@@ -327,7 +327,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
gen_code_buf = tcg_ctx->code_gen_ptr;
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
tb->pc = pc;
if (!(cflags & CF_PCREL)) {
tb->pc = pc;
}
tb->cs_base = cs_base;
tb->flags = flags;
tb->cflags = cflags;
@@ -630,7 +632,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
* operations only (which execute after completion) so we don't
* double instrument the instruction.
*/
cpu->cflags_next_tb = curr_cflags(cpu) | CF_MEMI_ONLY | n;
cpu->cflags_next_tb = curr_cflags(cpu) | CF_MEMI_ONLY | CF_LAST_IO | n;
if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
vaddr pc = log_pc(cpu, tb);

View File

@@ -89,7 +89,7 @@ static TCGOp *gen_tb_start(DisasContextBase *db, uint32_t cflags)
* 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);
set_can_do_io(db, db->max_insns == 1 && (cflags & CF_LAST_IO));
return icount_start_insn;
}
@@ -151,7 +151,13 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
ops->tb_start(db, cpu);
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);
}
db->plugin_enabled = plugin_enabled;
while (true) {
@@ -163,13 +169,11 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
plugin_gen_insn_start(cpu, db);
}
/*
* Disassemble one instruction. The translate_insn hook should
* update db->pc_next and db->is_jmp to indicate what should be
* done next -- either exiting this loop or locate the start of
* the next instruction.
*/
if (db->num_insns == db->max_insns) {
/* Disassemble one instruction. The translate_insn hook should
update db->pc_next and db->is_jmp to indicate what should be
done next -- either exiting this loop or locate the start of
the next instruction. */
if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) {
/* Accept I/O on the last instruction. */
set_can_do_io(db, true);
}

View File

@@ -1744,7 +1744,7 @@ static AudioState *audio_init(Audiodev *dev, Error **errp)
if (driver) {
done = !audio_driver_init(s, driver, dev, errp);
} else {
error_setg(errp, "Unknown audio driver `%s'", drvname);
error_setg(errp, "Unknown audio driver `%s'\n", drvname);
}
if (!done) {
goto out;
@@ -1758,15 +1758,12 @@ static AudioState *audio_init(Audiodev *dev, Error **errp)
goto out;
}
s->dev = dev = e->dev;
QSIMPLEQ_REMOVE_HEAD(&default_audiodevs, next);
g_free(e);
drvname = AudiodevDriver_str(dev->driver);
driver = audio_driver_lookup(drvname);
if (!audio_driver_init(s, driver, dev, NULL)) {
break;
}
qapi_free_Audiodev(dev);
s->dev = NULL;
QSIMPLEQ_REMOVE_HEAD(&default_audiodevs, next);
}
}

View File

@@ -30,8 +30,7 @@ endforeach
if dbus_display
module_ss = ss.source_set()
module_ss.add(when: [gio, dbus_display1_dep, pixman],
if_true: files('dbusaudio.c'))
module_ss.add(when: [gio, pixman], if_true: files('dbusaudio.c'))
audio_modules += {'dbus': module_ss}
endif

View File

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

39
block.c
View File

@@ -1713,7 +1713,7 @@ open_failed:
bdrv_unref_child(bs, bs->file);
assert(!bs->file);
}
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
g_free(bs->opaque);
bs->opaque = NULL;
@@ -3577,7 +3577,7 @@ int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
bdrv_drained_begin(drain_bs);
bdrv_graph_wrlock(backing_hd);
ret = bdrv_set_backing_hd_drained(bs, backing_hd, errp);
bdrv_graph_wrunlock(backing_hd);
bdrv_graph_wrunlock();
bdrv_drained_end(drain_bs);
bdrv_unref(drain_bs);
@@ -3796,7 +3796,7 @@ BdrvChild *bdrv_open_child(const char *filename,
child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
errp);
aio_context_release(ctx);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
return child;
}
@@ -4652,7 +4652,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
bdrv_graph_wrlock(NULL);
tran_commit(tran);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) {
BlockDriverState *bs = bs_entry->state.bs;
@@ -4671,7 +4671,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
abort:
bdrv_graph_wrlock(NULL);
tran_abort(tran);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
if (bs_entry->prepared) {
@@ -4857,7 +4857,7 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
ret = bdrv_set_file_or_backing_noperm(bs, new_child_bs, is_backing,
tran, errp);
bdrv_graph_wrunlock_ctx(ctx);
bdrv_graph_wrunlock();
if (old_ctx != ctx) {
aio_context_release(ctx);
@@ -5216,7 +5216,7 @@ static void bdrv_close(BlockDriverState *bs)
assert(!bs->backing);
assert(!bs->file);
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
g_free(bs->opaque);
bs->opaque = NULL;
@@ -5511,7 +5511,7 @@ int bdrv_drop_filter(BlockDriverState *bs, Error **errp)
bdrv_drained_begin(child_bs);
bdrv_graph_wrlock(bs);
ret = bdrv_replace_node_common(bs, child_bs, true, true, errp);
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
bdrv_drained_end(child_bs);
return ret;
@@ -5593,7 +5593,7 @@ out:
tran_finalize(tran, ret);
bdrv_refresh_limits(bs_top, NULL, NULL);
bdrv_graph_wrunlock(bs_top);
bdrv_graph_wrunlock();
bdrv_drained_end(bs_top);
bdrv_drained_end(bs_new);
@@ -5631,7 +5631,7 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
tran_finalize(tran, ret);
bdrv_graph_wrunlock(new_bs);
bdrv_graph_wrunlock();
bdrv_drained_end(old_bs);
bdrv_drained_end(new_bs);
bdrv_unref(old_bs);
@@ -5720,7 +5720,7 @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options,
bdrv_drained_begin(new_node_bs);
bdrv_graph_wrlock(new_node_bs);
ret = bdrv_replace_node(bs, new_node_bs, errp);
bdrv_graph_wrunlock(new_node_bs);
bdrv_graph_wrunlock();
bdrv_drained_end(new_node_bs);
bdrv_drained_end(bs);
bdrv_unref(bs);
@@ -6015,7 +6015,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
* That's a FIXME.
*/
bdrv_replace_node_common(top, base, false, false, &local_err);
bdrv_graph_wrunlock(base);
bdrv_graph_wrunlock();
if (local_err) {
error_report_err(local_err);
@@ -6052,7 +6052,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
goto exit;
exit_wrlock:
bdrv_graph_wrunlock(base);
bdrv_graph_wrunlock();
exit:
bdrv_drained_end(base);
bdrv_unref(top);
@@ -7254,16 +7254,6 @@ void bdrv_unref(BlockDriverState *bs)
}
}
static void bdrv_schedule_unref_bh(void *opaque)
{
BlockDriverState *bs = opaque;
AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
bdrv_unref(bs);
aio_context_release(ctx);
}
/*
* Release a BlockDriverState reference while holding the graph write lock.
*
@@ -7277,7 +7267,8 @@ void bdrv_schedule_unref(BlockDriverState *bs)
if (!bs) {
return;
}
aio_bh_schedule_oneshot(qemu_get_aio_context(), bdrv_schedule_unref_bh, bs);
aio_bh_schedule_oneshot(qemu_get_aio_context(),
(QEMUBHFunc *) bdrv_unref, bs);
}
struct BdrvOpBlocker {

View File

@@ -499,7 +499,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
bdrv_graph_wrlock(target);
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
&error_abort);
bdrv_graph_wrunlock(target);
bdrv_graph_wrunlock();
return &job->common;

View File

@@ -68,7 +68,7 @@ typedef struct {
CoQueue bounce_available;
/* The value of the "mem-region-alignment" property */
uint64_t mem_region_alignment;
size_t mem_region_alignment;
/* Can we skip adding/deleting blkio_mem_regions? */
bool needs_mem_regions;

View File

@@ -253,7 +253,7 @@ fail_log:
if (ret < 0) {
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->log_file);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
s->log_file = NULL;
}
fail:
@@ -268,7 +268,7 @@ static void blk_log_writes_close(BlockDriverState *bs)
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->log_file);
s->log_file = NULL;
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
}
static int64_t coroutine_fn GRAPH_RDLOCK
@@ -328,39 +328,22 @@ static void coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
{
BDRVBlkLogWritesState *s = lr->bs->opaque;
/*
* 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;
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
s->nr_entries++;
s->cur_log_sector += entry_nr_sectors;
s->cur_log_sector +=
ROUND_UP(lr->qiov->size, s->sectorsize) >> s->sectorbits;
/*
* 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->log_ret = bdrv_co_pwritev(s->log_file, cur_log_offset, lr->qiov->size,
lr->qiov, 0);
/* Logging for the "write zeroes" operation */
if (lr->log_ret == 0 && lr->zero_size) {
const uint64_t zeroes_offset = entry_offset + qiov_aligned_size;
cur_log_offset = s->cur_log_sector << s->sectorbits;
s->cur_log_sector +=
ROUND_UP(lr->zero_size, s->sectorsize) >> s->sectorbits;
lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, zeroes_offset,
lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, cur_log_offset,
lr->zero_size, 0);
}

View File

@@ -154,7 +154,7 @@ static void blkverify_close(BlockDriverState *bs)
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->test_file);
s->test_file = NULL;
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
}
static int64_t coroutine_fn GRAPH_RDLOCK

View File

@@ -882,14 +882,11 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
/*
* Disassociates the currently associated BlockDriverState from @blk.
*
* The caller must hold the AioContext lock for the BlockBackend.
*/
void blk_remove_bs(BlockBackend *blk)
{
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
BdrvChild *root;
AioContext *ctx;
GLOBAL_STATE_CODE();
@@ -919,10 +916,9 @@ void blk_remove_bs(BlockBackend *blk)
root = blk->root;
blk->root = NULL;
ctx = bdrv_get_aio_context(root->bs);
bdrv_graph_wrlock(root->bs);
bdrv_graph_wrlock(NULL);
bdrv_root_unref_child(root);
bdrv_graph_wrunlock_ctx(ctx);
bdrv_graph_wrunlock();
}
/*
@@ -933,8 +929,6 @@ void blk_remove_bs(BlockBackend *blk)
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
{
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
AioContext *ctx = bdrv_get_aio_context(bs);
GLOBAL_STATE_CODE();
bdrv_ref(bs);
bdrv_graph_wrlock(bs);
@@ -942,7 +936,7 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
blk->perm, blk->shared_perm,
blk, errp);
bdrv_graph_wrunlock_ctx(ctx);
bdrv_graph_wrunlock();
if (blk->root == NULL) {
return -EPERM;
}

View File

@@ -102,7 +102,7 @@ static void commit_abort(Job *job)
bdrv_drained_begin(commit_top_backing_bs);
bdrv_graph_wrlock(commit_top_backing_bs);
bdrv_replace_node(s->commit_top_bs, commit_top_backing_bs, &error_abort);
bdrv_graph_wrunlock(commit_top_backing_bs);
bdrv_graph_wrunlock();
bdrv_drained_end(commit_top_backing_bs);
bdrv_unref(s->commit_top_bs);
@@ -370,19 +370,19 @@ void commit_start(const char *job_id, BlockDriverState *bs,
ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
iter_shared_perms, errp);
if (ret < 0) {
bdrv_graph_wrunlock(top);
bdrv_graph_wrunlock();
goto fail;
}
}
if (bdrv_freeze_backing_chain(commit_top_bs, base, errp) < 0) {
bdrv_graph_wrunlock(top);
bdrv_graph_wrunlock();
goto fail;
}
s->chain_frozen = true;
ret = block_job_add_bdrv(&s->common, "base", base, 0, BLK_PERM_ALL, errp);
bdrv_graph_wrunlock(top);
bdrv_graph_wrunlock();
if (ret < 0) {
goto fail;
@@ -436,7 +436,7 @@ fail:
bdrv_drained_begin(top);
bdrv_graph_wrlock(top);
bdrv_replace_node(commit_top_bs, top, &error_abort);
bdrv_graph_wrunlock(top);
bdrv_graph_wrunlock();
bdrv_drained_end(top);
}
}

View File

@@ -283,7 +283,6 @@ static void vu_blk_drained_begin(void *opaque)
{
VuBlkExport *vexp = opaque;
vexp->vu_server.quiescing = true;
vhost_user_server_detach_aio_context(&vexp->vu_server);
}
@@ -292,23 +291,19 @@ static void vu_blk_drained_end(void *opaque)
{
VuBlkExport *vexp = opaque;
vexp->vu_server.quiescing = false;
vhost_user_server_attach_aio_context(&vexp->vu_server, vexp->export.ctx);
}
/*
* Ensures that bdrv_drained_begin() waits until in-flight requests complete
* and the server->co_trip coroutine has terminated. It will be restarted in
* vhost_user_server_attach_aio_context().
* Ensures that bdrv_drained_begin() waits until in-flight requests complete.
*
* Called with vexp->export.ctx acquired.
*/
static bool vu_blk_drained_poll(void *opaque)
{
VuBlkExport *vexp = opaque;
VuServer *server = &vexp->vu_server;
return server->co_trip || vhost_user_server_has_in_flight(server);
return vhost_user_server_has_in_flight(&vexp->vu_server);
}
static const BlockDevOps vu_blk_dev_ops = {

View File

@@ -161,21 +161,11 @@ void no_coroutine_fn bdrv_graph_wrlock(BlockDriverState *bs)
}
}
void no_coroutine_fn bdrv_graph_wrunlock_ctx(AioContext *ctx)
void bdrv_graph_wrunlock(void)
{
GLOBAL_STATE_CODE();
assert(qatomic_read(&has_writer));
/*
* Release only non-mainloop AioContext. The mainloop often relies on the
* BQL and doesn't lock the main AioContext before doing things.
*/
if (ctx && ctx != qemu_get_aio_context()) {
aio_context_release(ctx);
} else {
ctx = NULL;
}
WITH_QEMU_LOCK_GUARD(&aio_context_list_lock) {
/*
* No need for memory barriers, this works in pair with
@@ -197,17 +187,6 @@ void no_coroutine_fn bdrv_graph_wrunlock_ctx(AioContext *ctx)
* progress.
*/
aio_bh_poll(qemu_get_aio_context());
if (ctx) {
aio_context_acquire(ctx);
}
}
void no_coroutine_fn bdrv_graph_wrunlock(BlockDriverState *bs)
{
AioContext *ctx = bs ? bdrv_get_aio_context(bs) : NULL;
bdrv_graph_wrunlock_ctx(ctx);
}
void coroutine_fn bdrv_graph_co_rdlock(void)

View File

@@ -2619,16 +2619,6 @@ bdrv_co_do_block_status(BlockDriverState *bs, bool want_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:

View File

@@ -773,7 +773,7 @@ static int mirror_exit_common(Job *job)
"would not lead to an abrupt change of visible data",
to_replace->node_name, target_bs->node_name);
}
bdrv_graph_wrunlock(target_bs);
bdrv_graph_wrunlock();
bdrv_drained_end(to_replace);
if (local_err) {
error_report_err(local_err);
@@ -798,7 +798,7 @@ static int mirror_exit_common(Job *job)
block_job_remove_all_bdrv(bjob);
bdrv_graph_wrlock(mirror_top_bs);
bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort);
bdrv_graph_wrunlock(mirror_top_bs);
bdrv_graph_wrunlock();
bdrv_drained_end(target_bs);
bdrv_unref(target_bs);
@@ -1920,7 +1920,7 @@ static BlockJob *mirror_start_job(
BLK_PERM_CONSISTENT_READ,
errp);
if (ret < 0) {
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
goto fail;
}
@@ -1965,17 +1965,17 @@ static BlockJob *mirror_start_job(
ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
iter_shared_perms, errp);
if (ret < 0) {
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
goto fail;
}
}
if (bdrv_freeze_backing_chain(mirror_top_bs, target, errp) < 0) {
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
goto fail;
}
}
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
QTAILQ_INIT(&s->ops_in_flight);
@@ -2006,7 +2006,7 @@ fail:
bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
&error_abort);
bdrv_replace_node(mirror_top_bs, bs, &error_abort);
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
bdrv_drained_end(bs);
bdrv_unref(mirror_top_bs);

View File

@@ -2809,7 +2809,7 @@ qcow2_do_close(BlockDriverState *bs, bool close_data_file)
bdrv_graph_rdunlock_main_loop();
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->data_file);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
s->data_file = NULL;
bdrv_graph_rdlock_main_loop();
}

View File

@@ -1044,7 +1044,7 @@ close_exit:
}
bdrv_unref_child(bs, s->children[i]);
}
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
g_free(s->children);
g_free(opened);
exit:
@@ -1061,7 +1061,7 @@ static void quorum_close(BlockDriverState *bs)
for (i = 0; i < s->num_children; i++) {
bdrv_unref_child(bs, s->children[i]);
}
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
g_free(s->children);
}

View File

@@ -568,7 +568,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
&local_err);
if (local_err) {
error_propagate(errp, local_err);
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
aio_context_release(aio_context);
return;
}
@@ -579,7 +579,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
BDRV_CHILD_DATA, &local_err);
if (local_err) {
error_propagate(errp, local_err);
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
aio_context_release(aio_context);
return;
}
@@ -592,7 +592,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
if (!top_bs || !bdrv_is_root_node(top_bs) ||
!check_top_bs(top_bs, bs)) {
error_setg(errp, "No top_bs or it is invalid");
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
reopen_backing_file(bs, false, NULL);
aio_context_release(aio_context);
return;
@@ -600,7 +600,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
bdrv_op_block_all(top_bs, s->blocker);
bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
s->backup_job = backup_job_create(
NULL, s->secondary_disk->bs, s->hidden_disk->bs,
@@ -696,7 +696,7 @@ static void replication_done(void *opaque, int ret)
s->secondary_disk = NULL;
bdrv_unref_child(bs, s->hidden_disk);
s->hidden_disk = NULL;
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
s->error = 0;
} else {

View File

@@ -196,10 +196,8 @@ bdrv_snapshot_fallback(BlockDriverState *bs)
int bdrv_can_snapshot(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
GLOBAL_STATE_CODE();
if (!drv || !bdrv_is_inserted(bs) || !bdrv_is_writable(bs)) {
if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
return 0;
}
@@ -294,7 +292,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
/* .bdrv_open() will re-attach it */
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, fallback);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp);
open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
@@ -631,6 +629,7 @@ int bdrv_all_goto_snapshot(const char *name,
while (iterbdrvs) {
BlockDriverState *bs = iterbdrvs->data;
AioContext *ctx = bdrv_get_aio_context(bs);
int ret = 0;
bool all_snapshots_includes_bs;
aio_context_acquire(ctx);
@@ -638,8 +637,9 @@ int bdrv_all_goto_snapshot(const char *name,
all_snapshots_includes_bs = bdrv_all_snapshots_includes_bs(bs);
bdrv_graph_rdunlock_main_loop();
ret = (devices || all_snapshots_includes_bs) ?
bdrv_snapshot_goto(bs, name, errp) : 0;
if (devices || all_snapshots_includes_bs) {
ret = bdrv_snapshot_goto(bs, name, errp);
}
aio_context_release(ctx);
if (ret < 0) {
bdrv_graph_rdlock_main_loop();

View File

@@ -99,9 +99,9 @@ static int stream_prepare(Job *job)
}
}
bdrv_graph_wrlock(s->target_bs);
bdrv_graph_wrlock(base);
bdrv_set_backing_hd_drained(unfiltered_bs, base, &local_err);
bdrv_graph_wrunlock(s->target_bs);
bdrv_graph_wrunlock();
/*
* This call will do I/O, so the graph can change again from here on.
@@ -369,7 +369,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
bdrv_graph_wrlock(bs);
if (block_job_add_bdrv(&s->common, "active node", bs, 0,
basic_flags | BLK_PERM_WRITE, errp)) {
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
goto fail;
}
@@ -389,11 +389,11 @@ void stream_start(const char *job_id, BlockDriverState *bs,
ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
basic_flags, errp);
if (ret < 0) {
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
goto fail;
}
}
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
s->base_overlay = base_overlay;
s->above_base = above_base;

View File

@@ -283,7 +283,7 @@ static void vmdk_free_extents(BlockDriverState *bs)
bdrv_unref_child(bs, e->file);
}
}
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
g_free(s->extents);
}
@@ -351,41 +351,29 @@ vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
BDRVVmdkState *s = bs->opaque;
int ret = 0;
size_t desc_buf_size;
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);
desc = g_malloc0(DESC_SIZE);
tmp_desc = g_malloc0(DESC_SIZE);
ret = bdrv_co_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
if (ret < 0) {
goto out;
}
desc[desc_buf_size - 1] = '\0';
desc[DESC_SIZE - 1] = '\0';
tmp_str = strstr(desc, "parentCID");
if (tmp_str == NULL) {
ret = -EINVAL;
goto out;
}
pstrcpy(tmp_desc, desc_buf_size, tmp_str);
pstrcpy(tmp_desc, DESC_SIZE, tmp_str);
p_name = strstr(desc, "CID");
if (p_name != NULL) {
p_name += sizeof("CID");
snprintf(p_name, desc_buf_size - (p_name - desc), "%" PRIx32 "\n", cid);
pstrcat(desc, desc_buf_size, tmp_desc);
snprintf(p_name, DESC_SIZE - (p_name - desc), "%" PRIx32 "\n", cid);
pstrcat(desc, DESC_SIZE, tmp_desc);
}
ret = bdrv_co_pwrite_sync(bs->file, s->desc_offset, desc_buf_size, desc, 0);
ret = bdrv_co_pwrite_sync(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
out:
g_free(desc);
@@ -1249,7 +1237,7 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
bdrv_graph_rdunlock_main_loop();
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
goto out;
}
@@ -1268,7 +1256,7 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
bdrv_graph_rdunlock_main_loop();
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
goto out;
}
@@ -1279,7 +1267,7 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
bdrv_graph_rdunlock_main_loop();
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
goto out;
}
@@ -1289,7 +1277,7 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
bdrv_graph_rdunlock_main_loop();
bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
ret = -ENOTSUP;
goto out;

View File

@@ -1613,7 +1613,7 @@ static void external_snapshot_abort(void *opaque)
bdrv_drained_begin(state->new_bs);
bdrv_graph_wrlock(state->old_bs);
bdrv_replace_node(state->new_bs, state->old_bs, &error_abort);
bdrv_graph_wrunlock(state->old_bs);
bdrv_graph_wrunlock();
bdrv_drained_end(state->new_bs);
bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */
@@ -2400,9 +2400,8 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
bdrv_co_lock(bs);
bdrv_drained_end(bs);
bdrv_co_unlock(bs);
blk_co_unref(blk);
bdrv_co_unlock(bs);
}
void qmp_block_stream(const char *job_id, const char *device,
@@ -3693,7 +3692,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child,
}
out:
bdrv_graph_wrunlock(NULL);
bdrv_graph_wrunlock();
}
BlockJobInfoList *qmp_query_block_jobs(Error **errp)

View File

@@ -212,7 +212,7 @@ void block_job_remove_all_bdrv(BlockJob *job)
g_slist_free_1(l);
}
bdrv_graph_wrunlock_ctx(job->job.aio_context);
bdrv_graph_wrunlock();
}
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
@@ -523,7 +523,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
job = job_create(job_id, &driver->job_driver, txn, bdrv_get_aio_context(bs),
flags, cb, opaque, errp);
if (job == NULL) {
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
return NULL;
}
@@ -563,11 +563,11 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
goto fail;
}
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
return job;
fail:
bdrv_graph_wrunlock(bs);
bdrv_graph_wrunlock();
job_early_fail(&job->job);
return NULL;
}

View File

@@ -235,7 +235,7 @@ static inline abi_long do_obreak(abi_ulong brk_val)
return target_brk;
}
/* Release heap if necessary */
/* Release heap if necesary */
if (new_brk < old_brk) {
target_munmap(new_brk, old_brk - new_brk);

View File

@@ -115,7 +115,7 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp,
}
qarg0 = argp = g_new0(char *, argc + 9);
/* save the first argument for the emulator */
/* save the first agrument for the emulator */
*argp++ = (char *)getprogname();
qargp = argp;
*argp++ = (char *)getprogname();

View File

@@ -146,7 +146,7 @@ static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2,
return ret;
}
/* undocumented nstat(char *path, struct nstat *ub) syscall */
/* undocummented nstat(char *path, struct nstat *ub) syscall */
static abi_long do_freebsd11_nstat(abi_long arg1, abi_long arg2)
{
abi_long ret;
@@ -162,7 +162,7 @@ static abi_long do_freebsd11_nstat(abi_long arg1, abi_long arg2)
return ret;
}
/* undocumented nfstat(int fd, struct nstat *sb) syscall */
/* undocummented nfstat(int fd, struct nstat *sb) syscall */
static abi_long do_freebsd11_nfstat(abi_long arg1, abi_long arg2)
{
abi_long ret;
@@ -175,7 +175,7 @@ static abi_long do_freebsd11_nfstat(abi_long arg1, abi_long arg2)
return ret;
}
/* undocumented nlstat(char *path, struct nstat *ub) syscall */
/* undocummented nlstat(char *path, struct nstat *ub) syscall */
static abi_long do_freebsd11_nlstat(abi_long arg1, abi_long arg2)
{
abi_long ret;

View File

@@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
s->max_size <= 0) {
return TRUE;
}
len = tcp_chr_read_poll(opaque);
if (len > sizeof(buf)) {
len = sizeof(buf);
len = sizeof(buf);
if (len > s->max_size) {
len = s->max_size;
}
size = tcp_chr_recv(chr, (void *)buf, len);
if (size == 0 || (size == -1 && errno != EAGAIN)) {

View File

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

51
configure vendored
View File

@@ -41,7 +41,12 @@ then
# This file is auto-generated by configure to support in-source tree
# 'make' command invocation
build:
ifeq ($(MAKECMDGOALS),)
recurse: all
endif
.NOTPARALLEL: %
%: force
@echo 'changing dir to build for $(MAKE) "$(MAKECMDGOALS)"...'
@$(MAKE) -C build -f Makefile $(MAKECMDGOALS)
@if test "$(MAKECMDGOALS)" = "distclean" && \
@@ -49,9 +54,8 @@ build:
then \
rm -rf build GNUmakefile ; \
fi
%: build
@
.PHONY: build
force: ;
.PHONY: force
GNUmakefile: ;
EOF
@@ -964,14 +968,14 @@ meson="$(cd pyvenv/bin; pwd)/meson"
# Conditionally ensure Sphinx is installed.
mkvenv_online_flag=""
if test "$download" = "enabled" ; then
mkvenv_online_flag=" --online"
mkvenv_flags=""
if test "$download" = "enabled" -a "$docs" = "enabled" ; then
mkvenv_flags="--online"
fi
if test "$docs" != "disabled" ; then
if ! $mkvenv ensuregroup \
$(test "$docs" = "enabled" && echo "$mkvenv_online_flag") \
$mkvenv_flags \
${source_path}/pythondeps.toml docs;
then
if test "$docs" = "enabled" ; then
@@ -1303,8 +1307,8 @@ probe_target_compiler() {
container_cross_cc=${container_cross_prefix}gcc
;;
i386)
container_image=debian-i686-cross
container_cross_prefix=i686-linux-gnu-
container_image=fedora-i386-cross
container_cross_prefix=
;;
loongarch64)
container_image=debian-loongarch-cross
@@ -1387,19 +1391,16 @@ probe_target_compiler() {
done
try=cross
# For softmmu/roms also look for a bi-endian or multilib-enabled host compiler
if [ "${1%softmmu}" != "$1" ] || test "$target_arch" = "$cpu"; then
case "$target_arch:$cpu" in
aarch64_be:aarch64 | \
armeb:arm | \
i386:x86_64 | \
mips*:mips64 | \
ppc*:ppc64 | \
sparc:sparc64 | \
"$cpu:$cpu")
try='native cross' ;;
esac
fi
case "$target_arch:$cpu" in
aarch64_be:aarch64 | \
armeb:arm | \
i386:x86_64 | \
mips*:mips64 | \
ppc*:ppc64 | \
sparc:sparc64 | \
"$cpu:$cpu")
try='native cross' ;;
esac
eval "target_cflags=\${cross_cc_cflags_$target_arch}"
for thistry in $try; do
case $thistry in
@@ -1630,7 +1631,6 @@ if test "$container" != no; then
fi
echo "SUBDIRS=$subdirs" >> $config_host_mak
echo "PYTHON=$python" >> $config_host_mak
echo "MKVENV_ENSUREGROUP=$mkvenv ensuregroup $mkvenv_online_flag" >> $config_host_mak
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
echo "MESON=$meson" >> $config_host_mak
echo "NINJA=$ninja" >> $config_host_mak
@@ -1675,9 +1675,6 @@ fi
mkdir -p tests/tcg
echo "# Automatically generated by configure - do not modify" > $config_host_mak
echo "SRC_PATH=$source_path" >> $config_host_mak
if test "$plugins" = "yes" ; then
echo "CONFIG_PLUGIN=y" >> tests/tcg/$config_host_mak
fi
tcg_tests_targets=
for target in $target_list; do

View File

@@ -49,7 +49,7 @@ all: $(SONAMES)
$(CC) $(CFLAGS) $(PLUGIN_CFLAGS) -c -o $@ $<
ifeq ($(CONFIG_WIN32),y)
lib%$(SO_SUFFIX): %.o win32_linker.o ../../plugins/libqemu_plugin_api.a
lib%$(SO_SUFFIX): %.o win32_linker.o ../../plugins/qemu_plugin_api.lib
$(CC) -shared -o $@ $^ $(LDLIBS)
else ifeq ($(CONFIG_DARWIN),y)
lib%$(SO_SUFFIX): %.o

View File

@@ -327,7 +327,7 @@ virgl_get_resource_info_modifiers(uint32_t resource_id,
#ifdef VIRGL_RENDERER_RESOURCE_INFO_EXT_VERSION
struct virgl_renderer_resource_info_ext info_ext;
ret = virgl_renderer_resource_get_info_ext(resource_id, &info_ext);
if (ret) {
if (ret < 0) {
return ret;
}
@@ -335,7 +335,7 @@ virgl_get_resource_info_modifiers(uint32_t resource_id,
*modifiers = info_ext.modifiers;
#else
ret = virgl_renderer_resource_get_info(resource_id, info);
if (ret) {
if (ret < 0) {
return ret;
}
@@ -372,7 +372,7 @@ virgl_cmd_set_scanout(VuGpu *g,
uint64_t modifiers = 0;
ret = virgl_get_resource_info_modifiers(ss.resource_id, &info,
&modifiers);
if (ret) {
if (ret == -1) {
g_critical("%s: illegal resource specified %d\n",
__func__, ss.resource_id);
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
@@ -401,7 +401,7 @@ virgl_cmd_set_scanout(VuGpu *g,
if (g->use_modifiers) {
/*
* The message uses all the fields set in dmabuf_scanout plus
* The mesage uses all the fields set in dmabuf_scanout plus
* modifiers which is appended after VhostUserGpuDMABUFScanout.
*/
msg.request = VHOST_USER_GPU_DMABUF_SCANOUT2;

View File

@@ -1731,10 +1731,10 @@ format_hex (unsigned long number,
unsigned (== 0). */
static char *
format_dec (long number, char *outbuffer, size_t outsize, int signedp)
format_dec (long number, char *outbuffer, int signedp)
{
last_immediate = number;
snprintf (outbuffer, outsize, signedp ? "%ld" : "%lu", number);
sprintf (outbuffer, signedp ? "%ld" : "%lu", number);
return outbuffer + strlen (outbuffer);
}
@@ -1876,12 +1876,6 @@ print_flags (struct cris_disasm_data *disdata, unsigned int insn, char *cp)
return cp;
}
#define FORMAT_DEC(number, tp, signedp) \
format_dec (number, tp, ({ \
assert(tp >= temp && tp <= temp + sizeof(temp)); \
temp + sizeof(temp) - tp; \
}), signedp)
/* Print out an insn with its operands, and update the info->insn_type
fields. The prefix_opcodep and the rest hold a prefix insn that is
supposed to be output as an address mode. */
@@ -2111,7 +2105,7 @@ print_with_operands (const struct cris_opcode *opcodep,
if ((*cs == 'z' && (insn & 0x20))
|| (opcodep->match == BDAP_QUICK_OPCODE
&& (nbytes <= 2 || buffer[1 + nbytes] == 0)))
tp = FORMAT_DEC (number, tp, signedp);
tp = format_dec (number, tp, signedp);
else
{
unsigned int highbyte = (number >> 24) & 0xff;
@@ -2247,7 +2241,7 @@ print_with_operands (const struct cris_opcode *opcodep,
with_reg_prefix);
if (number >= 0)
*tp++ = '+';
tp = FORMAT_DEC (number, tp, 1);
tp = format_dec (number, tp, 1);
info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
info->target = (prefix_insn >> 12) & 15;
@@ -2346,7 +2340,7 @@ print_with_operands (const struct cris_opcode *opcodep,
{
if (number >= 0)
*tp++ = '+';
tp = FORMAT_DEC (number, tp, 1);
tp = format_dec (number, tp, 1);
}
}
else
@@ -2403,7 +2397,7 @@ print_with_operands (const struct cris_opcode *opcodep,
break;
case 'I':
tp = FORMAT_DEC (insn & 63, tp, 0);
tp = format_dec (insn & 63, tp, 0);
break;
case 'b':
@@ -2432,11 +2426,11 @@ print_with_operands (const struct cris_opcode *opcodep,
break;
case 'c':
tp = FORMAT_DEC (insn & 31, tp, 0);
tp = format_dec (insn & 31, tp, 0);
break;
case 'C':
tp = FORMAT_DEC (insn & 15, tp, 0);
tp = format_dec (insn & 15, tp, 0);
break;
case 'o':
@@ -2469,7 +2463,7 @@ print_with_operands (const struct cris_opcode *opcodep,
if (number > 127)
number = number - 256;
tp = FORMAT_DEC (number, tp, 1);
tp = format_dec (number, tp, 1);
*tp++ = ',';
tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
}
@@ -2480,7 +2474,7 @@ print_with_operands (const struct cris_opcode *opcodep,
break;
case 'i':
tp = FORMAT_DEC ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
tp = format_dec ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
break;
case 'P':

View File

@@ -1968,10 +1968,6 @@ print_insn_hppa (bfd_vma memaddr, disassemble_info *info)
insn = bfd_getb32 (buffer);
info->fprintf_func(info->stream, " %02x %02x %02x %02x ",
(insn >> 24) & 0xff, (insn >> 16) & 0xff,
(insn >> 8) & 0xff, insn & 0xff);
for (i = 0; i < NUMOPCODES; ++i)
{
const struct pa_opcode *opcode = &pa_opcodes[i];
@@ -2830,6 +2826,6 @@ print_insn_hppa (bfd_vma memaddr, disassemble_info *info)
return sizeof (insn);
}
}
info->fprintf_func(info->stream, "<unknown>");
(*info->fprintf_func) (info->stream, "#%8x", insn);
return sizeof (insn);
}

View File

@@ -236,16 +236,6 @@ it. Since all recent x86 hardware from the past >10 years is capable of the
64-bit x86 extensions, a corresponding 64-bit OS should be used instead.
System emulator CPUs
--------------------
Nios II CPU (since 8.2)
'''''''''''''''''''''''
The Nios II architecture is orphan. The ``nios2`` guest CPU support is
deprecated and will be removed in a future version of QEMU.
System emulator machines
------------------------
@@ -264,11 +254,6 @@ These old machine types are quite neglected nowadays and thus might have
various pitfalls with regards to live migration. Use a newer machine type
instead.
Nios II ``10m50-ghrd`` and ``nios2-generic-nommu`` machines (since 8.2)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The Nios II architecture is orphan.
Backend options
---------------
@@ -529,5 +514,5 @@ old compression method (since 8.2)
Compression method fails too much. Too many races. We are going to
remove it if nobody fixes it. For starters, migration-test
compression tests are disabled because they fail randomly. If you need
compression tests are disabled becase they fail randomly. If you need
compression, use multifd compression methods.

View File

@@ -129,9 +129,8 @@ causing most hypervisors to trap and fault on them.
.. warning::
Semihosting inherently bypasses any isolation there may be between
the guest and the host. As a result a program using semihosting can
happily trash your host system. Some semihosting calls (e.g.
``SYS_READC``) can block execution indefinitely. You should only
ever run trusted code with semihosting enabled.
happily trash your host system. You should only ever run trusted
code with semihosting enabled.
Redirection
~~~~~~~~~~~

View File

@@ -122,78 +122,10 @@ functioning. These are performed using a few more helper functions:
indicated by $TMPC.
Python virtual environments and the build process
-------------------------------------------------
An important step in ``configure`` is to create a Python virtual
environment (venv) during the configuration phase. The Python interpreter
comes from the ``--python`` command line option, the ``$PYTHON`` variable
from the environment, or the system PATH, in this order. The venv resides
in the ``pyvenv`` directory in the build tree, and provides consistency
in how the build process runs Python code.
At this stage, ``configure`` also queries the chosen Python interpreter
about QEMU's build dependencies. Note that the build process does *not*
look for ``meson``, ``sphinx-build`` or ``avocado`` binaries in the PATH;
likewise, there are no options such as ``--meson`` or ``--sphinx-build``.
This avoids a potential mismatch, where Meson and Sphinx binaries on the
PATH might operate in a different Python environment than the one chosen
by the user during the build process. On the other hand, it introduces
a potential source of confusion where the user installs a dependency but
``configure`` is not able to find it. When this happens, the dependency
was installed in the ``site-packages`` directory of another interpreter,
or with the wrong ``pip`` program.
If a package is available for the chosen interpreter, ``configure``
prepares a small script that invokes it from the venv itself[#distlib]_.
If not, ``configure`` can also optionally install dependencies in the
virtual environment with ``pip``, either from wheels in ``python/wheels``
or by downloading the package with PyPI. Downloading can be disabled with
``--disable-download``; and anyway, it only happens when a ``configure``
option (currently, only ``--enable-docs``) is explicitly enabled but
the dependencies are not present[#pip]_.
.. [#distlib] The scripts are created based on the package's metadata,
specifically the ``console_script`` entry points. This is the
same mechanism that ``pip`` uses when installing a package.
Currently, in all cases it would be possible to use ``python -m``
instead of an entry point script, which makes this approach a
bit overkill. On the other hand, creating the scripts is
future proof and it makes the contents of the ``pyvenv/bin``
directory more informative. Portability is also not an issue,
because the Python Packaging Authority provides a package
``distlib.scripts`` to perform this task.
.. [#pip] ``pip`` might also be used when running ``make check-avocado``
if downloading is enabled, to ensure that Avocado is
available.
The required versions of the packages are stored in a configuration file
``pythondeps.toml``. The format is custom to QEMU, but it is documented
at the top of the file itself and it should be easy to understand. The
requirements should make it possible to use the version that is packaged
that is provided by supported distros.
When dependencies are downloaded, instead, ``configure`` uses a "known
good" version that is also listed in ``pythondeps.toml``. In this
scenario, ``pythondeps.toml`` behaves like the "lock file" used by
``cargo``, ``poetry`` or other dependency management systems.
Bundled Python packages
-----------------------
Python packages that are **mandatory** dependencies to build QEMU,
but are not available in all supported distros, are bundled with the
QEMU sources. Currently this includes Meson (outdated in CentOS 8
and derivatives, Ubuntu 20.04 and 22.04, and openSUSE Leap) and tomli
(absent in Ubuntu 20.04).
If you need to update these, please do so by modifying and rerunning
``python/scripts/vendor.py``. This script embeds the sha256 hash of
package sources and checks it. The pypi.org web site provides an easy
way to retrieve the sha256 hash of the sources.
Python virtual environments and the QEMU build system
-----------------------------------------------------
TBD
Stage 2: Meson
==============
@@ -444,15 +376,6 @@ This is needed to obey the --python= option passed to the configure
script, which may point to something other than the first python3
binary on the path.
By the time Meson runs, Python dependencies are available in the virtual
environment and should be invoked through the scripts that ``configure``
places under ``pyvenv``. One way to do so is as follows, using Meson's
``find_program`` function::
sphinx_build = find_program(
fs.parent(python.full_path()) / 'sphinx-build',
required: get_option('docs'))
Stage 3: Make
=============
@@ -511,11 +434,6 @@ number of dynamically created files listed later.
executables. Build rules for various subdirectories are included in
other meson.build files spread throughout the QEMU source tree.
``python/scripts/mkvenv.py``
A wrapper for the Python ``venv`` and ``distlib.scripts`` packages.
It handles creating the virtual environment, creating scripts in
``pyvenv/bin``, and calling ``pip`` to install dependencies.
``tests/Makefile.include``
Rules for external test harnesses. These include the TCG tests
and the Avocado-based integration tests.

View File

@@ -572,6 +572,27 @@ Others (especially either older devices or system devices which for
some reason don't have a bus concept) make use of the ``instance id``
for otherwise identically named devices.
Fixed-ram format
----------------
When the ``fixed-ram`` capability is enabled, a slightly different
stream format is used for the RAM section. Instead of having a
sequential stream of pages that follow the RAMBlock headers, the dirty
pages for a RAMBlock follow its header. This ensures that each RAM
page has a fixed offset in the resulting migration file.
The ``fixed-ram`` capability must be enabled in both source and
destination with:
``migrate_set_capability fixed-ram on``
Since pages are written to their relatives offsets and out of order
(due to the memory dirtying patterns), streaming channels such as
sockets are not supported. A seekable channel such as a file is
required. This can be verified in the QIOChannel by the presence of
the QIO_CHANNEL_FEATURE_SEEKABLE. In more practical terms, this
migration format requires the ``file:`` URI when migrating.
Return path
-----------
@@ -1061,7 +1082,7 @@ QEMU version, in this case pc-5.1.
4 - qemu-5.1 -M pc-5.2 -> migrates to -> qemu-5.1 -M pc-5.2
This combination is not possible as the qemu-5.1 doesn't understand
This combination is not possible as the qemu-5.1 doen't understand
pc-5.2 machine type. So nothing to worry here.
Now it comes the interesting ones, when both QEMU processes are
@@ -1214,8 +1235,8 @@ machine types to have the right value::
...
};
A device with different features on both sides
----------------------------------------------
A device with diferent features on both sides
---------------------------------------------
Let's assume that we are using the same QEMU binary on both sides,
just to make the things easier. But we have a device that has
@@ -1294,12 +1315,12 @@ Host B:
$ qemu-system-x86_64 -cpu host,taa-no=off
And you would be able to migrate between them. It is responsibility
And you would be able to migrate between them. It is responsability
of the management application or of the user to make sure that the
configuration is correct. QEMU doesn't know how to look at this kind
of features in general.
Notice that we don't recommend to use -cpu host for migration. It is
Notice that we don't recomend to use -cpu host for migration. It is
used in this example because it makes the example simpler.
Other devices have worse control about individual features. If they

View File

@@ -15,7 +15,7 @@ have default values:
-smp 1,drawers=3,books=3,sockets=2,cores=2,maxcpus=36 \
-device z14-s390x-cpu,core-id=19,entitlement=high \
-device z14-s390x-cpu,core-id=11,entitlement=low \
-device z14-s390x-cpu,core-id=12,entitlement=high \
-device z14-s390x-cpu,core-id=112,entitlement=high \
...
Additions to query-cpus-fast
@@ -78,7 +78,7 @@ modifiers for all configured vCPUs.
"dedicated": true,
"thread-id": 537005,
"props": {
"core-id": 12,
"core-id": 112,
"socket-id": 0,
"drawer-id": 3,
"book-id": 2
@@ -86,7 +86,7 @@ modifiers for all configured vCPUs.
"cpu-state": "operating",
"entitlement": "high",
"qom-path": "/machine/peripheral-anon/device[2]",
"cpu-index": 12,
"cpu-index": 112,
"target": "s390x"
}
]

View File

@@ -62,6 +62,12 @@ To deal with this case, when an I/O access is made we:
- re-compile a single [1]_ instruction block for the current PC
- exit the cpu loop and execute the re-compiled block
The new block is created with the CF_LAST_IO compile flag which
ensures the final instruction translation starts with a call to
gen_io_start() so we don't enter a perpetual loop constantly
recompiling a single instruction block. For translators using the
common translator_loop this is done automatically.
.. [1] sometimes two instructions if dealing with delay slots
Other I/O operations

View File

@@ -668,11 +668,11 @@ suppressing it. More information on the file format can be found here:
https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions
tests/tsan/ignore.tsan - Has TSan warnings we wish to disable
tests/tsan/blacklist.tsan - Has TSan warnings we wish to disable
at compile time for test or debug.
Add flags to configure to enable:
"--extra-cflags=-fsanitize-blacklist=<src path>/tests/tsan/ignore.tsan"
"--extra-cflags=-fsanitize-blacklist=<src path>/tests/tsan/blacklist.tsan"
More information on the file format can be found here under "Blacklist Format":
@@ -1016,7 +1016,7 @@ class. Here's a simple usage example:
self.vm.launch()
res = self.vm.cmd('human-monitor-command',
command_line='info version')
self.assertRegex(res, r'^(\d+\.\d+\.\d)')
self.assertRegexpMatches(res, r'^(\d+\.\d+\.\d)')
To execute your test, run:
@@ -1077,7 +1077,7 @@ and hypothetical example follows:
'human-monitor-command',
command_line='info version')
self.assertEqual(first_res, second_res, third_res)
self.assertEquals(first_res, second_res, third_res)
At test "tear down", ``avocado_qemu.Test`` handles all the QEMUMachines
shutdown.
@@ -1371,33 +1371,23 @@ conditions. For example, tests that take longer to execute when QEMU is
compiled with debug flags. Therefore, the ``AVOCADO_TIMEOUT_EXPECTED`` variable
has been used to determine whether those tests should run or not.
QEMU_TEST_FLAKY_TESTS
^^^^^^^^^^^^^^^^^^^^^
Some tests are not working reliably and thus are disabled by default.
This includes tests that don't run reliably on GitLab's CI which
usually expose real issues that are rarely seen on developer machines
due to the constraints of the CI environment. If you encounter a
similar situation then raise a bug and then mark the test as shown on
the code snippet below:
GITLAB_CI
^^^^^^^^^
A number of tests are flagged to not run on the GitLab CI. Usually because
they proved to the flaky or there are constraints on the CI environment which
would make them fail. If you encounter a similar situation then use that
variable as shown on the code snippet below to skip the test:
.. code::
# See https://gitlab.com/qemu-project/qemu/-/issues/nnnn
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
def test(self):
do_something()
You can also add ``:avocado: tags=flaky`` to the test meta-data so
only the flaky tests can be run as a group:
.. code::
env QEMU_TEST_FLAKY_TESTS=1 ./pyvenv/bin/avocado \
run tests/avocado -filter-by-tags=flaky
Tests should not live in this state forever and should either be fixed
or eventually removed.
QEMU_TEST_FLAKY_TESTS
^^^^^^^^^^^^^^^^^^^^^
Some tests are not working reliably and thus are disabled by default.
Set this environment variable to enable them.
Uninstalling Avocado
~~~~~~~~~~~~~~~~~~~~

View File

@@ -148,9 +148,9 @@ Vring descriptor indices for packed virtqueues
A vring address description
^^^^^^^^^^^^^^^^^^^^^^^^^^^
+-------+-------+------------+------+-----------+-----+
| index | flags | descriptor | used | available | log |
+-------+-------+------------+------+-----------+-----+
+-------+-------+------+------------+------+-----------+-----+
| index | flags | size | descriptor | used | available | log |
+-------+-------+------+------------+------+-----------+-----+
:index: a 32-bit vring index

View File

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

View File

@@ -1,5 +1,3 @@
.. _tpm-device:
===============
QEMU TPM Device
===============

View File

@@ -515,7 +515,7 @@ class QAPIDocDirective(Directive):
except QAPIError as err:
# Launder QAPI parse errors into Sphinx extension errors
# so they are displayed nicely to the user
raise ExtensionError(str(err)) from err
raise ExtensionError(str(err))
def do_parse(self, rstlist, node):
"""Parse rST source lines and add them to the specified node

View File

@@ -70,7 +70,7 @@ the following architecture extensions:
- FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN)
- FEAT_PAN3 (Support for SCTLR_ELx.EPAN)
- FEAT_PAuth (Pointer authentication)
- FEAT_PAuth2 (Enhancements to pointer authentication)
- FEAT_PAuth2 (Enhacements to pointer authentication)
- FEAT_PMULL (PMULL, PMULL2 instructions)
- FEAT_PMUv3p1 (PMU Extensions v3.1)
- FEAT_PMUv3p4 (PMU Extensions v3.4)

View File

@@ -1,39 +1,34 @@
Xen Device Emulation Backend (``xenpvh``)
XENPVH (``xenpvh``)
=========================================
This machine creates a IOREQ server to register/connect with Xen Hypervisor.
This machine is a little unusual compared to others as QEMU just acts
as an IOREQ server to register/connect with Xen Hypervisor. Control of
the VMs themselves is left to the Xen tooling.
When TPM is enabled, this machine also creates a tpm-tis-device at a user input
tpm base address, adds a TPM emulator and connects to a swtpm application
running on host machine via chardev socket. This enables xenpvh to support TPM
functionalities for a guest domain.
When TPM is enabled, this machine also creates a tpm-tis-device at a
user input tpm base address, adds a TPM emulator and connects to a
swtpm application running on host machine via chardev socket. This
enables xenpvh to support TPM functionalities for a guest domain.
More information about TPM use and installing swtpm linux application
can be found in the :ref:`tpm-device` section.
More information about TPM use and installing swtpm linux application can be
found at: docs/specs/tpm.rst.
Example for starting swtpm on host machine:
.. code-block:: console
mkdir /tmp/vtpm2
swtpm socket --tpmstate dir=/tmp/vtpm2 \
--ctrl type=unixio,path=/tmp/vtpm2/swtpm-sock &
--ctrl type=unixio,path=/tmp/vtpm2/swtpm-sock &
Sample QEMU xenpvh commands for running and connecting with Xen:
.. code-block:: console
qemu-system-aarch64 -xen-domid 1 \
-chardev socket,id=libxl-cmd,path=qmp-libxl-1,server=on,wait=off \
-mon chardev=libxl-cmd,mode=control \
-chardev socket,id=libxenstat-cmd,path=qmp-libxenstat-1,server=on,wait=off \
-mon chardev=libxenstat-cmd,mode=control \
-xen-attach -name guest0 -vnc none -display none -nographic \
-machine xenpvh -m 1301 \
-chardev socket,id=chrtpm,path=tmp/vtpm2/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm -machine tpm-base-addr=0x0C000000
-chardev socket,id=libxl-cmd,path=qmp-libxl-1,server=on,wait=off \
-mon chardev=libxl-cmd,mode=control \
-chardev socket,id=libxenstat-cmd,path=qmp-libxenstat-1,server=on,wait=off \
-mon chardev=libxenstat-cmd,mode=control \
-xen-attach -name guest0 -vnc none -display none -nographic \
-machine xenpvh -m 1301 \
-chardev socket,id=chrtpm,path=tmp/vtpm2/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm -machine tpm-base-addr=0x0C000000
In above QEMU command, last two lines are for connecting xenpvh QEMU to swtpm
via chardev socket.

View File

@@ -60,7 +60,7 @@ As TCG cannot track all memory accesses in user-mode there is no
support for watchpoints.
Relocating code
===============
---------------
On modern kernels confusion can be caused by code being relocated by
features such as address space layout randomisation. To avoid
@@ -68,17 +68,6 @@ confusion when debugging such things you either need to update gdb's
view of where things are in memory or perhaps more trivially disable
ASLR when booting the system.
Debugging user-space in system emulation
========================================
While it is technically possible to debug a user-space program running
inside a system image, it does present challenges. Kernel preemption
and execution mode changes between kernel and user mode can make it
hard to follow what's going on. Unless you are specifically trying to
debug some interaction between kernel and user-space you are better
off running your guest program with gdb either in the guest or using
a gdbserver exposed via a port to the outside world.
Debugging multicore machines
============================

View File

@@ -1,9 +1,8 @@
During the graphical emulation, you can use special key combinations from
the following table to change modes. By default the modifier is Ctrl-Alt
(used in the table below) which can be changed with ``-display`` suboption
``mod=`` where appropriate. For example, ``-display sdl,
grab-mod=lshift-lctrl-lalt`` changes the modifier key to Ctrl-Alt-Shift,
while ``-display sdl,grab-mod=rctrl`` changes it to the right Ctrl key.
During the graphical emulation, you can use special key combinations to
change modes. The default key mappings are shown below, but if you use
``-alt-grab`` then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt)
and if you use ``-ctrl-grab`` then the modifier is the right Ctrl key
(instead of Ctrl-Alt):
Ctrl-Alt-f
Toggle full screen
@@ -29,7 +28,7 @@ Ctrl-Alt-n
*3*
Serial port
Ctrl-Alt-g
Ctrl-Alt
Toggle mouse and keyboard grab.
In the virtual consoles, you can use Ctrl-Up, Ctrl-Down, Ctrl-PageUp and

View File

@@ -96,10 +96,6 @@ uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
static int dump_cleanup(DumpState *s)
{
if (s->dump_info.arch_cleanup_fn) {
s->dump_info.arch_cleanup_fn(s);
}
guest_phys_blocks_free(&s->guest_phys_blocks);
memory_mapping_list_free(&s->list);
close(s->fd);

View File

@@ -692,7 +692,7 @@ static int gdb_handle_vcont(const char *p)
/*
* target_count and last_target keep track of how many CPUs we are going to
* step or resume, and a pointer to the state structure of one of them,
* respectively
* respectivelly
*/
int target_count = 0;
CPUState *last_target = NULL;

View File

@@ -24,7 +24,6 @@ enum {
GDB_SIGNAL_TRAP = 5,
GDB_SIGNAL_ABRT = 6,
GDB_SIGNAL_ALRM = 14,
GDB_SIGNAL_STOP = 17,
GDB_SIGNAL_IO = 23,
GDB_SIGNAL_XCPU = 24,
GDB_SIGNAL_UNKNOWN = 143

View File

@@ -183,7 +183,7 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
break;
case RUN_STATE_IO_ERROR:
trace_gdbstub_hit_io_error();
ret = GDB_SIGNAL_STOP;
ret = GDB_SIGNAL_IO;
break;
case RUN_STATE_WATCHDOG:
trace_gdbstub_hit_watchdog();

View File

@@ -28,7 +28,7 @@ atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
static inline Int128 ATTRIBUTE_ATOMIC128_OPT
atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
{
Int128Aligned *ptr_align = __builtin_assume_aligned(ptr, 16);
__int128_t *ptr_align = __builtin_assume_aligned(ptr, 16);
Int128Alias r, c, n;
c.s = cmp;

View File

@@ -58,7 +58,7 @@ atomic16_read_rw(Int128 *ptr)
static inline void ATTRIBUTE_ATOMIC128_OPT
atomic16_set(Int128 *ptr, Int128 val)
{
Int128Aligned *ptr_align = __builtin_assume_aligned(ptr, 16);
__int128_t *ptr_align = __builtin_assume_aligned(ptr, 16);
__int128_t old;
Int128Alias new;

View File

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

View File

@@ -169,8 +169,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
epit_table[i].irq));
}
object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num,
&error_abort);
object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num, &err);
qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fec), errp)) {

View File

@@ -379,8 +379,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
spi_table[i].irq));
}
object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num,
&error_abort);
object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num, &err);
qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->eth), errp)) {
return;

View File

@@ -44,6 +44,7 @@ static void netduino2_init(MachineState *machine)
clock_set_hz(sysclk, SYSCLK_FRQ);
dev = qdev_new(TYPE_STM32F205_SOC);
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
@@ -53,14 +54,8 @@ static void netduino2_init(MachineState *machine)
static void netduino2_machine_init(MachineClass *mc)
{
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m3"),
NULL
};
mc->desc = "Netduino 2 Machine (Cortex-M3)";
mc->init = netduino2_init;
mc->valid_cpu_types = valid_cpu_types;
mc->ignore_memory_transaction_failures = true;
}

View File

@@ -44,6 +44,7 @@ static void netduinoplus2_init(MachineState *machine)
clock_set_hz(sysclk, SYSCLK_FRQ);
dev = qdev_new(TYPE_STM32F405_SOC);
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
@@ -54,14 +55,8 @@ static void netduinoplus2_init(MachineState *machine)
static void netduinoplus2_machine_init(MachineClass *mc)
{
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m4"),
NULL
};
mc->desc = "Netduino Plus 2 Machine (Cortex-M4)";
mc->init = netduinoplus2_init;
mc->valid_cpu_types = valid_cpu_types;
}
DEFINE_MACHINE("netduinoplus2", netduinoplus2_machine_init)

View File

@@ -47,6 +47,7 @@ static void olimex_stm32_h405_init(MachineState *machine)
clock_set_hz(sysclk, SYSCLK_FRQ);
dev = qdev_new(TYPE_STM32F405_SOC);
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
@@ -57,14 +58,9 @@ static void olimex_stm32_h405_init(MachineState *machine)
static void olimex_stm32_h405_machine_init(MachineClass *mc)
{
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m4"),
NULL
};
mc->desc = "Olimex STM32-H405 (Cortex-M4)";
mc->init = olimex_stm32_h405_init;
mc->valid_cpu_types = valid_cpu_types;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
/* SRAM pre-allocated as part of the SoC instantiation */
mc->default_ram_size = 0;

View File

@@ -675,8 +675,6 @@ static void smmu_base_reset_hold(Object *obj)
{
SMMUState *s = ARM_SMMU(obj);
memset(s->smmu_pcibus_by_bus_num, 0, sizeof(s->smmu_pcibus_by_bus_num));
g_hash_table_remove_all(s->configs);
g_hash_table_remove_all(s->iotlb);
}

View File

@@ -115,7 +115,7 @@ static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp)
/* Init ARMv7m */
armv7m = DEVICE(&s->armv7m);
qdev_prop_set_uint32(armv7m, "num-irq", 61);
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
qdev_prop_set_bit(armv7m, "enable-bitband", true);
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
qdev_connect_clock_in(armv7m, "refclk", s->refclk);
@@ -180,12 +180,17 @@ static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp)
create_unimplemented_device("CRC", 0x40023000, 0x400);
}
static Property stm32f100_soc_properties[] = {
DEFINE_PROP_STRING("cpu-type", STM32F100State, cpu_type),
DEFINE_PROP_END_OF_LIST(),
};
static void stm32f100_soc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = stm32f100_soc_realize;
/* No vmstate or reset required: device has no internal state */
device_class_set_props(dc, stm32f100_soc_properties);
}
static const TypeInfo stm32f100_soc_info = {

View File

@@ -127,7 +127,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
armv7m = DEVICE(&s->armv7m);
qdev_prop_set_uint32(armv7m, "num-irq", 96);
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
qdev_prop_set_bit(armv7m, "enable-bitband", true);
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
qdev_connect_clock_in(armv7m, "refclk", s->refclk);
@@ -201,12 +201,17 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
}
}
static Property stm32f205_soc_properties[] = {
DEFINE_PROP_STRING("cpu-type", STM32F205State, cpu_type),
DEFINE_PROP_END_OF_LIST(),
};
static void stm32f205_soc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = stm32f205_soc_realize;
/* No vmstate or reset required: device has no internal state */
device_class_set_props(dc, stm32f205_soc_properties);
}
static const TypeInfo stm32f205_soc_info = {

View File

@@ -149,7 +149,7 @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
armv7m = DEVICE(&s->armv7m);
qdev_prop_set_uint32(armv7m, "num-irq", 96);
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
qdev_prop_set_bit(armv7m, "enable-bitband", true);
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
qdev_connect_clock_in(armv7m, "refclk", s->refclk);
@@ -287,11 +287,17 @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
create_unimplemented_device("RNG", 0x50060800, 0x400);
}
static Property stm32f405_soc_properties[] = {
DEFINE_PROP_STRING("cpu-type", STM32F405State, cpu_type),
DEFINE_PROP_END_OF_LIST(),
};
static void stm32f405_soc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = stm32f405_soc_realize;
device_class_set_props(dc, stm32f405_soc_properties);
/* No vmstate or reset required: device has no internal state */
}

View File

@@ -47,6 +47,7 @@ static void stm32vldiscovery_init(MachineState *machine)
clock_set_hz(sysclk, SYSCLK_FRQ);
dev = qdev_new(TYPE_STM32F100_SOC);
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
@@ -57,14 +58,8 @@ static void stm32vldiscovery_init(MachineState *machine)
static void stm32vldiscovery_machine_init(MachineClass *mc)
{
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-m3"),
NULL
};
mc->desc = "ST STM32VLDISCOVERY (Cortex-M3)";
mc->init = stm32vldiscovery_init;
mc->valid_cpu_types = valid_cpu_types;
}
DEFINE_MACHINE("stm32vldiscovery", stm32vldiscovery_machine_init)

View File

@@ -576,8 +576,7 @@ static void fdt_add_gic_node(VirtMachineState *vms)
if (vms->virt) {
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_GIC_MAINT_IRQ),
GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
}
} else {
@@ -601,8 +600,7 @@ static void fdt_add_gic_node(VirtMachineState *vms)
2, vms->memmap[VIRT_GIC_VCPU].base,
2, vms->memmap[VIRT_GIC_VCPU].size);
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_GIC_MAINT_IRQ),
GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
}
}

View File

@@ -670,13 +670,8 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
cnt += (transferred + d->leftover) >> 2;
if (s->sctl & loop_sel) {
/*
* loop_sel tells us which bit in the SCTL register to look at
* (either P1_LOOP_SEL, P2_LOOP_SEL or R1_LOOP_SEL). The sense
* of these bits is 0 for loop mode (set interrupt and keep recording
* when the sample count reaches zero) or 1 for stop mode (set
* interrupt and stop recording).
*/
/* Bah, how stupid is that having a 0 represent true value?
i just spent few hours on this shit */
AUD_log ("es1370: warning", "non looping mode\n");
} else {
d->frame_cnt = size;

View File

@@ -22,7 +22,6 @@
#include "hw/qdev-properties.h"
#include "intel-hda.h"
#include "migration/vmstate.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "intel-hda-defs.h"
#include "audio/audio.h"
@@ -190,9 +189,9 @@ struct HDAAudioState {
bool use_timer;
};
static inline uint32_t hda_bytes_per_second(HDAAudioStream *st)
static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
{
return 2 * (uint32_t)st->as.nchannels * (uint32_t)st->as.freq;
return 2LL * st->as.nchannels * st->as.freq;
}
static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos)
@@ -223,18 +222,12 @@ static void hda_audio_input_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t uptime = now - st->buft_start;
int64_t buft_start = st->buft_start;
int64_t wpos = st->wpos;
int64_t rpos = st->rpos;
int64_t wanted_rpos;
if (uptime <= 0) {
/* wanted_rpos <= 0 */
goto out_timer;
}
wanted_rpos = muldiv64(uptime, hda_bytes_per_second(st),
NANOSECONDS_PER_SECOND);
int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start)
/ NANOSECONDS_PER_SECOND;
wanted_rpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_rpos <= rpos) {
@@ -293,18 +286,12 @@ static void hda_audio_output_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t uptime = now - st->buft_start;
int64_t buft_start = st->buft_start;
int64_t wpos = st->wpos;
int64_t rpos = st->rpos;
int64_t wanted_wpos;
if (uptime <= 0) {
/* wanted_wpos <= 0 */
goto out_timer;
}
wanted_wpos = muldiv64(uptime, hda_bytes_per_second(st),
NANOSECONDS_PER_SECOND);
int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start)
/ NANOSECONDS_PER_SECOND;
wanted_wpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_wpos <= wpos) {
@@ -868,10 +855,10 @@ static Property hda_audio_properties[] = {
static void hda_audio_init_output(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
const struct desc_codec *desc = &output_mixemu;
const struct desc_codec *desc = &output_nomixemu;
if (!a->mixer) {
desc = &output_nomixemu;
desc = &output_mixemu;
}
hda_audio_init(hda, desc, errp);
@@ -880,10 +867,10 @@ static void hda_audio_init_output(HDACodecDevice *hda, Error **errp)
static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
const struct desc_codec *desc = &duplex_mixemu;
const struct desc_codec *desc = &duplex_nomixemu;
if (!a->mixer) {
desc = &duplex_nomixemu;
desc = &duplex_mixemu;
}
hda_audio_init(hda, desc, errp);
@@ -892,10 +879,10 @@ static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp)
static void hda_audio_init_micro(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
const struct desc_codec *desc = &micro_mixemu;
const struct desc_codec *desc = &micro_nomixemu;
if (!a->mixer) {
desc = &micro_nomixemu;
desc = &micro_mixemu;
}
hda_audio_init(hda, desc, errp);

View File

@@ -211,14 +211,14 @@ static void out_cb(void *opaque, int avail)
AUD_set_active_out(s->vo, 0);
}
if (c->type & STAT_EOL) {
via_isa_set_irq(&s->dev, 0, 1);
pci_set_irq(&s->dev, 1);
}
}
if (CLEN_IS_FLAG(c)) {
c->stat |= STAT_FLAG;
c->stat |= STAT_PAUSED;
if (c->type & STAT_FLAG) {
via_isa_set_irq(&s->dev, 0, 1);
pci_set_irq(&s->dev, 1);
}
}
if (CLEN_IS_STOP(c)) {
@@ -305,13 +305,13 @@ static void sgd_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
if (val & STAT_EOL) {
s->aur.stat &= ~(STAT_EOL | STAT_PAUSED);
if (s->aur.type & STAT_EOL) {
via_isa_set_irq(&s->dev, 0, 0);
pci_set_irq(&s->dev, 0);
}
}
if (val & STAT_FLAG) {
s->aur.stat &= ~(STAT_FLAG | STAT_PAUSED);
if (s->aur.type & STAT_FLAG) {
via_isa_set_irq(&s->dev, 0, 0);
pci_set_irq(&s->dev, 0);
}
}
break;

View File

@@ -47,14 +47,12 @@ static void virtio_snd_pci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidevklass = PCI_DEVICE_CLASS(klass);
device_class_set_props(dc, virtio_snd_pci_properties);
dc->desc = "Virtio Sound";
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
vpciklass->realize = virtio_snd_pci_realize;
pcidevklass->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
}
static void virtio_snd_pci_instance_init(Object *obj)

View File

@@ -36,7 +36,6 @@ static void virtio_snd_pcm_out_cb(void *data, int available);
static void virtio_snd_process_cmdq(VirtIOSound *s);
static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream);
static void virtio_snd_pcm_in_cb(void *data, int available);
static void virtio_snd_unrealize(DeviceState *dev);
static uint32_t supported_formats = BIT(VIRTIO_SND_PCM_FMT_S8)
| BIT(VIRTIO_SND_PCM_FMT_U8)
@@ -69,7 +68,6 @@ static const VMStateDescription vmstate_virtio_snd_device = {
static const VMStateDescription vmstate_virtio_snd = {
.name = TYPE_VIRTIO_SND,
.unmigratable = 1,
.minimum_version_id = VIRTIO_SOUND_VM_VERSION,
.version_id = VIRTIO_SOUND_VM_VERSION,
.fields = (VMStateField[]) {
@@ -1067,9 +1065,23 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
virtio_snd_pcm_set_params default_params = { 0 };
uint32_t status;
vsnd->pcm = NULL;
vsnd->vmstate =
qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
trace_virtio_snd_realize(vsnd);
/* check number of jacks and streams */
vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
vsnd->pcm->snd = vsnd;
vsnd->pcm->streams =
g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
vsnd->pcm->pcm_params =
g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
/* set number of jacks and streams */
if (vsnd->snd_conf.jacks > 8) {
error_setg(errp,
"Invalid number of jacks: %"PRIu32,
@@ -1090,22 +1102,7 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
return;
}
if (!AUD_register_card("virtio-sound", &vsnd->card, errp)) {
return;
}
vsnd->vmstate =
qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
vsnd->pcm->snd = vsnd;
vsnd->pcm->streams =
g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
vsnd->pcm->pcm_params =
g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
AUD_register_card("virtio-sound", &vsnd->card, errp);
/* set default params for all streams */
default_params.features = 0;
@@ -1129,23 +1126,18 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
status = virtio_snd_set_pcm_params(vsnd, i, &default_params);
if (status != cpu_to_le32(VIRTIO_SND_S_OK)) {
error_setg(errp,
"Can't initialize stream params, device responded with %s.",
"Can't initalize stream params, device responded with %s.",
print_code(status));
goto error_cleanup;
return;
}
status = virtio_snd_pcm_prepare(vsnd, i);
if (status != cpu_to_le32(VIRTIO_SND_S_OK)) {
error_setg(errp,
"Can't prepare streams, device responded with %s.",
print_code(status));
goto error_cleanup;
return;
}
}
return;
error_cleanup:
virtio_snd_unrealize(dev);
}
static inline void return_tx_buffer(VirtIOSoundPCMStream *stream,

View File

@@ -233,10 +233,6 @@ static void atmega_realize(DeviceState *dev, Error **errp)
/* CPU */
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);
cpudev = DEVICE(&s->cpu);

View File

@@ -80,39 +80,16 @@ struct PFlashCFI01 {
uint16_t ident3;
uint8_t cfi_table[0x52];
uint64_t counter;
uint32_t writeblock_size;
unsigned int writeblock_size;
MemoryRegion mem;
char *name;
void *storage;
VMChangeStateEntry *vmstate;
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 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 = {
.name = "pflash_cfi01",
.version_id = 1,
@@ -124,10 +101,6 @@ static const VMStateDescription vmstate_pflash = {
VMSTATE_UINT8(status, PFlashCFI01),
VMSTATE_UINT64(counter, PFlashCFI01),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
&vmstate_pflash_blk_write,
NULL
}
};
@@ -252,10 +225,34 @@ static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset,
uint32_t ret;
p = pfl->storage;
if (be) {
ret = ldn_be_p(p + offset, width);
} else {
ret = ldn_le_p(p + offset, width);
switch (width) {
case 1:
ret = p[offset];
break;
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);
return ret;
@@ -403,61 +400,40 @@ 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,
uint32_t value, int width, int be)
{
uint8_t *p;
uint8_t *p = pfl->storage;
if (pfl->blk_offset != -1) {
/* block write: redirect writes to block update buffer */
if ((offset < pfl->blk_offset) ||
(offset + width > pfl->blk_offset + pfl->writeblock_size)) {
pfl->status |= 0x10; /* Programming error */
return;
trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter);
switch (width) {
case 1:
p[offset] = value;
break;
case 2:
if (be) {
p[offset] = value >> 8;
p[offset + 1] = value;
} else {
p[offset] = value;
p[offset + 1] = value >> 8;
}
trace_pflash_data_write_block(pfl->name, offset, width, value,
pfl->counter);
p = pfl->blk_bytes + (offset - pfl->blk_offset);
} else {
/* write directly to storage */
trace_pflash_data_write(pfl->name, offset, width, value);
p = pfl->storage + offset;
break;
case 4:
if (be) {
p[offset] = value >> 24;
p[offset + 1] = value >> 16;
p[offset + 2] = value >> 8;
p[offset + 3] = value;
} 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,
@@ -572,9 +548,9 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
} else {
value = extract32(value, 0, pfl->bank_width * 8);
}
trace_pflash_write_block(pfl->name, value);
pfl->counter = value;
pfl->wcycle++;
pflash_blk_write_start(pfl, offset);
break;
case 0x60:
if (cmd == 0xd0) {
@@ -605,7 +581,12 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
switch (pfl->cmd) {
case 0xe8: /* Block write */
/* FIXME check @offset, @width */
if (!pfl->ro && (pfl->blk_offset != -1)) {
if (!pfl->ro) {
/*
* 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);
} else {
pfl->status |= 0x10; /* Programming error */
@@ -614,8 +595,18 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
pfl->status |= 0x80;
if (!pfl->counter) {
hwaddr mask = pfl->writeblock_size - 1;
mask = ~mask;
trace_pflash_write(pfl->name, "block write finished");
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--;
@@ -627,17 +618,20 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
case 3: /* Confirm mode */
switch (pfl->cmd) {
case 0xe8: /* Block write */
if ((cmd == 0xd0) && !(pfl->status & 0x10)) {
pflash_blk_write_flush(pfl);
if (cmd == 0xd0) {
/* FIXME this is where we should write out the buffer */
pfl->wcycle = 0;
pfl->status |= 0x80;
} else {
pflash_blk_write_abort(pfl);
qemu_log_mask(LOG_UNIMP,
"%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;
}
break;
default:
pflash_blk_write_abort(pfl);
goto error_flash;
}
break;
@@ -871,9 +865,6 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
pfl->cmd = 0x00;
pfl->status = 0x80; /* WSM ready */
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)
@@ -893,8 +884,6 @@ static void pflash_cfi01_system_reset(DeviceState *dev)
* This model deliberately ignores this delay.
*/
pfl->status = 0x80;
pfl->blk_offset = -1;
}
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;
}
trace_pflash_data_write(pfl->name, offset, width, value);
trace_pflash_data_write(pfl->name, offset, width, value, 0);
if (!pfl->ro) {
p = (uint8_t *)pfl->storage + offset;
if (pfl->be) {

View File

@@ -12,8 +12,7 @@ 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_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_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_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_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_erase_complete(const char *name) "%s: sector erase complete"
@@ -33,9 +32,7 @@ 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_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_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(const char *name, uint32_t value) "%s: block write: bytes:0x%x"
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_invalid(const char *name, uint8_t cmd) "%s: invalid write for command 0x%02x"

View File

@@ -326,6 +326,7 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
if (s->connected) {
return 0;
}
s->connected = true;
s->dev.num_queues = s->num_queues;
s->dev.nvqs = s->num_queues;
@@ -342,14 +343,15 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
return ret;
}
s->connected = true;
/* restore vhost state */
if (virtio_device_started(vdev, vdev->status)) {
ret = vhost_user_blk_start(vdev, errp);
if (ret < 0) {
return ret;
}
}
return ret;
return 0;
}
static void vhost_user_blk_disconnect(DeviceState *dev)

View File

@@ -65,7 +65,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
iov_discard_undo(&req->inhdr_undo);
iov_discard_undo(&req->outhdr_undo);
virtqueue_push(req->vq, &req->elem, req->in_len);
if (qemu_in_iothread()) {
if (s->dataplane_started && !s->dataplane_disabled) {
virtio_blk_data_plane_notify(s->dataplane, req->vq);
} else {
virtio_notify(vdev, req->vq);

View File

@@ -91,27 +91,9 @@ static bool xen_block_find_free_vdev(XenBlockDevice *blockdev, Error **errp)
existing_frontends = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, fe_path,
&nr_existing);
if (!existing_frontends) {
if (errno == ENOENT) {
/*
* If the frontend directory doesn't exist because there are
* no existing vbd devices, that's fine. Just ensure that we
* don't dereference the NULL existing_frontends pointer, by
* checking that nr_existing is zero so the loop below is not
* entered.
*
* In fact this is redundant since nr_existing is initialized
* to zero, but setting it again here makes it abundantly clear
* to Coverity, and to the human reader who doesn't know the
* semantics of qemu_xen_xs_directory() off the top of their
* head.
*/
nr_existing = 0;
} else {
/* All other errors accessing the frontend directory are fatal. */
error_setg_errno(errp, errno, "cannot read %s", fe_path);
return false;
}
if (!existing_frontends && errno != ENOENT) {
error_setg_errno(errp, errno, "cannot read %s", fe_path);
return false;
}
memset(used_devs, 0, sizeof(used_devs));

View File

@@ -505,7 +505,7 @@ ssize_t load_elf_ram_sym(const char *filename,
clear_lsb, data_swab, as, load_rom, sym_cb);
}
if (ret > 0) {
if (ret != ELF_LOAD_FAILED) {
debuginfo_report_elf(filename, fd, 0);
}

View File

@@ -35,8 +35,7 @@
GlobalProperty hw_compat_8_1[] = {
{ TYPE_PCI_BRIDGE, "x-pci-express-writeable-slt-bug", "true" },
{ "ramfb", "x-migrate", "off" },
{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" },
{ "igb", "x-pcie-flr-init", "off" },
{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }
};
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);

View File

@@ -689,36 +689,23 @@ static void get_prop_array(Object *obj, Visitor *v, const char *name,
Property *prop = opaque;
uint32_t *alenptr = object_field_prop_ptr(obj, prop);
void **arrayptr = (void *)obj + prop->arrayoffset;
char *elemptr = *arrayptr;
ArrayElementList *list = NULL, *elem;
ArrayElementList **tail = &list;
const size_t size = sizeof(*list);
char *elem = *arrayptr;
GenericList *list;
const size_t list_elem_size = sizeof(*list) + prop->arrayfieldsize;
int i;
bool ok;
/* At least the string output visitor needs a real list */
for (i = 0; i < *alenptr; i++) {
elem = g_new0(ArrayElementList, 1);
elem->value = elemptr;
elemptr += prop->arrayfieldsize;
*tail = elem;
tail = &elem->next;
}
if (!visit_start_list(v, name, (GenericList **) &list, size, errp)) {
if (!visit_start_list(v, name, &list, list_elem_size, errp)) {
return;
}
elem = list;
while (elem) {
Property elem_prop = array_elem_prop(obj, prop, name, elem->value);
for (i = 0; i < *alenptr; i++) {
Property elem_prop = array_elem_prop(obj, prop, name, elem);
prop->arrayinfo->get(obj, v, NULL, &elem_prop, errp);
if (*errp) {
goto out_obj;
}
elem = (ArrayElementList *) visit_next_list(v, (GenericList*) elem,
size);
elem += prop->arrayfieldsize;
}
/* visit_check_list() can only fail for input visitors */
@@ -727,12 +714,6 @@ static void get_prop_array(Object *obj, Visitor *v, const char *name,
out_obj:
visit_end_list(v, (void**) &list);
while (list) {
elem = list;
list = elem->next;
g_free(elem);
}
}
static void default_prop_array(ObjectProperty *op, const Property *prop)

View File

@@ -49,7 +49,6 @@ static void ct3_build_cdat(CDATObject *cdat, Error **errp)
g_autofree CDATTableHeader *cdat_header = NULL;
g_autofree CDATEntry *cdat_st = NULL;
uint8_t sum = 0;
uint8_t *hdr_buf;
int ent, i;
/* Use default table if fopen == NULL */
@@ -64,7 +63,7 @@ static void ct3_build_cdat(CDATObject *cdat, Error **errp)
cdat->built_buf_len = cdat->build_cdat_table(&cdat->built_buf,
cdat->private);
if (cdat->built_buf_len <= 0) {
if (!cdat->built_buf_len) {
/* Build later as not all data available yet */
cdat->to_update = true;
return;
@@ -96,12 +95,8 @@ static void ct3_build_cdat(CDATObject *cdat, Error **errp)
/* For now, no runtime updates */
cdat_header->sequence = 0;
cdat_header->length += sizeof(CDATTableHeader);
hdr_buf = (uint8_t *)cdat_header;
for (i = 0; i < sizeof(*cdat_header); i++) {
sum += hdr_buf[i];
}
sum += cdat_header->revision + cdat_header->sequence +
cdat_header->length;
/* Sum of all bytes including checksum must be 0 */
cdat_header->checksum = ~sum + 1;

View File

@@ -81,7 +81,7 @@ static uint64_t cxl_cache_mem_read_reg(void *opaque, hwaddr offset,
return 0;
default:
/*
* In line with specification limitaions on access sizes, this
* In line with specifiction limitaions on access sizes, this
* routine is not called with other sizes.
*/
g_assert_not_reached();
@@ -152,7 +152,7 @@ static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t value,
return;
default:
/*
* In line with specification limitaions on access sizes, this
* In line with specifiction limitaions on access sizes, this
* routine is not called with other sizes.
*/
g_assert_not_reached();
@@ -199,7 +199,7 @@ void cxl_component_register_block_init(Object *obj,
/* io registers controls link which we don't care about in QEMU */
memory_region_init_io(&cregs->io, obj, NULL, cregs, ".io",
CXL2_COMPONENT_IO_REGION_SIZE);
memory_region_init_io(&cregs->cache_mem, obj, &cache_mem_ops, cxl_cstate,
memory_region_init_io(&cregs->cache_mem, obj, &cache_mem_ops, cregs,
".cache_mem", CXL2_COMPONENT_CM_REGION_SIZE);
memory_region_add_subregion(&cregs->component_registers, 0, &cregs->io);

View File

@@ -229,9 +229,12 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
static uint64_t mdev_reg_read(void *opaque, hwaddr offset, unsigned size)
{
CXLDeviceState *cxl_dstate = opaque;
uint64_t retval = 0;
return cxl_dstate->memdev_status;
retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MEDIA_STATUS, 1);
retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MBOX_READY, 1);
return retval;
}
static void ro_reg_write(void *opaque, hwaddr offset, uint64_t value,
@@ -368,15 +371,7 @@ static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
cxl_dstate->mbox_msi_n = msi_n;
}
static void memdev_reg_init_common(CXLDeviceState *cxl_dstate)
{
uint64_t memdev_status_reg;
memdev_status_reg = FIELD_DP64(0, CXL_MEM_DEV_STS, MEDIA_STATUS, 1);
memdev_status_reg = FIELD_DP64(memdev_status_reg, CXL_MEM_DEV_STS,
MBOX_READY, 1);
cxl_dstate->memdev_status = memdev_status_reg;
}
static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { }
void cxl_device_register_init_t3(CXLType3Dev *ct3d)
{

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