Compare commits

...

91 Commits

Author SHA1 Message Date
Michael Roth 920019e0e0 Update version for 3.1.1.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 17:27:10 -05:00
Michael Roth 9efdbc0224 slrip: ip_reass: Fix use after free
Using ip_deq after m_free might read pointers from an allocation reuse.

This would be difficult to exploit, but that is still related with
CVE-2019-14378 which generates fragmented IP packets that would trigger this
issue and at least produce a DoS.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
(from libslirp.git commit c59279437eda91841b9d26079c70b8a540d41204)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 17:00:56 -05:00
Michael Roth 28c1dde9aa slirp: Fix heap overflow in ip_reass on big packet input
When the first fragment does not fit in the preallocated buffer, q will
already be pointing to the ext buffer, so we mustn't try to update it.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
(from libslirp.git commit 126c04acbabd7ad32c2b018fe10dfac2a3bc1210)
(from libslirp.git commit e0be80430c390bce181ea04dfcdd6ea3dfa97de1)
*squash in e0be80 (clarifying comments)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 17:00:56 -05:00
Cole Robinson ab630a065a pvrdma: Fix compilation error
In function ‘create_qp’:
  hw/rdma/vmw/pvrdma_cmd.c:517:16: error: ‘rc’ undeclared

The backport of 509f57c98 in 41dd30ff6 mishandled the conflict

Signed-off-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-19 11:20:17 -05:00
Michael Roth 71049d2a74 Update version for 3.1.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-08-02 11:02:35 -05:00
Prasad J Pandit 03d7712b4b qemu-bridge-helper: restrict interface name to IFNAMSIZ
The network interface name in Linux is defined to be of size
IFNAMSIZ(=16), including the terminating null('\0') byte.
The same is applied to interface names read from 'bridge.conf'
file to form ACL rules. If user supplied '--br=bridge' name
is not restricted to the same length, it could lead to ACL bypass
issue. Restrict interface name to IFNAMSIZ, including null byte.

Reported-by: Riccardo Schirone <rschiron@redhat.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 6f5d867122)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:44:36 -05:00
Kevin Wolf 4482258130 block: Fix hangs in synchronous APIs with iothreads
In the block layer, synchronous APIs are often implemented by creating a
coroutine that calls the asynchronous coroutine-based implementation and
then waiting for completion with BDRV_POLL_WHILE().

For this to work with iothreads (more specifically, when the synchronous
API is called in a thread that is not the home thread of the block
device, so that the coroutine will run in a different thread), we must
make sure to call aio_wait_kick() at the end of the operation. Many
places are missing this, so that BDRV_POLL_WHILE() keeps hanging even if
the condition has long become false.

Note that bdrv_dec_in_flight() involves an aio_wait_kick() call. This
corresponds to the BDRV_POLL_WHILE() in the drain functions, but it is
generally not enough for most other operations because they haven't set
the return value in the coroutine entry stub yet. To avoid race
conditions there, we need to kick after setting the return value.

The race window is small enough that the problem doesn't usually surface
in the common path. However, it does surface and causes easily
reproducible hangs if the operation can return early before even calling
bdrv_inc/dec_in_flight, which many of them do (trivial error or no-op
success paths).

The bug in bdrv_truncate(), bdrv_check() and bdrv_invalidate_cache() is
slightly different: These functions even neglected to schedule the
coroutine in the home thread of the node. This avoids the hang, but is
obviously wrong, too. Fix those to schedule the coroutine in the right
AioContext in addition to adding aio_wait_kick() calls.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 4720cbeea1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:44:05 -05:00
Prasad J Pandit 41dd30ff63 pvrdma: release ring object in case of an error
create_cq and create_qp routines allocate ring object, but it's
not released in case of an error, leading to memory leakage.

Reported-by: Li Qiang <liq3ea@163.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit 509f57c98e)
 Conflicts:
	hw/rdma/vmw/pvrdma_cmd.c
*drop dependency on 09178217
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:38:45 -05:00
Prasad J Pandit a1001760ab pvrdma: check return value from pvrdma_idx_ring_has_ routines
pvrdma_idx_ring_has_[data/space] routines also return invalid
index PVRDMA_INVALID_IDX[=-1], if ring has no data/space. Check
return value from these routines to avoid plausible infinite loops.

Reported-by: Li Qiang <liq3ea@163.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit f1e2e38ee0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:19:47 -05:00
Prasad J Pandit 2a0e6f1369 pvrdma: check number of pages when creating rings
When creating CQ/QP rings, an object can have up to
PVRDMA_MAX_FAST_REG_PAGES 8 pages. Check 'npages' parameter
to avoid excessive memory allocation or a null dereference.

Reported-by: Li Qiang <liq3ea@163.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit 2c858ce5da)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:19:15 -05:00
Markus Armbruster 017f271f7a device_tree: Fix integer overflowing in load_device_tree()
If the value of get_image_size() exceeds INT_MAX / 2 - 10000, the
computation of @dt_size overflows to a negative number, which then
gets converted to a very large size_t for g_malloc0() and
load_image_size().  In the (fortunately improbable) case g_malloc0()
succeeds and load_image_size() survives, we'd assign the negative
number to *sizep.  What that would do to the callers I can't say, but
it's unlikely to be good.

Fix by rejecting images whose size would overflow.

Reported-by: Kurtis Miller <kurtis.miller@nccgroup.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20190409174018.25798-1-armbru@redhat.com>
(cherry picked from commit 065e6298a7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Peter Maydell 5149630fed device_tree.c: Don't use load_image()
The load_image() function is deprecated, as it does not let the
caller specify how large the buffer to read the file into is.
Instead use load_image_size().

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20181130151712.2312-9-peter.maydell@linaro.org
(cherry picked from commit da885fe1ee)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Prasad J Pandit 59a823017a sun4u: add power_mem_read routine
Define skeleton 'power_mem_read' routine. Avoid NULL dereference.

Reported-by: Fakhri Zulkifli <mohdfakhrizulkifli@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
(cherry picked from commit ad280559c6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Prasad J Pandit 3be7eb2f47 qxl: check release info object
When releasing spice resources in release_resource() routine,
if release info object 'ext.info' is null, it leads to null
pointer dereference. Add check to avoid it.

Reported-by: Bugs SysSec <bugs-syssec@rub.de>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 20190425063534.32747-1-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit d52680fc93)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Daniel P. Berrangé 576964bf2a seccomp: don't kill process for resource control syscalls
The Mesa library tries to set process affinity on some of its threads in
order to optimize its performance. Currently this results in QEMU being
immediately terminated when seccomp is enabled.

Mesa doesn't consider failure of the process affinity settings to be
fatal to its operation, but our seccomp policy gives it no choice in
gracefully handling this denial.

It is reasonable to consider that malicious code using the resource
control syscalls to be a less serious attack than if they were trying
to spawn processes or change UIDs and other such things. Generally
speaking changing the resource control setting will "merely" affect
quality of service of processes on the host. With this in mind, rather
than kill the process, we can relax the policy for these syscalls to
return the EPERM errno value. This allows callers to detect that QEMU
does not want them to change resource allocations, and apply some
reasonable fallback logic.

The main downside to this is for code which uses these syscalls but does
not check the return value, blindly assuming they will always
succeeed. Returning an errno could result in sub-optimal behaviour.
Arguably though such code is already broken & needs fixing regardless.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
(cherry picked from commit 9a1565a03b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Gerd Hoffmann 4c7f4c4bbb i2c-ddc: fix oob read
Suggested-by: Michael Hanselmann <public@hansmi.ch>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Michael Hanselmann <public@hansmi.ch>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190108102301.1957-1-kraxel@redhat.com
(cherry picked from commit b05b267840)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Prasad J Pandit 4e74e7a867 slirp: check data length while emulating ident function
While emulating identification protocol, tcp_emu() does not check
available space in the 'sc_rcv->sb_data' buffer. It could lead to
heap buffer overflow issue. Add check to avoid it.

Reported-by: Kira <864786842@qq.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
(cherry picked from commit a7104eda7d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Paolo Bonzini 375667af78 scsi-generic: avoid possible out-of-bounds access to r->buf
Whenever the allocation length of a SCSI request is shorter than the size of the
VPD page list, page_idx is used blindly to index into r->buf.  Even though
the stores in the insertion sort are protected against overflows, the same is not
true of the reads and the final store of 0xb0.

This basically does the same thing as commit 57dbb58d80 ("scsi-generic: avoid
out-of-bounds access to VPD page list", 2018-11-06), except that here the
allocation length can be chosen by the guest.  Note that according to the SCSI
standard, the contents of the PAGE LENGTH field are not altered based
on the allocation length.

The code was introduced by commit 6c219fc8a1 ("scsi-generic: keep VPD
page list sorted", 2018-11-06) but the overflow was already possible before.

Reported-by: Kevin Wolf <kwolf@redhat.com>
Fixes: a71c775b24
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e909ff9369)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Prasad J Pandit bceff528ba pvrdma: add uar_read routine
Define skeleton 'uar_read' routine. Avoid NULL dereference.

Reported-by: Li Qiang <liq3ea@163.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit 2aa86456fb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Prasad J Pandit 1549e3a54a pvrdma: release device resources in case of an error
If during pvrdma device initialisation an error occurs,
pvrdma_realize() does not release memory resources, leading
to memory leakage.

Reported-by: Li Qiang <liq3ea@163.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <20181212175817.815-1-ppandit@redhat.com>
Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit cce648613b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Niels de Vos 86d4f40141 gluster: the glfs_io_cbk callback function pointer adds pre/post stat args
The glfs_*_async() functions do a callback once finished. This callback
has changed its arguments, pre- and post-stat structures have been
added. This makes it possible to improve caching, which is useful for
Samba and NFS-Ganesha, but not so much for QEMU. Gluster 6 is the first
release that includes these new arguments.

With an additional detection in ./configure, the new arguments can
conditionally get included in the glfs_io_cbk handler.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 0e3b891fef)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Prasanna Kumar Kalever 37867211d9 gluster: Handle changed glfs_ftruncate signature
New versions of Glusters libgfapi.so have an updated glfs_ftruncate()
function that returns additional 'struct stat' structures to enable
advanced caching of attributes. This is useful for file servers, not so
much for QEMU. Nevertheless, the API has changed and needs to be
adopted.

Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e014dbe74e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Philippe Mathieu-Daudé 43a3a1b694 hw/block/pflash_cfi01: Add missing DeviceReset() handler
To avoid incoherent states when the machine resets (see bug report
below), add the device reset callback.

A "system reset" sets the device state machine in READ_ARRAY mode
and, after some delay, set the SR.7 READY bit.

Since we do not model timings, we set the SR.7 bit directly.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1678713
Reported-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
[Laszlo Ersek: Regression tested EDK2 OVMF IA32X64, ArmVirtQemu Aarch64
 https://lists.gnu.org/archive/html/qemu-devel/2019-07/msg04373.html]
Message-Id: <20190718104837.13905-2-philmd@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
(cherry picked from commit 3a283507c0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:15:46 -05:00
Markus Armbruster ddacb784b3 hw: Use PFLASH_CFI0{1,2} and TYPE_PFLASH_CFI0{1,2}
We have two open-coded copies of macro PFLASH_CFI01().  Move the macro
to the header, so we can ditch the copies.  Move PFLASH_CFI02() to the
header for symmetry.

We define macros TYPE_PFLASH_CFI01 and TYPE_PFLASH_CFI02 for type name
strings, then mostly use the strings.  If the macros are worth
defining, they are worth using.  Replace the strings by the macros.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20190308094610.21210-6-armbru@redhat.com>
(cherry picked from commit 81c7db723e)
*prereq for 3a283507
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:14:29 -05:00
Markus Armbruster 03f130c682 pflash: Rename *CFI_PFLASH* to *PFLASH_CFI*
pflash_cfi01.c and pflash_cfi02.c start their identifiers with
pflash_cfi01_ and pflash_cfi02_ respectively, except for
CFI_PFLASH01(), TYPE_CFI_PFLASH01, CFI_PFLASH02(), TYPE_CFI_PFLASH02.
Rename for consistency.

Suggested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20190308094610.21210-5-armbru@redhat.com>
(cherry picked from commit e7b6274197)
*prereq for 3a283507
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:14:00 -05:00
Markus Armbruster 10b1d6070a pflash_cfi01: Log use of flawed "write to buffer"
Our implementation of "write to buffer" (command 0xE8) is flawed.
LOG_UNIMP its use, and add some FIXME comments.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20190308094610.21210-4-armbru@redhat.com>
(cherry picked from commit 4dbda935e0)
*prereq for 3a283507
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:13:29 -05:00
Markus Armbruster e634054c9d pflash_cfi01: Do not exit() on guest aborting "write to buffer"
When a guest tries to abort "write to buffer" (command 0xE8), we print
"PFLASH: Possible BUG - Write block confirm", then exit(1).  Letting
the guest terminate QEMU is not a good idea.  Instead, LOG_UNIMP we
screwed up, then reset the device.

Macro PFLASH_BUG() is now unused; delete it.

Suggested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20190308094610.21210-3-armbru@redhat.com>
(cherry picked from commit 2d93bebf81)
*prereq for 3a283507
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:12:55 -05:00
Markus Armbruster 13cb31ce08 pflash: Rename pflash_t to PFlashCFI01, PFlashCFI02
flash.h's incomplete struct pflash_t is completed both in
pflash_cfi01.c and in pflash_cfi02.c.  The complete types are
incompatible.  This can hide type errors, such as passing a pflash_t
created with pflash_cfi02_register() to pflash_cfi01_get_memory().

Furthermore, POSIX reserves typedef names ending with _t.

Rename the two structs to PFlashCFI01 and PFlashCFI02.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190308094610.21210-2-armbru@redhat.com>
(cherry picked from commit 1643406520)
*prereq for 3a283507
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:07:50 -05:00
Stephen Checkoway d0cb440280 block/pflash_cfi02: Fix memory leak and potential use-after-free
Don't dynamically allocate the pflash's timer. But do use timer_del in
an unrealize function to make sure that the timer can't fire after the
pflash_t has been freed.

Signed-off-by: Stephen Checkoway <stephen.checkoway@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Wei Yang <richardw.yang@linux.intel.com>
Message-Id: <20190219153727.62279-1-stephen.checkoway@oberlin.edu>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit d80cf1eb2e)
*prereq for 16434065/3a283507
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 15:07:18 -05:00
Philippe Mathieu-Daudé 21e5c69b85 hw/display/xlnx_dp: Avoid crash when reading empty RX FIFO
In the previous commit we fixed a crash when the guest read a
register that pop from an empty FIFO.
By auditing the repository, we found another similar use with
an easy way to reproduce:

  $ qemu-system-aarch64 -M xlnx-zcu102 -monitor stdio -S
  QEMU 4.0.50 monitor - type 'help' for more information
  (qemu) xp/b 0xfd4a0134
  Aborted (core dumped)

  (gdb) bt
  #0  0x00007f6936dea57f in raise () at /lib64/libc.so.6
  #1  0x00007f6936dd4895 in abort () at /lib64/libc.so.6
  #2  0x0000561ad32975ec in xlnx_dp_aux_pop_rx_fifo (s=0x7f692babee70) at hw/display/xlnx_dp.c:431
  #3  0x0000561ad3297dc0 in xlnx_dp_read (opaque=0x7f692babee70, offset=77, size=4) at hw/display/xlnx_dp.c:667
  #4  0x0000561ad321b896 in memory_region_read_accessor (mr=0x7f692babf620, addr=308, value=0x7ffe05c1db88, size=4, shift=0, mask=4294967295, attrs=...) at memory.c:439
  #5  0x0000561ad321bd70 in access_with_adjusted_size (addr=308, value=0x7ffe05c1db88, size=1, access_size_min=4, access_size_max=4, access_fn=0x561ad321b858 <memory_region_read_accessor>, mr=0x7f692babf620, attrs=...) at memory.c:569
  #6  0x0000561ad321e9d5 in memory_region_dispatch_read1 (mr=0x7f692babf620, addr=308, pval=0x7ffe05c1db88, size=1, attrs=...) at memory.c:1420
  #7  0x0000561ad321ea9d in memory_region_dispatch_read (mr=0x7f692babf620, addr=308, pval=0x7ffe05c1db88, size=1, attrs=...) at memory.c:1447
  #8  0x0000561ad31bd742 in flatview_read_continue (fv=0x561ad69c04f0, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1, addr1=308, l=1, mr=0x7f692babf620) at exec.c:3385
  #9  0x0000561ad31bd895 in flatview_read (fv=0x561ad69c04f0, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1) at exec.c:3423
  #10 0x0000561ad31bd90b in address_space_read_full (as=0x561ad5bb3020, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1) at exec.c:3436
  #11 0x0000561ad33b1c42 in address_space_read (len=1, buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", attrs=..., addr=4249485620, as=0x561ad5bb3020) at include/exec/memory.h:2131
  #12 0x0000561ad33b1c42 in memory_dump (mon=0x561ad59c4530, count=1, format=120, wsize=1, addr=4249485620, is_physical=1) at monitor/misc.c:723
  #13 0x0000561ad33b1fc1 in hmp_physical_memory_dump (mon=0x561ad59c4530, qdict=0x561ad6c6fd00) at monitor/misc.c:795
  #14 0x0000561ad37b4a9f in handle_hmp_command (mon=0x561ad59c4530, cmdline=0x561ad59d0f22 "/b 0x00000000fd4a0134") at monitor/hmp.c:1082

Fix by checking the FIFO is not empty before popping from it.

The datasheet is not clear about the reset value of this register,
we choose to return '0'.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20190709113715.7761-4-philmd@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit a09ef50404)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 14:45:55 -05:00
Philippe Mathieu-Daudé e2ec206ea9 hw/ssi/mss-spi: Avoid crash when reading empty RX FIFO
Reading the RX_DATA register when the RX_FIFO is empty triggers
an abort. This can be easily reproduced:

  $ qemu-system-arm -M emcraft-sf2 -monitor stdio -S
  QEMU 4.0.50 monitor - type 'help' for more information
  (qemu) x 0x40001010
  Aborted (core dumped)

  (gdb) bt
  #1  0x00007f035874f895 in abort () at /lib64/libc.so.6
  #2  0x00005628686591ff in fifo8_pop (fifo=0x56286a9a4c68) at util/fifo8.c:66
  #3  0x00005628683e0b8e in fifo32_pop (fifo=0x56286a9a4c68) at include/qemu/fifo32.h:137
  #4  0x00005628683e0efb in spi_read (opaque=0x56286a9a4850, addr=4, size=4) at hw/ssi/mss-spi.c:168
  #5  0x0000562867f96801 in memory_region_read_accessor (mr=0x56286a9a4b60, addr=16, value=0x7ffeecb0c5c8, size=4, shift=0, mask=4294967295, attrs=...) at memory.c:439
  #6  0x0000562867f96cdb in access_with_adjusted_size (addr=16, value=0x7ffeecb0c5c8, size=4, access_size_min=1, access_size_max=4, access_fn=0x562867f967c3 <memory_region_read_accessor>, mr=0x56286a9a4b60, attrs=...) at memory.c:569
  #7  0x0000562867f99940 in memory_region_dispatch_read1 (mr=0x56286a9a4b60, addr=16, pval=0x7ffeecb0c5c8, size=4, attrs=...) at memory.c:1420
  #8  0x0000562867f99a08 in memory_region_dispatch_read (mr=0x56286a9a4b60, addr=16, pval=0x7ffeecb0c5c8, size=4, attrs=...) at memory.c:1447
  #9  0x0000562867f38721 in flatview_read_continue (fv=0x56286aec6360, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, addr1=16, l=4, mr=0x56286a9a4b60) at exec.c:3385
  #10 0x0000562867f38874 in flatview_read (fv=0x56286aec6360, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4) at exec.c:3423
  #11 0x0000562867f388ea in address_space_read_full (as=0x56286aa3e890, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4) at exec.c:3436
  #12 0x0000562867f389c5 in address_space_rw (as=0x56286aa3e890, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, is_write=false) at exec.c:3466
  #13 0x0000562867f3bdd7 in cpu_memory_rw_debug (cpu=0x56286aa19d00, addr=1073745936, buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, is_write=0) at exec.c:3976
  #14 0x000056286811ed51 in memory_dump (mon=0x56286a8c32d0, count=1, format=120, wsize=4, addr=1073745936, is_physical=0) at monitor/misc.c:730
  #15 0x000056286811eff1 in hmp_memory_dump (mon=0x56286a8c32d0, qdict=0x56286b15c400) at monitor/misc.c:785
  #16 0x00005628684740ee in handle_hmp_command (mon=0x56286a8c32d0, cmdline=0x56286a8caeb2 "0x40001010") at monitor/hmp.c:1082

From the datasheet "Actel SmartFusion Microcontroller Subsystem
User's Guide" Rev.1, Table 13-3 "SPI Register Summary", this
register has a reset value of 0.

Check the FIFO is not empty before accessing it, else log an
error message.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20190709113715.7761-3-philmd@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit c0bccee9b4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 14:45:15 -05:00
Philippe Mathieu-Daudé 1f30e35861 hw/ssi/xilinx_spips: Avoid out-of-bound access to lqspi_buf[]
Both lqspi_read() and lqspi_load_cache() expect a 32-bit
aligned address.

>From UG1085 datasheet [*] chapter on 'Quad-SPI Controller':

  Transfer Size Limitations

    Because of the 32-bit wide TX, RX, and generic FIFO, all
    APB/AXI transfers must be an integer multiple of 4-bytes.
    Shorter transfers are not possible.

Set MemoryRegionOps.impl values to force 32-bit accesses,
this way we are sure we do not access the lqspi_buf[] array
out of bound.

[*] https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf

Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 526668c734)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 14:44:36 -05:00
Philippe Mathieu-Daudé 19f55e7ab5 target/m68k: Fix a tcg_temp leak
The function gen_get_ccr() returns a tcg_temp created with
tcg_temp_new(). Free it with tcg_temp_free().

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190310003428.11723-4-f4bug@amsat.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit 44c64e9095)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 14:33:20 -05:00
Michael S. Tsirkin c6b77a64b4 virtio-balloon: free pbp more aggressively
Previous patches switched to a temporary pbp but that does not go far
enough: after device uses a buffer, guest is free to reuse it, so
tracking the page and freeing it later is wrong.

Free and reset the pbp after we push each element.

Fixes: ed48c59875 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size")
Cc: qemu-stable@nongnu.org #v4.0.0
Cc: David Hildenbrand <david@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 1b47b37c33)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:46:52 -05:00
David Hildenbrand 0965d5583e virtio-balloon: don't track subpages for the PBP
As ramblocks cannot get removed/readded while we are processing a bulk
of inflation requests, there is no more need to track the page size
in form of the number of subpages.

