Compare commits

...

236 Commits

Author SHA1 Message Date
Gerd Hoffmann
1271f7f7c6 gtk: update mouse position in mouse_set()
Without that the next mouse motion event uses the old position
as base for relative move calculation, giving wrong results and
making your mouse pointer jump around.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-05-06 08:38:05 +02:00
Gerd Hoffmann
dc7ff34418 gtk: create gtk.h
Move various gtk bits (includes, data structures) to a header file.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-05-06 08:38:05 +02:00
Gerd Hoffmann
1301e515ef gtk: add ui_info support
Pass new display size to the guest after window resizes.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-05-06 08:38:05 +02:00
Gerd Hoffmann
b7fb49f0c7 console: add dpy_ui_info_supported
Allow ui code to check whenever the emulated
display supports display change notifications.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-05-06 08:38:05 +02:00
Gerd Hoffmann
cf1ecc82ab console: delayed ui_info guest notification
So we don't flood the guest with display change notifications
while the user resizes the window.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-05-06 08:38:05 +02:00
Peter Maydell
874e9aeeeb Merge remote-tracking branch 'remotes/kraxel/tags/pull-sdl-20150505-1' into staging
sdl2: add opengl support

# gpg: Signature made Tue May  5 10:36:25 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-sdl-20150505-1:
  sdl2: Fix RGB555
  sdl2: add support for display rendering using opengl.
  sdl2: move SDL_* includes to sdl2.h
  console-gl: add opengl rendering helper functions
  opengl: add shader helper functions.
  opengl: add shader build infrastructure

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-05-05 14:06:12 +01:00
Peter Maydell
b4c5df7a15 Merge remote-tracking branch 'remotes/armbru/tags/pull-cov-model-2015-05-05' into staging
coverity: fix address_space_rw model

# gpg: Signature made Tue May  5 09:44:26 2015 BST using RSA key ID EB918653
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>"
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>"

* remotes/armbru/tags/pull-cov-model-2015-05-05:
  coverity: fix address_space_rw model

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-05-05 10:23:22 +01:00
Max Reitz
e444ea34f8 sdl2: Fix RGB555
Reproducable with:

$ x86_64-softmmu/qemu-system-x86_64 \
    -kernel $vmlinuz_of_your_choice \
    -append vga=0x313 -sdl

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-05-05 10:48:26 +02:00
Gerd Hoffmann
0b71a5d5ca sdl2: add support for display rendering using opengl.
Add new sdl2-gl.c file, with display
rendering functions using opengl.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2015-05-05 10:48:26 +02:00
Gerd Hoffmann
19dadfccd0 sdl2: move SDL_* includes to sdl2.h
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2015-05-05 10:48:26 +02:00
Gerd Hoffmann
cd2bc889e5 console-gl: add opengl rendering helper functions
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2015-05-05 10:48:22 +02:00
Gerd Hoffmann
985e1c9b00 opengl: add shader helper functions.
Helper functions to compile, link and run opengl shader programs.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-05-05 10:43:03 +02:00
Paolo Bonzini
2e1c92daff coverity: fix address_space_rw model
If the is_write argument is true, address_space_rw writes to memory
and thus reads from the buffer.  The opposite holds if is_write is
false.  Fix the model.

Cc: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-05-05 10:42:11 +02:00
Gerd Hoffmann
d98bc0b654 opengl: add shader build infrastructure
perl script to transform shader programs into c include files with
static string constands containing the shader programs, so we can
easily embed them into qemu.  Also some Makefile logic for them.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2015-05-05 09:03:32 +02:00
Peter Maydell
5bccbb04a4 Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches

# gpg: Signature made Thu Apr 30 19:51:16 2015 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  Enable NVMe start controller for Windows guest.
  MAINTAINERS: Add qemu-block list where missing
  MAINTAINERS: make block layer core Kevin Wolf's responsibility
  MAINTAINERS: make image fuzzer Stefan Hajnoczi's responsibility
  MAINTAINERS: make block I/O path Stefan Hajnoczi's responsibility
  MAINTAINERS: split out image formats
  MAINTAINERS: make virtio-blk Stefan Hajnoczi's responsibility

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-30 20:34:54 +01:00
Peter Maydell
f90f5b9a9a Merge remote-tracking branch 'remotes/mjt/tags/pull-trivial-patches-2015-04-30' into staging
trivial patches for 2015-04-30

# gpg: Signature made Thu Apr 30 14:07:50 2015 BST using RSA key ID A4C3D7DB
# gpg: Good signature from "Michael Tokarev <mjt@tls.msk.ru>"
# gpg:                 aka "Michael Tokarev <mjt@corpit.ru>"
# gpg:                 aka "Michael Tokarev <mjt@debian.org>"

* remotes/mjt/tags/pull-trivial-patches-2015-04-30: (42 commits)
  openrisc: cpu: Remove unused cpu_get_pc
  microblaze: fix memory leak
  tcg: Delete unused cpu_pc_from_tb()
  kvm: Silence warning from valgrind
  vhost-user: remove superfluous '\n' around error_report()
  target-mips: fix memory leak
  qmp-commands: Fix typo
  linux-user/elfload: use QTAILQ_FOREACH instead of open-coding it
  coroutine: remove unnecessary parentheses in qemu_co_queue_empty
  qemu-char: remove unused list node from FDCharDriver
  input: remove unused mouse_handlers list
  cpus: use first_cpu macro instead of QTAILQ_FIRST(&cpus)
  microblaze: cpu: delete unused cpu_interrupts_enabled
  microblaze: cpu: Renumber EXCP_* constants to close gap
  microblaze: cpu: Delete EXCP_NMI
  microblaze: cpu: Remove unused CC_OP enum
  microblaze: cpu: Remote unused cpu_get_pc
  microblaze: mmu: Delete flip_um fn prototype
  defconfigs: Piggyback microblazeel on microblaze
  libcacard: do not use full paths for include files in the same dir
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-30 15:18:30 +01:00
Daniel Stekloff
4a4d614ff5 Enable NVMe start controller for Windows guest.
Windows seems to send two separate calls to NVMe controller configuration. The
first sends configuration info and the second the enable bit. I couldn't
enable the Windows 8.1 in-box NVMe driver with base Qemu. I made the
following change to store the configuration data and then handle enable and
NVMe driver works on Windows 8.1.

I am not a Windows expert and I'm not entirely sure this is the correct
approach. I'm offering it for anyone who wishes to use NVMe on Windows 8.1
using Qemu.

I have tested this change with Linux and Windows guests with NVMe devices.

Signed-off-by: Daniel Stekloff <dan@wendan.org>
Acked-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-30 15:35:26 +02:00
Peter Maydell
498147529d Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20150430' into staging
First pile of s390x patches for 2.4, including:
- some cleanup patches
- sort most of the s390x devices into categories
- support for the new STSI post handler, used to insert vm name and
  friends
- support for the new MEM_OP ioctl (including access register mode)
  for accessing guest memory

# gpg: Signature made Thu Apr 30 12:56:58 2015 BST using RSA key ID C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"

* remotes/cohuck/tags/s390x-20150430:
  kvm: better advice for failed s390x startup
  s390x/kvm: Support access register mode for KVM_S390_MEM_OP ioctl
  s390x/mmu: Use ioctl for reading and writing from/to guest memory
  s390x/kvm: Put vm name, extended name and UUID into STSI322 SYSIB
  linux-headers: update
  s390x/mmu: Use access type definitions instead of magic values
  s390x/ipl: sort into categories
  sclp: sort into categories
  s390-virtio: sort into categories
  virtio-ccw: sort into categories

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-30 14:15:56 +01:00
Kevin Wolf
c95e4c0e53 MAINTAINERS: Add qemu-block list where missing
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-30 15:15:13 +02:00
Stefan Hajnoczi
17f1e8f5ac MAINTAINERS: make block layer core Kevin Wolf's responsibility
Kevin is now sole maintainer of the core block layer, including
BlockDriverState graphs and monitor commands.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-30 15:11:34 +02:00
Stefan Hajnoczi
abfe4e9408 MAINTAINERS: make image fuzzer Stefan Hajnoczi's responsibility
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-30 15:11:34 +02:00
Stefan Hajnoczi
d55053b16e MAINTAINERS: make block I/O path Stefan Hajnoczi's responsibility
The block I/O path includes the asynchronous I/O machinery and
read/write/flush/discard processing.  It somewhat arbitrarily also
includes block migration, which I've found myself reviewing patches for
over the years.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-30 15:11:33 +02:00
Stefan Hajnoczi
e7c6e631b1 MAINTAINERS: split out image formats
Block driver submaintainers has proven to be a good model.  Kevin and
Stefan are splitting up the unclaimed block drivers so each has a
dedicated maintainer.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-30 15:11:33 +02:00
Stefan Hajnoczi
b457a5f54c MAINTAINERS: make virtio-blk Stefan Hajnoczi's responsibility
Cc: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-30 15:11:33 +02:00
Peter Crosthwaite
553029351b openrisc: cpu: Remove unused cpu_get_pc
This function is not used by anything. Remove.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:06:18 +03:00
Gonglei
4d850406a8 microblaze: fix memory leak
When not assign a -dtb argument, the variable dtb_filename
storage returned from qemu_find_file(), which should be freed
after use. Alternatively we define a local variable filename,
with 'char *' type, free after use.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:06:18 +03:00
Peter Crosthwaite
fee068e4f1 tcg: Delete unused cpu_pc_from_tb()
No code uses the cpu_pc_from_tb() function. Delete from tricore and
arm which each provide an unused implementation. Update the comment
in tcg.h to reflect that this is obsoleted by synchronize_from_tb.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:06:18 +03:00
Thomas Huth
2ed0c3dad7 kvm: Silence warning from valgrind
valgrind complains here about uninitialized bytes with the following message:

==17814== Syscall param ioctl(generic) points to uninitialised byte(s)
==17814==    at 0x466A780: ioctl (in /usr/lib64/power8/libc-2.17.so)
==17814==    by 0x100735B7: kvm_vm_ioctl (kvm-all.c:1920)
==17814==    by 0x10074583: kvm_set_ioeventfd_mmio (kvm-all.c:574)

Let's fix it by using a proper struct initializer in kvm_set_ioeventfd_mmio().

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:06:17 +03:00
Gonglei
ab7c5aaf31 vhost-user: remove superfluous '\n' around error_report()
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:06:17 +03:00
Gonglei
3ad9fd5a25 target-mips: fix memory leak
Coveristy reports that variable prom_buf/params_buf going
out of scope leaks the storage it points to.

Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:06:17 +03:00
John Snow
5403432f39 qmp-commands: Fix typo
Just a trivial patch to correct a QMP example in qmp-commands.hx.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:06:17 +03:00
Emilio G. Cota
52a53afebd linux-user/elfload: use QTAILQ_FOREACH instead of open-coding it
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:49 +03:00
Emilio G. Cota
b1201addc7 coroutine: remove unnecessary parentheses in qemu_co_queue_empty
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:49 +03:00
Emilio G. Cota
63d229c32b qemu-char: remove unused list node from FDCharDriver
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:49 +03:00
Emilio G. Cota
dfbf272b77 input: remove unused mouse_handlers list
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Emilio G. Cota
c28e399cad cpus: use first_cpu macro instead of QTAILQ_FIRST(&cpus)
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
93100f67c7 microblaze: cpu: delete unused cpu_interrupts_enabled
This function is unused. Remove.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Michael Tokarev
2161be35ce microblaze: cpu: Renumber EXCP_* constants to close gap
After removal of EXCP_NMI there's a gap in EXCP_*
numbering. Let's remove it.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
059ec9aa34 microblaze: cpu: Delete EXCP_NMI
This define is unused. Remove.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
004f979fbb microblaze: cpu: Remove unused CC_OP enum
This enum is not used by anything. Remove.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
b133b09a9d microblaze: cpu: Remote unused cpu_get_pc
This function is not used by anything. Remove.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
19191a6bc5 microblaze: mmu: Delete flip_um fn prototype
This is not implemented or used.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
a0970d91c9 defconfigs: Piggyback microblazeel on microblaze
Theres no difference in defconfig. Going forward microblazeel should
superset microblaze so use an include.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Michael Tokarev
f66759d3ae libcacard: do not use full paths for include files in the same dir
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-30 16:05:48 +03:00
Paolo Bonzini
28507a415a libcacard: stop including qemu-common.h
This is a small step towards making libcacard standalone.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Laszlo Ersek
d3e4abdddf docs/atomics.txt: fix two typos
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
5ecaa4ed88 configure: alphabetize tricore in target list
tricore was out of alphabetical order in the target list. Fix.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Acked-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Peter Crosthwaite
ef1d27f4b1 arm: cpu.h: Remove unused typdefs
These CP accessor function prototypes are unused. Remove them.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Thomas Huth
3bf2af7b40 util: Remove unused functions
Delete the unused functions qemu_signalfd_available(),
qemu_send_full() and qemu_recv_full().

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Thomas Huth
ec29ea1b2b usb: Remove unused functions
Delete set_usb_string(), usb_ep_get_ifnum(), usb_ep_get_max_packet_size()
usb_ep_get_max_streams() and usb_ep_set_pipeline() since they are
not used anymore.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Thomas Huth
26b93109c0 monitor: Remove unused functions
The functions ringbuf_read_completion() and monitor_get_rs()
are not used anywhere anymore, so let's remove them.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Cc: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Thomas Huth
04768b985e pci: Remove unused function ich9_d2pbr_init()
The function ich9_d2pbr_init() is completely unused and
thus can be deleted.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Thomas Huth
9dcfda1298 vmxnet: Remove unused function vmxnet_rx_pkt_get_num_frags()
The function is not used anymore and thus can be deleted.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Cc: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Michael Tokarev
825976153e qemu-options: trivial spelling fix (messsage)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Eric Blake <eblake@redhat.com>
2015-04-30 16:05:48 +03:00
Jan Kiszka
c2cb2b041b hostmem: Fix mem-path property name in error report
The subtle difference between "property not found" and "property not
set" is already confusing enough.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Stefan Berger
29b558d877 tpm: fix coding style
Fix coding style in one instance.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Paolo Bonzini
1897b212b7 qemu-config: remove stray inclusions of hw/ files
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Paolo Bonzini
f2fbb40ea3 range: remove useless inclusions
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Stefan Weil
631b22ea20 misc: Fix new collection of typos
All of them were reported by codespell.
Most typos are in comments, one is in an error message.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Chih-Min Chao
c9f88ce330 hw/display : remove 'struct' from 'typedef QXL struct'
Signed-off-by: Chih-Min Chao <cmchao@gmail.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Chih-Min Chao
9425c004fe ui/console : remove 'struct' from 'typedef struct' type
Signed-off-by: Chih-Min Chao <cmchao@gmail.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Chih-Min Chao
4769a881cb ui/vnc : remove 'struct' of 'typedef struct'
Signed-off-by: Chih-Min Chao <cmchao@gmail.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Chih-Min Chao
494cb81741 ui/vnc : fix coding style
reported by checkpatch.pl

Signed-off-by: Chih-Min Chao <cmchao@gmail.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Chih-Min Chao
4188e39055 bitops : fix coding style
don't mix tab and space. The rule is 4 spaces

Signed-off-by: Chih-Min Chao <cmchao@gmail.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Stefan Berger
4d1ba9c4f8 tpm: Modify DPRINTF to enable -Wformat checking
Modify DPRINTF to always enable -Wformat checking.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Stefan Berger
070c7607f6 tpm: Cast 64bit variables to int when used in DPRINTF
Cast 64bit variables to int when used in DPRINTF. They only contain
32bit of data.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-04-30 16:05:48 +03:00
Cornelia Huck
2c80e996e4 kvm: better advice for failed s390x startup
If KVM_CREATE failed on s390x, we print a hint to enable the switch_amode
kernel parameter. This only applies to old kernels, and only if the
error was -EINVAL. Moreover, with new kernels, the most likely reason
for -EINVAL is that pgstes were not enabled.

Let's update the error message to give a better hint on where things
may need fixing.

Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:42 +02:00
Alexander Yarygin
6cb1e49de5 s390x/kvm: Support access register mode for KVM_S390_MEM_OP ioctl
Access register mode is one of the modes that control dynamic address
translation. In this mode the address space is specified by values of
the access registers. The effective address-space-control element is
obtained from the result of the access register translation. See
the "Access-Register Introduction" section of the chapter 5 "Program
Execution" in "Principles of Operations" for more details.

When the CPU is in AR mode, the s390_cpu_virt_mem_rw() function must
know which access register number to use for address translation.
This patch does several things:
- add new parameter 'uint8_t ar' to that function
- decode ar number from intercepted instructions
- pass the ar number to s390_cpu_virt_mem_rw(), which in turn passes it
to the KVM_S390_MEM_OP ioctl.

Signed-off-by: Alexander Yarygin <yarygin@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:42 +02:00
Thomas Huth
a9bcd1b871 s390x/mmu: Use ioctl for reading and writing from/to guest memory
Add code to make use of the new ioctl for reading from / writing to
virtual guest memory. By using the ioctl, the memory accesses are now
protected with the so-called ipte-lock in the kernel.

[CH: moved error message into kvm_s390_mem_op()]
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:42 +02:00
Ekaterina Tumanova
f07177a559 s390x/kvm: Put vm name, extended name and UUID into STSI322 SYSIB
KVM prefills the SYSIB, returned by STSI 3.2.2. This patch allows
userspace to intercept execution, and fill in the values, that are
known to qemu: machine name (8 chars), extended machine name (256
chars), extended machine name encoding (equals 2 for UTF-8) and UUID.

STSI322 qemu handler also finds a highest virtualization level in
level-3 virtualization stack that doesn't support Extended Names
(Ext Name delimiter) and propagates zero Ext Name to all levels below,
because this level is not capable of managing Extended Names of lower
levels.

