Compare commits

...
39 Commits
Author SHA1 Message Date
Richard Henderson b2bdfb711a tcg/i386: Set P_REXW in tcg_out_addi_ptr
The REXW bit must be set to produce a 64-bit pointer result; the
bit is disabled in 32-bit mode, so we can do this unconditionally.

Fixes: 7d9e1ee424 ("tcg/i386: Adjust assert in tcg_out_addi_ptr")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1592
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1642
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 988998503b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Jason Andryuk dbdbd71acf 9pfs/xen: Fix segfault on shutdown
xen_9pfs_free can't use gnttabdev since it is already closed and NULL-ed
out when free is called.  Do the teardown in _disconnect().  This
matches the setup done in _connect().

trace-events are also added for the XenDevOps functions.

Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Message-Id: <20230502143722.15613-1-jandryuk@gmail.com>
[C.S.: - Remove redundant return in xen_9pfs_free().
       - Add comment to trace-events. ]
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 92e667f6fd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Ilya Leoshkevich 6b765cbbc2 s390x/tcg: Fix LDER instruction format
It's RRE, not RXE.

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

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

Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230426235813.198183-2-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit e8ecdfeb30)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Shivaprasad G Bhat 8e964243f5 tcg: ppc64: Fix mask generation for vextractdm
In function do_extractm() the mask is calculated as
dup_const(1 << (element_width - 1)). '1' being signed int
works fine for MO_8,16,32. For MO_64, on PPC64 host
this ends up becoming 0 on compilation. The vextractdm
uses MO_64, and it ends up having mask as 0.

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

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

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

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

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230420202939.1982044-1-clg@kaod.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d66ba6dc1c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(Mjt: cherry-picked to stable-8.0 to eliminate CI failures on win*)
2023-05-30 22:05:27 +03:00
Peter Maydell b249153dfd target/arm: Correct AArch64.S2MinTxSZ 32-bit EL1 input size check
In check_s2_mmu_setup() we have a check that is attempting to
implement the part of AArch64.S2MinTxSZ that is specific to when EL1
is AArch32:

    if !s1aarch64 then
        // EL1 is AArch32
        min_txsz = Min(min_txsz, 24);

Unfortunately we got this wrong in two ways:

(1) The minimum txsz corresponds to a maximum inputsize, but we got
the sense of the comparison wrong and were faulting for all
inputsizes less than 40 bits

(2) We try to implement this as an extra check that happens after
we've done the same txsz checks we would do for an AArch64 EL1, but
in fact the pseudocode is *loosening* the requirements, so that txsz
values that would fault for an AArch64 EL1 do not fault for AArch32
EL1, because it does Min(old_min, 24), not Max(old_min, 24).

You can see this also in the text of the Arm ARM in table D8-8, which
shows that where the implemented PA size is less than 40 bits an
AArch32 EL1 is still OK with a configured stage2 T0SZ for a 40 bit
IPA, whereas if EL1 is AArch64 then the T0SZ must be big enough to
constrain the IPA to the implemented PA size.

Because of part (2), we can't do this as a separate check, but
have to integrate it into aa64_va_parameters(). Add a new argument
to that function to indicate that EL1 is 32-bit. All the existing
callsites except the one in get_phys_addr_lpae() can pass 'false',
because they are either doing a lookup for a stage 1 regime or
else they don't care about the tsz/tsz_oob fields.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1627
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230509092059.3176487-1-peter.maydell@linaro.org
(cherry picked from commit 478dccbb99)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Peter Maydell 9acb3d7e52 ui: Fix pixel colour channel order for PNG screenshots
When we take a PNG screenshot the ordering of the colour channels in
the data is not correct, resulting in the image having weird
colouring compared to the actual display.  (Specifically, on a
little-endian host the blue and red channels are swapped; on
big-endian everything is wrong.)

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

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

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

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

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

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

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1622
Fixes: 9a0a119a38 ("Added parameter to take screenshot with screendump as PNG")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20230502135548.2451309-1-peter.maydell@linaro.org
(cherry picked from commit cd22a0f520)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Peter Maydell 1335d26a8b target/arm: Fix handling of SW and NSW bits for stage 2 walks
We currently don't correctly handle the VSTCR_EL2.SW and VTCR_EL2.NSW
configuration bits.  These allow configuration of whether the stage 2
page table walks for Secure IPA and NonSecure IPA should do their
descriptor reads from Secure or NonSecure physical addresses. (This
is separate from how the translation table base address and other
parameters are set: an NS IPA always uses VTTBR_EL2 and VTCR_EL2
for its base address and walk parameters, regardless of the NSW bit,
and similarly for Secure.)

Provide a new function ptw_idx_for_stage_2() which returns the
MMU index to use for descriptor reads, and use it to set up
the .in_ptw_idx wherever we call get_phys_addr_lpae().

For a stage 2 walk, wherever we call get_phys_addr_lpae():
 * .in_ptw_idx should be ptw_idx_for_stage_2() of the .in_mmu_idx
 * .in_secure should be true if .in_mmu_idx is Stage2_S

This allows us to correct S1_ptw_translate() so that it consistently
always sets its (out_secure, out_phys) to the result it gets from the
S2 walk (either by calling get_phys_addr_lpae() or by TLB lookup).
This makes better conceptual sense because the S2 walk should return
us an (address space, address) tuple, not an address that we then
randomly assign to S or NS.

Our previous handling of SW and NSW was broken, so guest code
trying to use these bits to put the s2 page tables in the "other"
address space wouldn't work correctly.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1600
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230504135425.2748672-3-peter.maydell@linaro.org
(cherry picked from commit fcc0b0418f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Richard Henderson 1d7592186e accel/tcg: Fix atomic_mmu_lookup for reads
A copy-paste bug had us looking at the victim cache for writes.

Cc: qemu-stable@nongnu.org
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Fixes: 08dff435e2 ("tcg: Probe the proper permissions for atomic ops")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20230505204049.352469-1-richard.henderson@linaro.org>
(cherry picked from commit 8c313254e6)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Jonathan Cameron 99812af143 hw/pci-bridge: pci_expander_bridge fix type in pxb_cxl_dev_reset()
Reproduce issue with

configure --enable-qom-cast-debug ...

qemu-system-x86_64 -display none -machine q35,cxl=on -device pxb-cxl,bus=pcie.0

  hw/pci-bridge/pci_expander_bridge.c:54:PXB_DEV: Object 0x5570e0b1ada0 is not an instance of type pxb
  Aborted

The type conversion results in the right state structure, but PXB_DEV is
not a parent of PXB_CXL_DEV hence the error. Rather than directly
cleaning up the inheritance, this is the minimal fix which will be
followed by the cleanup.

Fixes: 154070eaf6 ("hw/pxb-cxl: Support passthrough HDM Decoders unless overridden")
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20230420142750.6950-2-Jonathan.Cameron@huawei.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 9136f661c7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Bin Meng 8c2fe857e8 target/riscv: Restore the predicate() NULL check behavior
When reading a non-existent CSR QEMU should raise illegal instruction
exception, but currently it just exits due to the g_assert() check.

This actually reverts commit 0ee342256a.
Some comments are also added to indicate that predicate() must be
provided for an implemented CSR.

Reported-by: Fei Wu <fei2.wu@intel.com>
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-Id: <20230417043054.3125614-1-bmeng@tinylab.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit eae04c4c13)
(mjt: context edit after ce3af0bbbc "target/riscv: add support for Zcmt extension")
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
LIU Zhiwei 37cc3ad29e target/riscv: Fix itrigger when icount is used
When I boot a ubuntu image, QEMU output a "Bad icount read" message and exit.
The reason is that when execute helper_mret or helper_sret, it will
cause a call to icount_get_raw_locked (), which needs set can_do_io flag
on cpustate.

Thus we setting this flag when execute these two instructions.

Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230324064011.976-1-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit df3ac6da47)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Kevin Wolf d24558bb62 block: Don't call no_coroutine_fns in qmp_block_resize()
This QMP handler runs in a coroutine, so it must use the corresponding
no_co_wrappers instead.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2185688
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20230504115750.54437-5-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 0c7d204f50)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Kevin Wolf 5b0c365c64 block: bdrv/blk_co_unref() for calls in coroutine context
These functions must not be called in coroutine context, because they
need write access to the graph.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20230504115750.54437-4-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b2ab5f545f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Kevin Wolf ded28d8298 block: Consistently call bdrv_activate() outside coroutine
Migration code can call bdrv_activate() in coroutine context, whereas
other callers call it outside of coroutines. As it calls other code that
is not supposed to run in coroutines, standardise on running outside of
coroutines.

This adds a no_co_wrapper to switch to the main loop before calling
bdrv_activate().

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20230504115750.54437-3-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit da4afaff07)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Kevin Wolf 83f6cbc53c block: Fix use after free in blockdev_mark_auto_del()
job_cancel_locked() drops the job list lock temporarily and it may call
aio_poll(). We must assume that the list has changed after this call.
Also, with unlucky timing, it can end up freeing the job during
job_completed_txn_abort_locked(), making the job pointer invalid, too.

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

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

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

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

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

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

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

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

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

But because of the typo it ends up doing

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

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

Cc: qemu-stable@nongnu.org
Fixes: 572c4d862f "softfloat: Convert float32_exp2 to FloatParts"
Partially-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1623
Reported-By: Luca Barbato (https://gitlab.com/lu-zero)
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Message-Id: <168304110865.537992.13059030916325018670.stgit@localhost.localdomain>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 1098cc3fcf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Stefan Hajnoczi 58e2d19b0e block/export: call blk_set_dev_ops(blk, NULL, NULL)
Most export types install BlockDeviceOps pointers. It is easy to forget
to remove them because that happens automatically via the "drive" qdev
property in hw/ but not block/export/.

Put blk_set_dev_ops(blk, NULL, NULL) calls in the core export.c code so
the export types don't need to remember.

This fixes the nbd and vhost-user-blk export types.

Fixes: fd6afc501a ("nbd/server: Use drained block ops to quiesce the server")
Fixes: ca858a5fe9 ("vhost-user-blk-server: notify client about disk resize")
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20230502211119.720647-1-stefanha@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit de79b52604)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Peter Maydell 6a3b8807e9 hw/net/allwinner-sun8i-emac: Correctly byteswap descriptor fields
In allwinner-sun8i-emac we just read directly from guest memory into
a host FrameDescriptor struct and back.  This only works on
little-endian hosts.  Reading and writing of descriptors is already
abstracted into functions; make those functions also handle the
byte-swapping so that TransferDescriptor structs as seen by the rest
of the code are always in host-order, and fix two places that were
doing ad-hoc descriptor reading without using the functions.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Improve the language to hopefully make things clearer.