Suggested-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190725113638.4702-8-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 9a7ca8a7c9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:46:46 -05:00
David Hildenbrand 14d9028a7d virtio-balloon: Use temporary PBP only
We still have multiple issues in the current code
- The PBP is not freed during unrealize()
- The PBP is not reset on device resets: After a reset, the PBP is stale.
- We are not indicating VIRTIO_BALLOON_F_MUST_TELL_HOST, therefore
  guests (esp. legacy guests) will reuse pages without deflating,
  turning the PBP stale. Adding that would require compat handling.

Instead, let's use the PBP only temporarily, when processing one bulk of
inflation requests. This will keep guest_page_size > 4k working (with
Linux guests). There is nothing to do for deflation requests anymore.
The pbp is only used for a limited amount of time.

Fixes: ed48c59875 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size")
Cc: qemu-stable@nongnu.org #v4.0.0
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190722134108.22151-7-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit a8cd64d488)
*drop context dependency on qemu_4_0_config_size changes
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:45:53 -05:00
David Hildenbrand 2aa5009412 virtio-balloon: Rework pbp tracking data
Using the address of a RAMBlock to test for a matching pbp is not really
safe. Instead, let's use the guest physical address of the base page
along with the page size (via the number of subpages).

Also, let's allocate the bitmap separately. This makes the code
easier to read and maintain - we can reuse bitmap_new().

Prepare the code to move the PBP out of the device.

Fixes: ed48c59875 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size")
Fixes: b27b323914 ("virtio-balloon: Fix possible guest memory corruption with inflates & deflates")
Cc: qemu-stable@nongnu.org #v4.0.0
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190722134108.22151-6-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 1c5cfc2b71)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:41:34 -05:00
David Hildenbrand 46275f9091 virtio-balloon: Better names for offset variables in inflate/deflate code
"host_page_base" is really confusing, let's make this clearer, also
rename the other offsets to indicate to which base they apply.

offset -> mr_offset
ram_offset -> rb_offset
host_page_base -> rb_aligned_offset

While at it, use QEMU_ALIGN_DOWN() instead of a handcrafted computation
and move the computation to the place where it is needed.

Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190722134108.22151-5-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit e6129b271b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:41:24 -05:00
David Hildenbrand b0d6feca99 virtio-balloon: Simplify deflate with pbp
Let's simplify this - the case we are optimizing for is very hard to
trigger and not worth the effort. If we're switching from inflation to
deflation, let's reset the pbp.

Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190722134108.22151-4-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2ffc49eea1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:41:18 -05:00
David Hildenbrand 07026c30c3 virtio-balloon: Fix QEMU crashes on pagesize > BALLOON_PAGE_SIZE
We are using the wrong functions to set/clear bits, effectively touching
multiple bits, writing out of range of the bitmap, resulting in memory
corruptions. We have to use set_bit()/clear_bit() instead.

Can easily be reproduced by starting a qemu guest on hugetlbfs memory,
inflating the balloon. QEMU crashes. This never could have worked
properly - especially, also pages would have been discarded when the
first sub-page would be inflated (the whole bitmap would be set).

While testing I realized, that on hugetlbfs it is pretty much impossible
to discard a page - the guest just frees the 4k sub-pages in random order
most of the time. I was only able to discard a hugepage a handful of
times - so I hope that now works correctly.

Fixes: ed48c59875 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size")
Fixes: b27b323914 ("virtio-balloon: Fix possible guest memory corruption with inflates & deflates")
Cc: qemu-stable@nongnu.org #v4.0.0
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190722134108.22151-3-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 483f13524b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:38:57 -05:00
David Hildenbrand 11dd808dc0 virtio-balloon: Fix wrong sign extension of PFNs
If we directly cast from int to uint64_t, we will first sign-extend to
an int64_t, which is wrong. We actually want to treat the PFNs like
unsigned values.

As far as I can see, this dates back to the initial virtio-balloon
commit, but wasn't triggered as fairly big guests would be required.

Cc: qemu-stable@nongnu.org
Reported-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190722134108.22151-2-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit ffa207d082)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:38:33 -05:00
David Gibson f8364784f0 virtio-balloon: Restore MADV_WILLNEED hint on balloon deflate
Prior to f6deb6d9 "virtio-balloon: Remove unnecessary MADV_WILLNEED on
deflate", the balloon device issued an madvise() MADV_WILLNEED on
pages removed from the balloon.  That would hint to the host kernel
that the pages were likely to be needed by the guest in the near
future.

It's unclear if this is actually valuable or not, and so f6deb6d9
removed this, essentially ignoring balloon deflate requests.  However,
concerns have been raised that this might cause a performance
regression by causing extra latency for the guest in certain
configurations.

So, until we can get actual benchmark data to see if that's the case,
this restores the old behaviour, issuing a MADV_WILLNEED when a page is
removed from the balloon.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <20190306030601.21986-4-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 596546fe9e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:36:15 -05:00
David Gibson 38e8e9007d virtio-balloon: Fix possible guest memory corruption with inflates & deflates
This fixes a balloon bug with a nasty consequence - potentially
corrupting guest memory - but which is extremely unlikely to be
triggered in practice.

The balloon always works in 4kiB units, but the host could have a
larger page size on certain platforms.  Since ed48c59 "virtio-balloon:
Safely handle BALLOON_PAGE_SIZE < host page size" we've handled this
by accumulating requests to balloon 4kiB subpages until they formed a
full host page.  Since f6deb6d "virtio-balloon: Remove unnecessary
MADV_WILLNEED on deflate" we essentially ignore deflate requests.

Suppose we have a host with 8kiB pages, and one host page has subpages
A & B.  If we get this sequence of events -
	inflate A
	deflate A
	inflate B
- the current logic will discard the whole host page.  That's
incorrect because the guest has deflated subpage A, and could have
written important data to it.

This patch fixes the problem by adjusting our state information about
partially ballooned host pages when deflate requests are received.

Fixes: ed48c59 "virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size"

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <20190306030601.21986-3-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: David Hildenbrand <david@redhat.com>
(cherry picked from commit b27b323914)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:35:14 -05:00
David Gibson 80c96a7b60 virtio-balloon: Don't mismatch g_malloc()/free (CID 1399146)
ed48c59875 "virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host
page size" introduced a new temporary data structure which tracks 4kiB
chunks which have been inserted into the balloon by the guest but
don't yet form a full host page which we can discard.

Unfortunately, I had a thinko and allocated that structure with
g_malloc0() but freed it with a plain free() rather than g_free().
This corrects the problem.

Fixes: ed48c59875
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <20190306030601.21986-2-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
(cherry picked from commit 301cf2a8dd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:34:38 -05:00
David Gibson 118112024d virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size
The virtio-balloon always works in units of 4kiB (BALLOON_PAGE_SIZE), but
we can only actually discard memory in units of the host page size.

Now, we handle this very badly: we silently ignore balloon requests that
aren't host page aligned, and for requests that are host page aligned we
discard the entire host page.  The latter can corrupt guest memory if its
page size is smaller than the host's.

The obvious choice would be to disable the balloon if the host page size is
not 4kiB.  However, that would break the special case where host and guest
have the same page size, but that's larger than 4kiB.  That case currently
works by accident[1] - and is used in practice on many production POWER
systems where 64kiB has long been the Linux default page size on both host
and guest.

To make the balloon safe, without breaking that useful special case, we
need to accumulate 4kiB balloon requests until we have a whole contiguous
host page to discard.

We could in principle do that across all guest memory, but it would require
a large bitmap to track.  This patch represents a compromise: we track
ballooned subpages for a single contiguous host page at a time.  This means
that if the guest discards all 4kiB chunks of a host page in succession,
we will discard it.  This is the expected behaviour in the (host page) ==
(guest page) != 4kiB case we want to support.

If the guest scatters 4kiB requests across different host pages, we don't
discard anything, and issue a warning.  Not ideal, but at least we don't
corrupt guest memory as the previous version could.

Warning reporting is kind of a compromise here.  Determining whether we're
in a problematic state at realize() time is tricky, because we'd have to
look at the host pagesizes of all memory backends, but we can't really know
if some of those backends could be for special purpose memory that's not
subject to ballooning.

Reporting only when the guest tries to balloon a partial page also isn't
great because if the guest page size happens to line up it won't indicate
that we're in a non ideal situation.  It could also cause alarming repeated
warnings whenever a migration is attempted.

So, what we do is warn the first time the guest attempts balloon a partial
host page, whether or not it will end up ballooning the rest of the page
immediately afterwards.

[1] Because when the guest attempts to balloon a page, it will submit
    requests for each 4kiB subpage.  Most will be ignored, but the one
    which happens to be host page aligned will discard the whole lot.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <20190214043916.22128-6-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit ed48c59875)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:34:09 -05:00
David Gibson 83cddbaadf virtio-balloon: Use ram_block_discard_range() instead of raw madvise()
Currently, virtio-balloon uses madvise() with MADV_DONTNEED to actually
discard RAM pages inserted into the balloon.  This is basically a Linux
only interface (MADV_DONTNEED exists on some other platforms, but doesn't
always have the same semantics).  It also doesn't work on hugepages and has
some other limitations.

It turns out that postcopy also needs to discard chunks of memory, and uses
a better interface for it: ram_block_discard_range().  It doesn't cover
every case, but it covers more than going direct to madvise() and this
gives us a single place to update for more possibilities in future.

There are some subtleties here to maintain the current balloon behaviour:

* For now, we just ignore requests to balloon in a hugepage backed region.
  That matches current behaviour, because MADV_DONTNEED on a hugepage would
  simply fail, and we ignore the error.

* If host page size is > BALLOON_PAGE_SIZE we can frequently call this on
  non-host-page-aligned addresses.  These would also fail in madvise(),
  which we then ignored.  ram_block_discard_range() error_report()s calls
  on unaligned addresses, so we explicitly check that case to avoid
  spamming the logs.

* We now call ram_block_discard_range() with the *host* page size, whereas
  we previously called madvise() with BALLOON_PAGE_SIZE.  Surprisingly,
  this also matches existing behaviour.  Although the kernel fails madvise
  on unaligned addresses, it will round unaligned sizes *up* to the host
  page size.  Yes, this means that if BALLOON_PAGE_SIZE < guest page size
  we can incorrectly discard more memory than the guest asked us to.  I'm
  planning to address that soon.

Errors other than the ones discussed above, will now be reported by
ram_block_discard_range(), rather than silently ignored, which means we
have a much better chance of seeing when something is going wrong.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20190214043916.22128-5-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit dbe1a27745)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:33:57 -05:00
David Gibson 89b0e359bc virtio-balloon: Rework ballon_page() interface
This replaces the balloon_page() internal interface with
ballon_inflate_page(), with a slightly different interface.  The new
interface will make future alterations simpler.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20190214043916.22128-4-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit e9550234d7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:33:48 -05:00
David Gibson b260cdec21 virtio-balloon: Corrections to address verification
The virtio-balloon device's verification of the address given to it by the
guest has a number of faults:
    * The addresses here are guest physical addresses, which should be
      'hwaddr' rather than 'ram_addr_t' (the distinction is admittedly
      pretty subtle and confusing)
    * We don't check for section.mr being NULL, which is the main way that
      memory_region_find() reports basic failures.  We really need to check
      that before looking at any other section fields, because
      memory_region_find() doesn't initialize them on the failure path
    * We're passing a length of '1' to memory_region_find(), but really the
      guest is requesting that we put the entire page into the balloon,
      so it makes more sense to call it with BALLOON_PAGE_SIZE

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20190214043916.22128-3-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit b218a70e6a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:33:37 -05:00
David Gibson 7a31a0af31 virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate
When the balloon is inflated, we discard memory place in it using madvise()
with MADV_DONTNEED.  And when we deflate it we use MADV_WILLNEED, which
sounds like it makes sense but is actually unnecessary.

The misleadingly named MADV_DONTNEED just discards the memory in question,
it doesn't set any persistent state on it in-kernel; all that's necessary
to bring the memory back is to touch it.  MADV_WILLNEED in contrast
specifically says that the memory will be used soon and faults it in.

This patch simplify's the balloon operation by dropping the madvise()
on deflate.  This might have an impact on performance - it will move a
delay at deflate time until that memory is actually touched, which
might be more latency sensitive.  However:

  * Memory that's being given back to the guest by deflating the
    balloon *might* be used soon, but it equally could just sit around
    in the guest's pools until needed (or even be faulted out again if
    the host is under memory pressure).

  * Usually, the timescale over which you'll be adjusting the balloon
    is long enough that a few extra faults after deflation aren't
    going to make a difference.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20190214043916.22128-2-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit f6deb6d95a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:33:30 -05:00
Peter Maydell f0a334345b hw/virtio/virtio-balloon: zero-initialize the virtio_balloon_config struct
In virtio_balloon_get_config() we initialize a struct virtio_balloon_config
which we then copy to guest memory. However, the local variable is not
zero initialized. This works OK at the moment because we initialize
all the fields in it; however an upcoming kernel header change will
add some new fields. If we don't zero out the whole struct then we
will start leaking a small amount of the contents of QEMU's stack
to the guest as soon as we update linux-headers/ to a set of headers
that includes the new fields.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190118183603.24757-1-peter.maydell@linaro.org
(cherry picked from commit 5385a5988c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:31:44 -05:00
Evgeny Yakovlev fc6c2bce38 i386/acpi: show PCI Express bus on pxb-pcie expanders
Show PCIe host bridge PNP id with PCI host bridge as a compatible id
when expanding a pcie bus.

Cc: qemu-stable@nongnu.org
Signed-off-by: Evgeny Yakovlev <wrfsh@yandex-team.ru>
Message-Id: <1563526469-15588-1-git-send-email-wrfsh@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit ee4b0c8686)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:12:05 -05:00
Evgeny Yakovlev 11665ca918 i386/acpi: fix gint overflow in crs_range_compare
When very large regions (32GB sized in our case, PCI pass-through of GPUs)
are compared substraction result does not fit into gint.

As a result crs_replace_with_free_ranges does not get sorted ranges and
incorrectly computes PCI64 free space regions. Which then makes linux
guest complain about device and PCI64 hole intersection and device
becomes unusable.

Fix that by returning exactly fitting ranges.

Also fix indentation of an entire crs_replace_with_free_ranges to make
checkpatch happy.

Cc: qemu-stable@nongnu.org
Signed-off-by: Evgeny Yakovlev <wrfsh@yandex-team.ru>
Message-Id: <1563466463-26012-1-git-send-email-wrfsh@yandex-team.ru>
Signed-off-by: Evgeny Yakovlev <wrfsh@yandex-team.ru>
(cherry picked from commit 21e2acd583)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:11:24 -05:00
Jan Kiszka df42bc4897 ioapic: kvm: Skip route updates for masked pins
Masked entries will not generate interrupt messages, thus do no need to
be routed by KVM. This is a cosmetic cleanup, just avoiding warnings of
the kind

qemu-system-x86_64: vtd_irte_get: detected non-present IRTE (index=0, high=0xff00, low=0x100)

if the masked entry happens to reference a non-present IRTE.

Cc: qemu-stable@nongnu.org
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Message-Id: <a84b7e03-f9a8-b577-be27-4d93d1caa1c9@siemens.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit be1927c97e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 12:10:58 -05:00
Stefan Berger c00635946f tpm_emulator: Translate TPM error codes to strings
Implement a function to translate TPM error codes to strings so that
at least the most common error codes can be translated to human
readable strings.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit 7e095e84ba)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 11:40:43 -05:00
Stefan Berger 51ce84e119 tpm: Exit in reset when backend indicates failure
Exit() in the frontend reset function when the backend indicates
intialization failure.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit bcfd16fe26)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-30 11:39:27 -05:00
Li Hangjing 0318166a9f vhost: fix vhost_log size overflow during migration
When a guest which doesn't support multiqueue is migrated with a multi queues
vhost-user-blk deivce, a crash will occur like:

