Compare commits

...
170 Commits
Author SHA1 Message Date
Michael Roth 23967e5b2a Update version for 4.0.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-17 15:15:33 -05:00
Paul Durrant a678cd4d30 xen-bus: check whether the frontend is active during device reset...
...not the backend

Commit cb323146 "xen-bus: Fix backend state transition on device reset"
contained a subtle mistake. The hunk

@@ -539,11 +556,11 @@ static void xen_device_backend_changed(void *opaque)

     /*
      * If the toolstack (or unplug request callback) has set the backend
-     * state to Closing, but there is no active frontend (i.e. the
-     * state is not Connected) then set the backend state to Closed.
+     * state to Closing, but there is no active frontend then set the
+     * backend state to Closed.
      */
     if (xendev->backend_state == XenbusStateClosing &&
-        xendev->frontend_state != XenbusStateConnected) {
+        !xen_device_state_is_active(state)) {
         xen_device_backend_set_state(xendev, XenbusStateClosed);
     }

mistakenly replaced the check of 'xendev->frontend_state' with a check
(now in a helper function) of 'state', which actually equates to
'xendev->backend_state'.

This patch fixes the mistake.

Fixes: cb32314607
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Message-Id: <20190910171753.3775-1-paul.durrant@citrix.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
(cherry picked from commit df6180bb56)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-14 18:34:20 -05:00
Philippe Mathieu-Daudé 6341bef468 virtio-blk: Cancel the pending BH when the dataplane is reset
When 'system_reset' is called, the main loop clear the memory
region cache before the BH has a chance to execute. Later when
the deferred function is called, some assumptions that were
made when scheduling them are no longer true when they actually
execute.