Signed-off-by: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:42 +02:00
Cornelia Huck
7a52ce8a16 linux-headers: update
This updates linux-headers against master 4.1-rc1 (commit
b787f68c36d49bb1d9236f403813641efa74a031).

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:42 +02:00
Thomas Huth
217a4acb21 s390x/mmu: Use access type definitions instead of magic values
Since there are now proper definitions for the MMU access type,
let's use them in the s390x MMU code, too, instead of the
hard-to-understand magic values.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:42 +02:00
Cornelia Huck
b4ab4572b3 s390x/ipl: sort into categories
The s390 ipl device has no real home (it's not really a storage device),
so let's sort it into the misc category.

Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:42 +02:00
Cornelia Huck
183f6b8d7e sclp: sort into categories
Sort the sclp consoles into the input category, just as virtio-serial.
Various other sclp devices don't have an obvious category, sort them
into misc.

Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:41 +02:00
Cornelia Huck
4d1866de94 s390-virtio: sort into categories
Sort the various s390-virtio devices into the same categories as their
virtio-pci counterparts.

Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:41 +02:00
Cornelia Huck
cd20d61634 virtio-ccw: sort into categories
Sort the various virtio-ccw devices into the same categories as their
virtio-pci counterparts.

Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2015-04-30 13:21:41 +02:00
Peter Maydell
06feaacfb4 Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
- miscellaneous cleanups for TCG (Emilio) and NBD (Bogdan)
- next part in the thread-safe address_space_* saga: atomic access
  to the bounce buffer and the map_clients list, from Fam
- optional support for linking with tcmalloc, also from Fam
- reapplying Peter Crosthwaite's "Respect as_translate_internal
  length clamp" after fixing the SPARC fallout.
- build system fix from Wei Liu
- small acpi-build and ioport cleanup by myself

# gpg: Signature made Wed Apr 29 09:34:00 2015 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# 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: 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: (22 commits)
  nbd/trivial: fix type cast for ioctl
  translate-all: use bitmap helpers for PageDesc's bitmap
  target-i386: disable LINT0 after reset
  Makefile.target: prepend $libs_softmmu to $LIBS
  milkymist: do not modify libs-softmmu
  configure: Add support for tcmalloc
  exec: Respect as_translate_internal length clamp
  ioport: reserve the whole range of an I/O port in the AddressSpace
  ioport: loosen assertions on emulation of 16-bit ports
  ioport: remove wrong comment
  ide: there is only one data port
  gus: clean up MemoryRegionPortio
  sb16: remove useless mixer_write_indexw
  sun4m: fix slavio sysctrl and led register sizes
  acpi-build: remove dependency from ram_addr.h
  memory: add memory_region_ram_resize
  dma-helpers: Fix race condition of continue_after_map_failure and dma_aio_cancel
  exec: Notify cpu_register_map_client caller if the bounce buffer is available
  exec: Protect map_client_list with mutex
  linux-user, bsd-user: Remove two calls to cpu_exec_init_all
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-30 12:04:11 +01:00
Peter Maydell
a1fe58f6ad Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
# gpg: Signature made Wed Apr 29 00:03:44 2015 BST using RSA key ID AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"
# 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: FAEB 9711 A12C F475 812F  18F2 88A9 064D 1835 61EB
#      Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76  CBD0 7DEF 8106 AAFC 390E

* remotes/jnsnow/tags/ide-pull-request:
  qtest: Add assertion that required environment variable is set
  qtest/ahci: add flush retry test
  libqos: add blkdebug_prepare_script
  libqtest: add qmp_async
  libqtest: add qmp_eventwait
  qtest/ahci: Allow override of default CLI options
  qtest/ahci: Add simple flush test
  qtest/ahci: test different disk sectors
  qtest/ahci: add qcow2 support to ahci-test
  fdc: remove sparc sun4m mutations

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-30 10:10:31 +01:00
Bogdan Purcareata
d064d9f381 nbd/trivial: fix type cast for ioctl
This fixes ioctl behavior on powerpc e6500 platforms with 64bit kernel and 32bit
userspace. The current type cast has no effect there and the value passed to the
kernel is still 0. Probably an issue related to the compiler, since I'm assuming
the same configuration works on a similar setup on x86.

Also ensure consistency with previous type cast in TRACE message.

Signed-off-by: Bogdan Purcareata <bogdan.purcareata@freescale.com>
Message-Id: <1428058914-32050-1-git-send-email-bogdan.purcareata@freescale.com>
Cc: qemu-stable@nongnu.org
[Fix parens as noticed by Michael. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-28 22:14:15 +02:00
Emilio G. Cota
510a647fa2 translate-all: use bitmap helpers for PageDesc's bitmap
Here we have an open-coded byte-based bitmap implementation.
Get rid of it since there's a ulong-based implementation to be
used by all code.

Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-28 22:14:14 +02:00
Nadav Amit
b8eb5512fd target-i386: disable LINT0 after reset
Due to old Seabios bug, QEMU reenable LINT0 after reset. This bug is long gone
and therefore this hack is no longer needed.  Since it violates the
specifications, it is removed.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428881529-29459-2-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-28 22:14:14 +02:00
Wei Liu
7398dfc779 Makefile.target: prepend $libs_softmmu to $LIBS
I discovered a problem when trying to build QEMU statically with gcc.
libm is an element of LIBS while libpixman-1 is an element in
libs_softmmu. Libpixman references functions in libm, so the original
ordering makes linking fail.

This fix is to reorder $libs_softmmu and $LIBS to make -lm appear after
-lpixman-1. However I'm not quite sure if this is the right fix, hence
the RFC tag.

Normally QEMU is built with c++ compiler which happens to link in libm
(at least this is the case with g++), so building QEMU statically
normally just works and nobody notices this issue.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Message-Id: <1425912873-21215-1-git-send-email-wei.liu2@citrix.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-28 22:14:14 +02:00
Paolo Bonzini
738e4171de milkymist: do not modify libs-softmmu
This is better and prepares for the next patch.  When we copy
libs_softmmu's value into LIBS with a := assignment, we cannot
anymore modify libs_softmmu in the Makefiles.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-28 22:14:14 +02:00
Fam Zheng
2847b46958 configure: Add support for tcmalloc
This adds "--enable-tcmalloc" and "--disable-tcmalloc" to allow linking
to libtcmalloc from gperftools.

tcmalloc is a malloc implementation that works well with threads and is
fast, so it is good for performance.

It is disabled by default, because the MALLOC_PERTURB_ flag we use in
tests doesn't work with tcmalloc. However we can enable tcmalloc
specific heap checker and profilers later.

An IOPS gain can be observed with virtio-blk-dataplane, other parts of
QEMU will directly benefit from it as well:

==========================================================
                       glibc malloc
----------------------------------------------------------
rw         bs         iodepth    bw     iops       latency
read       4k         1          150    38511      24
----------------------------------------------------------

==========================================================
                         tcmalloc
----------------------------------------------------------
rw         bs         iodepth    bw     iops       latency
read       4k         1          156    39969      23
----------------------------------------------------------

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1427338992-27057-1-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-28 22:14:11 +02:00
Ed Maste
c836867498 qtest: Add assertion that required environment variable is set
Signed-off-by: Ed Maste <emaste@freebsd.org>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1427911244-22565-1-git-send-email-emaste@freebsd.org
Signed-off-by: John Snow <jsnow@redhat.com>
2015-04-28 15:27:51 -04:00
John Snow
cf5aa89e9d qtest/ahci: add flush retry test
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1426018503-821-7-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
John Snow
72c85e949f libqos: add blkdebug_prepare_script
Pull this helper out of ide-test and into libqos,
to be shared with ahci-test.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1426018503-821-6-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
John Snow
ba4ed39346 libqtest: add qmp_async
Add qmp_async, which lets us send QMP commands asynchronously.
This is useful when we want to send commands that will trigger
event responses, but we don't know in what order to expect them.

Sometimes the event responses may arrive even before the command
confirmation will show up, so it is convenient to leave the responses
in the stream.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1426018503-821-5-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
John Snow
8fe941f749 libqtest: add qmp_eventwait
Allow the user to poll until a desired interrupt occurs.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1426018503-821-4-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
John Snow
debaaa114a qtest/ahci: Allow override of default CLI options
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1426018503-821-3-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
John Snow
4e217074ca qtest/ahci: Add simple flush test
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1426018503-821-2-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
John Snow
727be1a755 qtest/ahci: test different disk sectors
Test sector offset 0, 1, and the last sector(s)
in LBA28 and LBA48 modes.

Signed-off-by: John Snow <jsnow@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1426274523-22661-3-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
John Snow
122fdf2d88 qtest/ahci: add qcow2 support to ahci-test
This will enable the testing of high offsets without
wasting a lot of disk space, and does not impact the
previous tests.

mkimg and mkqcow2 are added to libqos for other tests.

Signed-off-by: John Snow <jsnow@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1426274523-22661-2-git-send-email-jsnow@redhat.com
2015-04-28 15:27:51 -04:00
Hervé Poussineau
24a5c62cfe fdc: remove sparc sun4m mutations
They were introduced in 6f7e9aec5e and
82407d1a40 and lots of bug fixes were done after that.

This fixes (at least) the detection of the floppy controller on Debian 4.0r9/SPARC,
and SS-5's OBP initialization routine still works.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-id: 1426351846-6497-1-git-send-email-hpoussin@reactos.org
Signed-off-by: John Snow <jsnow@redhat.com>
2015-04-28 15:27:51 -04:00
Peter Maydell
52b7aba62f Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150428.0' into staging
VFIO updates
 - Correction to BAR overflow
 - Fix error sign
 - Reset workaround for AMD Bonaire & Hawaii GPUs

# gpg: Signature made Tue Apr 28 18:26:43 2015 BST using RSA key ID 3BB08B22
# gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>"
# gpg:                 aka "Alex Williamson <alex@shazbot.org>"
# gpg:                 aka "Alex Williamson <alwillia@redhat.com>"
# gpg:                 aka "Alex Williamson <alex.l.williamson@gmail.com>"

* remotes/awilliam/tags/vfio-update-20150428.0:
  vfio-pci: Reset workaround for AMD Bonaire and Hawaii GPUs
  vfio-pci: Fix error path sign
  vfio-pci: Further fix BAR size overflow

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-28 18:58:15 +01:00
Alex Williamson
5655f931ab vfio-pci: Reset workaround for AMD Bonaire and Hawaii GPUs
Somehow these GPUs manage not to respond to a PCI bus reset, removing
our primary mechanism for resetting graphics cards.  The result is
that these devices typically work well for a single VM boot.  If the
VM is rebooted or restarted, the guest driver is not able to init the
card from the dirty state, resulting in a blue screen for Windows
guests.

The workaround is to use a device specific reset.  This is not 100%
reliable though since it depends on the incoming state of the device,
but it substantially improves the usability of these devices in a VM.

Credit to Alex Deucher <alexander.deucher@amd.com> for his guidance.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2015-04-28 11:14:02 -06:00
Alex Williamson
c6d231e2fd vfio-pci: Fix error path sign
This is an impossible error path due to the fact that we're reading a
kernel provided, rather than user provided link, which will certainly
always fit in PATH_MAX.  Currently it returns a fixed 26 char path
plus %d group number, which typically maxes out at double digits.
However, the caller of the initfn certainly expects a less-than zero
return value on error, not just a non-zero value.  Therefore we
should correct the sign here.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2015-04-28 11:14:02 -06:00
Alex Williamson
07ceaf9880 vfio-pci: Further fix BAR size overflow
In an analysis by Laszlo, the resulting type of our calculation for
the end of the MSI-X table, and thus the start of memory after the
table, is uint32_t.  We're therefore not correctly preventing the
corner case overflow that we intended to fix here where a BAR >=4G
could place the MSI-X table to end exactly at the 4G boundary.  The
MSI-X table offset is defined by the hardware spec to 32bits, so we
simply use a cast rather than changing data structure types.  This
scenario is purely theoretically, typically the MSI-X table is located
at the front of the BAR.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2015-04-28 11:14:02 -06:00
Peter Maydell
a9392bc93c Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches

# gpg: Signature made Tue Apr 28 15:35:05 2015 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (76 commits)
  block: move I/O request processing to block/io.c
  block: extract bdrv_setup_io_funcs()
  block: add bdrv_set_dirty()/bdrv_reset_dirty() to block_int.h
  block: replace bdrv_states iteration with bdrv_next()
  vmdk: Widen before shifting 32 bit header field
  block/dmg: make it modular
  block/mirror: Always call block_job_sleep_ns()
  iotests: add incremental backup granularity tests
  iotests: add incremental backup failure recovery test
  iotests: add simple incremental backup case
  iotests: add QMP event waiting queue
  iotests: add invalid input incremental backup tests
  hbitmap: truncate tests
  block: Resize bitmaps on bdrv_truncate
  block: Ensure consistent bitmap function prototypes
  block: add BdrvDirtyBitmap documentation
  qmp: Add dirty bitmap status field in query-block
  qmp: add block-dirty-bitmap-clear
  qmp: Add support of "dirty-bitmap" sync mode for drive-backup
  block: Add bitmap successors
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-28 16:55:03 +01:00
Stefan Hajnoczi
61007b316c block: move I/O request processing to block/io.c
The block.c file has grown to over 6000 lines.  It is time to split this
file so there are fewer conflicts and the code is easier to maintain.

Extract I/O request processing code:
 * Read
 * Write
 * Zero writes and making the image empty
 * Flush
 * Discard
 * ioctl
 * Tracked requests and queuing
 * Throttling and copy-on-read
 * Block status and allocated functions
 * Refreshing block limits
 * Reading/writing vmstate
 * qemu_blockalign() and friends

The patch simply moves code from block.c into block/io.c.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:17 +02:00
Stefan Hajnoczi
0eb7217e49 block: extract bdrv_setup_io_funcs()
Move the code to install coroutine and aio emulation function pointers
in a BlockDriver to its own function.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:17 +02:00
Stefan Hajnoczi
e0c47b6cb1 block: add bdrv_set_dirty()/bdrv_reset_dirty() to block_int.h
The dirty bitmap functions are called from the block I/O processing
code.  Make them visible to block_int.h users so they can be used
outside block.c.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:17 +02:00
Stefan Hajnoczi
4f5472cb2d block: replace bdrv_states iteration with bdrv_next()
The bdrv_states list is a static variable in block.c.

bdrv_drain_all() and bdrv_flush_all() use this variable to iterate over
all drives.

The next patch will move bdrv_drain_all() and bdrv_flush_all() out of
block.c so it's necessary to switch to the public bdrv_next() interface.

Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:17 +02:00
Fam Zheng
7237aecd7e vmdk: Widen before shifting 32 bit header field
Coverity spotted this.

The field is 32 bits, but if it's possible to overflow in 32 bit
left shift.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
Michael Tokarev
5505e8b76f block/dmg: make it modular
dmg can optionally utilize libbz2, make it modular

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
Max Reitz
001c95b740 block/mirror: Always call block_job_sleep_ns()
The mirror block job is trying to take a clever shortcut if delay_ns is
0 and skips block_job_sleep_ns() in that case. But that function must be
called in every block job iteration, because otherwise it is for example
impossible to pause the job.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
John Snow
59fc5d844f iotests: add incremental backup granularity tests
Test what happens if you fiddle with the granularity.

Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-22-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
John Snow
24618f5381 iotests: add incremental backup failure recovery test
Test the failure case for incremental backups.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-21-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
John Snow
a3d715958c iotests: add simple incremental backup case
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-20-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
John Snow
7898f74e78 iotests: add QMP event waiting queue
A filter is added to allow callers to request very specific
events to be pulled from the event queue, while leaving undesired
events still in the stream.

This allows us to poll for completion data for multiple asynchronous
events in any arbitrary order.

A new timeout context is added to the qmp pull_event method's
wait parameter to allow tests to fail if they do not complete
within some expected period of time.

Also fixed is a bug in qmp.pull_event where we try to retrieve an event
from an empty list if we attempt to retrieve an event with wait=False
but no events have occurred.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-19-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
John Snow
9f7264f57c iotests: add invalid input incremental backup tests
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-18-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
John Snow
a94e87c08c hbitmap: truncate tests
The general approach is to set bits close to the boundaries of
where we are truncating and ensure that everything appears to
have gone OK.

We test growing and shrinking by different amounts:
- Less than the granularity
- Less than the granularity, but across a boundary
- Less than sizeof(unsigned long)
- Less than sizeof(unsigned long), but across a ulong boundary
- More than sizeof(unsigned long)

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-17-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:11 +02:00
John Snow
ce1ffea8cd block: Resize bitmaps on bdrv_truncate
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-16-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
20dca81075 block: Ensure consistent bitmap function prototypes
We often don't need the BlockDriverState for functions
that operate on bitmaps. Remove it.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-15-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
aa0c7ca506 block: add BdrvDirtyBitmap documentation
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-14-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
a113534ffb qmp: Add dirty bitmap status field in query-block
Add the "frozen" status booleans, to inform clients
when a bitmap is occupied doing a task.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1429314609-29776-13-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
e74e6b78e6 qmp: add block-dirty-bitmap-clear
Add bdrv_clear_dirty_bitmap and a matching QMP command,
qmp_block_dirty_bitmap_clear that enables a user to reset
the bitmap attached to a drive.

This allows us to reset a bitmap in the event of a full
drive backup.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1429314609-29776-12-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
d58d845397 qmp: Add support of "dirty-bitmap" sync mode for drive-backup
For "dirty-bitmap" sync mode, the block job will iterate through the
given dirty bitmap to decide if a sector needs backup (backup all the
dirty clusters and skip clean ones), just as allocation conditions of
"top" sync mode.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-11-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
9bd2b08f27 block: Add bitmap successors
A bitmap successor is an anonymous BdrvDirtyBitmap that is intended to
be created just prior to a sensitive operation (e.g. Incremental Backup)
that can either succeed or fail, but during the course of which we still
want a bitmap tracking writes.

On creating a successor, we "freeze" the parent bitmap which prevents
its deletion, enabling, anonymization, or creating a bitmap with the
same name.

On success, the parent bitmap can "abdicate" responsibility to the
successor, which will inherit its name. The successor will have been
tracking writes during the course of the backup operation. The parent
will be safely deleted.

On failure, we can "reclaim" the successor from the parent, unifying
them such that the resulting bitmap describes all writes occurring since
the last successful backup, for instance. Reclamation will thaw the
parent, but not explicitly re-enable it.

BdrvDirtyBitmap operations that target a single bitmap are protected
by assertions that the bitmap is not frozen and/or disabled.

BdrvDirtyBitmap operations that target a group of bitmaps, such as
bdrv_{set,reset}_dirty will ignore frozen/disabled drives with a
conditional instead.

Internal functions that enable/disable dirty bitmaps have assertions
added to them to prevent modifying frozen bitmaps.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1429314609-29776-10-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
b8e6fb752e block: Add bitmap disabled status
Add a status indicating the enabled/disabled state of the bitmap.
A bitmap is by default enabled, but you can lock the bitmap into
a read-only state by setting disabled = true.

A previous version of this patch added a QMP interface for changing
the state of the bitmap, but it has since been removed for now until
a use case emerges where this state must be revealed to the user.

The disabled state WILL be used internally for bitmap migration and
bitmap persistence.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-9-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
be58721dbf hbitmap: add hbitmap_merge
We add a bitmap merge operation to assist in error cases
where we wish to combine two bitmaps together.

This is algorithmically O(bits) provided HBITMAP_LEVELS remains
constant. For a full bitmap on a 64bit machine:
sum(bits/64^k, k, 0, HBITMAP_LEVELS) ~= 1.01587 * bits

We may be able to improve running speed for particularly sparse
bitmaps by using iterators, but the running time for dense maps
will be worse.

We present the simpler solution first, and we can refine it later
if needed.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-8-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
8515efbef1 hbitmap: cache array lengths
As a convenience: between incremental backups, bitmap migrations
and bitmap persistence we seem to need to recalculate these a lot.

Because the lengths are a little bit-twiddly, let's just solidly
cache them and be done with it.

Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-7-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
592fdd02ae block: Introduce bdrv_dirty_bitmap_granularity()
This returns the granularity (in bytes) of dirty bitmap,
which matches the QMP interface and the existing query
interface.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-6-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
341ebc2f81 qmp: Add block-dirty-bitmap-add and block-dirty-bitmap-remove
The new command pair is added to manage a user created dirty bitmap. The
dirty bitmap's name is mandatory and must be unique for the same device,
but different devices can have bitmaps with the same names.

The granularity is an optional field. If it is not specified, we will
choose a default granularity based on the cluster size if available,
clamped to between 4K and 64K to mirror how the 'mirror' code was
already choosing granularity. If we do not have cluster size info
available, we choose 64K. This code has been factored out into a helper
shared with block/mirror.

This patch also introduces the 'block_dirty_bitmap_lookup' helper,
which takes a device name and a dirty bitmap name and validates the
lookup, returning NULL and setting errp if there is a problem with
either field. This helper will be re-used in future patches in this
series.

The types added to block-core.json will be re-used in future patches
in this series, see:
'qapi: Add transaction support to block-dirty-bitmap-{add, enable, disable}'

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1429314609-29776-5-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
5fba6c0e50 qmp: Ensure consistent granularity type
We treat this field with a variety of different types everywhere
in the code. Now it's just uint32_t.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-4-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Fam Zheng
0db6e54a8a qapi: Add optional field "name" to block dirty bitmap
This field will be set for user created dirty bitmap. Also pass in an
error pointer to bdrv_create_dirty_bitmap, so when a name is already
taken on this BDS, it can report an error message. This is not global
check, two BDSes can have dirty bitmap with a common name.

Implemented bdrv_find_dirty_bitmap to find a dirty bitmap by name, will
be used later when other QMP commands want to reference dirty bitmap by
name.

Add bdrv_dirty_bitmap_make_anon. This unsets the name of dirty bitmap.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1429314609-29776-3-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
John Snow
efcfa278dc docs: incremental backup documentation
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1429314609-29776-2-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
9eac3622a2 block/iscsi: use the allocationmap also if cache.direct=on
the allocationmap has only a hint character. The driver always
double checks that blocks marked unallocated in the cache are
still unallocated before taking the fast path and return zeroes.
So using the allocationmap is migration safe and can
also be enabled with cache.direct=on.

Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-10-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
03e40fef46 block/iscsi: bump year in copyright notice
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-9-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
e380aff831 block/iscsi: handle SCSI_STATUS_TASK_SET_FULL
a target may issue a SCSI_STATUS_TASK_SET_FULL status
if there is more than one "BUSY" command queued already.

Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-8-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
59dd0a22ca block/iscsi: increase retry count
The idea is that a command is retried in a BUSY condition
up a time of approx. 60 seconds before it is failed. This should
be far higher than any command timeout in the guest.

Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-7-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
73b5394e2e block/iscsi: optimize WRITE10/16 if cache.writeback is not set
SCSI allowes to tell the target to not return from a write command
if the date is not written to the disk. Use this so called FUA
bit if it is supported to optimize WRITE commands if writeback is
not allowed.

In this case qemu always issues a WRITE followed by a FLUSH. This
is 2 round trip times. If we set the FUA bit we can ignore the
following FLUSH.

Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-6-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
752ce45150 block/iscsi: store DPOFUA bit from the modesense command
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-5-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
7191f2080c block/iscsi: rename iscsi_write_protected and let it return void
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-4-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
0a386e4852 block/iscsi: change all iscsilun properties from uint8_t to bool
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-3-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:10 +02:00
Peter Lieven
20474e9aa0 block/iscsi: do not forget to logout from target
We actually were always impolitely dropping the connection and
not cleanly logging out.

CC: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-id: 1429193313-4263-2-git-send-email-pl@kamp.de
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Alberto Garcia
d5a8ee60a0 qmp: fill in the image field in BlockDeviceInfo
The image field in BlockDeviceInfo is supposed to contain an ImageInfo
object. However that is being filled in by bdrv_query_info(), not by
bdrv_block_device_info(), which is where BlockDeviceInfo is actually
created.

Anyone calling bdrv_block_device_info() directly will get a null image
field. As a consequence of this, the HMP command 'info block -n -v'
crashes QEMU.

This patch moves the code that fills in that field from
bdrv_query_info() to bdrv_block_device_info().

Signed-off-by: Alberto Garcia <berto@igalia.com>
Message-id: 1429271563-3765-1-git-send-email-berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Stefan Hajnoczi
9419874f70 Revert "hmp: fix crash in 'info block -n -v'"
This reverts commit 638b836620.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Alberto Garcia
dc881b441d block: add 'node-name' field to BLOCK_IMAGE_CORRUPTED
Since this event can occur in nodes that cannot have a device name
associated, include also a field with the node name.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 147cec5b3594f4bec0cb41c98afe5fcbfb67567c.1428485266.git.berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Alberto Garcia
81e5f78a9f block: use bdrv_get_device_or_node_name() in error messages
There are several error messages that identify a BlockDriverState by
its device name. However those errors can be produced in nodes that
don't have a device name associated.

In those cases we should use bdrv_get_device_or_node_name() to fall
back to the node name and produce a more meaningful message. The
messages are also updated to use the more generic term 'node' instead
of 'device'.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 9823a1f0514fdb0692e92868661c38a9e00a12d6.1428485266.git.berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Alberto Garcia
9b2aa84f87 block: add bdrv_get_device_or_node_name()
This function gets the device name associated with a BlockDriverState,
or its node name if the device name is empty.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 4fa30aa8d61d9052ce266fd5429a59a14e941255.1428485266.git.berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Stefan Hajnoczi
ec683d6040 block: document block-stream in qmp-commands.hx
The 'block-stream' QMP command is documented in block-core.json but not
qmp-commands.hx.  Add a summary of the command to qmp-commands.hx
(similar to the documentation for 'block-commit').

Reported-by: Kashyap Chamarthy <kchamart@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1429094622-26218-1-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Stefan Hajnoczi
c485cf9c92 m25p80: fix s->blk usage before assignment
Delay the call to blk_blockalign() until s->blk has been assigned.

This never caused a crash because blk_blockalign(NULL, size) defaults to
4096 alignment but it's technically incorrect.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1429091024-25098-1-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Paolo Bonzini
d07063e460 m25p80: add missing blk_attach_dev_nofail
Of the block devices that poked into -drive options via drive_get_next,
m25p80 was the only one who also did not attach itself to the BlockBackend.

Since sd does it, and all other devices go through a "drive" property,
with this change all block backends attached to the guest will have a
non-NULL result for blk_get_attached_dev().

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 1429025387-11077-1-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Michael S. Tsirkin
4eb867e98c virtio_blk: comment fix
update virtio blk header from latest linux, include comment fixups.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1428854036-12806-1-git-send-email-mst@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Paolo Bonzini
0b5a24454f block: avoid unnecessary bottom halves
bdrv_aio_* APIs can use coroutines to achieve asynchronicity.  However,
the coroutine may terminate without having yielded back to the caller
(for example because of something that invokes a nested event loop,
or because the coroutine is doing nothing at all).  In this case,
the bdrv_aio_* API must delay the completion to the next iteration
of the main loop, because bdrv_aio_* will never invoke the callback
before returning.

This can be done with a bottom half, and indeed bdrv_aio_* is always
using one for simplicity.  It is possible to gain some performance
(~3%) by avoiding this in the common case.  A new field in the
BlockAIOCBCoroutine struct is set to true until the first time the
corotine has yielded to its creator, and completion goes through a
new function bdrv_co_complete.  If the flag is false, bdrv_co_complete
invokes the callback immediately.  If it is true, the caller will
notice that the coroutine has completed and schedule the bottom
half itself.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427524638-28157-1-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Fam Zheng
a7282330c0 blockjob: Update function name in comments
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1428069921-2957-5-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Fam Zheng
e62303a437 qemu-iotests: Test that "stop" doesn't drain block jobs
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1428069921-2957-4-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Fam Zheng
69da3b0b47 block: Pause block jobs in bdrv_drain_all
This is necessary to suppress more IO requests from being generated from
block job coroutines.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1428069921-2957-3-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Fam Zheng
751ebd76e6 blockjob: Allow nested pause
This patch changes block_job_pause to increase the pause counter and
block_job_resume to decrease it.

The counter will allow calling block_job_pause/block_job_resume
unconditionally on a job when we need to suspend the IO temporarily.

From now on, each block_job_resume must be paired with a block_job_pause
to keep the counter balanced.

The user pause from QMP or HMP will only trigger block_job_pause once
until it's resumed, this is achieved by adding a user_paused flag in
BlockJob.

One occurrence of block_job_resume in mirror_complete is replaced with
block_job_enter which does what is necessary.

In block_job_cancel, the cancel flag is good enough to instruct
coroutines to quit loop, so use block_job_enter to replace the unpaired
block_job_resume.

Upon block job IO error, user is notified about the entering to the
pause state, so this pause belongs to user pause, set the flag
accordingly and expect a matching QMP resume.

[Extended doc comments as suggested by Paolo Bonzini
<pbonzini@redhat.com>.
--Stefan]

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1428069921-2957-2-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Fam Zheng
199667a8c8 MAINTAINERS: Add Fam Zheng as Null block driver maintainer
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427852740-24315-4-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Fam Zheng
1c2b49a172 block/null: Support reopen
Reopen is used in block-commit. With this always-succeed operation, it
is now possible to test committing to a null drive, by specifying
"null-aio://" or "null-co://" as the backing image when creating the
qcow2 image.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427852740-24315-3-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Fam Zheng
e5e51dd3af block/null: Latency simulation by adding new option "latency-ns"
Aio context switch should just work because the requests will be
drained, so the scheduled timer(s) on the old context will be freed.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427852740-24315-2-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Stefan Hajnoczi
9eddd6a4b3 scripts: add 'qemu coroutine' command to qemu-gdb.py
The 'qemu coroutine <coroutine-address>' GDB command prints the
backtrace for a CoroutineUContext.  This is useful for peeking inside
yielded coroutines that are waiting for file descriptor events, timers,
etc.

For example:

  $ gdb tests/test-coroutine
  (gdb) b test_yield
  (gdb) r
  (gdb) b qemu_coroutine_enter
  (gdb) c
  (gdb) c
  Continuing.

  Breakpoint 2, qemu_coroutine_enter (co=0x555555c66520, opaque=0x0) at qemu-coroutine.c:103
  103	{
  (gdb) source scripts/qemu-gdb.py
  (gdb) qemu coroutine 0x555555c66520
  #0  0x000055555557a740 in qemu_coroutine_switch (from_=<optimized out>, to_=0x7ffff7f90a70, action=COROUTINE_YIELD) at coroutine-ucontext.c:177
  #1  0x0000555555566af9 in yield_5_times (opaque=0x7fffffffdbb7) at tests/test-coroutine.c:107
  #2  0x000055555557a7aa in coroutine_trampoline (i0=<optimized out>, i1=<optimized out>) at coroutine-ucontext.c:80
  #3  0x00007ffff08de000 in __start_context () at /lib64/libc.so.6

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427409754-8556-1-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Stefan Hajnoczi
1faa5bb732 thread-pool: clean up thread_pool_completion_bh()
This patch simplifies thread_pool_completion_bh().

The function first checks elem->state:

  if (elem->state != THREAD_DONE) {
      continue;
  }

It then goes on to check elem->state == THREAD_DONE although we already
know this must be the case.

The QLIST_REMOVE() is duplicated down both branches of an if-else
statement so that can be lifted out as well.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1427992762-10126-1-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:09 +02:00
Kevin Wolf
d1a126c53d vhdx: Fix zero-fill iov length
Fix the length of the zero-fill for the back, which was accidentally
using the same value as for the front. This is caught by qemu-iotests
033.

For consistency, change the code for the front as well to use the length
stored in the iov (it is the same value, copied four lines above).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Jeff Cody <jcody@redhat.com>
2015-04-28 15:36:09 +02:00
Kevin Wolf
8eedfbd4a5 blkdebug: Add bdrv_truncate()
This is, amongst others, required for qemu-iotests 033 to run as
intended on VHDX, which uses explicit bdrv_truncate() calls to bs->file
when allocating new blocks.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
2015-04-28 15:36:09 +02:00
Kevin Wolf
e4f5874923 qemu-iotests: Some qemu-img convert tests
This adds a regression test for some problems that the qemu-img convert
rewrite just fixed.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2015-04-28 15:36:09 +02:00
Kevin Wolf
690c730160 qemu-img convert: Rewrite copying logic
The implementation of qemu-img convert is (a) messy, (b) buggy, and
(c) less efficient than possible. The changes required to beat some
sense into it are massive enough that incremental changes would only
make my and the reviewers' life harder. So throw it away and reimplement
it from scratch.

Let me give some examples what I mean by messy, buggy and inefficient:

(a) The copying logic of qemu-img convert has two separate branches for
    compressed and normal target images, which roughly do the same -
    except for a little code that handles actual differences between
    compressed and uncompressed images, and much more code that
    implements just a different set of optimisations and bugs. This is
    unnecessary code duplication, and makes the code for compressed
    output (unsurprisingly) suffer from bitrot.

    The code for uncompressed ouput is run twice to count the the total
    length for the progress bar. In the first run it just takes a
    shortcut and runs only half the loop, and when it's done, it toggles
    a boolean, jumps out of the loop with a backwards goto and starts
    over. Works, but pretty is something different.

(b) Converting while keeping a backing file (-B option) is broken in
    several ways. This includes not writing to the image file if the
    input has zero clusters or data filled with zeros (ignoring that the
    backing file will be visible instead).

    It also doesn't correctly limit every iteration of the copy loop to
    sectors of the same status so that too many sectors may be copied to
    in the target image. For -B this gives an unexpected result, for
    other images it just does more work than necessary.

    Conversion with a compressed target completely ignores any target
    backing file.

(c) qemu-img convert skips reading and writing an area if it knows from
    metadata that copying isn't needed (except for the bug mentioned
    above that ignores a status change in some cases). It does, however,
    read from the source even if it knows that it will read zeros, and
    then search for non-zero bytes in the read buffer, if it's possible
    that a write might be needed.

This reimplementation of the copying core reorganises the code to remove
the duplication and have a much more obvious code flow, by essentially
splitting the copy iteration loop into three parts:

1. Find the number of contiguous sectors of the same status at the
   current offset (This can also be called in a separate loop before the
   copying loop in order to determine the total sectors for the progress
   bar.)

2. Read sectors. If the status implies that there is no data there to
   read (zero or unallocated cluster), don't do anything.

3. Write sectors depending on the status. If it's data, write it. If
   we want the backing file to be visible (with -B), don't write it. If
   it's zeroed, skip it if you can, otherwise use bdrv_write_zeroes() to
   optimise the write at least where possible.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2015-04-28 15:36:09 +02:00
Kevin Wolf
0df89e8e6f block-backend: Expose bdrv_write_zeroes()
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2015-04-28 15:36:08 +02:00
Paolo Bonzini
a0710f7995 iothread: release iothread around aio_poll
This is the first step towards having fine-grained critical sections in
dataplane threads, which resolves lock ordering problems between
address_space_* functions (which need the BQL when doing MMIO, even
after we complete RCU-based dispatch) and the AioContext.

Because AioContext does not use contention callbacks anymore, the
unit test has to be changed.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1424449612-18215-4-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Paolo Bonzini
49110174f8 AioContext: acquire/release AioContext during aio_poll
This is the first step in pushing down acquire/release, and will let
rfifolock drop the contention callback feature.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1424449612-18215-3-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Paolo Bonzini
e98ab09709 aio-posix: move pollfds to thread-local storage
By using thread-local storage, aio_poll can stop using global data during
g_poll_ns.  This will make it possible to drop callbacks from rfifolock.

[Moved npfd = 0 assignment to end of walking_handlers region as
suggested by Paolo.  This resolves the assert(npfd == 0) assertion
failure in pollfds_cleanup().
--Stefan]

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1424449612-18215-2-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Fam Zheng
de50a20a4c block: Switch to host monotonic clock for IO throttling
Currently, throttle timers won't make any progress when VCPU is not
running, which would stall the request queue in utils, qtest, vm
suspending, and live migration, without special handling.

Block jobs are confusingly inconsistent between with and without
throttling: if user sets a bps limit, stops the vm, then start a block
job, the block job will not make any progress; in contrary, if user
unsets the bps limit, or if it's not set, the block job will run
normally.

After this patch, with the host clock, even if the VCPUs are stopped,
the throttle queues will be processed.

This patch also enables potential to add throttle to bdrv_drain_all.
Currently all requests are drained immediately. In other words whenever
it is called, IO throttling goes ineffective (examples: system reset,
migration and many block job operations.). This is a loophole that guest
could exploit. If we use the host clock, we can later just trust the
nested poll. This could be done on top.

Note that for qemu-iotests case 093, which uses qtest, we still keep vm
clock so the script can control the clock stepping in order to be
deterministic.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1427268446-6426-1-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
8b6ee9aeb3 checkpatch: complain about ffs(3) calls
The ffs(3) family of functions is not portable.  MinGW doesn't always
provide the function.

Use ctz32() or ctz64() instead.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-10-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
f450a85899 os-win32: drop ffs(3) prototype
The lack of ffs(3) in the MinGW headers is a hint that we shouldn't rely
on it.  MinGW 4.9.2 does not make it available for linking when QEMU's
./configure --enable-debug is used (release builds are fine though).

Now that all QEMU code has been switched to ctz32() there is no need for
ffs(3).

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-9-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Paolo Bonzini
41074f3d3f omap_intc: convert ffs(3) to ctz32() in omap_inth_sir_update()
Rewrite the loop using level &= level - 1 to clear the least significant
bit after each iteration.  This simplifies the loop and makes it easy to
replace ffs(3) with ctz32().

Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-8-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
c9d9331851 sd: convert sd_normal_command() ffs(3) call to ctz32()
ffs() cannot be replaced with ctz32() when the argument might be zero,
because ffs(0) returns 0 while ctz32(0) returns 32.

The ffs(3) call in sd_normal_command() is a special case though.  It can
be converted to ctz32() + 1 because the argument is never zero:

  if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
      ~~~~~~~~~~~~~~~
            ^--------------- req.arg cannot be zero

Cc: Markus Armbruster <armbru@redhat.com>
Cc: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-7-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
bd2a88840e Convert ffs() != 0 callers to ctz32()
There are a number of ffs(3) callers that do roughly:

  bit = ffs(val);
  if (bit) {
      do_something(bit - 1);
  }

This pattern can be converted to ctz32() like this:

  zeroes = ctz32(val);
  if (zeroes != 32) {
      do_something(zeroes);
  }

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-6-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
786a4ea82e Convert (ffs(val) - 1) to ctz32(val)
This commit was generated mechanically by coccinelle from the following
semantic patch:

@@
expression val;
@@
- (ffs(val) - 1)
+ ctz32(val)

The call sites have been audited to ensure the ffs(0) - 1 == -1 case
never occurs (due to input validation, asserts, etc).  Therefore we
don't need to worry about the fact that ctz32(0) == 32.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-5-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
5863d374a3 uninorth: convert ffs(3) to ctz32()
It is not clear from the code how a 0 parameter should be handled by the
hardware.  Keep the same behavior as ffs(0) - 1 == -1.

Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-4-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
ad5f5fdca8 hw/arm/nseries: convert ffs(3) to ctz32()
It is not clear from the code how a 0 parameter should be handled by the
hardware.  Keep the same behavior as ffs(0) - 1 == -1.

Cc: Andrzej Zaborowski <balrog@zabor.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-3-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Stefan Hajnoczi
588ef9d411 bt-sdp: fix broken uuids power-of-2 calculation
The binary search in sdp_uuid_match() only works when the number of
elements to search is a power of two.

  lo = record->uuid;
  hi = record->uuids;
  while (hi >>= 1)
      if (lo[hi] <= val)
          lo += hi;

  return *lo == val;

I noticed that the record->uuids calculation in
sdp_service_record_build() was suspect:

  record->uuids = 1 << ffs(record->uuids - 1);

Unlike most ffs(val) - 1 users, the expression is ffs(val - 1)!

Actually ffs() is the wrong function to use for power-of-2.  Use
pow2ceil() to achieve the correct effect.  Now the record->uuid[] array
is sized correctly and the binary search in sdp_uuid_match() should
work.

I'm not sure how to run/test this code.

Cc: Andrzej Zaborowski <balrog@zabor.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1427124571-28598-2-git-send-email-stefanha@redhat.com
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Alberto Garcia
ecdda9e03d MAINTAINERS: Add myself as the maintainer of the Quorum driver
Signed-off-by: Alberto Garcia <berto@igalia.com>
Message-id: 1426522925-14444-1-git-send-email-berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Yi Wang
407bc15033 savevm: create snapshot failed when id_str already exists
The command "virsh create" will fail in such condition: vm has two
disks: vda and vdb. vda has snapshot s1 with id "1", vdb doesn't have
s1 but has snapshot s2 with id "1".  When we want to run command "virsh
create s1", del_existing_snapshots() only deletes s1 in vda, and
bdrv_snapshot_create() tries to create vdb's snapshot s1 with id "1",
but id "1" alreay exists in vdb with name "s2"!

The simplest way is call find_new_snapshot_id() unconditionally.

Signed-off-by: Yi Wang <up2wing@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-04-28 15:36:08 +02:00
Peter Maydell
84cbd63f87 Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
X86 queue, 2015-04-27 (v2)

# gpg: Signature made Mon Apr 27 19:42:39 2015 BST using RSA key ID 984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# 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: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/x86-pull-request:
  target-i386: Remove AMD feature flag aliases from CPU model table
  target-i386: X86CPU::xlevel2 QOM property
  target-i386: Make "level" and "xlevel" properties static
  qemu-config: Accept empty option values
  MAINTAINERS: Change status of X86 to Maintained
  MAINTAINERS: Add myself to X86

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-28 12:22:20 +01:00
Peter Maydell
54965ee61d Merge remote-tracking branch 'remotes/ehabkost/tags/numa-pull-request' into staging
NUMA queue, 2015-04-27

# gpg: Signature made Mon Apr 27 19:02:19 2015 BST using RSA key ID 984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# 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: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/numa-pull-request:
  MAINTAINERS: Add myself as NUMA code maintainer

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-28 11:33:47 +01:00
Peter Maydell
da378d014d Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20150427' into staging
target-arm queue:
 * memory system updates to support transaction attributes
 * set user-mode and secure attributes for accesses made by ARM CPUs
 * rename c1_coproc to cpacr_el1
 * adjust id_aa64pfr0 when has_el3 CPU property disabled
 * allow ARMv8 SCR.SMD updates

# gpg: Signature made Mon Apr 27 16:14:30 2015 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20150427:
  Allow ARMv8 SCR.SMD updates
  target-arm: Adjust id_aa64pfr0 when has_el3 CPU property disabled
  target-arm: rename c1_coproc to cpacr_el1
  target-arm: Check watchpoints against CPU security state
  target-arm: Use attribute info to handle user-only watchpoints
  target-arm: Add user-mode transaction attribute
  target-arm: Use correct memory attributes for page table walks
  target-arm: Honour NS bits in page tables
  Switch non-CPU callers from ld/st*_phys to address_space_ld/st*
  exec.c: Capture the memory attributes for a watchpoint hit
  exec.c: Add new address_space_ld*/st* functions
  exec.c: Make address_space_rw take transaction attributes
  exec.c: Convert subpage memory ops to _with_attrs
  Add MemTxAttrs to the IOTLB
  Make CPU iotlb a structure rather than a plain hwaddr
  memory: Replace io_mem_read/write with memory_region_dispatch_read/write
  memory: Define API for MemoryRegionOps to take attrs and return status

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-28 10:31:03 +01:00
Peter Maydell
3d27b09cf6 Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20150427-1' into staging
spice: misc fixes.

# gpg: Signature made Mon Apr 27 12:03:16 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/spice/tags/pull-spice-20150427-1:
  spice: learn to hide cursor
  spice: set pointer position on hotspot
  spice: fix mouse cursor position
  spice: fix simple display on bigendian hosts
  monitor: Make client_migrate_info synchronous

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-27 20:00:57 +01:00
Eduardo Habkost
726a8ff686 target-i386: Remove AMD feature flag aliases from CPU model table
When CPU vendor is AMD, the AMD feature alias bits on
CPUID[0x80000001].EDX are already automatically copied from CPUID[1].EDX
on x86_cpu_realizefn(). When CPU vendor is Intel, those bits are
reserved and should be zero. On either case, those bits shouldn't be set
in the CPU model table.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-04-27 15:41:03 -03:00
Eduardo Habkost
01431f3ce0 target-i386: X86CPU::xlevel2 QOM property
We already have "level" and "xlevel", only "xlevel2" is missing.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-04-27 15:41:03 -03:00
Eduardo Habkost
b9472b76d2 target-i386: Make "level" and "xlevel" properties static
Static properties require only 1 line of code, much simpler than the
existing code that requires writing new getters/setters.

As a nice side-effect, this fixes an existing bug where the setters were
incorrectly allowing the properties to be changed after the CPU was
already realized.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-04-27 15:40:22 -03:00
Eduardo Habkost
d9f7e29ee5 qemu-config: Accept empty option values
Currently it is impossible to set an option in a config file to an empty
string, because the parser matches only lines containing non-empty
strings between double-quotes.

As sscanf() "[" conversion specifier only matches non-empty strings, add
a special case for empty strings.

Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-04-27 15:38:13 -03:00
Eduardo Habkost
b203a4ba93 MAINTAINERS: Change status of X86 to Maintained
"Odd Fixes" doesn't reflect the current status of target-i386. We have
people looking after it, now.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-04-27 15:38:13 -03:00
Eduardo Habkost
e1a0433956 MAINTAINERS: Add myself to X86
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-04-27 15:38:13 -03:00
Peter Maydell
3f9d69ba12 Merge remote-tracking branch 'remotes/kraxel/tags/pull-gtk-20150427-1' into staging
gtk: support text consoles without vte, bugfixes.

# gpg: Signature made Mon Apr 27 14:34:15 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-gtk-20150427-1:
  gtk: Avoid accel key leakage into guest on console switch
  gtk: Fix VTE focus grabbing
  console/gtk: add qemu_console_get_label
  gtk: bind to text terminal consoles too
  gtk: handle switch_surface(NULL) properly

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-27 19:06:08 +01:00
Eduardo Habkost
2f54eb98c3 MAINTAINERS: Add myself as NUMA code maintainer
The "srat" and "numa" keywords will help get_maintainer.pl catch
NUMA-related code in other files too.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-04-27 14:59:03 -03:00
Peter Maydell
0d81cdddaa Merge remote-tracking branch 'remotes/qmp-unstable/tags/for-upstream' into staging
Four little fixes

# gpg: Signature made Fri Apr 24 19:56:51 2015 BST using RSA key ID E24ED5A7
# gpg: Good signature from "Luiz Capitulino <lcapitulino@gmail.com>"

* remotes/qmp-unstable/tags/for-upstream:
  qmp: Give saner messages related to qmp_capabilities misuse
  qmp-commands: fix incorrect uses of ":O" specifier
  qapi: Drop dead genlist parameter
  balloon: improve error msg when adding second device

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-27 17:28:41 +01:00
Peter Crosthwaite
23820dbfc7 exec: Respect as_translate_internal length clamp
address_space_translate_internal will clamp the *plen length argument
based on the size of the memory region being queried. The iommu walker
logic in addresss_space_translate was ignoring this by discarding the
post fn call value of *plen. Fix by just always using *plen as the
length argument throughout the fn, removing the len local variable.

This fixes a bootloader bug when a single elf section spans multiple
QEMU memory regions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-Id: <1426570554-15940-1-git-send-email-peter.crosthwaite@xilinx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:19 +02:00
Paolo Bonzini
4080a13c11 ioport: reserve the whole range of an I/O port in the AddressSpace
When an I/O port is more than 1 byte long, ioport.c is currently
creating "short" regions, for example 0x1ce-0x1ce for the 16-bit
Bochs index port.  When I/O ports are memory mapped, and thus
accessed via a subpage_ops memory region, subpage_accepts gets
confused because it finds a hole at 0x1cf and rejects the access.

In order to fix this, modify registration of the region to cover
the whole size of the I/O port.  Attempts to access an invalid
port will be blocked by find_portio returning NULL.

This only affects the VBE DISPI regions.  For all other cases,
the MemoryRegionPortio entries for 2- or 4-byte accesses overlap
an entry for 1-byte accesses, thus the size of the memory region
is not affected.

Reported-by: Zoltan Balaton <balaton@eik.bme.hu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:19 +02:00
Paolo Bonzini
147ed37983 ioport: loosen assertions on emulation of 16-bit ports
Right now, ioport.c assumes that the entire range specified with
MemoryRegionPortio includes a region with size == 1.  This however
is not true for the VBE DISPI ports, which are 16-bit only.  The
next patch will make these regions' length equal to two, which can
cause the assertions to trigger.  Replace them with simple conditionals.

Also, ioport.c will emulate a 16-bit ioport with two distinct reads
or writes, even if one of the two accesses is out of the bounds given
by the MemoryRegionPortio array.  Do not do this anymore, instead
discard writes to the incorrect register and read it as all-ones.
This ensures that the mrp->read and mrp->write callbacks get an
in-range ioport number.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:19 +02:00
Paolo Bonzini
30476b2282 ioport: remove wrong comment
ioport.c has not been using an alias since commit b40acf9 (ioport:
Switch dispatching to memory core layer, 2013-06-24).  Remove the
obsolete comment.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:19 +02:00
Paolo Bonzini
e477317cce ide: there is only one data port
IDE PIO data must be written, for example, at 0x1f0.  You cannot
do word or dword writes to 0x1f1..0x1f3 to access the data register.
Adjust the ide_portio_list accordingly.

Cc: John Snow <jsnow@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:19 +02:00
Paolo Bonzini
54da54e543 gus: clean up MemoryRegionPortio
Remove 16-bit reads/writes, since ioport.c is able to synthesize them.
Remove the two MIDI registers (0x300 and 0x301) from gus_portio_list1,
and add the second MIDI register (0x301) to gus_portio_list2.

Tested with Second Reality.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:18 +02:00
Paolo Bonzini
3337d0b279 sb16: remove useless mixer_write_indexw
ioport.c is already able to split a 16-bit access into two 8-bit
accesses to consecutive ports.  Tested with Epic Pinball.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:18 +02:00
Mark Cave-Ayland
0e1cd6576c sun4m: fix slavio sysctrl and led register sizes
These were being incorrectly declared as MISC_SIZE (1 byte) rather than
4 bytes and 2 bytes respectively. As a result accesses clamped to the
real register size would unexpectedly fail.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <1427987370-15897-1-git-send-email-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:18 +02:00
Paolo Bonzini
339240b5cd acpi-build: remove dependency from ram_addr.h
ram_addr_t is an internal interface, everyone should go through
MemoryRegion.  Clean it up by making rom_add_blob return a
MemoryRegion* and using the new qemu_ram_resize infrastructure.

Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:18 +02:00
Paolo Bonzini
37d7c08413 memory: add memory_region_ram_resize
This is a simple MemoryRegion wrapper for qemu_ram_resize.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:18 +02:00
Fam Zheng
e95205e1f9 dma-helpers: Fix race condition of continue_after_map_failure and dma_aio_cancel
If DMA's owning thread cancels the IO while the bounce buffer's owning thread
is notifying the "cpu client list", a use-after-free happens:

     continue_after_map_failure               dma_aio_cancel
     ------------------------------------------------------------------
     aio_bh_new
                                              qemu_bh_delete
     qemu_bh_schedule (use after free)

Also, the old code doesn't run the bh in the right AioContext.

Fix both problems by passing a QEMUBH to cpu_register_map_client.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <1426496617-10702-6-git-send-email-famz@redhat.com>
[Remove unnecessary forward declaration. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:18 +02:00
Fam Zheng
33b6c2edf6 exec: Notify cpu_register_map_client caller if the bounce buffer is available
The caller's workflow is like

    if (!address_space_map()) {
        ...
        cpu_register_map_client();
    }

If bounce buffer became available after address_space_map() but before
cpu_register_map_client(), the caller could miss it and has to wait for the
next bounce buffer notify, which may never happen in the worse case.

Just notify the list in cpu_register_map_client().

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1426496617-10702-5-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:18 +02:00
Fam Zheng
38e047b50d exec: Protect map_client_list with mutex
So that accesses from multiple threads are safe.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1426496617-10702-4-git-send-email-famz@redhat.com>
[Remove #if from cpu_exec_init_all. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:17 +02:00
Fam Zheng
02f4035c47 linux-user, bsd-user: Remove two calls to cpu_exec_init_all
The function is a nop for user mode, so just remove them.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1426496617-10702-3-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:17 +02:00
Fam Zheng
c2cba0ffe4 exec: Atomic access to bounce buffer
There could be a race condition when two processes call
address_space_map concurrently and both want to use the bounce buffer.

Add an in_use flag in BounceBuffer to sync it.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1426496617-10702-2-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:17 +02:00
Emilio G. Cota
e3a0abfda7 translate-all: use glib for all page descriptor allocations
Since commit

  b7b5233a "bsd-user/mmap.c: Don't try to override g_malloc/g_free"

the exception we make here for usermode has been unnecessary.
Get rid of it.

Signed-off-by: Emilio G. Cota <cota@braap.org>
Message-Id: <1428610053-26148-1-git-send-email-cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-27 18:24:17 +02:00
Marc-André Lureau
700cd855de spice: learn to hide cursor
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-27 12:47:04 +02:00
Marc-André Lureau
dc8dceee64 spice: set pointer position on hotspot
The Spice protocol uses cursor position on hotspot: the client is
applying hotspot offset when drawing the cursor.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-27 12:47:04 +02:00
Marc-André Lureau
d0df04a156 spice: fix mouse cursor position
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-27 12:47:04 +02:00
Gerd Hoffmann
c1d37cd353 spice: fix simple display on bigendian hosts
Denis Kirjanov is busy getting spice run on ppc64 and trapped into this
one.  Spice wire format is little endian, so we have to explicitly say
we want little endian when letting pixman convert the data for us.

Reported-by: Denis Kirjanov <kirjanov@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-27 12:47:03 +02:00
Markus Armbruster
3b5704b2f8 monitor: Make client_migrate_info synchronous
Live migration with spice works like this today:

  (1) client_migrate_info monitor cmd
  (2) spice server notifies client, client connects to target host.
  (3) qemu waits until spice client connect is finished.
  (4) send over vmstate (i.e. main part of live migration).
  (5) spice handover to target host.

(3) is implemented by making client_migrate_info a async monitor
command.  This is the only async monitor command we have.

The original reason to implement this dance was that qemu did not accept
new tcp connections while the incoming migration was running, so (2) and
(4) could not be done in parallel.  That issue was fixed long ago though.
Qemu version 1.3.0 (released Dec 2012) and newer happily accept tcp
connects while the incoming migration runs.

Time to drop step (3).  This patch does exactly that, by making the
monitor command synchronous and removing the code needed to handle the
async monitor command in ui/spice-core.c

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-27 12:46:57 +02:00
Jan Kiszka
1a01716a30 gtk: Avoid accel key leakage into guest on console switch
GTK2 sends the accel key to the guest when switching to the graphic
console via that shortcut. Resolve this by ignoring any keys until the
next key-release event. However, do not ignore keys when switching via
the menu or when on GTK3.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-27 11:00:43 +02:00
Jan Kiszka
9d677e1c2f gtk: Fix VTE focus grabbing
At least on GTK2, the VTE terminal has to be specified as target of
gtk_widget_grab_focus. Otherwise, switching from one VTE terminal to
another causes the focus to get lost.

CC: John Snow <jsnow@redhat.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>

[ kraxel: fixed build with CONFIG_VTE=n ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-27 11:00:07 +02:00
Greg Bellows
4eb2764083 Allow ARMv8 SCR.SMD updates
Updated scr_write to always allow updates to the SCR.SMD bit on ARMv8
regardless of whether virtualization (EL2) is enabled or not.

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
Message-id: 1429888797-4378-1-git-send-email-greg.bellows@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-26 16:49:26 +01:00
Sergey Fedorov
3d5c84ff21 target-arm: Adjust id_aa64pfr0 when has_el3 CPU property disabled
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Message-id: 1429669112-29835-1-git-send-email-serge.fdrv@gmail.com
Reviewed-by: Greg Bellows <greg.bellows@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-26 16:49:26 +01:00
Sergey Fedorov
7ebd5f2e03 target-arm: rename c1_coproc to cpacr_el1
Rename the field holding CPACR_EL1 system register state in AArch64
naming style.

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
[PMM: also fixed a couple of missed occurrences in cpu.c]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-26 16:49:25 +01:00
Peter Maydell
ef7bab8d73 target-arm: Check watchpoints against CPU security state
Fix a TODO in bp_wp_matches() now that we have a function for
testing whether the CPU is currently in Secure mode or not.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:25 +01:00
Peter Maydell
9e1fc5bdfd target-arm: Use attribute info to handle user-only watchpoints
Now that we have memory access attribute information in the watchpoint
checking code, we can correctly implement handling of watchpoints
which should match only on userspace accesses, where LDRT/STRT/LDT/STT
from EL1 are treated as userspace accesses.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:25 +01:00
Peter Maydell
0995bf8cd9 target-arm: Add user-mode transaction attribute
Add a transaction attribute indicating that a memory access is being
done from user-mode (unprivileged). This corresponds to an equivalent
signal in ARM AMBA buses.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:25 +01:00
Peter Maydell
ebca90e4c3 target-arm: Use correct memory attributes for page table walks
Factor out the page table walk memory accesses into their own function,
so that we can specify the correct S/NS memory attributes for them.
This will also provide a place to use the correct endianness and
handle the need for a stage-2 translation when virtualization is
supported.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:25 +01:00
Peter Maydell
8bf5b6a9c1 target-arm: Honour NS bits in page tables
Honour the NS bit in ARM page tables:
 * when adding entries to the TLB, include the Secure/NonSecure
   transaction attribute
 * set the NS bit in the PAR when doing ATS operations

Note that we don't yet correctly use the NSTable bit to
cause the page table walk itself to use the right attributes.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:25 +01:00
Peter Maydell
42874d3a8c Switch non-CPU callers from ld/st*_phys to address_space_ld/st*
Switch all the uses of ld/st*_phys to address_space_ld/st*,
except for those cases where the address space is the CPU's
(ie cs->as). This was done with the following script which
generates a Coccinelle patch.

A few over-80-columns lines in the result were rewrapped by
hand where Coccinelle failed to do the wrapping automatically,
as well as one location where it didn't put a line-continuation
'\' when wrapping lines on a change made to a match inside
a macro definition.

===begin===
#!/bin/sh -e
# Usage:
# ./ldst-phys.spatch.sh > ldst-phys.spatch
# spatch -sp_file ldst-phys.spatch -dir . | sed -e '/^+/s/\t/        /g' > out.patch
# patch -p1 < out.patch

for FN in ub uw_le uw_be l_le l_be q_le q_be uw l q; do
cat <<EOF
@ cpu_matches_ld_${FN} @
expression E1,E2;
identifier as;
@@

ld${FN}_phys(E1->as,E2)

@ other_matches_ld_${FN} depends on !cpu_matches_ld_${FN} @
expression E1,E2;
@@

-ld${FN}_phys(E1,E2)
+address_space_ld${FN}(E1,E2, MEMTXATTRS_UNSPECIFIED, NULL)

EOF

done

for FN in b w_le w_be l_le l_be q_le q_be w l q; do
cat <<EOF
@ cpu_matches_st_${FN} @
expression E1,E2,E3;
identifier as;
@@

st${FN}_phys(E1->as,E2,E3)

@ other_matches_st_${FN} depends on !cpu_matches_st_${FN} @
expression E1,E2,E3;
@@

-st${FN}_phys(E1,E2,E3)
+address_space_st${FN}(E1,E2,E3, MEMTXATTRS_UNSPECIFIED, NULL)

EOF

done
===endit===

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:24 +01:00
Peter Maydell
66b9b43c42 exec.c: Capture the memory attributes for a watchpoint hit
Capture the memory attributes for the transaction which triggered
a watchpoint; this allows CPU specific code to implement features
like ARM's "user-mode only WPs also hit for LDRT/STRT accesses
made from privileged code". This change also correctly passes
through the memory attributes to the underlying device when
a watchpoint access doesn't hit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:24 +01:00
Peter Maydell
500131154d exec.c: Add new address_space_ld*/st* functions
Add new address_space_ld*/st* functions which allow transaction
attributes and error reporting for basic load and stores. These
are named to be in line with the address_space_read/write/rw
buffer operations.

The existing ld/st*_phys functions are now wrappers around
the new functions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:24 +01:00
Peter Maydell
5c9eb0286c exec.c: Make address_space_rw take transaction attributes
Make address_space_rw take transaction attributes, rather
than always using the 'unspecified' attributes.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:24 +01:00
Peter Maydell
f25a49e005 exec.c: Convert subpage memory ops to _with_attrs
Convert the subpage memory ops to _with_attrs; this will allow
us to pass the attributes through to the underlying access
functions. (Nothing uses the attributes yet.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2015-04-26 16:49:24 +01:00
Peter Maydell
fadc1cbe85 Add MemTxAttrs to the IOTLB
Add a MemTxAttrs field to the IOTLB, and allow target-specific
code to set it via a new tlb_set_page_with_attrs() function;
pass the attributes through to the device when making IO accesses.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:24 +01:00
Peter Maydell
e469b22ffd Make CPU iotlb a structure rather than a plain hwaddr
Make the CPU iotlb a structure rather than a plain hwaddr;
this will allow us to add transaction attributes to it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:23 +01:00
Peter Maydell
3b64349539 memory: Replace io_mem_read/write with memory_region_dispatch_read/write
Rather than retaining io_mem_read/write as simple wrappers around
the memory_region_dispatch_read/write functions, make the latter
public and change all the callers to use them, since we need to
touch all the callsites anyway to add MemTxAttrs and MemTxResult
support. Delete io_mem_read and io_mem_write entirely.

(All the callers currently pass MEMTXATTRS_UNSPECIFIED
and convert the return value back to bool or ignore it.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:23 +01:00
Peter Maydell
cc05c43ad9 memory: Define API for MemoryRegionOps to take attrs and return status
Define an API so that devices can register MemoryRegionOps whose read
and write callback functions are passed an arbitrary pointer to some
transaction attributes and can return a success-or-failure status code.
This will allow us to model devices which:
 * behave differently for ARM Secure/NonSecure memory accesses
 * behave differently for privileged/unprivileged accesses
 * may return a transaction failure (causing a guest exception)
   for erroneous accesses

This patch defines the new API and plumbs the attributes parameter through
to the memory.c public level functions io_mem_read() and io_mem_write(),
where it is currently dummied out.

The success/failure response indication is also propagated out to
io_mem_read() and io_mem_write(), which retain the old-style
boolean true-for-error return.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 16:49:23 +01:00
Peter Maydell
e1a5476354 Open 2.4 development tree
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-04-25 22:05:07 +01:00
Eric Blake
2d5a8346a4 qmp: Give saner messages related to qmp_capabilities misuse
Pretending that QMP doesn't understand a command merely because
we are not in the right mode doesn't help first-time users figure
out what to do to correct things.  Although the documentation for
QMP calls out capabilities negotiation, we should also make it
clear in our error messages what we were expecting.  With this
patch, I now get the following transcript:

$ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
{"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
{"execute":"huh"}
{"error": {"class": "CommandNotFound", "desc": "The command huh has not been found"}}
{"execute":"quit"}
{"error": {"class": "CommandNotFound", "desc": "Expecting capabilities negotiation with 'qmp_capabilities' before command 'quit'"}}
{"execute":"qmp_capabilities"}
{"return": {}}
{"execute":"qmp_capabilities"}
{"error": {"class": "CommandNotFound", "desc": "Capabilities negotiation is already complete, command 'qmp_capabilities' ignored"}}
{"execute":"quit"}
{"return": {}}
{"timestamp": {"seconds": 1429110729, "microseconds": 181935}, "event": "SHUTDOWN"}

Signed-off-by: Eric Blake <eblake@redhat.com>
Tested-By: Kashyap Chamarthy <kchamart@redhat.com>
Reviewed-by: Paulo Vital <paulo.vital@profitbricks.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-04-24 14:18:06 -04:00
Paolo Bonzini
43d0a2c1af qmp-commands: fix incorrect uses of ":O" specifier
As far as the QMP parser is concerned, neither the 'O' nor the 'q' format specifiers
put any constraint on the command.  However, there are two differences:

1) from a documentation point of view 'O' says that this command takes
a dictionary.  The dictionary will be converted to QemuOpts in the
handler to match the corresponding HMP command.

2) 'O' sets QMP_ACCEPT_UNKNOWNS, resulting in the command accepting invalid
extra arguments.  For example the following is accepted:

   { "execute": "send-key",
        "arguments": { "keys": [ { "type": "qcode", "data": "ctrl" },
                                 { "type": "qcode", "data": "alt" },
                                 { "type": "qcode", "data": "delete" } ], "foo": "bar" } }

Neither send-key nor migrate-set-capabilities take a QemuOpts-like
dictionary; they take an array of dictionaries.  And neither command
really wants to have extra unknown arguments.  Thus, the right
specifier to use in this case is 'q'; with this patch the above
command fails with

   {"error": {"class": "GenericError", "desc": "Invalid parameter 'foo'"}}

as intended.

Reported-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-04-24 14:18:06 -04:00
Eric Blake
6540e9f35b qapi: Drop dead genlist parameter
Defaulting a parameter to True, then having all callers omit or
pass an explicit True for that parameter, is pointless. Looks
like it has been dead since introduction in commit 06d64c6, more
than 4 years ago.

Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-04-24 14:18:05 -04:00
Luiz Capitulino
46abb81240 balloon: improve error msg when adding second device
A VM supports only one balloon device, but due to several changes
in infrastructure the error message got messed up when trying
to add a second device. Fix it.

Before this fix

Command-line:

qemu-qmp: -device virtio-balloon-pci,id=balloon0: Another balloon device already registered
qemu-qmp: -device virtio-balloon-pci,id=balloon0: Adding balloon handler failed
qemu-qmp: -device virtio-balloon-pci,id=balloon0: Device 'virtio-balloon-pci' could not be initialized

HMP:

Another balloon device already registered
Adding balloon handler failed
Device 'virtio-balloon-pci' could not be initialized

QMP:

{ "execute": "device_add", "arguments": { "driver": "virtio-balloon-pci", "id": "balloon0" } }
{
	"error": {
		"class": "GenericError",
		"desc": "Adding balloon handler failed"
	}
}

After this fix

Command-line:

qemu-qmp: -device virtio-balloon-pci,id=balloon0: Only one balloon device is supported
qemu-qmp: -device virtio-balloon-pci,id=balloon0: Device 'virtio-balloon-pci' could not be initialized

HMP:

(qemu) device_add virtio-balloon-pci,id=balloon0
Only one balloon device is supported
Device 'virtio-balloon-pci' could not be initialized
(qemu)

QMP:

{ "execute": "device_add",
          "arguments": { "driver": "virtio-balloon-pci", "id": "balloon0" } }
{
    "error": {
        "class": "GenericError",
        "desc": "Only one balloon device is supported"
    }
}

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2015-04-24 14:18:05 -04:00
Gerd Hoffmann
779ce88fbd console/gtk: add qemu_console_get_label
Add a new function to get a nice label for a given QemuConsole.
Drop the labeling code in gtk.c and use the new function instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-22 13:21:16 +02:00
Gerd Hoffmann
f8c223f69a gtk: bind to text terminal consoles too
This way gtk has text terminal consoles even when building without vte.
Most notably you'll get a monitor tab on windows now.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-22 13:21:16 +02:00
Gerd Hoffmann
f98f43eab0 gtk: handle switch_surface(NULL) properly
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-04-22 13:21:16 +02:00
268 changed files with 9541 additions and 4509 deletions

View File

@@ -172,7 +172,8 @@ F: hw/unicore32/
X86
M: Paolo Bonzini <pbonzini@redhat.com>
M: Richard Henderson <rth@twiddle.net>
S: Odd Fixes
M: Eduardo Habkost <ehabkost@redhat.com>
S: Maintained
F: target-i386/
F: hw/i386/
@@ -703,10 +704,13 @@ F: tests/virtio-9p-test.c
T: git git://github.com/kvaneesh/QEMU.git
virtio-blk
M: Kevin Wolf <kwolf@redhat.com>
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: hw/block/virtio-blk.c
F: hw/block/dataplane/*
F: hw/virtio/dataplane/*
T: git git://github.com/stefanha/qemu.git block
virtio-ccw
M: Cornelia Huck <cornelia.huck@de.ibm.com>
@@ -731,12 +735,14 @@ F: backends/rng*.c
nvme
M: Keith Busch <keith.busch@intel.com>
L: qemu-block@nongnu.org
S: Supported
F: hw/block/nvme*
F: tests/nvme-test.c
megasas
M: Hannes Reinecke <hare@suse.de>
L: qemu-block@nongnu.org
S: Supported
F: hw/scsi/megasas.c
F: hw/scsi/mfi.h
@@ -766,21 +772,26 @@ F: tests/ac97-test.c
F: tests/es1370-test.c
F: tests/intel-hda-test.c
Block
Block layer core
M: Kevin Wolf <kwolf@redhat.com>
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: async.c
F: aio-*.c
F: block*
F: block/
F: hw/block/
F: migration/block*
F: qemu-img*
F: qemu-io*
F: tests/image-fuzzer/
F: tests/qemu-iotests/
T: git git://repo.or.cz/qemu/kevin.git block
Block I/O path
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: async.c
F: aio-*.c
F: block/io.c
F: migration/block*
T: git git://github.com/stefanha/qemu.git block
Block Jobs
@@ -905,6 +916,15 @@ F: nbd.*
F: qemu-nbd.c
T: git git://github.com/bonzini/qemu.git nbd-next
NUMA
M: Eduardo Habkost <ehabkost@redhat.com>
S: Maintained
F: numa.c
F: include/sysemu/numa.h
K: numa|NUMA
K: srat|SRAT
T: git git://github.com/ehabkost/qemu.git numa
QAPI
M: Luiz Capitulino <lcapitulino@redhat.com>
M: Michael Roth <mdroth@linux.vnet.ibm.com>
@@ -1094,6 +1114,7 @@ Block drivers
-------------
VMDK
M: Fam Zheng <famz@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/vmdk.c
@@ -1124,6 +1145,7 @@ T: git git://github.com/codyprime/qemu-kvm-jtc.git block
VDI
M: Stefan Weil <sw@weilnetz.de>
L: qemu-block@nongnu.org
S: Maintained
F: block/vdi.c
@@ -1131,6 +1153,7 @@ iSCSI
M: Ronnie Sahlberg <ronniesahlberg@gmail.com>
M: Paolo Bonzini <pbonzini@redhat.com>
M: Peter Lieven <pl@kamp.de>
L: qemu-block@nongnu.org
S: Supported
F: block/iscsi.c
@@ -1172,7 +1195,102 @@ S: Supported
F: block/gluster.c
T: git git://github.com/codyprime/qemu-kvm-jtc.git block
Null Block Driver
M: Fam Zheng <famz@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/null.c
Bootdevice
M: Gonglei <arei.gonglei@huawei.com>
S: Maintained
F: bootdevice.c
Quorum
M: Alberto Garcia <berto@igalia.com>
S: Supported
F: block/quorum.c
L: qemu-block@nongnu.org
blkverify
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/blkverify.c
bochs
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/bochs.c
cloop
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/cloop.c
dmg
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/dmg.c
parallels
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/parallels.c
qed
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/qed.c
raw
M: Kevin Wolf <kwolf@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/linux-aio.c
F: block/raw-aio.h
F: block/raw-posix.c
F: block/raw-win32.c
F: block/raw_bsd.c
F: block/win32-aio.c
qcow2
M: Kevin Wolf <kwolf@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/qcow2*
qcow
M: Kevin Wolf <kwolf@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/qcow.c
blkdebug
M: Kevin Wolf <kwolf@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/blkdebug.c
vpc
M: Kevin Wolf <kwolf@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/vpc.c
vvfat
M: Kevin Wolf <kwolf@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: block/vvfat.c
Image format fuzzer
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: tests/image-fuzzer/

View File

@@ -296,6 +296,7 @@ clean:
rm -f fsdev/*.pod
rm -rf .libs */.libs
rm -f qemu-img-cmds.h
rm -f ui/shader/*-vert.h ui/shader/*-frag.h
@# May not be present in GENERATED_HEADERS
rm -f trace/generated-tracers-dtrace.dtrace*
rm -f trace/generated-tracers-dtrace.h*
@@ -441,6 +442,22 @@ cscope:
find "$(SRC_PATH)" -name "*.[chsS]" -print | sed 's,^\./,,' > ./cscope.files
cscope -b
# opengl shader programs
ui/shader/%-vert.h: $(SRC_PATH)/ui/shader/%.vert $(SRC_PATH)/scripts/shaderinclude.pl
@mkdir -p $(dir $@)
$(call quiet-command,\
perl $(SRC_PATH)/scripts/shaderinclude.pl $< > $@,\
" VERT $@")
ui/shader/%-frag.h: $(SRC_PATH)/ui/shader/%.frag $(SRC_PATH)/scripts/shaderinclude.pl
@mkdir -p $(dir $@)
$(call quiet-command,\
perl $(SRC_PATH)/scripts/shaderinclude.pl $< > $@,\
" FRAG $@")
ui/console-gl.o: $(SRC_PATH)/ui/console-gl.c \
ui/shader/texture-blit-vert.h ui/shader/texture-blit-frag.h
# documentation
MAKEINFO=makeinfo
MAKEINFOFLAGS=--no-headers --no-split --number-sections

View File

@@ -134,7 +134,7 @@ obj-$(CONFIG_KVM) += kvm-all.o
obj-y += memory.o savevm.o cputlb.o
obj-y += memory_mapping.o
obj-y += dump.o
LIBS+=$(libs_softmmu)
LIBS := $(libs_softmmu) $(LIBS)
# xen support
obj-$(CONFIG_XEN) += xen-common.o

View File

@@ -1 +1 @@
2.3.0
2.3.50

View File

@@ -24,7 +24,6 @@ struct AioHandler
IOHandler *io_read;
IOHandler *io_write;
int deleted;
int pollfds_idx;
void *opaque;
QLIST_ENTRY(AioHandler) node;
};
@@ -83,7 +82,6 @@ void aio_set_fd_handler(AioContext *ctx,
node->io_read = io_read;
node->io_write = io_write;
node->opaque = opaque;
node->pollfds_idx = -1;
node->pfd.events = (io_read ? G_IO_IN | G_IO_HUP | G_IO_ERR : 0);
node->pfd.events |= (io_write ? G_IO_OUT | G_IO_ERR : 0);
@@ -186,13 +184,61 @@ bool aio_dispatch(AioContext *ctx)
return progress;
}
/* These thread-local variables are used only in a small part of aio_poll
* around the call to the poll() system call. In particular they are not
* used while aio_poll is performing callbacks, which makes it much easier
* to think about reentrancy!
*
* Stack-allocated arrays would be perfect but they have size limitations;
* heap allocation is expensive enough that we want to reuse arrays across
* calls to aio_poll(). And because poll() has to be called without holding
* any lock, the arrays cannot be stored in AioContext. Thread-local data
* has none of the disadvantages of these three options.
*/
static __thread GPollFD *pollfds;
static __thread AioHandler **nodes;
static __thread unsigned npfd, nalloc;
static __thread Notifier pollfds_cleanup_notifier;
static void pollfds_cleanup(Notifier *n, void *unused)
{
g_assert(npfd == 0);
g_free(pollfds);
g_free(nodes);
nalloc = 0;
}
static void add_pollfd(AioHandler *node)
{
if (npfd == nalloc) {
if (nalloc == 0) {
pollfds_cleanup_notifier.notify = pollfds_cleanup;
qemu_thread_atexit_add(&pollfds_cleanup_notifier);
nalloc = 8;
} else {
g_assert(nalloc <= INT_MAX);
nalloc *= 2;
}
pollfds = g_renew(GPollFD, pollfds, nalloc);
nodes = g_renew(AioHandler *, nodes, nalloc);
}
nodes[npfd] = node;
pollfds[npfd] = (GPollFD) {
.fd = node->pfd.fd,
.events = node->pfd.events,
};
npfd++;
}
bool aio_poll(AioContext *ctx, bool blocking)
{
AioHandler *node;
bool was_dispatching;
int ret;
int i, ret;
bool progress;
int64_t timeout;
aio_context_acquire(ctx);
was_dispatching = ctx->dispatching;
progress = false;
@@ -210,39 +256,36 @@ bool aio_poll(AioContext *ctx, bool blocking)
ctx->walking_handlers++;
g_array_set_size(ctx->pollfds, 0);
assert(npfd == 0);
/* fill pollfds */
QLIST_FOREACH(node, &ctx->aio_handlers, node) {
node->pollfds_idx = -1;
if (!node->deleted && node->pfd.events) {
GPollFD pfd = {
.fd = node->pfd.fd,
.events = node->pfd.events,
};
node->pollfds_idx = ctx->pollfds->len;
g_array_append_val(ctx->pollfds, pfd);
add_pollfd(node);
}
}
ctx->walking_handlers--;
timeout = blocking ? aio_compute_timeout(ctx) : 0;
/* wait until next event */
ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data,
ctx->pollfds->len,
blocking ? aio_compute_timeout(ctx) : 0);
if (timeout) {
aio_context_release(ctx);
}
ret = qemu_poll_ns((GPollFD *)pollfds, npfd, timeout);
if (timeout) {
aio_context_acquire(ctx);
}
/* if we have any readable fds, dispatch event */
if (ret > 0) {
QLIST_FOREACH(node, &ctx->aio_handlers, node) {
if (node->pollfds_idx != -1) {
GPollFD *pfd = &g_array_index(ctx->pollfds, GPollFD,
node->pollfds_idx);
node->pfd.revents = pfd->revents;
}
for (i = 0; i < npfd; i++) {
nodes[i]->pfd.revents = pollfds[i].revents;
}
}
npfd = 0;
ctx->walking_handlers--;
/* Run dispatch even if there were no readable fds to run timers */
aio_set_dispatching(ctx, true);
if (aio_dispatch(ctx)) {
@@ -250,5 +293,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
}
aio_set_dispatching(ctx, was_dispatching);
aio_context_release(ctx);
return progress;
}

View File

@@ -283,6 +283,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
int count;
int timeout;
aio_context_acquire(ctx);
have_select_revents = aio_prepare(ctx);
if (have_select_revents) {
blocking = false;
@@ -323,7 +324,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
timeout = blocking
? qemu_timeout_ns_to_ms(aio_compute_timeout(ctx)) : 0;
if (timeout) {
aio_context_release(ctx);
}
ret = WaitForMultipleObjects(count, events, FALSE, timeout);
if (timeout) {
aio_context_acquire(ctx);
}
aio_set_dispatching(ctx, true);
if (first && aio_bh_poll(ctx)) {
@@ -349,5 +356,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
progress |= timerlistgroup_run_timers(&ctx->tlg);
aio_set_dispatching(ctx, was_dispatching);
aio_context_release(ctx);
return progress;
}

10
async.c
View File

@@ -230,7 +230,6 @@ aio_ctx_finalize(GSource *source)
event_notifier_cleanup(&ctx->notifier);
rfifolock_destroy(&ctx->lock);
qemu_mutex_destroy(&ctx->bh_lock);
g_array_free(ctx->pollfds, TRUE);
timerlistgroup_deinit(&ctx->tlg);
}
@@ -281,12 +280,6 @@ static void aio_timerlist_notify(void *opaque)
aio_notify(opaque);
}
static void aio_rfifolock_cb(void *opaque)
{
/* Kick owner thread in case they are blocked in aio_poll() */
aio_notify(opaque);
}
AioContext *aio_context_new(Error **errp)
{
int ret;
@@ -302,10 +295,9 @@ AioContext *aio_context_new(Error **errp)
aio_set_event_notifier(ctx, &ctx->notifier,
(EventNotifierHandler *)
event_notifier_test_and_clear);
ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
ctx->thread_pool = NULL;
qemu_mutex_init(&ctx->bh_lock);
rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
rfifolock_init(&ctx->lock, NULL, NULL);
timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);
return ctx;

View File

@@ -43,7 +43,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
return;
}
if (!fb->mem_path) {
error_setg(errp, "mem_path property not set");
error_setg(errp, "mem-path property not set");
return;
}
#ifndef CONFIG_LINUX

View File

@@ -58,7 +58,6 @@ int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
/* We're already registered one balloon handler. How many can
* a guest really have?
*/
error_report("Another balloon device already registered");
return -1;
}
balloon_event_fn = event_func;

2740
block.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o
@@ -9,7 +9,7 @@ block-obj-y += block-backend.o snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
block-obj-$(CONFIG_POSIX) += raw-posix.o
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
block-obj-y += null.o mirror.o
block-obj-y += null.o mirror.o io.o
block-obj-y += nbd.o nbd-client.o sheepdog.o
block-obj-$(CONFIG_LIBISCSI) += iscsi.o
@@ -37,6 +37,7 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
ssh.o-cflags := $(LIBSSH2_CFLAGS)
ssh.o-libs := $(LIBSSH2_LIBS)
archipelago.o-libs := $(ARCHIPELAGO_LIBS)
block-obj-m += dmg.o
dmg.o-libs := $(BZIP2_LIBS)
qcow.o-libs := -lz
linux-aio.o-libs := -laio

View File

@@ -37,6 +37,8 @@ typedef struct CowRequest {
typedef struct BackupBlockJob {
BlockJob common;
BlockDriverState *target;
/* bitmap for sync=dirty-bitmap */
BdrvDirtyBitmap *sync_bitmap;
MirrorSyncMode sync_mode;
RateLimit limit;
BlockdevOnError on_source_error;
@@ -242,6 +244,91 @@ static void backup_complete(BlockJob *job, void *opaque)
g_free(data);
}
static bool coroutine_fn yield_and_check(BackupBlockJob *job)
{
if (block_job_is_cancelled(&job->common)) {
return true;
}
/* we need to yield so that bdrv_drain_all() returns.
* (without, VM does not reboot)
*/
if (job->common.speed) {
uint64_t delay_ns = ratelimit_calculate_delay(&job->limit,
job->sectors_read);
job->sectors_read = 0;
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
} else {
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);
}
if (block_job_is_cancelled(&job->common)) {
return true;
}
return false;
}
static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
{
bool error_is_read;
int ret = 0;
int clusters_per_iter;
uint32_t granularity;
int64_t sector;
int64_t cluster;
int64_t end;
int64_t last_cluster = -1;
BlockDriverState *bs = job->common.bs;
HBitmapIter hbi;
granularity = bdrv_dirty_bitmap_granularity(job->sync_bitmap);
clusters_per_iter = MAX((granularity / BACKUP_CLUSTER_SIZE), 1);
bdrv_dirty_iter_init(job->sync_bitmap, &hbi);
/* Find the next dirty sector(s) */
while ((sector = hbitmap_iter_next(&hbi)) != -1) {
cluster = sector / BACKUP_SECTORS_PER_CLUSTER;
/* Fake progress updates for any clusters we skipped */
if (cluster != last_cluster + 1) {
job->common.offset += ((cluster - last_cluster - 1) *
BACKUP_CLUSTER_SIZE);
}
for (end = cluster + clusters_per_iter; cluster < end; cluster++) {
do {
if (yield_and_check(job)) {
return ret;
}
ret = backup_do_cow(bs, cluster * BACKUP_SECTORS_PER_CLUSTER,
BACKUP_SECTORS_PER_CLUSTER, &error_is_read);
if ((ret < 0) &&
backup_error_action(job, error_is_read, -ret) ==
BLOCK_ERROR_ACTION_REPORT) {
return ret;
}
} while (ret < 0);
}
/* If the bitmap granularity is smaller than the backup granularity,
* we need to advance the iterator pointer to the next cluster. */
if (granularity < BACKUP_CLUSTER_SIZE) {
bdrv_set_dirty_iter(&hbi, cluster * BACKUP_SECTORS_PER_CLUSTER);
}
last_cluster = cluster - 1;
}
/* Play some final catchup with the progress meter */
end = DIV_ROUND_UP(job->common.len, BACKUP_CLUSTER_SIZE);
if (last_cluster + 1 < end) {
job->common.offset += ((end - last_cluster - 1) * BACKUP_CLUSTER_SIZE);
}
return ret;
}
static void coroutine_fn backup_run(void *opaque)
{
BackupBlockJob *job = opaque;
@@ -259,8 +346,7 @@ static void coroutine_fn backup_run(void *opaque)
qemu_co_rwlock_init(&job->flush_rwlock);
start = 0;
end = DIV_ROUND_UP(job->common.len / BDRV_SECTOR_SIZE,
BACKUP_SECTORS_PER_CLUSTER);
end = DIV_ROUND_UP(job->common.len, BACKUP_CLUSTER_SIZE);
job->bitmap = hbitmap_alloc(end, 0);
@@ -278,28 +364,13 @@ static void coroutine_fn backup_run(void *opaque)
qemu_coroutine_yield();
job->common.busy = true;
}
} else if (job->sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP) {
ret = backup_run_incremental(job);
} else {
/* Both FULL and TOP SYNC_MODE's require copying.. */
for (; start < end; start++) {
bool error_is_read;
if (block_job_is_cancelled(&job->common)) {
break;
}
/* we need to yield so that qemu_aio_flush() returns.
* (without, VM does not reboot)
*/
if (job->common.speed) {
uint64_t delay_ns = ratelimit_calculate_delay(
&job->limit, job->sectors_read);
job->sectors_read = 0;
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
} else {
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);
}
if (block_job_is_cancelled(&job->common)) {
if (yield_and_check(job)) {
break;
}
@@ -357,6 +428,18 @@ static void coroutine_fn backup_run(void *opaque)
qemu_co_rwlock_wrlock(&job->flush_rwlock);
qemu_co_rwlock_unlock(&job->flush_rwlock);
if (job->sync_bitmap) {
BdrvDirtyBitmap *bm;
if (ret < 0) {
/* Merge the successor back into the parent, delete nothing. */
bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
assert(bm);
} else {
/* Everything is fine, delete this bitmap and install the backup. */
bm = bdrv_dirty_bitmap_abdicate(bs, job->sync_bitmap, NULL);
assert(bm);
}
}
hbitmap_free(job->bitmap);
bdrv_iostatus_disable(target);
@@ -369,6 +452,7 @@ static void coroutine_fn backup_run(void *opaque)
void backup_start(BlockDriverState *bs, BlockDriverState *target,
int64_t speed, MirrorSyncMode sync_mode,
BdrvDirtyBitmap *sync_bitmap,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
BlockCompletionFunc *cb, void *opaque,
@@ -412,17 +496,36 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
return;
}
if (sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP) {
if (!sync_bitmap) {
error_setg(errp, "must provide a valid bitmap name for "
"\"dirty-bitmap\" sync mode");
return;
}
/* Create a new bitmap, and freeze/disable this one. */
if (bdrv_dirty_bitmap_create_successor(bs, sync_bitmap, errp) < 0) {
return;
}
} else if (sync_bitmap) {
error_setg(errp,
"a sync_bitmap was provided to backup_run, "
"but received an incompatible sync_mode (%s)",
MirrorSyncMode_lookup[sync_mode]);
return;
}
len = bdrv_getlength(bs);
if (len < 0) {
error_setg_errno(errp, -len, "unable to get length for '%s'",
bdrv_get_device_name(bs));
return;
goto error;
}
BackupBlockJob *job = block_job_create(&backup_job_driver, bs, speed,
cb, opaque, errp);
if (!job) {
return;
goto error;
}
bdrv_op_block_all(target, job->common.blocker);
@@ -431,7 +534,15 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
job->on_target_error = on_target_error;
job->target = target;
job->sync_mode = sync_mode;
job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP ?
sync_bitmap : NULL;
job->common.len = len;
job->common.co = qemu_coroutine_create(backup_run);
qemu_coroutine_enter(job->common.co, job);
return;
error:
if (sync_bitmap) {
bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);
}
}

View File

@@ -721,6 +721,11 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
return bdrv_getlength(bs->file);
}
static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
{
return bdrv_truncate(bs->file, offset);
}
static void blkdebug_refresh_filename(BlockDriverState *bs)
{
QDict *opts;
@@ -779,6 +784,7 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_file_open = blkdebug_open,
.bdrv_close = blkdebug_close,
.bdrv_getlength = blkdebug_getlength,
.bdrv_truncate = blkdebug_truncate,
.bdrv_refresh_filename = blkdebug_refresh_filename,
.bdrv_aio_readv = blkdebug_aio_readv,

View File

@@ -515,6 +515,17 @@ int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
return bdrv_write(blk->bs, sector_num, buf, nb_sectors);
}
int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
int nb_sectors, BdrvRequestFlags flags)
{
int ret = blk_check_request(blk, sector_num, nb_sectors);
if (ret < 0) {
return ret;
}
return bdrv_write_zeroes(blk->bs, sector_num, nb_sectors, flags);
}
static void error_callback_bh(void *opaque)
{
struct BlockBackendAIOCB *acb = opaque;

2540
block/io.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
* QEMU Block driver for iSCSI images
*
* Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
* Copyright (c) 2012-2014 Peter Lieven <pl@kamp.de>
* Copyright (c) 2012-2015 Peter Lieven <pl@kamp.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -57,9 +57,6 @@ typedef struct IscsiLun {
int events;
QEMUTimer *nop_timer;
QEMUTimer *event_timer;
uint8_t lbpme;
uint8_t lbprz;
uint8_t has_write_same;
struct scsi_inquiry_logical_block_provisioning lbp;
struct scsi_inquiry_block_limits bl;
unsigned char *zeroblock;
@@ -67,6 +64,11 @@ typedef struct IscsiLun {
int cluster_sectors;
bool use_16_for_rw;
bool write_protected;
bool lbpme;
bool lbprz;
bool dpofua;
bool has_write_same;
bool force_next_flush;
} IscsiLun;
typedef struct IscsiTask {
@@ -79,6 +81,7 @@ typedef struct IscsiTask {
QEMUBH *bh;
IscsiLun *iscsilun;
QEMUTimer retry_timer;
bool force_next_flush;
} IscsiTask;
typedef struct IscsiAIOCB {
@@ -100,7 +103,7 @@ typedef struct IscsiAIOCB {
#define NOP_INTERVAL 5000
#define MAX_NOP_FAILURES 3
#define ISCSI_CMD_RETRIES ARRAY_SIZE(iscsi_retry_times)
static const unsigned iscsi_retry_times[] = {8, 32, 128, 512, 2048};
static const unsigned iscsi_retry_times[] = {8, 32, 128, 512, 2048, 8192, 32768};
/* this threshold is a trade-off knob to choose between
* the potential additional overhead of an extra GET_LBA_STATUS request
@@ -183,10 +186,13 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
iTask->do_retry = 1;
goto out;
}
if (status == SCSI_STATUS_BUSY) {
/* status 0x28 is SCSI_TASK_SET_FULL. It was first introduced
* in libiscsi 1.10.0. Hardcode this value here to avoid
* the need to bump the libiscsi requirement to 1.10.0 */
if (status == SCSI_STATUS_BUSY || status == 0x28) {
unsigned retry_time =
exp_random(iscsi_retry_times[iTask->retries - 1]);
error_report("iSCSI Busy (retry #%u in %u ms): %s",
error_report("iSCSI Busy/TaskSetFull (retry #%u in %u ms): %s",
iTask->retries, retry_time,
iscsi_get_error(iscsi));
aio_timer_init(iTask->iscsilun->aio_context,
@@ -199,6 +205,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
}
}
error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));
} else {
iTask->iscsilun->force_next_flush |= iTask->force_next_flush;
}
out:
@@ -369,6 +377,7 @@ static int coroutine_fn iscsi_co_writev(BlockDriverState *bs,
struct IscsiTask iTask;
uint64_t lba;
uint32_t num_sectors;
int fua;
if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
return -EINVAL;
@@ -384,15 +393,17 @@ static int coroutine_fn iscsi_co_writev(BlockDriverState *bs,
num_sectors = sector_qemu2lun(nb_sectors, iscsilun);
iscsi_co_init_iscsitask(iscsilun, &iTask);
retry:
fua = iscsilun->dpofua && !bs->enable_write_cache;
iTask.force_next_flush = !fua;
if (iscsilun->use_16_for_rw) {
iTask.task = iscsi_write16_task(iscsilun->iscsi, iscsilun->lun, lba,
NULL, num_sectors * iscsilun->block_size,
iscsilun->block_size, 0, 0, 0, 0, 0,
iscsilun->block_size, 0, 0, fua, 0, 0,
iscsi_co_generic_cb, &iTask);
} else {
iTask.task = iscsi_write10_task(iscsilun->iscsi, iscsilun->lun, lba,
NULL, num_sectors * iscsilun->block_size,
iscsilun->block_size, 0, 0, 0, 0, 0,
iscsilun->block_size, 0, 0, fua, 0, 0,
iscsi_co_generic_cb, &iTask);
}
if (iTask.task == NULL) {
@@ -460,7 +471,7 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
*pnum = nb_sectors;
/* LUN does not support logical block provisioning */
if (iscsilun->lbpme == 0) {
if (!iscsilun->lbpme) {
goto out;
}
@@ -620,8 +631,12 @@ static int coroutine_fn iscsi_co_flush(BlockDriverState *bs)
return 0;
}
iscsi_co_init_iscsitask(iscsilun, &iTask);
if (!iscsilun->force_next_flush) {
return 0;
}
iscsilun->force_next_flush = false;
iscsi_co_init_iscsitask(iscsilun, &iTask);
retry:
if (iscsi_synchronizecache10_task(iscsilun->iscsi, iscsilun->lun, 0, 0, 0,
0, iscsi_co_generic_cb, &iTask) == NULL) {
@@ -917,6 +932,7 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
}
iscsi_co_init_iscsitask(iscsilun, &iTask);
iTask.force_next_flush = true;
retry:
if (use_16_for_ws) {
iTask.task = iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, lba,
@@ -1121,8 +1137,8 @@ static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
} else {
iscsilun->block_size = rc16->block_length;
iscsilun->num_blocks = rc16->returned_lba + 1;
iscsilun->lbpme = rc16->lbpme;
iscsilun->lbprz = rc16->lbprz;
iscsilun->lbpme = !!rc16->lbpme;
iscsilun->lbprz = !!rc16->lbprz;
iscsilun->use_16_for_rw = (rc16->returned_lba > 0xffffffff);
}
}
@@ -1253,11 +1269,12 @@ static void iscsi_attach_aio_context(BlockDriverState *bs,
iscsi_timed_set_events, iscsilun);
}
static bool iscsi_is_write_protected(IscsiLun *iscsilun)
static void iscsi_modesense_sync(IscsiLun *iscsilun)
{
struct scsi_task *task;
struct scsi_mode_sense *ms = NULL;
bool wrprotected = false;
iscsilun->write_protected = false;
iscsilun->dpofua = false;
task = iscsi_modesense6_sync(iscsilun->iscsi, iscsilun->lun,
1, SCSI_MODESENSE_PC_CURRENT,
@@ -1278,13 +1295,13 @@ static bool iscsi_is_write_protected(IscsiLun *iscsilun)
iscsi_get_error(iscsilun->iscsi));
goto out;
}
wrprotected = ms->device_specific_parameter & 0x80;
iscsilun->write_protected = ms->device_specific_parameter & 0x80;
iscsilun->dpofua = ms->device_specific_parameter & 0x10;
out:
if (task) {
scsi_free_scsi_task(task);
}
return wrprotected;
}
/*
@@ -1403,7 +1420,8 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
scsi_free_scsi_task(task);
task = NULL;
iscsilun->write_protected = iscsi_is_write_protected(iscsilun);
iscsi_modesense_sync(iscsilun);
/* Check the write protect flag of the LUN if we want to write */
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
iscsilun->write_protected) {
@@ -1481,7 +1499,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
iscsilun->block_size) >> BDRV_SECTOR_BITS;
if (iscsilun->lbprz && !(bs->open_flags & BDRV_O_NOCACHE)) {
if (iscsilun->lbprz) {
iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
if (iscsilun->allocationmap == NULL) {
ret = -ENOMEM;
@@ -1501,6 +1519,9 @@ out:
if (ret) {
if (iscsi != NULL) {
if (iscsi_is_logged_in(iscsi)) {
iscsi_logout_sync(iscsi);
}
iscsi_destroy_context(iscsi);
}
memset(iscsilun, 0, sizeof(IscsiLun));
@@ -1514,6 +1535,9 @@ static void iscsi_close(BlockDriverState *bs)
struct iscsi_context *iscsi = iscsilun->iscsi;
iscsi_detach_aio_context(bs);
if (iscsi_is_logged_in(iscsi)) {
iscsi_logout_sync(iscsi);
}
iscsi_destroy_context(iscsi);
g_free(iscsilun->zeroblock);
g_free(iscsilun->allocationmap);
@@ -1649,7 +1673,7 @@ out:
static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
{
IscsiLun *iscsilun = bs->opaque;
bdi->unallocated_blocks_are_zero = !!iscsilun->lbprz;
bdi->unallocated_blocks_are_zero = iscsilun->lbprz;
bdi->can_write_zeroes_with_unmap = iscsilun->lbprz && iscsilun->lbp.lbpws;
bdi->cluster_size = iscsilun->cluster_sectors * BDRV_SECTOR_SIZE;
return 0;

View File

@@ -125,11 +125,9 @@ static void mirror_write_complete(void *opaque, int ret)
MirrorOp *op = opaque;
MirrorBlockJob *s = op->s;
if (ret < 0) {
BlockDriverState *source = s->common.bs;
BlockErrorAction action;
bdrv_set_dirty_bitmap(source, s->dirty_bitmap, op->sector_num,
op->nb_sectors);
bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
action = mirror_error_action(s, false, -ret);
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
s->ret = ret;
@@ -143,11 +141,9 @@ static void mirror_read_complete(void *opaque, int ret)
MirrorOp *op = opaque;
MirrorBlockJob *s = op->s;
if (ret < 0) {
BlockDriverState *source = s->common.bs;
BlockErrorAction action;
bdrv_set_dirty_bitmap(source, s->dirty_bitmap, op->sector_num,
op->nb_sectors);
bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
action = mirror_error_action(s, true, -ret);
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
s->ret = ret;
@@ -170,10 +166,9 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
s->sector_num = hbitmap_iter_next(&s->hbi);
if (s->sector_num < 0) {
bdrv_dirty_iter_init(source, s->dirty_bitmap, &s->hbi);
bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
s->sector_num = hbitmap_iter_next(&s->hbi);
trace_mirror_restart_iter(s,
bdrv_get_dirty_count(source, s->dirty_bitmap));
trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap));
assert(s->sector_num >= 0);
}
@@ -288,8 +283,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
next_sector += sectors_per_chunk;
}
bdrv_reset_dirty_bitmap(source, s->dirty_bitmap, sector_num,
nb_sectors);
bdrv_reset_dirty_bitmap(s->dirty_bitmap, sector_num, nb_sectors);
/* Copy the dirty cluster. */
s->in_flight++;
@@ -446,7 +440,7 @@ static void coroutine_fn mirror_run(void *opaque)
assert(n > 0);
if (ret == 1) {
bdrv_set_dirty_bitmap(bs, s->dirty_bitmap, sector_num, n);
bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
sector_num = next;
} else {
sector_num += n;
@@ -454,7 +448,7 @@ static void coroutine_fn mirror_run(void *opaque)
}
}
bdrv_dirty_iter_init(bs, s->dirty_bitmap, &s->hbi);
bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
for (;;) {
uint64_t delay_ns = 0;
@@ -466,7 +460,7 @@ static void coroutine_fn mirror_run(void *opaque)
goto immediate_exit;
}
cnt = bdrv_get_dirty_count(bs, s->dirty_bitmap);
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
/* s->common.offset contains the number of bytes already processed so
* far, cnt is the number of dirty sectors remaining and
* s->sectors_in_flight is the number of sectors currently being
@@ -475,7 +469,7 @@ static void coroutine_fn mirror_run(void *opaque)
(cnt + s->sectors_in_flight) * BDRV_SECTOR_SIZE;
/* Note that even when no rate limit is applied we need to yield
* periodically with no pending I/O so that qemu_aio_flush() returns.
* periodically with no pending I/O so that bdrv_drain_all() returns.
* We do so every SLICE_TIME nanoseconds, or when there is an error,
* or when the source is clean, whichever comes first.
*/
@@ -488,9 +482,6 @@ static void coroutine_fn mirror_run(void *opaque)
continue;
} else if (cnt != 0) {
delay_ns = mirror_iteration(s);
if (delay_ns == 0) {
continue;
}
}
}
@@ -516,7 +507,7 @@ static void coroutine_fn mirror_run(void *opaque)
should_complete = s->should_complete ||
block_job_is_cancelled(&s->common);
cnt = bdrv_get_dirty_count(bs, s->dirty_bitmap);
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
}
}
@@ -531,7 +522,7 @@ static void coroutine_fn mirror_run(void *opaque)
*/
trace_mirror_before_drain(s, cnt);
bdrv_drain(bs);
cnt = bdrv_get_dirty_count(bs, s->dirty_bitmap);
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
}
ret = 0;
@@ -634,7 +625,7 @@ static void mirror_complete(BlockJob *job, Error **errp)
}
s->should_complete = true;
block_job_resume(job);
block_job_enter(&s->common);
}
static const BlockJobDriver mirror_job_driver = {
@@ -656,7 +647,7 @@ static const BlockJobDriver commit_active_job_driver = {
static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
const char *replaces,
int64_t speed, int64_t granularity,
int64_t speed, uint32_t granularity,
int64_t buf_size,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
@@ -668,15 +659,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
MirrorBlockJob *s;
if (granularity == 0) {
/* Choose the default granularity based on the target file's cluster
* size, clamped between 4k and 64k. */
BlockDriverInfo bdi;
if (bdrv_get_info(target, &bdi) >= 0 && bdi.cluster_size != 0) {
granularity = MAX(4096, bdi.cluster_size);
granularity = MIN(65536, granularity);
} else {
granularity = 65536;
}
granularity = bdrv_get_default_bitmap_granularity(target);
}
assert ((granularity & (granularity - 1)) == 0);
@@ -703,7 +686,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
s->granularity = granularity;
s->buf_size = MAX(buf_size, granularity);
s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, errp);
s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
if (!s->dirty_bitmap) {
return;
}
@@ -717,7 +700,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
void mirror_start(BlockDriverState *bs, BlockDriverState *target,
const char *replaces,
int64_t speed, int64_t granularity, int64_t buf_size,
int64_t speed, uint32_t granularity, int64_t buf_size,
MirrorSyncMode mode, BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
BlockCompletionFunc *cb,
@@ -726,6 +709,10 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
bool is_none_mode;
BlockDriverState *base;
if (mode == MIRROR_SYNC_MODE_DIRTY_BITMAP) {
error_setg(errp, "Sync mode 'dirty-bitmap' not supported");
return;
}
is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
base = mode == MIRROR_SYNC_MODE_TOP ? bs->backing_hd : NULL;
mirror_start_job(bs, target, replaces,

View File

@@ -12,8 +12,11 @@
#include "block/block_int.h"
#define NULL_OPT_LATENCY "latency-ns"
typedef struct {
int64_t length;
int64_t latency_ns;
} BDRVNullState;
static QemuOptsList runtime_opts = {
@@ -30,6 +33,12 @@ static QemuOptsList runtime_opts = {
.type = QEMU_OPT_SIZE,
.help = "size of the null block",
},
{
.name = NULL_OPT_LATENCY,
.type = QEMU_OPT_NUMBER,
.help = "nanoseconds (approximated) to wait "
"before completing request",
},
{ /* end of list */ }
},
};
@@ -39,13 +48,20 @@ static int null_file_open(BlockDriverState *bs, QDict *options, int flags,
{
QemuOpts *opts;
BDRVNullState *s = bs->opaque;
int ret = 0;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &error_abort);
s->length =
qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 1 << 30);
s->latency_ns =
qemu_opt_get_number(opts, NULL_OPT_LATENCY, 0);
if (s->latency_ns < 0) {
error_setg(errp, "latency-ns is invalid");
ret = -EINVAL;
}
qemu_opts_del(opts);
return 0;
return ret;
}
static void null_close(BlockDriverState *bs)
@@ -58,28 +74,40 @@ static int64_t null_getlength(BlockDriverState *bs)
return s->length;
}
static coroutine_fn int null_co_common(BlockDriverState *bs)
{
BDRVNullState *s = bs->opaque;
if (s->latency_ns) {
co_aio_sleep_ns(bdrv_get_aio_context(bs), QEMU_CLOCK_REALTIME,
s->latency_ns);
}
return 0;
}
static coroutine_fn int null_co_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{
return 0;
return null_co_common(bs);
}
static coroutine_fn int null_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{
return 0;
return null_co_common(bs);
}
static coroutine_fn int null_co_flush(BlockDriverState *bs)
{
return 0;
return null_co_common(bs);
}
typedef struct {
BlockAIOCB common;
QEMUBH *bh;
QEMUTimer timer;
} NullAIOCB;
static const AIOCBInfo null_aiocb_info = {
@@ -94,15 +122,33 @@ static void null_bh_cb(void *opaque)
qemu_aio_unref(acb);
}
static void null_timer_cb(void *opaque)
{
NullAIOCB *acb = opaque;
acb->common.cb(acb->common.opaque, 0);
timer_deinit(&acb->timer);
qemu_aio_unref(acb);
}
static inline BlockAIOCB *null_aio_common(BlockDriverState *bs,
BlockCompletionFunc *cb,
void *opaque)
{
NullAIOCB *acb;
BDRVNullState *s = bs->opaque;
acb = qemu_aio_get(&null_aiocb_info, bs, cb, opaque);
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), null_bh_cb, acb);
qemu_bh_schedule(acb->bh);
/* Only emulate latency after vcpu is running. */
if (s->latency_ns) {
aio_timer_init(bdrv_get_aio_context(bs), &acb->timer,
QEMU_CLOCK_REALTIME, SCALE_NS,
null_timer_cb, acb);
timer_mod_ns(&acb->timer,
qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + s->latency_ns);
} else {
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), null_bh_cb, acb);
qemu_bh_schedule(acb->bh);
}
return &acb->common;
}
@@ -131,6 +177,12 @@ static BlockAIOCB *null_aio_flush(BlockDriverState *bs,
return null_aio_common(bs, cb, opaque);
}
static int null_reopen_prepare(BDRVReopenState *reopen_state,
BlockReopenQueue *queue, Error **errp)
{
return 0;
}
static BlockDriver bdrv_null_co = {
.format_name = "null-co",
.protocol_name = "null-co",
@@ -143,6 +195,7 @@ static BlockDriver bdrv_null_co = {
.bdrv_co_readv = null_co_readv,
.bdrv_co_writev = null_co_writev,
.bdrv_co_flush_to_disk = null_co_flush,
.bdrv_reopen_prepare = null_reopen_prepare,
};
static BlockDriver bdrv_null_aio = {
@@ -157,6 +210,7 @@ static BlockDriver bdrv_null_aio = {
.bdrv_aio_readv = null_aio_readv,
.bdrv_aio_writev = null_aio_writev,
.bdrv_aio_flush = null_aio_flush,
.bdrv_reopen_prepare = null_reopen_prepare,
};
static void bdrv_null_init(void)

View File

@@ -31,8 +31,10 @@
#include "qapi/qmp/types.h"
#include "sysemu/block-backend.h"
BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs, Error **errp)
{
ImageInfo **p_image_info;
BlockDriverState *bs0;
BlockDeviceInfo *info = g_malloc0(sizeof(*info));
info->file = g_strdup(bs->filename);
@@ -92,6 +94,25 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
info->write_threshold = bdrv_write_threshold_get(bs);
bs0 = bs;
p_image_info = &info->image;
while (1) {
Error *local_err = NULL;
bdrv_query_image_info(bs0, p_image_info, &local_err);
if (local_err) {
error_propagate(errp, local_err);
qapi_free_BlockDeviceInfo(info);
return NULL;
}
if (bs0->drv && bs0->backing_hd) {
bs0 = bs0->backing_hd;
(*p_image_info)->has_backing_image = true;
p_image_info = &((*p_image_info)->backing_image);
} else {
break;
}
}
return info;
}
@@ -264,9 +285,6 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
{
BlockInfo *info = g_malloc0(sizeof(*info));
BlockDriverState *bs = blk_bs(blk);
BlockDriverState *bs0;
ImageInfo **p_image_info;
Error *local_err = NULL;
info->device = g_strdup(blk_name(blk));
info->type = g_strdup("unknown");
info->locked = blk_dev_is_medium_locked(blk);
@@ -289,23 +307,9 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
if (bs->drv) {
info->has_inserted = true;
info->inserted = bdrv_block_device_info(bs);
bs0 = bs;
p_image_info = &info->inserted->image;
while (1) {
bdrv_query_image_info(bs0, p_image_info, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto err;
}
if (bs0->drv && bs0->backing_hd) {
bs0 = bs0->backing_hd;
(*p_image_info)->has_backing_image = true;
p_image_info = &((*p_image_info)->backing_image);
} else {
break;
}
info->inserted = bdrv_block_device_info(bs, errp);
if (info->inserted == NULL) {
goto err;
}
}

View File

@@ -124,7 +124,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
snprintf(version, sizeof(version), "QCOW version %" PRIu32,
header.version);
error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bdrv_get_device_name(bs), "qcow", version);
bdrv_get_device_or_node_name(bs), "qcow", version);
ret = -ENOTSUP;
goto fail;
}
@@ -229,9 +229,9 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Disable migration when qcow images are used */
error_set(&s->migration_blocker,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"qcow", bdrv_get_device_name(bs), "live migration");
error_setg(&s->migration_blocker, "The qcow format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
migrate_add_blocker(s->migration_blocker);
qemu_co_mutex_init(&s->lock);

View File

@@ -2450,7 +2450,7 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
if (ret < 0) {
return ret;
} else if (ret > 0) {
int metadata_ol_bitnr = ffs(ret) - 1;
int metadata_ol_bitnr = ctz32(ret);
assert(metadata_ol_bitnr < QCOW2_OL_MAX_BITNR);
qcow2_signal_corruption(bs, true, offset, size, "Preventing invalid "

View File

@@ -351,10 +351,8 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
memset(sn, 0, sizeof(*sn));
/* Generate an ID if it wasn't passed */
if (sn_info->id_str[0] == '\0') {
find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));
}
/* Generate an ID */
find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));
/* Check that the ID is unique */
if (find_snapshot_by_id_and_name(bs, sn_info->id_str, NULL) >= 0) {

View File

@@ -208,7 +208,7 @@ static void GCC_FMT_ATTR(3, 4) report_unsupported(BlockDriverState *bs,
va_end(ap);
error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bdrv_get_device_name(bs), "qcow2", msg);
bdrv_get_device_or_node_name(bs), "qcow2", msg);
}
static void report_unsupported_feature(BlockDriverState *bs,
@@ -1802,7 +1802,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
{
/* Calculate cluster_bits */
int cluster_bits;
cluster_bits = ffs(cluster_size) - 1;
cluster_bits = ctz32(cluster_size);
if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
(1 << cluster_bits) != cluster_size)
{
@@ -2110,7 +2110,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
goto finish;
}
refcount_order = ffs(refcount_bits) - 1;
refcount_order = ctz32(refcount_bits);
ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
cluster_size, prealloc, opts, version, refcount_order,
@@ -2824,6 +2824,7 @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
int64_t size, const char *message_format, ...)
{
BDRVQcowState *s = bs->opaque;
const char *node_name;
char *message;
va_list ap;
@@ -2847,8 +2848,11 @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
"corruption events will be suppressed\n", message);
}
qapi_event_send_block_image_corrupted(bdrv_get_device_name(bs), message,
offset >= 0, offset, size >= 0, size,
node_name = bdrv_get_node_name(bs);
qapi_event_send_block_image_corrupted(bdrv_get_device_name(bs),
*node_name != '\0', node_name,
message, offset >= 0, offset,
size >= 0, size,
fatal, &error_abort);
g_free(message);

View File

@@ -408,7 +408,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
snprintf(buf, sizeof(buf), "%" PRIx64,
s->header.features & ~QED_FEATURE_MASK);
error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bdrv_get_device_name(bs), "QED", buf);
bdrv_get_device_or_node_name(bs), "QED", buf);
return -ENOTSUP;
}
if (!qed_is_cluster_size_valid(s->header.cluster_size)) {
@@ -436,9 +436,9 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
s->table_nelems = (s->header.cluster_size * s->header.table_size) /
sizeof(uint64_t);
s->l2_shift = ffs(s->header.cluster_size) - 1;
s->l2_shift = ctz32(s->header.cluster_size);
s->l2_mask = s->table_nelems - 1;
s->l1_shift = s->l2_shift + ffs(s->table_nelems) - 1;
s->l1_shift = s->l2_shift + ctz32(s->table_nelems);
/* Header size calculation must not overflow uint32_t */
if (s->header.header_size > UINT32_MAX / s->header.cluster_size) {

View File

@@ -226,10 +226,7 @@ static void quorum_report_bad(QuorumAIOCB *acb, char *node_name, int ret)
static void quorum_report_failure(QuorumAIOCB *acb)
{
const char *reference = bdrv_get_device_name(acb->common.bs)[0] ?
bdrv_get_device_name(acb->common.bs) :
acb->common.bs->node_name;
const char *reference = bdrv_get_device_or_node_name(acb->common.bs);
qapi_event_send_quorum_failure(reference, acb->sector_num,
acb->nb_sectors, &error_abort);
}

View File

@@ -325,7 +325,7 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
error_setg(errp, "obj size too small");
return -EINVAL;
}
obj_order = ffs(objsize) - 1;
obj_order = ctz32(objsize);
}
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);