0 qemu_memfd_alloc (name=<value optimized out>, size=562949953421312, seals=<value optimized out>, fd=0x7f87171fe8b4, errp=0x7f87171fe8a8) at util/memfd.c:153
1 0x00007f883559d7cf in vhost_log_alloc (size=70368744177664, share=true) at hw/virtio/vhost.c:186
2 0x00007f88355a0758 in vhost_log_get (listener=0x7f8838bd7940, enable=1) at qemu-2-12/hw/virtio/vhost.c:211
3 vhost_dev_log_resize (listener=0x7f8838bd7940, enable=1) at hw/virtio/vhost.c:263
4 vhost_migration_log (listener=0x7f8838bd7940, enable=1) at hw/virtio/vhost.c:787
5 0x00007f88355463d6 in memory_global_dirty_log_start () at memory.c:2503
6 0x00007f8835550577 in ram_init_bitmaps (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2173
7 ram_init_all (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2192
8 ram_save_setup (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2219
9 0x00007f88357a419d in qemu_savevm_state_setup (f=0x7f88384ce600) at migration/savevm.c:1002
10 0x00007f883579fc3e in migration_thread (opaque=0x7f8837530400) at migration/migration.c:2382
11 0x00007f8832447893 in start_thread () from /lib64/libpthread.so.0
12 0x00007f8832178bfd in clone () from /lib64/libc.so.6

This is because vhost_get_log_size() returns a overflowed vhost-log size.
In this function, it uses the uninitialized variable vqs->used_phys and
vqs->used_size to get the vhost-log size.

Signed-off-by: Li Hangjing <lihangjing@baidu.com>
Reviewed-by: Xie Yongji <xieyongji@baidu.com>
Reviewed-by: Chai Wen <chaiwen@baidu.com>
Message-Id: <20190603061524.24076-1-lihangjing@baidu.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 240e647a14)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-18 14:49:38 -05:00
Max Reitz 261d7f653a iotests: Test unaligned raw images with O_DIRECT
We already have 221 for accesses through the page cache, but it is
better to create a new file for O_DIRECT instead of integrating those
test cases into 221.  This way, we can make use of
_supported_cache_modes (and _default_cache_mode) so the test is
automatically skipped on filesystems that do not support O_DIRECT.

As part of the split, add _supported_cache_modes to 221.  With that, it
no longer fails when run with -c none or -c directsync.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2fab30c80b)
*remove context dependencies on iotests not in 3.1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 15:44:17 -05:00
Max Reitz 044b0bcedf block/file-posix: Unaligned O_DIRECT block-status
Currently, qemu crashes whenever someone queries the block status of an
unaligned image tail of an O_DIRECT image:
$ echo > foo
$ qemu-img map --image-opts driver=file,filename=foo,cache.direct=on
Offset          Length          Mapped to       File
qemu-img: block/io.c:2093: bdrv_co_block_status: Assertion `*pnum &&
QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset'
failed.

This is because bdrv_co_block_status() checks that the result returned
by the driver's implementation is aligned to the request_alignment, but
file-posix can fail to do so, which is actually mentioned in a comment
there: "[...] possibly including a partial sector at EOF".

Fix this by rounding up those partial sectors.

There are two possible alternative fixes:
(1) We could refuse to open unaligned image files with O_DIRECT
    altogether.  That sounds reasonable until you realize that qcow2
    does necessarily not fill up its metadata clusters, and that nobody
    runs qemu-img create with O_DIRECT.  Therefore, unpreallocated qcow2
    files usually have an unaligned image tail.

(2) bdrv_co_block_status() could ignore unaligned tails.  It actually
    throws away everything past the EOF already, so that sounds
    reasonable.
    Unfortunately, the block layer knows file lengths only with a
    granularity of BDRV_SECTOR_SIZE, so bdrv_co_block_status() usually
    would have to guess whether its file length information is inexact
    or whether the driver is broken.

Fixing what raw_co_block_status() returns is the safest thing to do.

There seems to be no other block driver that sets request_alignment and
does not make sure that it always returns aligned values.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9c3db310ff)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 15:44:17 -05:00
Max Reitz 1742e3c74e iotests: Filter second BLOCK_JOB_ERROR from 229
Without this filter, this test sometimes fails.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit fff2388d5d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 15:44:17 -05:00
Peter Lieven f173a43a6d megasas: fix mapped frame size
the current value of 1024 bytes (16 * MFI_FRAME_SIZE) we map is not enough to hold
the maximum number of scatter gather elements we advertise. We actually need a
maximum of 2048 bytes. This is 128 max sg elements * 16 bytes (sizeof (union mfi_sgl)).

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <20190404121015.28634-1-pl@kamp.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2e56fbc87f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 14:10:31 -05:00
Christian Borntraeger 2157938f7b s390x/cpumodel: ignore csske for expansion
csske will be removed in a future machine. Ignore it for expanding the
cpu model. Otherwise qemu falls back to z9.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190429090250.7648-3-borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit eaf6f642ab)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 13:41:42 -05:00
Dan Streetman f56e70ee4f do not call vhost_net_cleanup() on running net from char user event
Buglink: https://launchpad.net/bugs/1823458

Currently, a user CHR_EVENT_CLOSED event will cause net_vhost_user_event()
to call vhost_user_cleanup(), which calls vhost_net_cleanup() for all
its queues.  However, vhost_net_cleanup() must never be called like
this for fully-initialized nets; when other code later calls
vhost_net_stop() - such as from virtio_net_vhost_status() - it will try
to access the already-cleaned-up fields and fail with assertion errors
or segfaults.

The vhost_net_cleanup() will eventually be called from
qemu_cleanup_net_client().

Signed-off-by: Dan Streetman <ddstreet@canonical.com>
Message-Id: <20190416184624.15397-3-dan.streetman@canonical.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 6ab79a20af)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 13:31:11 -05:00
Kevin Wolf 8a5aaad6c2 block: Fix AioContext switch for bs->drv == NULL
Even for block nodes with bs->drv == NULL, we can't just ignore a
bdrv_set_aio_context() call. Leaving the node in its old context can
mean that it's still in an iothread context in bdrv_close_all() during
shutdown, resulting in an attempted unlock of the AioContext lock which
we don't hold.

This is an example stack trace of a related crash:

 #0  0x00007ffff59da57f in raise () at /lib64/libc.so.6
 #1  0x00007ffff59c4895 in abort () at /lib64/libc.so.6
 #2  0x0000555555b97b1e in error_exit (err=<optimized out>, msg=msg@entry=0x555555d386d0 <__func__.19059> "qemu_mutex_unlock_impl") at util/qemu-thread-posix.c:36
 #3  0x0000555555b97f7f in qemu_mutex_unlock_impl (mutex=mutex@entry=0x5555568002f0, file=file@entry=0x555555d378df "util/async.c", line=line@entry=507) at util/qemu-thread-posix.c:97
 #4  0x0000555555b92f55 in aio_context_release (ctx=ctx@entry=0x555556800290) at util/async.c:507
 #5  0x0000555555b05cf8 in bdrv_prwv_co (child=child@entry=0x7fffc80012f0, offset=offset@entry=131072, qiov=qiov@entry=0x7fffffffd4f0, is_write=is_write@entry=true, flags=flags@entry=0)
         at block/io.c:833
 #6  0x0000555555b060a9 in bdrv_pwritev (qiov=0x7fffffffd4f0, offset=131072, child=0x7fffc80012f0) at block/io.c:990
 #7  0x0000555555b060a9 in bdrv_pwrite (child=0x7fffc80012f0, offset=131072, buf=<optimized out>, bytes=<optimized out>) at block/io.c:990
 #8  0x0000555555ae172b in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568cc740, i=i@entry=0) at block/qcow2-cache.c:51
 #9  0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568cc740) at block/qcow2-cache.c:248
 #10 0x0000555555ae15de in qcow2_cache_flush (bs=0x555556810680, c=<optimized out>) at block/qcow2-cache.c:259
 #11 0x0000555555ae16b1 in qcow2_cache_flush_dependency (c=0x5555568a1700, c=0x5555568a1700, bs=0x555556810680) at block/qcow2-cache.c:194
 #12 0x0000555555ae16b1 in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568a1700, i=i@entry=0) at block/qcow2-cache.c:194
 #13 0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568a1700) at block/qcow2-cache.c:248
 #14 0x0000555555ae15de in qcow2_cache_flush (bs=bs@entry=0x555556810680, c=<optimized out>) at block/qcow2-cache.c:259
 #15 0x0000555555ad242c in qcow2_inactivate (bs=bs@entry=0x555556810680) at block/qcow2.c:2124
 #16 0x0000555555ad2590 in qcow2_close (bs=0x555556810680) at block/qcow2.c:2153
 #17 0x0000555555ab0c62 in bdrv_close (bs=0x555556810680) at block.c:3358
 #18 0x0000555555ab0c62 in bdrv_delete (bs=0x555556810680) at block.c:3542
 #19 0x0000555555ab0c62 in bdrv_unref (bs=0x555556810680) at block.c:4598
 #20 0x0000555555af4d72 in blk_remove_bs (blk=blk@entry=0x5555568103d0) at block/block-backend.c:785
 #21 0x0000555555af4dbb in blk_remove_all_bs () at block/block-backend.c:483
 #22 0x0000555555aae02f in bdrv_close_all () at block.c:3412
 #23 0x00005555557f9796 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4776

The reproducer I used is a qcow2 image on gluster volume, where the
virtual disk size (4 GB) is larger than the gluster volume size (64M),
so we can easily trigger an ENOSPC. This backend is assigned to a
virtio-blk device using an iothread, and then from the guest a
'dd if=/dev/zero of=/dev/vda bs=1G count=1' causes the VM to stop
because of an I/O error. qemu_gluster_co_flush_to_disk() sets
bs->drv = NULL on error, so when virtio-blk stops the dataplane, the
block nodes stay in the iothread AioContext. A 'quit' monitor command
issued from this paused state crashes the process.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1631227
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
(cherry picked from commit 1bffe1ae7a)
*drop context dependency on e64f25f30b
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 12:22:01 -05:00
Eric Blake 3c9e488dbe cutils: Fix size_to_str() on 32-bit platforms
When extracting a human-readable size formatter, we changed 'uint64_t
div' pre-patch to 'unsigned long div' post-patch. Which breaks on
32-bit platforms, resulting in 'inf' instead of intended values larger
than 999GB.

Fixes: 22951aaa
CC: qemu-stable@nongnu.org
Reported-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 754da86714)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 12:22:01 -05:00
Kevin Wolf c627cc38be qcow2: Avoid COW during metadata preallocation
Limiting the allocation to INT_MAX bytes isn't particularly clever
because it means that the final cluster will be a partial cluster which
will be completed through a COW operation. This results in unnecessary
data read and write requests which lead to an unwanted non-sparse
filesystem block for metadata preallocation.

Align the maximum allocation size down to the cluster size to avoid this
situation.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit f29fbf7c6b)
*modified to avoid functional dependency on 93e32b3e
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-07-09 12:21:26 -05:00
Daniel P. Berrangé b443db97c1 qemu-img: fix error reporting for -object
Error reporting for user_creatable_add_opts_foreach was changed so that
it no longer called 'error_report_err' in:

  commit 7e1e0c1112
  Author: Markus Armbruster <armbru@redhat.com>
  Date:   Wed Oct 17 10:26:43 2018 +0200

    qom: Clean up error reporting in user_creatable_add_opts_foreach()

Some callers were updated to pass in "&error_fatal" but all the ones in
qemu-img were left passing NULL. As a result all errors went to
/dev/null instead of being reported to the user.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 334c43e2c3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-04-05 15:29:48 -05:00
Gerd Hoffmann 6b29db871d usb-mtp: use O_NOFOLLOW and O_CLOEXEC.
Open files and directories with O_NOFOLLOW to avoid symlinks attacks.
While being at it also add O_CLOEXEC.

usb-mtp only handles regular files and directories and ignores
everything else, so users should not see a difference.

Because qemu ignores symlinks, carrying out a successful symlink attack
requires swapping an existing file or directory below rootdir for a
symlink and winning the race against the inotify notification to qemu.

Fixes: CVE-2018-16872
Cc: Prasad J Pandit <ppandit@redhat.com>
Cc: Bandan Das <bsd@redhat.com>
Reported-by: Michael Hanselmann <public@hansmi.ch>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Michael Hanselmann <public@hansmi.ch>
Message-id: 20181213122511.13853-1-kraxel@redhat.com
(cherry picked from commit bab9df35ce)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 13:00:29 -05:00
Daniel Henrique Barboza 6c77b5ab35 qga: update docs with systemd suspend support info
Commit 067927d62e ("qga: systemd hibernate/suspend/hybrid-sleep
support") failed to update qapi-schema.json after adding systemd
hibernate/suspend/hybrid-sleep capabilities to guest-suspend-* QGA
commands.

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
(cherry picked from commit bb6c8d407e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:29:37 -05:00
Mark Cave-Ayland 11cd30e71a mac_newworld: use node name instead of alias name for hd device in FWPathProvider
When using -drive to configure the hd drive for the New World machine, the node
name "disk" should be used instead of the "hd" alias.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20190307212058.4890-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 31bc6fa7fa)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:28:17 -05:00
Mark Cave-Ayland 4a25ba2e2b mac_oldworld: use node name instead of alias name for hd device in FWPathProvider
When using -drive to configure the hd drive for the Old World machine, the node
name "disk" should be used instead of the "hd" alias.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20190307212058.4890-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 484d366e02)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:28:12 -05:00
Thomas Petazzoni 847fe10828 configure: improve usbfs check
The current check to test if usbfs support should be compiled or not
solely relies on the presence of <linux/usbdevice_fs.h>, without
actually checking that all definition used by Qemu are provided by
this header file.

With sufficiently old kernel headers, <linux/usbdevice_fs.h> may be
present, but some of the definitions needed by Qemu may not be
available.

This commit improves the check by building a small program that
actually tests whether the necessary definitions are available.

In addition, it fixes a bug where have_usbfs was set to "yes"
regardless of the result of the test.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20190213211827.20300-1-thomas.petazzoni@bootlin.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit 96566d09aa)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:27:42 -05:00
Michael Roth f3a70a4ae1 qga-win: include glib when building VSS DLL
Commit 3ebee3b191 defined assert() as g_assert(), but when we build
the VSS DLL component of QGA (to handle fsfreeze) we do not include
glib, which results in breakage when building with VSS support enabled.

Fix this by including glib (along with the -lintl and -lws2_32
dependencies it brings).

Since the VSS DLL is built statically, this introduces an additional
dependency on static glib and supporting libs for the mingw environment
(possibly why we didn't include glib originally), but VSS support
already has very specific prerequisites so it shouldn't affect too many
build environments.

Since the VSS DLL code does use qemu/osdep.h, this should also help
avoid future breakages and possibly allow for some clean ups in current
VSS code.

Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Cc: Daniel P. Berrangé <berrange@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
(cherry picked from commit 82a58d270c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:26:43 -05:00
Christophe Fergeau d7cae05bf5 json: Fix % handling when not interpolating
Commit 8bca4613 added support for %% in json strings when interpolating,
but in doing so broke handling of % when not interpolating.

When parse_string() is fed a string token containing '%', it skips the
'%' regardless of ctxt->ap, i.e. even it's not interpolating.  If the
'%' is the string's last character, it fails an assertion.  Else, it
"merely" swallows the '%'.

Fix parse_string() to handle '%' specially only when interpolating.

To gauge the bug's impact, let's review non-interpolating users of this
parser, i.e. code passing NULL context to json_message_parser_init():

* tests/check-qjson.c, tests/test-qobject-input-visitor.c,
  tests/test-visitor-serialization.c

  Plenty of tests, but we still failed to cover the buggy case.

* monitor.c: QMP input

* qga/main.c: QGA input

* qobject_from_json():

  - qobject-input-visitor.c: JSON command line option arguments of
    -display and -blockdev

    Reproducer: -blockdev '{"%"}'

  - block.c: JSON pseudo-filenames starting with "json:"

    Reproducer: https://bugzilla.redhat.com/show_bug.cgi?id=1668244#c3

  - block/rbd.c: JSON key pairs

    Pseudo-filenames starting with "rbd:".

Command line, QMP and QGA input are trusted.

Filenames are trusted when they come from command line, QMP or HMP.
They are untrusted when they come from from image file headers.
Example: QCOW2 backing file name.  Note that this is *not* the security
boundary between host and guest.  It's the boundary between host and an
image file from an untrusted source.

Neither failing an assertion nor skipping a character in a filename of
your choice looks exploitable.  Note that we don't support compiling
with NDEBUG.

Fixes: 8bca4613e6
Cc: qemu-stable@nongnu.org
Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Message-Id: <20190102140535.11512-1-cfergeau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
[Commit message extended to discuss impact]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit bbc0586ced)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:21:25 -05:00
Paolo Bonzini d03c389511 i386: remove the 'INTEL_PT' CPUID bit from named CPU models
Processor tracing is not yet implemented for KVM and it will be an
opt in feature requiring a special module parameter.
Disable it, because it is wrong to enable it by default and
it is impossible that no one has ever used it.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 4c257911dc)
*drop context dependency on ecb85fe48
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:20:19 -05:00
Robert Hoo 02d735c274 i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model
PCONFIG is not available to guests; it must be specifically enabled
using the PCONFIG_ENABLE execution control.  Disable it, because
no one can ever use it.

Signed-off-by: Robert Hoo <robert.hu@linux.intel.com>
Message-Id: <1545227081-213696-2-git-send-email-robert.hu@linux.intel.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 76e5a4d583)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:16:56 -05:00
Cornelia Huck 821314aec3 vfio-ap: flag as compatible with balloon
vfio-ap devices do not pin any pages in the host. Therefore, they
are compatible with memory ballooning.

Flag them as compatible, so both vfio-ap and a balloon can be
used simultaneously.

Cc: qemu-stable@nongnu.org
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Tested-by: Tony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 1883e8fc80)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-28 11:16:28 -05:00
Liam Merwick 7c693f0c3f tpm_tis: fix loop that cancels any seizure by a lower locality
In tpm_tis_mmio_write() if the requesting locality is seizing
access, any seizure by a lower locality is cancelled.  However the
loop doing the seizure had an off-by-one error and the locality
immediately preceding the requesting locality was not being cleared.
This is fixed by adjusting the test in the for loop to check the
localities up to the requesting locality.

Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
(cherry picked from commit 37b55d67c0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:12:14 -05:00
William Bowling 83cd9ed3d7 slirp: check sscanf result when emulating ident
When emulating ident in tcp_emu, if the strchr checks passed but the
sscanf check failed, two uninitialized variables would be copied and
sent in the reply, so move this code inside the if(sscanf()) clause.

Signed-off-by: William Bowling <will@wbowling.info>
Cc: qemu-stable@nongnu.org
Cc: secalert@redhat.com
Message-Id: <1551476756-25749-1-git-send-email-will@wbowling.info>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
(cherry picked from commit d3222975c7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:11:30 -05:00
Marcel Apfelbaum c6f25642e0 hw/rdma: another clang compilation fix
Configuring QEMU with:
   configure --target-list="x86_64-softmmu" --cc=clang --enable-pvrdma
Results in:
   qemu/hw/rdma/rdma_rm_defs.h:108:3: error: redefinition of typedef 'RdmaDeviceResources' is a C11 feature [-Werror,-Wtypedef-redefinition]
   } RdmaDeviceResources;
     ^
   qemu/hw/rdma/rdma_backend_defs.h:24:36: note: previous definition is here
   typedef struct RdmaDeviceResources RdmaDeviceResources;

Fix by removing one of the 'typedef' definitions.

Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Message-Id: <20190214154053.15050-1-marcel.apfelbaum@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Kamal Heib <kamalheib1@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
(cherry picked from commit 59f911938f)
*drop context dep. on c2dd117b38
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:09:09 -05:00
Kevin Wolf 27df37c1ea block: Fix invalidate_cache error path for parent activation
bdrv_co_invalidate_cache() clears the BDRV_O_INACTIVE flag before
actually activating a node so that the correct permissions etc. are
taken. In case of errors, the flag must be restored so that the next
call to bdrv_co_invalidate_cache() retries activation.

Restoring the flag was missing in the error path for a failed
parent->role->activate() call. The consequence is that this attempt to
activate all images correctly fails because we still set errp, however
on the next attempt BDRV_O_INACTIVE is already clear, so we return
success without actually retrying the failed action.

An example where this is observable in practice is migration to a QEMU
instance that has a raw format block node attached to a guest device
with share-rw=off (the default) while another process holds
BLK_PERM_WRITE for the same image. In this case, all activation steps
before parent->role->activate() succeed because raw can tolerate other
writers to the image. Only the parent callback (in particular
blk_root_activate()) tries to implement the share-rw=on property and
requests exclusive write permissions. This fails when the migration
completes and correctly displays an error. However, a manual 'cont' will
incorrectly resume the VM without calling blk_root_activate() again.

This case is described in more detail in the following bug report:
https://bugzilla.redhat.com/show_bug.cgi?id=1531888

Fix this by correctly restoring the BDRV_O_INACTIVE flag in the error
path.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 78fc3b3a26)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:07:13 -05:00
Stefan Berger fe87edd5ed tpm: Make sure the locality received from backend is valid
Make sure that the locality passed from the backend to
tpm_tis_request_completed() is valid.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit a639f96111)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:07:05 -05:00
Stefan Berger 27b0c099fd tpm: Make sure new locality passed to tpm_tis_prep_abort() is valid
Make sure that the new locality passed to tpm_tis_prep_abort()
is valid.

Add a comment to aborting_locty that it may be any locality, including
TPM_TIS_NO_LOCALITY.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit e92b63ea61)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:06:57 -05:00
Peter Maydell 00d0932e0b exec.c: Don't reallocate IOMMUNotifiers that are in use
The tcg_register_iommu_notifier() code has a GArray of
TCGIOMMUNotifier structs which it has registered by passing
memory_region_register_iommu_notifier() a pointer to the embedded
IOMMUNotifier field. Unfortunately, if we need to enlarge the
array via g_array_set_size() this can cause a realloc(), which
invalidates the pointer that memory_region_register_iommu_notifier()
put into the MemoryRegion's iommu_notify list. This can result
in segfaults.

Switch the GArray to holding pointers to the TCGIOMMUNotifier
structs, so that we can individually allocate and free them.

Cc: qemu-stable@nongnu.org
Fixes: 1f871c5e6b ("exec.c: Handle IOMMUs in address_space_translate_for_iotlb()")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190128174241.5860-1-peter.maydell@linaro.org
(cherry picked from commit 5601be3b01)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:06:46 -05:00
Janosch Frank 2e5502300e s390x: Return specification exception for unimplemented diag 308 subcodes
The architecture specifies specification exceptions for all
unavailable subcodes.

The presence of subcodes is indicated by checking some query subcode.
For example 6 will indicate that 3-6 are available. So future systems
might call new subcodes to check for new features. This should not
trigger a hw error, instead we return the architectured specification
exception.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Cc: qemu-stable@nongnu.org
Message-Id: <20190111113657.66195-3-frankja@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 37dbd1f4d4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:06:38 -05:00
Peter Maydell 8ec7368c8f linux-user: make pwrite64/pread64(fd, NULL, 0, offset) return 0
Linux returns success if pwrite64() or pread64() are called with a
zero length NULL buffer, but QEMU was returning -TARGET_EFAULT.

This is the same bug that we fixed in commit 58cfa6c2e6
for the write syscall, and long before that in 38d840e679
for the read syscall.

Fixes: https://bugs.launchpad.net/qemu/+bug/1810433

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190108184900.9654-1-peter.maydell@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
(cherry picked from commit 2bd3f8998e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:05:38 -05:00
Thomas Huth 85bfce130a hw/s390x: Fix bad mask in time2tod()
Since "s390x/tcg: avoid overflows in time2tod/tod2time", the
time2tod() function tries to deal with the 9 uppermost bits in the
time value, but uses the wrong mask for this: 0xff80000000000000 should
be used instead of 0xff10000000000000 here.

Fixes: 14055ce53c
Cc: qemu-stable@nongnu.org
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1544792887-14575-1-git-send-email-thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
[CH: tweaked commit message]
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit aba7a5a2de)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:05:20 -05:00
Corey Minyard 98cf1bb872 pc:piix4: Update smbus I/O space after a migration
Otherwise it won't be set up correctly and won't work after
miigration.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Igor Mammedov <imammedo@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 2b4e573c7c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:05:08 -05:00
Zheng Xiang 5363028d1f pcie: set link state inactive/active after hot unplug/plug
When VM boots from the latest version of linux kernel, after
hot-unpluging virtio-blk disks which are hotplugged into
pcie-root-port, the VM's dmesg log shows:

[  151.046242] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0001 from Slot Status
[  151.046365] pciehp 0000:00:05.0:pcie004: Slot(0-3): Attention button pressed
[  151.046369] pciehp 0000:00:05.0:pcie004: Slot(0-3): Powering off due to button press
[  151.046420] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  151.046425] pciehp 0000:00:05.0:pcie004: pciehp_green_led_blink: SLOTCTRL a8 write cmd 200
[  151.046464] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  151.046468] pciehp 0000:00:05.0:pcie004: pciehp_set_attention_status: SLOTCTRL a8 write cmd c0
[  156.163421] pciehp 0000:00:05.0:pcie004: pciehp_get_power_status: SLOTCTRL a8 value read 2f1
[  156.163427] pciehp 0000:00:05.0:pcie004: pciehp_unconfigure_device: domain🚌dev = 0000:06:00
[  156.198736] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  156.198772] pciehp 0000:00:05.0:pcie004: pciehp_power_off_slot: SLOTCTRL a8 write cmd 400
[  157.224124] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0018 from Slot Status
[  157.224194] pciehp 0000:00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 write cmd 300
[  157.224220] pciehp 0000:00:05.0:pcie004: pciehp_check_link_active: lnk_status = 2011
[  157.224223] pciehp 0000:00:05.0:pcie004: Slot(0-3): Link Up
[  157.224233] pciehp 0000:00:05.0:pcie004: pciehp_get_power_status: SLOTCTRL a8 value read 7f1
[  157.224281] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  157.224285] pciehp 0000:00:05.0:pcie004: pciehp_power_on_slot: SLOTCTRL a8 write cmd 0
[  157.224300] pciehp 0000:00:05.0:pcie004: __pciehp_link_set: lnk_ctrl = 0
[  157.224336] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  157.224339] pciehp 0000:00:05.0:pcie004: pciehp_green_led_blink: SLOTCTRL a8 write cmd 200
[  159.739294] pci 0000:06:00.0 id reading try 50 times with interval 20 ms to get ffffffff
[  159.739315] pciehp 0000:00:05.0:pcie004: pciehp_check_link_status: lnk_status = 2011
[  159.739318] pciehp 0000:00:05.0:pcie004: Failed to check link status
[  159.739371] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  159.739394] pciehp 0000:00:05.0:pcie004: pciehp_power_off_slot: SLOTCTRL a8 write cmd 400
[  160.771426] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  160.771452] pciehp 0000:00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 write cmd 300
[  160.771495] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  160.771499] pciehp 0000:00:05.0:pcie004: pciehp_set_attention_status: SLOTCTRL a8 write cmd 40
[  160.771535] pciehp 0000:00:05.0:pcie004: pending interrupts 0x0010 from Slot Status
[  160.771539] pciehp 0000:00:05.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 write cmd 300

After analyzing the log information, it seems that qemu doesn't
change the Link Status from active to inactive after hot-unplug.
This results in the abnormal log after the linux kernel commit
d331710ea78fea merged.

Furthermore, If I hotplug the same virtio-blk disk after hot-unplug,
the virtio-blk would turn on and then back off.

So this patch set the Link Status inactive after hot-unplug and
active after hot-plug.

Signed-off-by: Zheng Xiang <zhengxiang9@huawei.com>
Signed-off-by: Zheng Xiang <xiang.zheng@linaro.org>
Cc: Wang Haibin <wanghaibin.wang@huawei.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2f2b18f60b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:04:46 -05:00
Paul A. Clarke 0d6b9ce17c Changes requirement for "vsubsbs" instruction
Changes requirement for "vsubsbs" instruction, which has been supported
since ISA 2.03. (Please see section 5.9.1.2 of ISA 2.03)

Reported-by: Paul A. Clarke <pc@us.ibm.com>
Signed-off-by: Paul A. Clarke <pc@us.ibm.com>
Signed-off-by: Leonardo Bras <leonardo@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit fcfbc18d00)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:04:28 -05:00
Christian Borntraeger def04278d1 iotests: make 235 work on s390 (and others)
"-machine pc" will not work all architectures. Lets fall back to the
default machine by not specifying it.

In addition we also need to specify -no-shutdown on s390 as qemu will
exit otherwise.

Cc: qemu-stable@nongnu.org
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2c26e648e4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:04:07 -05:00
BALATON Zoltan 08c410e390 i2c: Move typedef of bitbang_i2c_interface to i2c.h
Clang 3.4 considers duplicate typedef in ppc4xx_i2c.h and
bitbang_i2c.h an error even if they are identical. Move it to a common
place to allow building with this clang version.

Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 2b4c1125ac)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-03-27 20:03:43 -05:00
78 changed files with 1299 additions and 324 deletions

View File

@ -1 +1 @@
3.1.0
3.1.1.1

19
block.c
View File

@ -3736,6 +3736,7 @@ static void bdrv_check_co_entry(void *opaque)
{
CheckCo *cco = opaque;
cco->ret = bdrv_co_check(cco->bs, cco->res, cco->fix);
aio_wait_kick();
}
int bdrv_check(BlockDriverState *bs,
@ -3754,7 +3755,7 @@ int bdrv_check(BlockDriverState *bs,
bdrv_check_co_entry(&cco);
} else {
co = qemu_coroutine_create(bdrv_check_co_entry, &cco);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, cco.ret == -EINPROGRESS);
}
@ -4553,6 +4554,7 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
if (parent->role->activate) {
parent->role->activate(parent, &local_err);
if (local_err) {
bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
return;
}
@ -4571,6 +4573,7 @@ static void coroutine_fn bdrv_invalidate_cache_co_entry(void *opaque)
InvalidateCacheCo *ico = opaque;
bdrv_co_invalidate_cache(ico->bs, ico->errp);
ico->done = true;
aio_wait_kick();
}
void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
@ -4587,7 +4590,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
bdrv_invalidate_cache_co_entry(&ico);
} else {
co = qemu_coroutine_create(bdrv_invalidate_cache_co_entry, &ico);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, !ico.done);
}
}
@ -5055,10 +5058,6 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
BdrvAioNotifier *baf, *baf_tmp;
BdrvChild *child;
if (!bs->drv) {
return;
}
assert(!bs->walking_aio_notifiers);
bs->walking_aio_notifiers = true;
QLIST_FOREACH_SAFE(baf, &bs->aio_notifiers, list, baf_tmp) {
@ -5073,7 +5072,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
*/
bs->walking_aio_notifiers = false;
if (bs->drv->bdrv_detach_aio_context) {
if (bs->drv && bs->drv->bdrv_detach_aio_context) {
bs->drv->bdrv_detach_aio_context(bs);
}
QLIST_FOREACH(child, &bs->children, next) {
@ -5089,16 +5088,12 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
BdrvAioNotifier *ban, *ban_tmp;
BdrvChild *child;
if (!bs->drv) {
return;
}
bs->aio_context = new_context;
QLIST_FOREACH(child, &bs->children, next) {
bdrv_attach_aio_context(child->bs, new_context);
}
if (bs->drv->bdrv_attach_aio_context) {
if (bs->drv && bs->drv->bdrv_attach_aio_context) {
bs->drv->bdrv_attach_aio_context(bs, new_context);
}

View File

@ -1220,6 +1220,7 @@ static void blk_read_entry(void *opaque)
rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, qiov->size,
qiov, rwco->flags);
aio_wait_kick();
}
static void blk_write_entry(void *opaque)
@ -1229,6 +1230,7 @@ static void blk_write_entry(void *opaque)
rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, qiov->size,
qiov, rwco->flags);
aio_wait_kick();
}
static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
@ -1540,6 +1542,7 @@ static void blk_ioctl_entry(void *opaque)
rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
qiov->iov[0].iov_base);
aio_wait_kick();
}
int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
@ -1586,6 +1589,7 @@ static void blk_flush_entry(void *opaque)
{
BlkRwCo *rwco = opaque;
rwco->ret = blk_co_flush(rwco->blk);
aio_wait_kick();
}
int blk_flush(BlockBackend *blk)
@ -2018,6 +2022,7 @@ static void blk_pdiscard_entry(void *opaque)
QEMUIOVector *qiov = rwco->iobuf;
rwco->ret = blk_co_pdiscard(rwco->blk, rwco->offset, qiov->size);
aio_wait_kick();
}
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes)

View File

@ -2461,6 +2461,8 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
off_t data = 0, hole = 0;
int ret;
assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment));
ret = fd_open(bs);
if (ret < 0) {
return ret;
@ -2486,6 +2488,20 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
/* On a data extent, compute bytes to the end of the extent,
* possibly including a partial sector at EOF. */
*pnum = MIN(bytes, hole - offset);
/*
* We are not allowed to return partial sectors, though, so
* round up if necessary.
*/
if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
int64_t file_length = raw_getlength(bs);
if (file_length > 0) {
/* Ignore errors, this is just a safeguard */
assert(hole == file_length);
}
*pnum = ROUND_UP(*pnum, bs->bl.request_alignment);
}
ret = BDRV_BLOCK_DATA;
} else {
/* On a hole, compute bytes to the beginning of the next extent. */

View File

@ -20,6 +20,10 @@
#include "qemu/option.h"
#include "qemu/cutils.h"
#ifdef CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT
# define glfs_ftruncate(fd, offset) glfs_ftruncate(fd, offset, NULL, NULL)
#endif
#define GLUSTER_OPT_FILENAME "filename"
#define GLUSTER_OPT_VOLUME "volume"
#define GLUSTER_OPT_PATH "path"
@ -725,7 +729,11 @@ static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
/*
* AIO callback routine called from GlusterFS thread.
*/
static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret,
#ifdef CONFIG_GLUSTERFS_IOCB_HAS_STAT
struct glfs_stat *pre, struct glfs_stat *post,
#endif
void *arg)
{
GlusterAIOCB *acb = (GlusterAIOCB *)arg;

View File

@ -806,6 +806,7 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
rwco->qiov->size, rwco->qiov,
rwco->flags);
}
aio_wait_kick();
}
/*
@ -2279,6 +2280,7 @@ static void coroutine_fn bdrv_block_status_above_co_entry(void *opaque)
data->offset, data->bytes,
data->pnum, data->map, data->file);
data->done = true;
aio_wait_kick();
}
/*
@ -2438,6 +2440,7 @@ static void coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
{
BdrvVmstateCo *co = opaque;
co->ret = bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
aio_wait_kick();
}
static inline int
@ -2559,6 +2562,7 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque)
FlushCo *rwco = opaque;
rwco->ret = bdrv_co_flush(rwco->bs);
aio_wait_kick();
}
int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
@ -2704,6 +2708,7 @@ static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
DiscardCo *rwco = opaque;
rwco->ret = bdrv_co_pdiscard(rwco->child, rwco->offset, rwco->bytes);
aio_wait_kick();
}
int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
@ -3217,6 +3222,7 @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
TruncateCo *tco = opaque;
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->prealloc,
tco->errp);
aio_wait_kick();
}
int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
@ -3236,7 +3242,7 @@ int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
bdrv_truncate_co_entry(&tco);
} else {
co = qemu_coroutine_create(bdrv_truncate_co_entry, &tco);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(child->bs, co);
BDRV_POLL_WHILE(child->bs, tco.ret == NOT_DONE);
}

View File

@ -116,6 +116,7 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
s->quit = true;
nbd_recv_coroutines_wake_all(s);
s->read_reply_co = NULL;
aio_wait_kick();
}
static int nbd_co_send_request(BlockDriverState *bs,

View File

@ -390,6 +390,7 @@ static void nvme_cmd_sync_cb(void *opaque, int ret)
{
int *pret = opaque;
*pret = ret;
aio_wait_kick();
}
static int nvme_cmd_sync(BlockDriverState *bs, NVMeQueuePair *q,

View File

@ -1665,6 +1665,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
/* From bdrv_co_create. */
qcow2_open_entry(&qoc);
} else {
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
qemu_coroutine_enter(qemu_coroutine_create(qcow2_open_entry, &qoc));
BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
}
@ -2590,6 +2591,7 @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
uint64_t new_length)
{
BDRVQcow2State *s = bs->opaque;
uint64_t bytes;
uint64_t host_offset = 0;
unsigned int cur_bytes;
@ -2600,7 +2602,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
bytes = new_length - offset;
while (bytes) {
cur_bytes = MIN(bytes, INT_MAX);
cur_bytes = MIN(bytes, QEMU_ALIGN_DOWN(INT_MAX, s->cluster_size));
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
&host_offset, &meta);
if (ret < 0) {

View File

@ -559,6 +559,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
if (qemu_in_coroutine()) {
bdrv_qed_open_entry(&qoc);
} else {
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc));
BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
}

61
configure vendored
View File

@ -453,6 +453,8 @@ glusterfs_xlator_opt="no"
glusterfs_discard="no"
glusterfs_fallocate="no"
glusterfs_zerofill="no"
glusterfs_ftruncate_has_stat="no"
glusterfs_iocb_has_stat="no"
gtk=""
gtk_gl="no"
tls_priority="NORMAL"
@ -3982,6 +3984,38 @@ if test "$glusterfs" != "no" ; then
glusterfs_fallocate="yes"
glusterfs_zerofill="yes"
fi
cat > $TMPC << EOF
#include <glusterfs/api/glfs.h>
int
main(void)
{
/* new glfs_ftruncate() passes two additional args */
return glfs_ftruncate(NULL, 0, NULL, NULL);
}
EOF
if compile_prog "$glusterfs_cflags" "$glusterfs_libs" ; then
glusterfs_ftruncate_has_stat="yes"
fi
cat > $TMPC << EOF
#include <glusterfs/api/glfs.h>
/* new glfs_io_cbk() passes two additional glfs_stat structs */
static void
glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
{}
int
main(void)
{
glfs_io_cbk iocb = &glusterfs_iocb;
iocb(NULL, 0 , NULL, NULL, NULL);
return 0;
}
EOF
if compile_prog "$glusterfs_cflags" "$glusterfs_libs" ; then
glusterfs_iocb_has_stat="yes"
fi
else
if test "$glusterfs" = "yes" ; then
feature_not_found "GlusterFS backend support" \
@ -4203,10 +4237,25 @@ fi
# check for usbfs
have_usbfs=no
if test "$linux_user" = "yes"; then
if check_include linux/usbdevice_fs.h; then
cat > $TMPC << EOF
#include <linux/usbdevice_fs.h>
#ifndef USBDEVFS_GET_CAPABILITIES
#error "USBDEVFS_GET_CAPABILITIES undefined"
#endif
#ifndef USBDEVFS_DISCONNECT_CLAIM
#error "USBDEVFS_DISCONNECT_CLAIM undefined"
#endif
int main(void)
{
return 0;
}
EOF
if compile_prog "" ""; then
have_usbfs=yes
fi
have_usbfs=yes
fi
# check for fallocate
@ -6735,6 +6784,14 @@ if test "$glusterfs_zerofill" = "yes" ; then
echo "CONFIG_GLUSTERFS_ZEROFILL=y" >> $config_host_mak
fi
if test "$glusterfs_ftruncate_has_stat" = "yes" ; then
echo "CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT=y" >> $config_host_mak
fi
if test "$glusterfs_iocb_has_stat" = "yes" ; then
echo "CONFIG_GLUSTERFS_IOCB_HAS_STAT=y" >> $config_host_mak
fi
if test "$libssh2" = "yes" ; then
echo "CONFIG_LIBSSH2=m" >> $config_host_mak
echo "LIBSSH2_CFLAGS=$libssh2_cflags" >> $config_host_mak

View File

@ -84,6 +84,10 @@ void *load_device_tree(const char *filename_path, int *sizep)
filename_path);
goto fail;
}
if (dt_size > INT_MAX / 2 - 10000) {
error_report("Device tree file '%s' is too large", filename_path);
goto fail;
}
/* Expand to 2x size to give enough room for manipulation. */
dt_size += 10000;
@ -91,7 +95,7 @@ void *load_device_tree(const char *filename_path, int *sizep)
/* First allocate space in qemu for device tree */
fdt = g_malloc0(dt_size);
dt_file_load_size = load_image(filename_path, fdt);
dt_file_load_size = load_image_size(filename_path, fdt, dt_size);
if (dt_file_load_size < 0) {
error_report("Unable to open device tree file '%s'",
filename_path);

10
exec.c
View File

@ -664,7 +664,7 @@ static void tcg_register_iommu_notifier(CPUState *cpu,
int i;
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
if (notifier->mr == mr && notifier->iommu_idx == iommu_idx) {
break;
}
@ -672,7 +672,8 @@ static void tcg_register_iommu_notifier(CPUState *cpu,
if (i == cpu->iommu_notifiers->len) {
/* Not found, add a new entry at the end of the array */
cpu->iommu_notifiers = g_array_set_size(cpu->iommu_notifiers, i + 1);
notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
notifier = g_new0(TCGIOMMUNotifier, 1);
g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i) = notifier;
notifier->mr = mr;
notifier->iommu_idx = iommu_idx;
@ -704,8 +705,9 @@ static void tcg_iommu_free_notifier_list(CPUState *cpu)
TCGIOMMUNotifier *notifier;
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
memory_region_unregister_iommu_notifier(notifier->mr, &notifier->n);
g_free(notifier);
}
g_array_free(cpu->iommu_notifiers, true);
}
@ -975,7 +977,7 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
}
cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier));
cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier *));
#endif
}

View File

@ -173,6 +173,7 @@ static int vmstate_acpi_post_load(void *opaque, int version_id)
PIIX4PMState *s = opaque;
pm_io_space_update(s);
smbus_io_space_update(s);
return 0;
}

View File

@ -512,10 +512,10 @@ static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt)
/* Open code a private version of pflash registration since we
* need to set non-default device width for VExpress platform.
*/
static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
DriveInfo *di)
static PFlashCFI01 *ve_pflash_cfi01_register(hwaddr base, const char *name,
DriveInfo *di)
{
DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
if (di) {
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di),
@ -536,7 +536,7 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
return PFLASH_CFI01(dev);
}
static void vexpress_common_init(MachineState *machine)
@ -548,7 +548,7 @@ static void vexpress_common_init(MachineState *machine)
qemu_irq pic[64];
uint32_t sys_id;
DriveInfo *dinfo;
pflash_t *pflash0;
PFlashCFI01 *pflash0;
I2CBus *i2c;
ram_addr_t vram_size, sram_size;
MemoryRegion *sysmem = get_system_memory();

View File

@ -34,6 +34,7 @@
#include "hw/arm/arm.h"
#include "hw/arm/primecell.h"
#include "hw/arm/virt.h"
#include "hw/block/flash.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "hw/vfio/vfio-amd-xgbe.h"
#include "hw/display/ramfb.h"
@ -876,7 +877,7 @@ static void create_one_flash(const char *name, hwaddr flashbase,
* parameters as the flash devices on the Versatile Express board.
*/
DriveInfo *dinfo = drive_get_next(IF_PFLASH);
DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
const uint64_t sectorlength = 256 * 1024;

View File

@ -49,12 +49,6 @@
#include "sysemu/sysemu.h"
#include "trace.h"
#define PFLASH_BUG(fmt, ...) \
do { \
fprintf(stderr, "PFLASH: Possible BUG - " fmt, ## __VA_ARGS__); \
exit(1); \
} while(0)
/* #define PFLASH_DEBUG */
#ifdef PFLASH_DEBUG
#define DPRINTF(fmt, ...) \
@ -65,12 +59,10 @@ do { \
#define DPRINTF(fmt, ...) do { } while (0)
#endif
#define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
#define PFLASH_BE 0
#define PFLASH_SECURE 1
struct pflash_t {
struct PFlashCFI01 {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
@ -109,17 +101,17 @@ static const VMStateDescription vmstate_pflash = {
.minimum_version_id = 1,
.post_load = pflash_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT8(wcycle, pflash_t),
VMSTATE_UINT8(cmd, pflash_t),
VMSTATE_UINT8(status, pflash_t),
VMSTATE_UINT64(counter, pflash_t),
VMSTATE_UINT8(wcycle, PFlashCFI01),
VMSTATE_UINT8(cmd, PFlashCFI01),
VMSTATE_UINT8(status, PFlashCFI01),
VMSTATE_UINT64(counter, PFlashCFI01),
VMSTATE_END_OF_LIST()
}
};
static void pflash_timer (void *opaque)
{
pflash_t *pfl = opaque;
PFlashCFI01 *pfl = opaque;
trace_pflash_timer_expired(pfl->cmd);
/* Reset flash */
@ -133,7 +125,7 @@ static void pflash_timer (void *opaque)
* If this code is called we know we have a device_width set for
* this flash.
*/
static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset)
static uint32_t pflash_cfi_query(PFlashCFI01 *pfl, hwaddr offset)
{
int i;
uint32_t resp = 0;
@ -193,7 +185,7 @@ static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset)
/* Perform a device id query based on the bank width of the flash. */
static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
static uint32_t pflash_devid_query(PFlashCFI01 *pfl, hwaddr offset)
{
int i;
uint32_t resp;
@ -241,7 +233,7 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
return resp;
}
static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset,
int width, int be)
{
uint8_t *p;
@ -284,8 +276,8 @@ static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
return ret;
}
static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
int width, int be)
static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
int width, int be)
{
hwaddr boff;
uint32_t ret;
@ -398,7 +390,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
}
/* update flash content on disk */
static void pflash_update(pflash_t *pfl, int offset,
static void pflash_update(PFlashCFI01 *pfl, int offset,
int size)
{
int offset_end;
@ -412,7 +404,7 @@ static void pflash_update(pflash_t *pfl, int offset,
}
}
static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
uint8_t *p = pfl->storage;
@ -448,7 +440,7 @@ static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
}
static void pflash_write(pflash_t *pfl, hwaddr offset,
static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
uint8_t *p;
@ -507,6 +499,10 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
break;
case 0xe8: /* Write to buffer */
DPRINTF("%s: Write to buffer\n", __func__);
/* FIXME should save @offset, @width for case 1+ */
qemu_log_mask(LOG_UNIMP,
"%s: Write to buffer emulation is flawed\n",
__func__);
pfl->status |= 0x80; /* Ready! */
break;
case 0xf0: /* Probe for AMD flash */
@ -550,6 +546,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
/* Mask writeblock size based on device width, or bank width if
* device width not specified.
*/
/* FIXME check @offset, @width */
if (pfl->device_width) {
value = extract32(value, 0, pfl->device_width * 8);
} else {
@ -587,7 +584,13 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
case 2:
switch (pfl->cmd) {
case 0xe8: /* Block write */
/* FIXME check @offset, @width */
if (!pfl->ro) {
/*
* FIXME writing straight to memory is *wrong*. We
* should write to a buffer, and flush it to memory
* only on confirm command (see below).
*/
pflash_data_write(pfl, offset, value, width, be);
} else {
pfl->status |= 0x10; /* Programming error */
@ -603,6 +606,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
pfl->wcycle++;
if (!pfl->ro) {
/* Flush the entire write buffer onto backing storage. */
/* FIXME premature! */
pflash_update(pfl, offset & mask, pfl->writeblock_size);
} else {
pfl->status |= 0x10; /* Programming error */
@ -619,11 +623,15 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
switch (pfl->cmd) {
case 0xe8: /* Block write */
if (cmd == 0xd0) {
/* FIXME this is where we should write out the buffer */
pfl->wcycle = 0;
pfl->status |= 0x80;
} else {
DPRINTF("%s: unknown command for \"write block\"\n", __func__);
PFLASH_BUG("Write block confirm");
qemu_log_mask(LOG_UNIMP,
"%s: Aborting write to buffer not implemented,"
" the data is already written to storage!\n"
"Flash device reset into READ mode.\n",
__func__);
goto reset_flash;
}
break;
@ -654,7 +662,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_t *value,
unsigned len, MemTxAttrs attrs)
{
pflash_t *pfl = opaque;
PFlashCFI01 *pfl = opaque;
bool be = !!(pfl->features & (1 << PFLASH_BE));
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
@ -668,7 +676,7 @@ static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_
static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, uint64_t value,
unsigned len, MemTxAttrs attrs)
{
pflash_t *pfl = opaque;
PFlashCFI01 *pfl = opaque;
bool be = !!(pfl->features & (1 << PFLASH_BE));
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
@ -687,7 +695,7 @@ static const MemoryRegionOps pflash_cfi01_ops = {
static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
{
pflash_t *pfl = CFI_PFLASH01(dev);
PFlashCFI01 *pfl = PFLASH_CFI01(dev);
uint64_t total_len;
int ret;
uint64_t blocks_per_device, sector_len_per_device, device_len;
@ -863,15 +871,33 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */
}
static void pflash_cfi01_system_reset(DeviceState *dev)
{
PFlashCFI01 *pfl = PFLASH_CFI01(dev);
/*
* The command 0x00 is not assigned by the CFI open standard,
* but QEMU historically uses it for the READ_ARRAY command (0xff).
*/
pfl->cmd = 0x00;
pfl->wcycle = 0;
memory_region_rom_device_set_romd(&pfl->mem, true);
/*
* The WSM ready timer occurs at most 150ns after system reset.
* This model deliberately ignores this delay.
*/
pfl->status = 0x80;
}
static Property pflash_cfi01_properties[] = {
DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
DEFINE_PROP_DRIVE("drive", PFlashCFI01, blk),
/* num-blocks is the number of blocks actually visible to the guest,
* ie the total size of the device divided by the sector length.
* If we're emulating flash devices wired in parallel the actual
* number of blocks per indvidual device will differ.
*/
DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0),
DEFINE_PROP_UINT32("num-blocks", PFlashCFI01, nb_blocs, 0),
DEFINE_PROP_UINT64("sector-length", PFlashCFI01, sector_len, 0),
/* width here is the overall width of this QEMU device in bytes.
* The QEMU device may be emulating a number of flash devices
* wired up in parallel; the width of each individual flash
@ -888,17 +914,17 @@ static Property pflash_cfi01_properties[] = {
* 16 bit devices making up a 32 bit wide QEMU device. This
* is deprecated for new uses of this device.
*/
DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0),
DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0),
DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0),
DEFINE_PROP_BIT("big-endian", struct pflash_t, features, PFLASH_BE, 0),
DEFINE_PROP_BIT("secure", struct pflash_t, features, PFLASH_SECURE, 0),
DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0),
DEFINE_PROP_STRING("name", struct pflash_t, name),
DEFINE_PROP_BOOL("old-multiple-chip-handling", struct pflash_t,
DEFINE_PROP_UINT8("width", PFlashCFI01, bank_width, 0),
DEFINE_PROP_UINT8("device-width", PFlashCFI01, device_width, 0),
DEFINE_PROP_UINT8("max-device-width", PFlashCFI01, max_device_width, 0),
DEFINE_PROP_BIT("big-endian", PFlashCFI01, features, PFLASH_BE, 0),
DEFINE_PROP_BIT("secure", PFlashCFI01, features, PFLASH_SECURE, 0),
DEFINE_PROP_UINT16("id0", PFlashCFI01, ident0, 0),
DEFINE_PROP_UINT16("id1", PFlashCFI01, ident1, 0),
DEFINE_PROP_UINT16("id2", PFlashCFI01, ident2, 0),
DEFINE_PROP_UINT16("id3", PFlashCFI01, ident3, 0),
DEFINE_PROP_STRING("name", PFlashCFI01, name),
DEFINE_PROP_BOOL("old-multiple-chip-handling", PFlashCFI01,
old_multiple_chip_handling, false),
DEFINE_PROP_END_OF_LIST(),
};
@ -907,6 +933,7 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->reset = pflash_cfi01_system_reset;
dc->realize = pflash_cfi01_realize;
dc->props = pflash_cfi01_properties;
dc->vmsd = &vmstate_pflash;
@ -915,9 +942,9 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
static const TypeInfo pflash_cfi01_info = {
.name = TYPE_CFI_PFLASH01,
.name = TYPE_PFLASH_CFI01,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct pflash_t),
.instance_size = sizeof(PFlashCFI01),
.class_init = pflash_cfi01_class_init,
};
@ -928,15 +955,17 @@ static void pflash_cfi01_register_types(void)
type_init(pflash_cfi01_register_types)
pflash_t *pflash_cfi01_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk,
uint32_t sector_len, int nb_blocs,
int bank_width, uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3, int be)
PFlashCFI01 *pflash_cfi01_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk,
uint32_t sector_len, int nb_blocs,
int bank_width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
int be)
{
DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH01);
DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
if (blk) {
qdev_prop_set_drive(dev, "drive", blk, &error_abort);
@ -953,17 +982,17 @@ pflash_t *pflash_cfi01_register(hwaddr base,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
return CFI_PFLASH01(dev);
return PFLASH_CFI01(dev);
}
MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl)
MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl)
{
return &fl->mem;
}
static void postload_update_cb(void *opaque, int running, RunState state)
{
pflash_t *pfl = opaque;
PFlashCFI01 *pfl = opaque;
/* This is called after bdrv_invalidate_cache_all. */
qemu_del_vm_change_state_handler(pfl->vmstate);
@ -975,7 +1004,7 @@ static void postload_update_cb(void *opaque, int running, RunState state)
static int pflash_post_load(void *opaque, int version_id)
{
pflash_t *pfl = opaque;
PFlashCFI01 *pfl = opaque;
if (!pfl->ro) {
pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,

View File

@ -57,9 +57,7 @@ do { \
#define PFLASH_LAZY_ROMD_THRESHOLD 42
#define CFI_PFLASH02(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH02)
struct pflash_t {
struct PFlashCFI02 {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
@ -84,7 +82,7 @@ struct pflash_t {
uint16_t unlock_addr0;
uint16_t unlock_addr1;
uint8_t cfi_table[0x52];
QEMUTimer *timer;
QEMUTimer timer;
/* The device replicates the flash memory across its memory space. Emulate
* that by having a container (.mem) filled with an array of aliases
* (.mem_mappings) pointing to the flash memory (.orig_mem).
@ -101,7 +99,7 @@ struct pflash_t {
/*
* Set up replicated mappings of the same region.
*/
static void pflash_setup_mappings(pflash_t *pfl)
static void pflash_setup_mappings(PFlashCFI02 *pfl)
{
unsigned i;
hwaddr size = memory_region_size(&pfl->orig_mem);
@ -115,7 +113,7 @@ static void pflash_setup_mappings(pflash_t *pfl)
}
}
static void pflash_register_memory(pflash_t *pfl, int rom_mode)
static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode)
{
memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
pfl->rom_mode = rom_mode;
@ -123,7 +121,7 @@ static void pflash_register_memory(pflash_t *pfl, int rom_mode)
static void pflash_timer (void *opaque)
{
pflash_t *pfl = opaque;
PFlashCFI02 *pfl = opaque;
trace_pflash_timer_expired(pfl->cmd);
/* Reset flash */
@ -137,8 +135,8 @@ static void pflash_timer (void *opaque)
pfl->cmd = 0;
}
static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
int width, int be)
static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
int width, int be)
{
hwaddr boff;
uint32_t ret;
@ -246,7 +244,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
}
/* update flash content on disk */
static void pflash_update(pflash_t *pfl, int offset,
static void pflash_update(PFlashCFI02 *pfl, int offset,
int size)
{
int offset_end;
@ -260,8 +258,8 @@ static void pflash_update(pflash_t *pfl, int offset,
}
}
static void pflash_write (pflash_t *pfl, hwaddr offset,
uint32_t value, int width, int be)
static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
hwaddr boff;
uint8_t *p;
@ -429,7 +427,7 @@ static void pflash_write (pflash_t *pfl, hwaddr offset,
}
pfl->status = 0x00;
/* Let's wait 5 seconds before chip erase is done */
timer_mod(pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(NANOSECONDS_PER_SECOND * 5));
break;
case 0x30:
@ -444,7 +442,7 @@ static void pflash_write (pflash_t *pfl, hwaddr offset,
}
pfl->status = 0x00;
/* Let's wait 1/2 second before sector erase is done */
timer_mod(pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(NANOSECONDS_PER_SECOND / 2));
break;
default:
@ -533,7 +531,7 @@ static const MemoryRegionOps pflash_cfi02_ops_le = {
static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
{
pflash_t *pfl = CFI_PFLASH02(dev);
PFlashCFI02 *pfl = PFLASH_CFI02(dev);
uint32_t chip_len;
int ret;
Error *local_err = NULL;
@ -596,7 +594,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
pfl->rom_mode = 1;
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
timer_init_ns(&pfl->timer, QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
pfl->wcycle = 0;
pfl->cmd = 0;
pfl->status = 0;
@ -679,35 +677,42 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
}
static Property pflash_cfi02_properties[] = {
DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
DEFINE_PROP_UINT32("sector-length", struct pflash_t, sector_len, 0),
DEFINE_PROP_UINT8("width", struct pflash_t, width, 0),
DEFINE_PROP_UINT8("mappings", struct pflash_t, mappings, 0),
DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0),
DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0),
DEFINE_PROP_UINT16("unlock-addr0", struct pflash_t, unlock_addr0, 0),
DEFINE_PROP_UINT16("unlock-addr1", struct pflash_t, unlock_addr1, 0),
DEFINE_PROP_STRING("name", struct pflash_t, name),
DEFINE_PROP_DRIVE("drive", PFlashCFI02, blk),
DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, nb_blocs, 0),
DEFINE_PROP_UINT32("sector-length", PFlashCFI02, sector_len, 0),
DEFINE_PROP_UINT8("width", PFlashCFI02, width, 0),
DEFINE_PROP_UINT8("mappings", PFlashCFI02, mappings, 0),
DEFINE_PROP_UINT8("big-endian", PFlashCFI02, be, 0),
DEFINE_PROP_UINT16("id0", PFlashCFI02, ident0, 0),
DEFINE_PROP_UINT16("id1", PFlashCFI02, ident1, 0),
DEFINE_PROP_UINT16("id2", PFlashCFI02, ident2, 0),
DEFINE_PROP_UINT16("id3", PFlashCFI02, ident3, 0),
DEFINE_PROP_UINT16("unlock-addr0", PFlashCFI02, unlock_addr0, 0),
DEFINE_PROP_UINT16("unlock-addr1", PFlashCFI02, unlock_addr1, 0),
DEFINE_PROP_STRING("name", PFlashCFI02, name),
DEFINE_PROP_END_OF_LIST(),
};
static void pflash_cfi02_unrealize(DeviceState *dev, Error **errp)
{
PFlashCFI02 *pfl = PFLASH_CFI02(dev);
timer_del(&pfl->timer);
}
static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pflash_cfi02_realize;
dc->unrealize = pflash_cfi02_unrealize;
dc->props = pflash_cfi02_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo pflash_cfi02_info = {
.name = TYPE_CFI_PFLASH02,
.name = TYPE_PFLASH_CFI02,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct pflash_t),
.instance_size = sizeof(PFlashCFI02),
.class_init = pflash_cfi02_class_init,
};
@ -718,17 +723,19 @@ static void pflash_cfi02_register_types(void)
type_init(pflash_cfi02_register_types)
pflash_t *pflash_cfi02_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk, uint32_t sector_len,
int nb_blocs, int nb_mappings, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
uint16_t unlock_addr0, uint16_t unlock_addr1,
int be)
PFlashCFI02 *pflash_cfi02_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk,
uint32_t sector_len, int nb_blocs,
int nb_mappings, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
uint16_t unlock_addr0,
uint16_t unlock_addr1,
int be)
{
DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH02);
DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI02);
if (blk) {
qdev_prop_set_drive(dev, "drive", blk, &error_abort);
@ -748,5 +755,5 @@ pflash_t *pflash_cfi02_register(hwaddr base,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
return CFI_PFLASH02(dev);
return PFLASH_CFI02(dev);
}

View File

@ -776,6 +776,9 @@ static void interface_release_resource(QXLInstance *sin,
QXLReleaseRing *ring;
uint64_t *item, id;
if (!ext.info) {
return;
}
if (ext.group_id == MEMSLOT_GROUP_HOST) {
/* host group -> vga mode update request */
QXLCommandExt *cmdext = (void *)(intptr_t)(ext.info->id);

View File

@ -426,11 +426,18 @@ static uint8_t xlnx_dp_aux_pop_rx_fifo(XlnxDPState *s)
uint8_t ret;
if (fifo8_is_empty(&s->rx_fifo)) {
DPRINTF("rx_fifo underflow..\n");
abort();
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Reading empty RX_FIFO\n",
__func__);
/*
* The datasheet is not clear about the reset value, it seems
* to be unspecified. We choose to return '0'.
*/
ret = 0;
} else {
ret = fifo8_pop(&s->rx_fifo);
DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
}
ret = fifo8_pop(&s->rx_fifo);
DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
return ret;
}

View File

@ -3,8 +3,6 @@
#include "hw/i2c/i2c.h"
typedef struct bitbang_i2c_interface bitbang_i2c_interface;
#define BITBANG_I2C_SDA 0
#define BITBANG_I2C_SCL 1

View File

@ -56,7 +56,7 @@ static int i2c_ddc_rx(I2CSlave *i2c)
I2CDDCState *s = I2CDDC(i2c);
int value;
value = s->edid_blob[s->reg];
value = s->edid_blob[s->reg % sizeof(s->edid_blob)];
s->reg++;
return value;
}

View File

@ -737,10 +737,16 @@ static void crs_range_set_free(CrsRangeSet *range_set)
static gint crs_range_compare(gconstpointer a, gconstpointer b)
{
CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
CrsRangeEntry *entry_b = *(CrsRangeEntry **)b;
CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
CrsRangeEntry *entry_b = *(CrsRangeEntry **)b;
return (int64_t)entry_a->base - (int64_t)entry_b->base;
if (entry_a->base < entry_b->base) {
return -1;
} else if (entry_a->base > entry_b->base) {
return 1;
} else {
return 0;
}
}
/*
@ -1888,10 +1894,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
scope = aml_scope("\\_SB");
dev = aml_device("PC%.02X", bus_num);
aml_append(dev, aml_name_decl("_UID", aml_int(bus_num)));
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
if (pci_bus_is_express(bus)) {
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
aml_append(dev, build_q35_osc_method());
} else {
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
}
if (numa_node != NUMA_NODE_UNASSIGNED) {

View File

@ -111,7 +111,7 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
char *fatal_errmsg = NULL;
hwaddr phys_addr = 0x100000000ULL;
int sector_bits, sector_size;
pflash_t *system_flash;
PFlashCFI01 *system_flash;
MemoryRegion *flash_mem;
char name[64];
void *flash_ptr;

View File

@ -188,9 +188,11 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s)
MSIMessage msg;
struct ioapic_entry_info info;
ioapic_entry_parse(s->ioredtbl[i], &info);
msg.address = info.addr;
msg.data = info.data;
kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL);
if (!info.masked) {
msg.address = info.addr;
msg.data = info.data;
kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL);
}
}
kvm_irqchip_commit_routes(kvm_state);
}

View File

@ -1188,7 +1188,7 @@ void mips_malta_init(MachineState *machine)
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
char *filename;
pflash_t *fl;
PFlashCFI01 *fl;
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *ram_high = g_new(MemoryRegion, 1);
MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);

View File

@ -345,6 +345,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
if (!dev->hotplugged) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
return;
}
@ -355,6 +359,10 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
if (pci_get_function_0(pci_dev)) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
pcie_cap_slot_event(PCI_DEVICE(hotplug_dev),
PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
}
@ -531,6 +539,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDC);
}

View File

@ -553,11 +553,11 @@ static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
return g_strdup("cdrom");
}
return g_strdup("hd");
return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) {
return g_strdup("hd");
return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) {

View File

@ -404,11 +404,11 @@ static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus,
return g_strdup("cdrom");
}
return g_strdup("hd");
return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) {
return g_strdup("hd");
return g_strdup("disk");
}
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) {

View File

@ -85,7 +85,7 @@ typedef struct RdmaRmPort {
enum ibv_port_state state;
} RdmaRmPort;
typedef struct RdmaDeviceResources {
struct RdmaDeviceResources {
RdmaRmPort ports[MAX_PORTS];
RdmaRmResTbl pd_tbl;
RdmaRmResTbl mr_tbl;
@ -94,6 +94,6 @@ typedef struct RdmaDeviceResources {
RdmaRmResTbl cq_tbl;
RdmaRmResTbl cqe_ctx_tbl;
GHashTable *qp_hash; /* Keeps mapping between real and emulated */
} RdmaDeviceResources;
};
#endif

View File

@ -261,6 +261,11 @@ static int create_cq_ring(PCIDevice *pci_dev , PvrdmaRing **ring,
int rc = -EINVAL;
char ring_name[MAX_RING_NAME_SZ];
if (!nchunks || nchunks > PVRDMA_MAX_FAST_REG_PAGES) {
pr_dbg("invalid nchunks: %d\n", nchunks);
return rc;
}
pr_dbg("pdir_dma=0x%llx\n", (long long unsigned int)pdir_dma);
dir = rdma_pci_dma_map(pci_dev, pdir_dma, TARGET_PAGE_SIZE);
if (!dir) {
@ -310,6 +315,14 @@ out:
return rc;
}
static void destroy_cq_ring(PvrdmaRing *ring)
{
pvrdma_ring_free(ring);
/* ring_state was in slot 1, not 0 so need to jump back */
rdma_pci_dma_unmap(ring->dev, --ring->ring_state, TARGET_PAGE_SIZE);
g_free(ring);
}
static int create_cq(PVRDMADev *dev, union pvrdma_cmd_req *req,
union pvrdma_cmd_resp *rsp)
{
@ -333,6 +346,10 @@ static int create_cq(PVRDMADev *dev, union pvrdma_cmd_req *req,
resp->hdr.err = rdma_rm_alloc_cq(&dev->rdma_dev_res, &dev->backend_dev,
cmd->cqe, &resp->cq_handle, ring);
if (resp->hdr.err) {
destroy_cq_ring(ring);
}
resp->cqe = cmd->cqe;
out:
@ -356,10 +373,7 @@ static int destroy_cq(PVRDMADev *dev, union pvrdma_cmd_req *req,
}
ring = (PvrdmaRing *)cq->opaque;
pvrdma_ring_free(ring);
/* ring_state was in slot 1, not 0 so need to jump back */
rdma_pci_dma_unmap(PCI_DEVICE(dev), --ring->ring_state, TARGET_PAGE_SIZE);
g_free(ring);
destroy_cq_ring(ring);
rdma_rm_dealloc_cq(&dev->rdma_dev_res, cmd->cq_handle);
@ -377,6 +391,12 @@ static int create_qp_rings(PCIDevice *pci_dev, uint64_t pdir_dma,
char ring_name[MAX_RING_NAME_SZ];
uint32_t wqe_sz;
if (!spages || spages > PVRDMA_MAX_FAST_REG_PAGES
|| !rpages || rpages > PVRDMA_MAX_FAST_REG_PAGES) {
pr_dbg("invalid pages: %d, %d\n", spages, rpages);
return rc;
}
pr_dbg("pdir_dma=0x%llx\n", (long long unsigned int)pdir_dma);
dir = rdma_pci_dma_map(pci_dev, pdir_dma, TARGET_PAGE_SIZE);
if (!dir) {
@ -451,6 +471,17 @@ out:
return rc;
}
static void destroy_qp_rings(PvrdmaRing *ring)
{
pr_dbg("sring=%p\n", &ring[0]);
pvrdma_ring_free(&ring[0]);
pr_dbg("rring=%p\n", &ring[1]);
pvrdma_ring_free(&ring[1]);
rdma_pci_dma_unmap(ring->dev, ring->ring_state, TARGET_PAGE_SIZE);
g_free(ring);
}
static int create_qp(PVRDMADev *dev, union pvrdma_cmd_req *req,
union pvrdma_cmd_resp *rsp)
{
@ -481,6 +512,10 @@ static int create_qp(PVRDMADev *dev, union pvrdma_cmd_req *req,
cmd->max_send_sge, cmd->send_cq_handle,
cmd->max_recv_wr, cmd->max_recv_sge,
cmd->recv_cq_handle, rings, &resp->qpn);
if (resp->hdr.err) {
destroy_qp_rings(rings);
goto out;
}
resp->max_send_wr = cmd->max_send_wr;
resp->max_recv_wr = cmd->max_recv_wr;
@ -555,13 +590,7 @@ static int destroy_qp(PVRDMADev *dev, union pvrdma_cmd_req *req,
rdma_rm_dealloc_qp(&dev->rdma_dev_res, cmd->qp_handle);
ring = (PvrdmaRing *)qp->opaque;
pr_dbg("sring=%p\n", &ring[0]);
pvrdma_ring_free(&ring[0]);
pr_dbg("rring=%p\n", &ring[1]);
pvrdma_ring_free(&ring[1]);
rdma_pci_dma_unmap(PCI_DEVICE(dev), ring->ring_state, TARGET_PAGE_SIZE);
g_free(ring);
destroy_qp_rings(ring);
return 0;
}

View File

@ -73,23 +73,16 @@ out:
void *pvrdma_ring_next_elem_read(PvrdmaRing *ring)
{
int e;
unsigned int idx = 0, offset;
/*
pr_dbg("%s: t=%d, h=%d\n", ring->name, ring->ring_state->prod_tail,
ring->ring_state->cons_head);
*/
if (!pvrdma_idx_ring_has_data(ring->ring_state, ring->max_elems, &idx)) {
e = pvrdma_idx_ring_has_data(ring->ring_state, ring->max_elems, &idx);
if (e <= 0) {
pr_dbg("No more data in ring\n");
return NULL;
}
offset = idx * ring->elem_sz;
/*
pr_dbg("idx=%d\n", idx);
pr_dbg("offset=%d\n", offset);
*/
return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);
}
@ -105,20 +98,20 @@ void pvrdma_ring_read_inc(PvrdmaRing *ring)
void *pvrdma_ring_next_elem_write(PvrdmaRing *ring)
{
unsigned int idx, offset, tail;
int idx;
unsigned int offset, tail;
/*
pr_dbg("%s: t=%d, h=%d\n", ring->name, ring->ring_state->prod_tail,
ring->ring_state->cons_head);
*/
if (!pvrdma_idx_ring_has_space(ring->ring_state, ring->max_elems, &tail)) {
idx = pvrdma_idx_ring_has_space(ring->ring_state, ring->max_elems, &tail);
if (idx <= 0) {
pr_dbg("CQ is full\n");
return NULL;
}
idx = pvrdma_idx(&ring->ring_state->prod_tail, ring->max_elems);
/* TODO: tail == idx */
if (idx < 0 || tail != idx) {
pr_dbg("invalid idx\n");
return NULL;
}
offset = idx * ring->elem_sz;
return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);

View File

@ -455,6 +455,11 @@ static const MemoryRegionOps regs_ops = {
},
};
static uint64_t uar_read(void *opaque, hwaddr addr, unsigned size)
{
return 0xffffffff;
}
static void uar_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
PVRDMADev *dev = opaque;
@ -496,6 +501,7 @@ static void uar_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
}
static const MemoryRegionOps uar_ops = {
.read = uar_read,
.write = uar_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
@ -572,7 +578,7 @@ static int pvrdma_check_ram_shared(Object *obj, void *opaque)
static void pvrdma_realize(PCIDevice *pdev, Error **errp)
{
int rc;
int rc = 0;
PVRDMADev *dev = PVRDMA_DEV(pdev);
Object *memdev_root;
bool ram_shared = false;
@ -632,6 +638,7 @@ static void pvrdma_realize(PCIDevice *pdev, Error **errp)
out:
if (rc) {
pvrdma_fini(pdev);
error_append_hint(errp, "Device fail to load\n");
}
}

View File

@ -477,7 +477,7 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
{
PCIDevice *pcid = PCI_DEVICE(s);
MegasasCmd *cmd = NULL;
int frame_size = MFI_FRAME_SIZE * 16;
int frame_size = MEGASAS_MAX_SGE * sizeof(union mfi_sgl);
hwaddr frame_size_p = frame_size;
unsigned long index;

View File

@ -182,7 +182,7 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
/* Also take care of the opt xfer len. */
stl_be_p(&r->buf[12],
MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
} else if (s->needs_vpd_bl_emulation && page == 0x00) {
} else if (s->needs_vpd_bl_emulation && page == 0x00 && r->buflen >= 4) {
/*
* Now we're capable of supplying the VPD Block Limits
* response if the hardware can't. Add it in the INQUIRY
@ -193,18 +193,20 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
* and will use it to proper setup the SCSI device.
*
* VPD page numbers must be sorted, so insert 0xb0 at the
* right place with an in-place insert. After the initialization
* part of the for loop is executed, the device response is
* at r[0] to r[page_idx - 1].
* right place with an in-place insert. When the while loop
* begins the device response is at r[0] to r[page_idx - 1].
*/
for (page_idx = lduw_be_p(r->buf + 2) + 4;
page_idx > 4 && r->buf[page_idx - 1] >= 0xb0;
page_idx--) {
page_idx = lduw_be_p(r->buf + 2) + 4;
page_idx = MIN(page_idx, r->buflen);
while (page_idx > 4 && r->buf[page_idx - 1] >= 0xb0) {
if (page_idx < r->buflen) {
r->buf[page_idx] = r->buf[page_idx - 1];
}
page_idx--;
}
if (page_idx < r->buflen) {
r->buf[page_idx] = 0xb0;
}
r->buf[page_idx] = 0xb0;
stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1);
}
}

View File

@ -214,6 +214,11 @@ typedef struct PowerDevice {
} PowerDevice;
/* Power */
static uint64_t power_mem_read(void *opaque, hwaddr addr, unsigned size)
{
return 0;
}
static void power_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
@ -224,6 +229,7 @@ static void power_mem_write(void *opaque, hwaddr addr,
}
static const MemoryRegionOps power_mem_ops = {
.read = power_mem_read,
.write = power_mem_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {

View File

@ -164,7 +164,13 @@ spi_read(void *opaque, hwaddr addr, unsigned int size)
case R_SPI_RX:
s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
s->regs[R_SPI_STATUS] &= ~S_RXCHOVRF;
ret = fifo32_pop(&s->rx_fifo);
if (fifo32_is_empty(&s->rx_fifo)) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Reading empty RX_FIFO\n",
__func__);
} else {
ret = fifo32_pop(&s->rx_fifo);
}
if (fifo32_is_empty(&s->rx_fifo)) {
s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
}

View File

@ -1221,6 +1221,10 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
static const MemoryRegionOps lqspi_ops = {
.read = lqspi_read,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
.valid = {
.min_access_size = 1,
.max_access_size = 4

View File

@ -265,7 +265,9 @@ static void tpm_crb_reset(void *dev)
s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->tpmbe),
CRB_CTRL_CMD_SIZE);
tpm_backend_startup_tpm(s->tpmbe, s->be_buffer_size);
if (tpm_backend_startup_tpm(s->tpmbe, s->be_buffer_size) < 0) {
exit(1);
}
}
static void tpm_crb_realize(DeviceState *dev, Error **errp)

View File

@ -81,6 +81,40 @@ typedef struct TPMEmulator {
TPMBlobBuffers state_blobs;
} TPMEmulator;
struct tpm_error {
uint32_t tpm_result;
const char *string;
};
static const struct tpm_error tpm_errors[] = {
/* TPM 1.2 error codes */
{ TPM_BAD_PARAMETER , "a parameter is bad" },
{ TPM_FAIL , "operation failed" },
{ TPM_KEYNOTFOUND , "key could not be found" },
{ TPM_BAD_PARAM_SIZE , "bad parameter size"},
{ TPM_ENCRYPT_ERROR , "encryption error" },
{ TPM_DECRYPT_ERROR , "decryption error" },
{ TPM_BAD_KEY_PROPERTY, "bad key property" },
{ TPM_BAD_MODE , "bad (encryption) mode" },
{ TPM_BAD_VERSION , "bad version identifier" },
{ TPM_BAD_LOCALITY , "bad locality" },
/* TPM 2 error codes */
{ TPM_RC_FAILURE , "operation failed" },
{ TPM_RC_LOCALITY , "bad locality" },
{ TPM_RC_INSUFFICIENT, "insufficient amount of data" },
};
static const char *tpm_emulator_strerror(uint32_t tpm_result)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(tpm_errors); i++) {
if (tpm_errors[i].tpm_result == tpm_result) {
return tpm_errors[i].string;
}
}
return "";
}
static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
size_t msg_len_in, size_t msg_len_out)
@ -263,7 +297,8 @@ static int tpm_emulator_stop_tpm(TPMBackend *tb)
res = be32_to_cpu(res);
if (res) {
error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x", res);
error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x %s", res,
tpm_emulator_strerror(res));
return -1;
}
@ -292,8 +327,9 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
psbs.u.resp.tpm_result = be32_to_cpu(psbs.u.resp.tpm_result);
if (psbs.u.resp.tpm_result != 0) {
error_report("tpm-emulator: TPM result for set buffer size : 0x%x",
psbs.u.resp.tpm_result);
error_report("tpm-emulator: TPM result for set buffer size : 0x%x %s",
psbs.u.resp.tpm_result,
tpm_emulator_strerror(psbs.u.resp.tpm_result));
return -1;
}
@ -338,7 +374,8 @@ static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, size_t buffersize,
res = be32_to_cpu(init.u.resp.tpm_result);
if (res) {
error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x", res);
error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x %s", res,
tpm_emulator_strerror(res));
goto err_exit;
}
return 0;
@ -398,8 +435,9 @@ static int tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
res = be32_to_cpu(reset_est.u.resp.tpm_result);
if (res) {
error_report("tpm-emulator: TPM result for rest establixhed flag: 0x%x",
res);
error_report(
"tpm-emulator: TPM result for rest established flag: 0x%x %s",
res, tpm_emulator_strerror(res));
return -1;
}
@ -637,7 +675,8 @@ static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
res = be32_to_cpu(pgs.u.resp.tpm_result);
if (res != 0 && (res & 0x800) == 0) {
error_report("tpm-emulator: Getting the stateblob (type %d) failed "
"with a TPM error 0x%x", type, res);
"with a TPM error 0x%x %s", type, res,
tpm_emulator_strerror(res));
return -1;
}
@ -757,7 +796,8 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
if (tpm_result != 0) {
error_report("tpm-emulator: Setting the stateblob (type %d) failed "
"with a TPM error 0x%x", type, tpm_result);
"with a TPM error 0x%x %s", type, tpm_result,
tpm_emulator_strerror(tpm_result));
return -1;
}
@ -887,8 +927,8 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
strerror(errno));
} else if (res != 0) {
error_report("tpm-emulator: TPM result for sutdown: 0x%x",
be32_to_cpu(res));
error_report("tpm-emulator: TPM result for shutdown: 0x%x %s",
be32_to_cpu(res), tpm_emulator_strerror(be32_to_cpu(res)));
}
}

View File

@ -39,7 +39,16 @@ struct tpm_resp_hdr {
#define TPM_TAG_RSP_AUTH1_COMMAND 0xc5
#define TPM_TAG_RSP_AUTH2_COMMAND 0xc6
#define TPM_BAD_PARAMETER 3
#define TPM_FAIL 9
#define TPM_KEYNOTFOUND 13
#define TPM_BAD_PARAM_SIZE 25
#define TPM_ENCRYPT_ERROR 32
#define TPM_DECRYPT_ERROR 33
#define TPM_BAD_KEY_PROPERTY 40
#define TPM_BAD_MODE 44
#define TPM_BAD_VERSION 46
#define TPM_BAD_LOCALITY 61
#define TPM_ORD_ContinueSelfTest 0x53
#define TPM_ORD_GetTicks 0xf1
@ -59,4 +68,8 @@ struct tpm_resp_hdr {
#define TPM2_PT_MAX_COMMAND_SIZE 0x11e
#define TPM_RC_INSUFFICIENT 0x9a
#define TPM_RC_FAILURE 0x101
#define TPM_RC_LOCALITY 0x907
#endif /* TPM_TPM_INT_H */

View File

@ -263,7 +263,9 @@ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty)
{
uint8_t busy_locty;
s->aborting_locty = locty;
assert(TPM_TIS_IS_VALID_LOCTY(newlocty));
s->aborting_locty = locty; /* may also be TPM_TIS_NO_LOCALITY */
s->next_locty = newlocty; /* locality after successful abort */
/*
@ -293,6 +295,8 @@ static void tpm_tis_request_completed(TPMIf *ti, int ret)
uint8_t locty = s->cmd.locty;
uint8_t l;
assert(TPM_TIS_IS_VALID_LOCTY(locty));
if (s->cmd.selftest_done) {
for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
s->loc[l].sts |= TPM_TIS_STS_SELFTEST_DONE;
@ -616,7 +620,7 @@ static void tpm_tis_mmio_write(void *opaque, hwaddr addr,
}
/* cancel any seize by a lower locality */
for (l = 0; l < locty - 1; l++) {
for (l = 0; l < locty; l++) {
s->loc[l].access &= ~TPM_TIS_ACCESS_SEIZE;
}
@ -891,7 +895,9 @@ static void tpm_tis_reset(DeviceState *dev)
s->rw_offset = 0;
}
tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size);
if (tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size) < 0) {
exit(1);
}
}
/* persistent state handling */

View File

@ -653,13 +653,18 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject *o)
{
struct dirent *entry;
DIR *dir;
int fd;
if (o->have_children) {
return;
}
o->have_children = true;
dir = opendir(o->path);
fd = open(o->path, O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
if (fd < 0) {
return;
}
dir = fdopendir(fd);
if (!dir) {
return;
}
@ -1007,7 +1012,7 @@ static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c,
trace_usb_mtp_op_get_object(s->dev.addr, o->handle, o->path);
d->fd = open(o->path, O_RDONLY);
d->fd = open(o->path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
if (d->fd == -1) {
usb_mtp_data_free(d);
return NULL;
@ -1031,7 +1036,7 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
c->argv[1], c->argv[2]);
d = usb_mtp_data_alloc(c);
d->fd = open(o->path, O_RDONLY);
d->fd = open(o->path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
if (d->fd == -1) {
usb_mtp_data_free(d);
return NULL;
@ -1658,7 +1663,7 @@ static void usb_mtp_write_data(MTPState *s)
0, 0, 0, 0);
goto done;
}
d->fd = open(path, O_CREAT | O_WRONLY, mask);
d->fd = open(path, O_CREAT | O_WRONLY | O_CLOEXEC | O_NOFOLLOW, mask);
if (d->fd == -1) {
usb_mtp_queue_result(s, RES_STORE_FULL, d->trans,
0, 0, 0, 0);

View File

@ -104,6 +104,14 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
vapdev->vdev.name = g_strdup_printf("%s", mdevid);
vapdev->vdev.dev = dev;
/*
* vfio-ap devices operate in a way compatible with
* memory ballooning, as no pages are pinned in the host.
* This needs to be set before vfio_get_device() for vfio common to
* handle the balloon inhibitor.
*/
vapdev->vdev.balloon_allowed = true;
ret = vfio_get_device(vfio_group, mdevid, &vapdev->vdev, &local_err);
if (ret) {
goto out_get_dev_err;

View File

@ -131,6 +131,11 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
}
for (i = 0; i < dev->nvqs; ++i) {
struct vhost_virtqueue *vq = dev->vqs + i;
if (!vq->used_phys && !vq->used_size) {
continue;
}
vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys,
range_get_last(vq->used_phys, vq->used_size));
}
@ -168,6 +173,11 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev)
}
for (i = 0; i < dev->nvqs; ++i) {
struct vhost_virtqueue *vq = dev->vqs + i;
if (!vq->used_phys && !vq->used_size) {
continue;
}
uint64_t last = vq->used_phys + vq->used_size - 1;
log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1);
}

View File

@ -33,11 +33,123 @@
#define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT)
static void balloon_page(void *addr, int deflate)
typedef struct PartiallyBalloonedPage {
ram_addr_t base_gpa;
unsigned long *bitmap;
} PartiallyBalloonedPage;
static void virtio_balloon_pbp_free(PartiallyBalloonedPage *pbp)
{
if (!qemu_balloon_is_inhibited()) {
qemu_madvise(addr, BALLOON_PAGE_SIZE,
deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED);
if (!pbp->bitmap) {
return;
}
g_free(pbp->bitmap);
pbp->bitmap = NULL;
}
static void virtio_balloon_pbp_alloc(PartiallyBalloonedPage *pbp,
ram_addr_t base_gpa,
long subpages)
{
pbp->base_gpa = base_gpa;
pbp->bitmap = bitmap_new(subpages);
}
static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp,
ram_addr_t base_gpa)
{
return pbp->base_gpa == base_gpa;
}
static void balloon_inflate_page(VirtIOBalloon *balloon,
MemoryRegion *mr, hwaddr mr_offset,
PartiallyBalloonedPage *pbp)
{
void *addr = memory_region_get_ram_ptr(mr) + mr_offset;
ram_addr_t rb_offset, rb_aligned_offset, base_gpa;
RAMBlock *rb;
size_t rb_page_size;
int subpages;
/* XXX is there a better way to get to the RAMBlock than via a
* host address? */
rb = qemu_ram_block_from_host(addr, false, &rb_offset);
rb_page_size = qemu_ram_pagesize(rb);
if (rb_page_size == BALLOON_PAGE_SIZE) {
/* Easy case */
ram_block_discard_range(rb, rb_offset, rb_page_size);
/* We ignore errors from ram_block_discard_range(), because it
* has already reported them, and failing to discard a balloon
* page is not fatal */
return;
}
/* Hard case
*
* We've put a piece of a larger host page into the balloon - we
* need to keep track until we have a whole host page to
* discard
*/
warn_report_once(
"Balloon used with backing page size > 4kiB, this may not be reliable");
rb_aligned_offset = QEMU_ALIGN_DOWN(rb_offset, rb_page_size);
subpages = rb_page_size / BALLOON_PAGE_SIZE;
base_gpa = memory_region_get_ram_addr(mr) + mr_offset -
(rb_offset - rb_aligned_offset);
if (pbp->bitmap && !virtio_balloon_pbp_matches(pbp, base_gpa)) {
/* We've partially ballooned part of a host page, but now
* we're trying to balloon part of a different one. Too hard,
* give up on the old partial page */
virtio_balloon_pbp_free(pbp);
}
if (!pbp->bitmap) {
virtio_balloon_pbp_alloc(pbp, base_gpa, subpages);
}
set_bit((rb_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE,
pbp->bitmap);
if (bitmap_full(pbp->bitmap, subpages)) {
/* We've accumulated a full host page, we can actually discard
* it now */
ram_block_discard_range(rb, rb_aligned_offset, rb_page_size);
/* We ignore errors from ram_block_discard_range(), because it
* has already reported them, and failing to discard a balloon
* page is not fatal */
virtio_balloon_pbp_free(pbp);
}
}
static void balloon_deflate_page(VirtIOBalloon *balloon,
MemoryRegion *mr, hwaddr mr_offset)
{
void *addr = memory_region_get_ram_ptr(mr) + mr_offset;
ram_addr_t rb_offset;
RAMBlock *rb;
size_t rb_page_size;
void *host_addr;
int ret;
/* XXX is there a better way to get to the RAMBlock than via a
* host address? */
rb = qemu_ram_block_from_host(addr, false, &rb_offset);
rb_page_size = qemu_ram_pagesize(rb);
host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1));
/* When a page is deflated, we hint the whole host page it lives
* on, since we can't do anything smaller */
ret = qemu_madvise(host_addr, rb_page_size, QEMU_MADV_WILLNEED);
if (ret != 0) {
warn_report("Couldn't MADV_WILLNEED on balloon deflate: %s",
strerror(errno));
/* Otherwise ignore, failing to page hint shouldn't be fatal */
}
}
@ -214,25 +326,29 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
MemoryRegionSection section;
for (;;) {
PartiallyBalloonedPage pbp = {};
size_t offset = 0;
uint32_t pfn;
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
if (!elem) {
return;
break;
}
while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) {
ram_addr_t pa;
ram_addr_t addr;
int p = virtio_ldl_p(vdev, &pfn);
unsigned int p = virtio_ldl_p(vdev, &pfn);
hwaddr pa;
pa = (ram_addr_t) p << VIRTIO_BALLOON_PFN_SHIFT;
pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT;
offset += 4;
/* FIXME: remove get_system_memory(), but how? */
section = memory_region_find(get_system_memory(), pa, 1);
if (!int128_nz(section.size) ||
!memory_region_is_ram(section.mr) ||
section = memory_region_find(get_system_memory(), pa,
BALLOON_PAGE_SIZE);
if (!section.mr) {
trace_virtio_balloon_bad_addr(pa);
continue;
}
if (!memory_region_is_ram(section.mr) ||
memory_region_is_rom(section.mr) ||
memory_region_is_romd(section.mr)) {
trace_virtio_balloon_bad_addr(pa);
@ -242,17 +358,23 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
trace_virtio_balloon_handle_output(memory_region_name(section.mr),
pa);
/* Using memory_region_get_ram_ptr is bending the rules a bit, but
should be OK because we only want a single page. */
addr = section.offset_within_region;
balloon_page(memory_region_get_ram_ptr(section.mr) + addr,
!!(vq == s->dvq));
if (!qemu_balloon_is_inhibited()) {
if (vq == s->ivq) {
balloon_inflate_page(s, section.mr,
section.offset_within_region, &pbp);
} else if (vq == s->dvq) {
balloon_deflate_page(s, section.mr, section.offset_within_region);
} else {
g_assert_not_reached();
}
}
memory_region_unref(section.mr);
}
virtqueue_push(vq, elem, offset);
virtio_notify(vdev, vq);
g_free(elem);
virtio_balloon_pbp_free(&pbp);
}
}
@ -311,7 +433,7 @@ out:
static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
{
VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
struct virtio_balloon_config config;
struct virtio_balloon_config config = {};
config.num_pages = cpu_to_le32(dev->num_pages);
config.actual = cpu_to_le32(dev->actual);

View File

@ -159,12 +159,12 @@ static void xtfpga_net_init(MemoryRegion *address_space,
memory_region_add_subregion(address_space, buffers, ram);
}
static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
const XtfpgaBoardDesc *board,
DriveInfo *dinfo, int be)
static PFlashCFI01 *xtfpga_flash_init(MemoryRegion *address_space,
const XtfpgaBoardDesc *board,
DriveInfo *dinfo, int be)
{
SysBusDevice *s;
DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
&error_abort);
@ -178,7 +178,7 @@ static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
s = SYS_BUS_DEVICE(dev);
memory_region_add_subregion(address_space, board->flash->base,
sysbus_mmio_get_region(s, 0));
return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
return PFLASH_CFI01(dev);
}
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
@ -224,7 +224,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
CPUXtensaState *env = NULL;
MemoryRegion *system_io;
DriveInfo *dinfo;
pflash_t *flash = NULL;
PFlashCFI01 *flash = NULL;
QemuOpts *machine_opts = qemu_get_machine_opts();
const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");

View File

@ -5,32 +5,45 @@
#include "exec/memory.h"
#define TYPE_CFI_PFLASH01 "cfi.pflash01"
#define TYPE_CFI_PFLASH02 "cfi.pflash02"
typedef struct pflash_t pflash_t;
/* pflash_cfi01.c */
pflash_t *pflash_cfi01_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk,
uint32_t sector_len, int nb_blocs, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3, int be);
#define TYPE_PFLASH_CFI01 "cfi.pflash01"
#define PFLASH_CFI01(obj) \
OBJECT_CHECK(PFlashCFI01, (obj), TYPE_PFLASH_CFI01)
typedef struct PFlashCFI01 PFlashCFI01;
PFlashCFI01 *pflash_cfi01_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk,
uint32_t sector_len, int nb_blocs,
int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
int be);
MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl);
/* pflash_cfi02.c */
pflash_t *pflash_cfi02_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk, uint32_t sector_len,
int nb_blocs, int nb_mappings, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
uint16_t unlock_addr0, uint16_t unlock_addr1,
int be);
MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl);
#define TYPE_PFLASH_CFI02 "cfi.pflash02"
#define PFLASH_CFI02(obj) \
OBJECT_CHECK(PFlashCFI02, (obj), TYPE_PFLASH_CFI02)
typedef struct PFlashCFI02 PFlashCFI02;
PFlashCFI02 *pflash_cfi02_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockBackend *blk,
uint32_t sector_len, int nb_blocs,
int nb_mappings,
int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
uint16_t unlock_addr0,
uint16_t unlock_addr1,
int be);
/* nand.c */
DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id);

View File

@ -82,6 +82,8 @@ int i2c_recv(I2CBus *bus);
DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr);
typedef struct bitbang_i2c_interface bitbang_i2c_interface;
/* lm832x.c */
void lm832x_key_event(DeviceState *dev, int key, int state);

View File

@ -31,9 +31,6 @@
#include "hw/sysbus.h"
#include "hw/i2c/i2c.h"
/* from hw/i2c/bitbang_i2c.h */
typedef struct bitbang_i2c_interface bitbang_i2c_interface;
#define TYPE_PPC4xx_I2C "ppc4xx-i2c"
#define PPC4xx_I2C(obj) OBJECT_CHECK(PPC4xxI2CState, (obj), TYPE_PPC4xx_I2C)

View File

@ -50,7 +50,7 @@ typedef struct S390TODClass {
/* Converts ns to s390's clock format */
static inline uint64_t time2tod(uint64_t ns)
{
return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9);
return (ns << 9) / 125 + (((ns & 0xff80000000000000ull) / 125) << 9);
}
/* Converts s390's clock format to ns */

View File

@ -30,6 +30,7 @@ typedef struct virtio_balloon_stat_modern {
uint64_t val;
} VirtIOBalloonStatModern;
typedef struct VirtIOBalloon {
VirtIODevice parent_obj;
VirtQueue *ivq, *dvq, *svq;

View File

@ -9677,8 +9677,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
arg4 = arg5;
arg5 = arg6;
}
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
return -TARGET_EFAULT;
if (arg2 == 0 && arg3 == 0) {
/* Special-case NULL buffer and zero length, which should succeed */
p = 0;
} else {
p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
if (!p) {
return -TARGET_EFAULT;
}
}
ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
unlock_user(p, arg2, ret);
return ret;
@ -9687,8 +9694,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
arg4 = arg5;
arg5 = arg6;
}
if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
return -TARGET_EFAULT;
if (arg2 == 0 && arg3 == 0) {
/* Special-case NULL buffer and zero length, which should succeed */
p = 0;
} else {
p = lock_user(VERIFY_READ, arg2, arg3, 1);
if (!p) {
return -TARGET_EFAULT;
}
}
ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
unlock_user(p, arg2, 0);
return ret;

View File

@ -223,7 +223,6 @@ static void chr_closed_bh(void *opaque)
s = DO_UPCAST(NetVhostUserState, nc, ncs[0]);
qmp_set_link(name, false, &err);
vhost_user_stop(queues, ncs);
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, net_vhost_user_event,
NULL, opaque, NULL, true);

View File

@ -109,6 +109,13 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
}
*argend = 0;
if (!g_str_equal(cmd, "include") && strlen(arg) >= IFNAMSIZ) {
fprintf(stderr, "name `%s' too long: %zu\n", arg, strlen(arg));
fclose(f);
errno = EINVAL;
return -1;
}
if (strcmp(cmd, "deny") == 0) {
acl_rule = g_malloc(sizeof(*acl_rule));
if (strcmp(arg, "all") == 0) {
@ -259,6 +266,10 @@ int main(int argc, char **argv)
usage();
return EXIT_FAILURE;
}
if (strlen(bridge) >= IFNAMSIZ) {
fprintf(stderr, "name `%s' too long: %zu\n", bridge, strlen(bridge));
return EXIT_FAILURE;
}
/* parse default acl file */
QSIMPLEQ_INIT(&acl_list);

View File

@ -503,7 +503,7 @@ static int img_create(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
goto fail;
}
@ -753,7 +753,7 @@ static int img_check(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
return 1;
}
@ -966,7 +966,7 @@ static int img_commit(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
return 1;
}
@ -1349,7 +1349,7 @@ static int img_compare(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
ret = 2;
goto out4;
}
@ -2159,7 +2159,7 @@ static int img_convert(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
goto fail_getopt;
}
@ -2713,7 +2713,7 @@ static int img_info(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
return 1;
}
@ -2932,7 +2932,7 @@ static int img_map(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
return 1;
}
@ -3081,7 +3081,7 @@ static int img_snapshot(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
return 1;
}
@ -3241,7 +3241,7 @@ static int img_rebase(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
return 1;
}
@ -3621,7 +3621,7 @@ static int img_resize(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
return 1;
}
@ -3865,7 +3865,7 @@ static int img_amend(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
ret = -1;
goto out_no_progress;
}
@ -4509,7 +4509,7 @@ static int img_dd(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
ret = -1;
goto out;
}
@ -4786,7 +4786,7 @@ static int img_measure(int argc, char **argv)
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
NULL, &error_fatal)) {
goto out;
}