Suggested-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20230424092249.58552-7-alex.bennee@linaro.org>
(cherry picked from commit c1654c3e37)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Wang Liang 4520611f88 block/monitor: Fix crash when executing HMP commit
hmp_commit() calls blk_is_available() from a non-coroutine context (and
in the main loop). blk_is_available() is a co_wrapper_mixed_bdrv_rdlock
function, and in the non-coroutine context it calls AIO_WAIT_WHILE(),
which crashes if the aio_context lock is not taken before.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1615
Signed-off-by: Wang Liang <wangliangzz@inspur.com>
Message-Id: <20230424103902.45265-1-wangliangzz@126.com>
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8c1e8fb2e7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Igor Mammedov e8df2d66bb acpi: pcihp: allow repeating hot-unplug requests
with Q35 using ACPI PCI hotplug by default, user's request to unplug
device is ignored when it's issued before guest OS has been booted.
And any additional attempt to request device hot-unplug afterwards
results in following error:

  "Device XYZ is already in the process of unplug"

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

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

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

1) 18416c62e3 ("pcie: expire pending delete")
2)
Fixes: cce8944cc9 ("qdev-monitor: Forbid repeated device_del")
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
CC: mst@redhat.com
CC: anisinha@redhat.com
CC: jusual@redhat.com
CC: kraxel@redhat.com
Message-Id: <20230418090449.2155757-1-imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 0f689cf5ad)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Axel Heider 5810375131 hw/timer/imx_epit: fix limit check
Fix the limit check. If the limit is less than the compare value,
the timer can never reach this value, thus it will never fire.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1491
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
Message-id: 168070611775.20412.2883242077302841473-2@git.sr.ht
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 25d758175d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Axel Heider 14a40a9157 hw/timer/imx_epit: don't shadow variable
Fix issue reported by Coverity.

Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
Message-id: 168070611775.20412.2883242077302841473-1@git.sr.ht
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 542fd43d79)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Yang Zhong 464aaf8b82 target/i386: Change wrong XFRM value in SGX CPUID leaf
The previous patch wrongly replaced FEAT_XSAVE_XCR0_{LO|HI} with
FEAT_XSAVE_XSS_{LO|HI} in CPUID(EAX=12,ECX=1):{ECX,EDX}.  As a result,
SGX enclaves only supported SSE and x87 feature (xfrm=0x3).

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

Fix it by checking hostlen.