This is what happens using a virtio-blk device (fresh RHEL7.8 install):

 $ (sleep 12.3; echo system_reset; sleep 12.3; echo system_reset; sleep 1; echo q) \
   | qemu-system-x86_64 -m 4G -smp 8 -boot menu=on \
     -device virtio-blk-pci,id=image1,drive=drive_image1 \
     -drive file=/var/lib/libvirt/images/rhel78.qcow2,if=none,id=drive_image1,format=qcow2,cache=none \
     -device virtio-net-pci,netdev=net0,id=nic0,mac=52:54:00:c4:e7:84 \
     -netdev tap,id=net0,script=/bin/true,downscript=/bin/true,vhost=on \
     -monitor stdio -serial null -nographic
  (qemu) system_reset
  (qemu) system_reset
  (qemu) qemu-system-x86_64: hw/virtio/virtio.c:225: vring_get_region_caches: Assertion `caches != NULL' failed.
  Aborted

  (gdb) bt
  Thread 1 (Thread 0x7f109c17b680 (LWP 10939)):
  #0  0x00005604083296d1 in vring_get_region_caches (vq=0x56040a24bdd0) at hw/virtio/virtio.c:227
  #1  0x000056040832972b in vring_avail_flags (vq=0x56040a24bdd0) at hw/virtio/virtio.c:235
  #2  0x000056040832d13d in virtio_should_notify (vdev=0x56040a240630, vq=0x56040a24bdd0) at hw/virtio/virtio.c:1648
  #3  0x000056040832d1f8 in virtio_notify_irqfd (vdev=0x56040a240630, vq=0x56040a24bdd0) at hw/virtio/virtio.c:1662
  #4  0x00005604082d213d in notify_guest_bh (opaque=0x56040a243ec0) at hw/block/dataplane/virtio-blk.c:75
  #5  0x000056040883dc35 in aio_bh_call (bh=0x56040a243f10) at util/async.c:90
  #6  0x000056040883dccd in aio_bh_poll (ctx=0x560409161980) at util/async.c:118
  #7  0x0000560408842af7 in aio_dispatch (ctx=0x560409161980) at util/aio-posix.c:460
  #8  0x000056040883e068 in aio_ctx_dispatch (source=0x560409161980, callback=0x0, user_data=0x0) at util/async.c:261
  #9  0x00007f10a8fca06d in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
  #10 0x0000560408841445 in glib_pollfds_poll () at util/main-loop.c:215
  #11 0x00005604088414bf in os_host_main_loop_wait (timeout=0) at util/main-loop.c:238
  #12 0x00005604088415c4 in main_loop_wait (nonblocking=0) at util/main-loop.c:514
  #13 0x0000560408416b1e in main_loop () at vl.c:1923
  #14 0x000056040841e0e8 in main (argc=20, argv=0x7ffc2c3f9c58, envp=0x7ffc2c3f9d00) at vl.c:4578

Fix this by cancelling the BH when the virtio dataplane is stopped.

[This is version of the patch was modified as discussed with Philippe on
the mailing list thread.
--Stefan]

Reported-by: Yihuang Yu <yihyu@redhat.com>
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Fixes: https://bugs.launchpad.net/qemu/+bug/1839428
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190816171503.24761-1-philmd@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit ebb6ff25cd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-14 18:30:31 -05:00
Yury Kotov 35d6458d6a migration: Fix use-after-free during process exit
It fixes heap-use-after-free which was found by clang's ASAN.

Control flow of this use-after-free:
main_thread:
    * Got SIGTERM and completes main loop
    * Calls migration_shutdown
      - migrate_fd_cancel (so, migration_thread begins to complete)
      - object_unref(OBJECT(current_migration));

migration_thread:
    * migration_iteration_finish -> schedule cleanup bh
    * object_unref(OBJECT(s)); (Now, current_migration is freed)
    * exits

main_thread:
    * Calls vm_shutdown -> drain bdrvs -> main loop
      -> cleanup_bh -> use after free

If you want to reproduce, these couple of sleeps will help:
vl.c:4613:
     migration_shutdown();
+    sleep(2);
migration.c:3269:
+    sleep(1);
     trace_migration_thread_after_loop();
     migration_iteration_finish(s);

Original output:
qemu-system-x86_64: terminating on signal 15 from pid 31980 (<unknown process>)
=================================================================
==31958==ERROR: AddressSanitizer: heap-use-after-free on address 0x61900001d210
  at pc 0x555558a535ca bp 0x7fffffffb190 sp 0x7fffffffb188
READ of size 8 at 0x61900001d210 thread T0 (qemu-vm-0)
    #0 0x555558a535c9 in migrate_fd_cleanup migration/migration.c:1502:23
    #1 0x5555594fde0a in aio_bh_call util/async.c:90:5
    #2 0x5555594fe522 in aio_bh_poll util/async.c:118:13
    #3 0x555559524783 in aio_poll util/aio-posix.c:725:17
    #4 0x555559504fb3 in aio_wait_bh_oneshot util/aio-wait.c:71:5
    #5 0x5555573bddf6 in virtio_blk_data_plane_stop
      hw/block/dataplane/virtio-blk.c:282:5
    #6 0x5555589d5c09 in virtio_bus_stop_ioeventfd hw/virtio/virtio-bus.c:246:9
    #7 0x5555589e9917 in virtio_pci_stop_ioeventfd hw/virtio/virtio-pci.c:287:5
    #8 0x5555589e22bf in virtio_pci_vmstate_change hw/virtio/virtio-pci.c:1072:9
    #9 0x555557628931 in virtio_vmstate_change hw/virtio/virtio.c:2257:9
    #10 0x555557c36713 in vm_state_notify vl.c:1605:9
    #11 0x55555716ef53 in do_vm_stop cpus.c:1074:9
    #12 0x55555716eeff in vm_shutdown cpus.c:1092:12
    #13 0x555557c4283e in main vl.c:4617:5
    #14 0x7fffdfdb482f in __libc_start_main
      (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #15 0x555556ecb118 in _start (x86_64-softmmu/qemu-system-x86_64+0x1977118)

0x61900001d210 is located 144 bytes inside of 952-byte region
  [0x61900001d180,0x61900001d538)
freed by thread T6 (live_migration) here:
    #0 0x555556f76782 in __interceptor_free
      /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:124:3
    #1 0x555558d5fa94 in object_finalize qom/object.c:618:9
    #2 0x555558d57651 in object_unref qom/object.c:1068:9
    #3 0x555558a55588 in migration_thread migration/migration.c:3272:5
    #4 0x5555595393f2 in qemu_thread_start util/qemu-thread-posix.c:502:9
    #5 0x7fffe057f6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)

previously allocated by thread T0 (qemu-vm-0) here:
    #0 0x555556f76b03 in __interceptor_malloc
      /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:146:3
    #1 0x7ffff6ee37b8 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4f7b8)
    #2 0x555558d58031 in object_new qom/object.c:640:12
    #3 0x555558a31f21 in migration_object_init migration/migration.c:139:25
    #4 0x555557c41398 in main vl.c:4320:5
    #5 0x7fffdfdb482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

Thread T6 (live_migration) created by T0 (qemu-vm-0) here:
    #0 0x555556f5f0dd in pthread_create
      /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:210:3
    #1 0x555559538cf9 in qemu_thread_create util/qemu-thread-posix.c:539:11
    #2 0x555558a53304 in migrate_fd_connect migration/migration.c:3332:5
    #3 0x555558a72bd8 in migration_channel_connect migration/channel.c:92:5
    #4 0x555558a6ef87 in exec_start_outgoing_migration migration/exec.c:42:5
    #5 0x555558a4f3c2 in qmp_migrate migration/migration.c:1922:9
    #6 0x555558bb4f6a in qmp_marshal_migrate qapi/qapi-commands-migration.c:607:5
    #7 0x555559363738 in do_qmp_dispatch qapi/qmp-dispatch.c:131:5
    #8 0x555559362a15 in qmp_dispatch qapi/qmp-dispatch.c:174:11
    #9 0x5555571bac15 in monitor_qmp_dispatch monitor.c:4124:11
    #10 0x55555719a22d in monitor_qmp_bh_dispatcher monitor.c:4207:9
    #11 0x5555594fde0a in aio_bh_call util/async.c:90:5
    #12 0x5555594fe522 in aio_bh_poll util/async.c:118:13
    #13 0x5555595201e0 in aio_dispatch util/aio-posix.c:460:5
    #14 0x555559503553 in aio_ctx_dispatch util/async.c:261:5
    #15 0x7ffff6ede196 in g_main_context_dispatch
      (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4a196)

SUMMARY: AddressSanitizer: heap-use-after-free migration/migration.c:1502:23
  in migrate_fd_cleanup
Shadow bytes around the buggy address:
  0x0c327fffb9f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fffba00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fffba10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fffba20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fffba30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c327fffba40: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fffba50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fffba60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fffba70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fffba80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fffba90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable: 00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone: fa
  Freed heap region: fd
  Stack left redzone: f1
  Stack mid redzone: f2
  Stack right redzone: f3
  Stack after return: f5
  Stack use after scope: f8
  Global redzone: f9
  Global init order: f6
  Poisoned by user: f7
  Container overflow: fc
  Array cookie: ac
  Intra object redzone: bb
  ASan internal: fe
  Left alloca redzone: ca
  Right alloca redzone: cb
  Shadow gap: cc
==31958==ABORTING

Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru>
Message-Id: <20190408113343.2370-1-yury-kotov@yandex-team.ru>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
  Fixed up comment formatting
(cherry picked from commit fd392cfa8e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-14 18:30:23 -05:00
Li Qiang 306ecc0d24 hw/nvram/fw_cfg: Store 'reboot-timeout' as little endian
The current codebase is not specific about the endianess of the
fw_cfg 'file' entry 'reboot-timeout'.

Per docs/specs/fw_cfg.txt:

  === All Other Data Items ===

  Please consult the QEMU source for the most up-to-date
  and authoritative list of selector keys and their respective
  items' purpose, format and writeability.

Checking the git history, this code was introduced in commit
ac05f34924, very similar to commit 3d3b8303c6 for the
'boot-menu-wait' entry, which explicitely use little-endian.

OVMF consumes 'boot-menu-wait' as little-endian, however it does
not consume 'reboot-timeout'.

Regarding the git history and OVMF use, we choose to explicit
'reboot-timeout' endianess as little-endian.

Signed-off-by: Li Qiang <liq3ea@163.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190424140643.62457-4-liq3ea@163.com>
[PMD: Reword commit description based on review comments]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
(cherry picked from commit 04da973501)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-14 18:30:11 -05:00
Philippe Mathieu-Daudé 1e821a0abc 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-10-03 13:46:05 -05:00
Philippe Mathieu-Daudé 96389e9061 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-10-03 13:43:12 -05:00
Michal Privoznik 535b8d00c1 nvme: Set number of queues later in nvme_init()
When creating the admin queue in nvme_init() the variable that
holds the number of queues created is modified before actual
queue creation. This is a problem because if creating the queue
fails then the variable is left in inconsistent state. This was
actually observed when I tried to hotplug a nvme disk. The
control got to nvme_file_open() which called nvme_init() which
failed and thus nvme_close() was called which in turn called
nvme_free_queue_pair() with queue being NULL. This lead to an
instant crash:

  #0  0x000055d9507ec211 in nvme_free_queue_pair (bs=0x55d952ddb880, q=0x0) at block/nvme.c:164
  #1  0x000055d9507ee180 in nvme_close (bs=0x55d952ddb880) at block/nvme.c:729
  #2  0x000055d9507ee3d5 in nvme_file_open (bs=0x55d952ddb880, options=0x55d952bb1410, flags=147456, errp=0x7ffd8e19e200) at block/nvme.c:781
  #3  0x000055d9507629f3 in bdrv_open_driver (bs=0x55d952ddb880, drv=0x55d95109c1e0 <bdrv_nvme>, node_name=0x0, options=0x55d952bb1410, open_flags=147456, errp=0x7ffd8e19e310) at block.c:1291
  #4  0x000055d9507633d6 in bdrv_open_common (bs=0x55d952ddb880, file=0x0, options=0x55d952bb1410, errp=0x7ffd8e19e310) at block.c:1551
  #5  0x000055d950766881 in bdrv_open_inherit (filename=0x0, reference=0x0, options=0x55d952bb1410, flags=32768, parent=0x55d9538ce420, child_role=0x55d950eaade0 <child_file>, errp=0x7ffd8e19e510) at block.c:3063
  #6  0x000055d950765ae4 in bdrv_open_child_bs (filename=0x0, options=0x55d9541cdff0, bdref_key=0x55d950af33aa "file", parent=0x55d9538ce420, child_role=0x55d950eaade0 <child_file>, allow_none=true, errp=0x7ffd8e19e510) at block.c:2712
  #7  0x000055d950766633 in bdrv_open_inherit (filename=0x0, reference=0x0, options=0x55d9541cdff0, flags=0, parent=0x0, child_role=0x0, errp=0x7ffd8e19e908) at block.c:3011
  #8  0x000055d950766dba in bdrv_open (filename=0x0, reference=0x0, options=0x55d953d00390, flags=0, errp=0x7ffd8e19e908) at block.c:3156
  #9  0x000055d9507cb635 in blk_new_open (filename=0x0, reference=0x0, options=0x55d953d00390, flags=0, errp=0x7ffd8e19e908) at block/block-backend.c:389
  #10 0x000055d950465ec5 in blockdev_init (file=0x0, bs_opts=0x55d953d00390, errp=0x7ffd8e19e908) at blockdev.c:602

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Message-id: 927aae40b617ba7d4b6c7ffe74e6d7a2595f8e86.1562770546.git.mprivozn@redhat.com
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 95667c3be0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-03 13:41:38 -05:00
Igor Mammedov a81a7fc22e pc-dimm: fix crash when invalid slot number is used
QEMU will crash with:
  Segmentation fault (core dumped)
when negative slot number is used, ex:
  qemu-system-x86_64 -m 1G,maxmem=20G,slots=256 \
      -object memory-backend-ram,id=mem1,size=1G \
      -device pc-dimm,id=dimm1,memdev=mem1,slot=-2

fix it by checking that slot number is within valid range.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20190723160859.27250-1-imammedo@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>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Signed-off-by: Igor Mammedov &lt;<a href="mailto:imammedo@redhat.com" target="_blank">imammedo@redhat.com</a>&gt;<br></blockquote><div><br></div><div>Reviewed-by: Li Qiang &lt;<a href="mailto:liq3ea@gmail.com">liq3ea@gmail.com</a>&gt;<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Reviewed-by: Pankaj Gupta <pagupta@redhat.com>
(cherry picked from commit 22235bb609)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-03 13:39:59 -05:00
Paolo Bonzini b65e78320b scsi: lsi: exit infinite loop while executing script (CVE-2019-12068)
When executing script in lsi_execute_script(), the LSI scsi adapter
emulator advances 's->dsp' index to read next opcode. This can lead
to an infinite loop if the next opcode is empty. Move the existing
loop exit after 10k iterations so that it covers no-op opcodes as
well.

Reported-by: Bugs SysSec <bugs-syssec@rub.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit de594e4765)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 19:12:53 -05:00
Thomas Huth 4f1c6cb2f9 hw/core/loader: Fix possible crash in rom_copy()
Both, "rom->addr" and "addr" are derived from the binary image
that can be loaded with the "-kernel" paramer. The code in
rom_copy() then calculates:

    d = dest + (rom->addr - addr);

and uses "d" as destination in a memcpy() some lines later. Now with
bad kernel images, it is possible that rom->addr is smaller than addr,
thus "rom->addr - addr" gets negative and the memcpy() then tries to
copy contents from the image to a bad memory location. This could
maybe be used to inject code from a kernel image into the QEMU binary,
so we better fix it with an additional sanity check here.

Cc: qemu-stable@nongnu.org
Reported-by: Guangming Liu
Buglink: https://bugs.launchpad.net/qemu/+bug/1844635
Message-Id: <20190925130331.27825-1-thuth@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit e423455c4f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 19:12:53 -05:00
Matthew Rosato a8f24b6bdf s390: PCI: fix IOMMU region init
The fix in dbe9cf606c shrinks the IOMMU memory region to a size
that seems reasonable on the surface, however is actually too
small as it is based against a 0-mapped address space.  This
causes breakage with small guests as they can overrun the IOMMU window.

Let's go back to the prior method of initializing iommu for now.

Fixes: dbe9cf606c ("s390x/pci: Set the iommu region size mpcifc request")
Cc: qemu-stable@nongnu.org
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
Reported-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Tested-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reported-by: Stefan Zimmerman <stzi@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Message-Id: <1569507036-15314-1-git-send-email-mjrosato@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
(cherry picked from commit 7df1dac5f1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 19:12:53 -05:00
Michael Roth b27192be13 slirp: 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)
Fixes: CVE-2019-15890
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 19:14:07 -05:00
Michael Roth c2e03e2aa4 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)
Fixes: CVE-2019-14378
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 19:12:53 -05:00
Max Reitz 4e5fe75422 curl: Check curl_multi_add_handle()'s return code
If we had done that all along, debugging would have been much simpler.
(Also, I/O errors are better than hangs.)

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190910124136.10565-8-mreitz@redhat.com
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit c34dc07f9f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 6739c97bde curl: Handle success in multi_check_completion
Background: As of cURL 7.59.0, it verifies that several functions are
not called from within a callback.  Among these functions is
curl_multi_add_handle().

curl_read_cb() is a callback from cURL and not a coroutine.  Waking up
acb->co will lead to entering it then and there, which means the current
request will settle and the caller (if it runs in the same coroutine)
may then issue the next request.  In such a case, we will enter
curl_setup_preadv() effectively from within curl_read_cb().

Calling curl_multi_add_handle() will then fail and the new request will
not be processed.

Fix this by not letting curl_read_cb() wake up acb->co.  Instead, leave
the whole business of settling the AIOCB objects to
curl_multi_check_completion() (which is called from our timer callback
and our FD handler, so not from any cURL callbacks).

Reported-by: Natalie Gavrielov <ngavrilo@redhat.com>
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1740193
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190910124136.10565-7-mreitz@redhat.com
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit bfb23b480a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz deea66dc61 curl: Report only ready sockets
Instead of reporting all sockets to cURL, only report the one that has
caused curl_multi_do_locked() to be called.  This lets us get rid of the
QLIST_FOREACH_SAFE() list, which was actually wrong: SAFE foreaches are
only safe when the current element is removed in each iteration.  If it
possible for the list to be concurrently modified, we cannot guarantee
that only the current element will be removed.  Therefore, we must not
use QLIST_FOREACH_SAFE() here.

Fixes: ff5ca1664a
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190910124136.10565-6-mreitz@redhat.com
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 9abaf9fc47)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 076796fd39 curl: Pass CURLSocket to curl_multi_do()
curl_multi_do_locked() currently marks all sockets as ready.  That is
not only inefficient, but in fact unsafe (the loop is).  A follow-up
patch will change that, but to do so, curl_multi_do_locked() needs to
know exactly which socket is ready; and that is accomplished by this
patch here.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190910124136.10565-5-mreitz@redhat.com
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 9dbad87d25)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 2aba40a2c8 curl: Check completion in curl_multi_do()
While it is more likely that transfers complete after some file
descriptor has data ready to read, we probably should not rely on it.
Better be safe than sorry and call curl_multi_check_completion() in
curl_multi_do(), too, just like it is done in curl_multi_read().

With this change, curl_multi_do() and curl_multi_read() are actually the
same, so drop curl_multi_read() and use curl_multi_do() as the sole FD
handler.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190910124136.10565-4-mreitz@redhat.com
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 948403bcb1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 06b178eb61 curl: Keep *socket until the end of curl_sock_cb()
This does not really change anything, but it makes the code a bit easier
to follow once we use @socket as the opaque pointer for
aio_set_fd_handler().

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190910124136.10565-3-mreitz@redhat.com
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 007f339b10)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz c4134c9c46 curl: Keep pointer to the CURLState in CURLSocket
A follow-up patch will make curl_multi_do() and curl_multi_read() take a
CURLSocket instead of the CURLState.  They still need the latter,
though, so add a pointer to it to the former.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 20190910124136.10565-2-mreitz@redhat.com
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 0487861685)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Sergio Lopez b9405afb09 blockjob: update nodes head while removing all bdrv
block_job_remove_all_bdrv() iterates through job->nodes, calling
bdrv_root_unref_child() for each entry. The call to the latter may
reach child_job_[can_]set_aio_ctx(), which will also attempt to
traverse job->nodes, potentially finding entries that where freed
on previous iterations.

To avoid this situation, update job->nodes head on each iteration to
ensure that already freed entries are no longer linked to the list.

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1746631
Signed-off-by: Sergio Lopez <slp@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190911100316.32282-1-mreitz@redhat.com
Reviewed-by: Sergio Lopez <slp@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit d876bf676f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Peter Lieven 6cb3e9e4f1 block/nfs: tear down aio before nfs_close
nfs_close is a sync call from libnfs and has its own event
handler polling on the nfs FD. Avoid that both QEMU and libnfs
are intefering here.

CC: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 601dc65597)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Philippe Mathieu-Daudé c24d971c13 block/create: Do not abort if a block driver is not available
The 'blockdev-create' QMP command was introduced as experimental
feature in commit b0292b851b, using the assert() debug call.
It got promoted to 'stable' command in 3fb588a0f2, but the
assert call was not removed.

Some block drivers are optional, and bdrv_find_format() might
return a NULL value, triggering the assertion.

Stable code is not expected to abort, so return an error instead.

This is easily reproducible when libnfs is not installed:

  ./configure
  [...]
  module support    no
  Block whitelist (rw)
  Block whitelist (ro)
  libiscsi support  yes
  libnfs support    no
  [...]

Start QEMU:

  $ qemu-system-x86_64 -S -qmp unix:/tmp/qemu.qmp,server,nowait

Send the 'blockdev-create' with the 'nfs' driver:

  $ ( cat << 'EOF'
  {'execute': 'qmp_capabilities'}
  {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'}
  EOF
  ) | socat STDIO UNIX:/tmp/qemu.qmp
  {"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 4}, "package": "v4.1.0-733-g89ea03a7dc"}, "capabilities": ["oob"]}}
  {"return": {}}

QEMU crashes:

  $ gdb qemu-system-x86_64 core
  Program received signal SIGSEGV, Segmentation fault.
  (gdb) bt
  #0  0x00007ffff510957f in raise () at /lib64/libc.so.6
  #1  0x00007ffff50f3895 in abort () at /lib64/libc.so.6
  #2  0x00007ffff50f3769 in _nl_load_domain.cold.0 () at /lib64/libc.so.6
  #3  0x00007ffff5101a26 in .annobin_assert.c_end () at /lib64/libc.so.6
  #4  0x0000555555d7e1f1 in qmp_blockdev_create (job_id=0x555556baee40 "x", options=0x555557666610, errp=0x7fffffffc770) at block/create.c:69
  #5  0x0000555555c96b52 in qmp_marshal_blockdev_create (args=0x7fffdc003830, ret=0x7fffffffc7f8, errp=0x7fffffffc7f0) at qapi/qapi-commands-block-core.c:1314
  #6  0x0000555555deb0a0 in do_qmp_dispatch (cmds=0x55555645de70 <qmp_commands>, request=0x7fffdc005c70, allow_oob=false, errp=0x7fffffffc898) at qapi/qmp-dispatch.c:131
  #7  0x0000555555deb2a1 in qmp_dispatch (cmds=0x55555645de70 <qmp_commands>, request=0x7fffdc005c70, allow_oob=false) at qapi/qmp-dispatch.c:174

With this patch applied, QEMU returns a QMP error:

  {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'}
  {"id": "x", "error": {"class": "GenericError", "desc": "Block driver 'nfs' not found or not supported"}}

Cc: qemu-stable@nongnu.org
Reported-by: Xu Tian <xutian@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d90d5cae2b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Johannes Berg ce9c8f6767 libvhost-user: fix SLAVE_SEND_FD handling
It doesn't look like this could possibly work properly since
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD is defined to 10, but the
dev->protocol_features has a bitmap. I suppose the peer this
was tested with also supported VHOST_USER_PROTOCOL_F_LOG_SHMFD,
in which case the test would always be false, but nevertheless
the code seems wrong.

Use has_feature() to fix this.

Fixes: d84599f56c ("libvhost-user: support host notifier")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Message-Id: <20190903200422.11693-1-johannes@sipsolutions.net>
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 8726b70b44)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz e40124c487 iotests: Test blockdev-create for vpc
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit cb73747e1a)
 Conflicts:
	tests/qemu-iotests/group
*drop context dep. on tests not in 4.0
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 491bf15671 iotests: Restrict nbd Python tests to nbd
We have two Python unittest-style tests that test NBD.  As such, they
should specify supported_protocols=['nbd'] so they are skipped when the
user wants to test some other protocol.

Furthermore, we should restrict their choice of formats to 'raw'.  The
idea of a protocol/format combination is to use some format over some
protocol; but we always use the raw format over NBD.  It does not really
matter what the NBD server uses on its end, and it is not a useful test
of the respective format driver anyway.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 7c932a1d69)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz f949655dd3 iotests: Restrict file Python tests to file
Most of our Python unittest-style tests only support the file protocol.
You can run them with any other protocol, but the test will simply
ignore your choice and use file anyway.

We should let them signal that they require the file protocol so they
are skipped when you want to test some other protocol.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 103cbc771e)
 Conflicts:
	tests/qemu-iotests/257
*drop changes for test 257, not present in 4.0
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 89e4faa9ca iotests: Add supported protocols to execute_test()
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 88d2aa533a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 43143d5d91 vpc: Return 0 from vpc_co_create() on success
blockdev_create_run() directly uses .bdrv_co_create()'s return value as
the job's return value.  Jobs must return 0 on success, not just any
nonnegative value.  Therefore, using blockdev-create for VPC images may
currently fail as the vpc driver may return a positive integer.

Because there is no point in returning a positive integer anywhere in
the block layer (all non-negative integers are generally treated as
complete success), we probably do not want to add more such cases.
Therefore, fix this problem by making the vpc driver always return 0 in
case of success.

Suggested-by: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 1a37e31244)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
John Snow 88a2ea5a48 iotests: add testing shim for script-style python tests
Because the new-style python tests don't use the iotests.main() test
launcher, we don't turn on the debugger logging for these scripts
when invoked via ./check -d.

Refactor the launcher shim into new and old style shims so that they
share environmental configuration.

Two cleanup notes: debug was not actually used as a global, and there
was no reason to create a class in an inner scope just to achieve
default variables; we can simply create an instance of the runner with
the values we want instead.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190709232550.10724-14-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 456a2d5ac7)
*prereq for 1a37e31244/88d2aa533a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Markus Armbruster 83f9b84c8b pr-manager: Fix invalid g_free() crash bug
pr_manager_worker() passes its @opaque argument to g_free().  Wrong;
it points to pr_manager_worker()'s automatic @data.  Broken when
commit 2f3a7ab39b converted @data from heap- to stack-allocated.  Fix
by deleting the g_free().

Fixes: 2f3a7ab39b
Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6b9d62c2a9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Anthony PERARD 434a15214f xen-bus: Fix backend state transition on device reset
When a frontend wants to reset its state and the backend one, it
starts with setting "Closing", then waits for the backend (QEMU) to do
the same.

But when QEMU is setting "Closing" to its state, it triggers an event
(xenstore watch) that re-execute xen_device_backend_changed() and set
the backend state to "Closed". QEMU should wait for the frontend to
set "Closed" before doing the same.

Before setting "Closed" to the backend_state, we are also going to
check if there is a frontend. If that the case, when the backend state
is set to "Closing" the frontend should react and sets its state to
"Closing" then "Closed". The backend should wait for that to happen.

Fixes: b6af8926fb
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
Message-Id: <20190823101534.465-2-anthony.perard@citrix.com>
(cherry picked from commit cb32314607)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Peter Maydell 0570d468b7 target/arm: Don't abort on M-profile exception return in linux-user mode
An attempt to do an exception-return (branch to one of the magic
addresses) in linux-user mode for M-profile should behave like
a normal branch, because linux-user mode is always going to be
in 'handler' mode. This used to work, but we broke it when we added
support for the M-profile security extension in commit d02a8698d7.

In that commit we allowed even handler-mode calls to magic return
values to be checked for and dealt with by causing an
EXCP_EXCEPTION_EXIT exception to be taken, because this is
needed for the FNC_RETURN return-from-non-secure-function-call
handling. For system mode we added a check in do_v7m_exception_exit()
to make any spurious calls from Handler mode behave correctly, but
forgot that linux-user mode would also be affected.

How an attempted return-from-non-secure-function-call in linux-user
mode should be handled is not clear -- on real hardware it would
result in return to secure code (not to the Linux kernel) which
could then handle the error in any way it chose. For QEMU we take
the simple approach of treating this erroneous return the same way
it would be handled on a CPU without the security extensions --
treat it as a normal branch.

The upshot of all this is that for linux-user mode we should never
do any of the bx_excret magic, so the code change is simple.

This ought to be a weird corner case that only affects broken guest
code (because Linux user processes should never be attempting to do
exception returns or NS function returns), except that the code that
assigns addresses in RAM for the process and stack in our linux-user
code does not attempt to avoid this magic address range, so
legitimate code attempting to return to a trampoline routine on the
stack can fall into this case. This change fixes those programs,
but we should also look at restricting the range of memory we
use for M-profile linux-user guests to the area that would be
real RAM in hardware.

Cc: qemu-stable@nongnu.org
Reported-by: Christophe Lyon <christophe.lyon@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20190822131534.16602-1-peter.maydell@linaro.org
Fixes: https://bugs.launchpad.net/qemu/+bug/1840922
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 5e5584c89f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Paolo Bonzini 53c641048e dma-helpers: ensure AIO callback is invoked after cancellation
dma_aio_cancel unschedules the BH if there is one, which corresponds
to the reschedule_dma case of dma_blk_cb.  This can stall the DMA
permanently, because dma_complete will never get invoked and therefore
nobody will ever invoke the original AIO callback in dbs->common.cb.

Fix this by invoking the callback (which is ensured to happen after
a bdrv_aio_cancel_async, or done manually in the dbs->bh case), and
add assertions to check that the DMA state machine is indeed waiting
for dma_complete or reschedule_dma, but never both.

Reported-by: John Snow <jsnow@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 20190729213416.1972-1-pbonzini@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 539343c0a4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Alberto Garcia cb7630af20 qcow2: Fix the calculation of the maximum L2 cache size
The size of the qcow2 L2 cache defaults to 32 MB, which can be easily
larger than the maximum amount of L2 metadata that the image can have.
For example: with 64 KB clusters the user would need a qcow2 image
with a virtual size of 256 GB in order to have 32 MB of L2 metadata.

Because of that, since commit b749562d98
we forbid the L2 cache to become larger than the maximum amount of L2
metadata for the image, calculated using this formula:

    uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);

The problem with this formula is that the result should be rounded up
to the cluster size because an L2 table on disk always takes one full
cluster.

For example, a 1280 MB qcow2 image with 64 KB clusters needs exactly
160 KB of L2 metadata, but we need 192 KB on disk (3 clusters) even if
the last 32 KB of those are not going to be used.

However QEMU rounds the numbers down and only creates 2 cache tables
(128 KB), which is not enough for the image.

A quick test doing 4KB random writes on a 1280 MB image gives me
around 500 IOPS, while with the correct cache size I get 16K IOPS.

Cc: qemu-stable@nongnu.org
Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b70d08205b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
John Snow 107018c4fd Revert "ide/ahci: Check for -ECANCELED in aio callbacks"
This reverts commit 0d910cfeaf.

It's not correct to just ignore an error code in a callback; we need to
handle that error and possible report failure to the guest so that they
don't wait indefinitely for an operation that will now never finish.

This ought to help cases reported by Nutanix where iSCSI returns a
legitimate -ECANCELED for certain operations which should be propagated
normally.

Reported-by: Shaju Abraham <shaju.abraham@nutanix.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190729223605.7163-1-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 8ec41c4265)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Vladimir Sementsov-Ogievskiy 7d4b467790 block/backup: disable copy_range for compressed backup
Enabled by default copy_range ignores compress option. It's definitely
unexpected for user.

It's broken since introduction of copy_range usage in backup in
9ded4a0114.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190730163251.755248-3-vsementsov@virtuozzo.com
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 110571be4e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 5a35dbf228 iotests: Test unaligned blocking mirror write
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190805113526.20319-1-mreitz@redhat.com
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 19ba4651fe)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz d65d02614b mirror: Only mirror granularity-aligned chunks
In write-blocking mode, all writes to the top node directly go to the
target.  We must only mirror chunks of data that are aligned to the
job's granularity, because that is how the dirty bitmap works.
Therefore, the request alignment for writes must be the job's
granularity (in write-blocking mode).

Unfortunately, this forces all reads and writes to have the same
granularity (we only need this alignment for writes to the target, not
the source), but that is something to be fixed another time.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190805153308.2657-1-mreitz@redhat.com
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Fixes: d06107ade0
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 9adc1cb49a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz f69d8f2347 iotests: Test incremental backup after truncation
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190805152840.32190-1-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 8a9cb86408)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Vladimir Sementsov-Ogievskiy fc5c701636 util/hbitmap: update orig_size on truncate
Without this, hbitmap_next_zero and hbitmap_next_dirty_area are broken
after truncate. So, orig_size is broken since it's introduction in
76d570dc49.

Fixes: 76d570dc49
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190805120120.23585-1-vsementsov@virtuozzo.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 4e4de22279)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz c430d7684e iotests: Test backup job with two guest writes
Perform two guest writes to not yet backed up areas of an image, where
the former touches an inner area of the latter.

Before HEAD^, copy offloading broke this in two ways:
(1) The target image differs from the reference image (what the source
    was when the backup started).
(2) But you will not see that in the failing output, because the job
    offset is reported as being greater than the job length.  This is
    because one cluster is copied twice, and thus accounted for twice,
    but of course the job length does not increase.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190801173900.23851-3-mreitz@redhat.com
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Tested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 5f594a2e99)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Max Reitz 70353442db backup: Copy only dirty areas
The backup job must only copy areas that the copy_bitmap reports as
dirty.  This is always the case when using traditional non-offloading
backup, because it copies each cluster separately.  When offloading the
copy operation, we sometimes copy more than one cluster at a time, but
we only check whether the first one is dirty.

Therefore, whenever copy offloading is possible, the backup job
currently produces wrong output when the guest writes to an area of
which an inner part has already been backed up, because that inner part
will be re-copied.

Fixes: 9ded4a0114
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190801173900.23851-2-mreitz@redhat.com
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 4a5b91ca02)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Vladimir Sementsov-Ogievskiy 872b7b8ef9 block/backup: refactor: split out backup_calculate_cluster_size
Split out cluster_size calculation. Move copy-bitmap creation above
block-job creation, as we are going to share it with upcoming
backup-top filter, which also should be created before actual block job
creation.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190429090842.57910-6-vsementsov@virtuozzo.com
[mreitz: Dropped a paragraph from the commit message that was left over
         from a previous version]
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit ae6b12fa4c)
*prereq for 110571be4e
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Vladimir Sementsov-Ogievskiy 54d45c8251 block/backup: unify different modes code path
Do full, top and incremental mode copying all in one place. This
unifies the code path and helps further improvements.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190429090842.57910-5-vsementsov@virtuozzo.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit c334e897d0)
*prereq for 110571be4e
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Vladimir Sementsov-Ogievskiy 87851171b4 block/backup: refactor and tolerate unallocated cluster skipping
Split allocation checking to separate function and reduce nesting.
Consider bdrv_is_allocated() fail as allocated area, as copying more
than needed is not wrong (and we do it anyway) and seems better than
fail the whole job. And, most probably we will fail on the next read,
if there are real problem with source.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190429090842.57910-4-vsementsov@virtuozzo.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 9eb5a248f3)
*prereq for 110571be4e
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Vladimir Sementsov-Ogievskiy 3f6c00eb61 block/backup: move to copy_bitmap with granularity
We are going to share this bitmap between backup and backup-top filter
driver, so let's share something more meaningful. It also simplifies
some calculations.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190429090842.57910-3-vsementsov@virtuozzo.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit a8389e315e)
*prereq for 4a5b91ca
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Vladimir Sementsov-Ogievskiy 0b55b27908 block/backup: simplify backup_incremental_init_copy_bitmap
Simplify backup_incremental_init_copy_bitmap using the function
bdrv_dirty_bitmap_next_dirty_area.

Note: move to job->len instead of bitmap size: it should not matter but
less code.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190429090842.57910-2-vsementsov@virtuozzo.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit c2da3413c0)
*prereq for 4a5b91ca
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Stefan Berger 6210ff6aa2 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-10-01 16:58:28 -05:00
Stefan Berger 0647727e47 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-10-01 16:58:28 -05:00
Evgeny Yakovlev d7e9b19f0b 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-10-01 16:58:28 -05:00
Michael S. Tsirkin c4ac494578 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-10-01 16:58:28 -05:00
David Hildenbrand f18bce29e1 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-10-01 16:58:28 -05:00
David Hildenbrand 8e20acad63 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)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
David Hildenbrand d0444b1ee3 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-10-01 16:58:28 -05:00
David Hildenbrand b50aab6b83 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-10-01 16:58:28 -05:00
David Hildenbrand 2c743c8522 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-10-01 16:58:28 -05:00
David Hildenbrand 04e35fe3c4 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-10-01 16:58:28 -05:00
David Hildenbrand 912440beb5 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-10-01 16:58:28 -05:00
Evgeny Yakovlev eeb25956e7 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-10-01 16:58:28 -05:00
Jan Kiszka d25b37247d 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-10-01 16:58:28 -05:00
Philippe Mathieu-Daudé 5ad70231d3 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-10-01 16:58:28 -05:00
Philippe Mathieu-Daudé 804a0ae6c0 hw/ssi/xilinx_spips: Avoid AXI writes to the LQSPI linear memory
Lei Sun found while auditing the code that a CPU write would
trigger a NULL pointer dereference.

>From UG1085 datasheet [*] AXI writes in this region are ignored
and generates an AXI Slave Error (SLVERR).

Fix by implementing the write_with_attrs() handler.
Return MEMTX_ERROR when the region is accessed (this error maps
to an AXI slave error).

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

Reported-by: Lei Sun <slei.casper@gmail.com>
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 936a236c4e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Philippe Mathieu-Daudé 255325da13 hw/ssi/xilinx_spips: Convert lqspi_read() to read_with_attrs
In the next commit we will implement the write_with_attrs()
handler. To avoid using different APIs, convert the read()
handler first.

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 5937bd50d3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
John Snow e11cd43f24 docs/bitmaps: use QMP lexer instead of json
The annotated style json we use in QMP documentation is not strict json
and depending on the version of Sphinx (2.0+) or Pygments installed,
might cause the build to fail.

Use the new QMP lexer.

Further, some versions of Sphinx can not apply custom lexers to "code"
directives and require the use of "code-block" directives instead, so
make that change at this time as well.

Tested under:
- Sphinx 1.3.6 and Pygments 2.4
- Sphinx 1.7.6 and Pygments 2.2 (Fedora 29 packages)
- Sphinx 2.0.1 and Pygments 2.4
- Sphinx 3.0.0+/f396b3a783 and Pygments 2.4 (From Sphinx git c4f44bdd)

Reported-by: Aarushi Mehta <mehta.aaru20@gmail.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Message-id: 20190603214653.29369-4-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit a7786bfb0e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
John Snow 22a03c48e7 sphinx: add qmp_lexer
Sphinx, through Pygments, does not like annotated json examples very
much. In some versions of Sphinx (1.7), it will render the non-json
portions of code blocks in red, but in newer versions (2.0) it will
throw an exception and not highlight the block at all. Though we can
suppress this warning, it doesn't bring back highlighting on non-strict
json blocks.

We can alleviate this by creating a custom lexer for QMP examples that
allows us to properly highlight these examples in a robust way, keeping
our directionality and elision notations.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reported-by: Aarushi Mehta <mehta.aaru20@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20190603214653.29369-3-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit cd231e13bd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
John Snow e653d5ed18 docs/interop/bitmaps.rst: Fix typos
Pygments and Sphinx get pickier all the time; Sphinx 2.1+ now catches
these errors.

Signed-off-by: John Snow <jsnow@redhat.com>
Reported-by: Aarushi Mehta <mehta.aaru20@gmail.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190603214653.29369-2-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 575e622628)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Stefan Hajnoczi a6fe4a3aa8 virtio-balloon: fix QEMU 4.0 config size migration incompatibility
The virtio-balloon config size changed in QEMU 4.0 even for existing
machine types.  Migration from QEMU 3.1 to 4.0 can fail in some
circumstances with the following error:

  qemu-system-x86_64: get_pci_config_device: Bad config data: i=0x10 read: a1 device: 1 cmask: ff wmask: c0 w1cmask:0

This happens because the virtio-balloon config size affects the VIRTIO
Legacy I/O Memory PCI BAR size.

Introduce a qdev property called "qemu-4-0-config-size" and enable it
only for the QEMU 4.0 machine types.  This way <4.0 machine types use
the old size, 4.0 uses the larger size, and >4.0 machine types use the
appropriate size depending on enabled virtio-balloon features.

Live migration to and from old QEMUs to QEMU 4.1 works again as long as
a versioned machine type is specified (do not use just "pc"!).

Originally-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20190710141440.27635-1-stefanha@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Tested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Tested-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2bbadb08ce)
 Conflicts:
	hw/core/machine.c
* drop context dep. on 0a71966253
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Marc-André Lureau e86e620656 usbredir: fix buffer-overflow on vmload
If interface_count is NO_INTERFACE_INFO, let's not access the arrays
out-of-bounds.

==994==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x625000243930 at pc 0x5642068086a8 bp 0x7f0b6f9ffa50 sp 0x7f0b6f9ffa40
READ of size 1 at 0x625000243930 thread T0
    #0 0x5642068086a7 in usbredir_check_bulk_receiving /home/elmarco/src/qemu/hw/usb/redirect.c:1503
    #1 0x56420681301c in usbredir_post_load /home/elmarco/src/qemu/hw/usb/redirect.c:2154
    #2 0x5642068a56c2 in vmstate_load_state /home/elmarco/src/qemu/migration/vmstate.c:168
    #3 0x56420688e2ac in vmstate_load /home/elmarco/src/qemu/migration/savevm.c:829
    #4 0x5642068980cb in qemu_loadvm_section_start_full /home/elmarco/src/qemu/migration/savevm.c:2211
    #5 0x564206899645 in qemu_loadvm_state_main /home/elmarco/src/qemu/migration/savevm.c:2395
    #6 0x5642068998cf in qemu_loadvm_state /home/elmarco/src/qemu/migration/savevm.c:2467
    #7 0x56420685f3e9 in process_incoming_migration_co /home/elmarco/src/qemu/migration/migration.c:449
    #8 0x564207106c47 in coroutine_trampoline /home/elmarco/src/qemu/util/coroutine-ucontext.c:115
    #9 0x7f0c0604e37f  (/lib64/libc.so.6+0x4d37f)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Liam Merwick <liam.merwick@oracle.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190807084048.4258-1-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 7b84b90966)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Marc-André Lureau 32e8ac8a28 virtio-pci: fix missing device properties
Since commit a4ee4c8baa ("virtio: Helper for registering virtio
device types"), virtio-gpu-pci, virtio-vga, and virtio-crypto-pci lost
some properties: "ioeventfd" and "vectors". This may cause various
issues, such as failing migration or invalid properties.

Since those VirtioPCI devices do not have a base name, their class are
initialized with virtio_pci_generic_base_class_init(). However, if the
VirtioPCIDeviceTypeInfo provided a class_init which sets dc->props,
the properties were overwritten by virtio_pci_generic_class_init().

Instead, introduce an intermediary base-type to register the generic
properties.

Fixes: a4ee4c8baa
Cc: qemu-stable@nongnu.org
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20190625232333.30752-1-marcandre.lureau@redhat.com>
(cherry picked from commit 683c1d89ef)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Daniel P. Berrangé 8da804f4f9 docs: recommend use of md-clear feature on all Intel CPUs
Update x86 CPU model guidance to recommend that the md-clear feature is
manually enabled with all Intel CPU models, when supported by the host
microcode.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20190515141011.5315-3-berrange@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 2c7e82a307)
Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Paolo Bonzini 7427060f98 target/i386: define md-clear bit
md-clear is a new CPUID bit which is set when microcode provides the
mechanism to invoke a flush of various exploitable CPU buffers by invoking
the VERW instruction.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20190515141011.5315-2-berrange@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit b2ae52101f)
Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Paolo Bonzini 41e1564fb5 target/i386: add MDS-NO feature
Microarchitectural Data Sampling is a hardware vulnerability which allows
unprivileged speculative access to data which is available in various CPU
internal buffers.

Some Intel processors use the ARCH_CAP_MDS_NO bit in the
IA32_ARCH_CAPABILITIES
MSR to report that they are not vulnerable, make it available to guests.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20190516185320.28340-1-pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 20140a82c6)
Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Markus Armbruster 8e29c657ca vl: Fix -drive / -blockdev persistent reservation management
qemu-system-FOO's main() acts on command line arguments in its own
idiosyncratic order.  There's not much method to its madness.
Whenever we find a case where one kind of command line argument needs
to refer to something created for another kind later, we rejigger the
order.

Recent commit cda4aa9a5a "vl: Create block backends before setting
machine properties" was such a rejigger.  Block backends are now
created before "delayed" objects.  This broke persistent reservation
management.  Reproducer:

    $ qemu-system-x86_64 -object pr-manager-helper,id=pr-helper0,path=/tmp/pr-helper0.sock-drive -drive file=/dev/mapper/crypt,file.pr-manager=pr-helper0,format=raw,if=none,id=drive-scsi0-0-0-2
    qemu-system-x86_64: -drive file=/dev/mapper/crypt,file.pr-manager=pr-helper0,format=raw,if=none,id=drive-scsi0-0-0-2: No persistent reservation manager with id 'pr-helper0'

The delayed pr-manager-helper object is created too late for use by
-drive or -blockdev.  Normal objects are still created in time.

pr-manager-helper has always been a delayed object (commit 7c9e527659
"scsi, file-posix: add support for persistent reservation
management").  Turns out there's no real reason for that.  Make it a
normal object.

Fixes: cda4aa9a5a
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20190604151251.9903-2-armbru@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9ea18ed25a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:58:28 -05:00
Alex Williamson 92fa1b1a28 q35: Revert to kernel irqchip
Backport of QEMU v4.1 commit for stable v4.0.1 release

commit c87759ce87
Author: Alex Williamson <alex.williamson@redhat.com>
Date:   Tue May 14 14:14:41 2019 -0600

    q35: Revert to kernel irqchip

    Commit b2fc91db84 ("q35: set split kernel irqchip as default") changed
    the default for the pc-q35-4.0 machine type to use split irqchip, which
    turned out to have disasterous effects on vfio-pci INTx support.  KVM
    resampling irqfds are registered for handling these interrupts, but
    these are non-functional in split irqchip mode.  We can't simply test
    for split irqchip in QEMU as userspace handling of this interrupt is a
    significant performance regression versus KVM handling (GeForce GPUs
    assigned to Windows VMs are non-functional without forcing MSI mode or
    re-enabling kernel irqchip).

    The resolution is to revert the change in default irqchip mode in the
    pc-q35-4.1 machine and create a pc-q35-4.0.1 machine for the 4.0-stable
    branch.  The qemu-q35-4.0 machine type should not be used in vfio-pci
    configurations for devices requiring legacy INTx support without
    explicitly modifying the VM configuration to use kernel irqchip.

Link: https://bugs.launchpad.net/qemu/+bug/1826422
Fixes: b2fc91db84 ("q35: set split kernel irqchip as default")
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
(upstream commit c87759ce87)
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
*add comments regarding AML mismatch warnings from
 tests/bios-tables-test.c
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-10-01 16:57:54 -05:00
Anton Blanchard 75f83e7c4a target/ppc: Fix lxvw4x, lxvh8x and lxvb16x
During the conversion these instructions were incorrectly treated as
stores. We need to use set_cpu_vsr* and not get_cpu_vsr*.

Fixes: 8b3b2d75c7 ("introduce get_cpu_vsr{l,h}() and set_cpu_vsr{l,h}() helpers for VSR register access")
Signed-off-by: Anton Blanchard <anton@ozlabs.org>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Message-Id: <20190524065345.25591-1-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(upstream commit 2a12243590)
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 15:17:04 -05:00
Anton Blanchard b6159fc9a6 target/ppc: Fix vsum2sws
A recent cleanup changed the pre zeroing of the result from 64 bit
to 32 bit operations:

-        result.u64[i] = 0;
+        result.VsrW(i) = 0;

This corrupts the result.

Fixes: 60594fea29 ("target/ppc: remove various HOST_WORDS_BIGENDIAN hacks in int_helper.c")
Signed-off-by: Anton Blanchard <anton@ozlabs.org>
Message-Id: <20190507004811.29968-9-anton@ozlabs.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(upstream commit 7fa0ddc1d6)
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 15:16:58 -05:00
Anton Blanchard da3bd13802 target/ppc: Fix xxbrq, xxbrw
Fix a typo in xxbrq and xxbrw where we put both results into the lower
doubleword.

Fixes: 8b3b2d75c7 ("introduce get_cpu_vsr{l,h}() and set_cpu_vsr{l,h}() helpers for VSR register access")
Signed-off-by: Anton Blanchard <anton@ozlabs.org>
Message-Id: <20190507004811.29968-3-anton@ozlabs.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(upstream commit d47a751ada)
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 15:14:57 -05:00
Anton Blanchard fd72de9047 target/ppc: Fix xvxsigdp
Fix a typo in xvxsigdp where we put both results into the lower
doubleword.

Fixes: dd977e4f45 ("target/ppc: Optimize x[sv]xsigdp using deposit_i64()")
Signed-off-by: Anton Blanchard <anton@ozlabs.org>
Message-Id: <20190507004811.29968-1-anton@ozlabs.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(upstream commit cf4e9363f7)
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 15:14:05 -05:00
Anton Blanchard 14c9bbab09 target/ppc: Fix xvabs[sd]p, xvnabs[sd]p, xvneg[sd]p, xvcpsgn[sd]p
We were using set_cpu_vsr*() when we should have used get_cpu_vsr*().

Fixes: 8b3b2d75c7 ("introduce get_cpu_vsr{l,h}() and set_cpu_vsr{l,h}() helpers for VSR register access")
Signed-off-by: Anton Blanchard <anton@ozlabs.org>
Message-Id: <20190509104912.6b754dff@kryten>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(upstream commit 77bd8937c0)
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 15:11:23 -05:00
Li Hangjing 1cf90f8a97 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-09-17 15:06:55 -05:00
John Snow 3a87d07722 migration/dirty-bitmaps: change bitmap enumeration method
Shift from looking at every root BDS to *every* BDS. This will migrate
bitmaps that are attached to blockdev created nodes instead of just ones
attached to emulated storage devices.

Note that this will not migrate anonymous or internal-use bitmaps, as
those are defined as having no name.

This will also fix the Coverity issues Peter Maydell has been asking
about for the past several releases, as well as fixing a real bug.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Reported-by: Coverity 😅
Reported-by: aihua liang <aliang@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190514201926.10407-1-jsnow@redhat.com
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1652490
Fixes: Coverity CID 1390625
CC: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 592203e7cf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 15:00:31 -05:00
John Snow 07cc0a207f iotests: add iotest 256 for testing blockdev-backup across iothread contexts
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190523170643.20794-6-jsnow@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[mreitz: Moved from 250 to 256]
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit ba7704f222)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:58:48 -05:00
John Snow 32097f14fc iotests.py: rewrite run_job to be pickier
Don't pull events out of the queue that don't belong to us;
be choosier so that we can use this method to drive jobs that
were launched by transactions that may have more jobs.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190523170643.20794-5-jsnow@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit d6a79af0e6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:58:36 -05:00
Max Reitz 2ab69df8db iotests.py: Fix VM.run_job
log() is in the current module, there is no need to prefix it.  In fact,
doing so may make VM.run_job() unusable in tests that never use
iotests.log() themselves.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 86a4f599a6)
*prereq for d6a79af0e6
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:58:36 -05:00
John Snow c7b4a73541 QEMUMachine: add events_wait method
Instead of event_wait which looks for a single event, add an events_wait
which can look for any number of events simultaneously. However, it
will still only return one at a time, whichever happens first.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190523170643.20794-4-jsnow@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit f6f4b3f045)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:58:36 -05:00
John Snow 94a14e6f2a iotests.py: do not use infinite waits
Cap waits to 60 seconds so that iotests can fail gracefully if something
goes wrong.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190523170643.20794-3-jsnow@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 8b6f5f8b9f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:58:36 -05:00
Kevin Wolf 7415a83e9b iotests: Test commit job start with concurrent I/O
This tests that concurrent requests are correctly drained before making
graph modifications instead of running into assertions in
bdrv_replace_node().

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit ac6fb43eae)
 Conflicts:
	tests/qemu-iotests/group
*prereq for d81e1efb tests
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:58:18 -05:00
Kevin Wolf 627fadfa1c block: Drain source node in bdrv_replace_node()
Instead of just asserting that no requests are in flight in
bdrv_replace_node(), which is a requirement that most callers ignore, we
can just drain the source node right there. This fixes at least starting
a commit job while I/O is active on the backing chain, but probably
other callers, too.

Having requests in flight on the target node isn't a problem because the
target just gets new parents, but the call path of running requests
isn't modified. So we can just drop this assertion without a replacement.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1711643
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit f871abd60f)
*prereq for d81e1efb tests
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:46:39 -05:00
John Snow 2429dc4eea blockdev-backup: don't check aio_context too early
in blockdev_backup_prepare, we check to make sure that the target is
associated with a compatible aio context. However, do_blockdev_backup is
called later and has some logic to move the target to a compatible
aio_context. The transaction version will fail certain commands
needlessly early as a result.

Allow blockdev_backup_prepare to simply call do_blockdev_backup, which
will ultimately decide if the contexts are compatible or not.

Note: the transaction version has always disallowed this operation since
its initial commit bd8baecd (2014), whereas the version of
qmp_blockdev_backup at the time, from commit c29c1dd312, tried to
enforce the aio_context switch instead. It's not clear, and I can't see
from the mailing list archives at the time, why the two functions take a
different approach. It wasn't until later in efd7556708 (2016) that the
standalone version tried to determine if it could set the context or
not.

Reported-by: aihua liang <aliang@redhat.com>
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1683498
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190523170643.20794-2-jsnow@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit d81e1efbea)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:38:18 -05:00
Christian Borntraeger f8d98e2b6d 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-09-17 14:36:35 -05:00
Max Reitz d8328a3ca5 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)
 Conflicts:
	tests/qemu-iotests/group
*fix context deps on test groups not in 4.0

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:35:03 -05:00
Max Reitz 241d89b760 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-09-17 14:34:13 -05:00
Gerd Hoffmann 665218cc08 usb-tablet: fix serial compat property
s/kbd/tablet/, fixes cut+paste bug.

Cc: qemu-stable@nongnu.org
Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520081805.15019-1-kraxel@redhat.com
(cherry picked from commit 442bac16a6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:32:54 -05:00
Gerd Hoffmann a68ab7c88f kbd-state: fix autorepeat handling
When allowing multiple down-events in a row (key autorepeat) we can't
use change_bit() any more to update the state, because autorepeat events
don't change the key state.  We have to explicitly use set_bit() and
clear_bit() instead.

Cc: qemu-stable@nongnu.org
Fixes: 3592186015 kbd-state: don't block auto-repeat events
Buglink: https://bugs.launchpad.net/qemu/+bug/1828272
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20190514042443.10735-1-kraxel@redhat.com
(cherry picked from commit 5fff13f245)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:31:50 -05:00
Cédric Le Goater ffabb55ec2 spapr/xive: fix EQ page addresses above 64GB
The high order bits of the address of the OS event queue is stored in
bits [4-31] of word2 of the XIVE END internal structures and the low
order bits in word3. This structure is using Big Endian ordering and
computing the value requires some simple arithmetic which happens to
be wrong. The mask removing bits [0-3] of word2 is applied to the
wrong value and the resulting address is bogus when above 64GB.

Guests with more than 64GB of RAM will allocate pages for the OS event
queues which will reside above the 64GB limit. In this case, the XIVE
device model will wake up the CPUs in case of a notification, such as
IPIs, but the update of the event queue will be written at the wrong
place in memory. The result is uncertain as the guest memory is
trashed and IPI are not delivered.

Introduce a helper xive_end_qaddr() to compute this value correctly in
all places where it is used.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20190508171946.657-3-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 13df93244e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:31:24 -05:00
John Snow 2974d63658 docs/interop/bitmaps: rewrite and modernize doc
This just about rewrites the entirety of the bitmaps.rst document to
make it consistent with the 4.0 release. I have added new features seen
in the 4.0 release, as well as tried to clarify some points that keep
coming up when discussing this feature both in-house and upstream.

It does not yet cover pull backups or migration details, but I intend to
keep extending this document to cover those cases.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190426221528.30293-3-jsnow@redhat.com
[Adjusted commit message. --js]
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 90edef80a0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:26:39 -05:00
John Snow da436b77d8 Makefile: add nit-picky mode to sphinx-build
If we add references that don't resolve (or accidentally remove them),
it will be helpful to have warning messages alerting us to that.

Further, turn those warnings into errors so we can be alerted to these
problems sooner rather than later.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190426221528.30293-2-jsnow@redhat.com
[adjusted commit message. --js]
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 9e5b6cb87d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:26:33 -05:00
Eric Blake 48025d942e 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-09-17 14:23:34 -05:00
Kevin Wolf 626a95f4aa 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)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:23:20 -05:00
Kevin Wolf 774f013111 qcow2: Fix qcow2_make_empty() with external data file
make_completely_empty() is an optimisated path for bdrv_make_empty()
where completely new metadata is created inside the image file instead
of going through all clusters and discarding them. For an external data
file, however, we actually need to do discard operations on the data
file; just overwriting the qcow2 file doesn't get rid of the data.

The necessary slow path with an explicit discard operation already
exists for other cases. Use it for external data files, too.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit db04524f82)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 14:22:27 -05:00
Peter Lieven 173e30de4c 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-09-17 14:21:41 -05:00
Kevin Wolf 4382e8da22 qcow2: Fix full preallocation with external data file
preallocate_co() already gave the data file the full size without
forwarding the requested preallocation mode to the protocol. When
bdrv_co_truncate() was called later with the preallocation mode, the
file didn't actually grow any more, so the data file stayed unallocated
even if full preallocation was requested.

Pass the right preallocation mode to preallocate_co() and remove the
second bdrv_co_truncate() to fix this. As a side effect, the ugly
one-byte write in preallocate_co() is replaced with a truncate call,
now leaving the last block unallocated on the protocol level as it
should be.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 718c0fce2f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 13:51:53 -05:00
Kevin Wolf e628c14be4 qcow2: Add errp to preallocate_co()
We'll add a bdrv_co_truncate() call in the next patch which can return
an Error that we don't want to discard. So add an errp parameter to
preallocate_co().

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 360bd07471)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 13:51:47 -05:00
Kevin Wolf 5669ef1e6c 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)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2019-09-17 13:51:40 -05:00
Peter Maydell 131b9a0570 Update version for v4.0.0 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-23 17:32:17 +01:00
Peter Maydell eeba63fc7f Update version for v4.0.0-rc4 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-16 21:53:00 +01:00
Daniel P. Berrangé 375cb86d9f usb-mtp: fix bounds check for guest provided filename
The ObjectInfo struct has a variable length array containing the UTF-16
encoded filename. The number of characters of trailing data is given by
the 'length' field in the struct and this must be validated against the
size of the data packet received from the guest.

Since the data is UTF-16, we must convert the byte count we have to a
character count before validating. This must take care to truncate if
a malicious guest sent an odd number of bytes.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-16 20:43:39 +01:00
Peter Maydell dbfc49b69a Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:

- qcow2: Fix potential corruption for preallocated resize with external data file

# gpg: Signature made Tue 16 Apr 2019 15:23:35 BST
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  qcow2: Fix preallocation bdrv_pwrite to wrong file

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-16 15:33:38 +01:00
Kevin Wolf 93e32b3e20 qcow2: Fix preallocation bdrv_pwrite to wrong file
With an external data file, preallocate_co() must write the final byte
to the external data file, not to the qcow2 image file.

This is harmless for preallocation of newly created images (only the
qcow2 file size is increased to the virtual disk size while it should be
much smaller), but with preallocated resize, it could in theory cause
visible corruption if the metadata of the image is larger than the data
(e.g. lots of bitmaps).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2019-04-16 16:23:24 +02:00
Marc-André Lureau a9b305ba29 socket: allow wait=false for client socket
Commit 767abe7 ("chardev: forbid 'wait' option with client sockets")
is a bit too strict. Current libvirt always set wait=false, and will
thus fail to add client chardev.

Make the code more permissive, allowing wait=false with client socket
chardevs. Deprecate usage of 'wait' with client sockets.

Fixes: 767abe7f49
Cc: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-id: 20190415163337.2795-1-marcandre.lureau@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-16 10:40:43 +01:00
Peter Maydell 677746b39f Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging
Slirp updates

Dr. David Alan Gilbert (1):
  slirp: Gcc 9 -O3 fix

# gpg: Signature made Mon 15 Apr 2019 19:05:39 BST
# gpg:                using RSA key E61DBB15D4172BDEC97E92D9DB550E89F0FA54F3
# gpg: Good signature from "Samuel Thibault <samuel.thibault@aquilenet.fr>" [unknown]
# gpg:                 aka "Samuel Thibault <sthibault@debian.org>" [marginal]
# gpg:                 aka "Samuel Thibault <samuel.thibault@gnu.org>" [unknown]
# gpg:                 aka "Samuel Thibault <samuel.thibault@inria.fr>" [marginal]
# gpg:                 aka "Samuel Thibault <samuel.thibault@labri.fr>" [marginal]
# gpg:                 aka "Samuel Thibault <samuel.thibault@ens-lyon.org>" [marginal]
# gpg:                 aka "Samuel Thibault <samuel.thibault@u-bordeaux.fr>" [unknown]
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 900C B024 B679 31D4 0F82  304B D017 8C76 7D06 9EE6
#      Subkey fingerprint: E61D BB15 D417 2BDE C97E  92D9 DB55 0E89 F0FA 54F3

* remotes/thibault/tags/samuel-thibault:
  slirp: Gcc 9 -O3 fix

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-16 09:27:35 +01:00
Dr. David Alan Gilbert 6fabae61a9 slirp: Gcc 9 -O3 fix
Gcc 9 needs some convincing that sopreprbuf really is going to fill
in iov in the call from soreadbuf, even though the failure case
shouldn't happen.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <20190415121740.9881-1-dgilbert@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
2019-04-15 20:01:18 +02:00
Peter Maydell afccfc0c4c Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:

- iotests fixes

# gpg: Signature made Fri 12 Apr 2019 17:04:09 BST
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  iotest: Fix 241 to run in generic directory
  iotests: Let 245 pass on tmpfs

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-12 17:06:49 +01:00
Eric Blake 9749636b00 iotest: Fix 241 to run in generic directory
Filter the qemu-nbd server output to get rid of a direct reference
to my build directory.

Fixes: e9dce9cb
Reported-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2019-04-12 18:03:01 +02:00
Max Reitz 23e1d05411 iotests: Let 245 pass on tmpfs
tmpfs does not support O_DIRECT.  Detect this case, and skip flipping
@direct if the filesystem does not support it.

Fixes: bf3e50f623
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2019-04-12 18:03:01 +02:00
John Snow 13c24edaa7 qemu-img: fix .hx and .texi disparity
It turns out that having options listed in three places continues to be
a bad idea. I'm still toying with the idea of an improved infrastructure
here, but in the meantime, another bandaid.

There are three locations:
(1) .hx file, formatted as texi
(2) .hx file, formatted as human readable.
(3) .texi file, as section headers, formatted as texi.

You can compare the two summaries within the .hx file like so:

Human-readable command summaries:
`./qemu-img --help | grep 'Command syntax' -A14`
Detokenized texi command summaries:
`grep "@item" qemu-img-cmds.hx | sed -E 's|@var\{([^\}]*?)\}|\1|g'`

You can compare the two separate texi summaries like so:

Texi command summaries:
`grep "@item" qemu-img-cmds.hx"`
Texi command headers:
grep -E "@item.*@var" qemu-img.texi | tail -14

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: 20190409210655.777-1-jsnow@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-12 14:17:10 +01:00
Gerd Hoffmann e1be98540e curses: fix wchar_t printf warning
On some systems wchar_t is "long int", on others just "int".
So go cast to "long int" and adjust the printf format accordingly.

Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190402073018.17747-1-kraxel@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-12 12:58:00 +01:00
Peter Maydell 9e4a484b4a Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.0-20190412' into staging
ppc patch queue for 2018-04-12