View File

@ -120,20 +120,37 @@ qemu_seccomp(unsigned int operation, unsigned int flags, void *args)
#endif
}
static uint32_t qemu_seccomp_get_kill_action(void)
static uint32_t qemu_seccomp_get_action(int set)
{
switch (set) {
case QEMU_SECCOMP_SET_DEFAULT:
case QEMU_SECCOMP_SET_OBSOLETE:
case QEMU_SECCOMP_SET_PRIVILEGED:
case QEMU_SECCOMP_SET_SPAWN: {
#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \
defined(SECCOMP_RET_KILL_PROCESS)
{
uint32_t action = SECCOMP_RET_KILL_PROCESS;
static int kill_process = -1;
if (kill_process == -1) {
uint32_t action = SECCOMP_RET_KILL_PROCESS;
if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
kill_process = 1;
}
kill_process = 0;
}
if (kill_process == 1) {
return SCMP_ACT_KILL_PROCESS;
}
}
#endif
return SCMP_ACT_TRAP;
}
return SCMP_ACT_TRAP;
case QEMU_SECCOMP_SET_RESOURCECTL:
return SCMP_ACT_ERRNO(EPERM);
default:
g_assert_not_reached();
}
}
@ -142,7 +159,6 @@ static int seccomp_start(uint32_t seccomp_opts)
int rc = 0;
unsigned int i = 0;
scmp_filter_ctx ctx;
uint32_t action = qemu_seccomp_get_kill_action();
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL) {
@ -156,10 +172,12 @@ static int seccomp_start(uint32_t seccomp_opts)
}
for (i = 0; i < ARRAY_SIZE(blacklist); i++) {
uint32_t action;
if (!(seccomp_opts & blacklist[i].set)) {
continue;
}
action = qemu_seccomp_get_action(blacklist[i].set);
rc = seccomp_rule_add_array(ctx, action, blacklist[i].num,
blacklist[i].narg, blacklist[i].arg_cmp);
if (rc < 0) {

View File

@ -532,12 +532,12 @@
#
# Suspend guest to disk.
#
# This command tries to execute the scripts provided by the pm-utils package.
# If it's not available, the suspend operation will be performed by manually
# writing to a sysfs file.
# This command attempts to suspend the guest using three strategies, in this
# order:
#
# For the best results it's strongly recommended to have the pm-utils
# package installed in the guest.
# - systemd hibernate
# - pm-utils (via pm-hibernate)
# - manual write into sysfs
#
# This command does NOT return a response on success. There is a high chance
# the command succeeded if the VM exits with a zero exit status or, when
@ -560,12 +560,12 @@
#
# Suspend guest to ram.
#
# This command tries to execute the scripts provided by the pm-utils package.
# If it's not available, the suspend operation will be performed by manually
# writing to a sysfs file.
# This command attempts to suspend the guest using three strategies, in this
# order:
#
# For the best results it's strongly recommended to have the pm-utils
# package installed in the guest.
# - systemd suspend
# - pm-utils (via pm-suspend)
# - manual write into sysfs
#
# IMPORTANT: guest-suspend-ram requires QEMU to support the 'system_wakeup'
# command. Thus, it's *required* to query QEMU for the presence of the
@ -592,7 +592,10 @@
#
# Save guest state to disk and suspend to ram.
#
# This command requires the pm-utils package to be installed in the guest.
# This command attempts to suspend the guest by executing, in this order:
#
# - systemd hybrid-sleep
# - pm-utils (via pm-suspend-hybrid)
#
# IMPORTANT: guest-suspend-hybrid requires QEMU to support the 'system_wakeup'
# command. Thus, it's *required* to query QEMU for the presence of the

View File

@ -5,7 +5,7 @@ qga-vss-dll-obj-y += requester.o provider.o install.o
obj-qga-vss-dll-obj-y = $(addprefix $(obj)/, $(qga-vss-dll-obj-y))
$(obj-qga-vss-dll-obj-y): QEMU_CXXFLAGS = $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls -fstack-protector-all -fstack-protector-strong, $(QEMU_CFLAGS)) -Wno-unknown-pragmas -Wno-delete-non-virtual-dtor
$(obj)/qga-vss.dll: LDFLAGS = -shared -Wl,--add-stdcall-alias,--enable-stdcall-fixup -lole32 -loleaut32 -lshlwapi -luuid -static
$(obj)/qga-vss.dll: LDFLAGS = -shared -Wl,--add-stdcall-alias,--enable-stdcall-fixup -lglib-2.0 -lole32 -loleaut32 -lshlwapi -luuid -lintl -lws2_32 -static
$(obj)/qga-vss.dll: $(obj-qga-vss-dll-obj-y) $(SRC_PATH)/$(obj)/qga-vss.def
$(call quiet-command,$(CXX) -o $@ $(qga-vss-dll-obj-y) $(SRC_PATH)/qga/vss-win32/qga-vss.def $(CXXFLAGS) $(LDFLAGS),"LINK","$(TARGET_DIR)$@")

View File

@ -208,11 +208,13 @@ static QString *parse_string(JSONParserContext *ctxt, JSONToken *token)
}
break;
case '%':
if (ctxt->ap && ptr[1] != '%') {
parse_error(ctxt, token, "can't interpolate into string");
goto out;
if (ctxt->ap) {
if (ptr[1] != '%') {
parse_error(ctxt, token, "can't interpolate into string");
goto out;
}
ptr++;
}
ptr++;
/* fall through */
default:
cp = mod_utf8_codepoint(ptr, 6, &end);

View File

@ -300,6 +300,7 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
*/
while (q != (struct ipasfrag*)&fp->frag_link &&
ip->ip_off + ip->ip_len > q->ipf_off) {
struct ipasfrag *prev;
i = (ip->ip_off + ip->ip_len) - q->ipf_off;
if (i < q->ipf_len) {
q->ipf_len -= i;
@ -307,9 +308,10 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
m_adj(dtom(slirp, q), i);
break;
}
prev = q;
q = q->ipf_next;
m_free(dtom(slirp, q->ipf_prev));
ip_deq(q->ipf_prev);
ip_deq(prev);
m_free(dtom(slirp, prev));
}
insert:
@ -334,6 +336,8 @@ insert:
q = fp->frag_link.next;
m = dtom(slirp, q);
int was_ext = m->m_flags & M_EXT;
q = (struct ipasfrag *) q->ipf_next;
while (q != (struct ipasfrag*)&fp->frag_link) {
struct mbuf *t = dtom(slirp, q);
@ -350,13 +354,12 @@ insert:
q = fp->frag_link.next;
/*
* If the fragments concatenated to an mbuf that's
* bigger than the total size of the fragment, then and
* m_ext buffer was alloced. But fp->ipq_next points to
* the old buffer (in the mbuf), so we must point ip
* into the new buffer.
* If the fragments concatenated to an mbuf that's bigger than the total
* size of the fragment and the mbuf was not already using an m_ext buffer,
* then an m_ext buffer was alloced. But fp->ipq_next points to the old
* buffer (in the mbuf), so we must point ip into the new buffer.
*/
if (m->m_flags & M_EXT) {
if (!was_ext && m->m_flags & M_EXT) {
int delta = (char *)q - m->m_dat;
q = (struct ipasfrag *)(m->m_ext + delta);
}

View File

@ -635,6 +635,11 @@ tcp_emu(struct socket *so, struct mbuf *m)
socklen_t addrlen = sizeof(struct sockaddr_in);
struct sbuf *so_rcv = &so->so_rcv;
if (m->m_len > so_rcv->sb_datalen
- (so_rcv->sb_wptr - so_rcv->sb_data)) {
return 1;
}
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_wptr += m->m_len;
so_rcv->sb_rptr += m->m_len;
@ -657,12 +662,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
break;
}
}
so_rcv->sb_cc = snprintf(so_rcv->sb_data,
so_rcv->sb_datalen,
"%d,%d\r\n", n1, n2);
so_rcv->sb_rptr = so_rcv->sb_data;
so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
}
so_rcv->sb_cc = snprintf(so_rcv->sb_data,
so_rcv->sb_datalen,
"%d,%d\r\n", n1, n2);
so_rcv->sb_rptr = so_rcv->sb_data;
so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
}
m_free(m);
return 0;