View File

@@ -1716,7 +1716,7 @@ static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt)
if ((object_size - 1) & object_size) { /* not a power of 2? */
return -EINVAL;
}
obj_order = ffs(object_size) - 1;
obj_order = ctz32(object_size);
if (obj_order < 20 || obj_order > 31) {
return -EINVAL;
}

View File

@@ -246,9 +246,9 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
if (bs->file) {
return bdrv_snapshot_delete(bs->file, snapshot_id, name, errp);
}
error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
drv->format_name, bdrv_get_device_name(bs),
"internal snapshot deletion");
error_setg(errp, "Block format '%s' used by device '%s' "
"does not support internal snapshot deletion",
drv->format_name, bdrv_get_device_name(bs));
return -ENOTSUP;
}
@@ -329,9 +329,9 @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs,
if (drv->bdrv_snapshot_load_tmp) {
return drv->bdrv_snapshot_load_tmp(bs, snapshot_id, name, errp);
}
error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
drv->format_name, bdrv_get_device_name(bs),
"temporarily load internal snapshot");
error_setg(errp, "Block format '%s' used by device '%s' "
"does not support temporarily loading internal snapshots",
drv->format_name, bdrv_get_device_name(bs));
return -ENOTSUP;
}

View File

@@ -502,9 +502,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Disable migration when vdi images are used */
error_set(&s->migration_blocker,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vdi", bdrv_get_device_name(bs), "live migration");
error_setg(&s->migration_blocker, "The vdi format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
migrate_add_blocker(s->migration_blocker);
qemu_co_mutex_init(&s->write_lock);

View File

@@ -1002,9 +1002,9 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
/* TODO: differencing files */
/* Disable migration when VHDX images are used */
error_set(&s->migration_blocker,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vhdx", bdrv_get_device_name(bs), "live migration");
error_setg(&s->migration_blocker, "The vhdx format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
migrate_add_blocker(s->migration_blocker);
return 0;
@@ -1269,7 +1269,7 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
iov1.iov_base = qemu_blockalign(bs, iov1.iov_len);
memset(iov1.iov_base, 0, iov1.iov_len);
qemu_iovec_concat_iov(&hd_qiov, &iov1, 1, 0,
sinfo.block_offset);
iov1.iov_len);
sectors_to_write += iov1.iov_len >> BDRV_SECTOR_BITS;
}
@@ -1285,7 +1285,7 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
iov2.iov_base = qemu_blockalign(bs, iov2.iov_len);
memset(iov2.iov_base, 0, iov2.iov_len);
qemu_iovec_concat_iov(&hd_qiov, &iov2, 1, 0,
sinfo.block_offset);
iov2.iov_len);
sectors_to_write += iov2.iov_len >> BDRV_SECTOR_BITS;
}
}