Here's a last minute pull request for 4.0.  Turns out my last pull
request, to fix a regression in extended config space access for the
pseries machine didn't fix things hard enough.  This PR has a single
patch which improves the fix to work in more cases.

It's a ghastly, ghastly hack, but it's simple and localized.  I
already have patches almost ready to go in 4.1 that provides a simpler
and cleaner solution to all this.

# gpg: Signature made Fri 12 Apr 2019 06:34:16 BST
# gpg:                using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-4.0-20190412:
  spapr_pci: Fix broken naming of PCI bus

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-12 11:23:14 +01:00
Greg Kurz 4560116e42 spapr_pci: Fix broken naming of PCI bus
Recent commit 5cf0d326a0 fixed a regression which was preventing the
guest to access the extended config space of a PCIe device. This was
done by introducing a new PCI bus subtype for PAPR. The original fix
was causing PCI busses to be named "spapr-pci-host-bridge-root-bus.N"
instead of "pci.N", which was making upper layers unhappy of course.
This got worked around by hardcoding the PCI bus name to "pci.0", but
this only works for the default PHB. And we're now hitting:

# qemu-system-ppc64 \
             -device spapr-pci-host-bridge,index=1 \
             -device e1000e,bus=pci.0 \
             -device e1000e,bus=pci.1
qemu-system-ppc64: -device e1000e,bus=pci.1: Bus 'pci.1' not found

David already posted some patches [1] to control PCI extended config
space accesses with a new flag in the base PCI bus class instead of
subtyping. These patches are a bit more intrusive though, and
are targetted for 4.1.

When no name is passed to pci_register_bus(), the core device code
generates a lowercase name based on the QOM typename. The typename
for the base PCI bus class is "PCI", hence the "pci.0", "pci.1"
bus names. Rename the type of the PAPR PCI bus to "pci", so that
the QOM code can generate proper names. This is a hack but it is
enough to fix the regression. And all this will be reworked properly
in 4.1.

[1] https://patchwork.ozlabs.org/project/qemu-devel/list/?series=100486

Fixes: 5cf0d326a0
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <155500034416.646888.1307366522340665522.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-04-12 12:23:02 +10:00
Peter Maydell 532cc6da74 Update version for v4.0.0-rc3 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-10 15:38:59 +01:00
Peter Maydell 6523516f32 Merge remote-tracking branch 'remotes/alistair/tags/pull-device-tree-20190409-1' into staging
Single device tree fix for 4.0

A single patch to avoid an overflow when loading device trees.

# gpg: Signature made Wed 10 Apr 2019 00:52:16 BST
# gpg:                using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full]
# Primary key fingerprint: F6C4 AC46 D493 4868 D3B8  CE8F 21E1 0D29 DF97 7054

* remotes/alistair/tags/pull-device-tree-20190409-1:
  device_tree: Fix integer overflowing in load_device_tree()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-10 08:57:19 +01:00
Markus Armbruster 065e6298a7 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>
2019-04-09 16:35:40 -07:00
Peter Maydell f151f8aca5 migration/ram.c: Fix use-after-free in multifd_recv_unfill_packet()
Coverity points out (CID 1400442) that in this code:

    if (packet->pages_alloc > p->pages->allocated) {
        multifd_pages_clear(p->pages);
        multifd_pages_init(packet->pages_alloc);
    }

we free p->pages in multifd_pages_clear() but continue to
use it in the following code. We also leak memory, because
multifd_pages_init() returns the pointer to a new MultiFDPages_t
struct but we are ignoring its return value.

Fix both of these bugs by adding the missing assignment of
the newly created struct to p->pages.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-id: 20190409151830.6024-1-peter.maydell@linaro.org
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2019-04-09 20:46:34 +01:00
Peter Maydell 4b9a21c344 Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* fixes for Alpine and SuSE
* fix crash when hot-plugging nvdimm on older machine types

# gpg: Signature made Tue 09 Apr 2019 17:34:27 BST
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  tests: Make check-block a phony target
  hw/i386/pc: Fix crash when hot-plugging nvdimm on older machine types
  include/qemu/bswap.h: Use __builtin_memcpy() in accessor functions
  roms: Allow passing configure options to the EDK2 build tools
  roms: Rename the EFIROM variable to avoid clashing with iPXE

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-09 17:36:01 +01:00
Markus Armbruster 3e20c81ed8 tests: Make check-block a phony target
Fixes: b93b63f574 "test makefile overhaul"

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190319072104.32591-1-armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-04-09 18:34:21 +02:00
Thomas Huth ae909496e9 hw/i386/pc: Fix crash when hot-plugging nvdimm on older machine types
QEMU currently crashes when you try to hot-plug an "nvdimm" device
on older machine types:

$ qemu-system-x86_64 -monitor stdio -M pc-1.1
QEMU 3.1.92 monitor - type 'help' for more information
(qemu) device_add nvdimm,id=nvdimmn1
qemu-system-x86_64: /home/thuth/devel/qemu/util/error.c:57: error_setv:
 Assertion `*errp == ((void *)0)' failed.
Aborted (core dumped)

The call to hotplug_handler_pre_plug() in pc_memory_pre_plug() has been
added recently before the check whether nvdimm is enabled. It should
be done after the check. And while we're at it, also check the errp
after the hotplug_handler_pre_plug(), otherwise errors are silently
ignored here.

Fixes: 9040e6dfa8
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20190407092314.11066-1-thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-04-09 18:34:21 +02:00
Peter Maydell 77b1757090 include/qemu/bswap.h: Use __builtin_memcpy() in accessor functions
In the accessor functions ld*_he_p() and st*_he_p() we use memcpy()
to perform a load or store to a pointer which might not be aligned
for the size of the type. We rely on the compiler to optimize this
memcpy() into an efficient load or store instruction where possible.
This is required for good performance, but at the moment it is also
required for correct operation, because some users of these functions
require that the access is atomic if the pointer is aligned, which
will only be the case if the compiler has optimized out the memcpy().
(The particular example where we discovered this is the virtio
vring_avail_idx() which calls virtio_lduw_phys_cached() which
eventually ends up calling lduw_he_p().)

Unfortunately some compile environments, such as the fortify-source
setup used in Alpine Linux, define memcpy() to a wrapper function
in a way that inhibits this compiler optimization.

The correct long-term fix here is to add a set of functions for
doing atomic accesses into AddressSpaces (and to other relevant
families of accessor functions like the virtio_*_phys_cached()
ones), and make sure that callsites which want atomic behaviour
use the correct functions.

In the meantime, switch to using __builtin_memcpy() in the
bswap.h accessor functions. This will make us robust against things
like this fortify library in the short term. In the longer term
it will mean that we don't end up with these functions being really
badly-performing even if the semantics of the out-of-line memcpy()
are correct.

Reported-by: Fernando Casas Schössow <casasfernando@outlook.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190318112938.8298-1-peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-04-09 18:34:21 +02:00
Philippe Mathieu-Daudé 1cab464136 roms: Allow passing configure options to the EDK2 build tools
Since commit f590a812c2 we build the EDK2 EfiRom utility
unconditionally.

Some distributions require to use extra compiler/linker flags,
i.e. SUSE which enforces the PIE protection (see [*]).

EDK2 build tools already provide a set of variables for that,
use them to allow the caller to easily inject compiler/linker
options..

Now build scripts can pass extra options, example:

  $ make -C roms \
      EDK2_BASETOOLS_OPTFLAGS='-fPIE' \
      efirom

[*] https://lists.opensuse.org/opensuse-factory/2017-06/msg00403.html

Reported-by: Olaf Hering <olaf@aepfle.de>
Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190409134536.15548-3-philmd@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-04-09 18:33:55 +02:00
Philippe Mathieu-Daudé d912e795e0 roms: Rename the EFIROM variable to avoid clashing with iPXE
The iPXE's 'veryclean' recipe removes $(EFIROM) even if the EFIROM
macro originates from elsewhere:

  $ git checkout f590a812c21~
  $ make -C roms clean EFIROM=$(type -P EfiRom)
  make: Entering directory '/source/qemu/roms'
  [...]
  make -C ipxe/src veryclean
  make[1]: Entering directory '/source/qemu/roms/ipxe/src'
  rm -f bin{,-*}/*.* bin{,-*}/.certificate.* bin{,-*}/.certificates.* bin{,-*}/.private_key.* bin{,-*}/errors bin{,-*}/NIC ./util/zbin ./util/elf2efi32 ./util/elf2efi64 /usr/bin/EfiRom ./util/efifatbin ./util/iccfix ./util/einfo TAGS bin{,-*}/symtab
  rm: cannot remove '/usr/bin/EfiRom': Permission denied
  make[1]: *** [Makefile.housekeeping:1564: clean] Error 1
  make[1]: Leaving directory '/source/qemu/roms/ipxe/src'
  make: *** [Makefile:152: clean] Error 2
  make: Leaving directory '/source/qemu/roms'

Before f590a812c2 this variable could be overridden or unset,
and the 'veryclean' Makefile rule would not complain.

Commit f590a812c2 enforces this variable to the Intel EfiRom
tool provided by the EDK2 project.

To avoid the name clash and make the difference between the
projects obvious, rename the variable used by the EDK2 project
as EDK2_EFIROM.

Fixes: f590a812c2
Reported-by: Olaf Hering <olaf@aepfle.de>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190409134536.15548-2-philmd@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-04-09 18:33:45 +02:00
Peter Maydell 8cb2ca3d74 target/i386: Generate #UD for LOCK on a register increment
Fix a TCG crash due to attempting an atomic increment
operation without having set up the address first.
This is a similar case to that dealt with in commit
e84fcd7f66, and we fix it in the same way.

Fixes: https://bugs.launchpad.net/qemu/+bug/1807675
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 20190328104750.25046-1-peter.maydell@linaro.org
2019-04-09 13:29:32 +01:00
Peter Maydell 120cba7ff1 Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.0-20190409' into staging
ppc patch queue 2019-04-09

This is a small, hard freeze, pull request which fixes a regression on
the pseries machine handling of PCI-E extended config space accesses.

# gpg: Signature made Tue 09 Apr 2019 08:00:36 BST
# gpg:                using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-4.0-20190409:
  spapr_pci: Fix extended config space accesses
  pci: Allow PCI bus subtypes to support extended config space accesses

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-09 12:58:50 +01:00
Peter Maydell 248987f92c Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.0-pull-request' into staging
fix gettid() clash with new glibc

# gpg: Signature made Mon 08 Apr 2019 20:36:06 BST
# gpg:                using RSA key F30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier2/tags/linux-user-for-4.0-pull-request:
  linux-user: rename gettid() to sys_gettid() to avoid clash with glibc
  linux-user: assume __NR_gettid always exists

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-09 10:02:30 +01:00
Greg Kurz 5cf0d326a0 spapr_pci: Fix extended config space accesses
The PAPR PHB acts as a legacy PCI bus but it allows PCIe extended
config space accesses anyway (for pseries-2.9 and newer machine
types).

Introduce a specific PCI bus subtype to inform the common PCI code
about that.

Fixes: c2077e2ca0
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <155414130834.574858.16502276132110219890.stgit@bahia.lan>
[dwg: Apply fix so we don't rename the default pci bus, breaking everything]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-04-09 15:03:10 +10:00
Greg Kurz 1c685a9026 pci: Allow PCI bus subtypes to support extended config space accesses
Some PHB implementations, eg. PAPR used on pseries machine, act like
a regular PCI bus rather than a PCIe bus, but allow access to the
PCIe extended config space anyway.

Introduce a new PCI bus class method to modelize this behaviour and
use it when adjusting the config space size limit during accesses.

No behaviour change for existing PCI bus types.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <155414130271.574858.4253514266378127489.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-04-09 09:14:47 +10:00
Peter Maydell 7fe1427b57 Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-04-08' into staging
nbd patches for 2019-04-08

- Fix minor issues in recent alignment patches

# gpg: Signature made Mon 08 Apr 2019 19:53:48 BST
# gpg:                using RSA key A7A16B4A2527436A
# gpg: Good signature from "Eric Blake <eblake@redhat.com>" [full]
# gpg:                 aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" [full]
# gpg:                 aka "[jpeg image of size 6874]" [full]
# Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2  F3AA A7A1 6B4A 2527 436A

* remotes/ericb/tags/pull-nbd-2019-04-08:
  nbd/client: Fix error message for server with unusable sizing
  nbd/server: Don't fail NBD_OPT_INFO for byte-aligned sources
  nbd/server: Trace client noncompliance on unaligned requests
  nbd/server: Fix blockstatus trace

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-08 20:10:21 +01:00
Eric Blake e53f88df77 nbd/client: Fix error message for server with unusable sizing
Add a missing space to the error message used when giving up on a
server that insists on an alignment which renders the last few bytes
of the export unreadable.

Fixes: 3add3ab78
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190404145226.32649-1-eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2019-04-08 13:51:25 -05:00
Eric Blake 099fbcd65c nbd/server: Don't fail NBD_OPT_INFO for byte-aligned sources
In commit 0c1d50bd, I added a couple of TODO comments about whether we
consult bl.request_alignment when responding to NBD_OPT_INFO. At the
time, qemu as server was hard-coding an advertised alignment of 512 to
clients that promised to obey constraints, and there was no function
for getting at a device's preferred alignment. But in hindsight,
advertising 512 when the block device prefers 1 caused other
compliance problems, and commit b0245d64 changed one of the two TODO
comments to advertise a more accurate alignment. Time to fix the other
TODO.  Doesn't really impact qemu as client (our normal client doesn't
use NBD_OPT_INFO, and qemu-nbd --list promises to obey block sizes),
but it might prove useful to other clients.

Fixes: b0245d64
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190403030526.12258-4-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2019-04-08 13:49:25 -05:00
Eric Blake 6e280648d2 nbd/server: Trace client noncompliance on unaligned requests
We've recently added traces for clients to flag server non-compliance;
let's do the same for servers to flag client non-compliance. According
to the spec, if the client requests NBD_INFO_BLOCK_SIZE, it is
promising to send all requests aligned to those boundaries.  Of
course, if the client does not request NBD_INFO_BLOCK_SIZE, then it
made no promises so we shouldn't flag anything; and because we are
willing to handle clients that made no promises (the spec allows us to
use NBD_REP_ERR_BLOCK_SIZE_REQD if we had been unwilling), we already
have to handle unaligned requests (which the block layer already does
on our behalf).  So even though the spec allows us to return EINVAL
for clients that promised to behave, it's easier to always answer
unaligned requests.  Still, flagging non-compliance can be useful in
debugging a client that is trying to be maximally portable.

Qemu as client used to have one spot where it sent non-compliant
requests: if the server sends an unaligned reply to
NBD_CMD_BLOCK_STATUS, and the client was iterating over the entire
disk, the next request would start at that unaligned point; this was
fixed in commit a39286dd when the client was taught to work around
server non-compliance; but is equally fixed if the server is patched
to not send unaligned replies in the first place (yes, qemu 4.0 as
server still has few such bugs, although they will be patched in
4.1). Fortunately, I did not find any more spots where qemu as client
was non-compliant. I was able to test the patch by using the following
hack to convince qemu-io to run various unaligned commands, coupled
with serving 512-byte alignment by intentionally omitting '-f raw' on
the server while viewing server traces.

| diff --git i/nbd/client.c w/nbd/client.c
| index 427980bdd22..1858b2aac35 100644
| --- i/nbd/client.c
| +++ w/nbd/client.c
| @@ -449,6 +449,7 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt,
|                  nbd_send_opt_abort(ioc);
|                  return -1;
|              }
| +            info->min_block = 1;//hack
|              if (!is_power_of_2(info->min_block)) {
|                  error_setg(errp, "server minimum block size %" PRIu32
|                             " is not a power of two", info->min_block);

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190403030526.12258-3-eblake@redhat.com>
[eblake: address minor review nits]
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2019-04-08 13:42:24 -05:00
Eric Blake 2178a569be nbd/server: Fix blockstatus trace
Don't increment remaining_bytes until we know that we will actually be
including the current block status extent in the reply; otherwise, the
value traced will include a bytes value that is oversized by the
length of the next block status extent which did not get sent because
it instead ended the loop.

Fixes: fb7afc79
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190403030526.12258-2-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2019-04-08 13:36:04 -05:00
Peter Maydell 5263724b78 Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:

- hmp: Fix drive_add ... format=help crash
- block: Forward 'discard' to temporary overlay

# gpg: Signature made Mon 08 Apr 2019 16:43:20 BST
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  hmp: Fix drive_add ... format=help crash
  block: Forward 'discard' to temporary overlay

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-08 17:53:18 +01:00
Markus Armbruster ab63817119 hmp: Fix drive_add ... format=help crash
drive_new() returns null without setting an error when it provided
help.  add_init_drive() assumes null means failure, and crashes trying
to report a null error.

Fixes: c4f26c9f37
Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2019-04-08 17:42:06 +02:00
Daniel P. Berrangé 71ba74f67e linux-user: rename gettid() to sys_gettid() to avoid clash with glibc
The glibc-2.29.9000-6.fc31.x86_64 package finally includes the gettid()
function as part of unistd.h when __USE_GNU is defined. This clashes
with linux-user code which unconditionally defines this function name
itself.

/home/berrange/src/virt/qemu/linux-user/syscall.c:253:16: error: static declaration of ‘gettid’ follows non-static declaration
  253 | _syscall0(int, gettid)
      |                ^~~~~~
/home/berrange/src/virt/qemu/linux-user/syscall.c:184:13: note: in definition of macro ‘_syscall0’
  184 | static type name (void)   \
      |             ^~~~
In file included from /usr/include/unistd.h:1170,
                 from /home/berrange/src/virt/qemu/include/qemu/osdep.h:107,
                 from /home/berrange/src/virt/qemu/linux-user/syscall.c:20:
/usr/include/bits/unistd_ext.h:34:16: note: previous declaration of ‘gettid’ was here
   34 | extern __pid_t gettid (void) __THROW;
      |                ^~~~~~
  CC      aarch64-linux-user/linux-user/signal.o
make[1]: *** [/home/berrange/src/virt/qemu/rules.mak:69: linux-user/syscall.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:449: subdir-aarch64-linux-user] Error 2

While we could make our definition conditional and rely on glibc's impl,
this patch simply renames our definition to sys_gettid() which is a
common pattern in this file.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20190320161842.13908-3-berrange@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
2019-04-08 17:27:13 +02:00
Daniel P. Berrangé 184943d827 linux-user: assume __NR_gettid always exists
The gettid syscall was introduced in Linux 2.4.11. This is old enough
that we can assume it always exists and thus not bother with the
conditional backcompat logic.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20190320161842.13908-2-berrange@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
2019-04-08 17:26:44 +02:00
Kevin Wolf 3f48686fac block: Forward 'discard' to temporary overlay
When bdrv_temp_snapshot_options() is called for snapshot=on, the
'discard' option in the options QDict hasn't been parsed and merged into
the flags yet. So copy the dict entry to make sure that the temporary
overlay enables discard when it was requested for the drive.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
2019-04-08 16:48:46 +02:00
Peter Maydell 2c57310627 Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2019-04-08' into staging
- Fix a crash in libqos with GCC 9
- Fix usage of wrong boolean types in libqos

# gpg: Signature made Mon 08 Apr 2019 11:48:56 BST
# gpg:                using RSA key 2ED9D774FE702DB5
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* remotes/huth-gitlab/tags/pull-request-2019-04-08:
  test qgraph.c: Fix segs due to out of scope default
  tests/libqos: fix usage of bool in pci-spapr.c
  tests/libqos: fix usage of bool in pci-pc.c

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-08 15:21:11 +01:00
Dr. David Alan Gilbert c19f2b711e test qgraph.c: Fix segs due to out of scope default
The test uses the trick:
   if (!opts) {
     opts = &(QOSGraph...Options) { };
   }

  in a couple of places, however the temporary created
by the &() {}  goes out of scope at the bottom of the if,
and results in a seg or assert when opts-> fields are
used (on fedora 30's gcc 9).

Fixes: fc281c8020
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190405184037.16799-1-dgilbert@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
2019-04-08 12:38:07 +02:00
Jafar Abdi c098aac7dc tests/libqos: fix usage of bool in pci-spapr.c
Clean up wrong usage of FALSE and TRUE in places that use "bool" from stdbool.h.

FALSE and TRUE (with capital letters) are the constants defined by glib for
being used with the "gboolean" type of glib. But some parts of the code also use
TRUE and FALSE for variables that are declared as "bool" (the type from <stdbool.h>).

Signed-off-by: Jafar Abdi <cafer.abdi@gmail.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <1553351197-14581-4-git-send-email-cafer.abdi@gmail.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
2019-04-08 12:38:07 +02:00
Jafar Abdi 08f7ad1b00 tests/libqos: fix usage of bool in pci-pc.c
Clean up wrong usage of FALSE and TRUE in places that use "bool" from stdbool.h.

FALSE and TRUE (with capital letters) are the constants defined by glib for
being used with the "gboolean" type of glib. But some parts of the code also use
TRUE and FALSE for variables that are declared as "bool" (the type from <stdbool.h>).

Signed-off-by: Jafar Abdi <cafer.abdi@gmail.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1553351197-14581-3-git-send-email-cafer.abdi@gmail.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
2019-04-08 12:38:07 +02:00
Peter Maydell f55a585d10 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pci, pc, virtio: fixes

intel-iommu fixes
virtio typo fixes
linker: a couple of asserts for consistency/security

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Tue 02 Apr 2019 16:51:19 BST
# gpg:                using RSA key 281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full]
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>" [full]
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  intel_iommu: Drop extended root field
  intel_iommu: Fix root_scalable migration breakage
  virtio-net: Fix typo in comment
  intel_iommu: Correct caching-mode error message
  acpi: verify file entries in bios_linker_loader_add_pointer()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-07 14:54:55 +01:00
Peter Maydell 90fb864a7d Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20190405a' into staging
Migration fixes pull for 4.0

A couple of fixes for crashes in colo and
migration parameters.

# gpg: Signature made Fri 05 Apr 2019 16:47:38 BST
# gpg:                using RSA key 45F5C71B4A0CB7FB977A9FA90516331EBC5BFDE7
# gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" [full]
# Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A  9FA9 0516 331E BC5B FDE7

* remotes/dgilbert/tags/pull-migration-20190405a:
  migration: Fix migrate_set_parameter
  migration/ram.c: Fix codes conflict about bitmap_mutex

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-06 00:22:34 +01:00
Juan Quintela d013283a46 migration: Fix migrate_set_parameter
Otherwise we are setting err twice, what is wrong and causes an abort.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Message-Id: <20190403114958.3705-2-quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2019-04-05 15:32:13 +01:00
Zhang Chen c6e5bafb6f migration/ram.c: Fix codes conflict about bitmap_mutex
I found upstream codes conflict with COLO and lead to crash,
and I located to this patch:

commit 386a907b37
Author: Wei Wang <wei.w.wang@intel.com>
Date:   Tue Dec 11 16:24:49 2018 +0800

migration: use bitmap_mutex in migration_bitmap_clear_dirty

My colleague Wei's patch add bitmap_mutex in migration_bitmap_clear_dirty,
but COLO didn't initialize the bitmap_mutex. So we always get an error
when COLO start up. like that:
qemu-system-x86_64: util/qemu-thread-posix.c:64: qemu_mutex_lock_impl: Assertion `mutex->initialized' failed.