View File

@ -2493,8 +2493,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
CPUID_7_0_EBX_INTEL_PT,
CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
.features[FEAT_7_0_ECX] =
CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE |
CPUID_7_0_ECX_AVX512VNNI,
@ -2546,7 +2545,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INTEL_PT,
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
.features[FEAT_7_0_ECX] =
CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
@ -2604,8 +2603,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
CPUID_7_0_EBX_INTEL_PT,
CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
.features[FEAT_7_0_ECX] =
CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
@ -2613,8 +2611,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
.features[FEAT_7_0_EDX] =
CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
CPUID_7_0_EDX_SPEC_CTRL_SSBD,
CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
/* Missing: XSAVES (not supported by some Linux versions,
* including v4.1 to v4.12).
* KVM doesn't yet expose any XSAVES state save component,

View File

@ -2226,6 +2226,7 @@ static TCGv gen_get_sr(DisasContext *s)
sr = tcg_temp_new();
tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
tcg_gen_or_i32(sr, sr, ccr);
tcg_temp_free(ccr);
return sr;
}

View File

@ -143,7 +143,7 @@ GEN_VXFORM(vaddsws, 0, 14),
GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
GEN_VXFORM(vsubuws, 0, 26),
GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_NONE, PPC2_ISA300),
GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_ALTIVEC, PPC2_ISA300),
GEN_VXFORM(vsubshs, 0, 29),
GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE),
GEN_VXFORM_207(vadduqm, 0, 4),

View File

@ -1297,6 +1297,8 @@ static void init_ignored_base_feat(void)
S390_FEAT_KM_TDEA_192,
S390_FEAT_KIMD_SHA_1,
S390_FEAT_KLMD_SHA_1,
/* CSSKE is deprecated on newer generations */
S390_FEAT_CONDITIONAL_SSKE,
};
int i;