View File

@@ -523,7 +523,7 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
}
ret = vmdk_add_extent(bs, file, false,
le32_to_cpu(header.disk_sectors),
le32_to_cpu(header.l1dir_offset) << 9,
(int64_t)le32_to_cpu(header.l1dir_offset) << 9,
0,
le32_to_cpu(header.l1dir_size),
4096,
@@ -669,7 +669,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
le32_to_cpu(header.version));
error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bdrv_get_device_name(bs), "vmdk", buf);
bdrv_get_device_or_node_name(bs), "vmdk", buf);
return -ENOTSUP;
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
/* VMware KB 2064959 explains that version 3 added support for
@@ -962,9 +962,9 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
qemu_co_mutex_init(&s->lock);
/* Disable migration when VMDK images are used */
error_set(&s->migration_blocker,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vmdk", bdrv_get_device_name(bs), "live migration");
error_setg(&s->migration_blocker, "The vmdk format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
migrate_add_blocker(s->migration_blocker);
g_free(buf);
return 0;

View File

@@ -318,9 +318,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
qemu_co_mutex_init(&s->lock);
/* Disable migration when VHD images are used */
error_set(&s->migration_blocker,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vpc", bdrv_get_device_name(bs), "live migration");
error_setg(&s->migration_blocker, "The vpc format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
migrate_add_blocker(s->migration_blocker);
return 0;

View File

@@ -1180,9 +1180,10 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
/* Disable migration when vvfat is used rw */
if (s->qcow) {
error_set(&s->migration_blocker,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vvfat (rw)", bdrv_get_device_name(bs), "live migration");
error_setg(&s->migration_blocker,
"The vvfat (rw) format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
migrate_add_blocker(s->migration_blocker);
}

View File

@@ -1164,6 +1164,68 @@ out_aio_context:
return NULL;
}
/**
* block_dirty_bitmap_lookup:
* Return a dirty bitmap (if present), after validating
* the node reference and bitmap names.
*
* @node: The name of the BDS node to search for bitmaps
* @name: The name of the bitmap to search for
* @pbs: Output pointer for BDS lookup, if desired. Can be NULL.
* @paio: Output pointer for aio_context acquisition, if desired. Can be NULL.
* @errp: Output pointer for error information. Can be NULL.
*
* @return: A bitmap object on success, or NULL on failure.
*/
static BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
const char *name,
BlockDriverState **pbs,
AioContext **paio,
Error **errp)
{
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
AioContext *aio_context;
if (!node) {
error_setg(errp, "Node cannot be NULL");
return NULL;
}
if (!name) {
error_setg(errp, "Bitmap name cannot be NULL");
return NULL;
}
bs = bdrv_lookup_bs(node, node, NULL);
if (!bs) {
error_setg(errp, "Node '%s' not found", node);
return NULL;
}
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
bitmap = bdrv_find_dirty_bitmap(bs, name);
if (!bitmap) {
error_setg(errp, "Dirty bitmap '%s' not found", name);
goto fail;
}
if (pbs) {
*pbs = bs;
}
if (paio) {
*paio = aio_context;
} else {
aio_context_release(aio_context);
}
return bitmap;
fail:
aio_context_release(aio_context);
return NULL;
}
/* New and old BlockDriverState structs for atomic group operations */
typedef struct BlkTransactionState BlkTransactionState;
@@ -1248,13 +1310,14 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
}
if (bdrv_is_read_only(bs)) {
error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
error_setg(errp, "Device '%s' is read only", device);
return;
}
if (!bdrv_can_snapshot(bs)) {
error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
bs->drv->format_name, device, "internal snapshot");
error_setg(errp, "Block format '%s' used by device '%s' "
"does not support internal snapshots",
bs->drv->format_name, device);
return;
}
@@ -1522,6 +1585,7 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
backup->sync,
backup->has_mode, backup->mode,
backup->has_speed, backup->speed,
backup->has_bitmap, backup->bitmap,
backup->has_on_source_error, backup->on_source_error,
backup->has_on_target_error, backup->on_target_error,
&local_err);
@@ -1953,6 +2017,102 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
aio_context_release(aio_context);
}
void qmp_block_dirty_bitmap_add(const char *node, const char *name,
bool has_granularity, uint32_t granularity,
Error **errp)
{
AioContext *aio_context;
BlockDriverState *bs;
if (!name || name[0] == '\0') {
error_setg(errp, "Bitmap name cannot be empty");
return;
}
bs = bdrv_lookup_bs(node, node, errp);
if (!bs) {
return;
}
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (has_granularity) {
if (granularity < 512 || !is_power_of_2(granularity)) {
error_setg(errp, "Granularity must be power of 2 "
"and at least 512");
goto out;
}
} else {
/* Default to cluster size, if available: */
granularity = bdrv_get_default_bitmap_granularity(bs);
}
bdrv_create_dirty_bitmap(bs, granularity, name, errp);
out:
aio_context_release(aio_context);
}
void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
Error **errp)
{
AioContext *aio_context;
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
if (!bitmap || !bs) {
return;
}
if (bdrv_dirty_bitmap_frozen(bitmap)) {
error_setg(errp,
"Bitmap '%s' is currently frozen and cannot be removed",
name);
goto out;
}
bdrv_dirty_bitmap_make_anon(bitmap);
bdrv_release_dirty_bitmap(bs, bitmap);
out:
aio_context_release(aio_context);
}
/**
* Completely clear a bitmap, for the purposes of synchronizing a bitmap
* immediately after a full backup operation.
*/
void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
Error **errp)
{
AioContext *aio_context;
BdrvDirtyBitmap *bitmap;
BlockDriverState *bs;
bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
if (!bitmap || !bs) {
return;
}
if (bdrv_dirty_bitmap_frozen(bitmap)) {
error_setg(errp,
"Bitmap '%s' is currently frozen and cannot be modified",
name);
goto out;
} else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
error_setg(errp,
"Bitmap '%s' is currently disabled and cannot be cleared",
name);
goto out;
}
bdrv_clear_dirty_bitmap(bitmap);
out:
aio_context_release(aio_context);
}
int hmp_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *id = qdict_get_str(qdict, "id");
@@ -2055,7 +2215,7 @@ void qmp_block_resize(bool has_device, const char *device,
error_set(errp, QERR_UNSUPPORTED);
break;
case -EACCES:
error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
error_setg(errp, "Device '%s' is read only", device);
break;
case -EBUSY:
error_set(errp, QERR_DEVICE_IN_USE, device);
@@ -2270,6 +2430,7 @@ void qmp_drive_backup(const char *device, const char *target,
enum MirrorSyncMode sync,
bool has_mode, enum NewImageMode mode,
bool has_speed, int64_t speed,
bool has_bitmap, const char *bitmap,
bool has_on_source_error, BlockdevOnError on_source_error,
bool has_on_target_error, BlockdevOnError on_target_error,
Error **errp)
@@ -2278,6 +2439,7 @@ void qmp_drive_backup(const char *device, const char *target,
BlockDriverState *bs;
BlockDriverState *target_bs;
BlockDriverState *source = NULL;
BdrvDirtyBitmap *bmap = NULL;
AioContext *aio_context;
BlockDriver *drv = NULL;
Error *local_err = NULL;
@@ -2377,7 +2539,16 @@ void qmp_drive_backup(const char *device, const char *target,
bdrv_set_aio_context(target_bs, aio_context);
backup_start(bs, target_bs, speed, sync, on_source_error, on_target_error,
if (has_bitmap) {
bmap = bdrv_find_dirty_bitmap(bs, bitmap);
if (!bmap) {
error_setg(errp, "Bitmap '%s' could not be found", bitmap);
goto out;
}
}
backup_start(bs, target_bs, speed, sync, bmap,
on_source_error, on_target_error,
block_job_cb, bs, &local_err);
if (local_err != NULL) {
bdrv_unref(target_bs);
@@ -2391,7 +2562,7 @@ out:
BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
{
return bdrv_named_nodes_list();
return bdrv_named_nodes_list(errp);
}
void qmp_blockdev_backup(const char *device, const char *target,
@@ -2438,8 +2609,8 @@ void qmp_blockdev_backup(const char *device, const char *target,
bdrv_ref(target_bs);
bdrv_set_aio_context(target_bs, aio_context);
backup_start(bs, target_bs, speed, sync, on_source_error, on_target_error,
block_job_cb, bs, &local_err);
backup_start(bs, target_bs, speed, sync, NULL, on_source_error,
on_target_error, block_job_cb, bs, &local_err);
if (local_err != NULL) {
bdrv_unref(target_bs);
error_propagate(errp, local_err);
@@ -2699,7 +2870,7 @@ void qmp_block_job_cancel(const char *device,
force = false;
}
if (job->paused && !force) {
if (job->user_paused && !force) {
error_setg(errp, "The block job for device '%s' is currently paused",
device);
goto out;
@@ -2716,10 +2887,11 @@ void qmp_block_job_pause(const char *device, Error **errp)
AioContext *aio_context;
BlockJob *job = find_block_job(device, &aio_context, errp);
if (!job) {
if (!job || job->user_paused) {
return;
}
job->user_paused = true;
trace_qmp_block_job_pause(job);
block_job_pause(job);
aio_context_release(aio_context);
@@ -2730,10 +2902,11 @@ void qmp_block_job_resume(const char *device, Error **errp)
AioContext *aio_context;
BlockJob *job = find_block_job(device, &aio_context, errp);
if (!job) {
if (!job || !job->user_paused) {
return;
}
job->user_paused = false;
trace_qmp_block_job_resume(job);
block_job_resume(job);
aio_context_release(aio_context);

View File

@@ -107,7 +107,7 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
void block_job_complete(BlockJob *job, Error **errp)
{
if (job->paused || job->cancelled || !job->driver->complete) {
if (job->pause_count || job->cancelled || !job->driver->complete) {
error_set(errp, QERR_BLOCK_JOB_NOT_READY,
bdrv_get_device_name(job->bs));
return;
@@ -118,17 +118,26 @@ void block_job_complete(BlockJob *job, Error **errp)
void block_job_pause(BlockJob *job)
{
job->paused = true;
job->pause_count++;
}
bool block_job_is_paused(BlockJob *job)
{
return job->paused;
return job->pause_count > 0;
}
void block_job_resume(BlockJob *job)
{
job->paused = false;
assert(job->pause_count > 0);
job->pause_count--;
if (job->pause_count) {
return;
}
block_job_enter(job);
}
void block_job_enter(BlockJob *job)
{
block_job_iostatus_reset(job);
if (job->co && !job->busy) {
qemu_coroutine_enter(job->co, NULL);
@@ -138,7 +147,7 @@ void block_job_resume(BlockJob *job)
void block_job_cancel(BlockJob *job)
{
job->cancelled = true;
block_job_resume(job);
block_job_enter(job);
}
bool block_job_is_cancelled(BlockJob *job)
@@ -258,7 +267,7 @@ BlockJobInfo *block_job_query(BlockJob *job)
info->device = g_strdup(bdrv_get_device_name(job->bs));
info->len = job->len;
info->busy = job->busy;
info->paused = job->paused;
info->paused = job->pause_count > 0;
info->offset = job->offset;
info->speed = job->speed;
info->io_status = job->iostatus;
@@ -335,6 +344,8 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
IO_OPERATION_TYPE_WRITE,
action, &error_abort);
if (action == BLOCK_ERROR_ACTION_STOP) {
/* make the pause user visible, which will be resumed from QMP. */
job->user_paused = true;
block_job_pause(job);
block_job_iostatus_set_err(job, error);
if (bs != job->bs) {

View File

@@ -905,7 +905,6 @@ int main(int argc, char **argv)
#endif
}
tcg_exec_init(0);
cpu_exec_init_all();
/* NOTE: we need to init the CPU at this stage to get
qemu_host_page_size */
cpu = cpu_init(cpu_model);

30
configure vendored
View File

@@ -336,6 +336,7 @@ libssh2=""
vhdx=""
quorum=""
numa=""
tcmalloc="no"
# parse CC options first
for opt do
@@ -1134,6 +1135,10 @@ for opt do
;;
--enable-numa) numa="yes"
;;
--disable-tcmalloc) tcmalloc="no"
;;
--enable-tcmalloc) tcmalloc="yes"
;;
*)
echo "ERROR: unknown option $opt"
echo "Try '$0 --help' for more information"
@@ -1407,6 +1412,8 @@ Advanced options (experts only):
--enable-quorum enable quorum block filter support
--disable-numa disable libnuma support
--enable-numa enable libnuma support
--disable-tcmalloc disable tcmalloc support
--enable-tcmalloc enable tcmalloc support
NOTE: The object files are built at the place where configure is launched
EOF
@@ -3135,7 +3142,7 @@ else
fi
if test "$opengl" != "no" ; then
opengl_pkgs="gl"
opengl_pkgs="gl glesv2"
if $pkg_config $opengl_pkgs x11 && test "$have_glx" = "yes"; then
opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
@@ -3330,6 +3337,22 @@ EOF
fi
fi
##########################################
# tcmalloc probe
if test "$tcmalloc" = "yes" ; then
cat > $TMPC << EOF
#include <stdlib.h>
int main(void) { malloc(1); return 0; }
EOF
if compile_prog "" "-ltcmalloc" ; then
LIBS="-ltcmalloc $LIBS"
else
feature_not_found "tcmalloc" "install gperftools devel"
fi
fi
##########################################
# signalfd probe
signalfd="no"
@@ -4441,6 +4464,7 @@ echo "lzo support $lzo"
echo "snappy support $snappy"
echo "bzip2 support $bzip2"
echo "NUMA host support $numa"
echo "tcmalloc support $tcmalloc"
if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5169,8 +5193,6 @@ case "$target_name" in
TARGET_BASE_ARCH=mips
echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
;;
tricore)
;;
moxie)
;;
or32)
@@ -5221,6 +5243,8 @@ case "$target_name" in
s390x)
gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml"
;;
tricore)
;;
unicore32)
;;
xtensa|xtensaeb)

2
cpus.c
View File

@@ -1016,7 +1016,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
qemu_cond_signal(&qemu_cpu_cond);
/* wait for initial kick-off after machine start */
while (QTAILQ_FIRST(&cpus)->stopped) {
while (first_cpu->stopped) {
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
/* process any pending work */

View File

@@ -249,9 +249,9 @@ static void tlb_add_large_page(CPUArchState *env, target_ulong vaddr,
* Called from TCG-generated code, which is under an RCU read-side
* critical section.
*/
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
hwaddr paddr, int prot,
int mmu_idx, target_ulong size)
void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
hwaddr paddr, MemTxAttrs attrs, int prot,
int mmu_idx, target_ulong size)
{
CPUArchState *env = cpu->env_ptr;
MemoryRegionSection *section;
@@ -301,7 +301,8 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
env->iotlb_v[mmu_idx][vidx] = env->iotlb[mmu_idx][index];
/* refill the tlb */
env->iotlb[mmu_idx][index] = iotlb - vaddr;
env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
env->iotlb[mmu_idx][index].attrs = attrs;
te->addend = addend - vaddr;
if (prot & PAGE_READ) {
te->addr_read = address;
@@ -331,6 +332,17 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
}
}
/* Add a new TLB entry, but without specifying the memory
* transaction attributes to be used.
*/
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
hwaddr paddr, int prot,
int mmu_idx, target_ulong size)
{
tlb_set_page_with_attrs(cpu, vaddr, paddr, MEMTXATTRS_UNSPECIFIED,
prot, mmu_idx, size);
}
/* NOTE: this function can trigger an exception */
/* NOTE2: the returned address is not exactly the physical address: it
* is actually a ram_addr_t (in system mode; the user mode emulation
@@ -349,7 +361,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
(addr & TARGET_PAGE_MASK))) {
cpu_ldub_code(env1, addr);
}
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
pd = env1->iotlb[mmu_idx][page_index].addr & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu, pd);
if (memory_region_is_unassigned(mr)) {
CPUClass *cc = CPU_GET_CLASS(cpu);

View File

@@ -1,11 +1,3 @@
# Default configuration for microblazeel-softmmu
CONFIG_PTIMER=y
CONFIG_PFLASH_CFI01=y
CONFIG_SERIAL=y
CONFIG_XILINX=y
CONFIG_XILINX_AXI=y
CONFIG_XILINX_SPI=y
CONFIG_XILINX_ETHLITE=y
CONFIG_SSI=y
CONFIG_SSI_M25P80=y
include microblaze-softmmu.mak

View File

@@ -10,7 +10,6 @@
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"
#include "trace.h"
#include "qemu/range.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
@@ -28,7 +27,8 @@ int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len)
memset(fillbuf, c, FILLBUF_SIZE);
while (len > 0) {
l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE;
error |= address_space_rw(as, addr, fillbuf, l, true);
error |= address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED,
fillbuf, l, true);
len -= l;
addr += l;
}
@@ -92,14 +92,6 @@ static void reschedule_dma(void *opaque)
dma_blk_cb(dbs, 0);
}
static void continue_after_map_failure(void *opaque)
{
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
dbs->bh = qemu_bh_new(reschedule_dma, dbs);
qemu_bh_schedule(dbs->bh);
}
static void dma_blk_unmap(DMAAIOCB *dbs)
{
int i;
@@ -161,7 +153,9 @@ static void dma_blk_cb(void *opaque, int ret)
if (dbs->iov.size == 0) {
trace_dma_map_wait(dbs);
cpu_register_map_client(dbs, continue_after_map_failure);
dbs->bh = aio_bh_new(blk_get_aio_context(dbs->blk),
reschedule_dma, dbs);
cpu_register_map_client(dbs->bh);
return;
}
@@ -183,6 +177,11 @@ static void dma_aio_cancel(BlockAIOCB *acb)
if (dbs->acb) {
blk_aio_cancel_async(dbs->acb);
}
if (dbs->bh) {
cpu_unregister_map_client(dbs->bh);
qemu_bh_delete(dbs->bh);
dbs->bh = NULL;
}
}

View File

@@ -281,7 +281,7 @@ note that the other barrier may actually be in a driver that runs in
the guest!
For the purposes of pairing, smp_read_barrier_depends() and smp_rmb()
both count as read barriers. A read barriers shall pair with a write
both count as read barriers. A read barrier shall pair with a write
barrier or a full barrier; a write barrier shall pair with a read
barrier or a full barrier. A full barrier can pair with anything.
For example:
@@ -294,7 +294,7 @@ For example:
smp_rmb();
y = a;
Note that the "writing" thread are accessing the variables in the
Note that the "writing" thread is accessing the variables in the
opposite order as the "reading" thread. This is expected: stores
before the write barrier will normally match the loads after the
read barrier, and vice versa. The same is true for more than 2

352
docs/bitmaps.md Normal file
View File

@@ -0,0 +1,352 @@
<!--
Copyright 2015 John Snow <jsnow@redhat.com> and Red Hat, Inc.
All rights reserved.
This file is licensed via The FreeBSD Documentation License, the full text of
which is included at the end of this document.
-->
# Dirty Bitmaps and Incremental Backup
* Dirty Bitmaps are objects that track which data needs to be backed up for the
next incremental backup.
* Dirty bitmaps can be created at any time and attached to any node
(not just complete drives.)
## Dirty Bitmap Names
* A dirty bitmap's name is unique to the node, but bitmaps attached to different
nodes can share the same name.
## Bitmap Modes
* A Bitmap can be "frozen," which means that it is currently in-use by a backup
operation and cannot be deleted, renamed, written to, reset,
etc.
## Basic QMP Usage
### Supported Commands ###
* block-dirty-bitmap-add
* block-dirty-bitmap-remove
* block-dirty-bitmap-clear
### Creation
* To create a new bitmap, enabled, on the drive with id=drive0:
```json
{ "execute": "block-dirty-bitmap-add",
"arguments": {
"node": "drive0",
"name": "bitmap0"
}
}
```
* This bitmap will have a default granularity that matches the cluster size of
its associated drive, if available, clamped to between [4KiB, 64KiB].
The current default for qcow2 is 64KiB.
* To create a new bitmap that tracks changes in 32KiB segments:
```json
{ "execute": "block-dirty-bitmap-add",
"arguments": {
"node": "drive0",
"name": "bitmap0",
"granularity": 32768
}
}
```
### Deletion
* Bitmaps that are frozen cannot be deleted.
* Deleting the bitmap does not impact any other bitmaps attached to the same
node, nor does it affect any backups already created from this node.
* Because bitmaps are only unique to the node to which they are attached,
you must specify the node/drive name here, too.
```json
{ "execute": "block-dirty-bitmap-remove",
"arguments": {
"node": "drive0",
"name": "bitmap0"
}
}
```
### Resetting
* Resetting a bitmap will clear all information it holds.
* An incremental backup created from an empty bitmap will copy no data,
as if nothing has changed.
```json
{ "execute": "block-dirty-bitmap-clear",
"arguments": {
"node": "drive0",
"name": "bitmap0"
}
}
```
## Transactions (Not yet implemented)
* Transactional commands are forthcoming in a future version,
and are not yet available for use. This section serves as
documentation of intent for their design and usage.
### Justification
Bitmaps can be safely modified when the VM is paused or halted by using
the basic QMP commands. For instance, you might perform the following actions:
1. Boot the VM in a paused state.
2. Create a full drive backup of drive0.
3. Create a new bitmap attached to drive0.
4. Resume execution of the VM.
5. Incremental backups are ready to be created.
At this point, the bitmap and drive backup would be correctly in sync,
and incremental backups made from this point forward would be correctly aligned
to the full drive backup.
This is not particularly useful if we decide we want to start incremental
backups after the VM has been running for a while, for which we will need to
perform actions such as the following:
1. Boot the VM and begin execution.
2. Using a single transaction, perform the following operations:
* Create bitmap0.
* Create a full drive backup of drive0.
3. Incremental backups are now ready to be created.
### Supported Bitmap Transactions
* block-dirty-bitmap-add
* block-dirty-bitmap-clear
The usages are identical to their respective QMP commands, but see below
for examples.
### Example: New Incremental Backup
As outlined in the justification, perhaps we want to create a new incremental
backup chain attached to a drive.
```json
{ "execute": "transaction",
"arguments": {
"actions": [
{"type": "block-dirty-bitmap-add",
"data": {"node": "drive0", "name": "bitmap0"} },
{"type": "drive-backup",
"data": {"device": "drive0", "target": "/path/to/full_backup.img",
"sync": "full", "format": "qcow2"} }
]
}
}
```
### Example: New Incremental Backup Anchor Point
Maybe we just want to create a new full backup with an existing bitmap and
want to reset the bitmap to track the new chain.
```json
{ "execute": "transaction",
"arguments": {
"actions": [
{"type": "block-dirty-bitmap-clear",
"data": {"node": "drive0", "name": "bitmap0"} },
{"type": "drive-backup",
"data": {"device": "drive0", "target": "/path/to/new_full_backup.img",
"sync": "full", "format": "qcow2"} }
]
}
}
```
## Incremental Backups
The star of the show.
**Nota Bene!** Only incremental backups of entire drives are supported for now.
So despite the fact that you can attach a bitmap to any arbitrary node, they are
only currently useful when attached to the root node. This is because
drive-backup only supports drives/devices instead of arbitrary nodes.
### Example: First Incremental Backup
1. Create a full backup and sync it to the dirty bitmap, as in the transactional
examples above; or with the VM offline, manually create a full copy and then
create a new bitmap before the VM begins execution.
* Let's assume the full backup is named 'full_backup.img'.
* Let's assume the bitmap you created is 'bitmap0' attached to 'drive0'.
2. Create a destination image for the incremental backup that utilizes the
full backup as a backing image.
* Let's assume it is named 'incremental.0.img'.
```sh
# qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F qcow2
```
3. Issue the incremental backup command:
```json
{ "execute": "drive-backup",
"arguments": {
"device": "drive0",
"bitmap": "bitmap0",
"target": "incremental.0.img",
"format": "qcow2",
"sync": "dirty-bitmap",
"mode": "existing"
}
}
```
### Example: Second Incremental Backup
1. Create a new destination image for the incremental backup that points to the
previous one, e.g.: 'incremental.1.img'
```sh
# qemu-img create -f qcow2 incremental.1.img -b incremental.0.img -F qcow2
```
2. Issue a new incremental backup command. The only difference here is that we
have changed the target image below.
```json
{ "execute": "drive-backup",
"arguments": {
"device": "drive0",
"bitmap": "bitmap0",
"target": "incremental.1.img",
"format": "qcow2",
"sync": "dirty-bitmap",
"mode": "existing"
}
}
```
## Errors
* In the event of an error that occurs after a backup job is successfully
launched, either by a direct QMP command or a QMP transaction, the user
will receive a BLOCK_JOB_COMPLETE event with a failure message, accompanied
by a BLOCK_JOB_ERROR event.
* In the case of an event being cancelled, the user will receive a
BLOCK_JOB_CANCELLED event instead of a pair of COMPLETE and ERROR events.
* In either case, the incremental backup data contained within the bitmap is
safely rolled back, and the data within the bitmap is not lost. The image
file created for the failed attempt can be safely deleted.
* Once the underlying problem is fixed (e.g. more storage space is freed up),
you can simply retry the incremental backup command with the same bitmap.
### Example
1. Create a target image:
```sh
# qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F qcow2
```
2. Attempt to create an incremental backup via QMP:
```json
{ "execute": "drive-backup",
"arguments": {
"device": "drive0",
"bitmap": "bitmap0",
"target": "incremental.0.img",
"format": "qcow2",
"sync": "dirty-bitmap",
"mode": "existing"
}
}
```
3. Receive an event notifying us of failure:
```json
{ "timestamp": { "seconds": 1424709442, "microseconds": 844524 },
"data": { "speed": 0, "offset": 0, "len": 67108864,
"error": "No space left on device",
"device": "drive1", "type": "backup" },
"event": "BLOCK_JOB_COMPLETED" }
```
4. Delete the failed incremental, and re-create the image.
```sh
# rm incremental.0.img
# qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F qcow2
```
5. Retry the command after fixing the underlying problem,
such as freeing up space on the backup volume:
```json
{ "execute": "drive-backup",
"arguments": {
"device": "drive0",
"bitmap": "bitmap0",
"target": "incremental.0.img",
"format": "qcow2",
"sync": "dirty-bitmap",
"mode": "existing"
}
}
```
6. Receive confirmation that the job completed successfully:
```json
{ "timestamp": { "seconds": 1424709668, "microseconds": 526525 },
"data": { "device": "drive1", "type": "backup",
"speed": 0, "len": 67108864, "offset": 67108864},
"event": "BLOCK_JOB_COMPLETED" }
```
<!--
The FreeBSD Documentation License
Redistribution and use in source (Markdown) and 'compiled' forms (SGML, HTML,
PDF, PostScript, RTF and so forth) with or without modification, are permitted
provided that the following conditions are met:
Redistributions of source code (Markdown) must retain the above copyright
notice, this list of conditions and the following disclaimer of this file
unmodified.
Redistributions in compiled form (transformed to other DTDs, converted to PDF,
PostScript, RTF and other formats) must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->

View File

@@ -31,21 +31,26 @@ Example:
BLOCK_IMAGE_CORRUPTED
---------------------
Emitted when a disk image is being marked corrupt.
Emitted when a disk image is being marked corrupt. The image can be
identified by its device or node name. The 'device' field is always
present for compatibility reasons, but it can be empty ("") if the
image does not have a device name associated.
Data:
- "device": Device name (json-string)
- "msg": Informative message (e.g., reason for the corruption) (json-string)
- "offset": If the corruption resulted from an image access, this is the access
offset into the image (json-int)
- "size": If the corruption resulted from an image access, this is the access
size (json-int)
- "device": Device name (json-string)
- "node-name": Node name (json-string, optional)
- "msg": Informative message (e.g., reason for the corruption)
(json-string)
- "offset": If the corruption resulted from an image access, this
is the access offset into the image (json-int)
- "size": If the corruption resulted from an image access, this
is the access size (json-int)
Example:
{ "event": "BLOCK_IMAGE_CORRUPTED",
"data": { "device": "ide0-hd0",
"data": { "device": "ide0-hd0", "node-name": "node0",
"msg": "Prevented active L1 table overwrite", "offset": 196608,
"size": 65536 },
"timestamp": { "seconds": 1378126126, "microseconds": 966463 } }

521
exec.c
View File

@@ -380,7 +380,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
IOMMUTLBEntry iotlb;
MemoryRegionSection *section;
MemoryRegion *mr;
hwaddr len = *plen;
rcu_read_lock();
for (;;) {
@@ -395,7 +394,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
iotlb = mr->iommu_ops->translate(mr, addr, is_write);
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
| (addr & iotlb.addr_mask));
len = MIN(len, (addr | iotlb.addr_mask) - addr + 1);
*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
if (!(iotlb.perm & (1 << is_write))) {
mr = &io_mem_unassigned;
break;
@@ -406,10 +405,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
len = MIN(page, len);
*plen = MIN(page, *plen);
}
*plen = len;
*xlat = addr;
rcu_read_unlock();
return mr;
@@ -429,15 +427,6 @@ address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr,
}
#endif
void cpu_exec_init_all(void)
{
#if !defined(CONFIG_USER_ONLY)
qemu_mutex_init(&ram_list.mutex);
memory_map_init();
io_mem_init();
#endif
}
#if !defined(CONFIG_USER_ONLY)
static int cpu_common_post_load(void *opaque, int version_id)
@@ -1858,7 +1847,7 @@ static const MemoryRegionOps notdirty_mem_ops = {
};
/* Generate a debug exception if a watchpoint has been hit. */
static void check_watchpoint(int offset, int len, int flags)
static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
{
CPUState *cpu = current_cpu;
CPUArchState *env = cpu->env_ptr;
@@ -1884,6 +1873,7 @@ static void check_watchpoint(int offset, int len, int flags)
wp->flags |= BP_WATCHPOINT_HIT_WRITE;
}
wp->hitaddr = vaddr;
wp->hitattrs = attrs;
if (!cpu->watchpoint_hit) {
cpu->watchpoint_hit = wp;
tb_check_watchpoint(cpu);
@@ -1905,69 +1895,93 @@ static void check_watchpoint(int offset, int len, int flags)
/* Watchpoint access routines. Watchpoints are inserted using TLB tricks,
so these check for a hit then pass through to the normal out-of-line
phys routines. */
static uint64_t watch_mem_read(void *opaque, hwaddr addr,
unsigned size)
static MemTxResult watch_mem_read(void *opaque, hwaddr addr, uint64_t *pdata,
unsigned size, MemTxAttrs attrs)
{
check_watchpoint(addr & ~TARGET_PAGE_MASK, size, BP_MEM_READ);
switch (size) {
case 1: return ldub_phys(&address_space_memory, addr);
case 2: return lduw_phys(&address_space_memory, addr);
case 4: return ldl_phys(&address_space_memory, addr);
default: abort();
}
}
MemTxResult res;
uint64_t data;
static void watch_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
check_watchpoint(addr & ~TARGET_PAGE_MASK, size, BP_MEM_WRITE);
check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_READ);
switch (size) {
case 1:
stb_phys(&address_space_memory, addr, val);
data = address_space_ldub(&address_space_memory, addr, attrs, &res);
break;
case 2:
stw_phys(&address_space_memory, addr, val);
data = address_space_lduw(&address_space_memory, addr, attrs, &res);
break;
case 4:
stl_phys(&address_space_memory, addr, val);
data = address_space_ldl(&address_space_memory, addr, attrs, &res);
break;
default: abort();
}
*pdata = data;
return res;
}
static MemTxResult watch_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size,
MemTxAttrs attrs)
{
MemTxResult res;
check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_WRITE);
switch (size) {
case 1:
address_space_stb(&address_space_memory, addr, val, attrs, &res);
break;
case 2:
address_space_stw(&address_space_memory, addr, val, attrs, &res);
break;
case 4:
address_space_stl(&address_space_memory, addr, val, attrs, &res);
break;
default: abort();
}
return res;
}
static const MemoryRegionOps watch_mem_ops = {
.read = watch_mem_read,
.write = watch_mem_write,
.read_with_attrs = watch_mem_read,
.write_with_attrs = watch_mem_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static uint64_t subpage_read(void *opaque, hwaddr addr,
unsigned len)
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
unsigned len, MemTxAttrs attrs)
{
subpage_t *subpage = opaque;
uint8_t buf[8];
MemTxResult res;
#if defined(DEBUG_SUBPAGE)
printf("%s: subpage %p len %u addr " TARGET_FMT_plx "\n", __func__,
subpage, len, addr);
#endif
address_space_read(subpage->as, addr + subpage->base, buf, len);
res = address_space_read(subpage->as, addr + subpage->base,
attrs, buf, len);
if (res) {
return res;
}
switch (len) {
case 1:
return ldub_p(buf);
*data = ldub_p(buf);
return MEMTX_OK;
case 2:
return lduw_p(buf);
*data = lduw_p(buf);
return MEMTX_OK;
case 4:
return ldl_p(buf);
*data = ldl_p(buf);
return MEMTX_OK;
case 8:
return ldq_p(buf);
*data = ldq_p(buf);
return MEMTX_OK;
default:
abort();
}
}
static void subpage_write(void *opaque, hwaddr addr,
uint64_t value, unsigned len)
static MemTxResult subpage_write(void *opaque, hwaddr addr,
uint64_t value, unsigned len, MemTxAttrs attrs)
{
subpage_t *subpage = opaque;
uint8_t buf[8];
@@ -1993,7 +2007,8 @@ static void subpage_write(void *opaque, hwaddr addr,
default:
abort();
}
address_space_write(subpage->as, addr + subpage->base, buf, len);
return address_space_write(subpage->as, addr + subpage->base,
attrs, buf, len);
}
static bool subpage_accepts(void *opaque, hwaddr addr,
@@ -2010,8 +2025,8 @@ static bool subpage_accepts(void *opaque, hwaddr addr,
}
static const MemoryRegionOps subpage_ops = {
.read = subpage_read,
.write = subpage_write,
.read_with_attrs = subpage_read,
.write_with_attrs = subpage_write,
.impl.min_access_size = 1,
.impl.max_access_size = 8,
.valid.min_access_size = 1,
@@ -2304,15 +2319,15 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
return l;
}
bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
int len, bool is_write)
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
uint8_t *buf, int len, bool is_write)
{
hwaddr l;
uint8_t *ptr;
uint64_t val;
hwaddr addr1;
MemoryRegion *mr;
bool error = false;
MemTxResult result = MEMTX_OK;
while (len > 0) {
l = len;
@@ -2327,22 +2342,26 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
case 8:
/* 64 bit write access */
val = ldq_p(buf);
error |= io_mem_write(mr, addr1, val, 8);
result |= memory_region_dispatch_write(mr, addr1, val, 8,
attrs);
break;
case 4:
/* 32 bit write access */
val = ldl_p(buf);
error |= io_mem_write(mr, addr1, val, 4);
result |= memory_region_dispatch_write(mr, addr1, val, 4,
attrs);
break;
case 2:
/* 16 bit write access */
val = lduw_p(buf);
error |= io_mem_write(mr, addr1, val, 2);
result |= memory_region_dispatch_write(mr, addr1, val, 2,
attrs);
break;
case 1:
/* 8 bit write access */
val = ldub_p(buf);
error |= io_mem_write(mr, addr1, val, 1);
result |= memory_region_dispatch_write(mr, addr1, val, 1,
attrs);
break;
default:
abort();
@@ -2361,22 +2380,26 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
switch (l) {
case 8:
/* 64 bit read access */
error |= io_mem_read(mr, addr1, &val, 8);
result |= memory_region_dispatch_read(mr, addr1, &val, 8,
attrs);
stq_p(buf, val);
break;
case 4:
/* 32 bit read access */
error |= io_mem_read(mr, addr1, &val, 4);
result |= memory_region_dispatch_read(mr, addr1, &val, 4,
attrs);
stl_p(buf, val);
break;
case 2:
/* 16 bit read access */
error |= io_mem_read(mr, addr1, &val, 2);
result |= memory_region_dispatch_read(mr, addr1, &val, 2,
attrs);
stw_p(buf, val);
break;
case 1:
/* 8 bit read access */
error |= io_mem_read(mr, addr1, &val, 1);
result |= memory_region_dispatch_read(mr, addr1, &val, 1,
attrs);
stb_p(buf, val);
break;
default:
@@ -2393,25 +2416,27 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
addr += l;
}
return error;
return result;
}
bool address_space_write(AddressSpace *as, hwaddr addr,
const uint8_t *buf, int len)
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
const uint8_t *buf, int len)
{
return address_space_rw(as, addr, (uint8_t *)buf, len, true);
return address_space_rw(as, addr, attrs, (uint8_t *)buf, len, true);
}
bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len)
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
uint8_t *buf, int len)
{
return address_space_rw(as, addr, buf, len, false);
return address_space_rw(as, addr, attrs, buf, len, false);
}
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
int len, int is_write)
{
address_space_rw(&address_space_memory, addr, buf, len, is_write);
address_space_rw(&address_space_memory, addr, MEMTXATTRS_UNSPECIFIED,
buf, len, is_write);
}
enum write_rom_type {
@@ -2482,48 +2507,79 @@ typedef struct {
void *buffer;
hwaddr addr;
hwaddr len;
bool in_use;
} BounceBuffer;
static BounceBuffer bounce;
typedef struct MapClient {
void *opaque;
void (*callback)(void *opaque);
QEMUBH *bh;
QLIST_ENTRY(MapClient) link;
} MapClient;
QemuMutex map_client_list_lock;
static QLIST_HEAD(map_client_list, MapClient) map_client_list
= QLIST_HEAD_INITIALIZER(map_client_list);
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
static void cpu_unregister_map_client_do(MapClient *client)
{
MapClient *client = g_malloc(sizeof(*client));
client->opaque = opaque;
client->callback = callback;
QLIST_INSERT_HEAD(&map_client_list, client, link);
return client;
}
static void cpu_unregister_map_client(void *_client)
{
MapClient *client = (MapClient *)_client;
QLIST_REMOVE(client, link);
g_free(client);
}
static void cpu_notify_map_clients(void)
static void cpu_notify_map_clients_locked(void)
{
MapClient *client;
while (!QLIST_EMPTY(&map_client_list)) {
client = QLIST_FIRST(&map_client_list);
client->callback(client->opaque);
cpu_unregister_map_client(client);
qemu_bh_schedule(client->bh);
cpu_unregister_map_client_do(client);
}
}
void cpu_register_map_client(QEMUBH *bh)
{
MapClient *client = g_malloc(sizeof(*client));
qemu_mutex_lock(&map_client_list_lock);
client->bh = bh;
QLIST_INSERT_HEAD(&map_client_list, client, link);
if (!atomic_read(&bounce.in_use)) {
cpu_notify_map_clients_locked();
}
qemu_mutex_unlock(&map_client_list_lock);
}
void cpu_exec_init_all(void)
{
qemu_mutex_init(&ram_list.mutex);
memory_map_init();
io_mem_init();
qemu_mutex_init(&map_client_list_lock);
}
void cpu_unregister_map_client(QEMUBH *bh)
{
MapClient *client;
qemu_mutex_lock(&map_client_list_lock);
QLIST_FOREACH(client, &map_client_list, link) {
if (client->bh == bh) {
cpu_unregister_map_client_do(client);
break;
}
}
qemu_mutex_unlock(&map_client_list_lock);
}
static void cpu_notify_map_clients(void)
{
qemu_mutex_lock(&map_client_list_lock);
cpu_notify_map_clients_locked();
qemu_mutex_unlock(&map_client_list_lock);
}
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
{
MemoryRegion *mr;
@@ -2570,7 +2626,7 @@ void *address_space_map(AddressSpace *as,
l = len;
mr = address_space_translate(as, addr, &xlat, &l, is_write);
if (!memory_access_is_direct(mr, is_write)) {
if (bounce.buffer) {
if (atomic_xchg(&bounce.in_use, true)) {
return NULL;
}
/* Avoid unbounded allocations */
@@ -2582,7 +2638,8 @@ void *address_space_map(AddressSpace *as,
memory_region_ref(mr);
bounce.mr = mr;
if (!is_write) {
address_space_read(as, addr, bounce.buffer, l);
address_space_read(as, addr, MEMTXATTRS_UNSPECIFIED,
bounce.buffer, l);
}
*plen = l;
@@ -2635,11 +2692,13 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
return;
}
if (is_write) {
address_space_write(as, bounce.addr, bounce.buffer, access_len);
address_space_write(as, bounce.addr, MEMTXATTRS_UNSPECIFIED,
bounce.buffer, access_len);
}
qemu_vfree(bounce.buffer);
bounce.buffer = NULL;
memory_region_unref(bounce.mr);
atomic_mb_set(&bounce.in_use, false);
cpu_notify_map_clients();
}
@@ -2657,19 +2716,22 @@ void cpu_physical_memory_unmap(void *buffer, hwaddr len,
}
/* warning: addr must be aligned */
static inline uint32_t ldl_phys_internal(AddressSpace *as, hwaddr addr,
enum device_endian endian)
static inline uint32_t address_space_ldl_internal(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
MemTxResult *result,
enum device_endian endian)
{
uint8_t *ptr;
uint64_t val;
MemoryRegion *mr;
hwaddr l = 4;
hwaddr addr1;
MemTxResult r;
mr = address_space_translate(as, addr, &addr1, &l, false);
if (l < 4 || !memory_access_is_direct(mr, false)) {
/* I/O case */
io_mem_read(mr, addr1, &val, 4);
r = memory_region_dispatch_read(mr, addr1, &val, 4, attrs);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap32(val);
@@ -2695,40 +2757,68 @@ static inline uint32_t ldl_phys_internal(AddressSpace *as, hwaddr addr,
val = ldl_p(ptr);
break;
}
r = MEMTX_OK;
}
if (result) {
*result = r;
}
return val;
}
uint32_t address_space_ldl(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_ldl_internal(as, addr, attrs, result,
DEVICE_NATIVE_ENDIAN);
}
uint32_t address_space_ldl_le(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_ldl_internal(as, addr, attrs, result,
DEVICE_LITTLE_ENDIAN);
}
uint32_t address_space_ldl_be(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_ldl_internal(as, addr, attrs, result,
DEVICE_BIG_ENDIAN);
}
uint32_t ldl_phys(AddressSpace *as, hwaddr addr)
{
return ldl_phys_internal(as, addr, DEVICE_NATIVE_ENDIAN);
return address_space_ldl(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr)
{
return ldl_phys_internal(as, addr, DEVICE_LITTLE_ENDIAN);
return address_space_ldl_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr)
{
return ldl_phys_internal(as, addr, DEVICE_BIG_ENDIAN);
return address_space_ldl_be(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline uint64_t ldq_phys_internal(AddressSpace *as, hwaddr addr,
enum device_endian endian)
static inline uint64_t address_space_ldq_internal(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
MemTxResult *result,
enum device_endian endian)
{
uint8_t *ptr;
uint64_t val;
MemoryRegion *mr;
hwaddr l = 8;
hwaddr addr1;
MemTxResult r;
mr = address_space_translate(as, addr, &addr1, &l,
false);
if (l < 8 || !memory_access_is_direct(mr, false)) {
/* I/O case */
io_mem_read(mr, addr1, &val, 8);
r = memory_region_dispatch_read(mr, addr1, &val, 8, attrs);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap64(val);
@@ -2754,48 +2844,88 @@ static inline uint64_t ldq_phys_internal(AddressSpace *as, hwaddr addr,
val = ldq_p(ptr);
break;
}
r = MEMTX_OK;
}
if (result) {
*result = r;
}
return val;
}
uint64_t address_space_ldq(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_ldq_internal(as, addr, attrs, result,
DEVICE_NATIVE_ENDIAN);
}
uint64_t address_space_ldq_le(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_ldq_internal(as, addr, attrs, result,
DEVICE_LITTLE_ENDIAN);
}
uint64_t address_space_ldq_be(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_ldq_internal(as, addr, attrs, result,
DEVICE_BIG_ENDIAN);
}
uint64_t ldq_phys(AddressSpace *as, hwaddr addr)
{
return ldq_phys_internal(as, addr, DEVICE_NATIVE_ENDIAN);
return address_space_ldq(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr)
{
return ldq_phys_internal(as, addr, DEVICE_LITTLE_ENDIAN);
return address_space_ldq_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr)
{
return ldq_phys_internal(as, addr, DEVICE_BIG_ENDIAN);
return address_space_ldq_be(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* XXX: optimize */
uint32_t ldub_phys(AddressSpace *as, hwaddr addr)
uint32_t address_space_ldub(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
uint8_t val;
address_space_rw(as, addr, &val, 1, 0);
MemTxResult r;
r = address_space_rw(as, addr, attrs, &val, 1, 0);
if (result) {
*result = r;
}
return val;
}
uint32_t ldub_phys(AddressSpace *as, hwaddr addr)
{
return address_space_ldub(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline uint32_t lduw_phys_internal(AddressSpace *as, hwaddr addr,
enum device_endian endian)
static inline uint32_t address_space_lduw_internal(AddressSpace *as,
hwaddr addr,
MemTxAttrs attrs,
MemTxResult *result,
enum device_endian endian)
{
uint8_t *ptr;
uint64_t val;
MemoryRegion *mr;
hwaddr l = 2;
hwaddr addr1;
MemTxResult r;
mr = address_space_translate(as, addr, &addr1, &l,
false);
if (l < 2 || !memory_access_is_direct(mr, false)) {
/* I/O case */
io_mem_read(mr, addr1, &val, 2);
r = memory_region_dispatch_read(mr, addr1, &val, 2, attrs);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap16(val);
@@ -2821,39 +2951,66 @@ static inline uint32_t lduw_phys_internal(AddressSpace *as, hwaddr addr,
val = lduw_p(ptr);
break;
}
r = MEMTX_OK;
}
if (result) {
*result = r;
}
return val;
}
uint32_t address_space_lduw(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_lduw_internal(as, addr, attrs, result,
DEVICE_NATIVE_ENDIAN);
}
uint32_t address_space_lduw_le(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_lduw_internal(as, addr, attrs, result,
DEVICE_LITTLE_ENDIAN);
}
uint32_t address_space_lduw_be(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return address_space_lduw_internal(as, addr, attrs, result,
DEVICE_BIG_ENDIAN);
}
uint32_t lduw_phys(AddressSpace *as, hwaddr addr)
{
return lduw_phys_internal(as, addr, DEVICE_NATIVE_ENDIAN);
return address_space_lduw(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr)
{
return lduw_phys_internal(as, addr, DEVICE_LITTLE_ENDIAN);
return address_space_lduw_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr)
{
return lduw_phys_internal(as, addr, DEVICE_BIG_ENDIAN);
return address_space_lduw_be(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned. The ram page is not masked as dirty
and the code inside is not invalidated. It is useful if the dirty
bits are used to track modified PTEs */
void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
uint8_t *ptr;
MemoryRegion *mr;
hwaddr l = 4;
hwaddr addr1;
MemTxResult r;
mr = address_space_translate(as, addr, &addr1, &l,
true);
if (l < 4 || !memory_access_is_direct(mr, true)) {
io_mem_write(mr, addr1, val, 4);
r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
} else {
addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
ptr = qemu_get_ram_ptr(addr1);
@@ -2867,18 +3024,30 @@ void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
cpu_physical_memory_set_dirty_range_nocode(addr1, 4);
}
}
r = MEMTX_OK;
}
if (result) {
*result = r;
}
}
void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
{
address_space_stl_notdirty(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline void stl_phys_internal(AddressSpace *as,
hwaddr addr, uint32_t val,
enum device_endian endian)
static inline void address_space_stl_internal(AddressSpace *as,
hwaddr addr, uint32_t val,
MemTxAttrs attrs,
MemTxResult *result,
enum device_endian endian)
{
uint8_t *ptr;
MemoryRegion *mr;
hwaddr l = 4;
hwaddr addr1;
MemTxResult r;
mr = address_space_translate(as, addr, &addr1, &l,
true);
@@ -2892,7 +3061,7 @@ static inline void stl_phys_internal(AddressSpace *as,
val = bswap32(val);
}
#endif
io_mem_write(mr, addr1, val, 4);
r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
} else {
/* RAM case */
addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
@@ -2909,40 +3078,79 @@ static inline void stl_phys_internal(AddressSpace *as,
break;
}
invalidate_and_set_dirty(addr1, 4);
r = MEMTX_OK;
}
if (result) {
*result = r;
}
}
void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
address_space_stl_internal(as, addr, val, attrs, result,
DEVICE_NATIVE_ENDIAN);
}
void address_space_stl_le(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
address_space_stl_internal(as, addr, val, attrs, result,
DEVICE_LITTLE_ENDIAN);
}
void address_space_stl_be(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
address_space_stl_internal(as, addr, val, attrs, result,
DEVICE_BIG_ENDIAN);
}
void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{
stl_phys_internal(as, addr, val, DEVICE_NATIVE_ENDIAN);
address_space_stl(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{
stl_phys_internal(as, addr, val, DEVICE_LITTLE_ENDIAN);
address_space_stl_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{
stl_phys_internal(as, addr, val, DEVICE_BIG_ENDIAN);
address_space_stl_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* XXX: optimize */
void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val)
void address_space_stb(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
uint8_t v = val;
address_space_rw(as, addr, &v, 1, 1);
MemTxResult r;
r = address_space_rw(as, addr, attrs, &v, 1, 1);
if (result) {
*result = r;
}
}
void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{
address_space_stb(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline void stw_phys_internal(AddressSpace *as,
hwaddr addr, uint32_t val,
enum device_endian endian)
static inline void address_space_stw_internal(AddressSpace *as,
hwaddr addr, uint32_t val,
MemTxAttrs attrs,
MemTxResult *result,
enum device_endian endian)
{
uint8_t *ptr;
MemoryRegion *mr;
hwaddr l = 2;
hwaddr addr1;
MemTxResult r;
mr = address_space_translate(as, addr, &addr1, &l, true);
if (l < 2 || !memory_access_is_direct(mr, true)) {
@@ -2955,7 +3163,7 @@ static inline void stw_phys_internal(AddressSpace *as,
val = bswap16(val);
}
#endif
io_mem_write(mr, addr1, val, 2);
r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
} else {
/* RAM case */
addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
@@ -2972,41 +3180,95 @@ static inline void stw_phys_internal(AddressSpace *as,
break;
}
invalidate_and_set_dirty(addr1, 2);
r = MEMTX_OK;
}
if (result) {
*result = r;
}
}
void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
address_space_stw_internal(as, addr, val, attrs, result,
DEVICE_NATIVE_ENDIAN);
}
void address_space_stw_le(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
address_space_stw_internal(as, addr, val, attrs, result,
DEVICE_LITTLE_ENDIAN);
}
void address_space_stw_be(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
address_space_stw_internal(as, addr, val, attrs, result,
DEVICE_BIG_ENDIAN);
}
void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{
stw_phys_internal(as, addr, val, DEVICE_NATIVE_ENDIAN);
address_space_stw(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{
stw_phys_internal(as, addr, val, DEVICE_LITTLE_ENDIAN);
address_space_stw_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{
stw_phys_internal(as, addr, val, DEVICE_BIG_ENDIAN);
address_space_stw_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* XXX: optimize */
void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result)
{
MemTxResult r;
val = tswap64(val);
r = address_space_rw(as, addr, attrs, (void *) &val, 8, 1);
if (result) {
*result = r;
}
}
void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result)
{
MemTxResult r;
val = cpu_to_le64(val);
r = address_space_rw(as, addr, attrs, (void *) &val, 8, 1);
if (result) {
*result = r;
}
}
void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result)
{
MemTxResult r;
val = cpu_to_be64(val);
r = address_space_rw(as, addr, attrs, (void *) &val, 8, 1);
if (result) {
*result = r;
}
}
void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val)
{
val = tswap64(val);
address_space_rw(as, addr, (void *) &val, 8, 1);
address_space_stq(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val)
{
val = cpu_to_le64(val);
address_space_rw(as, addr, (void *) &val, 8, 1);
address_space_stq_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val)
{
val = cpu_to_be64(val);
address_space_rw(as, addr, (void *) &val, 8, 1);
address_space_stq_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
}
/* virtual memory access for debug (includes writing to ROM) */
@@ -3030,7 +3292,8 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
if (is_write) {
cpu_physical_memory_write_rom(cpu->as, phys_addr, buf, l);
} else {
address_space_rw(cpu->as, phys_addr, buf, l, 0);
address_space_rw(cpu->as, phys_addr, MEMTXATTRS_UNSPECIFIED,
buf, l, 0);
}
len -= l;
buf += l;

View File

@@ -998,8 +998,7 @@ ETEXI
.params = "protocol hostname port tls-port cert-subject",
.help = "send migration info to spice/vnc client",
.user_print = monitor_user_noop,
.mhandler.cmd_async = client_migrate_info,
.flags = MONITOR_CMD_ASYNC,
.mhandler.cmd_new = client_migrate_info,
},
STEXI

6
hmp.c
View File

@@ -391,8 +391,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
inserted->iops_size);
}
/* TODO: inserted->image should never be null */
if (verbose && inserted->image) {
if (verbose) {
monitor_printf(mon, "\nImages:\n");
image_info = inserted->image;
while (1) {
@@ -1062,7 +1061,8 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
qmp_drive_backup(device, filename, !!format, format,
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
true, mode, false, 0, false, 0, false, 0, &err);
true, mode, false, 0, false, NULL,
false, 0, false, 0, &err);
hmp_handle_error(mon, &err);
}

1
hmp.h
View File

@@ -109,7 +109,6 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
void watchdog_action_completion(ReadLineState *rs, int nb_args,
const char *str);
void migrate_set_capability_completion(ReadLineState *rs, int nb_args,

View File

@@ -31,7 +31,6 @@
#include "hw/pci/pci.h"
#include "hw/acpi/acpi.h"
#include "sysemu/sysemu.h"
#include "qemu/range.h"
#include "exec/ioport.h"
#include "exec/address-spaces.h"
#include "hw/pci/pci_bus.h"
@@ -120,7 +119,7 @@ static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
{
BusChild *kid, *next;
int slot = ffs(slots) - 1;
int slot = ctz32(slots);
PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
if (!bus) {

View File

@@ -157,9 +157,12 @@ static void clipper_init(MachineState *machine)
load_image_targphys(initrd_filename, initrd_base,
ram_size - initrd_base);
stq_phys(&address_space_memory,
param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL);
stq_phys(&address_space_memory, param_offset + 0x108, initrd_size);
address_space_stq(&address_space_memory, param_offset + 0x100,
initrd_base + 0xfffffc0000000000ULL,
MEMTXATTRS_UNSPECIFIED,
NULL);
address_space_stq(&address_space_memory, param_offset + 0x108,
initrd_size, MEMTXATTRS_UNSPECIFIED, NULL);
}
}
}

View File

@@ -613,7 +613,8 @@ static bool make_iommu_tlbe(hwaddr taddr, hwaddr mask, IOMMUTLBEntry *ret)
translation, given the address of the PTE. */
static bool pte_translate(hwaddr pte_addr, IOMMUTLBEntry *ret)
{
uint64_t pte = ldq_phys(&address_space_memory, pte_addr);
uint64_t pte = address_space_ldq(&address_space_memory, pte_addr,
MEMTXATTRS_UNSPECIFIED, NULL);
/* Check valid bit. */
if ((pte & 1) == 0) {

View File

@@ -170,7 +170,8 @@ static void default_reset_secondary(ARMCPU *cpu,
{
CPUARMState *env = &cpu->env;
stl_phys_notdirty(&address_space_memory, info->smp_bootreg_addr, 0);
address_space_stl_notdirty(&address_space_memory, info->smp_bootreg_addr,
0, MEMTXATTRS_UNSPECIFIED, NULL);
env->regs[15] = info->smp_loader_start;
}
@@ -180,7 +181,8 @@ static inline bool have_dtb(const struct arm_boot_info *info)
}
#define WRITE_WORD(p, value) do { \
stl_phys_notdirty(&address_space_memory, p, value); \
address_space_stl_notdirty(&address_space_memory, p, value, \
MEMTXATTRS_UNSPECIFIED, NULL); \
p += 4; \
} while (0)

View File

@@ -69,11 +69,17 @@ static void hb_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
switch (info->nb_cpus) {
case 4:
stl_phys_notdirty(&address_space_memory, SMP_BOOT_REG + 0x30, 0);
address_space_stl_notdirty(&address_space_memory,
SMP_BOOT_REG + 0x30, 0,
MEMTXATTRS_UNSPECIFIED, NULL);
case 3:
stl_phys_notdirty(&address_space_memory, SMP_BOOT_REG + 0x20, 0);
address_space_stl_notdirty(&address_space_memory,
SMP_BOOT_REG + 0x20, 0,
MEMTXATTRS_UNSPECIFIED, NULL);
case 2:
stl_phys_notdirty(&address_space_memory, SMP_BOOT_REG + 0x10, 0);
address_space_stl_notdirty(&address_space_memory,
SMP_BOOT_REG + 0x10, 0,
MEMTXATTRS_UNSPECIFIED, NULL);
env->regs[15] = SMP_BOOT_ADDR;
break;
default:

View File

@@ -579,7 +579,10 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
case 0x26: /* GAMSET */
if (!s->pm) {
s->gamma = ffs(s->param[0] & 0xf) - 1;
s->gamma = ctz32(s->param[0] & 0xf);
if (s->gamma == 32) {
s->gamma = -1; /* XXX: should this be 0? */
}
} else if (s->pm < 0) {
s->pm = 1;
}

View File

@@ -2004,8 +2004,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr,
case 0x04: /* OUTPUT_REG */
diff = (s->outputs ^ value) & ~s->dir;
s->outputs = value;
while ((ln = ffs(diff))) {
ln --;
while ((ln = ctz32(diff)) != 32) {
if (s->handler[ln])
qemu_set_irq(s->handler[ln], (value >> ln) & 1);
diff &= ~(1 << ln);
@@ -2017,8 +2016,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr,
s->dir = value;
value = s->outputs & ~s->dir;
while ((ln = ffs(diff))) {
ln --;
while ((ln = ctz32(diff)) != 32) {
if (s->handler[ln])
qemu_set_irq(s->handler[ln], (value >> ln) & 1);
diff &= ~(1 << ln);

View File

@@ -274,7 +274,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC;
s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
s->cpu->env.cp15.sctlr_ns = 0;
s->cpu->env.cp15.c1_coproc = 0;
s->cpu->env.cp15.cpacr_el1 = 0;
s->cpu->env.cp15.ttbr0_el[1] = 0;
s->cpu->env.cp15.dacr_ns = 0;
s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */

View File

@@ -137,7 +137,7 @@ static void pxa2xx_gpio_handler_update(PXA2xxGPIOInfo *s) {
level = s->olevel[i] & s->dir[i];
for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) {
bit = ffs(diff) - 1;
bit = ctz32(diff);
line = bit + 32 * i;
qemu_set_irq(s->handler[line], (level >> bit) & 1);
}

View File

@@ -528,7 +528,7 @@ static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s)
level = s->olevel & s->dir;
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
bit = ffs(diff) - 1;
bit = ctz32(diff);
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
}
@@ -745,7 +745,7 @@ static void strongarm_ppc_handler_update(StrongARMPPCInfo *s)
level = s->olevel & s->dir;
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
bit = ffs(diff) - 1;
bit = ctz32(diff);
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
}

View File

@@ -71,13 +71,6 @@ IO_READ_PROTO (gus_readb)
return gus_read (&s->emu, nport, 1);
}
IO_READ_PROTO (gus_readw)
{
GUSState *s = opaque;
return gus_read (&s->emu, nport, 2);
}
IO_WRITE_PROTO (gus_writeb)
{
GUSState *s = opaque;
@@ -85,13 +78,6 @@ IO_WRITE_PROTO (gus_writeb)
gus_write (&s->emu, nport, 1, val);
}
IO_WRITE_PROTO (gus_writew)
{
GUSState *s = opaque;
gus_write (&s->emu, nport, 2, val);
}
static int write_audio (GUSState *s, int samples)
{
int net = 0;
@@ -236,17 +222,13 @@ static const VMStateDescription vmstate_gus = {
static const MemoryRegionPortio gus_portio_list1[] = {
{0x000, 1, 1, .write = gus_writeb },
{0x000, 1, 2, .write = gus_writew },
{0x006, 10, 1, .read = gus_readb, .write = gus_writeb },
{0x006, 10, 2, .read = gus_readw, .write = gus_writew },
{0x100, 8, 1, .read = gus_readb, .write = gus_writeb },
{0x100, 8, 2, .read = gus_readw, .write = gus_writew },
PORTIO_END_OF_LIST (),
};
static const MemoryRegionPortio gus_portio_list2[] = {
{0, 1, 1, .read = gus_readb },
{0, 1, 2, .read = gus_readw },
{0, 2, 1, .read = gus_readb },
PORTIO_END_OF_LIST (),
};

View File

@@ -1121,12 +1121,6 @@ static IO_WRITE_PROTO (mixer_write_datab)
s->mixer_regs[s->mixer_nreg] = val;
}
static IO_WRITE_PROTO (mixer_write_indexw)
{
mixer_write_indexb (opaque, nport, val & 0xff);
mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
}
static IO_READ_PROTO (mixer_read)
{
SB16State *s = opaque;
@@ -1345,7 +1339,6 @@ static const VMStateDescription vmstate_sb16 = {
static const MemoryRegionPortio sb16_ioport_list[] = {
{ 4, 1, 1, .write = mixer_write_indexb },
{ 4, 1, 2, .write = mixer_write_indexw },
{ 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
{ 6, 1, 1, .read = dsp_read, .write = dsp_write },
{ 10, 1, 1, .read = dsp_read },

View File

@@ -535,8 +535,6 @@ struct FDCtrl {
uint8_t pwrd;
/* Floppy drives */
uint8_t num_floppies;
/* Sun4m quirks? */
int sun4m;
FDrive drives[MAX_FD];
int reset_sensei;
uint32_t check_media_rate;
@@ -885,13 +883,6 @@ static void fdctrl_reset_irq(FDCtrl *fdctrl)
static void fdctrl_raise_irq(FDCtrl *fdctrl)
{
/* Sparc mutation */
if (fdctrl->sun4m && (fdctrl->msr & FD_MSR_CMDBUSY)) {
/* XXX: not sure */
fdctrl->msr &= ~FD_MSR_CMDBUSY;
fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
return;
}
if (!(fdctrl->sra & FD_SRA_INTPEND)) {
qemu_set_irq(fdctrl->irq, 1);
fdctrl->sra |= FD_SRA_INTPEND;
@@ -1080,12 +1071,6 @@ static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl)
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
fdctrl->dor |= FD_DOR_nRESET;
/* Sparc mutation */
if (fdctrl->sun4m) {
retval |= FD_MSR_DIO;
fdctrl_reset_irq(fdctrl);
};
FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
return retval;
@@ -2241,8 +2226,6 @@ static void sun4m_fdc_initfn(Object *obj)
FDCtrlSysBus *sys = SYSBUS_FDC(obj);
FDCtrl *fdctrl = &sys->state;
fdctrl->sun4m = 1;
memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops,
fdctrl, "fdctrl", 0x08);
sysbus_init_mmio(sbd, &fdctrl->iomem);

View File

@@ -621,7 +621,6 @@ static int m25p80_init(SSISlave *ss)
s->size = s->pi->sector_size * s->pi->n_sectors;
s->dirty_page = -1;
s->storage = blk_blockalign(s->blk, s->size);
/* FIXME use a qdev drive property instead of drive_get_next() */
dinfo = drive_get_next(IF_MTD);
@@ -629,6 +628,9 @@ static int m25p80_init(SSISlave *ss)
if (dinfo) {
DB_PRINT_L(0, "Binding to IF_MTD drive\n");
s->blk = blk_by_legacy_dinfo(dinfo);
blk_attach_dev_nofail(s->blk, s);
s->storage = blk_blockalign(s->blk, s->size);
/* FIXME: Move to late init */
if (blk_read(s->blk, 0, s->storage,
@@ -638,6 +640,7 @@ static int m25p80_init(SSISlave *ss)
}
} else {
DB_PRINT_L(0, "No BDRV - binding to RAM\n");
s->storage = blk_blockalign(NULL, s->size);
memset(s->storage, 0xFF, s->size);
}

View File

@@ -615,6 +615,13 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
n->bar.intmc = n->bar.intms;
break;
case 0x14:
/* Windows first sends data, then sends enable bit */
if (!NVME_CC_EN(data) && !NVME_CC_EN(n->bar.cc) &&
!NVME_CC_SHN(data) && !NVME_CC_SHN(n->bar.cc))
{
n->bar.cc = data;
}
if (NVME_CC_EN(data) && !NVME_CC_EN(n->bar.cc)) {
n->bar.cc = data;
if (nvme_start_ctrl(n)) {

View File

@@ -515,7 +515,7 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
type = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type);
/* VIRTIO_BLK_T_OUT defines the command direction. VIRTIO_BLK_T_BARRIER
* is an optional flag. Altough a guest should not send this flag if
* is an optional flag. Although a guest should not send this flag if
* not negotiated we ignored it in the past. So keep ignoring it. */
switch (type & ~(VIRTIO_BLK_T_OUT | VIRTIO_BLK_T_BARRIER)) {
case VIRTIO_BLK_T_IN:

View File

@@ -707,7 +707,7 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
len += sdp_attr_max_size(&def->attributes[record->attributes ++].data,
&record->uuids);
}
record->uuids = 1 << ffs(record->uuids - 1);
record->uuids = pow2ceil(record->uuids);
record->attribute_list =
g_malloc0(record->attributes * sizeof(*record->attribute_list));
record->uuid =

View File

@@ -364,6 +364,7 @@ static void console_class_init(ObjectClass *klass, void *data)
ec->can_handle_event = can_handle_event;
ec->read_event_data = read_event_data;
ec->write_event_data = write_event_data;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo sclp_console_info = {

View File

@@ -266,6 +266,7 @@ static void console_class_init(ObjectClass *klass, void *data)
ec->can_handle_event = can_handle_event;
ec->read_event_data = read_event_data;
ec->write_event_data = write_event_data;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo sclp_console_info = {

View File

@@ -814,12 +814,12 @@ static uint32_t find_free_port_id(VirtIOSerial *vser)
max_nr_ports = vser->serial.max_virtserial_ports;
for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
uint32_t map, bit;
uint32_t map, zeroes;
map = vser->ports_map[i];
bit = ffs(~map);
if (bit) {
return (bit - 1) + i * 32;
zeroes = ctz32(~map);
if (zeroes != 32) {
return zeroes + i * 32;
}
}
return VIRTIO_CONSOLE_BAD_ID;

View File

@@ -835,12 +835,12 @@ err:
return -1;
}
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
size_t max_len, hwaddr addr, const char *fw_file_name,
FWCfgReadCallback fw_callback, void *callback_opaque)
{
Rom *rom;
ram_addr_t ret = RAM_ADDR_MAX;
MemoryRegion *mr = NULL;
rom = g_malloc0(sizeof(*rom));
rom->name = g_strdup(name);
@@ -858,7 +858,7 @@ ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
if (rom_file_has_mr) {
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
ret = memory_region_get_ram_addr(rom->mr);
mr = rom->mr;
} else {
data = rom->data;
}
@@ -867,7 +867,7 @@ ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
fw_callback, callback_opaque,
data, rom->datasize);
}
return ret;
return mr;
}
/* This function is specific for elf program because we don't need to allocate

View File

@@ -21,7 +21,7 @@ common-obj-$(CONFIG_ZAURUS) += tc6393xb.o
ifeq ($(CONFIG_MILKYMIST_TMU2),y)
common-obj-y += milkymist-tmu2.o
milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS)
libs_softmmu += $(OPENGL_LIBS)
milkymist-tmu2.o-libs += $(OPENGL_LIBS)
endif
obj-$(CONFIG_OMAP) += omap_dss.o

View File

@@ -696,7 +696,7 @@ static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
/* called from spice server thread context only */
static void interface_release_resource(QXLInstance *sin,
struct QXLReleaseInfoExt ext)
QXLReleaseInfoExt ext)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
QXLReleaseRing *ring;

View File

@@ -171,7 +171,7 @@ static void tc6393xb_gpio_handler_update(TC6393xbState *s)
level = s->gpio_level & s->gpio_dir;
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
bit = ffs(diff) - 1;
bit = ctz32(diff);
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
}

View File

@@ -205,10 +205,22 @@ again:
if (size == 0) {
/* Transfer complete. */
if (ch->lli) {
ch->src = ldl_le_phys(&address_space_memory, ch->lli);
ch->dest = ldl_le_phys(&address_space_memory, ch->lli + 4);
ch->ctrl = ldl_le_phys(&address_space_memory, ch->lli + 12);
ch->lli = ldl_le_phys(&address_space_memory, ch->lli + 8);
ch->src = address_space_ldl_le(&address_space_memory,
ch->lli,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->dest = address_space_ldl_le(&address_space_memory,
ch->lli + 4,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->ctrl = address_space_ldl_le(&address_space_memory,
ch->lli + 12,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->lli = address_space_ldl_le(&address_space_memory,
ch->lli + 8,
MEMTXATTRS_UNSPECIFIED,
NULL);
} else {
ch->conf &= ~PL080_CCONF_E;
}

View File

@@ -263,7 +263,8 @@ static uint32_t iommu_page_get_flags(IOMMUState *s, hwaddr addr)
iopte = s->regs[IOMMU_BASE] << 4;
addr &= ~s->iostart;
iopte += (addr >> (IOMMU_PAGE_SHIFT - 2)) & ~3;
ret = ldl_be_phys(&address_space_memory, iopte);
ret = address_space_ldl_be(&address_space_memory, iopte,
MEMTXATTRS_UNSPECIFIED, NULL);
trace_sun4m_iommu_page_get_flags(pa, iopte, ret);
return ret;
}

View File

@@ -96,7 +96,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
case 0x01: /* Output port */
for (diff = (data ^ s->level) & ~s->direction; diff;
diff &= ~(1 << line)) {
line = ffs(diff) - 1;
line = ctz32(diff);
if (s->handler[line])
qemu_set_irq(s->handler[line], (data >> line) & 1);
}

View File

@@ -125,8 +125,7 @@ static void omap_gpio_write(void *opaque, hwaddr addr,
case 0x04: /* DATA_OUTPUT */
diff = (s->outputs ^ value) & ~s->dir;
s->outputs = value;
while ((ln = ffs(diff))) {
ln --;
while ((ln = ctz32(diff)) != 32) {
if (s->handler[ln])
qemu_set_irq(s->handler[ln], (value >> ln) & 1);
diff &= ~(1 << ln);
@@ -138,8 +137,7 @@ static void omap_gpio_write(void *opaque, hwaddr addr,
s->dir = value;
value = s->outputs & ~s->dir;
while ((ln = ffs(diff))) {
ln --;
while ((ln = ctz32(diff)) != 32) {
if (s->handler[ln])
qemu_set_irq(s->handler[ln], (value >> ln) & 1);
diff &= ~(1 << ln);
@@ -253,8 +251,7 @@ static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
s->outputs ^= diff;
diff &= ~s->dir;
while ((ln = ffs(diff))) {
ln --;
while ((ln = ctz32(diff)) != 32) {
qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
diff &= ~(1 << ln);
}
@@ -442,8 +439,8 @@ static void omap2_gpio_module_write(void *opaque, hwaddr addr,
s->dir = value;
value = s->outputs & ~s->dir;
while ((ln = ffs(diff))) {
diff &= ~(1 <<-- ln);
while ((ln = ctz32(diff)) != 32) {
diff &= ~(1 << ln);
qemu_set_irq(s->handler[ln], (value >> ln) & 1);
}

View File

@@ -65,7 +65,7 @@ static inline void scoop_gpio_handler_update(ScoopInfo *s) {
level = s->gpio_level & s->gpio_dir;
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
bit = ffs(diff) - 1;
bit = ctz32(diff);
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
}

View File

@@ -171,9 +171,13 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
case 0x0c: /* I2C_IV */
if (s->revision >= OMAP2_INTR_REV)
break;
ret = ffs(s->stat & s->mask);
if (ret)
s->stat ^= 1 << (ret - 1);
ret = ctz32(s->stat & s->mask);
if (ret != 32) {
s->stat ^= 1 << ret;
ret++;
} else {
ret = 0;
}
omap_i2c_interrupts_update(s);
return ret;

View File

@@ -26,7 +26,6 @@
#include "qemu-common.h"
#include "qemu/bitmap.h"
#include "qemu/osdep.h"
#include "qemu/range.h"
#include "qemu/error-report.h"
#include "hw/pci/pci.h"
#include "qom/cpu.h"
@@ -58,7 +57,6 @@
#include "qapi/qmp/qint.h"
#include "qom/qom-qobject.h"
#include "exec/ram_addr.h"
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
@@ -1323,13 +1321,13 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
typedef
struct AcpiBuildState {
/* Copy of table in RAM (for patching). */
ram_addr_t table_ram;
MemoryRegion *table_mr;
/* Is table patched? */
uint8_t patched;
PcGuestInfo *guest_info;
void *rsdp;
ram_addr_t rsdp_ram;
ram_addr_t linker_ram;
MemoryRegion *rsdp_mr;
MemoryRegion *linker_mr;
} AcpiBuildState;
static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
@@ -1513,15 +1511,15 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
g_array_free(table_offsets, true);
}
static void acpi_ram_update(ram_addr_t ram, GArray *data)
static void acpi_ram_update(MemoryRegion *mr, GArray *data)
{
uint32_t size = acpi_data_len(data);
/* Make sure RAM size is correct - in case it got changed e.g. by migration */
qemu_ram_resize(ram, size, &error_abort);
memory_region_ram_resize(mr, size, &error_abort);
memcpy(qemu_get_ram_ptr(ram), data->data, size);
cpu_physical_memory_set_dirty_range_nocode(ram, size);
memcpy(memory_region_get_ram_ptr(mr), data->data, size);
memory_region_set_dirty(mr, 0, size);
}
static void acpi_build_update(void *build_opaque, uint32_t offset)
@@ -1539,15 +1537,15 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
acpi_build(build_state->guest_info, &tables);
acpi_ram_update(build_state->table_ram, tables.table_data);
acpi_ram_update(build_state->table_mr, tables.table_data);
if (build_state->rsdp) {
memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp));
} else {
acpi_ram_update(build_state->rsdp_ram, tables.rsdp);
acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
}
acpi_ram_update(build_state->linker_ram, tables.linker);
acpi_ram_update(build_state->linker_mr, tables.linker);
acpi_build_tables_cleanup(&tables, true);
}
@@ -1557,8 +1555,9 @@ static void acpi_build_reset(void *build_opaque)
build_state->patched = 0;
}
static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
const char *name, uint64_t max_size)
static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
GArray *blob, const char *name,
uint64_t max_size)
{
return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
name, acpi_build_update, build_state);
@@ -1604,12 +1603,12 @@ void acpi_setup(PcGuestInfo *guest_info)
acpi_build(build_state->guest_info, &tables);
/* Now expose it all to Guest */
build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data,
build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
ACPI_BUILD_TABLE_FILE,
ACPI_BUILD_TABLE_MAX_SIZE);
assert(build_state->table_ram != RAM_ADDR_MAX);
assert(build_state->table_mr != NULL);
build_state->linker_ram =
build_state->linker_mr =
acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
@@ -1627,10 +1626,10 @@ void acpi_setup(PcGuestInfo *guest_info)
fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
acpi_build_update, build_state,
build_state->rsdp, rsdp_size);
build_state->rsdp_ram = (ram_addr_t)-1;
build_state->rsdp_mr = NULL;
} else {
build_state->rsdp = NULL;
build_state->rsdp_ram = acpi_add_rom_blob(build_state, tables.rsdp,
build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
ACPI_BUILD_RSDP_FILE, 0);
}

View File

@@ -246,7 +246,8 @@ static void vtd_generate_interrupt(IntelIOMMUState *s, hwaddr mesg_addr_reg,
data = vtd_get_long_raw(s, mesg_data_reg);
VTD_DPRINTF(FLOG, "msi: addr 0x%"PRIx64 " data 0x%"PRIx32, addr, data);
stl_le_phys(&address_space_memory, addr, data);
address_space_stl_le(&address_space_memory, addr, data,
MEMTXATTRS_UNSPECIFIED, NULL);
}
/* Generate a fault event to software via MSI if conditions are met.

View File

@@ -2436,8 +2436,8 @@ void ide_init2(IDEBus *bus, qemu_irq irq)
static const MemoryRegionPortio ide_portio_list[] = {
{ 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
{ 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew },
{ 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel },
{ 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew },
{ 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel },
PORTIO_END_OF_LIST(),
};

View File

@@ -23,7 +23,7 @@
static void aw_a10_pic_update(AwA10PICState *s)
{
uint8_t i;
int irq = 0, fiq = 0, pending;
int irq = 0, fiq = 0, zeroes;
s->vector = 0;
@@ -32,9 +32,9 @@ static void aw_a10_pic_update(AwA10PICState *s)
fiq |= s->select[i] & s->irq_pending[i] & ~s->mask[i];
if (!s->vector) {
pending = ffs(s->irq_pending[i] & ~s->mask[i]);
if (pending) {
s->vector = (i * 32 + pending - 1) * 4;
zeroes = ctz32(s->irq_pending[i] & ~s->mask[i]);
if (zeroes != 32) {
s->vector = (i * 32 + zeroes) * 4;
}
}
}

View File

@@ -243,15 +243,6 @@ static void apic_reset_common(DeviceState *dev)
info->vapic_base_update(s);
apic_init_reset(dev);
if (bsp) {
/*
* LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
* time typically by BIOS, so PIC interrupt can be delivered to the
* processor when local APIC is enabled.
*/
s->lvt[APIC_LVT_LINT0] = 0x700;
}
}
/* This function is only used for old state version 1 and 2 */

View File

@@ -60,7 +60,7 @@ struct omap_intr_handler_s {
static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
{
int i, j, sir_intr, p_intr, p, f;
int i, j, sir_intr, p_intr, p;
uint32_t level;
sir_intr = 0;
p_intr = 255;
@@ -72,14 +72,15 @@ static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
for (j = 0; j < s->nbanks; ++j) {
level = s->bank[j].irqs & ~s->bank[j].mask &
(is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq);
for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,
level >>= f) {
while (level != 0) {
i = ctz32(level);
p = s->bank[j].priority[i];
if (p <= p_intr) {
p_intr = p;
sir_intr = 32 * j + i;
}
f = ffs(level >> 1);
level &= level - 1;
}
}
s->sir_intr[is_fiq] = sir_intr;

View File

@@ -113,15 +113,15 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
const char *kernel_filename;
const char *kernel_cmdline;
const char *dtb_arg;
char *filename = NULL;
machine_opts = qemu_get_machine_opts();
kernel_filename = qemu_opt_get(machine_opts, "kernel");
kernel_cmdline = qemu_opt_get(machine_opts, "append");
dtb_arg = qemu_opt_get(machine_opts, "dtb");
if (dtb_arg) { /* Preference a -dtb argument */
dtb_filename = dtb_arg;
} else { /* default to pcbios dtb as passed by machine_init */
dtb_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
/* default to pcbios dtb as passed by machine_init */
if (!dtb_arg) {
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
}
boot_info.machine_cpu_reset = machine_cpu_reset;
@@ -203,7 +203,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
boot_info.initrd_start,
boot_info.initrd_end,
kernel_cmdline,
dtb_filename);
/* Preference a -dtb argument */
dtb_arg ? dtb_arg : filename);
}
g_free(filename);
}

View File

@@ -168,6 +168,7 @@ static int64_t load_kernel (CPUMIPSState *env)
rom_add_blob_fixed("prom", prom_buf, prom_size,
cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
g_free(prom_buf);
return kernel_entry;
}

View File

@@ -61,7 +61,8 @@ static void main_cpu_reset(void *opaque)
static uint64_t rtc_read(void *opaque, hwaddr addr, unsigned size)
{
uint8_t val;
address_space_read(&address_space_memory, 0x90000071, &val, 1);
address_space_read(&address_space_memory, 0x90000071,
MEMTXATTRS_UNSPECIFIED, &val, 1);
return val;
}
@@ -69,7 +70,8 @@ static void rtc_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
uint8_t buf = val & 0xff;
address_space_write(&address_space_memory, 0x90000071, &buf, 1);
address_space_write(&address_space_memory, 0x90000071,
MEMTXATTRS_UNSPECIFIED, &buf, 1);
}
static const MemoryRegionOps rtc_ops = {

View File

@@ -861,6 +861,7 @@ static int64_t load_kernel (void)
rom_add_blob_fixed("prom", prom_buf, prom_size,
cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
g_free(prom_buf);
return kernel_entry;
}

View File

@@ -139,6 +139,7 @@ static int64_t load_kernel(void)
rom_add_blob_fixed("params", params_buf, params_size,
(16 << 20) - 264);
g_free(params_buf);
return entry;
}

View File

@@ -279,7 +279,7 @@ static const MemoryRegionOps edu_mmio_ops = {
};
/*
* We purposedly use a thread, so that users are forced to wait for the status
* We purposely use a thread, so that users are forced to wait for the status
* register.
*/
static void *edu_fact_thread(void *opaque)

View File

@@ -68,6 +68,7 @@ typedef struct APCState {
} APCState;
#define MISC_SIZE 1
#define LED_SIZE 2
#define SYSCTRL_SIZE 4
#define AUX1_TC 0x02
@@ -452,13 +453,13 @@ static int slavio_misc_init1(SysBusDevice *sbd)
/* 16 bit registers */
/* ss600mp diag LEDs */
memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s,
"leds", MISC_SIZE);
"leds", LED_SIZE);
sysbus_init_mmio(sbd, &s->led_iomem);
/* 32 bit registers */
/* System control */
memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s,
"system-control", MISC_SIZE);
"system-control", SYSCTRL_SIZE);
sysbus_init_mmio(sbd, &s->sysctrl_iomem);
/* AUX 1 (Misc System Functions) */

View File

@@ -1590,7 +1590,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
n->max_queues = MAX(n->nic_conf.peers.queues, 1);
if (n->max_queues * 2 + 1 > VIRTIO_PCI_QUEUE_MAX) {
error_setg(errp, "Invalid number of queues (= %" PRIu32 "), "
"must be a postive integer less than %d.",
"must be a positive integer less than %d.",
n->max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2);
virtio_cleanup(vdev);
return;

View File

@@ -172,13 +172,6 @@ bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt)
return pkt->has_virt_hdr;
}
uint16_t vmxnet_rx_pkt_get_num_frags(struct VmxnetRxPkt *pkt)
{
assert(pkt);
return pkt->vec_len;
}
uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt)
{
assert(pkt);

View File

@@ -113,15 +113,6 @@ bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt);
*/
bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt);
/**
* returns number of frags attached to the packet
*
* @pkt: packet
* @ret: number of frags
*
*/
uint16_t vmxnet_rx_pkt_get_num_frags(struct VmxnetRxPkt *pkt);
/**
* attach data to rx packet
*

View File

@@ -101,27 +101,6 @@ static const TypeInfo i82801b11_bridge_info = {
.class_init = i82801b11_bridge_class_init,
};
PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus)
{
PCIDevice *d;
PCIBridge *br;
char buf[16];
DeviceState *qdev;
d = pci_create_multifunction(bus, devfn, true, "i82801b11-bridge");
if (!d) {
return NULL;
}
br = PCI_BRIDGE(d);
qdev = DEVICE(d);
snprintf(buf, sizeof(buf), "pci.%d", sec_bus);
pci_bridge_map_irq(br, buf, pci_swizzle_map_irq_fn);
qdev_init_nofail(qdev);
return pci_bridge_get_sec_bus(br);
}
static void d2pbr_register(void)
{
type_register_static(&i82801b11_bridge_info);

View File

@@ -289,7 +289,8 @@ static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr,
}
}
tte = ldq_be_phys(&address_space_memory, baseaddr + offset);
tte = address_space_ldq_be(&address_space_memory, baseaddr + offset,
MEMTXATTRS_UNSPECIFIED, NULL);
if (!(tte & IOMMU_TTE_DATA_V)) {
/* Invalid mapping */

View File

@@ -427,7 +427,7 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr)
cfgaddr |= (s->regs[BONITO_PCIMAP_CFG] & 0xffff) << 16;
idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> BONITO_PCICONF_IDSEL_OFFSET;
devno = ffs(idsel) - 1;
devno = ctz32(idsel);
funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET;
regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;

View File

@@ -140,7 +140,8 @@ static uint64_t raven_io_read(void *opaque, hwaddr addr,
uint8_t buf[4];
addr = raven_io_address(s, addr);
address_space_read(&s->pci_io_as, addr + 0x80000000, buf, size);
address_space_read(&s->pci_io_as, addr + 0x80000000,
MEMTXATTRS_UNSPECIFIED, buf, size);
if (size == 1) {
return buf[0];
@@ -171,7 +172,8 @@ static void raven_io_write(void *opaque, hwaddr addr,
g_assert_not_reached();
}
address_space_write(&s->pci_io_as, addr + 0x80000000, buf, size);
address_space_write(&s->pci_io_as, addr + 0x80000000,
MEMTXATTRS_UNSPECIFIED, buf, size);
}
static const MemoryRegionOps raven_io_ops = {

View File

@@ -92,7 +92,10 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
uint32_t slot, func;
/* Grab CFA0 style values */
slot = ffs(reg & 0xfffff800) - 1;
slot = ctz32(reg & 0xfffff800);
if (slot == 32) {
slot = -1; /* XXX: should this be 0? */
}
func = (reg >> 8) & 7;
/* ... and then convert them to x86 format */

View File

@@ -72,7 +72,7 @@ static inline uint8_t msi_cap_sizeof(uint16_t flags)
static inline unsigned int msi_nr_vectors(uint16_t flags)
{
return 1U <<
((flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1));
((flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE));
}
static inline uint8_t msi_flags_off(const PCIDevice* dev)
@@ -175,9 +175,9 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
assert(nr_vectors > 0);
assert(nr_vectors <= PCI_MSI_VECTORS_MAX);
/* the nr of MSI vectors is up to 32 */
vectors_order = ffs(nr_vectors) - 1;
vectors_order = ctz32(nr_vectors);
flags = vectors_order << (ffs(PCI_MSI_FLAGS_QMASK) - 1);
flags = vectors_order << ctz32(PCI_MSI_FLAGS_QMASK);
if (msi64bit) {
flags |= PCI_MSI_FLAGS_64BIT;
}
@@ -291,7 +291,8 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
"notify vector 0x%x"
" address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
vector, msg.address, msg.data);
stl_le_phys(&dev->bus_master_as, msg.address, msg.data);
address_space_stl_le(&dev->bus_master_as, msg.address, msg.data,
MEMTXATTRS_UNSPECIFIED, NULL);
}
/* Normally called by pci_default_write_config(). */
@@ -354,12 +355,12 @@ void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
* just don't crash the host
*/
log_num_vecs =
(flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
(flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE);
log_max_vecs =
(flags & PCI_MSI_FLAGS_QMASK) >> (ffs(PCI_MSI_FLAGS_QMASK) - 1);
(flags & PCI_MSI_FLAGS_QMASK) >> ctz32(PCI_MSI_FLAGS_QMASK);
if (log_num_vecs > log_max_vecs) {
flags &= ~PCI_MSI_FLAGS_QSIZE;
flags |= log_max_vecs << (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
flags |= log_max_vecs << ctz32(PCI_MSI_FLAGS_QSIZE);
pci_set_word(dev->config + msi_flags_off(dev), flags);
}

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