This patch add the bitmap_mutex initialize and destroy in COLO
lifecycle.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
Message-Id: <20190329222951.28945-1-chen.zhang@intel.com>
Reviewed-by: Wei Wang <wei.w.wang@intel.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2019-04-05 15:29:48 +01:00
Peter Maydell 10546e09e1 Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-4.0-rc3-v2' into staging
RISC-V Patches for 4.0-rc3, v2

This patch set contains a pair of tightly coupled PLIC bug fixes:

* We were calculating the PLIC addresses incorrectly.
* We were installing the wrong number of PLIC interrupts.

The two bugs togther resulted in a mostly-working system, but they're
impossible to seperate because fixing one bug would result in
significant breakage.  As a result they're in the same patch.

There is also a cleanup to use qemu_log_mask(LOG_GUEST_ERROR,...) for
error reporting.

As far as I know these are the last outstanding RISC-V patches for 4.0.

v2 no longer fails "make check" for me... sorry!

# gpg: Signature made Fri 05 Apr 2019 01:33:57 BST
# gpg:                using RSA key 00CE76D1834960DFCE886DF8EF4CA1502CCBAB41
# gpg:                issuer "palmer@dabbelt.com"
# gpg: Good signature from "Palmer Dabbelt <palmer@dabbelt.com>" [unknown]
# gpg:                 aka "Palmer Dabbelt <palmer@sifive.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 00CE 76D1 8349 60DF CE88  6DF8 EF4C A150 2CCB AB41

* remotes/palmer/tags/riscv-for-master-4.0-rc3-v2:
  riscv: plic: Log guest errors
  riscv: plic: Fix incorrect irq calculation

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-05 04:50:30 +01:00
Peter Maydell bc939abe00 Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20190404' into staging
Xen queue

xen-block fixes

# gpg: Signature made Thu 04 Apr 2019 18:04:38 BST
# gpg:                using RSA key F80C006308E22CFD8A92E7980CF5572FD7FB55AF
# gpg:                issuer "anthony.perard@citrix.com"
# gpg: Good signature from "Anthony PERARD <anthony.perard@gmail.com>" [marginal]
# gpg:                 aka "Anthony PERARD <anthony.perard@citrix.com>" [marginal]
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5379 2F71 024C 600F 778A  7161 D8D5 7199 DF83 42C8
#      Subkey fingerprint: F80C 0063 08E2 2CFD 8A92  E798 0CF5 572F D7FB 55AF

* remotes/aperard/tags/pull-xen-20190404:
  xen-block: scale sector based quantities correctly
  xen-block: only advertize discard to the frontend when it is enabled...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-05 03:52:05 +01:00
Alistair Francis 79bcac250f riscv: plic: Log guest errors
Instead of using error_report() to print guest errors let's use
qemu_log_mask(LOG_GUEST_ERROR,...) to log the error.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
2019-04-04 16:36:21 -07:00
Alistair Francis 0feb4a7129 riscv: plic: Fix incorrect irq calculation
This patch fixes four different things, to maintain bisectability they
have been merged into a single patch. The following fixes are below:

sifive_plic: Fix incorrect irq calculation
The irq is incorrectly calculated to be off by one. It has worked in the
past as the priority_base offset has also been set incorrectly. We are
about to fix the priority_base offset so first first the irq
calculation.

sifive_u: Fix PLIC priority base offset and numbering
According to the FU540 manual the PLIC source priority address starts at
an offset of 0x04 and not 0x00. The same manual also specifies that the
PLIC only has 53 source priorities. Fix these two incorrect header
files.

We also need to over extend the plic_gpios[] array as the PLIC sources
count from 1 and not 0.

riscv: sifive_e: Fix PLIC priority base offset
According to the FE31 manual the PLIC source priority address starts at
an offset of 0x04 and not 0x00.

riscv: virt: Fix PLIC priority base offset
Update the virt offsets based on the newly updated SiFive U and SiFive E
offsets.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
2019-04-04 16:36:19 -07:00
Paul Durrant 2bcd05cf24 xen-block: scale sector based quantities correctly
The Xen blkif protocol requires that sector based quantities should be
interpreted strictly as multiples of 512 bytes. Specifically:

"first_sect and last_sect in blkif_request_segment, as well as
sector_number in blkif_request, are always expressed in 512-byte units."

Commit fcab2b464e "xen: add header and build dataplane/xen-block.c"
incorrectly modified behaviour to use the block device logical_block_size
property as the scale, instead of correctly shifting values by the
hardcoded BDRV_SECTOR_BITS (and hence scaling them to 512 byte units).
This patch undoes that change and restores compliance with the spec.

Furthermore, this patch also restores the original xen_disk behaviour
of advertizing a hardcoded 'sector-size' value of 512 in xenstore and
scaling 'sectors' accordingly. The realize() method is also modified to
fail if logical_block_size is set to anything other than 512.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Message-Id: <20190401121719.27208-1-paul.durrant@citrix.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
2019-04-04 18:00:07 +01:00
Paul Durrant 15f084505a xen-block: only advertize discard to the frontend when it is enabled...
...and properly enable it when synthesizing a drive.

The Xen toolstack sets 'discard-enable' to '1' in xenstore when it wants
to enable discard on a specified image. The code in
xen_block_drive_create() correctly parses this and uses it to set
'discard' to 'unmap' for the file_layer, but fails to do the same for the
driver_layer (which effectively disables it). Meanwhile the code in
xen_block_realize() advertizes discard support to the frontend in the
default case (because conf->discard_granularity defaults to -1), even when
the underlying image may not handle it.

This patch adds the missing option to the driver_layer in
xen_block_driver_create() and checks whether BDRV_O_UNMAP is actually
set on the block device before advertizing discard to the frontend.
In the case that discard is supported it also makes sure that the
granularity is set to the physical block size.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Message-Id: <20190320142825.24565-1-paul.durrant@citrix.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
2019-04-04 12:41:23 +01:00
Peter Maydell f4b3717137 Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190403' into staging
Fix taking address of fields in packed structs warnings
by gcc 9

# gpg: Signature made Wed 03 Apr 2019 10:58:42 BST
# gpg:                using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF
# gpg:                issuer "cohuck@redhat.com"
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown]
# gpg:                 aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cohuck@kernel.org>" [unknown]
# gpg:                 aka "Cornelia Huck <cohuck@redhat.com>" [unknown]
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20190403:
  hw/s390x/3270-ccw: avoid taking address of fields in packed struct
  hw/s390x/ipl: avoid taking address of fields in packed struct
  hw/s390/css: avoid taking address members in packed structs
  hw/vfio/ccw: avoid taking address members in packed structs

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-04-03 13:13:30 +01:00
Daniel P. Berrangé 7357b22159 hw/s390x/3270-ccw: avoid taking address of fields in packed struct
Compiling with GCC 9 complains

hw/s390x/3270-ccw.c: In function ‘emulated_ccw_3270_cb’:
hw/s390x/3270-ccw.c:81:19: error: taking address of packed member of ‘struct SCHIB’ may result in an unaligned pointer value [-Werror=address-of-packed-member]
   81 |         SCSW *s = &sch->curr_status.scsw;
      |                   ^~~~~~~~~~~~~~~~~~~~~~

This local variable is only present to save a little bit of
typing when setting the field later. Get rid of this to avoid
the warning about unaligned accesses.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20190329111104.17223-15-berrange@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-04-03 11:19:57 +02:00
Daniel P. Berrangé 5d45a33292 hw/s390x/ipl: avoid taking address of fields in packed struct
Compiling with GCC 9 complains

hw/s390x/ipl.c: In function ‘s390_ipl_set_boot_menu’:
hw/s390x/ipl.c:256:25: warning: taking address of packed member of ‘struct QemuIplParameters’ may result in an unaligned pointer value [-Waddress-of-packed-member]
  256 |     uint32_t *timeout = &ipl->qipl.boot_menu_timeout;
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

This local variable is only present to save a little bit of
typing when setting the field later. Get rid of this to avoid
the warning about unaligned accesses.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20190329111104.17223-14-berrange@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-04-03 11:19:57 +02:00
Daniel P. Berrangé bea0279b72 hw/s390/css: avoid taking address members in packed structs
The GCC 9 compiler complains about many places in s390 code
that take the address of members of the 'struct SCHIB' which
is marked packed:

hw/s390x/css.c: In function ‘sch_handle_clear_func’:
hw/s390x/css.c:698:15: warning: taking address of packed member of ‘struct SCHIB’ may result in an unaligned pointer val\
ue [-Waddress-of-packed-member]
  698 |     PMCW *p = &sch->curr_status.pmcw;
      |               ^~~~~~~~~~~~~~~~~~~~~~
hw/s390x/css.c:699:15: warning: taking address of packed member of ‘struct SCHIB’ may result in an unaligned pointer val\
ue [-Waddress-of-packed-member]
  699 |     SCSW *s = &sch->curr_status.scsw;
      |               ^~~~~~~~~~~~~~~~~~~~~~

...snip many more...

Almost all of these are just done for convenience to avoid
typing out long variable/field names when referencing struct
members. We can get most of this convenience by taking the
address of the 'struct SCHIB' instead, avoiding triggering
the compiler warnings.

In a couple of places we copy via a local variable which is
a technique already applied elsewhere in s390 code for this
problem.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20190329111104.17223-13-berrange@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-04-03 11:19:57 +02:00
Daniel P. Berrangé e1d0b37261 hw/vfio/ccw: avoid taking address members in packed structs
The GCC 9 compiler complains about many places in s390 code
that take the address of members of the 'struct SCHIB' which
is marked packed:

hw/vfio/ccw.c: In function ‘vfio_ccw_io_notifier_handler’:
hw/vfio/ccw.c:133:15: warning: taking address of packed member of ‘struct SCHIB’ may result in an unaligned pointer value \
[-Waddress-of-packed-member]
  133 |     SCSW *s = &sch->curr_status.scsw;
      |               ^~~~~~~~~~~~~~~~~~~~~~
hw/vfio/ccw.c:134:15: warning: taking address of packed member of ‘struct SCHIB’ may result in an unaligned pointer value \
[-Waddress-of-packed-member]
  134 |     PMCW *p = &sch->curr_status.pmcw;
      |               ^~~~~~~~~~~~~~~~~~~~~~

...snip many more...

Almost all of these are just done for convenience to avoid
typing out long variable/field names when referencing struct
members. We can get most of this convenience by taking the
address of the 'struct SCHIB' instead, avoiding triggering
the compiler warnings.

In a couple of places we copy via a local variable which is
a technique already applied elsewhere in s390 code for this
problem.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20190329111104.17223-12-berrange@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-04-03 11:19:57 +02:00
Peter Xu 81fb1e646e intel_iommu: Drop extended root field
VTD_RTADDR_RTT is dropped even by the VT-d spec, so QEMU should
probably do the same thing (after all we never really implemented it).
Since we've had a field for that in the migration stream, to keep
compatibility we need to fill the hole up.

Please refer to VT-d spec 10.4.6.

Signed-off-by: Peter Xu <peterx@redhat.com>
Message-Id: <20190329061422.7926-3-peterx@redhat.com>
Reviewed-by: Liu, Yi L <yi.l.liu@intel.com>
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2019-04-02 11:49:14 -04:00
Peter Xu 2811af3b49 intel_iommu: Fix root_scalable migration breakage
When introducing the initial support for scalable mode we added a
new field into vmstate however we blindly migrate that field without
notice.  That'll break migration no matter forward or backward.

The normal way should be that we use something like
VMSTATE_UINT32_TEST() or subsections for the new vmstate field however
for this case of vt-d we can even make it simpler because we've
already migrated all the registers and it'll be fairly simple that we
re-generate root_scalable field from the register values during post
load of the device.

Fixes: fb43cf739e ("intel_iommu: scalable mode emulation")
Reviewed-by: Yi Sun <yi.y.sun@linux.intel.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Message-Id: <20190329061422.7926-2-peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2019-04-02 11:49:14 -04:00
Yuval Shaia 20f86a75a7 virtio-net: Fix typo in comment
Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com>
Message-Id: <20190321161832.10533-1-yuval.shaia@oracle.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2019-04-02 11:49:14 -04:00
Alex Williamson 75c5626c88 intel_iommu: Correct caching-mode error message
If we try to use the intel-iommu device with vfio-pci devices without
caching mode enabled, we're told:

  qemu-system-x86_64: We need to set caching-mode=1 for intel-iommu to enable
  device assignment with IOMMU protection.

But to enable caching mode, the option is actually "caching-mode=on".

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Message-Id: <155364147432.16467.15898335025013220939.stgit@gimli.home>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Alex Williamson &lt;<a href="mailto:alex.williamson@redhat.com" target="_blank" rel="noreferrer">alex.williamson@redhat.com</a>&gt;<br>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2019-04-02 11:49:14 -04:00
Liam Merwick 22132828d1 acpi: verify file entries in bios_linker_loader_add_pointer()
The callers to bios_linker_find_file() assert that the file entry returned
is not NULL, except for those in bios_linker_loader_add_pointer().  Add two
asserts in that case for completeness and to facilitate static code analysis.

Signed-off-by: Liam Merwick <liam.merwick@oracle.com>
Message-Id: <1553199229-25318-1-git-send-email-liam.merwick@oracle.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2019-04-02 11:49:14 -04:00
155 changed files with 3600 additions and 1284 deletions

No files matched your search