View File

@ -130,7 +130,7 @@ out:
}
return;
default:
hw_error("Unhandled diag308 subcode %" PRIx64, subcode);
s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
break;
}
}

View File

@ -70,6 +70,7 @@ check-unit-y += tests/test-bdrv-drain$(EXESUF)
check-unit-y += tests/test-blockjob$(EXESUF)
check-unit-y += tests/test-blockjob-txn$(EXESUF)
check-unit-y += tests/test-block-backend$(EXESUF)
check-unit-y += tests/test-block-iothread$(EXESUF)
check-unit-y += tests/test-image-locking$(EXESUF)
check-unit-y += tests/test-x86-cpuid$(EXESUF)
# all code tested by test-x86-cpuid is inside topology.h
@ -538,6 +539,7 @@ tests/test-bdrv-drain$(EXESUF): tests/test-bdrv-drain.o $(test-block-obj-y) $(te
tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-block-backend$(EXESUF): tests/test-block-backend.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-block-iothread$(EXESUF): tests/test-block-iothread.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-image-locking$(EXESUF): tests/test-image-locking.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)

View File

@ -175,6 +175,11 @@ static void utf8_string(void)
"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
},
/* '%' character when not interpolating */
{
"100%",
"100%",
},
/* 2 Boundary condition test cases */
/* 2.1 First possible sequence of a certain length */