Reported by Coverity.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3f9c41c5df)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-05-30 22:05:27 +03:00
Michael Tokarev 26df00f45b gitlab-ci: crash-test-debian: make it verbose (remove -q) 2023-05-30 22:05:20 +03:00
Michael Tokarev 6773aac9c7 gitlab: improvements to handling of stable staging branches
5-patch series by Daniel P. Berrangé
2023-05-30 20:30:51 +03:00
62 changed files with 594 additions and 283 deletions
+56 -7
View File
@@ -1,10 +1,24 @@
variables:
# On stable branches this is changed by later rules. Should also
# be overridden per pipeline if running pipelines concurrently
# for different branches in contributor forks.
QEMU_CI_CONTAINER_TAG: latest
# For purposes of CI rules, upstream is the gitlab.com/qemu-project
# namespace. When testing CI, it might be usefult to override this
# to point to a fork repo
QEMU_CI_UPSTREAM: qemu-project
# The order of rules defined here is critically important.
# They are evaluated in order and first match wins.
#
# Thus we group them into a number of stages, ordered from
# most restrictive to least restrictive
#
# For pipelines running for stable "staging-X.Y" branches
# we must override QEMU_CI_CONTAINER_TAG
#
.base_job_template:
variables:
# Each script line from will be in a collapsible section in the job output
@@ -19,28 +33,36 @@
# want jobs to run
#############################################################
# Never run jobs upstream on stable branch, staging branch jobs already ran
- if: '$CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_BRANCH =~ /^stable-/'
when: never
# Never run jobs upstream on tags, staging branch jobs already ran
- if: '$CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_TAG'
when: never
# Cirrus jobs can't run unless the creds / target repo are set
- if: '$QEMU_JOB_CIRRUS && ($CIRRUS_GITHUB_REPO == null || $CIRRUS_API_TOKEN == null)'
when: never
# Publishing jobs should only run on the default branch in upstream
- if: '$QEMU_JOB_PUBLISH == "1" && $CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH'
- if: '$QEMU_JOB_PUBLISH == "1" && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH'
when: never
# Non-publishing jobs should only run on staging branches in upstream
- if: '$QEMU_JOB_PUBLISH != "1" && $CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH !~ /staging/'
- if: '$QEMU_JOB_PUBLISH != "1" && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_BRANCH !~ /staging/'
when: never
# Jobs only intended for forks should always be skipped on upstream
- if: '$QEMU_JOB_ONLY_FORKS == "1" && $CI_PROJECT_NAMESPACE == "qemu-project"'
- if: '$QEMU_JOB_ONLY_FORKS == "1" && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM'
when: never
# Forks don't get pipelines unless QEMU_CI=1 or QEMU_CI=2 is set
- if: '$QEMU_CI != "1" && $QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
- if: '$QEMU_CI != "1" && $QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
when: never
# Avocado jobs don't run in forks unless $QEMU_CI_AVOCADO_TESTING is set
- if: '$QEMU_JOB_AVOCADO && $QEMU_CI_AVOCADO_TESTING != "1" && $CI_PROJECT_NAMESPACE != "qemu-project"'
- if: '$QEMU_JOB_AVOCADO && $QEMU_CI_AVOCADO_TESTING != "1" && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
when: never
@@ -50,17 +72,29 @@
#############################################################
# Optional jobs should not be run unless manually triggered
- if: '$QEMU_JOB_OPTIONAL && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_BRANCH =~ /staging-[[:digit:]]+\.[[:digit:]]/'
when: manual
allow_failure: true
variables:
QEMU_CI_CONTAINER_TAG: $CI_COMMIT_REF_SLUG
- if: '$QEMU_JOB_OPTIONAL'
when: manual
allow_failure: true
# Skipped jobs should not be run unless manually triggered
- if: '$QEMU_JOB_SKIPPED && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_BRANCH =~ /staging-[[:digit:]]+\.[[:digit:]]/'
when: manual
allow_failure: true
variables:
QEMU_CI_CONTAINER_TAG: $CI_COMMIT_REF_SLUG
- if: '$QEMU_JOB_SKIPPED'
when: manual
allow_failure: true
# Avocado jobs can be manually start in forks if $QEMU_CI_AVOCADO_TESTING is unset
- if: '$QEMU_JOB_AVOCADO && $CI_PROJECT_NAMESPACE != "qemu-project"'
- if: '$QEMU_JOB_AVOCADO && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
when: manual
allow_failure: true
@@ -72,8 +106,23 @@
# Forks pipeline jobs don't start automatically unless
# QEMU_CI=2 is set
- if: '$QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
- if: '$QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
when: manual
# Upstream pipeline jobs start automatically unless told not to
# by setting QEMU_CI=1
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_BRANCH =~ /staging/'
when: manual
variables:
QEMU_CI_CONTAINER_TAG: $CI_COMMIT_REF_SLUG
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM'
when: manual
# Jobs can run if any jobs they depend on were successful
- if: '$QEMU_JOB_SKIPPED && $CI_PROJECT_NAMESPACE == $QEMU_CI_UPSTREAM && $CI_COMMIT_BRANCH =~ /staging-[[:digit:]]+\.[[:digit:]]/'
when: on_success
variables:
QEMU_CI_CONTAINER_TAG: $CI_COMMIT_REF_SLUG
- when: on_success
+2 -2
View File
@@ -1,7 +1,7 @@
.native_build_job_template:
extends: .base_job_template
stage: build
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
before_script:
- JOBS=$(expr $(nproc) + 1)
script:
@@ -44,7 +44,7 @@
.common_test_job_template:
extends: .base_job_template
stage: test
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
script:
- scripts/git-submodule.sh update
$(sed -n '/GIT_SUBMODULES=/ s/.*=// p' build/config-host.mak)
+3 -3
View File
@@ -103,7 +103,7 @@ crash-test-debian:
script:
- cd build
- make check-venv
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-i386
- tests/venv/bin/python3 scripts/device-crash-test ./qemu-system-i386
build-system-fedora:
extends:
@@ -532,7 +532,7 @@ build-without-defaults:
build-libvhost-user:
extends: .base_job_template
stage: build
image: $CI_REGISTRY_IMAGE/qemu/fedora:latest
image: $CI_REGISTRY_IMAGE/qemu/fedora:$QEMU_CI_CONTAINER_TAG
needs:
job: amd64-fedora-container
script:
@@ -572,7 +572,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-amd64:latest
image: $CI_REGISTRY_IMAGE/qemu/debian-amd64:$QEMU_CI_CONTAINER_TAG
stage: test
needs:
- job: build-tools-and-docs-debian
+2 -1
View File
@@ -5,7 +5,8 @@
services:
- docker:dind
before_script:
- export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
- export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:$QEMU_CI_CONTAINER_TAG"
# Always ':latest' because we always use upstream as a common cache source
- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest"
- apk add python3
- docker info
+3 -3
View File
@@ -1,7 +1,7 @@
.cross_system_build_job:
extends: .base_job_template
stage: build
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
timeout: 80m
script:
- mkdir build
@@ -27,7 +27,7 @@
.cross_accel_build_job:
extends: .base_job_template
stage: build
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
timeout: 30m
script:
- mkdir build
@@ -39,7 +39,7 @@
.cross_user_build_job:
extends: .base_job_template
stage: build
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
script:
- mkdir build
- cd build
+2 -2
View File
@@ -26,7 +26,7 @@ check-dco:
check-python-minreqs:
extends: .base_job_template
stage: test
image: $CI_REGISTRY_IMAGE/qemu/python:latest
image: $CI_REGISTRY_IMAGE/qemu/python:$QEMU_CI_CONTAINER_TAG
script:
- make -C python check-minreqs
variables:
@@ -37,7 +37,7 @@ check-python-minreqs:
check-python-tox:
extends: .base_job_template
stage: test
image: $CI_REGISTRY_IMAGE/qemu/python:latest
image: $CI_REGISTRY_IMAGE/qemu/python:$QEMU_CI_CONTAINER_TAG
script:
- make -C python check-tox
variables:
+1 -1
View File
@@ -1830,7 +1830,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
} else /* if (prot & PAGE_READ) */ {
tlb_addr = tlbe->addr_read;
if (!tlb_hit(tlb_addr, addr)) {
if (!VICTIM_TLB_HIT(addr_write, addr)) {
if (!VICTIM_TLB_HIT(addr_read, addr)) {
tlb_fill(env_cpu(env), addr, size,
MMU_DATA_LOAD, mmu_idx, retaddr);
index = tlb_index(env, mmu_idx, addr);
+1 -1
View File
@@ -680,7 +680,7 @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
ret = 0;
out:
blk_unref(blk);
blk_co_unref(blk);
return ret;
}
+9 -1
View File
@@ -2018,7 +2018,15 @@ void blk_activate(BlockBackend *blk, Error **errp)
return;
}
bdrv_activate(bs, errp);
/*
* Migration code can call this function in coroutine context, so leave
* coroutine context if necessary.
*/
if (qemu_in_coroutine()) {
bdrv_co_activate(bs, errp);
} else {
bdrv_activate(bs, errp);
}
}
bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
+3 -3
View File
@@ -355,7 +355,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
ret = 0;
cleanup:
qcrypto_block_free(crypto);
blk_unref(blk);
blk_co_unref(blk);
return ret;
}
@@ -661,7 +661,7 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
ret = 0;
fail:
bdrv_unref(bs);
bdrv_co_unref(bs);
return ret;
}
@@ -730,7 +730,7 @@ fail:
bdrv_co_delete_file_noerr(bs);
}
bdrv_unref(bs);
bdrv_co_unref(bs);
qapi_free_QCryptoBlockCreateOptions(create_opts);
qobject_unref(cryptoopts);
return ret;
+2
View File
@@ -192,6 +192,7 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
return exp;
fail:
blk_set_dev_ops(exp->blk, NULL, NULL);
blk_unref(blk);
aio_context_release(ctx);
if (exp) {
@@ -219,6 +220,7 @@ static void blk_exp_delete_bh(void *opaque)
assert(exp->refcount == 0);
QLIST_REMOVE(exp, next);
exp->drv->delete(exp);
blk_set_dev_ops(exp->blk, NULL, NULL);
blk_unref(exp->blk);
qapi_event_send_block_export_deleted(exp->id);
g_free(exp->id);
-1
View File
@@ -346,7 +346,6 @@ static void vduse_blk_exp_delete(BlockExport *exp)
blk_remove_aio_context_notifier(exp->blk, blk_aio_attached, blk_aio_detach,
vblk_exp);
blk_set_dev_ops(exp->blk, NULL, NULL);
ret = vduse_dev_destroy(vblk_exp->dev);
if (ret != -EBUSY) {
unlink(vblk_exp->recon_file);
+6 -4
View File
@@ -214,15 +214,17 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
error_report("Device '%s' not found", device);
return;
}
if (!blk_is_available(blk)) {
error_report("Device '%s' has no medium", device);
return;
}
bs = bdrv_skip_implicit_filters(blk_bs(blk));
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (!blk_is_available(blk)) {
error_report("Device '%s' has no medium", device);
aio_context_release(aio_context);
return;
}
ret = bdrv_commit(bs);
aio_context_release(aio_context);
+3 -3
View File
@@ -613,8 +613,8 @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
ret = 0;
out:
blk_unref(blk);
bdrv_unref(bs);
blk_co_unref(blk);
bdrv_co_unref(bs);
return ret;
exit:
@@ -691,7 +691,7 @@ parallels_co_create_opts(BlockDriver *drv, const char *filename,
done:
qobject_unref(qdict);
bdrv_unref(bs);
bdrv_co_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
+3 -3
View File
@@ -915,8 +915,8 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
g_free(tmp);
ret = 0;
exit:
blk_unref(qcow_blk);
bdrv_unref(bs);
blk_co_unref(qcow_blk);
bdrv_co_unref(bs);
qcrypto_block_free(crypto);
return ret;
}
@@ -1015,7 +1015,7 @@ qcow_co_create_opts(BlockDriver *drv, const char *filename,
fail:
g_free(backing_fmt);
qobject_unref(qdict);
bdrv_unref(bs);
bdrv_co_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
+7 -7
View File
@@ -3705,7 +3705,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
goto out;
}
blk_unref(blk);
blk_co_unref(blk);
blk = NULL;
/*
@@ -3785,7 +3785,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
}
}
blk_unref(blk);
blk_co_unref(blk);
blk = NULL;
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning.
@@ -3810,9 +3810,9 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
ret = 0;
out:
blk_unref(blk);
bdrv_unref(bs);
bdrv_unref(data_bs);
blk_co_unref(blk);
bdrv_co_unref(bs);
bdrv_co_unref(data_bs);
return ret;
}
@@ -3943,8 +3943,8 @@ finish:
}
qobject_unref(qdict);
bdrv_unref(bs);
bdrv_unref(data_bs);
bdrv_co_unref(bs);
bdrv_co_unref(data_bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
+3 -3
View File
@@ -748,8 +748,8 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
ret = 0; /* success */
out:
g_free(l1_table);
blk_unref(blk);
bdrv_unref(bs);
blk_co_unref(blk);
bdrv_co_unref(bs);
return ret;
}
@@ -819,7 +819,7 @@ bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
fail:
qobject_unref(qdict);
bdrv_unref(bs);
bdrv_co_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
+3 -3
View File
@@ -886,8 +886,8 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
ret = 0;
exit:
blk_unref(blk);
bdrv_unref(bs_file);
blk_co_unref(blk);
bdrv_co_unref(bs_file);
g_free(bmap);
return ret;
}
@@ -975,7 +975,7 @@ vdi_co_create_opts(BlockDriver *drv, const char *filename,
done:
qobject_unref(qdict);
qapi_free_BlockdevCreateOptions(create_options);
bdrv_unref(bs_file);
bdrv_co_unref(bs_file);
return ret;
}
+3 -3
View File
@@ -2053,8 +2053,8 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
ret = 0;
delete_and_exit:
blk_unref(blk);
bdrv_unref(bs);
blk_co_unref(blk);
bdrv_co_unref(bs);
g_free(creator);
return ret;
}
@@ -2144,7 +2144,7 @@ vhdx_co_create_opts(BlockDriver *drv, const char *filename,
fail:
qobject_unref(qdict);
bdrv_unref(bs);
bdrv_co_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
+9 -9
View File
@@ -2306,7 +2306,7 @@ exit:
if (pbb) {
*pbb = blk;
} else {
blk_unref(blk);
blk_co_unref(blk);
blk = NULL;
}
}
@@ -2516,12 +2516,12 @@ vmdk_co_do_create(int64_t size,
if (strcmp(blk_bs(backing)->drv->format_name, "vmdk")) {
error_setg(errp, "Invalid backing file format: %s. Must be vmdk",
blk_bs(backing)->drv->format_name);
blk_unref(backing);
blk_co_unref(backing);
ret = -EINVAL;
goto exit;
}
ret = vmdk_read_cid(blk_bs(backing), 0, &parent_cid);
blk_unref(backing);
blk_co_unref(backing);
if (ret) {
error_setg(errp, "Failed to read parent CID");
goto exit;
@@ -2542,14 +2542,14 @@ vmdk_co_do_create(int64_t size,
blk_bs(extent_blk)->filename);
created_size += cur_size;
extent_idx++;
blk_unref(extent_blk);
blk_co_unref(extent_blk);
}
/* Check whether we got excess extents */
extent_blk = extent_fn(-1, extent_idx, flat, split, compress, zeroed_grain,
opaque, NULL);
if (extent_blk) {
blk_unref(extent_blk);
blk_co_unref(extent_blk);
error_setg(errp, "List of extents contains unused extents");
ret = -EINVAL;
goto exit;
@@ -2590,7 +2590,7 @@ vmdk_co_do_create(int64_t size,
ret = 0;
exit:
if (blk) {
blk_unref(blk);
blk_co_unref(blk);
}
g_free(desc);
g_free(parent_desc_line);
@@ -2641,7 +2641,7 @@ vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
errp)) {
goto exit;
}
bdrv_unref(bs);
bdrv_co_unref(bs);
exit:
g_free(ext_filename);
return blk;
@@ -2797,12 +2797,12 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
return NULL;
}
blk_set_allow_write_beyond_eof(blk, true);
bdrv_unref(bs);
bdrv_co_unref(bs);
if (size != -1) {
ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
if (ret) {
blk_unref(blk);
blk_co_unref(blk);
blk = NULL;
}
}
+3 -3
View File
@@ -1082,8 +1082,8 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
}
out:
blk_unref(blk);
bdrv_unref(bs);
blk_co_unref(blk);
bdrv_co_unref(bs);
return ret;
}
@@ -1162,7 +1162,7 @@ vpc_co_create_opts(BlockDriver *drv, const char *filename,
fail:
qobject_unref(qdict);
bdrv_unref(bs);
bdrv_co_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
+16 -6
View File
@@ -153,12 +153,22 @@ void blockdev_mark_auto_del(BlockBackend *blk)
JOB_LOCK_GUARD();
for (job = block_job_next_locked(NULL); job;
job = block_job_next_locked(job)) {
if (block_job_has_bdrv(job, blk_bs(blk))) {
do {
job = block_job_next_locked(NULL);
while (job && (job->job.cancelled ||
job->job.deferred_to_main_loop ||
!block_job_has_bdrv(job, blk_bs(blk))))
{
job = block_job_next_locked(job);
}
if (job) {
/*
* This drops the job lock temporarily and polls, so we need to
* restart processing the list from the start after this.
*/
job_cancel_locked(&job->job, false);
}
}
} while (job);
dinfo->auto_del = 1;
}
@@ -2430,7 +2440,7 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
return;
}
blk = blk_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp);
blk = blk_co_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp);
if (!blk) {
return;
}
@@ -2445,7 +2455,7 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
bdrv_co_lock(bs);
bdrv_drained_end(bs);
blk_unref(blk);
blk_co_unref(blk);
bdrv_co_unlock(bs);
}
+2 -2
View File
@@ -219,8 +219,8 @@ Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
System emulator machines
------------------------
Arm ``virt`` machine ``dtb-kaslr-seed`` property
''''''''''''''''''''''''''''''''''''''''''''''''
Arm ``virt`` machine ``dtb-kaslr-seed`` property (since 7.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``dtb-kaslr-seed`` property on the ``virt`` board has been
deprecated; use the new name ``dtb-randomness`` instead. The new name
+11
View File
@@ -70,6 +70,17 @@ in a handful of namespaces
repository CI settings, or as git push variables, to influence
which jobs get run in a pipeline
* QEMU_CI_CONTAINER_TAG - the tag used to publish containers
in stage 1, for use by build jobs in stage 2. Defaults to
'latest', but if running pipelines for different branches
concurrently, it should be overridden per pipeline.
* QEMU_CI_UPSTREAM - gitlab namespace that is considerd to be
the 'upstream'. This defaults to 'qemu-project'. Contributors
may choose to override this if they are modifying rules in
base.yml and need to validate how they will operate when in
an upstream context, as opposed to their fork context.
* nnn - other misc variables not falling into the above
categories, or using different names for historical reasons
and not yet converted.
+1 -1
View File
@@ -5135,7 +5135,7 @@ float32 float32_exp2(float32 a, float_status *status)
float64_unpack_canonical(&rp, float64_one, status);
for (i = 0 ; i < 15 ; i++) {
float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
rp = *parts_muladd(&tp, &xp, &rp, 0, status);
rp = *parts_muladd(&tp, &xnp, &rp, 0, status);
xnp = *parts_mul(&xnp, &xp, status);
}
+6
View File
@@ -48,3 +48,9 @@ v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name %s"
v9fs_setattr(uint16_t tag, uint8_t id, int32_t fid, int32_t valid, int32_t mode, int32_t uid, int32_t gid, int64_t size, int64_t atime_sec, int64_t mtime_sec) "tag %u id %u fid %d iattr={valid %d mode %d uid %d gid %d size %"PRId64" atime=%"PRId64" mtime=%"PRId64" }"
v9fs_setattr_return(uint16_t tag, uint8_t id) "tag %u id %u"
# xen-9p-backend.c
xen_9pfs_alloc(char *name) "name %s"
xen_9pfs_connect(char *name) "name %s"
xen_9pfs_disconnect(char *name) "name %s"
xen_9pfs_free(char *name) "name %s"
+22 -13
View File
@@ -25,6 +25,8 @@
#include "qemu/iov.h"
#include "fsdev/qemu-fsdev.h"
#include "trace.h"
#define VERSIONS "1"
#define MAX_RINGS 8
#define MAX_RING_ORDER 9
@@ -336,6 +338,8 @@ static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
int i;
trace_xen_9pfs_disconnect(xendev->name);
for (i = 0; i < xen_9pdev->num_rings; i++) {
if (xen_9pdev->rings[i].evtchndev != NULL) {
qemu_set_fd_handler(qemu_xen_evtchn_fd(xen_9pdev->rings[i].evtchndev),
@@ -344,40 +348,41 @@ static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
xen_9pdev->rings[i].local_port);
xen_9pdev->rings[i].evtchndev = NULL;
}
}
}
static int xen_9pfs_free(struct XenLegacyDevice *xendev)
{
Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
int i;
if (xen_9pdev->rings[0].evtchndev != NULL) {
xen_9pfs_disconnect(xendev);
}
for (i = 0; i < xen_9pdev->num_rings; i++) {
if (xen_9pdev->rings[i].data != NULL) {
xen_be_unmap_grant_refs(&xen_9pdev->xendev,
xen_9pdev->rings[i].data,
xen_9pdev->rings[i].intf->ref,
(1 << xen_9pdev->rings[i].ring_order));
xen_9pdev->rings[i].data = NULL;
}
if (xen_9pdev->rings[i].intf != NULL) {
xen_be_unmap_grant_ref(&xen_9pdev->xendev,
xen_9pdev->rings[i].intf,
xen_9pdev->rings[i].ref);
xen_9pdev->rings[i].intf = NULL;
}
if (xen_9pdev->rings[i].bh != NULL) {
qemu_bh_delete(xen_9pdev->rings[i].bh);
xen_9pdev->rings[i].bh = NULL;
}
}
g_free(xen_9pdev->id);
xen_9pdev->id = NULL;
g_free(xen_9pdev->tag);
xen_9pdev->tag = NULL;
g_free(xen_9pdev->path);
xen_9pdev->path = NULL;
g_free(xen_9pdev->security_model);
xen_9pdev->security_model = NULL;
g_free(xen_9pdev->rings);
xen_9pdev->rings = NULL;
}
static int xen_9pfs_free(struct XenLegacyDevice *xendev)
{
trace_xen_9pfs_free(xendev->name);
return 0;
}
@@ -389,6 +394,8 @@ static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
V9fsState *s = &xen_9pdev->state;
QemuOpts *fsdev;
trace_xen_9pfs_connect(xendev->name);
if (xenstore_read_fe_int(&xen_9pdev->xendev, "num-rings",
&xen_9pdev->num_rings) == -1 ||
xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) {
@@ -496,6 +503,8 @@ out:
static void xen_9pfs_alloc(struct XenLegacyDevice *xendev)
{
trace_xen_9pfs_alloc(xendev->name);
xenstore_write_be_str(xendev, "versions", VERSIONS);
xenstore_write_be_int(xendev, "max-rings", MAX_RINGS);
xenstore_write_be_int(xendev, "max-ring-page-order", MAX_RING_ORDER);
+10
View File
@@ -357,6 +357,16 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
* acpi_pcihp_eject_slot() when the operation is completed.
*/
pdev->qdev.pending_deleted_event = true;
/* if unplug was requested before OSPM is initialized,
* linux kernel will clear GPE0.sts[] bits during boot, which effectively
* hides unplug event. And than followup qmp_device_del() calls remain
* blocked by above flag permanently.
* Unblock qmp_device_del() by setting expire limit, so user can
* repeat unplug request later when OSPM has been booted.
*/
pdev->qdev.pending_deleted_expires_ms =
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); /* 1 msec */
s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
}
+20 -18
View File
@@ -200,33 +200,35 @@ struct AspeedMachineState {
static void aspeed_write_smpboot(ARMCPU *cpu,
const struct arm_boot_info *info)
{
static const uint32_t poll_mailbox_ready[] = {
AddressSpace *as = arm_boot_address_space(cpu, info);
static const ARMInsnFixup poll_mailbox_ready[] = {
/*
* r2 = per-cpu go sign value
* r1 = AST_SMP_MBOX_FIELD_ENTRY
* r0 = AST_SMP_MBOX_FIELD_GOSIGN
*/
0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5 */
0xe21000ff, /* ands r0, r0, #255 */
0xe59f201c, /* ldr r2, [pc, #28] */
0xe1822000, /* orr r2, r2, r0 */
{ 0xee100fb0 }, /* mrc p15, 0, r0, c0, c0, 5 */
{ 0xe21000ff }, /* ands r0, r0, #255 */
{ 0xe59f201c }, /* ldr r2, [pc, #28] */
{ 0xe1822000 }, /* orr r2, r2, r0 */
0xe59f1018, /* ldr r1, [pc, #24] */
0xe59f0018, /* ldr r0, [pc, #24] */
{ 0xe59f1018 }, /* ldr r1, [pc, #24] */
{ 0xe59f0018 }, /* ldr r0, [pc, #24] */
0xe320f002, /* wfe */
0xe5904000, /* ldr r4, [r0] */
0xe1520004, /* cmp r2, r4 */
0x1afffffb, /* bne <wfe> */
0xe591f000, /* ldr pc, [r1] */
AST_SMP_MBOX_GOSIGN,
AST_SMP_MBOX_FIELD_ENTRY,
AST_SMP_MBOX_FIELD_GOSIGN,
{ 0xe320f002 }, /* wfe */
{ 0xe5904000 }, /* ldr r4, [r0] */
{ 0xe1520004 }, /* cmp r2, r4 */
{ 0x1afffffb }, /* bne <wfe> */
{ 0xe591f000 }, /* ldr pc, [r1] */
{ AST_SMP_MBOX_GOSIGN },
{ AST_SMP_MBOX_FIELD_ENTRY },
{ AST_SMP_MBOX_FIELD_GOSIGN },
{ 0, FIXUP_TERMINATOR }
};
static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
rom_add_blob_fixed("aspeed.smpboot", poll_mailbox_ready,
sizeof(poll_mailbox_ready),
info->smp_loader_start);
arm_write_bootloader("aspeed.smpboot", as, info->smp_loader_start,
poll_mailbox_ready, fixupcontext);
}
static void aspeed_reset_secondary(ARMCPU *cpu,
+8 -27
View File
@@ -60,26 +60,6 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu,
return cpu_get_address_space(cs, asidx);
}
typedef enum {
FIXUP_NONE = 0, /* do nothing */
FIXUP_TERMINATOR, /* end of insns */
FIXUP_BOARDID, /* overwrite with board ID number */
FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
FIXUP_BOOTREG, /* overwrite with boot register address */
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
FIXUP_MAX,
} FixupType;
typedef struct ARMInsnFixup {
uint32_t insn;
FixupType fixup;
} ARMInsnFixup;
static const ARMInsnFixup bootloader_aarch64[] = {
{ 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
{ 0xaa1f03e1 }, /* mov x1, xzr */
@@ -150,9 +130,10 @@ static const ARMInsnFixup smpboot[] = {
{ 0, FIXUP_TERMINATOR }
};
static void write_bootloader(const char *name, hwaddr addr,
const ARMInsnFixup *insns, uint32_t *fixupcontext,
AddressSpace *as)
void arm_write_bootloader(const char *name,
AddressSpace *as, hwaddr addr,
const ARMInsnFixup *insns,
const uint32_t *fixupcontext)
{
/* Fix up the specified bootloader fragment and write it into
* guest memory using rom_add_blob_fixed(). fixupcontext is
@@ -214,8 +195,8 @@ static void default_write_secondary(ARMCPU *cpu,
fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
}
write_bootloader("smpboot", info->smp_loader_start,
smpboot, fixupcontext, as);
arm_write_bootloader("smpboot", as, info->smp_loader_start,
smpboot, fixupcontext);
}
void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
@@ -1186,8 +1167,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
write_bootloader("bootloader", info->loader_start,
primary_loader, fixupcontext, as);
arm_write_bootloader("bootloader", as, info->loader_start,
primary_loader, fixupcontext);
if (info->write_board_setup) {
info->write_board_setup(cpu, info);
+34 -30
View File
@@ -16,6 +16,7 @@
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "hw/arm/boot.h"
#include "hw/arm/bcm2836.h"
#include "hw/registerfields.h"
#include "qemu/error-report.h"
@@ -124,20 +125,22 @@ static const char *board_type(uint32_t board_rev)
static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
{
static const uint32_t smpboot[] = {
0xe1a0e00f, /* mov lr, pc */
0xe3a0fe00 + (BOARDSETUP_ADDR >> 4), /* mov pc, BOARDSETUP_ADDR */
0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
0xe7e10050, /* ubfx r0, r0, #0, #2 ;extract LSB */
0xe59f5014, /* ldr r5, =0x400000CC ;load mbox base */
0xe320f001, /* 1: yield */
0xe7953200, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core*/
0xe3530000, /* cmp r3, #0 ;spin while zero */
0x0afffffb, /* beq 1b */
0xe7853200, /* str r3, [r5, r0, lsl #4] ;clear mbox */
0xe12fff13, /* bx r3 ;jump to target */
0x400000cc, /* (constant: mailbox 3 read/clear base) */
static const ARMInsnFixup smpboot[] = {
{ 0xe1a0e00f }, /* mov lr, pc */
{ 0xe3a0fe00 + (BOARDSETUP_ADDR >> 4) }, /* mov pc, BOARDSETUP_ADDR */
{ 0xee100fb0 }, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
{ 0xe7e10050 }, /* ubfx r0, r0, #0, #2 ;extract LSB */
{ 0xe59f5014 }, /* ldr r5, =0x400000CC ;load mbox base */
{ 0xe320f001 }, /* 1: yield */
{ 0xe7953200 }, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core */
{ 0xe3530000 }, /* cmp r3, #0 ;spin while zero */
{ 0x0afffffb }, /* beq 1b */
{ 0xe7853200 }, /* str r3, [r5, r0, lsl #4] ;clear mbox */
{ 0xe12fff13 }, /* bx r3 ;jump to target */
{ 0x400000cc }, /* (constant: mailbox 3 read/clear base) */
{ 0, FIXUP_TERMINATOR }
};
static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
/* check that we don't overrun board setup vectors */
QEMU_BUILD_BUG_ON(SMPBOOT_ADDR + sizeof(smpboot) > MVBAR_ADDR);
@@ -145,9 +148,8 @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
QEMU_BUILD_BUG_ON((BOARDSETUP_ADDR & 0xf) != 0
|| (BOARDSETUP_ADDR >> 4) >= 0x100);
rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
info->smp_loader_start,
arm_boot_address_space(cpu, info));
arm_write_bootloader("raspi_smpboot", arm_boot_address_space(cpu, info),
info->smp_loader_start, smpboot, fixupcontext);
}
static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
@@ -161,26 +163,28 @@ static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
* the primary CPU goes into the kernel. We put these variables inside
* a rom blob, so that the reset for ROM contents zeroes them for us.
*/
static const uint32_t smpboot[] = {
0xd2801b05, /* mov x5, 0xd8 */
0xd53800a6, /* mrs x6, mpidr_el1 */
0x924004c6, /* and x6, x6, #0x3 */
0xd503205f, /* spin: wfe */
0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
0xb4ffffc4, /* cbz x4, spin */
0xd2800000, /* mov x0, #0x0 */
0xd2800001, /* mov x1, #0x0 */
0xd2800002, /* mov x2, #0x0 */
0xd2800003, /* mov x3, #0x0 */
0xd61f0080, /* br x4 */
static const ARMInsnFixup smpboot[] = {
{ 0xd2801b05 }, /* mov x5, 0xd8 */
{ 0xd53800a6 }, /* mrs x6, mpidr_el1 */
{ 0x924004c6 }, /* and x6, x6, #0x3 */
{ 0xd503205f }, /* spin: wfe */
{ 0xf86678a4 }, /* ldr x4, [x5,x6,lsl #3] */
{ 0xb4ffffc4 }, /* cbz x4, spin */
{ 0xd2800000 }, /* mov x0, #0x0 */
{ 0xd2800001 }, /* mov x1, #0x0 */
{ 0xd2800002 }, /* mov x2, #0x0 */
{ 0xd2800003 }, /* mov x3, #0x0 */
{ 0xd61f0080 }, /* br x4 */
{ 0, FIXUP_TERMINATOR }
};
static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
static const uint64_t spintables[] = {
0, 0, 0, 0
};
rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
info->smp_loader_start, as);
arm_write_bootloader("raspi_smpboot", as, info->smp_loader_start,
smpboot, fixupcontext);
rom_add_blob_fixed_as("raspi_spintables", spintables, sizeof(spintables),
SPINTABLE_ADDR, as);
}
+2 -5
View File
@@ -49,12 +49,9 @@ static void aw_a10_pic_update(AwA10PICState *s)
static void aw_a10_pic_set_irq(void *opaque, int irq, int level)
{
AwA10PICState *s = opaque;
uint32_t *pending_reg = &s->irq_pending[irq / 32];
if (level) {
set_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
} else {
clear_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
}
*pending_reg = deposit32(*pending_reg, irq % 32, 1, level);
aw_a10_pic_update(s);
}
+15 -7
View File
@@ -350,8 +350,13 @@ static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
FrameDescriptor *desc,
uint32_t phys_addr)
{
dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc),
uint32_t desc_words[4];
dma_memory_read(&s->dma_as, phys_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
desc->status = le32_to_cpu(desc_words[0]);
desc->status2 = le32_to_cpu(desc_words[1]);
desc->addr = le32_to_cpu(desc_words[2]);
desc->next = le32_to_cpu(desc_words[3]);
}
static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
@@ -400,10 +405,15 @@ static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
}
static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
FrameDescriptor *desc,
const FrameDescriptor *desc,
uint32_t phys_addr)
{
dma_memory_write(&s->dma_as, phys_addr, desc, sizeof(*desc),
uint32_t desc_words[4];
desc_words[0] = cpu_to_le32(desc->status);
desc_words[1] = cpu_to_le32(desc->status2);
desc_words[2] = cpu_to_le32(desc->addr);
desc_words[3] = cpu_to_le32(desc->next);
dma_memory_write(&s->dma_as, phys_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
}
@@ -638,8 +648,7 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
break;
case REG_TX_CUR_BUF: /* Transmit Current Buffer */
if (s->tx_desc_curr != 0) {
dma_memory_read(&s->dma_as, s->tx_desc_curr, &desc, sizeof(desc),
MEMTXATTRS_UNSPECIFIED);
allwinner_sun8i_emac_get_desc(s, &desc, s->tx_desc_curr);
value = desc.addr;
} else {
value = 0;
@@ -652,8 +661,7 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
break;
case REG_RX_CUR_BUF: /* Receive Current Buffer */
if (s->rx_desc_curr != 0) {
dma_memory_read(&s->dma_as, s->rx_desc_curr, &desc, sizeof(desc),
MEMTXATTRS_UNSPECIFIED);
allwinner_sun8i_emac_get_desc(s, &desc, s->rx_desc_curr);
value = desc.addr;
} else {
value = 0;
+10 -6
View File
@@ -118,14 +118,18 @@ static void emac_load_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
d->next = le32_to_cpu(d->next);
}
static void emac_store_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
static void emac_store_desc(MSF2EmacState *s, const EmacDesc *d, hwaddr desc)
{
/* Convert from host endianness into LE. */
d->pktaddr = cpu_to_le32(d->pktaddr);
d->pktsize = cpu_to_le32(d->pktsize);
d->next = cpu_to_le32(d->next);
EmacDesc outd;
/*
* Convert from host endianness into LE. We use a local struct because
* calling code may still want to look at the fields afterwards.
*/
outd.pktaddr = cpu_to_le32(d->pktaddr);
outd.pktsize = cpu_to_le32(d->pktsize);
outd.next = cpu_to_le32(d->next);
address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, &outd, sizeof outd);
}
static void msf2_dma_tx(MSF2EmacState *s)
+1 -1
View File
@@ -311,7 +311,7 @@ static void pxb_cxl_dev_reset(DeviceState *dev)
* The CXL specification allows for host bridges with no HDM decoders
* if they only have a single root port.
*/
if (!PXB_DEV(dev)->hdm_for_passthrough) {
if (!PXB_CXL_DEV(dev)->hdm_for_passthrough) {
dsp_count = pcie_count_ds_ports(hb->bus);
}
/* Initial reset will have 0 dsp so wait until > 0 */
+26 -5
View File
@@ -302,6 +302,30 @@ static void allwinner_sdhost_auto_stop(AwSdHostState *s)
}
}
static void read_descriptor(AwSdHostState *s, hwaddr desc_addr,
TransferDescriptor *desc)
{
uint32_t desc_words[4];
dma_memory_read(&s->dma_as, desc_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
desc->status = le32_to_cpu(desc_words[0]);
desc->size = le32_to_cpu(desc_words[1]);
desc->addr = le32_to_cpu(desc_words[2]);
desc->next = le32_to_cpu(desc_words[3]);
}
static void write_descriptor(AwSdHostState *s, hwaddr desc_addr,
const TransferDescriptor *desc)
{
uint32_t desc_words[4];
desc_words[0] = cpu_to_le32(desc->status);
desc_words[1] = cpu_to_le32(desc->size);
desc_words[2] = cpu_to_le32(desc->addr);
desc_words[3] = cpu_to_le32(desc->next);
dma_memory_write(&s->dma_as, desc_addr, &desc_words, sizeof(desc_words),
MEMTXATTRS_UNSPECIFIED);
}
static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
hwaddr desc_addr,
TransferDescriptor *desc,
@@ -312,9 +336,7 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
uint32_t num_bytes = max_bytes;
uint8_t buf[1024];
/* Read descriptor */
dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc),
MEMTXATTRS_UNSPECIFIED);
read_descriptor(s, desc_addr, desc);
if (desc->size == 0) {
desc->size = klass->max_desc_size;
} else if (desc->size > klass->max_desc_size) {
@@ -356,8 +378,7 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
/* Clear hold flag and flush descriptor */
desc->status &= ~DESC_STATUS_HOLD;
dma_memory_write(&s->dma_as, desc_addr, desc, sizeof(*desc),
MEMTXATTRS_UNSPECIFIED);
write_descriptor(s, desc_addr, desc);
return num_done;
}
+1 -1
View File
@@ -179,7 +179,7 @@ static void imx_epit_update_compare_timer(IMXEPITState *s)
* the compare value. Otherwise it may fire at most once in the
* current round.
*/
bool is_oneshot = (limit >= s->cmp);
is_oneshot = (limit < s->cmp);
if (counter >= s->cmp) {
/* The compare timer fires in the current round. */
counter -= s->cmp;
+7 -2
View File
@@ -166,7 +166,11 @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
const char *node_name, Error **errp);
int bdrv_activate(BlockDriverState *bs, Error **errp);
int no_coroutine_fn bdrv_activate(BlockDriverState *bs, Error **errp);
int coroutine_fn no_co_wrapper
bdrv_co_activate(BlockDriverState *bs, Error **errp);
void bdrv_activate_all(Error **errp);
int bdrv_inactivate_all(void);
@@ -214,7 +218,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
bool quiet, Error **errp);
void bdrv_ref(BlockDriverState *bs);
void bdrv_unref(BlockDriverState *bs);
void no_coroutine_fn bdrv_unref(BlockDriverState *bs);
void coroutine_fn no_co_wrapper bdrv_co_unref(BlockDriverState *bs);
void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
BlockDriverState *child_bs,
+49
View File
@@ -183,4 +183,53 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
const struct arm_boot_info *info,
hwaddr mvbar_addr);
typedef enum {
FIXUP_NONE = 0, /* do nothing */
FIXUP_TERMINATOR, /* end of insns */
FIXUP_BOARDID, /* overwrite with board ID number */
FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
FIXUP_BOOTREG, /* overwrite with boot register address */
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
FIXUP_MAX,
} FixupType;
typedef struct ARMInsnFixup {
uint32_t insn;
FixupType fixup;
} ARMInsnFixup;
/**
* arm_write_bootloader - write a bootloader to guest memory
* @name: name of the bootloader blob
* @as: AddressSpace to write the bootloader
* @addr: guest address to write it
* @insns: the blob to be loaded
* @fixupcontext: context to be used for any fixups in @insns
*
* Write a bootloader to guest memory at address @addr in the address
* space @as. @name is the name to use for the resulting ROM blob, so
* it should be unique in the system and reasonably identifiable for debugging.
*
* @insns must be an array of ARMInsnFixup structs, each of which has
* one 32-bit value to be written to the guest memory, and a fixup to be
* applied to the value. FIXUP_NONE (do nothing) is value 0, so effectively
* the fixup is optional when writing a struct initializer.
* The final entry in the array must be { 0, FIXUP_TERMINATOR }.
*
* All other supported fixup types have the semantics "ignore insn
* and instead use the value from the array element @fixupcontext[fixup]".
* The caller should therefore provide @fixupcontext as an array of
* size FIXUP_MAX whose elements have been initialized for at least
* the entries that @insns refers to.
*/
void arm_write_bootloader(const char *name,
AddressSpace *as, hwaddr addr,
const ARMInsnFixup *insns,
const uint32_t *fixupcontext);
#endif /* HW_ARM_BOOT_H */
+4 -1
View File
@@ -42,7 +42,10 @@ blk_co_new_open(const char *filename, const char *reference, QDict *options,
int blk_get_refcnt(BlockBackend *blk);
void blk_ref(BlockBackend *blk);
void blk_unref(BlockBackend *blk);
void no_coroutine_fn blk_unref(BlockBackend *blk);
void coroutine_fn no_co_wrapper blk_co_unref(BlockBackend *blk);
void blk_remove_all_bs(void);
BlockBackend *blk_by_name(const char *name);
BlockBackend *blk_next(BlockBackend *blk);
+4
View File
@@ -3213,6 +3213,10 @@ modinfo_files = []
block_mods = []
softmmu_mods = []
foreach d, list : modules
if not (d == 'block' ? have_block : have_system)
continue
endif
foreach m, module_ss : list
if enable_modules and targetos != 'windows'
module_ss = module_ss.apply(config_all, strict: false)
+22 -2
View File
@@ -1143,10 +1143,22 @@ have gone through several iterations as the feature set and complexity
of the block layer have grown. Many online guides to QEMU often
reference older and deprecated options, which can lead to confusion.
The recommended modern way to describe disks is to use a combination of
The most explicit way to describe disks is to use a combination of
``-device`` to specify the hardware device and ``-blockdev`` to
describe the backend. The device defines what the guest sees and the
backend describes how QEMU handles the data.
backend describes how QEMU handles the data. It is the only guaranteed
stable interface for describing block devices and as such is
recommended for management tools and scripting.
The ``-drive`` option combines the device and backend into a single
command line option which is a more human friendly. There is however no
interface stability guarantee although some older board models still
need updating to work with the modern blockdev forms.
Older options like ``-hda`` are essentially macros which expand into
``-drive`` options for various drive interfaces. The original forms
bake in a lot of assumptions from the days when QEMU was emulating a
legacy PC, they are not recommended for modern configurations.
ERST
@@ -1639,6 +1651,14 @@ SRST
the raw disk image you use is not written back. You can however
force the write back by pressing C-a s (see the :ref:`disk images`
chapter in the System Emulation Users Guide).
.. warning::
snapshot is incompatible with ``-blockdev`` (instead use qemu-img
to manually create snapshot images to attach to your blockdev).
If you have mixed ``-blockdev`` and ``-drive`` declarations you
can use the 'snapshot' property on your drive declarations
instead of this global option.
ERST
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
+1 -1
View File
@@ -233,7 +233,7 @@ int aarch64_gdb_get_pauth_reg(CPUARMState *env, GByteArray *buf, int reg)
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
ARMVAParameters param;
param = aa64_va_parameters(env, -is_high, mmu_idx, is_data);
param = aa64_va_parameters(env, -is_high, mmu_idx, is_data, false);
return gdb_get_reg64(buf, pauth_ptr_mask(param));
}
default:
+13 -2
View File
@@ -4904,7 +4904,7 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
unsigned int page_size_granule, page_shift, num, scale, exponent;
/* Extract one bit to represent the va selector in use. */
uint64_t select = sextract64(value, 36, 1);
ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true, false);
TLBIRange ret = { };
ARMGranuleSize gran;
@@ -11193,7 +11193,8 @@ static ARMGranuleSize sanitize_gran_size(ARMCPU *cpu, ARMGranuleSize gran,
}
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
ARMMMUIdx mmu_idx, bool data)
ARMMMUIdx mmu_idx, bool data,
bool el1_is_aa32)
{
uint64_t tcr = regime_tcr(env, mmu_idx);
bool epd, hpd, tsz_oob, ds, ha, hd;
@@ -11289,6 +11290,16 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
}
}
if (stage2 && el1_is_aa32) {
/*
* For AArch32 EL1 the min txsz (and thus max IPA size) requirements
* are loosened: a configured IPA of 40 bits is permitted even if
* the implemented PA is less than that (and so a 40 bit IPA would
* fault for an AArch64 EL1). See R_DTLMN.
*/
min_tsz = MIN(min_tsz, 24);
}
if (tsz > max_tsz) {
tsz = max_tsz;
tsz_oob = true;
+11 -1
View File
@@ -1091,8 +1091,18 @@ typedef struct ARMVAParameters {
ARMGranuleSize gran : 2;
} ARMVAParameters;
/**
* aa64_va_parameters: Return parameters for an AArch64 virtual address
* @env: CPU
* @va: virtual address to look up
* @mmu_idx: determines translation regime to use
* @data: true if this is a data access
* @el1_is_aa32: true if we are asking about stage 2 when EL1 is AArch32
* (ignored if @mmu_idx is for a stage 1 regime; only affects tsz/tsz_oob)
*/
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
ARMMMUIdx mmu_idx, bool data);
ARMMMUIdx mmu_idx, bool data,
bool el1_is_aa32);
int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx);
+2
View File
@@ -280,6 +280,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
}
}
kvm_arm_init_debug(s);
return ret;
}
+4 -14
View File
@@ -74,24 +74,16 @@ GArray *hw_breakpoints, *hw_watchpoints;
#define get_hw_bp(i) (&g_array_index(hw_breakpoints, HWBreakpoint, i))
#define get_hw_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i))
/**
* kvm_arm_init_debug() - check for guest debug capabilities
* @cs: CPUState
*
* kvm_check_extension returns the number of debug registers we have
* or 0 if we have none.
*
*/
static void kvm_arm_init_debug(CPUState *cs)
void kvm_arm_init_debug(KVMState *s)
{
have_guest_debug = kvm_check_extension(cs->kvm_state,
have_guest_debug = kvm_check_extension(s,
KVM_CAP_SET_GUEST_DEBUG);
max_hw_wps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_WPS);
max_hw_wps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_WPS);
hw_watchpoints = g_array_sized_new(true, true,
sizeof(HWWatchpoint), max_hw_wps);
max_hw_bps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_BPS);
max_hw_bps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_BPS);
hw_breakpoints = g_array_sized_new(true, true,
sizeof(HWBreakpoint), max_hw_bps);
return;
@@ -920,8 +912,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
kvm_arm_init_debug(cs);
/* Check whether user space can specify guest syndrome value */
kvm_arm_init_serror_injection(cs);
+8
View File
@@ -18,6 +18,14 @@
#define KVM_ARM_VGIC_V2 (1 << 0)
#define KVM_ARM_VGIC_V3 (1 << 1)
/**
* kvm_arm_init_debug() - initialize guest debug capabilities
* @s: KVMState
*
* Should be called only once before using guest debug capabilities.
*/
void kvm_arm_init_debug(KVMState *s);
/**
* kvm_arm_vcpu_init:
* @cs: CPUState
+53 -37
View File
@@ -103,6 +103,37 @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
return stage_1_mmu_idx(arm_mmu_idx(env));
}
/*
* Return where we should do ptw loads from for a stage 2 walk.
* This depends on whether the address we are looking up is a
* Secure IPA or a NonSecure IPA, which we know from whether this is
* Stage2 or Stage2_S.
* If this is the Secure EL1&0 regime we need to check the NSW and SW bits.
*/
static ARMMMUIdx ptw_idx_for_stage_2(CPUARMState *env, ARMMMUIdx stage2idx)
{
bool s2walk_secure;
/*
* We're OK to check the current state of the CPU here because
* (1) we always invalidate all TLBs when the SCR_EL3.NS bit changes
* (2) there's no way to do a lookup that cares about Stage 2 for a
* different security state to the current one for AArch64, and AArch32
* never has a secure EL2. (AArch32 ATS12NSO[UP][RW] allow EL3 to do
* an NS stage 1+2 lookup while the NS bit is 0.)
*/
if (!arm_is_secure_below_el3(env) || !arm_el_is_aa64(env, 3)) {
return ARMMMUIdx_Phys_NS;
}
if (stage2idx == ARMMMUIdx_Stage2_S) {
s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
} else {
s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
}
return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
}
static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
{
return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
@@ -220,7 +251,6 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
uint8_t pte_attrs;
bool pte_secure;
ptw->out_virt = addr;
@@ -232,8 +262,8 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
if (regime_is_stage2(s2_mmu_idx)) {
S1Translate s2ptw = {
.in_mmu_idx = s2_mmu_idx,
.in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS,
.in_secure = is_secure,
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
.in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
.in_debug = true,
};
GetPhysAddrResult s2 = { };
@@ -244,12 +274,12 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
}
ptw->out_phys = s2.f.phys_addr;
pte_attrs = s2.cacheattrs.attrs;
pte_secure = s2.f.attrs.secure;
ptw->out_secure = s2.f.attrs.secure;
} else {
/* Regime is physical. */
ptw->out_phys = addr;
pte_attrs = 0;
pte_secure = is_secure;
ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
}
ptw->out_host = NULL;
ptw->out_rw = false;
@@ -270,7 +300,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK);
ptw->out_rw = full->prot & PAGE_WRITE;
pte_attrs = full->pte_attrs;
pte_secure = full->attrs.secure;
ptw->out_secure = full->attrs.secure;
#else
g_assert_not_reached();
#endif
@@ -293,11 +323,6 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
}
}
/* Check if page table walk is to secure or non-secure PA space. */
ptw->out_secure = (is_secure
&& !(pte_secure
? env->cp15.vstcr_el2 & VSTCR_SW
: env->cp15.vtcr_el2 & VTCR_NSW));
ptw->out_be = regime_translation_big_endian(env, mmu_idx);
return true;
@@ -1097,17 +1122,6 @@ static int check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint64_t tcr,
sl0 = extract32(tcr, 6, 2);
if (is_aa64) {
/*
* AArch64.S2InvalidTxSZ: While we checked tsz_oob near the top of
* get_phys_addr_lpae, that used aa64_va_parameters which apply
* to aarch64. If Stage1 is aarch32, the min_txsz is larger.
* See AArch64.S2MinTxSZ, where min_tsz is 24, translated to
* inputsize is 64 - 24 = 40.
*/
if (iasize < 40 && !arm_el_is_aa64(&cpu->env, 1)) {
goto fail;
}
/*
* AArch64.S2InvalidSL: Interpretation of SL depends on the page size,
* so interleave AArch64.S2StartLevel.
@@ -1247,7 +1261,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
int ps;
param = aa64_va_parameters(env, address, mmu_idx,
access_type != MMU_INST_FETCH);
access_type != MMU_INST_FETCH,
!arm_el_is_aa64(env, 1));
level = 0;
/*
@@ -2713,7 +2728,7 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
hwaddr ipa;
int s1_prot, s1_lgpgsz;
bool is_secure = ptw->in_secure;
bool ret, ipa_secure, s2walk_secure;
bool ret, ipa_secure;
ARMCacheAttrs cacheattrs1;
bool is_el0;
uint64_t hcr;
@@ -2727,20 +2742,11 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
ipa = result->f.phys_addr;
ipa_secure = result->f.attrs.secure;
if (is_secure) {
/* Select TCR based on the NS bit from the S1 walk. */
s2walk_secure = !(ipa_secure
? env->cp15.vstcr_el2 & VSTCR_SW
: env->cp15.vtcr_el2 & VTCR_NSW);
} else {
assert(!ipa_secure);
s2walk_secure = false;
}
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
ptw->in_ptw_idx = s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
ptw->in_secure = s2walk_secure;
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
ptw->in_secure = ipa_secure;
ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx);
/*
* S1 is done, now do S2 translation.
@@ -2848,6 +2854,16 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
break;
case ARMMMUIdx_Stage2:
case ARMMMUIdx_Stage2_S:
/*
* Second stage lookup uses physical for ptw; whether this is S or
* NS may depend on the SW/NSW bits if this is a stage 2 lookup for
* the Secure EL2&0 regime.
*/
ptw->in_ptw_idx = ptw_idx_for_stage_2(env, mmu_idx);
break;
case ARMMMUIdx_E10_0:
s1_mmu_idx = ARMMMUIdx_Stage1_E0;
goto do_twostage;
@@ -2871,7 +2887,7 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
/* fall through */
default:
/* Single stage and second stage uses physical for ptw. */
/* Single stage uses physical for ptw. */
ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
break;
}
+3 -3
View File
@@ -293,7 +293,7 @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
ARMPACKey *key, bool data)
{
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
uint64_t pac, ext_ptr, ext, test;
int bot_bit, top_bit;
@@ -355,7 +355,7 @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
ARMPACKey *key, bool data, int keynumber)
{
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
int bot_bit, top_bit;
uint64_t pac, orig_ptr, test;
@@ -379,7 +379,7 @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
{
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
return pauth_original_ptr(ptr, param);
}
+2 -2
View File
@@ -2816,7 +2816,7 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
dc_isar_feature(aa64_sel2, s)) {
/* Target EL is EL<3 minus SCR_EL3.EEL2> */
tcg_el = load_cpu_field(cp15.scr_el3);
tcg_el = load_cpu_field_low32(cp15.scr_el3);
tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
tcg_gen_addi_i32(tcg_el, tcg_el, 3);
} else {
@@ -6396,7 +6396,7 @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
}
if (s->current_el == 2) {
/* ERET from Hyp uses ELR_Hyp, not LR */
tmp = load_cpu_field(elr_el[2]);
tmp = load_cpu_field_low32(elr_el[2]);
} else {
tmp = load_reg(s, 14);
}
+7
View File
@@ -61,6 +61,13 @@ static inline TCGv_i32 load_cpu_offset(int offset)
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
/* Load from the low half of a 64-bit field to a TCGv_i32 */
#define load_cpu_field_low32(name) \
({ \
QEMU_BUILD_BUG_ON(sizeof_field(CPUARMState, name) != 8); \
load_cpu_offset(offsetoflow32(CPUARMState, name)); \
})
void store_cpu_offset(TCGv_i32 var, int offset, int size);
#define store_cpu_field(var, name) \
+2 -2
View File
@@ -5718,8 +5718,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
} else {
*eax &= env->features[FEAT_SGX_12_1_EAX];
*ebx &= 0; /* ebx reserve */
*ecx &= env->features[FEAT_XSAVE_XSS_LO];
*edx &= env->features[FEAT_XSAVE_XSS_HI];
*ecx &= env->features[FEAT_XSAVE_XCR0_LO];
*edx &= env->features[FEAT_XSAVE_XCR0_HI];
/* FP and SSE are always allowed regardless of XSAVE/XCR0. */
*ecx |= XSTATE_FP_MASK | XSTATE_SSE_MASK;
+1 -1
View File
@@ -2058,7 +2058,7 @@ static bool trans_VEXPANDQM(DisasContext *ctx, arg_VX_tb *a)
static bool do_vextractm(DisasContext *ctx, arg_VX_tb *a, unsigned vece)
{
const uint64_t elem_width = 8 << vece, elem_count_half = 8 >> vece,
mask = dup_const(vece, 1 << (elem_width - 1));
mask = dup_const(vece, 1ULL << (elem_width - 1));
uint64_t i, j;
TCGv_i64 lo, hi, t0, t1;
+9 -2
View File
@@ -3797,6 +3797,11 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
return RISCV_EXCP_ILLEGAL_INST;
}
/* ensure CSR is implemented by checking predicate */
if (!csr_ops[csrno].predicate) {
return RISCV_EXCP_ILLEGAL_INST;
}
/* privileged spec version check */
if (env->priv_ver < csr_min_priv) {
return RISCV_EXCP_ILLEGAL_INST;
@@ -3814,7 +3819,6 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
* illegal instruction exception should be triggered instead of virtual
* instruction exception. Hence this comes after the read / write check.
*/
g_assert(csr_ops[csrno].predicate != NULL);
RISCVException ret = csr_ops[csrno].predicate(env, csrno);
if (ret != RISCV_EXCP_NONE) {
return ret;
@@ -3991,7 +3995,10 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
return ret;
}
/* Control and Status Register function table */
/*
* Control and Status Register function table
* riscv_csr_operations::predicate() must be provided for an implemented CSR
*/
riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
/* User Floating-Point CSRs */
[CSR_FFLAGS] = { "fflags", fs, read_fflags, write_fflags },
@@ -77,6 +77,9 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
#ifndef CONFIG_USER_ONLY
if (has_ext(ctx, RVS)) {
decode_save_opc(ctx);
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
gen_helper_sret(cpu_pc, cpu_env);
exit_tb(ctx); /* no chaining */
ctx->base.is_jmp = DISAS_NORETURN;
@@ -93,6 +96,9 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
{
#ifndef CONFIG_USER_ONLY
decode_save_opc(ctx);
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
gen_helper_mret(cpu_pc, cpu_env);
exit_tb(ctx); /* no chaining */
ctx->base.is_jmp = DISAS_NORETURN;
+1 -1
View File
@@ -606,7 +606,7 @@
F(0xed04, LDEB, RXE, Z, 0, m2_32u, new, f1, ldeb, 0, IF_BFP)
F(0xed05, LXDB, RXE, Z, 0, m2_64, new_x, x1, lxdb, 0, IF_BFP)
F(0xed06, LXEB, RXE, Z, 0, m2_32u, new_x, x1, lxeb, 0, IF_BFP)
F(0xb324, LDER, RXE, Z, 0, e2, new, f1, lde, 0, IF_AFP1)
F(0xb324, LDER, RRE, Z, 0, e2, new, f1, lde, 0, IF_AFP1)
F(0xed24, LDE, RXE, Z, 0, m2_32u, new, f1, lde, 0, IF_AFP1)
/* LOAD ROUNDED */
F(0xb344, LEDBR, RRF_e, Z, 0, f2, new, e1, ledb, 0, IF_BFP)
+58 -23
View File
@@ -1534,18 +1534,51 @@ static DisasJumpType op_bal(DisasContext *s, DisasOps *o)
}
}
/*
* Disassemble the target of a branch. The results are returned in a form
* suitable for passing into help_branch():
*
* - bool IS_IMM reflects whether the target is fixed or computed. Non-EXECUTEd
* branches, whose DisasContext *S contains the relative immediate field RI,
* are considered fixed. All the other branches are considered computed.
* - int IMM is the value of RI.
* - TCGv_i64 CDEST is the address of the computed target.
*/
#define disas_jdest(s, ri, is_imm, imm, cdest) do { \
if (have_field(s, ri)) { \
if (unlikely(s->ex_value)) { \
cdest = tcg_temp_new_i64(); \
tcg_gen_ld_i64(cdest, cpu_env, offsetof(CPUS390XState, ex_target));\
tcg_gen_addi_i64(cdest, cdest, (int64_t)get_field(s, ri) * 2); \
is_imm = false; \
} else { \
is_imm = true; \
} \
} else { \
is_imm = false; \
} \
imm = is_imm ? get_field(s, ri) : 0; \
} while (false)
static DisasJumpType op_basi(DisasContext *s, DisasOps *o)
{
DisasCompare c;
bool is_imm;
int imm;
pc_to_link_info(o->out, s, s->pc_tmp);
return help_goto_direct(s, s->base.pc_next + (int64_t)get_field(s, i2) * 2);
disas_jdest(s, i2, is_imm, imm, o->in2);
disas_jcc(s, &c, 0xf);
return help_branch(s, &c, is_imm, imm, o->in2);
}
static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
{
int m1 = get_field(s, m1);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
int imm;
/* BCR with R2 = 0 causes no branching */
if (have_field(s, r2) && get_field(s, r2) == 0) {
@@ -1562,6 +1595,7 @@ static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
disas_jdest(s, i2, is_imm, imm, o->in2);
disas_jcc(s, &c, m1);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1569,10 +1603,10 @@ static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
static DisasJumpType op_bct32(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
TCGv_i64 t;
int imm;
c.cond = TCG_COND_NE;
c.is_64 = false;
@@ -1584,6 +1618,7 @@ static DisasJumpType op_bct32(DisasContext *s, DisasOps *o)
c.u.s32.b = tcg_constant_i32(0);
tcg_gen_extrl_i64_i32(c.u.s32.a, t);
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1611,9 +1646,9 @@ static DisasJumpType op_bcth(DisasContext *s, DisasOps *o)
static DisasJumpType op_bct64(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
int imm;
c.cond = TCG_COND_NE;
c.is_64 = true;
@@ -1622,6 +1657,7 @@ static DisasJumpType op_bct64(DisasContext *s, DisasOps *o)
c.u.s64.a = regs[r1];
c.u.s64.b = tcg_constant_i64(0);
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1629,10 +1665,10 @@ static DisasJumpType op_bx32(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
int r3 = get_field(s, r3);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
TCGv_i64 t;
int imm;
c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
c.is_64 = false;
@@ -1645,6 +1681,7 @@ static DisasJumpType op_bx32(DisasContext *s, DisasOps *o)
tcg_gen_extrl_i64_i32(c.u.s32.b, regs[r3 | 1]);
store_reg32_i64(r1, t);
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1652,9 +1689,9 @@ static DisasJumpType op_bx64(DisasContext *s, DisasOps *o)
{
int r1 = get_field(s, r1);
int r3 = get_field(s, r3);
bool is_imm = have_field(s, i2);
int imm = is_imm ? get_field(s, i2) : 0;
DisasCompare c;
bool is_imm;
int imm;
c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
c.is_64 = true;
@@ -1668,6 +1705,7 @@ static DisasJumpType op_bx64(DisasContext *s, DisasOps *o)
tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]);
c.u.s64.a = regs[r1];
disas_jdest(s, i2, is_imm, imm, o->in2);
return help_branch(s, &c, is_imm, imm, o->in2);
}
@@ -1685,10 +1723,9 @@ static DisasJumpType op_cj(DisasContext *s, DisasOps *o)
c.u.s64.a = o->in1;
c.u.s64.b = o->in2;
is_imm = have_field(s, i4);
if (is_imm) {
imm = get_field(s, i4);
} else {
o->out = NULL;
disas_jdest(s, i4, is_imm, imm, o->out);
if (!is_imm && !o->out) {
imm = 0;
o->out = get_address(s, 0, get_field(s, b4),
get_field(s, d4));
@@ -5774,15 +5811,13 @@ static void in2_a2(DisasContext *s, DisasOps *o)
static TCGv gen_ri2(DisasContext *s)
{
int64_t delta = (int64_t)get_field(s, i2) * 2;
TCGv ri2;
TCGv ri2 = NULL;
bool is_imm;
int imm;
if (unlikely(s->ex_value)) {
ri2 = tcg_temp_new_i64();
tcg_gen_ld_i64(ri2, cpu_env, offsetof(CPUS390XState, ex_target));
tcg_gen_addi_i64(ri2, ri2, delta);
} else {
ri2 = tcg_constant_i64(s->base.pc_next + delta);
disas_jdest(s, i2, is_imm, imm, ri2);
if (is_imm) {
ri2 = tcg_constant_i64(s->base.pc_next + imm * 2);
}
return ri2;
+1 -1
View File
@@ -1083,7 +1083,7 @@ static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
{
/* This function is only used for passing structs by reference. */
tcg_debug_assert(imm == (int32_t)imm);
tcg_out_modrm_offset(s, OPC_LEA, rd, rs, imm);
tcg_out_modrm_offset(s, OPC_LEA | P_REXW, rd, rs, imm);
}
static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
+2 -2
View File
@@ -311,7 +311,7 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
png_struct *png_ptr;
png_info *info_ptr;
g_autoptr(pixman_image_t) linebuf =
qemu_pixman_linebuf_create(PIXMAN_a8r8g8b8, width);
qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
uint8_t *buf = (uint8_t *)pixman_image_get_data(linebuf);
FILE *f = fdopen(fd, "wb");
int y;
@@ -341,7 +341,7 @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
png_init_io(png_ptr, f);
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
+1 -1
View File
@@ -3751,7 +3751,7 @@ static int vnc_display_get_address(const char *addrstr,
addr->type = SOCKET_ADDRESS_TYPE_INET;
inet = &addr->u.inet;
if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
if (hostlen && addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
inet->host = g_strndup(addrstr + 1, hostlen - 2);
} else {
inet->host = g_strndup(addrstr, hostlen);
+14
View File
@@ -164,7 +164,21 @@ int aio_bh_poll(AioContext *ctx)
/* Synchronizes with QSLIST_INSERT_HEAD_ATOMIC in aio_bh_enqueue(). */
QSLIST_MOVE_ATOMIC(&slice.bh_list, &ctx->bh_list);
/*
* GCC13 [-Werror=dangling-pointer=] complains that the local variable
* 'slice' is being stored in the global 'ctx->bh_slice_list' but the
* list is emptied before this function returns.
*/
#if !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wdangling-pointer="
#endif
QSIMPLEQ_INSERT_TAIL(&ctx->bh_slice_list, &slice, next);
#if !defined(__clang__)
#pragma GCC diagnostic pop
#endif
while ((s = QSIMPLEQ_FIRST(&ctx->bh_slice_list))) {
QEMUBH *bh;