+1 -1
View File
@@ -899,7 +899,7 @@ docs/version.texi: $(SRC_PATH)/VERSION
sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index.html
# Canned command to build a single manual
build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -b html -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -W -n -b html -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
# We assume all RST files in the manual's directory are used in it
manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
+1 -1
View File
@@ -1 +1 @@
3.1.92
4.0.1
+8 -14
View File
@@ -950,8 +950,9 @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
qdict_set_default_str(child_options, BDRV_OPT_CACHE_DIRECT, "off");
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
/* Copy the read-only option from the parent */
/* Copy the read-only and discard options from the parent */
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
qdict_copy_default(child_options, parent_options, BDRV_OPT_DISCARD);
/* aio=native doesn't work for cache.direct=off, so disable it for the
* temporary snapshot */
@@ -3986,13 +3987,13 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
uint64_t perm = 0, shared = BLK_PERM_ALL;
int ret;
assert(!atomic_read(&from->in_flight));
assert(!atomic_read(&to->in_flight));
/* Make sure that @from doesn't go away until we have successfully attached
* all of its parents to @to. */
bdrv_ref(from);
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
bdrv_drained_begin(from);
/* Put all parents into @list and calculate their cumulative permissions */
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
assert(c->bs == from);
@@ -4033,6 +4034,7 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
out:
g_slist_free(list);
bdrv_drained_end(from);
bdrv_unref(from);
}
@@ -5671,10 +5673,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) {
@@ -5689,7 +5687,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) {
@@ -5708,10 +5706,6 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
BdrvAioNotifier *ban, *ban_tmp;
BdrvChild *child;
if (!bs->drv) {
return;
}
if (bs->quiesce_counter) {
aio_disable_external(new_context);
}
@@ -5721,7 +5715,7 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
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);
}
+117 -141
View File
@@ -113,7 +113,8 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1);
assert(QEMU_IS_ALIGNED(start, job->cluster_size));
hbitmap_reset(job->copy_bitmap, start, job->cluster_size);
nbytes = MIN(job->cluster_size, job->len - start);
if (!*bounce_buffer) {
*bounce_buffer = blk_blockalign(blk, job->cluster_size);
@@ -147,7 +148,7 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
return nbytes;
fail:
hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1);
hbitmap_set(job->copy_bitmap, start, job->cluster_size);
return ret;
}
@@ -167,16 +168,15 @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
assert(QEMU_IS_ALIGNED(start, job->cluster_size));
nbytes = MIN(job->copy_range_size, end - start);
nr_clusters = DIV_ROUND_UP(nbytes, job->cluster_size);
hbitmap_reset(job->copy_bitmap, start / job->cluster_size,
nr_clusters);
hbitmap_reset(job->copy_bitmap, start, job->cluster_size * nr_clusters);
ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
read_flags, write_flags);
if (ret < 0) {
trace_backup_do_cow_copy_range_fail(job, start, ret);
hbitmap_set(job->copy_bitmap, start / job->cluster_size,
nr_clusters);
hbitmap_set(job->copy_bitmap, start, job->cluster_size * nr_clusters);
return ret;
}
@@ -204,22 +204,31 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
cow_request_begin(&cow_request, job, start, end);
while (start < end) {
if (!hbitmap_get(job->copy_bitmap, start / job->cluster_size)) {
int64_t dirty_end;
if (!hbitmap_get(job->copy_bitmap, start)) {
trace_backup_do_cow_skip(job, start);
start += job->cluster_size;
continue; /* already copied */
}
dirty_end = hbitmap_next_zero(job->copy_bitmap, start, (end - start));
if (dirty_end < 0) {
dirty_end = end;
}
trace_backup_do_cow_process(job, start);
if (job->use_copy_range) {
ret = backup_cow_with_offload(job, start, end, is_write_notifier);
ret = backup_cow_with_offload(job, start, dirty_end,
is_write_notifier);
if (ret < 0) {
job->use_copy_range = false;
}
}
if (!job->use_copy_range) {
ret = backup_cow_with_bounce_buffer(job, start, end, is_write_notifier,
ret = backup_cow_with_bounce_buffer(job, start, dirty_end,
is_write_notifier,
error_is_read, &bounce_buffer);
}
if (ret < 0) {
@@ -300,6 +309,11 @@ static void backup_clean(Job *job)
assert(s->target);
blk_unref(s->target);
s->target = NULL;
if (s->copy_bitmap) {
hbitmap_free(s->copy_bitmap);
s->copy_bitmap = NULL;
}
}
static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
@@ -312,7 +326,6 @@ static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
void backup_do_checkpoint(BlockJob *job, Error **errp)
{
BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
int64_t len;
assert(block_job_driver(job) == &backup_job_driver);
@@ -322,8 +335,7 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
return;
}
len = DIV_ROUND_UP(backup_job->len, backup_job->cluster_size);
hbitmap_set(backup_job->copy_bitmap, 0, len);
hbitmap_set(backup_job->copy_bitmap, 0, backup_job->len);
}
static void backup_drain(BlockJob *job)
@@ -374,20 +386,44 @@ static bool coroutine_fn yield_and_check(BackupBlockJob *job)
return false;
}
static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
static bool bdrv_is_unallocated_range(BlockDriverState *bs,
int64_t offset, int64_t bytes)
{
int64_t end = offset + bytes;
while (offset < end && !bdrv_is_allocated(bs, offset, bytes, &bytes)) {
if (bytes == 0) {
return true;
}
offset += bytes;
bytes = end - offset;
}
return offset >= end;
}
static int coroutine_fn backup_loop(BackupBlockJob *job)
{
int ret;
bool error_is_read;
int64_t cluster;
int64_t offset;
HBitmapIter hbi;
BlockDriverState *bs = blk_bs(job->common.blk);
hbitmap_iter_init(&hbi, job->copy_bitmap, 0);
while ((cluster = hbitmap_iter_next(&hbi)) != -1) {
while ((offset = hbitmap_iter_next(&hbi)) != -1) {
if (job->sync_mode == MIRROR_SYNC_MODE_TOP &&
bdrv_is_unallocated_range(bs, offset, job->cluster_size))
{
hbitmap_reset(job->copy_bitmap, offset, job->cluster_size);
continue;
}
do {
if (yield_and_check(job)) {
return 0;
}
ret = backup_do_cow(job, cluster * job->cluster_size,
ret = backup_do_cow(job, offset,
job->cluster_size, &error_is_read, false);
if (ret < 0 && backup_error_action(job, error_is_read, -ret) ==
BLOCK_ERROR_ACTION_REPORT)
@@ -403,66 +439,43 @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
/* init copy_bitmap from sync_bitmap */
static void backup_incremental_init_copy_bitmap(BackupBlockJob *job)
{
BdrvDirtyBitmapIter *dbi;
int64_t offset;
int64_t end = DIV_ROUND_UP(bdrv_dirty_bitmap_size(job->sync_bitmap),
job->cluster_size);
uint64_t offset = 0;
uint64_t bytes = job->len;
dbi = bdrv_dirty_iter_new(job->sync_bitmap);
while ((offset = bdrv_dirty_iter_next(dbi)) != -1) {
int64_t cluster = offset / job->cluster_size;
int64_t next_cluster;
while (bdrv_dirty_bitmap_next_dirty_area(job->sync_bitmap,
&offset, &bytes))
{
hbitmap_set(job->copy_bitmap, offset, bytes);
offset += bdrv_dirty_bitmap_granularity(job->sync_bitmap);
if (offset >= bdrv_dirty_bitmap_size(job->sync_bitmap)) {
hbitmap_set(job->copy_bitmap, cluster, end - cluster);
offset += bytes;
if (offset >= job->len) {
break;
}
offset = bdrv_dirty_bitmap_next_zero(job->sync_bitmap, offset,
UINT64_MAX);
if (offset == -1) {
hbitmap_set(job->copy_bitmap, cluster, end - cluster);
break;
}
next_cluster = DIV_ROUND_UP(offset, job->cluster_size);
hbitmap_set(job->copy_bitmap, cluster, next_cluster - cluster);
if (next_cluster >= end) {
break;
}
bdrv_set_dirty_iter(dbi, next_cluster * job->cluster_size);
bytes = job->len - offset;
}
/* TODO job_progress_set_remaining() would make more sense */
job_progress_update(&job->common.job,
job->len - hbitmap_count(job->copy_bitmap) * job->cluster_size);
bdrv_dirty_iter_free(dbi);
job->len - hbitmap_count(job->copy_bitmap));
}
static int coroutine_fn backup_run(Job *job, Error **errp)
{
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
BlockDriverState *bs = blk_bs(s->common.blk);
int64_t offset, nb_clusters;
int ret = 0;
QLIST_INIT(&s->inflight_reqs);
qemu_co_rwlock_init(&s->flush_rwlock);
nb_clusters = DIV_ROUND_UP(s->len, s->cluster_size);
job_progress_set_remaining(job, s->len);
s->copy_bitmap = hbitmap_alloc(nb_clusters, 0);
if (s->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
backup_incremental_init_copy_bitmap(s);
} else {
hbitmap_set(s->copy_bitmap, 0, nb_clusters);
hbitmap_set(s->copy_bitmap, 0, s->len);
}
s->before_write.notify = backup_before_write_notify;
bdrv_add_before_write_notifier(bs, &s->before_write);
@@ -474,68 +487,8 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
* notify callback service CoW requests. */
job_yield(job);
}
} else if (s->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
ret = backup_run_incremental(s);
} else {
/* Both FULL and TOP SYNC_MODE's require copying.. */
for (offset = 0; offset < s->len;
offset += s->cluster_size) {
bool error_is_read;
int alloced = 0;
if (yield_and_check(s)) {
break;
}
if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
int i;
int64_t n;
/* Check to see if these blocks are already in the
* backing file. */
for (i = 0; i < s->cluster_size;) {
/* bdrv_is_allocated() only returns true/false based
* on the first set of sectors it comes across that
* are are all in the same state.
* For that reason we must verify each sector in the
* backup cluster length. We end up copying more than
* needed but at some point that is always the case. */
alloced =
bdrv_is_allocated(bs, offset + i,
s->cluster_size - i, &n);
i += n;
if (alloced || n == 0) {
break;
}
}
/* If the above loop never found any sectors that are in
* the topmost image, skip this backup. */
if (alloced == 0) {
continue;
}
}
/* FULL sync mode we copy the whole drive. */
if (alloced < 0) {
ret = alloced;
} else {
ret = backup_do_cow(s, offset, s->cluster_size,
&error_is_read, false);
}
if (ret < 0) {
/* Depending on error action, fail now or retry cluster */
BlockErrorAction action =
backup_error_action(s, error_is_read, -ret);
if (action == BLOCK_ERROR_ACTION_REPORT) {
break;
} else {
offset -= s->cluster_size;
continue;
}
}
}
ret = backup_loop(s);
}
notifier_with_return_remove(&s->before_write);
@@ -543,7 +496,6 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
/* wait until pending backup_do_cow() calls have completed */
qemu_co_rwlock_wrlock(&s->flush_rwlock);
qemu_co_rwlock_unlock(&s->flush_rwlock);
hbitmap_free(s->copy_bitmap);
return ret;
}
@@ -564,6 +516,42 @@ static const BlockJobDriver backup_job_driver = {
.drain = backup_drain,
};
static int64_t backup_calculate_cluster_size(BlockDriverState *target,
Error **errp)
{
int ret;
BlockDriverInfo bdi;
/*
* If there is no backing file on the target, we cannot rely on COW if our
* backup cluster size is smaller than the target cluster size. Even for
* targets with a backing file, try to avoid COW if possible.
*/
ret = bdrv_get_info(target, &bdi);
if (ret == -ENOTSUP && !target->backing) {
/* Cluster size is not defined */
warn_report("The target block device doesn't provide "
"information about the block size and it doesn't have a "
"backing file. The default block size of %u bytes is "
"used. If the actual block size of the target exceeds "
"this default, the backup may be unusable",
BACKUP_CLUSTER_SIZE_DEFAULT);
return BACKUP_CLUSTER_SIZE_DEFAULT;
} else if (ret < 0 && !target->backing) {
error_setg_errno(errp, -ret,
"Couldn't determine the cluster size of the target image, "
"which has no backing file");
error_append_hint(errp,
"Aborting, since this may create an unusable destination image\n");
return ret;
} else if (ret < 0 && target->backing) {
/* Not fatal; just trudge on ahead. */
return BACKUP_CLUSTER_SIZE_DEFAULT;
}
return MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
}
BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BlockDriverState *target, int64_t speed,
MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
@@ -575,9 +563,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
JobTxn *txn, Error **errp)
{
int64_t len;
BlockDriverInfo bdi;
BackupBlockJob *job = NULL;
int ret;
int64_t cluster_size;
HBitmap *copy_bitmap = NULL;
assert(bs);
assert(target);
@@ -639,6 +628,13 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
goto error;
}
cluster_size = backup_calculate_cluster_size(target, errp);
if (cluster_size < 0) {
goto error;
}
copy_bitmap = hbitmap_alloc(len, ctz32(cluster_size));
/* job->len is fixed, so we can't allow resize */
job = block_job_create(job_id, &backup_job_driver, txn, bs,
BLK_PERM_CONSISTENT_READ,
@@ -667,34 +663,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
/* Detect image-fleecing (and similar) schemes */
job->serialize_target_writes = bdrv_chain_contains(target, bs);
/* If there is no backing file on the target, we cannot rely on COW if our
* backup cluster size is smaller than the target cluster size. Even for
* targets with a backing file, try to avoid COW if possible. */
ret = bdrv_get_info(target, &bdi);
if (ret == -ENOTSUP && !target->backing) {
/* Cluster size is not defined */
warn_report("The target block device doesn't provide "
"information about the block size and it doesn't have a "
"backing file. The default block size of %u bytes is "
"used. If the actual block size of the target exceeds "
"this default, the backup may be unusable",
BACKUP_CLUSTER_SIZE_DEFAULT);
job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
} else if (ret < 0 && !target->backing) {
error_setg_errno(errp, -ret,
"Couldn't determine the cluster size of the target image, "
"which has no backing file");
error_append_hint(errp,
"Aborting, since this may create an unusable destination image\n");
goto error;
} else if (ret < 0 && target->backing) {
/* Not fatal; just trudge on ahead. */
job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
} else {
job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
}
job->use_copy_range = true;
job->cluster_size = cluster_size;
job->copy_bitmap = copy_bitmap;
copy_bitmap = NULL;
job->use_copy_range = !compress; /* compression isn't supported for it */
job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
blk_get_max_transfer(job->target));
job->copy_range_size = MAX(job->cluster_size,
@@ -709,6 +681,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
return &job->common;
error:
if (copy_bitmap) {
assert(!job || !job->copy_bitmap);
hbitmap_free(copy_bitmap);
}
if (sync_bitmap) {
bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);
}
+5 -1
View File
@@ -63,9 +63,13 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
const char *fmt = BlockdevDriver_str(options->driver);
BlockDriver *drv = bdrv_find_format(fmt);
if (!drv) {
error_setg(errp, "Block driver '%s' not found or not supported", fmt);
return;
}
/* If the driver is in the schema, we know that it exists. But it may not
* be whitelisted. */
assert(drv);
if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
error_setg(errp, "Driver is not whitelisted");
return;
+60 -75
View File
@@ -79,6 +79,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
#define CURL_BLOCK_OPT_TIMEOUT_DEFAULT 5
struct BDRVCURLState;
struct CURLState;
static bool libcurl_initialized;
@@ -96,6 +97,7 @@ typedef struct CURLAIOCB {
typedef struct CURLSocket {
int fd;
struct CURLState *state;
QLIST_ENTRY(CURLSocket) next;
} CURLSocket;
@@ -136,7 +138,6 @@ typedef struct BDRVCURLState {
static void curl_clean_state(CURLState *s);
static void curl_multi_do(void *arg);
static void curl_multi_read(void *arg);
#ifdef NEED_CURL_TIMER_CALLBACK
/* Called from curl_multi_do_locked, with s->mutex held. */
@@ -169,33 +170,29 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
QLIST_FOREACH(socket, &state->sockets, next) {
if (socket->fd == fd) {
if (action == CURL_POLL_REMOVE) {
QLIST_REMOVE(socket, next);
g_free(socket);
}
break;
}
}
if (!socket) {
socket = g_new0(CURLSocket, 1);
socket->fd = fd;
socket->state = state;
QLIST_INSERT_HEAD(&state->sockets, socket, next);
}
socket = NULL;
trace_curl_sock_cb(action, (int)fd);
switch (action) {
case CURL_POLL_IN:
aio_set_fd_handler(s->aio_context, fd, false,
curl_multi_read, NULL, NULL, state);
curl_multi_do, NULL, NULL, socket);
break;
case CURL_POLL_OUT:
aio_set_fd_handler(s->aio_context, fd, false,
NULL, curl_multi_do, NULL, state);
NULL, curl_multi_do, NULL, socket);
break;
case CURL_POLL_INOUT:
aio_set_fd_handler(s->aio_context, fd, false,
curl_multi_read, curl_multi_do, NULL, state);
curl_multi_do, curl_multi_do, NULL, socket);
break;
case CURL_POLL_REMOVE:
aio_set_fd_handler(s->aio_context, fd, false,
@@ -203,6 +200,11 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
break;
}
if (action == CURL_POLL_REMOVE) {
QLIST_REMOVE(socket, next);
g_free(socket);
}
return 0;
}
@@ -226,7 +228,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
CURLState *s = ((CURLState*)opaque);
size_t realsize = size * nmemb;
int i;
trace_curl_read_cb(realsize);
@@ -242,32 +243,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
memcpy(s->orig_buf + s->buf_off, ptr, realsize);
s->buf_off += realsize;
for(i=0; i<CURL_NUM_ACB; i++) {
CURLAIOCB *acb = s->acb[i];
if (!acb)
continue;
if ((s->buf_off >= acb->end)) {
size_t request_length = acb->bytes;
qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
acb->end - acb->start);
if (acb->end - acb->start < request_length) {
size_t offset = acb->end - acb->start;
qemu_iovec_memset(acb->qiov, offset, 0,
request_length - offset);
}
acb->ret = 0;
s->acb[i] = NULL;
qemu_mutex_unlock(&s->s->mutex);
aio_co_wake(acb->co);
qemu_mutex_lock(&s->s->mutex);
}
}
read_end:
/* curl will error out if we do not return this value */
return size * nmemb;
@@ -348,13 +323,14 @@ static void curl_multi_check_completion(BDRVCURLState *s)
break;
if (msg->msg == CURLMSG_DONE) {
int i;
CURLState *state = NULL;
bool error = msg->data.result != CURLE_OK;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE,
(char **)&state);
/* ACBs for successful messages get completed in curl_read_cb */
if (msg->data.result != CURLE_OK) {
int i;
if (error) {
static int errcount = 100;
/* Don't lose the original error message from curl, since
@@ -366,20 +342,35 @@ static void curl_multi_check_completion(BDRVCURLState *s)
error_report("curl: further errors suppressed");
}
}
}
for (i = 0; i < CURL_NUM_ACB; i++) {
CURLAIOCB *acb = state->acb[i];
for (i = 0; i < CURL_NUM_ACB; i++) {
CURLAIOCB *acb = state->acb[i];
if (acb == NULL) {
continue;
}
acb->ret = -EIO;
state->acb[i] = NULL;
qemu_mutex_unlock(&s->mutex);
aio_co_wake(acb->co);
qemu_mutex_lock(&s->mutex);
if (acb == NULL) {
continue;
}
if (!error) {
/* Assert that we have read all data */
assert(state->buf_off >= acb->end);
qemu_iovec_from_buf(acb->qiov, 0,
state->orig_buf + acb->start,
acb->end - acb->start);
if (acb->end - acb->start < acb->bytes) {
size_t offset = acb->end - acb->start;
qemu_iovec_memset(acb->qiov, offset, 0,
acb->bytes - offset);
}
}
acb->ret = error ? -EIO : 0;
state->acb[i] = NULL;
qemu_mutex_unlock(&s->mutex);
aio_co_wake(acb->co);
qemu_mutex_lock(&s->mutex);
}
curl_clean_state(state);
@@ -389,42 +380,30 @@ static void curl_multi_check_completion(BDRVCURLState *s)
}
/* Called with s->mutex held. */
static void curl_multi_do_locked(CURLState *s)
static void curl_multi_do_locked(CURLSocket *socket)
{
CURLSocket *socket, *next_socket;
BDRVCURLState *s = socket->state->s;
int running;
int r;
if (!s->s->multi) {
if (!s->multi) {
return;
}
/* Need to use _SAFE because curl_multi_socket_action() may trigger
* curl_sock_cb() which might modify this list */
QLIST_FOREACH_SAFE(socket, &s->sockets, next, next_socket) {
do {
r = curl_multi_socket_action(s->s->multi, socket->fd, 0, &running);
} while (r == CURLM_CALL_MULTI_PERFORM);
}
do {
r = curl_multi_socket_action(s->multi, socket->fd, 0, &running);
} while (r == CURLM_CALL_MULTI_PERFORM);
}
static void curl_multi_do(void *arg)
{
CURLState *s = (CURLState *)arg;
CURLSocket *socket = arg;
BDRVCURLState *s = socket->state->s;
qemu_mutex_lock(&s->s->mutex);
curl_multi_do_locked(s);
qemu_mutex_unlock(&s->s->mutex);
}
static void curl_multi_read(void *arg)
{
CURLState *s = (CURLState *)arg;
qemu_mutex_lock(&s->s->mutex);
curl_multi_do_locked(s);
curl_multi_check_completion(s->s);
qemu_mutex_unlock(&s->s->mutex);
qemu_mutex_lock(&s->mutex);
curl_multi_do_locked(socket);
curl_multi_check_completion(s);
qemu_mutex_unlock(&s->mutex);
}
static void curl_multi_timeout_do(void *arg)
@@ -902,7 +881,13 @@ static void curl_setup_preadv(BlockDriverState *bs, CURLAIOCB *acb)
trace_curl_setup_preadv(acb->bytes, start, state->range);
curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
curl_multi_add_handle(s->multi, state->curl);
if (curl_multi_add_handle(s->multi, state->curl) != CURLM_OK) {
state->acb[0] = NULL;
acb->ret = -EIO;
curl_clean_state(state);
goto out;
}
/* Tell curl it needs to kick things off */
curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
+16
View File
@@ -2475,6 +2475,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;
@@ -2500,6 +2502,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. */
+29
View File
@@ -1477,6 +1477,15 @@ static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c,
*nshared = BLK_PERM_ALL;
}
static void bdrv_mirror_top_refresh_limits(BlockDriverState *bs, Error **errp)
{
MirrorBDSOpaque *s = bs->opaque;
if (s && s->job && s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING) {
bs->bl.request_alignment = s->job->granularity;
}
}
/* Dummy node that provides consistent read to its users without requiring it
* from its backing file and that allows writes on the backing file chain. */
static BlockDriver bdrv_mirror_top = {
@@ -1489,6 +1498,7 @@ static BlockDriver bdrv_mirror_top = {
.bdrv_co_block_status = bdrv_co_block_status_from_backing,
.bdrv_refresh_filename = bdrv_mirror_top_refresh_filename,
.bdrv_child_perm = bdrv_mirror_top_child_perm,
.bdrv_refresh_limits = bdrv_mirror_top_refresh_limits,
};
static void mirror_start_job(const char *job_id, BlockDriverState *bs,
@@ -1627,6 +1637,25 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
s->should_complete = true;
}
/*
* Must be called before we start tracking writes, but after
*
* ((MirrorBlockJob *)
* ((MirrorBDSOpaque *)
* mirror_top_bs->opaque
* )->job
* )->copy_mode
*
* has the correct value.
* (We start tracking writes as of the following
* bdrv_create_dirty_bitmap() call.)
*/
bdrv_refresh_limits(mirror_top_bs, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto fail;
}
s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
if (!s->dirty_bitmap) {
goto fail;
+4 -2
View File
@@ -389,12 +389,14 @@ static void nfs_attach_aio_context(BlockDriverState *bs,
static void nfs_client_close(NFSClient *client)
{
if (client->context) {
qemu_mutex_lock(&client->mutex);
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
false, NULL, NULL, NULL, NULL);
qemu_mutex_unlock(&client->mutex);
if (client->fh) {
nfs_close(client->context, client->fh);
client->fh = NULL;
}
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
false, NULL, NULL, NULL, NULL);
nfs_destroy_context(client->context);
client->context = NULL;
}
+1 -1
View File
@@ -612,12 +612,12 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
/* Set up admin queue. */
s->queues = g_new(NVMeQueuePair *, 1);
s->nr_queues = 1;
s->queues[0] = nvme_create_queue_pair(bs, 0, NVME_QUEUE_SIZE, errp);
if (!s->queues[0]) {
ret = -EINVAL;
goto out;
}
s->nr_queues = 1;
QEMU_BUILD_BUG_ON(NVME_QUEUE_SIZE & 0xF000);
s->regs->aqa = cpu_to_le32((NVME_QUEUE_SIZE << 16) | NVME_QUEUE_SIZE);
s->regs->asq = cpu_to_le64(s->queues[0]->sq.iova);
+37 -23
View File
@@ -831,7 +831,11 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
bool l2_cache_entry_size_set;
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size);
/* An L2 table is always one cluster in size so the max cache size
* should be a multiple of the cluster size. */
uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),
s->cluster_size);
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
@@ -2721,10 +2725,13 @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
* Returns: 0 on success, -errno on failure.
*/
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
uint64_t new_length)
uint64_t new_length, PreallocMode mode,
Error **errp)
{
BDRVQcow2State *s = bs->opaque;
uint64_t bytes;
uint64_t host_offset = 0;
int64_t file_length;
unsigned int cur_bytes;
int ret;
QCowL2Meta *meta;
@@ -2733,10 +2740,11 @@ 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) {
error_setg_errno(errp, -ret, "Allocating clusters failed");
return ret;
}
@@ -2745,6 +2753,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
ret = qcow2_alloc_cluster_link_l2(bs, meta);
if (ret < 0) {
error_setg_errno(errp, -ret, "Mapping clusters failed");
qcow2_free_any_clusters(bs, meta->alloc_offset,
meta->nb_clusters, QCOW2_DISCARD_NEVER);
return ret;
@@ -2769,10 +2778,18 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
* all of the allocated clusters (otherwise we get failing reads after
* EOF). Extend the image to the last allocated sector.
*/
if (host_offset != 0) {
uint8_t data = 0;
ret = bdrv_pwrite(bs->file, (host_offset + cur_bytes) - 1,
&data, 1);
file_length = bdrv_getlength(s->data_file->bs);
if (file_length < 0) {
error_setg_errno(errp, -file_length, "Could not get file size");
return file_length;
}
if (host_offset + cur_bytes > file_length) {
if (mode == PREALLOC_MODE_METADATA) {
mode = PREALLOC_MODE_OFF;
}
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, mode,
errp);
if (ret < 0) {
return ret;
}
@@ -3744,12 +3761,17 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
switch (prealloc) {
case PREALLOC_MODE_OFF:
if (has_data_file(bs)) {
ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
if (ret < 0) {
goto fail;
}
}
break;
case PREALLOC_MODE_METADATA:
ret = preallocate_co(bs, old_length, offset);
ret = preallocate_co(bs, old_length, offset, prealloc, errp);
if (ret < 0) {
error_setg_errno(errp, -ret, "Preallocation failed");
goto fail;
}
break;
@@ -3765,9 +3787,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
/* With a data file, preallocation means just allocating the metadata
* and forwarding the truncate request to the data file */
if (has_data_file(bs)) {
ret = preallocate_co(bs, old_length, offset);
ret = preallocate_co(bs, old_length, offset, prealloc, errp);
if (ret < 0) {
error_setg_errno(errp, -ret, "Preallocation failed");
goto fail;
}
break;
@@ -3881,16 +3902,6 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
bs->total_sectors = offset / BDRV_SECTOR_SIZE;
if (has_data_file(bs)) {
if (prealloc == PREALLOC_MODE_METADATA) {
prealloc = PREALLOC_MODE_OFF;
}
ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
if (ret < 0) {
goto fail;
}
}
/* write updated header.size */
offset = cpu_to_be64(offset);
ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
@@ -4377,14 +4388,17 @@ static int qcow2_make_empty(BlockDriverState *bs)
if (s->qcow_version >= 3 && !s->snapshots && !s->nb_bitmaps &&
3 + l1_clusters <= s->refcount_block_size &&
s->crypt_method_header != QCOW_CRYPT_LUKS) {
s->crypt_method_header != QCOW_CRYPT_LUKS &&
!has_data_file(bs)) {
/* The following function only works for qcow2 v3 images (it
* requires the dirty flag) and only as long as there are no
* features that reserve extra clusters (such as snapshots,
* LUKS header, or persistent bitmaps), because it completely
* empties the image. Furthermore, the L1 table and three
* additional clusters (image header, refcount table, one
* refcount block) have to fit inside one refcount block. */
* refcount block) have to fit inside one refcount block. It
* only resets the image file, i.e. does not work with an
* external data file. */
return make_completely_empty(bs);
}
+2 -1
View File
@@ -881,6 +881,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
goto fail;
}
ret = 0;
fail:
return ret;
}
@@ -904,7 +905,7 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
return ret;
}
return ret;
return 0;
}
static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,
-4
View File
@@ -1871,10 +1871,6 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
}
aio_context = bdrv_get_aio_context(bs);
if (aio_context != bdrv_get_aio_context(target)) {
error_setg(errp, "Backup between two IO threads is not implemented");
return;
}
aio_context_acquire(aio_context);
state->bs = bs;
+13 -4
View File
@@ -193,14 +193,23 @@ static const BdrvChildRole child_job = {
void block_job_remove_all_bdrv(BlockJob *job)
{
GSList *l;
for (l = job->nodes; l; l = l->next) {
/*
* bdrv_root_unref_child() may reach child_job_[can_]set_aio_ctx(),
* which will also traverse job->nodes, so consume the list one by
* one to make sure that such a concurrent access does not attempt
* to process an already freed BdrvChild.
*/
while (job->nodes) {
GSList *l = job->nodes;
BdrvChild *c = l->data;
job->nodes = l->next;
bdrv_op_unblock_all(c->bs, job->blocker);
bdrv_root_unref_child(c);
g_slist_free_1(l);
}
g_slist_free(job->nodes);
job->nodes = NULL;
}
int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
+8 -4
View File
@@ -1263,10 +1263,14 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
return false;
}
if (sock->has_wait) {
error_setg(errp, "%s",
"'wait' option is incompatible with "
"socket in client connect mode");
return false;
warn_report("'wait' option is deprecated with "
"socket in client connect mode");
if (sock->wait) {
error_setg(errp, "%s",
"'wait' option is incompatible with "
"socket in client connect mode");
return false;
}
}
}
+2 -1
View File
@@ -1085,7 +1085,8 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
vmsg.fd_num = fd_num;
if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
if (!has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {
return false;
}
+1 -1
View File
@@ -48,7 +48,7 @@ static DriveInfo *add_init_drive(const char *optstr)
mc = MACHINE_GET_CLASS(current_machine);
dinfo = drive_new(opts, mc->block_default_type, &err);
if (!dinfo) {
if (err) {
error_report_err(err);
qemu_opts_del(opts);
return NULL;
+4
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;
+9 -4
View File
@@ -90,6 +90,7 @@ static void reschedule_dma(void *opaque)
{
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
assert(!dbs->acb && dbs->bh);
qemu_bh_delete(dbs->bh);
dbs->bh = NULL;
dma_blk_cb(dbs, 0);
@@ -111,15 +112,12 @@ static void dma_complete(DMAAIOCB *dbs, int ret)
{
trace_dma_complete(dbs, ret, dbs->common.cb);
assert(!dbs->acb && !dbs->bh);
dma_blk_unmap(dbs);
if (dbs->common.cb) {
dbs->common.cb(dbs->common.opaque, ret);
}
qemu_iovec_destroy(&dbs->iov);
if (dbs->bh) {
qemu_bh_delete(dbs->bh);
dbs->bh = NULL;
}
qemu_aio_unref(dbs);
}
@@ -179,14 +177,21 @@ static void dma_aio_cancel(BlockAIOCB *acb)
trace_dma_aio_cancel(dbs);
assert(!(dbs->acb && dbs->bh));
if (dbs->acb) {
/* This will invoke dma_blk_cb. */
blk_aio_cancel_async(dbs->acb);
return;
}
if (dbs->bh) {
cpu_unregister_map_client(dbs->bh);
qemu_bh_delete(dbs->bh);
dbs->bh = NULL;
}
if (dbs->common.cb) {
dbs->common.cb(dbs->common.opaque, -ECANCELED);
}
}
static AioContext *dma_get_aio_context(BlockAIOCB *acb)
+2 -2
View File
@@ -41,7 +41,7 @@ except NameError:
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use an absolute path starting from qemu_docdir.
#
# sys.path.insert(0, os.path.join(qemu_docdir, "my_subdir"))
sys.path.insert(0, os.path.join(qemu_docdir, "sphinx"))
# -- General configuration ------------------------------------------------
@@ -54,7 +54,7 @@ needs_sphinx = '1.3'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
extensions = ['qmp_lexer']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
+1286 -357
View File
File diff suppressed because it is too large. Load diff
+12
View File
@@ -200,6 +200,18 @@ Not included by default in any Intel CPU model.
Should be explicitly turned on for all Intel CPU models.
Note that not all CPU hardware will support this feature.
@item @code{md-clear}
Required to confirm the MDS (CVE-2018-12126, CVE-2018-12127, CVE-2018-12130,
CVE-2019-11091) fixes.
Not included by default in any Intel CPU model.
Must be explicitly turned on for all Intel CPU models.
Requires the host CPU microcode to support this feature before it
can be used for guest CPUs.
@end table
+43
View File
@@ -0,0 +1,43 @@
# QEMU Monitor Protocol Lexer Extension
#
# Copyright (C) 2019, Red Hat Inc.
#
# Authors:
# Eduardo Habkost <ehabkost@redhat.com>
# John Snow <jsnow@redhat.com>
#
# This work is licensed under the terms of the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
"""qmp_lexer is a Sphinx extension that provides a QMP lexer for code blocks."""
from pygments.lexer import RegexLexer, DelegatingLexer
from pygments.lexers.data import JsonLexer
from pygments import token
from sphinx import errors
class QMPExampleMarkersLexer(RegexLexer):
"""
QMPExampleMarkersLexer lexes QMP example annotations.
This lexer adds support for directionality flow and elision indicators.
"""
tokens = {
'root': [
(r'-> ', token.Generic.Prompt),
(r'<- ', token.Generic.Prompt),
(r' ?\.{3} ?', token.Generic.Prompt),
]
}
class QMPExampleLexer(DelegatingLexer):
"""QMPExampleLexer lexes annotated QMP examples."""
def __init__(self, **options):
super(QMPExampleLexer, self).__init__(JsonLexer, QMPExampleMarkersLexer,
token.Error, **options)
def setup(sphinx):
"""For use by the Sphinx extensions API."""
try:
sphinx.require_sphinx('2.1')
sphinx.add_lexer('QMP', QMPExampleLexer)
except errors.VersionRequirementError:
sphinx.add_lexer('QMP', QMPExampleLexer())
+4 -2
View File
@@ -1825,8 +1825,10 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
p->has_xbzrle_cache_size = true;
visit_type_size(v, param, &cache_size, &err);
if (err || cache_size > INT64_MAX
|| (size_t)cache_size != cache_size) {
if (err) {
break;
}
if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
error_setg(&err, "Invalid size %s", valuestr);
break;
}
+2
View File
@@ -283,6 +283,8 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker,
const BiosLinkerFileEntry *source_file =
bios_linker_find_file(linker, src_file);
assert(dst_file);
assert(source_file);
assert(dst_patched_offset < dst_file->blob->len);
assert(dst_patched_offset + dst_patched_size <= dst_file->blob->len);
assert(src_offset < source_file->blob->len);
+3
View File
@@ -291,6 +291,9 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}
qemu_bh_cancel(s->bh);
notify_guest_bh(s); /* final chance to notify guest */
/* Clean up guest notifier (irq) */
k->set_guest_notifiers(qbus->parent, nvqs, false);
+13 -15
View File
@@ -49,7 +49,6 @@ struct XenBlockDataPlane {
unsigned int *ring_ref;
unsigned int nr_ring_ref;
void *sring;
int64_t file_blk;
int protocol;
blkif_back_rings_t rings;
int more_work;
@@ -168,7 +167,7 @@ static int xen_block_parse_request(XenBlockRequest *request)
goto err;
}
request->start = request->req.sector_number * dataplane->file_blk;
request->start = request->req.sector_number * XEN_BLKIF_SECTOR_SIZE;
for (i = 0; i < request->req.nr_segments; i++) {
if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
error_report("error: nr_segments too big");
@@ -178,14 +177,14 @@ static int xen_block_parse_request(XenBlockRequest *request)
error_report("error: first > last sector");
goto err;
}
if (request->req.seg[i].last_sect * dataplane->file_blk >=
if (request->req.seg[i].last_sect * XEN_BLKIF_SECTOR_SIZE >=
XC_PAGE_SIZE) {
error_report("error: page crossing");
goto err;
}
len = (request->req.seg[i].last_sect -
request->req.seg[i].first_sect + 1) * dataplane->file_blk;
request->req.seg[i].first_sect + 1) * XEN_BLKIF_SECTOR_SIZE;
request->size += len;
}
if (request->start + request->size > blk_getlength(dataplane->blk)) {
@@ -205,7 +204,6 @@ static int xen_block_copy_request(XenBlockRequest *request)
XenDevice *xendev = dataplane->xendev;
XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
int i, count;
int64_t file_blk = dataplane->file_blk;
bool to_domain = (request->req.operation == BLKIF_OP_READ);
void *virt = request->buf;
Error *local_err = NULL;
@@ -220,16 +218,17 @@ static int xen_block_copy_request(XenBlockRequest *request)
if (to_domain) {
segs[i].dest.foreign.ref = request->req.seg[i].gref;
segs[i].dest.foreign.offset = request->req.seg[i].first_sect *
file_blk;
XEN_BLKIF_SECTOR_SIZE;
segs[i].source.virt = virt;
} else {
segs[i].source.foreign.ref = request->req.seg[i].gref;
segs[i].source.foreign.offset = request->req.seg[i].first_sect *
file_blk;
XEN_BLKIF_SECTOR_SIZE;
segs[i].dest.virt = virt;
}
segs[i].len = (request->req.seg[i].last_sect -
request->req.seg[i].first_sect + 1) * file_blk;
request->req.seg[i].first_sect + 1) *
XEN_BLKIF_SECTOR_SIZE;
virt += segs[i].len;
}
@@ -331,22 +330,22 @@ static bool xen_block_split_discard(XenBlockRequest *request,
XenBlockDataPlane *dataplane = request->dataplane;
int64_t byte_offset;
int byte_chunk;
uint64_t byte_remaining, limit;
uint64_t byte_remaining;
uint64_t sec_start = sector_number;
uint64_t sec_count = nr_sectors;
/* Wrap around, or overflowing byte limit? */
if (sec_start + sec_count < sec_count ||
sec_start + sec_count > INT64_MAX / dataplane->file_blk) {
sec_start + sec_count > INT64_MAX / XEN_BLKIF_SECTOR_SIZE) {
return false;
}
limit = BDRV_REQUEST_MAX_SECTORS * dataplane->file_blk;
byte_offset = sec_start * dataplane->file_blk;
byte_remaining = sec_count * dataplane->file_blk;
byte_offset = sec_start * XEN_BLKIF_SECTOR_SIZE;
byte_remaining = sec_count * XEN_BLKIF_SECTOR_SIZE;
do {
byte_chunk = byte_remaining > limit ? limit : byte_remaining;
byte_chunk = byte_remaining > BDRV_REQUEST_MAX_BYTES ?
BDRV_REQUEST_MAX_BYTES : byte_remaining;
request->aio_inflight++;
blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
xen_block_complete_aio, request);
@@ -632,7 +631,6 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev,
XenBlockDataPlane *dataplane = g_new0(XenBlockDataPlane, 1);
dataplane->xendev = xendev;
dataplane->file_blk = conf->logical_block_size;
dataplane->blk = conf->blk;
QLIST_INIT(&dataplane->inflight);
+17 -5
View File
@@ -149,7 +149,7 @@ static void xen_block_set_size(XenBlockDevice *blockdev)
const char *type = object_get_typename(OBJECT(blockdev));
XenBlockVdev *vdev = &blockdev->props.vdev;
BlockConf *conf = &blockdev->props.conf;
int64_t sectors = blk_getlength(conf->blk) / conf->logical_block_size;
int64_t sectors = blk_getlength(conf->blk) / XEN_BLKIF_SECTOR_SIZE;
XenDevice *xendev = XEN_DEVICE(blockdev);
trace_xen_block_size(type, vdev->disk, vdev->partition, sectors);
@@ -223,6 +223,12 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
blkconf_blocksizes(conf);
if (conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) {
error_setg(errp, "logical_block_size != %u not supported",
XEN_BLKIF_SECTOR_SIZE);
return;
}
if (conf->logical_block_size > conf->physical_block_size) {
error_setg(
errp, "logical_block_size > physical_block_size not supported");
@@ -232,8 +238,14 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
blk_set_dev_ops(conf->blk, &xen_block_dev_ops, blockdev);
blk_set_guest_block_size(conf->blk, conf->logical_block_size);
if (conf->discard_granularity > 0) {
if (conf->discard_granularity == -1) {
conf->discard_granularity = conf->physical_block_size;
}
if (blk_get_flags(conf->blk) & BDRV_O_UNMAP) {
xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
xen_device_backend_printf(xendev, "discard-granularity", "%u",
conf->discard_granularity);
}
xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
@@ -247,7 +259,7 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
blockdev->device_type);
xen_device_backend_printf(xendev, "sector-size", "%u",
conf->logical_block_size);
XEN_BLKIF_SECTOR_SIZE);
xen_block_set_size(blockdev);
@@ -755,6 +767,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
drive->id = g_strdup(id);
file_layer = qdict_new();
driver_layer = qdict_new();
qdict_put_str(file_layer, "driver", "file");
qdict_put_str(file_layer, "filename", filename);
@@ -782,6 +795,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
if (!qemu_strtoul(discard_enable, NULL, 2, &value) && !!value) {
qdict_put_str(file_layer, "discard", "unmap");
qdict_put_str(driver_layer, "discard", "unmap");
}
}
@@ -791,8 +805,6 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
*/
qdict_put_str(file_layer, "locking", "off");
driver_layer = qdict_new();
qdict_put_str(driver_layer, "driver", driver);
g_free(driver);
+2
View File
@@ -143,4 +143,6 @@ static inline void blkif_get_x86_64_req(blkif_request_t *dst,
}
}
#define XEN_BLKIF_SECTOR_SIZE 512
#endif /* XEN_BLKIF_H */
+1 -1
View File
@@ -1240,7 +1240,7 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
if (rom->addr + rom->romsize < addr) {
continue;
}
if (rom->addr > end) {
if (rom->addr > end || rom->addr < addr) {
break;
}
+7 -1
View File
@@ -24,6 +24,11 @@
#include "hw/pci/pci.h"
#include "hw/mem/nvdimm.h"
GlobalProperty hw_compat_4_0[] = {
{ "virtio-balloon-device", "qemu-4-0-config-size", "true" },
};
const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0);
GlobalProperty hw_compat_3_1[] = {
{ "pcie-root-port", "x-speed", "2_5" },
{ "pcie-root-port", "x-width", "1" },
@@ -33,9 +38,10 @@ GlobalProperty hw_compat_3_1[] = {
{ "tpm-tis", "ppi", "false" },
{ "usb-kbd", "serial", "42" },
{ "usb-mouse", "serial", "42" },
{ "usb-kbd", "serial", "42" },
{ "usb-tablet", "serial", "42" },
{ "virtio-blk-device", "discard", "false" },
{ "virtio-blk-device", "write-zeroes", "false" },
{ "virtio-balloon-device", "qemu-4-0-config-size", "false" },
};
const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1);
+11 -4
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;
}
+13 -4
View File
@@ -743,10 +743,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;
}
}
/*
@@ -1895,10 +1901,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) {
+23 -9
View File
@@ -162,6 +162,15 @@ static inline void vtd_iommu_unlock(IntelIOMMUState *s)
qemu_mutex_unlock(&s->iommu_lock);
}
static void vtd_update_scalable_state(IntelIOMMUState *s)
{
uint64_t val = vtd_get_quad_raw(s, DMAR_RTADDR_REG);
if (s->scalable_mode) {
s->root_scalable = val & VTD_RTADDR_SMT;
}
}
/* Whether the address space needs to notify new mappings */
static inline gboolean vtd_as_has_map_notifier(VTDAddressSpace *as)
{
@@ -1709,13 +1718,11 @@ error:
static void vtd_root_table_setup(IntelIOMMUState *s)
{
s->root = vtd_get_quad_raw(s, DMAR_RTADDR_REG);
s->root_extended = s->root & VTD_RTADDR_RTT;
if (s->scalable_mode) {
s->root_scalable = s->root & VTD_RTADDR_SMT;
}
s->root &= VTD_RTADDR_ADDR_MASK(s->aw_bits);
trace_vtd_reg_dmar_root(s->root, s->root_extended);
vtd_update_scalable_state(s);
trace_vtd_reg_dmar_root(s->root, s->root_scalable);
}
static void vtd_iec_notify_all(IntelIOMMUState *s, bool global,
@@ -2919,7 +2926,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
IntelIOMMUState *s = vtd_as->iommu_state;
if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
error_report("We need to set caching-mode=1 for intel-iommu to enable "
error_report("We need to set caching-mode=on for intel-iommu to enable "
"device assignment with IOMMU protection.");
exit(1);
}
@@ -2945,6 +2952,15 @@ static int vtd_post_load(void *opaque, int version_id)
*/
vtd_switch_address_space_all(iommu);
/*
* We don't need to migrate the root_scalable because we can
* simply do the calculation after the loading is complete. We
* can actually do similar things with root, dmar_enabled, etc.
* however since we've had them already so we'd better keep them
* for compatibility of migration.
*/
vtd_update_scalable_state(iommu);
return 0;
}
@@ -2965,8 +2981,7 @@ static const VMStateDescription vtd_vmstate = {
VMSTATE_UINT16(next_frcd_reg, IntelIOMMUState),
VMSTATE_UINT8_ARRAY(csr, IntelIOMMUState, DMAR_REG_SIZE),
VMSTATE_UINT8(iq_last_desc_type, IntelIOMMUState),
VMSTATE_BOOL(root_extended, IntelIOMMUState),
VMSTATE_BOOL(root_scalable, IntelIOMMUState),
VMSTATE_UNUSED(1), /* bool root_extended is obsolete by VT-d */
VMSTATE_BOOL(dmar_enabled, IntelIOMMUState),
VMSTATE_BOOL(qi_enabled, IntelIOMMUState),
VMSTATE_BOOL(intr_enabled, IntelIOMMUState),
@@ -3487,7 +3502,6 @@ static void vtd_init(IntelIOMMUState *s)
memset(s->womask, 0, DMAR_REG_SIZE);
s->root = 0;
s->root_extended = false;
s->root_scalable = false;
s->dmar_enabled = false;
s->intr_enabled = false;
-1
View File
@@ -171,7 +171,6 @@
#define VTD_CCMD_FM(val) (((val) >> 32) & 3ULL)
/* RTADDR_REG */
#define VTD_RTADDR_RTT (1ULL << 11)
#define VTD_RTADDR_SMT (1ULL << 10)
#define VTD_RTADDR_ADDR_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL)
+10 -2
View File
@@ -115,6 +115,9 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
/* Physical Address of PVH entry point read from kernel ELF NOTE */
static size_t pvh_start_addr;
GlobalProperty pc_compat_4_0[] = {};
const size_t pc_compat_4_0_len = G_N_ELEMENTS(pc_compat_4_0);
GlobalProperty pc_compat_3_1[] = {
{ "intel-iommu", "dma-drain", "off" },
{ "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" },
@@ -2078,6 +2081,7 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
const MachineState *ms = MACHINE(hotplug_dev);
const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
const uint64_t legacy_align = TARGET_PAGE_SIZE;
Error *local_err = NULL;
/*
* When -no-acpi is used with Q35 machine type, no ACPI is built,
@@ -2090,13 +2094,17 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
hotplug_handler_pre_plug(pcms->acpi_dev, dev, errp);
if (is_nvdimm && !ms->nvdimms_state->is_enabled) {
error_setg(errp, "nvdimm is not enabled: missing 'nvdimm' in '-M'");
return;
}
hotplug_handler_pre_plug(pcms->acpi_dev, dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev),
pcmc->enforce_aligned_dimm ? NULL : &legacy_align, errp);
}
+14 -2
View File
@@ -357,7 +357,7 @@ static void pc_q35_machine_options(MachineClass *m)
m->units_per_default_bus = 1;
m->default_machine_opts = "firmware=bios-256k.bin";
m->default_display = "std";
m->default_kernel_irqchip_split = true;
m->default_kernel_irqchip_split = false;
m->no_floppy = 1;
machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
@@ -365,12 +365,24 @@ static void pc_q35_machine_options(MachineClass *m)
m->max_cpus = 288;
}
static void pc_q35_4_0_machine_options(MachineClass *m)
static void pc_q35_4_0_1_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
m->alias = "q35";
}
DEFINE_Q35_MACHINE(v4_0_1, "pc-q35-4.0.1", NULL,
pc_q35_4_0_1_machine_options);
static void pc_q35_4_0_machine_options(MachineClass *m)
{
pc_q35_4_0_1_machine_options(m);
m->default_kernel_irqchip_split = true;
m->alias = NULL;
compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
}
DEFINE_Q35_MACHINE(v4_0, "pc-q35-4.0", NULL,
pc_q35_4_0_machine_options);
+1 -1
View File
@@ -45,7 +45,7 @@ vtd_pt_enable_fast_path(uint16_t sid, bool success) "sid 0x%"PRIu16" %d"
vtd_irq_generate(uint64_t addr, uint64_t data) "addr 0x%"PRIx64" data 0x%"PRIx64
vtd_reg_read(uint64_t addr, uint64_t size) "addr 0x%"PRIx64" size 0x%"PRIx64
vtd_reg_write(uint64_t addr, uint64_t size, uint64_t val) "addr 0x%"PRIx64" size 0x%"PRIx64" value 0x%"PRIx64
vtd_reg_dmar_root(uint64_t addr, bool extended) "addr 0x%"PRIx64" extended %d"
vtd_reg_dmar_root(uint64_t addr, bool scalable) "addr 0x%"PRIx64" scalable %d"
vtd_reg_ir_root(uint64_t addr, uint32_t size) "addr 0x%"PRIx64" size 0x%"PRIx32
vtd_reg_write_gcmd(uint32_t status, uint32_t val) "status 0x%"PRIx32" value 0x%"PRIx32
vtd_reg_write_fectl(uint32_t value) "value 0x%"PRIx32
-3
View File
@@ -1022,9 +1022,6 @@ static void ncq_cb(void *opaque, int ret)
IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
ncq_tfs->aiocb = NULL;
if (ret == -ECANCELED) {
return;
}
if (ret < 0) {
bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED;
-14
View File
@@ -722,9 +722,6 @@ static void ide_sector_read_cb(void *opaque, int ret)
s->pio_aiocb = NULL;
s->status &= ~BUSY_STAT;
if (ret == -ECANCELED) {
return;
}
if (ret != 0) {
if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO |
IDE_RETRY_READ)) {
@@ -840,10 +837,6 @@ static void ide_dma_cb(void *opaque, int ret)
uint64_t offset;
bool stay_active = false;
if (ret == -ECANCELED) {
return;
}
if (ret == -EINVAL) {
ide_dma_error(s);
return;
@@ -975,10 +968,6 @@ static void ide_sector_write_cb(void *opaque, int ret)
IDEState *s = opaque;
int n;
if (ret == -ECANCELED) {
return;
}
s->pio_aiocb = NULL;
s->status &= ~BUSY_STAT;
@@ -1058,9 +1047,6 @@ static void ide_flush_cb(void *opaque, int ret)
s->pio_aiocb = NULL;
if (ret == -ECANCELED) {
return;
}
if (ret < 0) {
/* XXX: What sector number to set here? */
if (ide_handle_rw_error(s, -ret, IDE_RETRY_FLUSH)) {
+5 -3
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);
}
+1 -2
View File
@@ -1144,8 +1144,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
}
if (xive_end_is_enqueue(end)) {
args[1] = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
| be32_to_cpu(end->w3);
args[1] = xive_end_qaddr(end);
args[2] = xive_get_field32(END_W0_QSIZE, end->w0) + 12;
} else {
args[1] = 0;
+3 -6
View File
@@ -1042,8 +1042,7 @@ static const TypeInfo xive_source_info = {
void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon)
{
uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
| be32_to_cpu(end->w3);
uint64_t qaddr_base = xive_end_qaddr(end);
uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
uint32_t qentries = 1 << (qsize + 10);
@@ -1072,8 +1071,7 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon)
void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon)
{
uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
| be32_to_cpu(end->w3);
uint64_t qaddr_base = xive_end_qaddr(end);
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
@@ -1101,8 +1099,7 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon)
static void xive_end_enqueue(XiveEND *end, uint32_t data)
{
uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
| be32_to_cpu(end->w3);
uint64_t qaddr_base = xive_end_qaddr(end);
uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
+7
View File
@@ -37,6 +37,13 @@ void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
slot = object_property_get_int(OBJECT(dimm), PC_DIMM_SLOT_PROP,
&error_abort);
if ((slot < 0 || slot >= machine->ram_slots) &&
slot != PC_DIMM_UNASSIGNED_SLOT) {
error_setg(&local_err, "invalid slot number, valid range is [0-%"
PRIu64 "]", machine->ram_slots - 1);
goto out;
}
slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot,
machine->ram_slots, &local_err);
if (local_err) {
+1 -1
View File
@@ -2281,7 +2281,7 @@ static void virtio_net_change_num_queues(VirtIONet *n, int new_max_queues)
/*
* We always need to remove and add ctrl vq if
* old_num_queues != new_num_queues. Remove ctrl_vq first,
* and then we only enter one of the following too loops.
* and then we only enter one of the following two loops.
*/
virtio_del_queue(vdev, old_num_queues - 1);
+3 -1
View File
@@ -178,6 +178,7 @@ static void fw_cfg_reboot(FWCfgState *s)
{
const char *reboot_timeout = NULL;
int64_t rt_val = -1;
uint32_t rt_le32;
/* get user configuration */
QemuOptsList *plist = qemu_find_opts("boot-opts");
@@ -194,7 +195,8 @@ static void fw_cfg_reboot(FWCfgState *s)
}
}
fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&rt_val, 4), 4);
rt_le32 = cpu_to_le32(rt_val);
fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&rt_le32, 4), 4);
}
static void fw_cfg_write(FWCfgState *s, uint8_t value)
+24
View File
@@ -147,6 +147,11 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
return NUMA_NODE_UNASSIGNED;
}
static bool pcibus_allows_extended_config_space(PCIBus *bus)
{
return false;
}
static void pci_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
@@ -162,6 +167,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
pbc->is_root = pcibus_is_root;
pbc->bus_num = pcibus_num;
pbc->numa_node = pcibus_numa_node;
pbc->allows_extended_config_space = pcibus_allows_extended_config_space;
}
static const TypeInfo pci_bus_info = {
@@ -182,9 +188,22 @@ static const TypeInfo conventional_pci_interface_info = {
.parent = TYPE_INTERFACE,
};
static bool pciebus_allows_extended_config_space(PCIBus *bus)
{
return true;
}
static void pcie_bus_class_init(ObjectClass *klass, void *data)
{
PCIBusClass *pbc = PCI_BUS_CLASS(klass);
pbc->allows_extended_config_space = pciebus_allows_extended_config_space;
}
static const TypeInfo pcie_bus_info = {
.name = TYPE_PCIE_BUS,
.parent = TYPE_PCI_BUS,
.class_init = pcie_bus_class_init,
};
static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
@@ -401,6 +420,11 @@ bool pci_bus_is_root(PCIBus *bus)
return PCI_BUS_GET_CLASS(bus)->is_root(bus);
}
bool pci_bus_allows_extended_config_space(PCIBus *bus)
{
return PCI_BUS_GET_CLASS(bus)->allows_extended_config_space(bus);
}
void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
const char *name,
MemoryRegion *address_space_mem,
+1 -1
View File
@@ -54,7 +54,7 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr)
static void pci_adjust_config_limit(PCIBus *bus, uint32_t *limit)
{
if (*limit > PCI_CONFIG_SPACE_SIZE) {
if (!pci_bus_is_express(bus)) {
if (!pci_bus_allows_extended_config_space(bus)) {
*limit = PCI_CONFIG_SPACE_SIZE;
return;
}
+25 -1
View File
@@ -1638,6 +1638,28 @@ static void spapr_phb_unrealize(DeviceState *dev, Error **errp)
memory_region_del_subregion(get_system_memory(), &sphb->mem32window);
}
static bool spapr_phb_allows_extended_config_space(PCIBus *bus)
{
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(BUS(bus)->parent);
return sphb->pcie_ecs;
}
static void spapr_phb_root_bus_class_init(ObjectClass *klass, void *data)
{
PCIBusClass *pbc = PCI_BUS_CLASS(klass);
pbc->allows_extended_config_space = spapr_phb_allows_extended_config_space;
}
#define TYPE_SPAPR_PHB_ROOT_BUS "pci"
static const TypeInfo spapr_phb_root_bus_info = {
.name = TYPE_SPAPR_PHB_ROOT_BUS,
.parent = TYPE_PCI_BUS,
.class_init = spapr_phb_root_bus_class_init,
};
static void spapr_phb_realize(DeviceState *dev, Error **errp)
{
/* We don't use SPAPR_MACHINE() in order to exit gracefully if the user
@@ -1742,7 +1764,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
bus = pci_register_root_bus(dev, NULL,
pci_spapr_set_irq, pci_spapr_map_irq, sphb,
&sphb->memspace, &sphb->iospace,
PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
PCI_DEVFN(0, 0), PCI_NUM_PINS,
TYPE_SPAPR_PHB_ROOT_BUS);
phb->bus = bus;
qbus_set_hotplug_handler(BUS(phb->bus), OBJECT(sphb), NULL);
@@ -2325,6 +2348,7 @@ void spapr_pci_rtas_init(void)
static void spapr_pci_register_types(void)
{
type_register_static(&spapr_phb_info);
type_register_static(&spapr_phb_root_bus_info);
}
type_init(spapr_pci_register_types)
+11 -5
View File
@@ -207,7 +207,7 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
if (addr >= plic->priority_base && /* 4 bytes per source */
addr < plic->priority_base + (plic->num_sources << 2))
{
uint32_t irq = (addr - plic->priority_base) >> 2;
uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
if (RISCV_DEBUG_PLIC) {
qemu_log("plic: read priority: irq=%d priority=%d\n",
irq, plic->source_priority[irq]);
@@ -263,7 +263,9 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
}
err:
error_report("plic: invalid register read: %08x", (uint32_t)addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Invalid register read 0x%" HWADDR_PRIx "\n",
__func__, addr);
return 0;
}
@@ -280,7 +282,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
if (addr >= plic->priority_base && /* 4 bytes per source */
addr < plic->priority_base + (plic->num_sources << 2))
{
uint32_t irq = (addr - plic->priority_base) >> 2;
uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
plic->source_priority[irq] = value & 7;
if (RISCV_DEBUG_PLIC) {
qemu_log("plic: write priority: irq=%d priority=%d\n",
@@ -290,7 +292,9 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
} else if (addr >= plic->pending_base && /* 1 bit per source */
addr < plic->pending_base + (plic->num_sources >> 3))
{
error_report("plic: invalid pending write: %08x", (uint32_t)addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid pending write: 0x%" HWADDR_PRIx "",
__func__, addr);
return;
} else if (addr >= plic->enable_base && /* 1 bit per source */
addr < plic->enable_base + plic->num_addrs * plic->enable_stride)
@@ -340,7 +344,9 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
}
err:
error_report("plic: invalid register write: %08x", (uint32_t)addr);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Invalid register write 0x%" HWADDR_PRIx "\n",
__func__, addr);
}
static const MemoryRegionOps sifive_plic_ops = {
+4 -4
View File
@@ -78,13 +78,13 @@ static int emulated_ccw_3270_cb(SubchDev *sch, CCW1 ccw)
if (rc == -EIO) {
/* I/O error, specific devices generate specific conditions */
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
sch->curr_status.scsw.dstat = SCSW_DSTAT_UNIT_CHECK;
sch->sense_data[0] = 0x40; /* intervention-req */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
}
+187 -201
View File
@@ -695,35 +695,32 @@ void css_adapter_interrupt(CssIoAdapterType type, uint8_t isc)
static void sch_handle_clear_func(SubchDev *sch)
{
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
int path;
/* Path management: In our simple css, we always choose the only path. */
path = 0x80;
/* Reset values prior to 'issuing the clear signal'. */
p->lpum = 0;
p->pom = 0xff;
s->flags &= ~SCSW_FLAGS_MASK_PNO;
schib->pmcw.lpum = 0;
schib->pmcw.pom = 0xff;
schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
/* We always 'attempt to issue the clear signal', and we always succeed. */
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
s->ctrl |= SCSW_STCTL_STATUS_PEND;
schib->scsw.ctrl &= ~SCSW_ACTL_CLEAR_PEND;
schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;
s->dstat = 0;
s->cstat = 0;
p->lpum = path;
schib->scsw.dstat = 0;
schib->scsw.cstat = 0;
schib->pmcw.lpum = path;
}
static void sch_handle_halt_func(SubchDev *sch)
{
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
hwaddr curr_ccw = sch->channel_prog;
int path;
@@ -733,20 +730,22 @@ static void sch_handle_halt_func(SubchDev *sch)
/* We always 'attempt to issue the halt signal', and we always succeed. */
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
s->ctrl &= ~SCSW_ACTL_HALT_PEND;
s->ctrl |= SCSW_STCTL_STATUS_PEND;
schib->scsw.ctrl &= ~SCSW_ACTL_HALT_PEND;
schib->scsw.ctrl |= SCSW_STCTL_STATUS_PEND;
if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
!((s->ctrl & SCSW_ACTL_START_PEND) ||
(s->ctrl & SCSW_ACTL_SUSP))) {
s->dstat = SCSW_DSTAT_DEVICE_END;
if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
SCSW_ACTL_DEVICE_ACTIVE)) ||
!((schib->scsw.ctrl & SCSW_ACTL_START_PEND) ||
(schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
schib->scsw.dstat = SCSW_DSTAT_DEVICE_END;
}
if ((s->ctrl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
(s->ctrl & SCSW_ACTL_SUSP)) {
s->cpa = curr_ccw + 8;
if ((schib->scsw.ctrl & (SCSW_ACTL_SUBCH_ACTIVE |
SCSW_ACTL_DEVICE_ACTIVE)) ||
(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
schib->scsw.cpa = curr_ccw + 8;
}
s->cstat = 0;
p->lpum = path;
schib->scsw.cstat = 0;
schib->pmcw.lpum = path;
}
@@ -1111,9 +1110,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
static void sch_handle_start_func_virtual(SubchDev *sch)
{
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
int path;
int ret;
bool suspend_allowed;
@@ -1121,27 +1118,27 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
/* Path management: In our simple css, we always choose the only path. */
path = 0x80;
if (!(s->ctrl & SCSW_ACTL_SUSP)) {
if (!(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
/* Start Function triggered via ssch, i.e. we have an ORB */
ORB *orb = &sch->orb;
s->cstat = 0;
s->dstat = 0;
schib->scsw.cstat = 0;
schib->scsw.dstat = 0;
/* Look at the orb and try to execute the channel program. */
p->intparm = orb->intparm;
schib->pmcw.intparm = orb->intparm;
if (!(orb->lpm & path)) {
/* Generate a deferred cc 3 condition. */
s->flags |= SCSW_FLAGS_MASK_CC;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
return;
}
sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
s->flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0;
schib->scsw.flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0;
sch->ccw_no_data_cnt = 0;
suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND);
} else {
/* Start Function resumed via rsch */
s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
schib->scsw.ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
/* The channel program had been suspended before. */
suspend_allowed = true;
}
@@ -1154,40 +1151,40 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
break;
case 0:
/* success */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_STATUS_PEND;
s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
s->cpa = sch->channel_prog + 8;
schib->scsw.dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
schib->scsw.cpa = sch->channel_prog + 8;
break;
case -EIO:
/* I/O errors, status depends on specific devices */
break;
case -ENOSYS:
/* unsupported command, generate unit check (command reject) */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->dstat = SCSW_DSTAT_UNIT_CHECK;
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.dstat = SCSW_DSTAT_UNIT_CHECK;
/* Set sense bit 0 in ecw0. */
sch->sense_data[0] = 0x80;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
s->cpa = sch->channel_prog + 8;
schib->scsw.cpa = sch->channel_prog + 8;
break;
case -EINPROGRESS:
/* channel program has been suspended */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->ctrl |= SCSW_ACTL_SUSP;
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.ctrl |= SCSW_ACTL_SUSP;
break;
default:
/* error, generate channel program check */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_PROG_CHECK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
s->cpa = sch->channel_prog + 8;
schib->scsw.cpa = sch->channel_prog + 8;
break;
}
} while (ret == -EAGAIN);
@@ -1196,14 +1193,11 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
{
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
ORB *orb = &sch->orb;
if (!(s->ctrl & SCSW_ACTL_SUSP)) {
if (!(schib->scsw.ctrl & SCSW_ACTL_SUSP)) {
assert(orb != NULL);
p->intparm = orb->intparm;
schib->pmcw.intparm = orb->intparm;
}
return s390_ccw_cmd_request(sch);
}
@@ -1216,14 +1210,13 @@ static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
*/
IOInstEnding do_subchannel_work_virtual(SubchDev *sch)
{
SCHIB *schib = &sch->curr_status;
SCSW *s = &sch->curr_status.scsw;
if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
sch_handle_clear_func(sch);
} else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
} else if (schib->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
sch_handle_halt_func(sch);
} else if (s->ctrl & SCSW_FCTL_START_FUNC) {
} else if (schib->scsw.ctrl & SCSW_FCTL_START_FUNC) {
/* Triggered by both ssch and rsch. */
sch_handle_start_func_virtual(sch);
}
@@ -1234,15 +1227,15 @@ IOInstEnding do_subchannel_work_virtual(SubchDev *sch)
IOInstEnding do_subchannel_work_passthrough(SubchDev *sch)
{
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
/* TODO: Clear handling */
sch_handle_clear_func(sch);
} else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
} else if (schib->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
/* TODO: Halt handling */
sch_handle_halt_func(sch);
} else if (s->ctrl & SCSW_FCTL_START_FUNC) {
} else if (schib->scsw.ctrl & SCSW_FCTL_START_FUNC) {
return sch_handle_start_func_passthrough(sch);
}
return IOINST_CC_EXPECTED;
@@ -1370,46 +1363,45 @@ static void copy_schib_from_guest(SCHIB *dest, const SCHIB *src)
IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
uint16_t oldflags;
SCHIB schib;
SCHIB schib_copy;
if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
if (!(schib->pmcw.flags & PMCW_FLAGS_MASK_DNV)) {
return IOINST_CC_EXPECTED;
}
if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
return IOINST_CC_STATUS_PRESENT;
}
if (s->ctrl &
if (schib->scsw.ctrl &
(SCSW_FCTL_START_FUNC|SCSW_FCTL_HALT_FUNC|SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY;
}
copy_schib_from_guest(&schib, orig_schib);
copy_schib_from_guest(&schib_copy, orig_schib);
/* Only update the program-modifiable fields. */
p->intparm = schib.pmcw.intparm;
oldflags = p->flags;
p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
schib->pmcw.intparm = schib_copy.pmcw.intparm;
oldflags = schib->pmcw.flags;
schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP);
p->flags |= schib.pmcw.flags &
schib->pmcw.flags |= schib_copy.pmcw.flags &
(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP);
p->lpm = schib.pmcw.lpm;
p->mbi = schib.pmcw.mbi;
p->pom = schib.pmcw.pom;
p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
p->chars |= schib.pmcw.chars &
schib->pmcw.lpm = schib_copy.pmcw.lpm;
schib->pmcw.mbi = schib_copy.pmcw.mbi;
schib->pmcw.pom = schib_copy.pmcw.pom;
schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
schib->pmcw.chars |= schib_copy.pmcw.chars &
(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
sch->curr_status.mba = schib.mba;
schib->mba = schib_copy.mba;
/* Has the channel been disabled? */
if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
&& (p->flags & PMCW_FLAGS_MASK_ENA) == 0) {
&& (schib->pmcw.flags & PMCW_FLAGS_MASK_ENA) == 0) {
sch->disable_cb(sch);
}
return IOINST_CC_EXPECTED;
@@ -1417,82 +1409,80 @@ IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *orig_schib)
IOInstEnding css_do_xsch(SubchDev *sch)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
if (s->ctrl & SCSW_CTRL_MASK_STCTL) {
if (schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) {
return IOINST_CC_STATUS_PRESENT;
}
if (!(s->ctrl & SCSW_CTRL_MASK_FCTL) ||
((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
(!(s->ctrl &
if (!(schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) ||
((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
(!(schib->scsw.ctrl &
(SCSW_ACTL_RESUME_PEND | SCSW_ACTL_START_PEND | SCSW_ACTL_SUSP))) ||
(s->ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
(schib->scsw.ctrl & SCSW_ACTL_SUBCH_ACTIVE)) {
return IOINST_CC_BUSY;
}
/* Cancel the current operation. */
s->ctrl &= ~(SCSW_FCTL_START_FUNC |
schib->scsw.ctrl &= ~(SCSW_FCTL_START_FUNC |
SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND |
SCSW_ACTL_SUSP);
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
s->dstat = 0;
s->cstat = 0;
schib->scsw.dstat = 0;
schib->scsw.cstat = 0;
return IOINST_CC_EXPECTED;
}
IOInstEnding css_do_csch(SubchDev *sch)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
/* Trigger the clear function. */
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
schib->scsw.ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
schib->scsw.ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
return do_subchannel_work(sch);
}
IOInstEnding css_do_hsch(SubchDev *sch)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
if (((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
(s->ctrl & (SCSW_STCTL_PRIMARY |
if (((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||
(schib->scsw.ctrl & (SCSW_STCTL_PRIMARY |
SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT))) {
return IOINST_CC_STATUS_PRESENT;
}
if (s->ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
if (schib->scsw.ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY;
}
/* Trigger the halt function. */
s->ctrl |= SCSW_FCTL_HALT_FUNC;
s->ctrl &= ~SCSW_FCTL_START_FUNC;
if (((s->ctrl & SCSW_CTRL_MASK_ACTL) ==
schib->scsw.ctrl |= SCSW_FCTL_HALT_FUNC;
schib->scsw.ctrl &= ~SCSW_FCTL_START_FUNC;
if (((schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL) ==
(SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&
((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) {
s->ctrl &= ~SCSW_STCTL_STATUS_PEND;
((schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL) ==
SCSW_STCTL_INTERMEDIATE)) {
schib->scsw.ctrl &= ~SCSW_STCTL_STATUS_PEND;
}
s->ctrl |= SCSW_ACTL_HALT_PEND;
schib->scsw.ctrl |= SCSW_ACTL_HALT_PEND;
return do_subchannel_work(sch);
}
@@ -1534,18 +1524,17 @@ static void css_update_chnmon(SubchDev *sch)
IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
return IOINST_CC_STATUS_PRESENT;
}
if (s->ctrl & (SCSW_FCTL_START_FUNC |
if (schib->scsw.ctrl & (SCSW_FCTL_START_FUNC |
SCSW_FCTL_HALT_FUNC |
SCSW_FCTL_CLEAR_FUNC)) {
return IOINST_CC_BUSY;
@@ -1558,13 +1547,13 @@ IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb)
sch->orb = *orb;
sch->channel_prog = orb->cpa;
/* Trigger the start function. */
s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
s->flags &= ~SCSW_FLAGS_MASK_PNO;
schib->scsw.ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
return do_subchannel_work(sch);
}
static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw,
static void copy_irb_to_guest(IRB *dest, const IRB *src, const PMCW *pmcw,
int *irb_len)
{
int i;
@@ -1603,24 +1592,24 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw,
int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
PMCW p;
uint16_t stctl;
IRB irb;
if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return 3;
}
stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
/* Prepare the irb for the guest. */
memset(&irb, 0, sizeof(IRB));
/* Copy scsw from current status. */
memcpy(&irb.scsw, s, sizeof(SCSW));
irb.scsw = schib->scsw;
if (stctl & SCSW_STCTL_STATUS_PEND) {
if (s->cstat & (SCSW_CSTAT_DATA_CHECK |
if (schib->scsw.cstat & (SCSW_CSTAT_DATA_CHECK |
SCSW_CSTAT_CHN_CTRL_CHK |
SCSW_CSTAT_INTF_CTRL_CHK)) {
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
@@ -1629,8 +1618,8 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
irb.esw[0] = 0x00800000;
}
/* If a unit check is pending, copy sense data. */
if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
(p->chars & PMCW_CHARS_MASK_CSENSE)) {
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
(schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
int i;
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
@@ -1643,34 +1632,34 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
}
}
/* Store the irb to the guest. */
copy_irb_to_guest(target_irb, &irb, p, irb_len);
p = schib->pmcw;
copy_irb_to_guest(target_irb, &irb, &p, irb_len);
return ((stctl & SCSW_STCTL_STATUS_PEND) == 0);
}
void css_do_tsch_update_subch(SubchDev *sch)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
uint16_t stctl;
uint16_t fctl;
uint16_t actl;
stctl = s->ctrl & SCSW_CTRL_MASK_STCTL;
fctl = s->ctrl & SCSW_CTRL_MASK_FCTL;
actl = s->ctrl & SCSW_CTRL_MASK_ACTL;
stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
fctl = schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL;
actl = schib->scsw.ctrl & SCSW_CTRL_MASK_ACTL;
/* Clear conditions on subchannel, if applicable. */
if (stctl & SCSW_STCTL_STATUS_PEND) {
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
if ((stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) ||
((fctl & SCSW_FCTL_HALT_FUNC) &&
(actl & SCSW_ACTL_SUSP))) {
s->ctrl &= ~SCSW_CTRL_MASK_FCTL;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_FCTL;
}
if (stctl != (SCSW_STCTL_INTERMEDIATE | SCSW_STCTL_STATUS_PEND)) {
s->flags &= ~SCSW_FLAGS_MASK_PNO;
s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
schib->scsw.ctrl &= ~(SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND |
SCSW_ACTL_HALT_PEND |
SCSW_ACTL_CLEAR_PEND |
@@ -1678,20 +1667,20 @@ void css_do_tsch_update_subch(SubchDev *sch)
} else {
if ((actl & SCSW_ACTL_SUSP) &&
(fctl & SCSW_FCTL_START_FUNC)) {
s->flags &= ~SCSW_FLAGS_MASK_PNO;
schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO;
if (fctl & SCSW_FCTL_HALT_FUNC) {
s->ctrl &= ~(SCSW_ACTL_RESUME_PEND |
schib->scsw.ctrl &= ~(SCSW_ACTL_RESUME_PEND |
SCSW_ACTL_START_PEND |
SCSW_ACTL_HALT_PEND |
SCSW_ACTL_CLEAR_PEND |
SCSW_ACTL_SUSP);
} else {
s->ctrl &= ~SCSW_ACTL_RESUME_PEND;
schib->scsw.ctrl &= ~SCSW_ACTL_RESUME_PEND;
}
}
}
/* Clear pending sense data. */
if (p->chars & PMCW_CHARS_MASK_CSENSE) {
if (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE) {
memset(sch->sense_data, 0 , sizeof(sch->sense_data));
}
}
@@ -1804,20 +1793,19 @@ void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
IOInstEnding css_do_rsch(SubchDev *sch)
{
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
if (~(p->flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) {
return IOINST_CC_NOT_OPERATIONAL;
}
if (s->ctrl & SCSW_STCTL_STATUS_PEND) {
if (schib->scsw.ctrl & SCSW_STCTL_STATUS_PEND) {
return IOINST_CC_STATUS_PRESENT;
}
if (((s->ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
(s->ctrl & SCSW_ACTL_RESUME_PEND) ||
(!(s->ctrl & SCSW_ACTL_SUSP))) {
if (((schib->scsw.ctrl & SCSW_CTRL_MASK_FCTL) != SCSW_FCTL_START_FUNC) ||
(schib->scsw.ctrl & SCSW_ACTL_RESUME_PEND) ||
(!(schib->scsw.ctrl & SCSW_ACTL_SUSP))) {
return IOINST_CC_BUSY;
}
@@ -1826,7 +1814,7 @@ IOInstEnding css_do_rsch(SubchDev *sch)
css_update_chnmon(sch);
}
s->ctrl |= SCSW_ACTL_RESUME_PEND;
schib->scsw.ctrl |= SCSW_ACTL_RESUME_PEND;
return do_subchannel_work(sch);
}
@@ -1927,28 +1915,27 @@ static int css_add_chpid(uint8_t cssid, uint8_t chpid, uint8_t type,
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
{
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
int i;
CssImage *css = channel_subsys.css[sch->cssid];
assert(css != NULL);
memset(p, 0, sizeof(PMCW));
p->flags |= PMCW_FLAGS_MASK_DNV;
p->devno = sch->devno;
memset(&schib->pmcw, 0, sizeof(PMCW));
schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
schib->pmcw.devno = sch->devno;
/* single path */
p->pim = 0x80;
p->pom = 0xff;
p->pam = 0x80;
p->chpid[0] = chpid;
schib->pmcw.pim = 0x80;
schib->pmcw.pom = 0xff;
schib->pmcw.pam = 0x80;
schib->pmcw.chpid[0] = chpid;
if (!css->chpids[chpid].in_use) {
css_add_chpid(sch->cssid, chpid, type, true);
}
memset(s, 0, sizeof(SCSW));
sch->curr_status.mba = 0;
for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
sch->curr_status.mda[i] = 0;
memset(&schib->scsw, 0, sizeof(SCSW));
schib->mba = 0;
for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
schib->mda[i] = 0;
}
}
@@ -2246,30 +2233,30 @@ int css_enable_mss(void)
void css_reset_sch(SubchDev *sch)
{
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
if ((schib->pmcw.flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
sch->disable_cb(sch);
}
p->intparm = 0;
p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
schib->pmcw.intparm = 0;
schib->pmcw.flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
PMCW_FLAGS_MASK_MP | PMCW_FLAGS_MASK_TF);
p->flags |= PMCW_FLAGS_MASK_DNV;
p->devno = sch->devno;
p->pim = 0x80;
p->lpm = p->pim;
p->pnom = 0;
p->lpum = 0;
p->mbi = 0;
p->pom = 0xff;
p->pam = 0x80;
p->chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
schib->pmcw.devno = sch->devno;
schib->pmcw.pim = 0x80;
schib->pmcw.lpm = schib->pmcw.pim;
schib->pmcw.pnom = 0;
schib->pmcw.lpum = 0;
schib->pmcw.mbi = 0;
schib->pmcw.pom = 0xff;
schib->pmcw.pam = 0x80;
schib->pmcw.chars &= ~(PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_XMWME |
PMCW_CHARS_MASK_CSENSE);
memset(&sch->curr_status.scsw, 0, sizeof(sch->curr_status.scsw));
sch->curr_status.mba = 0;
memset(&schib->scsw, 0, sizeof(schib->scsw));
schib->mba = 0;
sch->channel_prog = 0x0;
sch->last_cmd_valid = false;
@@ -2433,7 +2420,7 @@ static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
FILE *fd;
uint32_t chpid[8];
int i;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/chpids",
dev_id->cssid, dev_id->ssid, dev_id->devid);
@@ -2452,8 +2439,8 @@ static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
return -EINVAL;
}
for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
p->chpid[i] = chpid[i];
for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
schib->pmcw.chpid[i] = chpid[i];
}
fclose(fd);
@@ -2467,7 +2454,7 @@ static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
char *fid_path;
FILE *fd;
uint32_t pim, pam, pom;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/pimpampom",
dev_id->cssid, dev_id->ssid, dev_id->devid);
@@ -2484,9 +2471,9 @@ static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
return -EINVAL;
}
p->pim = pim;
p->pam = pam;
p->pom = pom;
schib->pmcw.pim = pim;
schib->pmcw.pam = pam;
schib->pmcw.pom = pom;
fclose(fd);
g_free(fid_path);
@@ -2528,16 +2515,15 @@ static int css_sch_get_chpid_type(uint8_t chpid, uint32_t *type,
int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
{
CssImage *css = channel_subsys.css[sch->cssid];
PMCW *p = &sch->curr_status.pmcw;
SCSW *s = &sch->curr_status.scsw;
SCHIB *schib = &sch->curr_status;
uint32_t type;
int i, ret;
assert(css != NULL);
memset(p, 0, sizeof(PMCW));
p->flags |= PMCW_FLAGS_MASK_DNV;
memset(&schib->pmcw, 0, sizeof(PMCW));
schib->pmcw.flags |= PMCW_FLAGS_MASK_DNV;
/* We are dealing with I/O subchannels only. */
p->devno = sch->devno;
schib->pmcw.devno = sch->devno;
/* Grab path mask from sysfs. */
ret = css_sch_get_path_masks(sch, dev_id);
@@ -2552,20 +2538,20 @@ int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
}
/* Build chpid type. */
for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
if (p->chpid[i] && !css->chpids[p->chpid[i]].in_use) {
ret = css_sch_get_chpid_type(p->chpid[i], &type, dev_id);
for (i = 0; i < ARRAY_SIZE(schib->pmcw.chpid); i++) {
if (schib->pmcw.chpid[i] && !css->chpids[schib->pmcw.chpid[i]].in_use) {
ret = css_sch_get_chpid_type(schib->pmcw.chpid[i], &type, dev_id);
if (ret) {
return ret;
}
css_add_chpid(sch->cssid, p->chpid[i], type, false);
css_add_chpid(sch->cssid, schib->pmcw.chpid[i], type, false);
}
}
memset(s, 0, sizeof(SCSW));
sch->curr_status.mba = 0;
for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
sch->curr_status.mda[i] = 0;
memset(&schib->scsw, 0, sizeof(SCSW));
schib->mba = 0;
for (i = 0; i < ARRAY_SIZE(schib->mda); i++) {
schib->mda[i] = 0;
}
return 0;
+5 -7
View File
@@ -252,8 +252,6 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
{
QemuOptsList *plist = qemu_find_opts("boot-opts");
QemuOpts *opts = QTAILQ_FIRST(&plist->head);
uint8_t *flags = &ipl->qipl.qipl_flags;
uint32_t *timeout = &ipl->qipl.boot_menu_timeout;
const char *tmp;
unsigned long splash_time = 0;
@@ -269,7 +267,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
case S390_IPL_TYPE_CCW:
/* In the absence of -boot menu, use zipl parameters */
if (!qemu_opt_get(opts, "menu")) {
*flags |= QIPL_FLAG_BM_OPTS_ZIPL;
ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_ZIPL;
return;
}
break;
@@ -286,23 +284,23 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
return;
}
*flags |= QIPL_FLAG_BM_OPTS_CMD;
ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_CMD;
tmp = qemu_opt_get(opts, "splash-time");
if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) {
error_report("splash-time is invalid, forcing it to 0");
*timeout = 0;
ipl->qipl.boot_menu_timeout = 0;
return;
}
if (splash_time > 0xffffffff) {
error_report("splash-time is too large, forcing it to max value");
*timeout = 0xffffffff;
ipl->qipl.boot_menu_timeout = 0xffffffff;
return;
}
*timeout = cpu_to_be32(splash_time);
ipl->qipl.boot_menu_timeout = cpu_to_be32(splash_time);
}
static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
+6 -1
View File
@@ -694,10 +694,15 @@ static const MemoryRegionOps s390_msi_ctrl_ops = {
void s390_pci_iommu_enable(S390PCIIOMMU *iommu)
{
/*
* The iommu region is initialized against a 0-mapped address space,
* so the smallest IOMMU region we can define runs from 0 to the end
* of the PCI address space.
*/
char *name = g_strdup_printf("iommu-s390-%04x", iommu->pbdev->uid);
memory_region_init_iommu(&iommu->iommu_mr, sizeof(iommu->iommu_mr),
TYPE_S390_IOMMU_MEMORY_REGION, OBJECT(&iommu->mr),
name, iommu->pal - iommu->pba + 1);
name, iommu->pal + 1);
iommu->enabled = true;
memory_region_add_subregion(&iommu->mr, 0, MEMORY_REGION(&iommu->iommu_mr));
g_free(name);
+27 -14
View File
@@ -184,6 +184,9 @@ static const char *names[] = {
/* Flag set if this is a tagged command. */
#define LSI_TAG_VALID (1 << 16)
/* Maximum instructions to process. */
#define LSI_MAX_INSN 10000
typedef struct lsi_request {
SCSIRequest *req;
uint32_t tag;
@@ -1131,7 +1134,21 @@ static void lsi_execute_script(LSIState *s)
s->istat1 |= LSI_ISTAT1_SRUN;
again:
insn_processed++;
if (++insn_processed > LSI_MAX_INSN) {
/* Some windows drivers make the device spin waiting for a memory
location to change. If we have been executed a lot of code then
assume this is the case and force an unexpected device disconnect.
This is apparently sufficient to beat the drivers into submission.
*/
if (!(s->sien0 & LSI_SIST0_UDC)) {
qemu_log_mask(LOG_GUEST_ERROR,
"lsi_scsi: inf. loop with UDC masked");
}
lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
lsi_disconnect(s);
trace_lsi_execute_script_stop();
return;
}
insn = read_dword(s, s->dsp);
if (!insn) {
/* If we receive an empty opcode increment the DSP by 4 bytes
@@ -1568,19 +1585,7 @@ again:
}
}
}
if (insn_processed > 10000 && s->waiting == LSI_NOWAIT) {
/* Some windows drivers make the device spin waiting for a memory
location to change. If we have been executed a lot of code then
assume this is the case and force an unexpected device disconnect.
This is apparently sufficient to beat the drivers into submission.
*/
if (!(s->sien0 & LSI_SIST0_UDC)) {
qemu_log_mask(LOG_GUEST_ERROR,
"lsi_scsi: inf. loop with UDC masked");
}
lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
lsi_disconnect(s);
} else if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
if (s->dcntl & LSI_DCNTL_SSM) {
lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
} else {
@@ -1968,6 +1973,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
case 0x2f: /* DSP[24:31] */
s->dsp &= 0x00ffffff;
s->dsp |= val << 24;
/*
* FIXME: if s->waiting != LSI_NOWAIT, this will only execute one
* instruction. Is this correct?
*/
if ((s->dmode & LSI_DMODE_MAN) == 0
&& (s->istat1 & LSI_ISTAT1_SRUN) == 0)
lsi_execute_script(s);
@@ -1986,6 +1995,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
break;
case 0x3b: /* DCNTL */
s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);
/*
* FIXME: if s->waiting != LSI_NOWAIT, this will only execute one
* instruction. Is this correct?
*/
if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
lsi_execute_script(s);
break;
+1 -1
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;
+7 -1
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;
}
+31 -12
View File
@@ -1199,28 +1199,47 @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
}
}
static uint64_t
lqspi_read(void *opaque, hwaddr addr, unsigned int size)
static MemTxResult lqspi_read(void *opaque, hwaddr addr, uint64_t *value,
unsigned size, MemTxAttrs attrs)
{
XilinxQSPIPS *q = opaque;
uint32_t ret;
XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
if (addr >= q->lqspi_cached_addr &&
addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
uint8_t *retp = &q->lqspi_buf[addr - q->lqspi_cached_addr];
ret = cpu_to_le32(*(uint32_t *)retp);
DB_PRINT_L(1, "addr: %08x, data: %08x\n", (unsigned)addr,
(unsigned)ret);
return ret;
} else {
lqspi_load_cache(opaque, addr);
return lqspi_read(opaque, addr, size);
*value = cpu_to_le32(*(uint32_t *)retp);
DB_PRINT_L(1, "addr: %08" HWADDR_PRIx ", data: %08" PRIx64 "\n",
addr, *value);
return MEMTX_OK;
}
lqspi_load_cache(opaque, addr);
return lqspi_read(opaque, addr, value, size, attrs);
}
static MemTxResult lqspi_write(void *opaque, hwaddr offset, uint64_t value,
unsigned size, MemTxAttrs attrs)
{
/*
* From UG1085, Chapter 24 (Quad-SPI controllers):
* - Writes are ignored
* - AXI writes generate an external AXI slave error (SLVERR)
*/
qemu_log_mask(LOG_GUEST_ERROR, "%s Unexpected %u-bit access to 0x%" PRIx64
" (value: 0x%" PRIx64 "\n",
__func__, size << 3, offset, value);
return MEMTX_ERROR;
}
static const MemoryRegionOps lqspi_ops = {
.read = lqspi_read,
.read_with_attrs = lqspi_read,
.write_with_attrs = lqspi_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
.valid = {
.min_access_size = 1,
.max_access_size = 4
+3 -1
View File
@@ -273,7 +273,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)
+50 -10
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)));
}
}
+13
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 */
+3 -1
View File
@@ -909,7 +909,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 */
+9 -2
View File
@@ -1699,12 +1699,19 @@ static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
MTPObject *o;
MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle);
uint32_t next_handle = s->next_handle;
size_t filename_chars = dlen - offsetof(ObjectInfo, filename);
/*
* filename is utf-16. We're intentionally doing
* integer division to truncate if malicious guest
* sent an odd number of bytes.
*/
filename_chars /= 2;
assert(!s->write_pending);
assert(p != NULL);
filename = utf16_to_str(MIN(dataset->length,
dlen - offsetof(ObjectInfo, filename)),
filename = utf16_to_str(MIN(dataset->length, filename_chars),
dataset->filename);
if (strchr(filename, '/')) {
+5
View File
@@ -1494,6 +1494,11 @@ static void usbredir_check_bulk_receiving(USBRedirDevice *dev)
for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) {
dev->endpoint[i].bulk_receiving_enabled = 0;
}
if (dev->interface_info.interface_count == NO_INTERFACE_INFO) {
return;
}
for (i = 0; i < dev->interface_info.interface_count; i++) {
quirks = usb_get_quirks(dev->device_info.vendor_id,
dev->device_info.product_id,
+22 -20
View File
@@ -130,8 +130,8 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
CcwDevice *ccw_dev = CCW_DEVICE(cdev);
SubchDev *sch = ccw_dev->sch;
SCSW *s = &sch->curr_status.scsw;
PMCW *p = &sch->curr_status.pmcw;
SCHIB *schib = &sch->curr_status;
SCSW s;
IRB irb;
int size;
@@ -145,33 +145,33 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
switch (errno) {
case ENODEV:
/* Generate a deferred cc 3 condition. */
s->flags |= SCSW_FLAGS_MASK_CC;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
goto read_err;
case EFAULT:
/* Memory problem, generate channel data check. */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_DATA_CHECK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err;
default:
/* Error, generate channel program check. */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_PROG_CHECK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err;
}
} else if (size != vcdev->io_region_size) {
/* Information transfer error, generate channel-control check. */
s->ctrl &= ~SCSW_ACTL_START_PEND;
s->cstat = SCSW_CSTAT_CHN_CTRL_CHK;
s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK;
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
goto read_err;
}
@@ -179,11 +179,13 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
memcpy(&irb, region->irb_area, sizeof(IRB));
/* Update control block via irb. */
copy_scsw_to_guest(s, &irb.scsw);
s = schib->scsw;
copy_scsw_to_guest(&s, &irb.scsw);
schib->scsw = s;
/* If a uint check is pending, copy sense data. */
if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
(p->chars & PMCW_CHARS_MASK_CSENSE)) {
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
(schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
}
+10
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);
}
+80 -63
View File
@@ -34,31 +34,53 @@
#define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT)
struct PartiallyBalloonedPage {
RAMBlock *rb;
ram_addr_t base;
unsigned long bitmap[];
};
typedef struct PartiallyBalloonedPage {
ram_addr_t base_gpa;
unsigned long *bitmap;
} PartiallyBalloonedPage;
static void virtio_balloon_pbp_free(PartiallyBalloonedPage *pbp)
{
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 offset)
MemoryRegion *mr, hwaddr mr_offset,
PartiallyBalloonedPage *pbp)
{
void *addr = memory_region_get_ram_ptr(mr) + offset;
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;
ram_addr_t ram_offset, host_page_base;
/* XXX is there a better way to get to the RAMBlock than via a
* host address? */
rb = qemu_ram_block_from_host(addr, false, &ram_offset);
rb = qemu_ram_block_from_host(addr, false, &rb_offset);
rb_page_size = qemu_ram_pagesize(rb);
host_page_base = ram_offset & ~(rb_page_size - 1);
if (rb_page_size == BALLOON_PAGE_SIZE) {
/* Easy case */
ram_block_discard_range(rb, ram_offset, rb_page_size);
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 */
@@ -74,81 +96,51 @@ static void balloon_inflate_page(VirtIOBalloon *balloon,
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 (balloon->pbp
&& (rb != balloon->pbp->rb
|| host_page_base != balloon->pbp->base)) {
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 */
g_free(balloon->pbp);
balloon->pbp = NULL;
virtio_balloon_pbp_free(pbp);
}
if (!balloon->pbp) {
/* Starting on a new host page */
size_t bitlen = BITS_TO_LONGS(subpages) * sizeof(unsigned long);
balloon->pbp = g_malloc0(sizeof(PartiallyBalloonedPage) + bitlen);
balloon->pbp->rb = rb;
balloon->pbp->base = host_page_base;
if (!pbp->bitmap) {
virtio_balloon_pbp_alloc(pbp, base_gpa, subpages);
}
bitmap_set(balloon->pbp->bitmap,
(ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE,
subpages);
set_bit((rb_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE,
pbp->bitmap);
if (bitmap_full(balloon->pbp->bitmap, subpages)) {
if (bitmap_full(pbp->bitmap, subpages)) {
/* We've accumulated a full host page, we can actually discard
* it now */
ram_block_discard_range(rb, balloon->pbp->base, rb_page_size);
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 */
g_free(balloon->pbp);
balloon->pbp = NULL;
virtio_balloon_pbp_free(pbp);
}
}
static void balloon_deflate_page(VirtIOBalloon *balloon,
MemoryRegion *mr, hwaddr offset)
MemoryRegion *mr, hwaddr mr_offset)
{
void *addr = memory_region_get_ram_ptr(mr) + offset;
void *addr = memory_region_get_ram_ptr(mr) + mr_offset;
ram_addr_t rb_offset;
RAMBlock *rb;
size_t rb_page_size;
ram_addr_t ram_offset, host_page_base;
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, &ram_offset);
rb = qemu_ram_block_from_host(addr, false, &rb_offset);
rb_page_size = qemu_ram_pagesize(rb);
host_page_base = ram_offset & ~(rb_page_size - 1);
if (balloon->pbp
&& rb == balloon->pbp->rb
&& host_page_base == balloon->pbp->base) {
int subpages = rb_page_size / BALLOON_PAGE_SIZE;
/*
* This means the guest has asked to discard some of the 4kiB
* subpages of a host page, but then changed its mind and
* asked to keep them after all. It's exceedingly unlikely
* for a guest to do this in practice, but handle it anyway,
* since getting it wrong could mean discarding memory the
* guest is still using. */
bitmap_clear(balloon->pbp->bitmap,
(ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE,
subpages);
if (bitmap_empty(balloon->pbp->bitmap, subpages)) {
g_free(balloon->pbp);
balloon->pbp = NULL;
}
}
host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1));
@@ -335,16 +327,18 @@ 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) {
unsigned int p = virtio_ldl_p(vdev, &pfn);
hwaddr pa;
int p = virtio_ldl_p(vdev, &pfn);
pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT;
offset += 4;
@@ -368,7 +362,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
if (!qemu_balloon_is_inhibited()) {
if (vq == s->ivq) {
balloon_inflate_page(s, section.mr,
section.offset_within_region);
section.offset_within_region, &pbp);
} else if (vq == s->dvq) {
balloon_deflate_page(s, section.mr, section.offset_within_region);
} else {
@@ -381,6 +375,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
virtqueue_push(vq, elem, offset);
virtio_notify(vdev, vq);
g_free(elem);
virtio_balloon_pbp_free(&pbp);
}
}
@@ -615,6 +610,22 @@ virtio_balloon_free_page_report_notify(NotifierWithReturn *n, void *data)
return 0;
}
static size_t virtio_balloon_config_size(VirtIOBalloon *s)
{
uint64_t features = s->host_features;
if (s->qemu_4_0_config_size) {
return sizeof(struct virtio_balloon_config);
}
if (virtio_has_feature(features, VIRTIO_BALLOON_F_PAGE_POISON)) {
return sizeof(struct virtio_balloon_config);
}
if (virtio_has_feature(features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
return offsetof(struct virtio_balloon_config, poison_val);
}
return offsetof(struct virtio_balloon_config, free_page_report_cmd_id);
}
static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
{
VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
@@ -635,7 +646,7 @@ static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
}
trace_virtio_balloon_get_config(config.num_pages, config.actual);
memcpy(config_data, &config, sizeof(struct virtio_balloon_config));
memcpy(config_data, &config, virtio_balloon_config_size(dev));
}
static int build_dimm_list(Object *obj, void *opaque)
@@ -679,7 +690,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
uint32_t oldactual = dev->actual;
ram_addr_t vm_ram_size = get_current_ram_size();
memcpy(&config, config_data, sizeof(struct virtio_balloon_config));
memcpy(&config, config_data, virtio_balloon_config_size(dev));
dev->actual = le32_to_cpu(config.actual);
if (dev->actual != oldactual) {
qapi_event_send_balloon_change(vm_ram_size -
@@ -766,7 +777,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
int ret;
virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON,
sizeof(struct virtio_balloon_config));
virtio_balloon_config_size(s));
ret = qemu_add_balloon_handler(virtio_balloon_to_target,
virtio_balloon_stat, s);
@@ -897,6 +908,12 @@ static Property virtio_balloon_properties[] = {
VIRTIO_BALLOON_F_DEFLATE_ON_OOM, false),
DEFINE_PROP_BIT("free-page-hint", VirtIOBalloon, host_features,
VIRTIO_BALLOON_F_FREE_PAGE_HINT, false),
/* QEMU 4.0 accidentally changed the config size even when free-page-hint
* is disabled, resulting in QEMU 3.1 migration incompatibility. This
* property retains this quirk for QEMU 4.1 machine types.
*/
DEFINE_PROP_BOOL("qemu-4-0-config-size", VirtIOBalloon,
qemu_4_0_config_size, false),
DEFINE_PROP_LINK("iothread", VirtIOBalloon, iothread, TYPE_IOTHREAD,
IOThread *),
DEFINE_PROP_END_OF_LIST(),
+14 -14
View File
@@ -1905,13 +1905,6 @@ static void virtio_pci_generic_class_init(ObjectClass *klass, void *data)
dc->props = virtio_pci_generic_properties;
}
/* Used when the generic type and the base type is the same */
static void virtio_pci_generic_base_class_init(ObjectClass *klass, void *data)
{
virtio_pci_base_class_init(klass, data);
virtio_pci_generic_class_init(klass, NULL);
}
static void virtio_pci_transitional_instance_init(Object *obj)
{
VirtIOPCIProxy *proxy = VIRTIO_PCI(obj);
@@ -1930,14 +1923,13 @@ static void virtio_pci_non_transitional_instance_init(Object *obj)
void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
{
char *base_name = NULL;
TypeInfo base_type_info = {
.name = t->base_name,
.parent = t->parent ? t->parent : TYPE_VIRTIO_PCI,
.instance_size = t->instance_size,
.instance_init = t->instance_init,
.class_size = t->class_size,
.class_init = virtio_pci_base_class_init,
.class_data = (void *)t,
.abstract = true,
};
TypeInfo generic_type_info = {
@@ -1953,13 +1945,20 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
if (!base_type_info.name) {
/* No base type -> register a single generic device type */
base_type_info.name = t->generic_name;
base_type_info.class_init = virtio_pci_generic_base_class_init;
base_type_info.interfaces = generic_type_info.interfaces;
base_type_info.abstract = false;
generic_type_info.name = NULL;
/* use intermediate %s-base-type to add generic device props */
base_name = g_strdup_printf("%s-base-type", t->generic_name);
base_type_info.name = base_name;
base_type_info.class_init = virtio_pci_generic_class_init;
generic_type_info.parent = base_name;
generic_type_info.class_init = virtio_pci_base_class_init;
generic_type_info.class_data = (void *)t;
assert(!t->non_transitional_name);
assert(!t->transitional_name);
} else {
base_type_info.class_init = virtio_pci_base_class_init;
base_type_info.class_data = (void *)t;
}
type_register(&base_type_info);
@@ -1997,6 +1996,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
};
type_register(&transitional_type_info);
}
g_free(base_name);
}
/* virtio-pci-bus */
+20 -3
View File
@@ -515,6 +515,23 @@ static void xen_device_backend_set_online(XenDevice *xendev, bool online)
xen_device_backend_printf(xendev, "online", "%u", online);
}
/*
* Tell from the state whether the frontend is likely alive,
* i.e. it will react to a change of state of the backend.
*/
static bool xen_device_state_is_active(enum xenbus_state state)
{
switch (state) {
case XenbusStateInitWait:
case XenbusStateInitialised:
case XenbusStateConnected:
case XenbusStateClosing:
return true;
default:
return false;
}
}
static void xen_device_backend_changed(void *opaque)
{
XenDevice *xendev = opaque;
@@ -538,11 +555,11 @@ static void xen_device_backend_changed(void *opaque)
/*
* If the toolstack (or unplug request callback) has set the backend
* state to Closing, but there is no active frontend (i.e. the
* state is not Connected) then set the backend state to Closed.
* state to Closing, but there is no active frontend then set the
* backend state to Closed.
*/
if (xendev->backend_state == XenbusStateClosing &&
xendev->frontend_state != XenbusStateConnected) {
!xen_device_state_is_active(xendev->frontend_state)) {
xen_device_backend_set_state(xendev, XenbusStateClosed);
}
+3
View File
@@ -293,6 +293,9 @@ struct MachineState {
} \
type_init(machine_initfn##_register_types)
extern GlobalProperty hw_compat_4_0[];
extern const size_t hw_compat_4_0_len;
extern GlobalProperty hw_compat_3_1[];
extern const size_t hw_compat_3_1_len;
-1
View File
@@ -234,7 +234,6 @@ struct IntelIOMMUState {
bool scalable_mode; /* RO - is Scalable Mode supported? */
dma_addr_t root; /* Current root table pointer */
bool root_extended; /* Type of root table (extended or not) */
bool root_scalable; /* Type of root table (scalable or not) */
bool dmar_enabled; /* Set if DMA remapping is enabled */
+3
View File
@@ -293,6 +293,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
int e820_get_num_entries(void);
bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
extern GlobalProperty pc_compat_4_0[];
extern const size_t pc_compat_4_0_len;
extern GlobalProperty pc_compat_3_1[];
extern const size_t pc_compat_3_1_len;
+2
View File
@@ -396,6 +396,8 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
bool pci_bus_is_express(PCIBus *bus);
bool pci_bus_is_root(PCIBus *bus);
bool pci_bus_allows_extended_config_space(PCIBus *bus);
void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
const char *name,
MemoryRegion *address_space_mem,
+1
View File
@@ -18,6 +18,7 @@ typedef struct PCIBusClass {
bool (*is_root)(PCIBus *bus);
int (*bus_num)(PCIBus *bus);
uint16_t (*numa_node)(PCIBus *bus);
bool (*allows_extended_config_space)(PCIBus *bus);
} PCIBusClass;
struct PCIBus {
+6
View File
@@ -208,6 +208,12 @@ typedef struct XiveEND {
#define xive_end_is_backlog(end) (be32_to_cpu((end)->w0) & END_W0_BACKLOG)
#define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & END_W0_ESCALATE_CTL)
static inline uint64_t xive_end_qaddr(XiveEND *end)
{
return ((uint64_t) be32_to_cpu(end->w2) & 0x0fffffff) << 32 |
be32_to_cpu(end->w3);
}
/* Notification Virtual Target (NVT) */
typedef struct XiveNVT {
uint32_t w0;
+1 -1
View File
@@ -70,7 +70,7 @@ enum {
#define SIFIVE_E_PLIC_HART_CONFIG "M"
#define SIFIVE_E_PLIC_NUM_SOURCES 127
#define SIFIVE_E_PLIC_NUM_PRIORITIES 7
#define SIFIVE_E_PLIC_PRIORITY_BASE 0x0
#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
#define SIFIVE_E_PLIC_PENDING_BASE 0x1000
#define SIFIVE_E_PLIC_ENABLE_BASE 0x2000
#define SIFIVE_E_PLIC_ENABLE_STRIDE 0x80
+2 -2
View File
@@ -68,9 +68,9 @@ enum {
};
#define SIFIVE_U_PLIC_HART_CONFIG "MS"
#define SIFIVE_U_PLIC_NUM_SOURCES 127
#define SIFIVE_U_PLIC_NUM_SOURCES 54
#define SIFIVE_U_PLIC_NUM_PRIORITIES 7
#define SIFIVE_U_PLIC_PRIORITY_BASE 0x0
#define SIFIVE_U_PLIC_PRIORITY_BASE 0x04
#define SIFIVE_U_PLIC_PENDING_BASE 0x1000
#define SIFIVE_U_PLIC_ENABLE_BASE 0x2000
#define SIFIVE_U_PLIC_ENABLE_STRIDE 0x80
+1 -1
View File
@@ -59,7 +59,7 @@ enum {
#define VIRT_PLIC_HART_CONFIG "MS"
#define VIRT_PLIC_NUM_SOURCES 127
#define VIRT_PLIC_NUM_PRIORITIES 7
#define VIRT_PLIC_PRIORITY_BASE 0x0
#define VIRT_PLIC_PRIORITY_BASE 0x04
#define VIRT_PLIC_PENDING_BASE 0x1000
#define VIRT_PLIC_ENABLE_BASE 0x2000
#define VIRT_PLIC_ENABLE_STRIDE 0x80
+2 -3
View File
@@ -33,8 +33,6 @@ typedef struct virtio_balloon_stat_modern {
uint64_t val;
} VirtIOBalloonStatModern;
typedef struct PartiallyBalloonedPage PartiallyBalloonedPage;
enum virtio_balloon_free_page_report_status {
FREE_PAGE_REPORT_S_STOP = 0,
FREE_PAGE_REPORT_S_REQUESTED = 1,
@@ -70,7 +68,8 @@ typedef struct VirtIOBalloon {
int64_t stats_last_update;
int64_t stats_poll_interval;
uint32_t host_features;
PartiallyBalloonedPage *pbp;
bool qemu_4_0_config_size;
} VirtIOBalloon;
#endif
+16 -10
View File
@@ -316,51 +316,57 @@ static inline void stb_p(void *ptr, uint8_t v)
*(uint8_t *)ptr = v;
}
/* Any compiler worth its salt will turn these memcpy into native unaligned
operations. Thus we don't need to play games with packed attributes, or
inline byte-by-byte stores. */
/*
* Any compiler worth its salt will turn these memcpy into native unaligned
* operations. Thus we don't need to play games with packed attributes, or
* inline byte-by-byte stores.
* Some compilation environments (eg some fortify-source implementations)
* may intercept memcpy() in a way that defeats the compiler optimization,
* though, so we use __builtin_memcpy() to give ourselves the best chance
* of good performance.
*/
static inline int lduw_he_p(const void *ptr)
{
uint16_t r;
memcpy(&r, ptr, sizeof(r));
__builtin_memcpy(&r, ptr, sizeof(r));
return r;
}
static inline int ldsw_he_p(const void *ptr)
{
int16_t r;
memcpy(&r, ptr, sizeof(r));
__builtin_memcpy(&r, ptr, sizeof(r));
return r;
}
static inline void stw_he_p(void *ptr, uint16_t v)
{
memcpy(ptr, &v, sizeof(v));
__builtin_memcpy(ptr, &v, sizeof(v));
}
static inline int ldl_he_p(const void *ptr)
{
int32_t r;
memcpy(&r, ptr, sizeof(r));
__builtin_memcpy(&r, ptr, sizeof(r));
return r;
}
static inline void stl_he_p(void *ptr, uint32_t v)
{
memcpy(ptr, &v, sizeof(v));
__builtin_memcpy(ptr, &v, sizeof(v));
}
static inline uint64_t ldq_he_p(const void *ptr)
{
uint64_t r;
memcpy(&r, ptr, sizeof(r));
__builtin_memcpy(&r, ptr, sizeof(r));
return r;
}
static inline void stq_he_p(void *ptr, uint64_t v)
{
memcpy(ptr, &v, sizeof(v));
__builtin_memcpy(ptr, &v, sizeof(v));
}
static inline int lduw_le_p(const void *ptr)
+6 -13
View File
@@ -249,15 +249,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
#define TARGET_NR__llseek TARGET_NR_llseek
#endif
#ifdef __NR_gettid
_syscall0(int, gettid)
#else
/* This is a replacement for the host gettid() and must return a host
errno. */
static int gettid(void) {
return -ENOSYS;
}
#endif
#define __NR_sys_gettid __NR_gettid
_syscall0(int, sys_gettid)
/* For the 64-bit guest on 32-bit host case we must emulate
* getdents using getdents64, because otherwise the host
@@ -5442,7 +5435,7 @@ static void *clone_func(void *arg)
cpu = ENV_GET_CPU(env);
thread_cpu = cpu;
ts = (TaskState *)cpu->opaque;
info->tid = gettid();
info->tid = sys_gettid();
task_settid(ts);
if (info->child_tidptr)
put_user_u32(info->tid, info->child_tidptr);
@@ -5587,9 +5580,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
mapping. We can't repeat the spinlock hack used above because
the child process gets its own copy of the lock. */
if (flags & CLONE_CHILD_SETTID)
put_user_u32(gettid(), child_tidptr);
put_user_u32(sys_gettid(), child_tidptr);
if (flags & CLONE_PARENT_SETTID)
put_user_u32(gettid(), parent_tidptr);
put_user_u32(sys_gettid(), parent_tidptr);
ts = (TaskState *)cpu->opaque;
if (flags & CLONE_SETTLS)
cpu_set_tls (env, newtls);
@@ -10629,7 +10622,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return TARGET_PAGE_SIZE;
#endif
case TARGET_NR_gettid:
return get_errno(gettid());
return get_errno(sys_gettid());
#ifdef TARGET_NR_readahead
case TARGET_NR_readahead:
#if TARGET_ABI_BITS == 32
+4 -10
View File
@@ -273,7 +273,6 @@ static int init_dirty_bitmap_migration(void)
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
DirtyBitmapMigBitmapState *dbms;
BdrvNextIterator it;
Error *local_err = NULL;
dirty_bitmap_mig_state.bulk_completed = false;
@@ -281,13 +280,8 @@ static int init_dirty_bitmap_migration(void)
dirty_bitmap_mig_state.prev_bitmap = NULL;
dirty_bitmap_mig_state.no_bitmaps = false;
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
const char *drive_name = bdrv_get_device_or_node_name(bs);
/* skip automatically inserted nodes */
while (bs && bs->drv && bs->implicit) {
bs = backing_bs(bs);
}
for (bs = bdrv_next_all_states(NULL); bs; bs = bdrv_next_all_states(bs)) {
const char *name = bdrv_get_device_or_node_name(bs);
for (bitmap = bdrv_dirty_bitmap_next(bs, NULL); bitmap;
bitmap = bdrv_dirty_bitmap_next(bs, bitmap))
@@ -296,7 +290,7 @@ static int init_dirty_bitmap_migration(void)
continue;
}
if (drive_name == NULL) {
if (!name || strcmp(name, "") == 0) {
error_report("Found bitmap '%s' in unnamed node %p. It can't "
"be migrated", bdrv_dirty_bitmap_name(bitmap), bs);
goto fail;
@@ -313,7 +307,7 @@ static int init_dirty_bitmap_migration(void)
dbms = g_new0(DirtyBitmapMigBitmapState, 1);
dbms->bs = bs;
dbms->node_name = drive_name;
dbms->node_name = name;
dbms->bitmap = bitmap;
dbms->total_sectors = bdrv_nb_sectors(bs);
dbms->sectors_per_chunk = CHUNK_SIZE * 8 *
+20 -5
View File
@@ -1495,10 +1495,8 @@ static void block_cleanup_parameters(MigrationState *s)
}
}
static void migrate_fd_cleanup(void *opaque)
static void migrate_fd_cleanup(MigrationState *s)
{
MigrationState *s = opaque;
qemu_bh_delete(s->cleanup_bh);
s->cleanup_bh = NULL;
@@ -1543,6 +1541,23 @@ static void migrate_fd_cleanup(void *opaque)
block_cleanup_parameters(s);
}
static void migrate_fd_cleanup_schedule(MigrationState *s)
{
/*
* Ref the state for bh, because it may be called when
* there're already no other refs
*/
object_ref(OBJECT(s));
qemu_bh_schedule(s->cleanup_bh);
}
static void migrate_fd_cleanup_bh(void *opaque)
{
MigrationState *s = opaque;
migrate_fd_cleanup(s);
object_unref(OBJECT(s));
}
void migrate_set_error(MigrationState *s, const Error *error)
{
qemu_mutex_lock(&s->error_mutex);
@@ -3144,7 +3159,7 @@ static void migration_iteration_finish(MigrationState *s)
error_report("%s: Unknown ending state %d", __func__, s->state);
break;
}
qemu_bh_schedule(s->cleanup_bh);
migrate_fd_cleanup_schedule(s);
qemu_mutex_unlock_iothread();
}
@@ -3279,7 +3294,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in)
bool resume = s->state == MIGRATION_STATUS_POSTCOPY_PAUSED;
s->expected_downtime = s->parameters.downtime_limit;
s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s);
s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s);
if (error_in) {
migrate_fd_error(s, error_in);
migrate_fd_cleanup(s);
+3 -1
View File
@@ -851,7 +851,7 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
*/
if (packet->pages_alloc > p->pages->allocated) {
multifd_pages_clear(p->pages);
multifd_pages_init(packet->pages_alloc);
p->pages = multifd_pages_init(packet->pages_alloc);
}
p->pages->used = be32_to_cpu(packet->pages_used);
@@ -3918,6 +3918,7 @@ int colo_init_ram_cache(void)
}
ram_state = g_new0(RAMState, 1);
ram_state->migration_dirty_pages = 0;
qemu_mutex_init(&ram_state->bitmap_mutex);
memory_global_dirty_log_start();
return 0;
@@ -3956,6 +3957,7 @@ void colo_release_ram_cache(void)
}
rcu_read_unlock();
qemu_mutex_destroy(&ram_state->bitmap_mutex);
g_free(ram_state);
ram_state = NULL;
}
+1 -1
View File
@@ -428,7 +428,7 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt,
}
if (info->min_block &&
!QEMU_IS_ALIGNED(info->size, info->min_block)) {
error_setg(errp, "export size %" PRIu64 "is not multiple of "
error_setg(errp, "export size %" PRIu64 " is not multiple of "
"minimum block size %" PRIu32, info->size,
info->min_block);
nbd_send_opt_abort(ioc);
+27 -12
View File
@@ -124,6 +124,8 @@ struct NBDClient {
int nb_requests;
bool closing;
uint32_t check_align; /* If non-zero, check for aligned client requests */
bool structured_reply;
NBDExportMetaContexts export_meta;
@@ -533,6 +535,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
bool blocksize = false;
uint32_t sizes[3];
char buf[sizeof(uint64_t) + sizeof(uint16_t)];
uint32_t check_align = 0;
/* Client sends:
4 bytes: L, name length (can be 0)
@@ -609,7 +612,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
* whether this is OPT_INFO or OPT_GO. */
/* minimum - 1 for back-compat, or actual if client will obey it. */
if (client->opt == NBD_OPT_INFO || blocksize) {
sizes[0] = blk_get_request_alignment(exp->blk);
check_align = sizes[0] = blk_get_request_alignment(exp->blk);
} else {
sizes[0] = 1;
}
@@ -640,11 +643,14 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
return rc;
}
/* If the client is just asking for NBD_OPT_INFO, but forgot to
* request block sizes, return an error.
* TODO: consult blk_bs(blk)->request_align, and only error if it
* is not 1? */
if (client->opt == NBD_OPT_INFO && !blocksize) {
/*
* If the client is just asking for NBD_OPT_INFO, but forgot to
* request block sizes in a situation that would impact
* performance, then return an error. But for NBD_OPT_GO, we
* tolerate all clients, regardless of alignments.
*/
if (client->opt == NBD_OPT_INFO && !blocksize &&
blk_get_request_alignment(exp->blk) > 1) {
return nbd_negotiate_send_rep_err(client,
NBD_REP_ERR_BLOCK_SIZE_REQD,
errp,
@@ -660,6 +666,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
if (client->opt == NBD_OPT_GO) {
client->exp = exp;
client->check_align = check_align;
QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
nbd_export_get(client->exp);
nbd_check_meta_export(client);
@@ -1880,17 +1887,12 @@ static int blockstatus_to_extents(BlockDriverState *bs, uint64_t offset,
flags = (ret & BDRV_BLOCK_ALLOCATED ? 0 : NBD_STATE_HOLE) |
(ret & BDRV_BLOCK_ZERO ? NBD_STATE_ZERO : 0);
offset += num;
remaining_bytes -= num;
if (first_extent) {
extent->flags = flags;
extent->length = num;
first_extent = false;
continue;
}
if (flags == extent->flags) {
} else if (flags == extent->flags) {
/* extend current extent */
extent->length += num;
} else {
@@ -1903,6 +1905,8 @@ static int blockstatus_to_extents(BlockDriverState *bs, uint64_t offset,
extent->flags = flags;
extent->length = num;
}
offset += num;
remaining_bytes -= num;
}
extents_end = extent + 1;
@@ -2129,6 +2133,17 @@ static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
return (request->type == NBD_CMD_WRITE ||
request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
}
if (client->check_align && !QEMU_IS_ALIGNED(request->from | request->len,
client->check_align)) {
/*
* The block layer gracefully handles unaligned requests, but
* it's still worth tracing client non-compliance
*/
trace_nbd_co_receive_align_compliance(nbd_cmd_lookup(request->type),
request->from,
request->len,
client->check_align);
}
valid_flags = NBD_CMD_FLAG_FUA;
if (request->type == NBD_CMD_READ && client->structured_reply) {
valid_flags |= NBD_CMD_FLAG_DF;
+1
View File
@@ -71,4 +71,5 @@ nbd_co_send_extents(uint64_t handle, unsigned int extents, uint32_t id, uint64_t
nbd_co_send_structured_error(uint64_t handle, int err, const char *errname, const char *msg) "Send structured error reply: handle = %" PRIu64 ", error = %d (%s), msg = '%s'"
nbd_co_receive_request_decode_type(uint64_t handle, uint16_t type, const char *name) "Decoding type: handle = %" PRIu64 ", type = %" PRIu16 " (%s)"
nbd_co_receive_request_payload_received(uint64_t handle, uint32_t len) "Payload received: handle = %" PRIu64 ", len = %" PRIu32
nbd_co_receive_align_compliance(const char *op, uint64_t from, uint32_t len, uint32_t align) "client sent non-compliant unaligned %s request: from=0x%" PRIx64 ", len=0x%" PRIx32 ", align=0x%" PRIx32
nbd_trip(void) "Reading request"
+50 -21
View File
@@ -408,42 +408,71 @@ class QEMUMachine(object):
self._qmp.clear_events()
return events
@staticmethod
def event_match(event, match=None):
"""
Check if an event matches optional match criteria.
The match criteria takes the form of a matching subdict. The event is
checked to be a superset of the subdict, recursively, with matching
values whenever those values are not None.
Examples, with the subdict queries on the left:
- None matches any object.
- {"foo": None} matches {"foo": {"bar": 1}}
- {"foo": {"baz": None}} does not match {"foo": {"bar": 1}}
- {"foo": {"baz": 2}} matches {"foo": {"bar": 1, "baz": 2}}
"""
if match is None:
return True
for key in match:
if key in event:
if isinstance(event[key], dict):
if not QEMUMachine.event_match(event[key], match[key]):
return False
elif event[key] != match[key]:
return False
else:
return False
return True
def event_wait(self, name, timeout=60.0, match=None):
"""
Wait for specified timeout on named event in QMP; optionally filter
results by match.
event_wait waits for and returns a named event from QMP with a timeout.
The 'match' is checked to be a recursive subset of the 'event'; skips
branch processing on match's value None
{"foo": {"bar": 1}} matches {"foo": None}
{"foo": {"bar": 1}} does not matches {"foo": {"baz": None}}
name: The event to wait for.
timeout: QEMUMonitorProtocol.pull_event timeout parameter.
match: Optional match criteria. See event_match for details.
"""
def event_match(event, match=None):
if match is None:
return True
return self.events_wait([(name, match)], timeout)
for key in match:
if key in event:
if isinstance(event[key], dict):
if not event_match(event[key], match[key]):
return False
elif event[key] != match[key]:
return False
else:
return False
def events_wait(self, events, timeout=60.0):
"""
events_wait waits for and returns a named event from QMP with a timeout.
return True
events: a sequence of (name, match_criteria) tuples.
The match criteria are optional and may be None.
See event_match for details.
timeout: QEMUMonitorProtocol.pull_event timeout parameter.
"""
def _match(event):
for name, match in events:
if (event['event'] == name and
self.event_match(event, match)):
return True
return False
# Search cached events
for event in self._events:
if (event['event'] == name) and event_match(event, match):
if _match(event):
self._events.remove(event)
return event
# Poll for new events
while True:
event = self._qmp.pull_event(wait=timeout)
if (event['event'] == name) and event_match(event, match):
if _match(event):
return event
self._events.append(event)
+5
View File
@@ -105,6 +105,11 @@ details.
The ``query-events'' command has been superseded by the more powerful
and accurate ``query-qmp-schema'' command.
@subsection chardev client socket with 'wait' option (since 4.0)
Character devices creating sockets in client mode should not specify
the 'wait' field, which is only applicable to sockets in server mode
@section Human Monitor Protocol (HMP) commands
@subsection The hub_id parameter of 'hostfwd_add' / 'hostfwd_remove' (since 3.1)
+1 -1
View File
@@ -46,7 +46,7 @@ ETEXI
DEF("convert", img_convert,
"convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename")
STEXI
@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
ETEXI
DEF("create", img_create,
+2 -2
View File
@@ -197,7 +197,7 @@ Command description:
@table @option
@item amend [--object @var{objectdef}] [--image-opts] [-p] [-p] [-f @var{fmt}] [-t @var{cache}] -o @var{options} @var{filename}
@item amend [--object @var{objectdef}] [--image-opts] [-p] [-q] [-f @var{fmt}] [-t @var{cache}] -o @var{options} @var{filename}
Amends the image format specific @var{options} for the image file
@var{filename}. Not all file formats support this operation.
@@ -424,7 +424,7 @@ To enumerate information about each disk image in the above chain, starting from
qemu-img info --backing-chain snap2.qcow2
@end example
@item map [-f @var{fmt}] [--output=@var{ofmt}] @var{filename}
@item map [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [--output=@var{ofmt}] [-U] @var{filename}
Dump the metadata of image @var{filename} and its backing file chain.
In particular, this commands dumps the allocation state of every sector
+18 -5
View File
@@ -47,7 +47,7 @@ SEABIOS_EXTRAVERSION="-prebuilt.qemu.org"
# We need that to combine multiple images (legacy bios,
# efi ia32, efi x64) into a single rom binary.
#
EFIROM = edk2/BaseTools/Source/C/bin/EfiRom
EDK2_EFIROM = edk2/BaseTools/Source/C/bin/EfiRom
default:
@echo "nothing is build by default"
@@ -102,8 +102,8 @@ pxe-rom-%: build-pxe-roms
efirom: $(patsubst %,efi-rom-%,$(pxerom_variants))
efi-rom-%: build-pxe-roms build-efi-roms $(EFIROM)
$(EFIROM) -f "0x$(VID)" -i "0x$(DID)" -l 0x02 \
efi-rom-%: build-pxe-roms build-efi-roms $(EDK2_EFIROM)
$(EDK2_EFIROM) -f "0x$(VID)" -i "0x$(DID)" -l 0x02 \
-b ipxe/src/bin/$(VID)$(DID).rom \
-ec ipxe/src/bin-i386-efi/$(VID)$(DID).efidrv \
-ec ipxe/src/bin-x86_64-efi/$(VID)$(DID).efidrv \
@@ -120,8 +120,21 @@ build-efi-roms: build-pxe-roms
$(patsubst %,bin-i386-efi/%.efidrv,$(pxerom_targets)) \
$(patsubst %,bin-x86_64-efi/%.efidrv,$(pxerom_targets))
$(EFIROM):
$(MAKE) -C edk2/BaseTools
# Build scripts can pass compiler/linker flags to the EDK2 build tools
# via the EDK2_BASETOOLS_OPTFLAGS (CPPFLAGS and CFLAGS) and
# EDK2_BASETOOLS_LDFLAGS (LDFLAGS) environment variables.
#
# Example:
#
# make -C roms \
# EDK2_BASETOOLS_OPTFLAGS='...' \
# EDK2_BASETOOLS_LDFLAGS='...' \
# efirom
#
$(EDK2_EFIROM):
$(MAKE) -C edk2/BaseTools \
EXTRA_OPTFLAGS='$(EDK2_BASETOOLS_OPTFLAGS)' \
EXTRA_LDFLAGS='$(EDK2_BASETOOLS_LDFLAGS)'
slof:
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) qemu
-1
View File
@@ -38,7 +38,6 @@ static int pr_manager_worker(void *opaque)
int fd = data->fd;
int r;
g_free(data);
trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
/* The reference was taken in pr_manager_execute. */
+11 -8
View File
@@ -297,6 +297,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;
@@ -304,9 +305,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:
@@ -331,6 +333,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);
@@ -347,13 +351,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);
}
+4 -1
View File
@@ -171,6 +171,7 @@ int
soread(struct socket *so)
{
int n, nn;
size_t buf_len;
struct sbuf *sb = &so->so_snd;
struct iovec iov[2];
@@ -181,7 +182,8 @@ soread(struct socket *so)
* No need to check if there's enough room to read.
* soread wouldn't have been called if there weren't
*/
sopreprbuf(so, iov, &n);
buf_len = sopreprbuf(so, iov, &n);
assert(buf_len != 0);
nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
if (nn <= 0) {
@@ -257,6 +259,7 @@ int soreadbuf(struct socket *so, const char *buf, int size)
* No need to check if there's enough room to read.
* soread wouldn't have been called if there weren't
*/
assert(size > 0);
if (sopreprbuf(so, iov, &n) < size)
goto err;
+20 -1
View File
@@ -964,10 +964,27 @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var)
store_cpu_field(var, thumb);
}
/* Set PC and Thumb state from var. var is marked as dead.
/*
* Set PC and Thumb state from var. var is marked as dead.
* For M-profile CPUs, include logic to detect exception-return
* branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
* and BX reg, and no others, and happens only for code in Handler mode.
* The Security Extension also requires us to check for the FNC_RETURN
* which signals a function return from non-secure state; this can happen
* in both Handler and Thread mode.
* To avoid having to do multiple comparisons in inline generated code,
* we make the check we do here loose, so it will match for EXC_RETURN
* in Thread mode. For system emulation do_v7m_exception_exit() checks
* for these spurious cases and returns without doing anything (giving
* the same behaviour as for a branch to a non-magic address).
*
* In linux-user mode it is unclear what the right behaviour for an
* attempted FNC_RETURN should be, because in real hardware this will go
* directly to Secure code (ie not the Linux kernel) which will then treat
* the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
* attempt behave the way it would on a CPU without the security extension,
* which is to say "like a normal branch". That means we can simply treat
* all branches as normal with no magic address behaviour.
*/
static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
{
@@ -975,10 +992,12 @@ static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
* s->base.is_jmp that we need to do the rest of the work later.
*/
gen_bx(s, var);
#ifndef CONFIG_USER_ONLY
if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
(s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
s->base.is_jmp = DISAS_BX_EXCRET;
}
#endif
}
static inline void gen_bx_excret_final_code(DisasContext *s)
+2 -2
View File
@@ -1076,7 +1076,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.feat_names = {
NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, "md-clear", NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
@@ -1183,7 +1183,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
"rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
"ssb-no", NULL, NULL, NULL,
"ssb-no", "mds-no", NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
+5
View File
@@ -1398,6 +1398,11 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
{
if (s1->prefix & PREFIX_LOCK) {
if (d != OR_TMP0) {
/* Lock prefix when destination is not memory */
gen_illegal_opcode(s1);
return;
}
tcg_gen_movi_tl(s1->T0, c > 0 ? 1 : -1);
tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
s1->mem_index, ot | MO_LE);
+1 -1
View File
@@ -2030,7 +2030,7 @@ void helper_vsum2sws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
for (i = 0; i < ARRAY_SIZE(r->u64); i++) {
int64_t t = (int64_t)b->VsrSW(upper + i * 2);
result.VsrW(i) = 0;
result.VsrD(i) = 0;
for (j = 0; j < ARRAY_SIZE(r->u64); j++) {
t += a->VsrSW(2 * i + j);
}
+12 -11
View File
@@ -102,8 +102,7 @@ static void gen_lxvw4x(DisasContext *ctx)
}
xth = tcg_temp_new_i64();
xtl = tcg_temp_new_i64();
get_cpu_vsrh(xth, xT(ctx->opcode));
get_cpu_vsrl(xtl, xT(ctx->opcode));
gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
@@ -126,6 +125,8 @@ static void gen_lxvw4x(DisasContext *ctx)
tcg_gen_addi_tl(EA, EA, 8);
tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ);
}
set_cpu_vsrh(xT(ctx->opcode), xth);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free(EA);
tcg_temp_free_i64(xth);
tcg_temp_free_i64(xtl);
@@ -185,8 +186,6 @@ static void gen_lxvh8x(DisasContext *ctx)
}
xth = tcg_temp_new_i64();
xtl = tcg_temp_new_i64();
get_cpu_vsrh(xth, xT(ctx->opcode));
get_cpu_vsrl(xtl, xT(ctx->opcode));
gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
@@ -197,6 +196,8 @@ static void gen_lxvh8x(DisasContext *ctx)
if (ctx->le_mode) {
gen_bswap16x8(xth, xtl, xth, xtl);
}
set_cpu_vsrh(xT(ctx->opcode), xth);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free(EA);
tcg_temp_free_i64(xth);
tcg_temp_free_i64(xtl);
@@ -214,14 +215,14 @@ static void gen_lxvb16x(DisasContext *ctx)
}
xth = tcg_temp_new_i64();
xtl = tcg_temp_new_i64();
get_cpu_vsrh(xth, xT(ctx->opcode));
get_cpu_vsrl(xtl, xT(ctx->opcode));
gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
gen_addr_reg_index(ctx, EA);
tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ);
tcg_gen_addi_tl(EA, EA, 8);
tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ);
set_cpu_vsrh(xT(ctx->opcode), xth);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free(EA);
tcg_temp_free_i64(xth);
tcg_temp_free_i64(xtl);
@@ -858,8 +859,8 @@ static void glue(gen_, name)(DisasContext * ctx) \
xbh = tcg_temp_new_i64(); \
xbl = tcg_temp_new_i64(); \
sgm = tcg_temp_new_i64(); \
set_cpu_vsrh(xB(ctx->opcode), xbh); \
set_cpu_vsrl(xB(ctx->opcode), xbl); \
get_cpu_vsrh(xbh, xB(ctx->opcode)); \
get_cpu_vsrl(xbl, xB(ctx->opcode)); \
tcg_gen_movi_i64(sgm, sgn_mask); \
switch (op) { \
case OP_ABS: { \
@@ -1192,7 +1193,7 @@ static void gen_xxbrq(DisasContext *ctx)
tcg_gen_bswap64_i64(xtl, xbh);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_gen_mov_i64(xth, t0);
set_cpu_vsrl(xT(ctx->opcode), xth);
set_cpu_vsrh(xT(ctx->opcode), xth);
tcg_temp_free_i64(t0);
tcg_temp_free_i64(xth);
@@ -1220,7 +1221,7 @@ static void gen_xxbrw(DisasContext *ctx)
get_cpu_vsrl(xbl, xB(ctx->opcode));
gen_bswap32x4(xth, xtl, xbh, xbl);
set_cpu_vsrl(xT(ctx->opcode), xth);
set_cpu_vsrh(xT(ctx->opcode), xth);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free_i64(xth);
@@ -1819,7 +1820,7 @@ static void gen_xvxsigdp(DisasContext *ctx)
tcg_gen_movi_i64(t0, 0x0010000000000000);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
tcg_gen_deposit_i64(xth, t0, xbl, 0, 52);
tcg_gen_deposit_i64(xtl, t0, xbl, 0, 52);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free_i64(t0);
Loaded 100 of 155 files, more files were not shown because too many files have changed in this diff. Show more