View File

@ -1,6 +1,7 @@
#!/bin/bash
#
# Test qemu-img vs. unaligned images
# (See also 253, which is the O_DIRECT version)
#
# Copyright (C) 2018 Red Hat, Inc.
#
@ -37,6 +38,9 @@ _supported_fmt raw
_supported_proto file
_supported_os Linux
_default_cache_mode writeback
_supported_cache_modes writeback writethrough unsafe
echo
echo "=== Check mapping of unaligned raw image ==="
echo

View File

@ -82,11 +82,15 @@ echo
echo '=== Force cancel job paused in error state ==='
echo
# Filter out BLOCK_JOB_ERROR events because they may or may not occur.
# Cancelling the job means resuming it for a bit before it is actually
# aborted, and in that time it may or may not re-encounter the error.
success_or_failure="y" _send_qemu_cmd $QEMU_HANDLE \
"{'execute': 'block-job-cancel',
'arguments': { 'device': 'testdisk',
'force': true}}" \
"BLOCK_JOB_CANCELLED" "Assertion"
"BLOCK_JOB_CANCELLED" "Assertion" \
| grep -v '"BLOCK_JOB_ERROR"'
# success, all done
echo "*** done"

View File

@ -17,7 +17,6 @@ wrote 2097152/2097152 bytes at offset 0
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": 1048576, "speed": 0, "type": "mirror"}}
*** done

View File

@ -49,7 +49,9 @@ qemu_img_create('-f', iotests.imgfmt, '-o', 'preallocation=metadata', disk,
str(size))
vm = QEMUMachine(iotests.qemu_prog)
vm.add_args('-machine', 'pc,accel=kvm')
vm.add_args('-machine', 'accel=kvm')
if iotests.qemu_default_machine == 's390-ccw-virtio':
vm.add_args('-no-shutdown')
vm.add_args('-drive', 'id=src,file=' + disk)
vm.launch()

View File

@ -0,0 +1,84 @@
#!/usr/bin/env bash
#
# Test qemu-img vs. unaligned images; O_DIRECT version
# (Originates from 221)
#
# Copyright (C) 2019 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
seq="$(basename $0)"
echo "QA output created by $seq"
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt raw
_supported_proto file
_supported_os Linux
_default_cache_mode none
_supported_cache_modes none directsync
echo
echo "=== Check mapping of unaligned raw image ==="
echo
# We do not know how large a physical sector is, but it is certainly
# going to be a factor of 1 MB
size=$((1 * 1024 * 1024 - 1))
# qemu-img create rounds size up to BDRV_SECTOR_SIZE
_make_test_img $size
$QEMU_IMG map --output=json --image-opts \
"driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
| _filter_qemu_img_map
# so we resize it and check again
truncate --size=$size "$TEST_IMG"
$QEMU_IMG map --output=json --image-opts \
"driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
| _filter_qemu_img_map
# qemu-io with O_DIRECT always writes whole physical sectors. Again,
# we do not know how large a physical sector is, so we just start
# writing from a 64 kB boundary, which should always be aligned.
offset=$((1 * 1024 * 1024 - 64 * 1024))
$QEMU_IO -c "w $offset $((size - offset))" "$TEST_IMG" | _filter_qemu_io
$QEMU_IMG map --output=json --image-opts \
"driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
| _filter_qemu_img_map
# Resize it and check again -- contrary to 221, we may not get partial
# sectors here, so there should be only two areas (one zero, one
# data).
truncate --size=$size "$TEST_IMG"
$QEMU_IMG map --output=json --image-opts \
"driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
| _filter_qemu_img_map
# success, all done
echo '*** done'
rm -f $seq.full
status=0

View File

@ -0,0 +1,14 @@
QA output created by 253
=== Check mapping of unaligned raw image ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575
[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
wrote 65535/65535 bytes at offset 983040
63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
*** done

View File

@ -233,3 +233,4 @@
233 auto quick
234 auto quick migration
235 auto quick
253 rw auto quick

View File

@ -0,0 +1,372 @@
/*
* Block tests for iothreads
*
* Copyright (c) 2018 Kevin Wolf <kwolf@redhat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "block/block.h"
#include "block/blockjob_int.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
#include "iothread.h"
static int coroutine_fn bdrv_test_co_prwv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
{
return 0;
}
static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
int64_t offset, int bytes)
{
return 0;
}
static int coroutine_fn
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
return 0;
}
static int coroutine_fn bdrv_test_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t offset, int64_t count,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
*pnum = count;
return 0;
}
static BlockDriver bdrv_test = {
.format_name = "test",
.instance_size = 1,
.bdrv_co_preadv = bdrv_test_co_prwv,
.bdrv_co_pwritev = bdrv_test_co_prwv,
.bdrv_co_pdiscard = bdrv_test_co_pdiscard,
.bdrv_co_truncate = bdrv_test_co_truncate,
.bdrv_co_block_status = bdrv_test_co_block_status,
};
static void test_sync_op_pread(BdrvChild *c)
{
uint8_t buf[512];
int ret;
/* Success */
ret = bdrv_pread(c, 0, buf, sizeof(buf));
g_assert_cmpint(ret, ==, 512);
/* Early error: Negative offset */
ret = bdrv_pread(c, -2, buf, sizeof(buf));
g_assert_cmpint(ret, ==, -EIO);
}
static void test_sync_op_pwrite(BdrvChild *c)
{
uint8_t buf[512];
int ret;
/* Success */
ret = bdrv_pwrite(c, 0, buf, sizeof(buf));
g_assert_cmpint(ret, ==, 512);
/* Early error: Negative offset */
ret = bdrv_pwrite(c, -2, buf, sizeof(buf));
g_assert_cmpint(ret, ==, -EIO);
}
static void test_sync_op_blk_pread(BlockBackend *blk)
{
uint8_t buf[512];
int ret;
/* Success */
ret = blk_pread(blk, 0, buf, sizeof(buf));
g_assert_cmpint(ret, ==, 512);
/* Early error: Negative offset */
ret = blk_pread(blk, -2, buf, sizeof(buf));
g_assert_cmpint(ret, ==, -EIO);
}
static void test_sync_op_blk_pwrite(BlockBackend *blk)
{
uint8_t buf[512];
int ret;
/* Success */
ret = blk_pwrite(blk, 0, buf, sizeof(buf), 0);
g_assert_cmpint(ret, ==, 512);
/* Early error: Negative offset */
ret = blk_pwrite(blk, -2, buf, sizeof(buf), 0);
g_assert_cmpint(ret, ==, -EIO);
}
static void test_sync_op_load_vmstate(BdrvChild *c)
{
uint8_t buf[512];
int ret;
/* Error: Driver does not support snapshots */
ret = bdrv_load_vmstate(c->bs, buf, 0, sizeof(buf));
g_assert_cmpint(ret, ==, -ENOTSUP);
}
static void test_sync_op_save_vmstate(BdrvChild *c)
{
uint8_t buf[512];
int ret;
/* Error: Driver does not support snapshots */
ret = bdrv_save_vmstate(c->bs, buf, 0, sizeof(buf));
g_assert_cmpint(ret, ==, -ENOTSUP);
}
static void test_sync_op_pdiscard(BdrvChild *c)
{
int ret;
/* Normal success path */
c->bs->open_flags |= BDRV_O_UNMAP;
ret = bdrv_pdiscard(c, 0, 512);
g_assert_cmpint(ret, ==, 0);
/* Early success: UNMAP not supported */
c->bs->open_flags &= ~BDRV_O_UNMAP;
ret = bdrv_pdiscard(c, 0, 512);
g_assert_cmpint(ret, ==, 0);
/* Early error: Negative offset */
ret = bdrv_pdiscard(c, -2, 512);
g_assert_cmpint(ret, ==, -EIO);
}
static void test_sync_op_blk_pdiscard(BlockBackend *blk)
{
int ret;
/* Early success: UNMAP not supported */
ret = blk_pdiscard(blk, 0, 512);
g_assert_cmpint(ret, ==, 0);
/* Early error: Negative offset */
ret = blk_pdiscard(blk, -2, 512);
g_assert_cmpint(ret, ==, -EIO);
}
static void test_sync_op_truncate(BdrvChild *c)
{
int ret;
/* Normal success path */
ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
g_assert_cmpint(ret, ==, 0);
/* Early error: Negative offset */
ret = bdrv_truncate(c, -2, PREALLOC_MODE_OFF, NULL);
g_assert_cmpint(ret, ==, -EINVAL);
/* Error: Read-only image */
c->bs->read_only = true;
c->bs->open_flags &= ~BDRV_O_RDWR;
ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
g_assert_cmpint(ret, ==, -EACCES);
c->bs->read_only = false;
c->bs->open_flags |= BDRV_O_RDWR;
}
static void test_sync_op_block_status(BdrvChild *c)
{
int ret;
int64_t n;
/* Normal success path */
ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
g_assert_cmpint(ret, ==, 0);
/* Early success: No driver support */
bdrv_test.bdrv_co_block_status = NULL;
ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
g_assert_cmpint(ret, ==, 1);
/* Early success: bytes = 0 */
ret = bdrv_is_allocated(c->bs, 0, 0, &n);
g_assert_cmpint(ret, ==, 0);
/* Early success: Offset > image size*/
ret = bdrv_is_allocated(c->bs, 0x1000000, 0x1000000, &n);
g_assert_cmpint(ret, ==, 0);
}
static void test_sync_op_flush(BdrvChild *c)
{
int ret;
/* Normal success path */
ret = bdrv_flush(c->bs);
g_assert_cmpint(ret, ==, 0);
/* Early success: Read-only image */
c->bs->read_only = true;
c->bs->open_flags &= ~BDRV_O_RDWR;
ret = bdrv_flush(c->bs);
g_assert_cmpint(ret, ==, 0);
c->bs->read_only = false;
c->bs->open_flags |= BDRV_O_RDWR;
}
static void test_sync_op_blk_flush(BlockBackend *blk)
{
BlockDriverState *bs = blk_bs(blk);
int ret;
/* Normal success path */
ret = blk_flush(blk);
g_assert_cmpint(ret, ==, 0);
/* Early success: Read-only image */
bs->read_only = true;
bs->open_flags &= ~BDRV_O_RDWR;
ret = blk_flush(blk);
g_assert_cmpint(ret, ==, 0);
bs->read_only = false;
bs->open_flags |= BDRV_O_RDWR;
}
static void test_sync_op_check(BdrvChild *c)
{
BdrvCheckResult result;
int ret;
/* Error: Driver does not implement check */
ret = bdrv_check(c->bs, &result, 0);
g_assert_cmpint(ret, ==, -ENOTSUP);
}
static void test_sync_op_invalidate_cache(BdrvChild *c)
{
/* Early success: Image is not inactive */
bdrv_invalidate_cache(c->bs, NULL);
}
typedef struct SyncOpTest {
const char *name;
void (*fn)(BdrvChild *c);
void (*blkfn)(BlockBackend *blk);
} SyncOpTest;
const SyncOpTest sync_op_tests[] = {
{
.name = "/sync-op/pread",
.fn = test_sync_op_pread,
.blkfn = test_sync_op_blk_pread,
}, {
.name = "/sync-op/pwrite",
.fn = test_sync_op_pwrite,
.blkfn = test_sync_op_blk_pwrite,
}, {
.name = "/sync-op/load_vmstate",
.fn = test_sync_op_load_vmstate,
}, {
.name = "/sync-op/save_vmstate",
.fn = test_sync_op_save_vmstate,
}, {
.name = "/sync-op/pdiscard",
.fn = test_sync_op_pdiscard,
.blkfn = test_sync_op_blk_pdiscard,
}, {
.name = "/sync-op/truncate",
.fn = test_sync_op_truncate,
}, {
.name = "/sync-op/block_status",
.fn = test_sync_op_block_status,
}, {
.name = "/sync-op/flush",
.fn = test_sync_op_flush,
.blkfn = test_sync_op_blk_flush,
}, {
.name = "/sync-op/check",
.fn = test_sync_op_check,
}, {
.name = "/sync-op/invalidate_cache",
.fn = test_sync_op_invalidate_cache,
},
};
/* Test synchronous operations that run in a different iothread, so we have to
* poll for the coroutine there to return. */
static void test_sync_op(const void *opaque)
{
const SyncOpTest *t = opaque;
IOThread *iothread = iothread_new();
AioContext *ctx = iothread_get_aio_context(iothread);
BlockBackend *blk;
BlockDriverState *bs;
BdrvChild *c;
blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
blk_insert_bs(blk, bs, &error_abort);
c = QLIST_FIRST(&bs->parents);
blk_set_aio_context(blk, ctx);
aio_context_acquire(ctx);
t->fn(c);
if (t->blkfn) {
t->blkfn(blk);
}
aio_context_release(ctx);
blk_set_aio_context(blk, qemu_get_aio_context());
bdrv_unref(bs);
blk_unref(blk);
}
int main(int argc, char **argv)
{
int i;
bdrv_init();
qemu_init_main_loop(&error_abort);
g_test_init(&argc, &argv, NULL);
for (i = 0; i < ARRAY_SIZE(sync_op_tests); i++) {
const SyncOpTest *t = &sync_op_tests[i];
g_test_add_data_func(t->name, t, test_sync_op);
}
return g_test_run();
}

View File

@ -754,7 +754,7 @@ const char *qemu_ether_ntoa(const MACAddr *mac)
char *size_to_str(uint64_t val)
{
static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
unsigned long div;
uint64_t div;
int i;
/*