Compare commits

...

416 Commits

Author SHA1 Message Date
Gerd Hoffmann
2082bac151 docs/multiseat.txt: add note about spice
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-04 08:40:42 +02:00
Gerd Hoffmann
90525fe279 docs/multiseat.txt: gtk joined the party
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-04 08:40:42 +02:00
Gerd Hoffmann
3503206a90 docs/multiseat.txt: use autoseat
When using the autoseat feature of systemd/logind we'll only need
a single udev rule for the pci bridge, which simplifies the guest
setup a bit.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-04 08:40:42 +02:00
Gerd Hoffmann
2deb4acc7c input/vnc: use kbd delays in press_key
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-04 08:40:42 +02:00
Gerd Hoffmann
5a165668e7 input/curses: add kbd delay between keydown and keyup events
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-04 08:40:42 +02:00
Gerd Hoffmann
2e377f1730 input: use kbd delays for send_key monitor command
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-04 08:40:41 +02:00
Gerd Hoffmann
be1a717624 input: add support for kbd delays
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-04 08:40:41 +02:00
Peter Maydell
e00fcfeab3 Merge remote-tracking branch 'remotes/awilliam/tags/vfio-pci-for-qemu-20140602.0' into staging
VFIO patches: realtek NIC quirk + SPAPR IOMMU AddressSpace support

# gpg: Signature made Mon 02 Jun 2014 22:44:42 BST using RSA key ID 3BB08B22
# gpg: Can't check signature: public key not found

* remotes/awilliam/tags/vfio-pci-for-qemu-20140602.0:
  vfio: Add guest side IOMMU support
  vfio: Create VFIOAddressSpace objects as needed
  vfio: Introduce VFIO address spaces
  vfio: Rework to have error paths
  vfio: Fix 128 bit handling
  int128: Add int128_exts64()
  memory: Sanity check that no listeners remain on a destroyed AddressSpace
  vfio-pci: Quirk RTL8168 NIC

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-03 14:37:43 +01:00
Peter Maydell
278073ba29 Merge remote-tracking branch 'remotes/kraxel/tags/pull-roms-3' into staging
seabios: update to 1.7.5 final

# gpg: Signature made Mon 02 Jun 2014 15:49:59 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-roms-3:
  seabios: update to 1.7.5 final

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-03 11:59:48 +01:00
Peter Maydell
82ea61c6da Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-8' into staging
qtest: improve ehci/uhci test
usb: misc fixes, mostly for usb3/xhci

# gpg: Signature made Mon 02 Jun 2014 15:40:34 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-usb-8:
  xhci: order superspeed ports first
  xhci: make port reset trace point more verbose
  usb: add usb_pick_speed
  usb-host: add HAVE_STREAMS define
  usb-host: allow attaching usb3 devices to ehci
  usb: improve ehci/uhci test
  usb: move ehci register defines to header file
  usb: add uhci port status reserved bit
  usb: move uhci register defines to header file
  qtest: fix qpci_config_writel

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-02 17:07:21 +01:00
Peter Maydell
1673e89e93 Merge remote-tracking branch 'remotes/kraxel/tags/pull-sdl-3' into staging
sdl2: add support for text consoles

# gpg: Signature made Mon 02 Jun 2014 15:35:20 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-3:
  sdl2: textinput + terminal
  sdl2: make Ctrl-Alt-<nr> hotkeys show and hide windows
  console: add kbd_put_string_console
  console: add kbd_put_qcode_console

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-02 16:10:12 +01:00
Gerd Hoffmann
3257fc8383 seabios: update to 1.7.5 final
git shortlog since -rc1:

Gerd Hoffmann (2):
      acpi: remove PORT_ACPI_PM_BASE constant
      Allow using full io region on q35.

Kevin O'Connor (2):
      vgabios: Add debug message if x86emu leal check triggers.
      python3 fixes for vgabios and csm builds.

Paolo Bonzini (1):
      smm: remove code to handle ACPI disable/enable

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:49:00 +02:00
Peter Maydell
36f5db59cf Merge remote-tracking branch 'remotes/kraxel/tags/pull-vnc-3' into staging
misc minor vnc patches

# gpg: Signature made Mon 02 Jun 2014 15:31:53 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-vnc-3:
  vnc-enc-tight: Fix divide-by-zero in tight_detect_smooth_image{16,24,32}
  vnc: add trace events for key events
  vnc: refuse to set a password with VNC_AUTH_NONE

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-02 15:47:40 +01:00
Gerd Hoffmann
7bafd8889e xhci: order superspeed ports first
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:38:09 +02:00
Gonglei
b52991537c vnc-enc-tight: Fix divide-by-zero in tight_detect_smooth_image{16,24,32}
Spotted by Coverity:

(1) Event assignment:  Assigning: "pixels" = "0".
(2) Event cond_true:  Condition "y < h", taking true branch
(3) Event cond_false:  Condition "x < w", taking false branch
(4) Event loop_end:  Reached end of loop
(5) Event divide_by_zero:  In expression "(stats[0] + stats[1]) * 100U / pixels",
division by expression "pixels" which may be zero has undefined behavior.

290     DEFINE_DETECT_FUNCTION(16)
291     DEFINE_DETECT_FUNCTION(32)

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:30:52 +02:00
Gerd Hoffmann
4006617552 vnc: add trace events for key events
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:29:01 +02:00
Gerd Hoffmann
cf864569cd vnc: refuse to set a password with VNC_AUTH_NONE
Current code silently changes the authentication settings
in case you try to set a password without password authentication
turned on.  This is bad.  Return an error instead.

If we want allow changing auth settings at runtime this should
be done explicitly using a separate monitor command, not as
side effect of set_passwd.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:29:01 +02:00
Gerd Hoffmann
7bd3055ffd xhci: make port reset trace point more verbose
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:29:00 +02:00
Gerd Hoffmann
b791c3b38c usb: add usb_pick_speed
We can pick the usb port speed in generic code, by looking at the port
and device speed masks and looking for the fastest match.  So add a
function to do exactly that, and drop the speed setting code from
usb_desc_attach as it isn't needed any more.

This way we can set the device speed before calling port->ops->attach,
which fixes some xhci hotplug issues.

https://bugzilla.redhat.com/show_bug.cgi?id=1046873

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:29:00 +02:00
Gerd Hoffmann
322fd1f4f7 usb-host: add HAVE_STREAMS define 2014-06-02 16:29:00 +02:00
Gerd Hoffmann
b88a3e01f5 usb-host: allow attaching usb3 devices to ehci
Extend compatibility test function to also figure whenever usb3
devices can be supported on ehci.  Tweak ep0 maxpacketsize field
due to usb2 <-> usb3 difference.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:59 +02:00
Gerd Hoffmann
d81d410635 usb: improve ehci/uhci test
* Attach usb devices to the bus.
 * Check initial port status register state.
 * Flip ehci initialization bit.
 * Check port status register state again to
   see whenever device handover to ehci worked.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:59 +02:00
Gerd Hoffmann
381626a969 usb: move ehci register defines to header file
So we can easily use them in tests.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:59 +02:00
Gerd Hoffmann
95dd1c4d7a usb: add uhci port status reserved bit
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:59 +02:00
Gerd Hoffmann
9a1d111e70 usb: move uhci register defines to header file
So we can easily use them in tests.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:59 +02:00
Gerd Hoffmann
ad489e9346 qtest: fix qpci_config_writel
Found by Paolo.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:59 +02:00
Gerd Hoffmann
f2335791fd sdl2: textinput + terminal
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:58 +02:00
Gerd Hoffmann
363f59d9e4 sdl2: make Ctrl-Alt-<nr> hotkeys show and hide windows
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:58 +02:00
Gerd Hoffmann
bdef972474 console: add kbd_put_string_console
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:58 +02:00
Gerd Hoffmann
50ef467923 console: add kbd_put_qcode_console
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-02 16:28:58 +02:00
Peter Maydell
f72b49398f Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches

# gpg: Signature made Mon 02 Jun 2014 14:56:00 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  qemu-img: Report error even with --oformat=json
  vmdk: Fix local_err in vmdk_create
  block/raw-posix.c: Avoid nonstandard LONG_LONG_MAX
  qemu-img: Plug memory leak in convert command
  block/sheepdog: Plug memory leak in sd_snapshot_create()
  block/vvfat: Plug memory leak in read_directory()
  block/vvfat: Plug memory leak in check_directory_consistency()
  block/qapi: Plug memory leak in dump_qobject() case QTYPE_QERROR
  blockdev: Plug memory leak in drive_init()
  blockdev: Plug memory leak in blockdev_init()
  qemu-io: Don't print NULL when open without non-option arg fails
  qemu-io: Plug memory leak in open command
  qemu-io: Support multiple -o in open command
  block: Plug memory leak on brv_open_image() error path
  qcow2: Plug memory leak on qcow2_invalidate_cache() error paths
  block/vvfat: Plug memory leak in enable_write_target()
  qemu-img: Plug memory leak on block option help error path

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-02 15:27:18 +01:00
Peter Maydell
9bb931802e Revert "bsd-user: replace fprintf(stderr, ...) with error_report()"
This reverts commit 1fba509527.

That commit converted various fprintf(stderr, ...) calls to
use error_report(); however none of these bsd-user files include
a header which gives a prototype for error_report, so this
causes compiler warnings. Since these are just straightforward
reporting of command line errors, we should handle these in the
obvious way by printing to stderr, as we do for linux-user.
There's no need to drag in the error-handling framework for this,
especially since user-mode doesn't have the "maybe we need to
send this to the monitor" issues system emulation does.

Acked-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-02 13:26:59 +01:00
Max Reitz
55d492d760 qemu-img: Report error even with --oformat=json
img_check() should report that the format of the given image does not
support checks even if JSON output is desired. JSON data is output to
stdout, as opposed to error messages, which are (in the case of
qemu-img) printed to stderr. Therefore, it is easy to distinguish
between the two.

Also, img_info() does already use error_report() for human-readable
messages even though JSON output is desired (through
collect_image_info_list()).

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-06-02 13:58:40 +02:00
David Gibson
5e70018b00 vfio: Add guest side IOMMU support
This patch uses the new IOMMU notifiers to allow VFIO pass through devices
to work with guest side IOMMUs, as long as the host-side VFIO iommu has
sufficient capability and granularity to match the guest side. This works
by tracking all map and unmap operations on the guest IOMMU using the
notifiers, and mirroring them into VFIO.

There are a number of FIXMEs, and the scheme involves rather more notifier
structures than I'd like, but it should make for a reasonable proof of
concept.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 13:10:07 -06:00
David Gibson
0688448b71 vfio: Create VFIOAddressSpace objects as needed
So far, VFIO has a notion of different logical DMA address spaces, but
only ever uses one (system memory).  This patch extends this, creating
new VFIOAddressSpace objects as necessary, according to the AddressSpace
reported by the PCI subsystem for this device's DMAs.

This isn't enough yet to support guest side IOMMUs with VFIO, but it does
mean we could now support VFIO devices on, for example, a guest side PCI
host bridge which maps system memory at somewhere other than 0 in PCI
space.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 13:09:14 -06:00
David Gibson
3df3e0a587 vfio: Introduce VFIO address spaces
The only model so far supported for VFIO passthrough devices is the model
usually used on x86, where all of the guest's RAM is mapped into the
(host) IOMMU and there is no IOMMU visible in the guest.

This patch begins to relax this model, introducing the notion of a
VFIOAddressSpace.  This represents a logical DMA address space which will
be visible to one or more VFIO devices by appropriate mapping in the (host)
IOMMU.  Thus the currently global list of containers becomes local to
a VFIOAddressSpace, and we verify that we don't attempt to add a VFIO
group to multiple address spaces.

For now, only one VFIOAddressSpace is created and used, corresponding to
main system memory, that will change in future patches.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 13:05:19 -06:00
Alexey Kardashevskiy
279a35ab4a vfio: Rework to have error paths
This reworks vfio_connect_container() and vfio_get_group() to have
common exit path at the end of the function bodies.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 13:03:21 -06:00
Alexey Kardashevskiy
7532d3cbf1 vfio: Fix 128 bit handling
Upcoming VFIO on SPAPR PPC64 support will initialize the IOMMU
memory region with UINT64_MAX (2^64 bytes) size so int128_get64()
will assert.

The patch takes care of this check. The existing type1 IOMMU code
is not expected to map all 64 bits of RAM so the patch does not
touch that part.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 13:02:02 -06:00
Alexey Kardashevskiy
12e1129b80 int128: Add int128_exts64()
This adds macro to extend signed 64bit value to signed 128bit value.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 13:00:28 -06:00
David Gibson
078c44f48e memory: Sanity check that no listeners remain on a destroyed AddressSpace
At the moment, most AddressSpace objects last as long as the guest system
in practice, but that could well change in future.  In addition, for VFIO
we will be introducing some private per-AdressSpace information, which must
be disposed of before the AddressSpace itself is destroyed.

To reduce the chances of subtle bugs in this area, this patch adds
asssertions to ensure that when an AddressSpace is destroyed, there are no
remaining MemoryListeners using that AS as a filter.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 12:59:00 -06:00
Alex Williamson
4cb47d281a vfio-pci: Quirk RTL8168 NIC
This device is ridiculous.  It has two MMIO BARs, BAR4 and BAR2.  BAR4
hosts the MSI-X table, so oviously it would be too easy to access it
directly, instead it creates a window register in BAR2 that, among
other things, provides access to the MSI-X table.  This means MSI-X
doesn't work in the guest because the driver actually manages to
program the physical table.  When interrupt remapping is present, the
device MSI will be blocked.  The Linux driver doesn't make use of this
window, so apparently it's not required to make use of MSI-X.  This
quirk makes the device work with the Windows driver that does use this
window for MSI-X, but I certainly cannot recommend this device for
assignment (the Windows 7 driver also constantly pokes PCI config
space).

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-05-30 12:43:50 -06:00
Fam Zheng
c13959c745 vmdk: Fix local_err in vmdk_create
In vmdk_create and vmdk_create_extent, initialize local_err before using
it, and don't leak it on error.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Peter Maydell
675036e4da block/raw-posix.c: Avoid nonstandard LONG_LONG_MAX
In the MacOSX specific code in raw-posix.c we use the define
LONG_LONG_MAX. This is actually a non-standard pre-C99 define;
switch to using the standard LLONG_MAX instead.

This apparently fixes a compilation failure with certain
compiler/OS versions (though it is unclear which).

Reported-by: Peter Bartoli <peter@bartoli.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
bb9cd2ee99 qemu-img: Plug memory leak in convert command
Introduced in commit 661a0f7.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
2df5fee2db block/sheepdog: Plug memory leak in sd_snapshot_create()
Has always been leaky.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
b122c3b6d0 block/vvfat: Plug memory leak in read_directory()
Has always been leaky.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
6262bbd363 block/vvfat: Plug memory leak in check_directory_consistency()
On error path.  Introduced in commit a046433a.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
f25391c2a6 block/qapi: Plug memory leak in dump_qobject() case QTYPE_QERROR
Introduced in commit a8d8ecb.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
3cb0e25c4b blockdev: Plug memory leak in drive_init()
bs_opts is leaked on all paths from its qdev_new() that don't got
through blockdev_init().  Add the missing QDECREF(), and zap bs_opts
after blockdev_init(), so the new QDECREF() does nothing when we go
through blockdev_init().

Leak introduced in commit f298d07.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
6376f95223 blockdev: Plug memory leak in blockdev_init()
blockdev_init() leaks bs_opts when qemu_opts_create() fails, i.e. when
the ID is bad.  Missed in commit ec9c10d.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
543f7bef13 qemu-io: Don't print NULL when open without non-option arg fails
Reproducer: "open -o a=b".  Broken in commit fd0fee3.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
29f2601aa6 qemu-io: Plug memory leak in open command
Introduced in commit b543c5c.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
443422fde7 qemu-io: Support multiple -o in open command
Instead of ignoring all option values but the last one, multiple -o
options now have the same meaning as having a single option with all
settings in the order of their respective -o options.

Same as commit 2dc8328 for qemu-img convert, except here we do it with
QemuOpts rather than QEMUOptionParameter.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
b20e61e0d5 block: Plug memory leak on brv_open_image() error path
Introduced in commit da557a.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
a1904e48c4 qcow2: Plug memory leak on qcow2_invalidate_cache() error paths
Introduced in commit 5a8a30d.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
75e347d66a block/vvfat: Plug memory leak in enable_write_target()
I figure the leak originated in bdrv_create2(), and was duplicated
into callers when commit 91a073a dropped that function.  Looks like
the other places have since been fixed.

Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:26:54 +02:00
Markus Armbruster
ebee92b4fe qemu-img: Plug memory leak on block option help error path
Introduced in commit a283cb6; mostly harmless.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-30 14:25:58 +02:00
Peter Maydell
d7d3d6092c Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-peter' into staging
QOM/QTest infrastructure fixes and device conversions

* qom-test extension
* QEMUMachineInitArgs conversion to MachineState
* -machine options turned into /machine properties
* Named GPIO IRQs for devices

# gpg: Signature made Wed 28 May 2014 18:24:04 BST using RSA key ID 3E7E013F
# gpg: Can't check signature: public key not found

* remotes/afaerber/tags/qom-devices-for-peter:
  ssi: Name the CS GPIO
  qdev: Implement named GPIOs
  machine: Make -machine opts properties of MachineState
  tests: Check empty QMP output visitor
  qapi: Avoid output visitor crashing if it encounters a NULL value
  vl.c: Do not set 'type' property in obj_set_property()
  machine: Conversion of QEMUMachineInitArgs to MachineState
  qom-test: Test qom-list on link<> properties

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 18:38:39 +01:00
Peter Maydell
66226ffd05 Merge remote-tracking branch 'remotes/rth/tcg-next' into staging
* remotes/rth/tcg-next:
  tcg/optimize: Remember garbage high bits for 32-bit ops
  tcg/optimize: Move updating of gen_opc_buf into tcg_opt_gen_mov*
  tcg-sparc: Make debug_frame const
  tcg-s390: Make debug_frame const
  tcg-arm: Make debug_frame const
  tcg-aarch64: Make debug_frame const
  tcg-i386: Make debug_frame const
  tcg: Allow the debug_frame data structure to be constant
  tcg: Move size effects out of dh_arg
  tcg: Remove sizemask and flags arguments to tcg_gen_callN
  tcg: Save flags and computed sizemask in TCGHelperInfo
  tcg: Register the helper info struct rather than the name
  tcg: Move side effects out of dh_sizemask
  tcg: Inline tcg_gen_helperN
  tcg: Use helper-gen.h in tcg-op.h
  tcg: Push tcg-runtime routines into exec/helper-*
  tcg: Invert the inclusion of helper.h
  tcg: Optimize brcond2 and setcond2 ne/eq

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 17:44:45 +01:00
Richard Henderson
24666baf1f tcg/optimize: Remember garbage high bits for 32-bit ops
For a 64-bit host, the high bits of a register after a 32-bit operation
are undefined.  Adjust the temps mask for all 32-bit ops to reflect that.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:56 -07:00
Richard Henderson
a62f6f5600 tcg/optimize: Move updating of gen_opc_buf into tcg_opt_gen_mov*
No functional change, just reduce a bit of redundancy.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:56 -07:00
Richard Henderson
ae18b28dd1 tcg-sparc: Make debug_frame const
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:56 -07:00
Richard Henderson
d2e16f2ce1 tcg-s390: Make debug_frame const
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:55 -07:00
Richard Henderson
1695974187 tcg-arm: Make debug_frame const
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:55 -07:00
Richard Henderson
3d9bddb30b tcg-aarch64: Make debug_frame const
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:55 -07:00
Richard Henderson
e9a9a5b605 tcg-i386: Make debug_frame const
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:55 -07:00
Richard Henderson
2c90784abf tcg: Allow the debug_frame data structure to be constant
Adjust the FDE to point to the code_buffer after we've copied it
to the image, rather than requiring that the backend set it prior.
This allows the backend to use read-only storage for its data.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:55 -07:00
Richard Henderson
011209e19f tcg: Move size effects out of dh_arg
Tidying the initialization of the args arrays at the same time.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:55 -07:00
Richard Henderson
bbb8a1b455 tcg: Remove sizemask and flags arguments to tcg_gen_callN
Take them from the TCGHelperInfo struct instead.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:55 -07:00
Richard Henderson
afb49896fa tcg: Save flags and computed sizemask in TCGHelperInfo
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:54 -07:00
Richard Henderson
72866e823e tcg: Register the helper info struct rather than the name
This will let us find all the info from the hash table.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:54 -07:00
Richard Henderson
a5ed2de10a tcg: Move side effects out of dh_sizemask
Moving them into dh_arg instead.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:54 -07:00
Richard Henderson
836d6ed96e tcg: Inline tcg_gen_helperN
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:54 -07:00
Richard Henderson
c017230d9b tcg: Use helper-gen.h in tcg-op.h
No need to open-code the setup of the builtin helpers.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:54 -07:00
Richard Henderson
944eea962b tcg: Push tcg-runtime routines into exec/helper-*
Rather than special casing them, use the standard mechanisms
for tcg helper generation.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:54 -07:00
Richard Henderson
2ef6175aa7 tcg: Invert the inclusion of helper.h
Rather than include helper.h with N values of GEN_HELPER, include a
secondary file that sets up the macros to include helper.h.  This
minimizes the files that must be rebuilt when changing the macros
for file N.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:54 -07:00
Richard Henderson
a763551ad5 tcg: Optimize brcond2 and setcond2 ne/eq
If either the high or low pair can be resolved, we can
simplify to either a constant or to a 32-bit comparison.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-28 09:33:53 -07:00
Peter Crosthwaite
de77914e50 ssi: Name the CS GPIO
To get it out of the default GPIO list. This allows child devices to
use the un-named GPIO namespace without having to be SSI aware. That
is, there is no more need for machines to know about the obscure
policy where GPIO 0 is the SSI chip-select and GPIO 1..N are the
concrete class GPIOs (defined locally as 0..N-1).

This is most notable in stellaris, which uses a device which has both
SSI and concrete level GPIOs.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:36:21 +02:00
Peter Crosthwaite
a5f54290ce qdev: Implement named GPIOs
Implement named GPIOs on the Device layer. Listifies the existing GPIOs
stuff using string keys. Legacy un-named GPIOs are preserved by using
a NULL name string - they are just a single matchable element in the
name list.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:36:21 +02:00
Marcel Apfelbaum
6b1b144019 machine: Make -machine opts properties of MachineState
Make machine's QemuOpts QOM properties of /machine. The properties
are automatically filled in. This opens the possibility to create
opts per machine rather than global.

Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:36:13 +02:00
Marcel Apfelbaum
a199b2b6a5 tests: Check empty QMP output visitor
Checks the output visitor behaviour for NULL values.

Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:36:09 +02:00
Marcel Apfelbaum
1d10b44546 qapi: Avoid output visitor crashing if it encounters a NULL value
A NULL value is not added to visitor's stack, but there
is no check for that when the visitor tries to return
that value, leading to QEMU crash.

Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:36:04 +02:00
Marcel Apfelbaum
13d7adf92a vl.c: Do not set 'type' property in obj_set_property()
Filter out also 'type' property when setting
object's properties.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:35:59 +02:00
Marcel Apfelbaum
3ef9622182 machine: Conversion of QEMUMachineInitArgs to MachineState
Total removal of QEMUMachineInitArgs struct. QEMUMachineInitArgs's fields
are copied into MachineState. Removed duplicated fields from MachineState.

All the other changes are only mechanical refactoring, no semantic changes.

Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> (s390)
Reviewed-by: Michael S. Tsirkin <mst@redhat.com> (PC)
[AF: Renamed ms -> machine, use MACHINE_GET_CLASS()]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:35:01 +02:00
Cole Robinson
0380aef323 qom-test: Test qom-list on link<> properties
But don't test their properties, otherwise we will recurse forever.
Their properties are already tested when we encounter them as child<>
properties elsewhere in the hierarchy, like /machine/unattached/...

This would have caught the crash fixed by 92b3eead.

Signed-off-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-05-28 17:35:01 +02:00
Peter Maydell
3ee933c9d4 Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request

# gpg: Signature made Wed 28 May 2014 13:31:15 BST using RSA key ID 81AB73C8
# gpg: Can't check signature: public key not found

* remotes/stefanha/tags/block-pull-request: (33 commits)
  block/sheepdog: Don't use qerror_report()
  block/sheepdog: Fix silent sd_open(), sd_create() failures
  block/sheepdog: Propagate errors to open and create methods
  block/sheepdog: Propagate errors through find_vdi_name()
  block/sheepdog: Propagate errors through do_sd_create()
  block/sheepdog: Propagate errors through sd_prealloc()
  block/sheepdog: Propagate errors through get_sheep_fd()
  block/sheepdog: Propagate errors through connect_to_sdog()
  block/vvfat: Propagate errors through init_directories()
  block/vvfat: Propagate errors through enable_write_target()
  block/ssh: Propagate errors to open and create methods
  block/ssh: Propagate errors through connect_to_ssh()
  block/ssh: Propagate errors through authenticate()
  block/ssh: Propagate errors through check_host_key()
  block/ssh: Drop superfluous libssh2_session_last_errno() calls
  block/rbd: Propagate errors to open and create methods
  qemu-nbd: Don't use qerror_report()
  blockdev: Don't use qerror_report() in do_drive_del()
  blockdev: Don't use qerror_report_err() in drive_init()
  docs: Define refcount_bits value
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 15:22:40 +01:00
Peter Maydell
052367ba85 Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140527' into staging
target-arm:
 * Preliminary restructuring for EL2/EL3 support
 * improve CPACR handling
 * fix pxa2xx_lcd palette formats
 * update highbank/midway maintainer

# gpg: Signature made Tue 27 May 2014 17:26:27 BST using RSA key ID 14360CDE
# gpg: Can't check signature: public key not found

* remotes/pmaydell/tags/pull-target-arm-20140527: (26 commits)
  target-arm: A64: Register VBAR_EL3
  target-arm: A64: Register VBAR_EL2
  target-arm: Make vbar_write writeback to any CPREG
  target-arm: A64: Generalize update_spsel for the various ELs
  target-arm: A64: Generalize ERET to various ELs
  target-arm: A64: Trap ERET from EL0 at translation time
  target-arm: A64: Forbid ERET to higher or unimplemented ELs
  target-arm: Register EL3 versions of ELR and SPSR
  target-arm: Register EL2 versions of ELR and SPSR
  target-arm: Add a feature flag for EL3
  target-arm: Add a feature flag for EL2
  target-arm: A64: Introduce aarch64_banked_spsr_index()
  target-arm: Add SPSR entries for EL2/HYP and EL3/MON
  target-arm: A64: Add ELR entries for EL2 and 3
  target-arm: A64: Add SP entries for EL2 and 3
  target-arm: c12_vbar -> vbar_el[]
  target-arm: Make esr_el1 an array
  target-arm: Make elr_el1 an array
  target-arm: Use a 1:1 mapping between EL and MMU index
  target-arm: A32: Use get_mem_index for load/stores
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 15:00:33 +01:00
Peter Maydell
adbfc34103 Merge remote-tracking branch 'remotes/xtensa/tags/20140526-xtensa' into staging
Xtensa fixes queue 2014-05-26:
- fix cross-page jumps/calls at the end of TB;
- add tests for TBs and instructions crossing page boundary.

# gpg: Signature made Mon 26 May 2014 09:37:39 BST using RSA key ID F83FA044
# gpg: Can't check signature: public key not found

* remotes/xtensa/tags/20140526-xtensa:
  target-xtensa: add tests for cross-page TB
  target-xtensa: completely clean TLB between MMU tests
  target-xtensa: fix cross-page jumps/calls at the end of TB

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 14:47:35 +01:00
Peter Maydell
972b09c219 Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-7' into staging
usb: usb3 streams support for usb-host and usb-redir
usb: xhci and mtp bugfixes.

# gpg: Signature made Mon 26 May 2014 09:44:09 BST using RSA key ID D3E87138
# gpg: Can't check signature: public key not found

* remotes/kraxel/tags/pull-usb-7:
  usb-host-libusb: Set stream id when submitting bulk-stream transfers
  usb-host-libusb: Add alloc / free streams ops
  usb-host-libusb: Fill in endpoint max_streams when available
  usb-redir: Add support for bulk streams
  usb-mtp: handle usb_mtp_get_object failure
  usb-mtp: handle lseek failure
  usb-mtp: use bool to track MTPObject init status
  xhci: add xhci_get_flag
  xhci: add endpoint cap on express bus only
  xhci: child detach fix

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 13:52:03 +01:00
Markus Armbruster
fbab9ccbdb block/sheepdog: Don't use qerror_report()
qerror_report() is a transitional interface to help with converting
existing HMP commands to QMP.  It should not be used elsewhere.
Replace by error_report().

Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
efde4b6252 block/sheepdog: Fix silent sd_open(), sd_create() failures
Open and create methods must set an error when they fail.

Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
e67c399363 block/sheepdog: Propagate errors to open and create methods
Completes the conversion to Error started in commit 015a103^..d5124c0,
except for a few bugs fixed in the next commit.

Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
dc83cd427b block/sheepdog: Propagate errors through find_vdi_name()
Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
7d2d3e74e5 block/sheepdog: Propagate errors through do_sd_create()
Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
318df29e10 block/sheepdog: Propagate errors through sd_prealloc()
Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
356b4ca2bb block/sheepdog: Propagate errors through get_sheep_fd()
Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
dfb12bf86e block/sheepdog: Propagate errors through connect_to_sdog()
Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
d11c8917b2 block/vvfat: Propagate errors through init_directories()
Completes the conversion of the open method to Error started in commit
015a103.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
68c70af16d block/vvfat: Propagate errors through enable_write_target()
Continues the conversion of the open method to Error started in commit
015a103.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
5496fb1aeb block/ssh: Propagate errors to open and create methods
Completes the conversion to Error started in commit 015a103^..d5124c0.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
5f0c39e598 block/ssh: Propagate errors through connect_to_ssh()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
4618e658e6 block/ssh: Propagate errors through authenticate()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
01c2b265fc block/ssh: Propagate errors through check_host_key()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
04bc7c0e38 block/ssh: Drop superfluous libssh2_session_last_errno() calls
libssh2_session_last_error() already returns the error code.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
d61563b235 block/rbd: Propagate errors to open and create methods
Completes the conversion to Error started in commit 015a103^..d5124c0.

Cc: Josh Durgin <josh.durgin@inktank.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:47 +02:00
Markus Armbruster
3775ec6f5a qemu-nbd: Don't use qerror_report()
qerror_report() is a transitional interface to help with converting
existing HMP commands to QMP.  It should not be used elsewhere.
Replace by error_report().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Markus Armbruster
b1422f2040 blockdev: Don't use qerror_report() in do_drive_del()
qerror_report() is a transitional interface to help with converting
existing HMP commands to QMP.  It should not be used elsewhere.

do_drive_del() is an HMP command that won't be converted to QMP (we'll
create a new QMP command instead).  It uses both qerror_report() and
error_report().  Convert the former to the latter.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Markus Armbruster
e8817e7b0e blockdev: Don't use qerror_report_err() in drive_init()
qerror_report_err() is a transitional interface to help with
converting existing HMP commands to QMP.  It should not be used
elsewhere.

drive_init() is not meant to be used by QMP commands.  It uses both
qerror_report_err() and error_report().  Convert the former to the
latter.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Maria Kustova
6815bce542 docs: Define refcount_bits value
The 'refcount_bits' term used in the description of refcount block entry is
not defined in the specification. The definition is added in the
'refcount_order' section where refcount_bits was used as 'width in bits'.

Signed-off-by: Maria Kustova <maria.k@catit.be>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
ce782938b8 block: Drop redundant bdrv_refresh_limits
The above bdrv_set_backing_hd already does this.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
826b6ca0b0 block: Add backing_blocker in BlockDriverState
This makes use of op_blocker and blocks all the operations except for
commit target, on each BlockDriverState->backing_hd.

The asserts for op_blocker in bdrv_swap are removed because with this
change, the target of block commit has at least the backing blocker of
its child, so the assertion is not true. Callers should do their check.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
920beae103 block: Use bdrv_set_backing_hd everywhere
We need to handle the coming backing_blocker properly, so don't open
code the assignment, instead, call bdrv_set_backing_hd to change
backing_hd.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
8d24cce1e3 block: Add bdrv_set_backing_hd()
This is the common but non-trivial steps to assign or change the
backing_hd of BDS.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
628ff68303 block: Move op_blocker check from block_job_create to its caller
It makes no sense to check for "any" blocker on bs, we are here only
because of the mechanical conversion from in_use to op_blockers. Remove
it now, and let the callers check specific operation types. Backup and
mirror already have it, add checker to stream and commit.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
3718d8ab65 block: Replace in_use with operation blocker
This drops BlockDriverState.in_use with op_blockers:

  - Call bdrv_op_block_all in place of bdrv_set_in_use(bs, 1).

  - Call bdrv_op_unblock_all in place of bdrv_set_in_use(bs, 0).

  - Check bdrv_op_is_blocked() in place of bdrv_in_use(bs).

    The specific types are used, e.g. in place of starting block backup,
    bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP, ...).

    There is one exception in block_job_create, where
    bdrv_op_blocker_is_empty() is used, because we don't know the operation
    type here. This doesn't matter because in a few commits away we will drop
    the check and move it to callers that _do_ know the type.

  - Check bdrv_op_blocker_is_empty() in place of assert(!bs->in_use).

Note: there is only bdrv_op_block_all and bdrv_op_unblock_all callers at
this moment. So although the checks are specific to op types, this
changes can still be seen as identical logic with previously with
in_use. The difference is error message are improved because of blocker
error info.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
fbe40ff780 block: Introduce op_blockers to BlockDriverState
BlockDriverState.op_blockers is an array of lists with BLOCK_OP_TYPE_MAX
elements. Each list is a list of blockers of an operation type
(BlockOpType), that marks this BDS as currently blocked for a certain
type of operation with reason errors stored in the list. The rule of
usage is:

 * BDS user who wants to take an operation should check if there's any
   blocker of the type with bdrv_op_is_blocked().

 * BDS user who wants to block certain types of operation, should call
   bdrv_op_block (or bdrv_op_block_all to block all types of operations,
   which is similar to the existing bdrv_set_in_use()).

 * A blocker is only referenced by op_blockers, so the lifecycle is
   managed by caller, and shouldn't be lost until unblock, so typically
   a caller does these:

   - Allocate a blocker with error_setg or similar, call bdrv_op_block()
     to block some operations.
   - Hold the blocker, do his job.
   - Unblock operations that it blocked, with the same reason pointer
     passed to bdrv_op_unblock().
   - Release the blocker with error_free().

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
8574575f90 block: Add BlockOpType enum
This adds the enum of all the operations that can be taken on a block
device.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Max Reitz
0bf7488afb iotests: Use _img_info in test 089
Currently, test 089 uses $QEMU_IMG info manually in order to obtain the
according output. However, the iotests should generally use _img_info as
this filters out more irrelevant information such as the host image size
or format specific information. Therefore, test 089 should use _img_info
as well.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reported-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Fam Zheng
271c0f68b4 aio: Fix use-after-free in cancellation path
The current flow of canceling a thread from THREAD_ACTIVE state is:

  1) Caller wants to cancel a request, so it calls thread_pool_cancel.

  2) thread_pool_cancel waits on the conditional variable
     elem->check_cancel.

  3) The worker thread changes state to THREAD_DONE once the task is
     done, and notifies elem->check_cancel to allow thread_pool_cancel
     to continue execution, and signals the notifier (pool->notifier) to
     allow callback function to be called later. But because of the
     global mutex, the notifier won't get processed until step 4) and 5)
     are done.

  4) thread_pool_cancel continues, leaving the notifier signaled, it
     just returns to caller.

  5) Caller thinks the request is already canceled successfully, so it
     releases any related data, such as freeing elem->common.opaque.

  6) In the next main loop iteration, the notifier handler,
     event_notifier_ready, is called. It finds the canceled thread in
     THREAD_DONE state, so calls elem->common.cb, with an (likely)
     dangling opaque pointer. This is a use-after-free.

Fix it by calling event_notifier_ready before leaving
thread_pool_cancel.

Test case update: This change will let cancel complete earlier than
test-thread-pool.c expects, so update the code to check this case: if
it's already done, done_cb sets .aiocb to NULL, skip calling
bdrv_aio_cancel on them.

Reported-by: Ulrich Obergfell <uobergfe@redhat.com>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Kevin Wolf
bd60436936 qcow2: Fix memory leak in COW error path
This triggers if bs->drv becomes NULL in a concurrent request. This is
currently only the case when corruption prevention kicks in (i.e. at
most once per image, and after that it produces I/O errors).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:28:46 +02:00
Leandro Dorileo
4ba6fabfb4 QemuOpt: add unit tests
Cover basic aspects and API usage for QemuOpt. The current implementation
covers the API's planned to be changed by Chunyan Liu in his QEMUOptionParameter
replacement/cleanup job.

Other APIs should be covered in future improvements.

[Squashing in a small fix "QemuOpt: use qemu_find_opts_err() to avoid
output on stderr in tests".

qemu_find_opts() calls error_report() instead of propagating the Error
object.  It is undesirable to clutter test case output with error
messages from a passing test.

Use qemu_find_opts_err() to avoid the output on stderr.
--Stefan]

Signed-off-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:27:42 +02:00
Fam Zheng
7cf6376ae8 qemu-iotests: Handle cache mode option in 091
We should allow testing this on tmpfs. Any cache setting in iotests
should try to obey $CACHEMODE.

The cache mode is still "none" by default but overridable

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-05-28 14:22:25 +02:00
Peter Maydell
53651ec26b Merge remote-tracking branch 'remotes/kraxel/tags/pull-console-1' into staging
console: multiwindow support for text terminal QemuConsoles
console: small fixes

# gpg: Signature made Mon 26 May 2014 09:17:27 BST using RSA key ID D3E87138
# gpg: Can't check signature: public key not found

* remotes/kraxel/tags/pull-console-1:
  console: add kbd_put_keysym_console
  console: rework text terminal cursor logic
  console: update text terminal surface unconditionally
  console: nicer initial screen
  console: Abort on property access errors

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 12:36:25 +01:00
Peter Maydell
109519fd32 Merge remote-tracking branch 'remotes/kraxel/tags/pull-gtk-7' into staging
gtk: ui overhaul, multiwindow support.

# gpg: Signature made Mon 26 May 2014 08:54:55 BST using RSA key ID D3E87138
# gpg: Can't check signature: public key not found

* remotes/kraxel/tags/pull-gtk-7: (24 commits)
  gtk: workaround gtk2 vte resize issue
  gtk: window sizing overhaul
  gtk: zap unused global_state
  gtk: Add handling for the xfree86 keycodes
  gtk: enable untabify for gfx
  gtk: detached window pointer grabs
  gtk: update all windows on mouse mode changes
  gtk: fix grab checks
  gtk: update gd_update_caption
  gtk: skip keyboard grab when hover autograb is active
  gtk: keep track of grab owner
  gtk: add gd_grab trace event
  gtk: add tab to trace events
  gtk: allow moving tabs to windows and back.
  gtk: simplify resize
  gtk: use device type as label
  gtk: support multiple gfx displays
  gtk: move vga state into VirtualGfxConsole
  gtk: VirtualConsole restruction
  gtk: remove page numbering assumtions from the code
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 11:18:58 +01:00
Peter Maydell
4aa23452e3 Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-9' into staging
input: add event routing and multiseat support.
input: misc bugfixes and minor improvements.

# gpg: Signature made Mon 26 May 2014 07:44:29 BST using RSA key ID D3E87138
# gpg: Can't check signature: public key not found

* remotes/kraxel/tags/pull-input-9:
  docs: add multiseat.txt
  usb: add input routing support for tablet and keyboard
  sdl: pass key event source to input layer
  input: bind devices and input routing
  input: switch hid mouse and tablet to the new input layer api.
  input: switch hid keyboard to new input layer api.
  input: keymap: add meta keys
  input: add name to input_event_key_number
  input: add qemu_input_key_number_to_qcode
  input (curses): mask keycodes to remove modifier bits

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-28 10:33:05 +01:00
Peter Maydell
9474ab1487 Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-2014-05-26' into staging
trivial patches for 2014-05-26

# gpg: Signature made Mon 26 May 2014 08:17:08 BST using RSA key ID A4C3D7DB
# gpg: Can't check signature: public key not found

* remotes/mjt/tags/trivial-patches-2014-05-26: (23 commits)
  libcacard: remove useless initializers
  net: cadence_gem: Fix top comment
  bsd-user: replace fprintf(stderr, ...) with error_report()
  audio: replace fprintf(stderr, ...) with error_report() in audio
  libcacard: fix wrong array expansion logic
  libcacard/vcard_emul_nss: Drop a redundant conditional
  libcacard: Convert two leftover realloc() to GLib
  libcacard/vreader: Tighten assertion to clarify intent
  libcacard/vreader: Drop broken recovery from failed assertion
  libcacard: Plug memory leaks around vreader_get_reader_list()
  libcacard/vscclient: Bury some dead code
  vl: fix 'name' option to work with -readconfig
  configure: Put tempfiles in a subdir of the build directory
  dma-helpers: avoid calling dma_bdrv_unmap() twice
  arch_init: replace fprintf(stderr, ...) with error_report()
  pci: move dereferencing of root only after verifying valid root pointer
  jazz_led: Add missing break in switch case
  bswap.h: Rename ldl_p, stl_p, etc to ldl_he_p, stl_he_p, etc
  configure: Automatically select GTK+ 3.0 if GTK+ 2.0 is unavailable
  nbd: Miscellaneous typo fixes.
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 22:45:03 +01:00
Peter Maydell
2f21ff25c0 Merge remote-tracking branch 'remotes/mwalle/tags/lm32-semihosting/20140524' into staging
* remotes/mwalle/tags/lm32-semihosting/20140524:
  lm32: remove lm32_sys
  test: lm32: use semihosting for testing
  target-lm32: add semihosting support
  test: lm32: make test cases independent

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 22:11:25 +01:00
Peter Maydell
27aa948502 Merge remote-tracking branch 'remotes/rth/tcg-mips' into staging
* remotes/rth/tcg-mips: (24 commits)
  tcg-mips: Enable direct chaining of TBs
  tcg-mips: Simplify movcond
  tcg-mips: Simplify brcond2
  tcg-mips: Improve setcond eq/ne vs zeros
  tcg-mips: Simplify setcond2
  tcg-mips: Simplify brcond
  tcg-mips: Simplify setcond
  tcg-mips: Commonize opcode implementations
  tcg-mips: Improve add2/sub2
  tcg-mips: Hoist args loads
  tcg-mips: Fix subtract immediate range
  tcg-mips: Name the opcode enumeration
  tcg-mips: Use EXT for AND on mips32r2
  tcg-mips: Use T9 for TCG_TMP1
  tcg-mips: Introduce TCG_TMP0, TCG_TMP1
  tcg-mips: Rearrange register allocation
  tcg-mips: Convert to new_ldst
  tcg-mips: Convert to new qemu_l/st helpers
  tcg-mips: Move softmmu slow path out of line
  tcg-mips: Split large ldst offsets
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 18:31:02 +01:00
Edgar E. Iglesias
a1ba125c0c target-arm: A64: Register VBAR_EL3
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-24-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:55 +01:00
Edgar E. Iglesias
d42e3c26cd target-arm: A64: Register VBAR_EL2
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-23-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:54 +01:00
Edgar E. Iglesias
855ea66dd5 target-arm: Make vbar_write writeback to any CPREG
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-22-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:54 +01:00
Edgar E. Iglesias
61d4b215d1 target-arm: A64: Generalize update_spsel for the various ELs
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-21-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:54 +01:00
Edgar E. Iglesias
db6c3cd0e7 target-arm: A64: Generalize ERET to various ELs
Adds support for ERET to and from AArch64 EL2 and 3.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-20-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:54 +01:00
Edgar E. Iglesias
14c521d45e target-arm: A64: Trap ERET from EL0 at translation time
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-19-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:54 +01:00
Edgar E. Iglesias
7ab6c10d00 target-arm: A64: Forbid ERET to higher or unimplemented ELs
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-18-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:53 +01:00
Edgar E. Iglesias
81547d6630 target-arm: Register EL3 versions of ELR and SPSR
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-17-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:53 +01:00
Edgar E. Iglesias
3b685ba7bf target-arm: Register EL2 versions of ELR and SPSR
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-16-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:53 +01:00
Edgar E. Iglesias
1fe8141ed4 target-arm: Add a feature flag for EL3
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-15-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:53 +01:00
Edgar E. Iglesias
cca7c2f523 target-arm: Add a feature flag for EL2
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-14-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:52 +01:00
Edgar E. Iglesias
2a923c4dde target-arm: A64: Introduce aarch64_banked_spsr_index()
Add aarch64_banked_spsr_index(), used to map an Exception Level
to an index in the banked_spsr array.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-13-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:52 +01:00
Edgar E. Iglesias
28c9457df0 target-arm: Add SPSR entries for EL2/HYP and EL3/MON
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-12-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:52 +01:00
Edgar E. Iglesias
1b1742386c target-arm: A64: Add ELR entries for EL2 and 3
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-11-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:52 +01:00
Edgar E. Iglesias
73fb3b764b target-arm: A64: Add SP entries for EL2 and 3
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-10-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:52 +01:00
Edgar E. Iglesias
68fdb6c5b0 target-arm: c12_vbar -> vbar_el[]
No functional change.
Preparation for adding EL2 and 3 versions of this reg.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-9-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:51 +01:00
Edgar E. Iglesias
d81c519c40 target-arm: Make esr_el1 an array
No functional change.
Prepares for future addtion of EL2 and 3 versions of this reg.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-8-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:51 +01:00
Edgar E. Iglesias
6947f05978 target-arm: Make elr_el1 an array
No functional change.
Prepares for future additions of the EL2 and 3 versions of this reg.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-7-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:51 +01:00
Edgar E. Iglesias
f79fbf39e2 target-arm: Use a 1:1 mapping between EL and MMU index
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Message-id: 1400980132-25949-6-git-send-email-edgar.iglesias@gmail.com
Message-id: 1400805738-11889-7-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:51 +01:00
Edgar E. Iglesias
6ce2faf43c target-arm: A32: Use get_mem_index for load/stores
Avoid using IS_USER directly as the MMU-idx to simplify future
changes to the MMU layout.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1400980132-25949-5-git-send-email-edgar.iglesias@gmail.com
Message-id: 1400805738-11889-6-git-send-email-edgar.iglesias@gmail.com
[PMM: parts relating to LDRT/STRT moved into earlier patches]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:50 +01:00
Peter Maydell
c119779543 target-arm/translate.c: Use get_mem_index() for SRS memory accesses
The SRS instruction was using a hardcoded 0 for the memory
accesses. This happens to be OK since the SRS instruction is
UNPREDICTABLE in User and System modes, but is awkward if we
want to rearrange the MMU index uses. Switch to using
get_mem_index() like all the other accesses.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1400980132-25949-4-git-send-email-edgar.iglesias@gmail.com
2014-05-27 17:09:50 +01:00
Peter Maydell
a99caa48d8 target-arm/translate.c: Clean up mmu index handling for ldrt/strt
Clean up the mmu index handling for ldrt/strt insns: instead
of a flag 'user' indicating whether to treat the store as user
mode or not, use 'memidx' to indicate the correct memory index to use.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1400980132-25949-3-git-send-email-edgar.iglesias@gmail.com
2014-05-27 17:09:50 +01:00
Edgar E. Iglesias
9d4c4e872e target-arm: Move get_mem_index to translate.h
So that it can be shared with the AArch32 code.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1400980132-25949-2-git-send-email-edgar.iglesias@gmail.com
Message-id: 1400805738-11889-5-git-send-email-edgar.iglesias@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:50 +01:00
Fabian Aggeler
f0aff25570 target-arm: implement CPACR register logic for ARMv7
In ARMv7 the CPACR register allows to control access rights to
coprocessor 0-13 interfaces. Bits corresponding to unimplemented
coprocessors should be RAZ/WI. Bits ASEDIS, D32DIS, TRCDIS are
UNK/SBZP if VFP is not implemented and RAO/WI in some cases.
Treating TRCDIS as RAZ/WI since we neither implement a trace
macrocell nor a CP14 interface to the trace macrocell registers.

Since CPACR bits for VFP/Neon access are honoured with the CPACR_FPEN
bit in the TB flags, flushing the TLB is not necessary anymore.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Message-id: 1400532968-30668-1-git-send-email-aggelerf@ethz.ch
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:49 +01:00
Peter Maydell
fc37b7a0b0 hw/display/pxa2xx_lcd: Fix 16bpp+alpha and 18bpp+alpha palette formats
The pxa2xx palette entry "16bpp plus transparency" format is
xxxxxxxTRRRRR000GGGGGG00BBBBB000, and "18bpp plus transparency" is
xxxxxxxTRRRRRR00GGGGGG00BBBBBB00.

Correct errors in the code for reading these and converting
them to the internal format. In particular, the buggy code
was attempting to mask out bit 24 of a uint16_t, which
Coverity spotted as an error.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1400233901-31785-1-git-send-email-peter.maydell@linaro.org
2014-05-27 17:09:49 +01:00
Rob Herring
9ef137cad6 MAINTAINERS: update Calxeda Highbank maintainer and status
Signed-off-by: Rob Herring <rob.herring@linaro.org>
Message-id: 1400116198-3155-1-git-send-email-robherring2@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 17:09:49 +01:00
Peter Maydell
93f94f9018 Merge remote-tracking branch 'remotes/rth/fix-tci' into staging
* remotes/rth/fix-tci:
  tci: Fix tcg_out_call

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 14:44:04 +01:00
Christoffer Dall
00d0f7cb66 target-arm: Fix segfault on startup when KVM enabled
Commit 50a2c6e55f introduced a bug where QEMU would segfault on startup
when using KVM on ARM hosts, because kvm_arm_reset_cpu() accesses
cpu->cpreg_reset_values, which is not allocated before
kvm_arch_init_vcpu(). Fix this by not calling cpu_reset() until after
qemu_init_vcpu().

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Faerber <afaerber@suse.de>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1401194263-13010-1-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-27 13:55:39 +01:00
Max Filippov
57a740514d target-xtensa: add tests for cross-page TB
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-05-26 12:33:54 +04:00
Max Filippov
ca3164df4d target-xtensa: completely clean TLB between MMU tests
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-05-26 12:33:54 +04:00
Max Filippov
433d33c555 target-xtensa: fix cross-page jumps/calls at the end of TB
Use tb->pc instead of dc->pc to check for cross-page jumps.
When TB translation stops at the page boundary dc->pc points to the next
page allowing chaining to TBs in it, which is wrong.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-05-26 12:33:54 +04:00
Gerd Hoffmann
8977bd111f docs: add multiseat.txt
Howto on setting up multiseat for guests.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:43 +02:00
Gerd Hoffmann
f85d28316a usb: add input routing support for tablet and keyboard
Add display property to the keyboard.
Add display and head properties to the tablet.

If properties are set bind device to the display specified to
setup input routing.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:43 +02:00
Gerd Hoffmann
ee8c0b622c sdl: pass key event source to input layer
So the input layer knows where the input is coming from
and input routing works correctly.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:43 +02:00
Gerd Hoffmann
6f5943cf45 input: bind devices and input routing
Add function to bind input devices to display devices.  Implementing
input routing on top of this:  Events coming from the display device in
question are routed to the input device bound to it (if there is one).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:43 +02:00
Gerd Hoffmann
8b84286f4c input: switch hid mouse and tablet to the new input layer api.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:43 +02:00
Gerd Hoffmann
1ff5eedd1d input: switch hid keyboard to new input layer api.
Minimal patch to get the switchover done.  We continue processing ps/2
scancodes for now as they are part of the live migration stream.  Fixing
that, then mapping directly from QKeyValue to HID keycodes is left as
excercise for another day.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:43 +02:00
Gerd Hoffmann
86846bfe64 input: keymap: add meta keys
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:43 +02:00
Gerd Hoffmann
2386a90730 input: add name to input_event_key_number
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:42 +02:00
Gerd Hoffmann
11c7fa7fa6 input: add qemu_input_key_number_to_qcode
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:42 +02:00
Andrew Oates
f5c0ab1312 input (curses): mask keycodes to remove modifier bits
Without the mask, control bits are passed on in the keycode, generating
incorrect PS/2 sequences when SHIFT, ALT, etc are held down.

Cc: qemu-stable@nongnu.org
Signed-off-by: Andrew Oates <andrew@aoates.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:42:42 +02:00
Michael Tokarev
1687a089f1 libcacard: remove useless initializers
libcacard has many functions which initializes local variables
at declaration time, which are always assigned some values later
(often right after declaration).  Clean up these initializers.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-26 10:41:22 +04:00
Peter Crosthwaite
116d554601 net: cadence_gem: Fix top comment
To indicate Cadence GEM not Xilinx.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-26 10:41:22 +04:00
Le Tan
1fba509527 bsd-user: replace fprintf(stderr, ...) with error_report()
Replace fprintf(stderr,...) with error_report() in files bsd-user/*.
The trailing "\n"s of the @fmt argument have been removed
because @fmt of error_report() should not contain newline.

Signed-off-by: Le Tan <tamlokveer@gmail.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-26 10:41:22 +04:00
Le Tan
69e995040c audio: replace fprintf(stderr, ...) with error_report() in audio
Replace fprintf(stderr,...) with error_report() in files audio/*.
The trailing "\n"s of the @fmt argument have been removed
because @fmt of error_report() should not contain newline.

Signed-off-by: Le Tan <tamlokveer@gmail.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-26 10:41:21 +04:00
Hans de Goede
8d1bd3c901 usb-host-libusb: Set stream id when submitting bulk-stream transfers
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Hans de Goede
56a9f18051 usb-host-libusb: Add alloc / free streams ops
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Hans de Goede
b664b80f19 usb-host-libusb: Fill in endpoint max_streams when available
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Hans de Goede
19e8393170 usb-redir: Add support for bulk streams
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Gerd Hoffmann
22513a9b44 usb-mtp: handle usb_mtp_get_object failure
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Gerd Hoffmann
68206d7342 usb-mtp: handle lseek failure
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Gerd Hoffmann
36084d7e31 usb-mtp: use bool to track MTPObject init status
Stop setting nchildren to -1.  Use separate bool variable to track
whenever we've already fetched the child objects instead.

Also make nchildren unsigned.

Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Gerd Hoffmann
f995523582 xhci: add xhci_get_flag
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Gerd Hoffmann
058fdcf52c xhci: add endpoint cap on express bus only
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:07 +02:00
Gerd Hoffmann
463c534db5 xhci: child detach fix
xhci_child_detach() zaps the wrong slot when unplugging a device
connected via usb-hub:  Instead of the device's slot the slot of the
usb-hub is used.  Fix it.

https://bugzilla.redhat.com/show_bug.cgi?id=1075846

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
2014-05-26 08:41:07 +02:00
Gerd Hoffmann
6fa2769751 gtk: workaround gtk2 vte resize issue
Hack isn't pretty, but gets the job done.
See source code comment for details.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:04 +02:00
Gerd Hoffmann
82fc18099a gtk: window sizing overhaul
Major overhaul for window size handling.  This basically switches qemu
over to use geometry hints for the window manager instead of trying to
get the job done with widget resize requests.  This allows to specify
better what we need and also avoids window resizes.

FIXME: on gtk2 someone overwrites the geometry hints :(

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:04 +02:00
Gerd Hoffmann
0f61a61df3 gtk: zap unused global_state
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:04 +02:00
Bruce Rogers
3158a3482b gtk: Add handling for the xfree86 keycodes
Currently only evdev keycodes are handled by the gtk-ui. SDL has
code to handle both. This patch adds similar processing so that
both keycode types will be handled via the gtk-ui.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:04 +02:00
Gerd Hoffmann
aa0a55d42d gtk: enable untabify for gfx
Now we have all grab fixes in place, so we can allow detaching
graphic display tabs too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:04 +02:00
Gerd Hoffmann
0c77a37f11 gtk: detached window pointer grabs
Make ungrab hotkey work with detached windows.
Enable pointer grabs for detached windows.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:04 +02:00
Gerd Hoffmann
99623c90d1 gtk: update all windows on mouse mode changes
We might have multiple graphic displays now which all need a cursor update.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
2884cf5b93 gtk: fix grab checks
Make it handle multiple windows case correctly.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
4eeaa3a885 gtk: update gd_update_caption
Adapt to recent changes, handle multiple windows.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
746b867030 gtk: skip keyboard grab when hover autograb is active
It's pointless.  With grab on hover enabled the keyboard grab
is already active when you press Ctrl-Alt-G ;)

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
4c638e2e4b gtk: keep track of grab owner
Simplifies grab state tracking and makes ungrab more reliable.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
1c856da57b gtk: add gd_grab trace event
Input grab code is tricky, add some debug & trouble shooting aid.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
74444bc198 gtk: add tab to trace events
So you can see which of multiple displays (if present) was resized ;)

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
cdeb7090ee gtk: allow moving tabs to windows and back.
"View->Detach tab" will move to tab to a new window.
Simply closing the window will move it back into a notebook tab.
The label will be permamently stored in VirtualConsole->label,
so it can easily be reused to (re-)label tabs and windows.

Works for vte tabs only for now. pointer/kbd grab code needs
adaptions before we can enable it for gfx tabs too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
d3ef575080 gtk: simplify resize
Simply ask for a small window size.  When the widgets don't fit in gtk
will automatically make the window large enougth to make things fit, no
need to try (and fail) duplicate that logic in qemu.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
6a24ced5ca gtk: use device type as label
IMO useful than showing VGA for any graphic device
even in case it is something completely different.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
ed1132e41a gtk: support multiple gfx displays
Each display gets its own tab.  Tab switching continues to work like it
did, just the hotkeys of the vte consoles changes in case a secondary
display is present as it will get ctrl-alt-2 assigned and the vtes are
shifted by one.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
e3500d1f5f gtk: move vga state into VirtualGfxConsole
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
271a25c0b6 gtk: VirtualConsole restruction
Move all vte-related items into VirtualVteConsole substruct.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
832189c9b1 gtk: remove page numbering assumtions from the code
Lookup page numbers using gtk_notebook_page_num() instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Cole Robinson
0fb20d1c39 gtk: Add a scrollbar for text consoles
Only show the scrollbar if the content doesn't fit on the visible space.

[ kraxel: fix box packing ]

Signed-off-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
ee5f31e48b gtk: cleanup CONFIG_VTE ifdef a bit.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
6fe83074d7 gtk: zap vte size requests
The vte tabs simply get the size of the vga tab then, with whatever
cols and lines are fitting in.  I find this bahavior more useful than
resizing the qemu window all day long.

YMMV.  Comments are welcome.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:03 +02:00
Gerd Hoffmann
3f9a6e852e console: add kbd_put_keysym_console
So you can send keysyms to a specific (text terminal) console.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:02 +02:00
Gerd Hoffmann
fd07d07ba9 gtk: zap scrolled_window
The vte widget implements the scrollable interface, placing it into
a scrolled window is pointless and creates a bunch of strange effects.
Zap it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:02 +02:00
Gerd Hoffmann
aea7947c74 console: rework text terminal cursor logic
Have a global timer.  Update all visible terminal windows syncronously.
Right now this can be the active_console only, but that will change
soon.  The global timer will disable itself if not needed, so we only
have to care start it if needed.  Which might be at console switch time
or when a new displaychangelistener is registered.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:02 +02:00
Gerd Hoffmann
b35e3ba01a console: update text terminal surface unconditionally
These days each QemuConsole has its own private DisplaySurface,
so we can simply render updates all the time.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:02 +02:00
Gerd Hoffmann
521a580d23 console: nicer initial screen
Now that we have a function to create a fancy DisplaySurface with a
message for the user, to handle non-existing graphics hardware, we
can make it more generic and use it for other things too.

This patch adds a text line to the in initial DisplaySurface, notifying
the user that the display isn't initialized yet by the guest.

You can see this in action when starting qemu with '-S'.  Also when
booting ovmf in qemu (which needs a few moments to initialize itself
before it initializes the vga).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:02 +02:00
Kirill Batuzov
afff2b15e8 console: Abort on property access errors
All defined properties of QemuConsole are mandatory and no access to them
should fail. Nevertheless not checking returned errors is bad because in case
of unexpected failure it will hide the bug and cause a memory leak.

Abort in case of unexpected property access errors. This change exposed a bug
where an attempt was made to write to a read-only property "head".

Set "head" property's value at creation time and do not attempt to change it
later. This fixes the bug mentioned above.

Signed-off-by: Kirill Batuzov <batuzovk@ispras.ru>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-26 08:41:02 +02:00
Michael Tokarev
d09b8fa161 libcacard: fix wrong array expansion logic
The currrent code in libcacard/vcard_emul_nss.c:vcard_emul_options()
has a weird bug in variable usage around expanding opts->vreader
array.

There's a helper variable, vreaderOpt, which is first needlessly
initialized to NULL, next, conditionally, only we have to expand
opts->vreader, receives array expansion from g_renew(), and next,
even if we don't actually perform expansion, the value of this
variable is assigned to the actual array, opts->vreader, which
was supposed to be expanded.

So, since we expand the array by READER_STEP increments, only
once in READER_STEP (=4) the code will work, in other 3/4 times
it will fail badly.

Fix this by not using this temp variable when expanding the
array, and by dropping the useless =NULL initializer too -
if it wasn't in place initially, compiler would have warned
us about this problem at the beginning.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
2014-05-26 10:40:04 +04:00
Michael Walle
25156d1061 lm32: remove lm32_sys
Since we have now semihosting on the lm32 target, this device is no longer
needed. Remove it.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-05-24 19:43:52 +02:00
Michael Walle
4e7d30a22a test: lm32: use semihosting for testing
Instead of the lm32-sys device, use semihosting to print to the host
console and exit the test.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-05-24 19:42:29 +02:00
Michael Walle
f7bbcfb5c3 target-lm32: add semihosting support
Intercept certain system calls if semihosting is enabled. This should
behave like the GDB simulator.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-05-24 19:42:29 +02:00
Michael Walle
a946ce8020 test: lm32: make test cases independent
Make test cases independent from from each other. Eg. if a test case needs
a specific value in register A, don't rely on the fact that it is already
set by the preceding test case.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-05-24 19:42:29 +02:00
Richard Henderson
b6bfeea92a tcg-mips: Enable direct chaining of TBs
Now that the code_gen_buffer is constrained to not cross 256mb
regions, we are assured that we can use J to reach another TB.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:48:37 -07:00
Richard Henderson
33fac20bb2 tcg-mips: Simplify movcond
Use the same table to fold comparisons as with setcond.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:47:14 -07:00
Richard Henderson
3401fd259e tcg-mips: Simplify brcond2
Emitting a single branch instead of (up to) 3, using setcond2
to generate the composite compare.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:47:08 -07:00
Richard Henderson
1db1c4d7d9 tcg-mips: Improve setcond eq/ne vs zeros
The original code results in one too many insns per zero
present in the input.  And since comparing 64-bit numbers
vs zero is common...

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:58 -07:00
Richard Henderson
9a2f0bfe32 tcg-mips: Simplify setcond2
Using tcg_unsigned_cond and tcg_high_cond.
Also, move the function up in the file for future cleanups.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:53 -07:00
Richard Henderson
c068896f7f tcg-mips: Simplify brcond
Use the same table to fold comparisons as with setcond.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:49 -07:00
Richard Henderson
fd1cf66630 tcg-mips: Simplify setcond
Use a table to fold comparisons to less-than.
Also, move the function up in the file for futher simplifications.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:39 -07:00
Richard Henderson
4f048535cd tcg-mips: Commonize opcode implementations
Most opcodes fall in to one of a couple of patterns.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:32 -07:00
Richard Henderson
741f117d9a tcg-mips: Improve add2/sub2
Reduce insn count from 5 to either 3 or 4.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:25 -07:00
Richard Henderson
22ee3a987d tcg-mips: Hoist args loads
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:20 -07:00
Richard Henderson
070603f62b tcg-mips: Fix subtract immediate range
Since we must use ADDUI, we would generate incorrect code for -32768.
Leaving off subtract of +32768 makes things easier for a follow-on patch.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:08 -07:00
Richard Henderson
ac0f3b1263 tcg-mips: Name the opcode enumeration
And use it in the opcode emission functions.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:46:03 -07:00
Richard Henderson
1c4182687e tcg-mips: Use EXT for AND on mips32r2
At the same time, tidy deposit by introducing tcg_out_opc_bf.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:56 -07:00
Richard Henderson
f216a35f36 tcg-mips: Use T9 for TCG_TMP1
T0 is an argument register for the n32 and n64 abis.  T9 is the call
address register for the abis, and is more directly under the control
of the backend.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:48 -07:00
Richard Henderson
6c530e32f4 tcg-mips: Introduce TCG_TMP0, TCG_TMP1
Use these instead of hard-coding the registers to use for temporaries.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:44 -07:00
Richard Henderson
418839044e tcg-mips: Rearrange register allocation
Use FP (also known as S8) as a normal call-saved register.

Include T0 in the allocation order and call-clobbered list
even though it's currently used as a TCG temporary.

Put the argument registers at the end of the allocation order.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:28 -07:00
Richard Henderson
fbef2cc80f tcg-mips: Convert to new_ldst
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:24 -07:00
Richard Henderson
ce0236cfbd tcg-mips: Convert to new qemu_l/st helpers
In addition, fill delay slots calling the helpers and tail
call to the store helpers.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:20 -07:00
Richard Henderson
9d8bf2d125 tcg-mips: Move softmmu slow path out of line
At the same time, tidy up the call helpers, avoiding a memory reference.
Split out several subroutines.  Use TCGMemOp constants.  Make endianness
selectable at runtime.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:16 -07:00
Richard Henderson
f9a716325f tcg-mips: Split large ldst offsets
Use this to reduce goto_tb by one insn.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:13 -07:00
Richard Henderson
7dae901d2d tcg-mips: Fill the exit_tb delay slot
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:09 -07:00
Richard Henderson
f8c9eddb2b tcg-mips: Use J and JAL opcodes
For userland builds calls will normally be in range,
and for the exit_tb opcode the branch to the epilogue.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:05 -07:00
Richard Henderson
483c76e140 tcg-mips: Constrain the code_gen_buffer to be within one 256mb segment
This assures us use of J for exit_tb and goto_tb, and JAL for calling
into the generated bswap helpers.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:45:00 -07:00
Richard Henderson
479eb12108 tcg-mips: Layout executable and code_gen_buffer
Choosing good addresses for them means we can use JAL for helper calls.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-24 08:44:44 -07:00
Markus Armbruster
42119fa356 libcacard/vcard_emul_nss: Drop a redundant conditional
Bailing out when PK11_FindGenericObjects() returns null ensures the
loop that follows it executes at least once.  The "loop did not
execute" test right after it is useless.  Drop it.

Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:46:37 +04:00
Markus Armbruster
26b78f4d3c libcacard: Convert two leftover realloc() to GLib
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:46:20 +04:00
Markus Armbruster
f33a984d51 libcacard/vreader: Tighten assertion to clarify intent
Bonus: hushes up Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:46:11 +04:00
Markus Armbruster
fa5912a17b libcacard/vreader: Drop broken recovery from failed assertion
We suppress some code when we got unexpected status and assertion
checking is off:

     assert(card_status == VCARD_DONE);
     if (card_status == VCARD_DONE) {
         int size = MIN(*receive_buf_len, response->b_total_len);
         memcpy(receive_buf, response->b_data, size);
         *receive_buf_len = size;
    }

Such "recovery" is of dubious value even when it works.  This one
doesn't: it fails to assign to receive_buf[] and *receive_buf_len,
which the callers expect.

Make the code unconditional.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:46:01 +04:00
Markus Armbruster
124fe7fb1b libcacard: Plug memory leaks around vreader_get_reader_list()
Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:45:57 +04:00
Markus Armbruster
d357e3d9d2 libcacard/vscclient: Bury some dead code
Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:45:49 +04:00
Dr. David Alan Gilbert
5b9d313e3f vl: fix 'name' option to work with -readconfig
The 'name' option silently failed when used in config files
( http://lists.gnu.org/archive/html/qemu-devel/2014-04/msg00378.html )

-readconfig stores the configuration read in QemuOpts.  Command line
option parsing should do the same, and no more.  In particular it should
not act upon the option.  That needs to be done separately, where both
command line and -readconfig settings are visible in QemuOpts.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reported-by: William Dauchy <william@gandi.net>
Tested-by: William Dauchy <william@gandi.net>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(mjt: added commit message by ambru@ and subject prefix)
2014-05-24 00:44:12 +04:00
Peter Maydell
8cd05ab65a configure: Put tempfiles in a subdir of the build directory
When libtool support was added to configure, the new temporary files
were left out of the list of files cleaned up on exit; this results
in a lot of stale .lo files being left around in /tmp. Worse, libtool
creates a /tmp/.libs directory which we can't easily clean up.

Put all our temporary files in a single temporary directory created
as a subdirectory of the build directory, so we can easily clean it up,
and don't need fragile or complicated code for creation to avoid it
clashing with temporary directories from other instances of QEMU
configure or being subject to attack from adversaries who can write
to /tmp.

Since the temporaries now live in the build tree, we have no
need to jump through hoops with a trap handler to try to remove
them when configure exits; this fixes some weird bugs where hitting
^C during a configure run wouldn't actually make it stop, because
we would run the trap handler but then not stop. (It is possible
to get the trap handler semantics right but it is convoluted largely
because of bugs in dash, so it is simpler to just avoid it.)

Note that "temporary files go in the build directory, not /tmp" is
the way autoconf behaves.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:34:38 +04:00
Jules Wang
9c132c7f64 dma-helpers: avoid calling dma_bdrv_unmap() twice
Calling dma_bdrv_unmap() twice is not necessary and may cause
potential problems if some code changes.

Signed-off-by: Jules Wang <junqing.wang@cs2c.com.cn>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:28:43 +04:00
Le Tan
0971f1bed2 arch_init: replace fprintf(stderr, ...) with error_report()
Replace fprintf(stderr,...) with error_report() in the file
arch_init.c. The trailing "\n"s of the @fmt argument have been removed
because @fmt of error_report() should not contain newline.

Signed-off-by: Le Tan <tamlokveer@gmail.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:10:42 +04:00
Saravanakumar
b645000e1a pci: move dereferencing of root only after verifying valid root pointer
Signed-off-by: Saravanakumar <saravanakumar.punith@gmail.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:10:29 +04:00
Saravanakumar
e35f29ded3 jazz_led: Add missing break in switch case
Signed-off-by: Saravanakumar <saravanakumar.punith@gmail.com>
Reviewed-by: Paolo Bonizni <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:07:56 +04:00
Peter Maydell
1a3de8dbec bswap.h: Rename ldl_p, stl_p, etc to ldl_he_p, stl_he_p, etc
We have an unfortunate naming clash between the functions
ldl_p, stl_p, etc defined in bswap.h (which have semantics
"load/store in host endianness") and the #defines of the same
name in cpu-all.h (which have the semantics "load/store in
target endianness").

Fortunately it turns out that the only users of the bswap.h
functions are all within bswap.h itself, so we can simply
rename them to include a _he_ infix for "host endianness".

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:07:29 +04:00
Stefan Weil
9e04c683fc configure: Automatically select GTK+ 3.0 if GTK+ 2.0 is unavailable
The configure option --with-gtkabi=3.0 is still supported, but no longer
needed when GTK+-2.0 is missing. When no GTK+ ABI is selected by the
user, configure first tries 2.0, then 3.0.

For some platforms (e.g. Windows) newer binaries of GTK+ are only
available for GTK+ 3.0. Now building on these platforms is a little bit
easier.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:07:29 +04:00
Hani Benhabiles
5672ee54d5 nbd: Miscellaneous typo fixes.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:07:29 +04:00
Hani Benhabiles
36af599417 nbd: Close socket on negotiation failure.
Otherwise, the nbd client may hang waiting for the server response.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:07:29 +04:00
Peter Maydell
aef553fdca iohandler.c: Properly initialize sigaction struct
The code in qemu_init_child_watch() wasn't clearing the 'struct
sigaction' before passing it to sigaction(); this meant that we
would block a random set of signals while executing the SIGCHLD
handler. Initialize properly by using memset() on the struct,
as we do in similar cases elsewhere.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-05-24 00:07:29 +04:00
Michael Tokarev
78a4b8d205 libcacard: g_malloc cleanups
This patch replaces g_malloc() in libcacard into g_new()
or g_new0() where appropriate (removing some init-to-zero
surrounding code), g_malloc+memcpy into g_memdup() and the
like.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
2014-05-24 00:07:29 +04:00
Richard Henderson
a3abb29292 tci: Fix tcg_out_call
Broken since dddbb2e1e3.
Do all the rest of the things that tcg_out_op did before
and after the big switch statement.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-22 13:25:34 -07:00
Peter Maydell
178ac111bc Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging
* remotes/qmp-unstable/queue/qmp:
  qapi: zero-initialize all QMP command parameters
  scripts/qapi.py: Avoid syntax not supported by Python 2.4
  doc: add "setup" to list of migration states

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-22 19:04:49 +01:00
Peter Maydell
6054d883d6 Merge remote-tracking branch 'remotes/kraxel/tags/pull-chardev-2' into staging
purge error_is_set()

# gpg: Signature made Wed 21 May 2014 11:43:44 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-chardev-2:
  error: error_is_set() is finally unused; remove
  char: Explain qmp_chardev_add()'s unusual error handling
  char: Clean up fragile use of error_is_set()
  char: Use return values instead of error_is_set(errp)
  qemu-socket: Clean up inet_connect_opts()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-22 18:14:01 +01:00
Peter Maydell
5118dc5975 Merge remote-tracking branch 'remotes/kraxel/tags/pull-audio-5' into staging
audio: two intel-hda fixes.

# gpg: Signature made Wed 21 May 2014 09:49:39 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-audio-5:
  hw/audio/intel-hda: Avoid shift into sign bit
  audio/intel-hda: support FIFORDY

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-22 17:05:36 +01:00
Peter Maydell
45e66b7beb Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20140520' into staging
some s390 patches:

- Enable irqfds on s390 via the new adapter interrupt routing type.
  As a prereq, fix the kvm enable_cap helpers for some compilers and
  split the s390 flic into kvm and non-kvm parts.
- Enable software and hardware debugging support on s390. This needs a
  kernel headers update.

# gpg: Signature made Tue 20 May 2014 12:30:54 BST using RSA key ID C6F02FAF
# gpg: Can't check signature: public key not found

* remotes/cohuck/tags/s390x-20140520:
  s390x/kvm: hw debugging support via guest PER facility
  s390x/kvm: software breakpoint support
  s390x: remove duplicate definitions of DIAG 501
  linux-headers: update
  s390x/virtio-ccw: wire up irq routing and irqfds
  s390x/virtio-ccw: reference-counted indicators
  s390x: add I/O adapter registration
  s390x: split flic into kvm and non-kvm parts
  kvm: Fix enable_cap helpers on older gcc

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-22 16:14:02 +01:00
Peter Maydell
65903a8b08 Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging
* remotes/bonzini/scsi-next:
  megasas: remove buildtime strings
  block: iscsi build fix if LIBISCSI_FEATURE_IOVECTOR is not defined
  virtio-scsi: Plug memory leak on virtio_scsi_push_event() error path
  scsi: Document intentional fall through in scsi_req_length()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-22 15:27:46 +01:00
Michael Roth
fc13d93726 qapi: zero-initialize all QMP command parameters
In general QMP command parameter values are specified by consumers of the
QMP/HMP interface, but in the case of optional parameters these values may
be left uninitialized.

It is considered a bug for code to make use of optional parameters that have
not been flagged as being present by the marshalling code (via corresponding
has_<parameter> parameter), however our marshalling code will still pass
these uninitialized values on to the corresponding QMP function (to then
be ignored). Some compilers (clang in particular) consider this unsafe
however, and generate warnings as a result. As reported by Peter Maydell:

  This is something clang's -fsanitize=undefined spotted. The
  code generated by qapi-commands.py in qmp-marshal.c for
  qmp_marshal_* functions where there are some optional
  arguments looks like this:

      bool has_force = false;
      bool force;

      mi = qmp_input_visitor_new_strict(QOBJECT(args));
      v = qmp_input_get_visitor(mi);
      visit_type_str(v, &device, "device", errp);
      visit_start_optional(v, &has_force, "force", errp);
      if (has_force) {
          visit_type_bool(v, &force, "force", errp);
      }
      visit_end_optional(v, errp);
      qmp_input_visitor_cleanup(mi);

      if (error_is_set(errp)) {
          goto out;
      }
      qmp_eject(device, has_force, force, errp);

  In the case where has_force is false, we never initialize
  force, but then we use it by passing it to qmp_eject.
  I imagine we don't then actually use the value, but clang
  complains in particular for 'bool' variables because the value
  that ends up being loaded from memory for 'force' is not either
  0 or 1 (being uninitialized stack contents).

Fix this by initializing all QMP command parameters to {0} in the
marshalling code prior to passing them on to the QMP functions.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-21 09:25:31 -04:00
Luiz Capitulino
3478881130 scripts/qapi.py: Avoid syntax not supported by Python 2.4
The Python "except Foo as x" syntax was only introduced in
Python 2.6, but we aim to support Python 2.4 and later.
Use the old-style "except Foo, x" syntax instead, thus
fixing configure/compile on systems with older Python.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Andreas Färber <andreas.faerber@web.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-21 09:04:03 -04:00
Markus Armbruster
d2e064a73e error: error_is_set() is finally unused; remove
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-21 11:57:58 +02:00
Markus Armbruster
3894c78764 char: Explain qmp_chardev_add()'s unusual error handling
Character backend open hasn't been fully converted to the Error API.
Some opens fail without setting an error.  qmp_chardev_add() needs to
detect when that happens, and set a generic error.  Explain that in a
comment, and inline error_is_set() for clarity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-21 11:57:58 +02:00
Markus Armbruster
0aff637e92 char: Clean up fragile use of error_is_set()
Using error_is_set(ERRP) to find out whether a function failed is
either wrong, fragile, or unnecessarily opaque.  It's wrong when ERRP
may be null, because errors go undetected when it is.  It's fragile
when proving ERRP non-null involves a non-local argument.  Else, it's
unnecessarily opaque (see commit 84d18f0).

The error_is_set(errp) in qemu_chr_new_from_opts() is merely fragile,
because the callers never pass a null errp argument.

Make the code more robust and more obviously correct: receive the
error in a local variable, then propagate it through the parameter.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-21 11:57:58 +02:00
Markus Armbruster
5f758366c0 char: Use return values instead of error_is_set(errp)
Using error_is_set(errp) to check whether a function call failed is
fragile: it breaks when errp is null.  Check perfectly suitable return
values instead when possible.  As far as I can tell, errp can't be
null there, but this is more robust and more obviously correct

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-21 11:57:57 +02:00
Markus Armbruster
3f9286b721 qemu-socket: Clean up inet_connect_opts()
Separate the search for a working addrinfo from the code that does
something with it.  Makes for a clearer search loop.

Use a local Error * to simplify resetting the error in the search
loop.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-21 11:57:57 +02:00
Peter Feiner
3b69595068 doc: add "setup" to list of migration states
On a slow VM (e.g., nested), you see the "setup" state when you query the
migration status.

Signed-off-by: Peter Feiner <peter@gridcentric.ca>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-20 14:39:19 -04:00
Olaf Hering
5a7733b0b7 megasas: remove buildtime strings
Using __DATE__ or __TIME__ in binary pkgs changes the checksum of
compiled binaries if they get rebuilt, even if there are no other
source changes.  Replace the dynamic strings with some equally
informative static strings.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-20 16:14:29 +02:00
David Hildenbrand
770a63792b s390x/kvm: hw debugging support via guest PER facility
This patch makes use of the hw debugging support in kvm (provided by the guest's
PER facility) on s390. It enables the following features, available using the
gdbserver:
- single-stepping
- hw breakpoints
- hw watchpoints

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:58 +02:00
David Hildenbrand
b30f4dfbda s390x/kvm: software breakpoint support
This patch allows to insert and remove sw breakpoints using the QEMU gdbserver
on s390 as well as to interrupt execution on a breakpoint hit when running
with KVM enabled.

Whenever a software breakpoint is inserted, common code calls kvm ioctl
KVM_UPDATE_GUEST_DEBUG. As this method's default on s390 is to return an error
if not implement, the insertion will fail. Therefore, KVM also has to be
updated in order to make use of software breakpoints.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:58 +02:00
David Hildenbrand
8e4e86afa5 s390x: remove duplicate definitions of DIAG 501
When restoring the previously saved instruction in
kvm_arch_remove_sw_breakpoint(), we only restored one byte. Let's use
the sizeof() operator to make sure we restore the entire instruction.

While we are at it, let's remove the duplicate definitions of DIAG 501
and replace its size (used when reading/writing the instruction) with
a sizeof() operator to make the code self explaining and less error-prone.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:58 +02:00
Jens Freimann
76eb98d51c linux-headers: update
Sync linux-headers with kvm/next (87c00572ba05aa8c9db118da75c608f47eb10b9e)

Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:58 +02:00
Cornelia Huck
d426d9fba8 s390x/virtio-ccw: wire up irq routing and irqfds
Make use of the new s390 adapter irq routing support to enable real
in-kernel irqfds for virtio-ccw with adapter interrupts.

Note that s390 doesn't provide the common KVM_CAP_IRQCHIP capability, but
rather needs KVM_CAP_S390_IRQCHIP to be enabled. This is to ensure backward
compatibility.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:58 +02:00
Cornelia Huck
7bca3892cb s390x/virtio-ccw: reference-counted indicators
Make code using the same indicators point to a single allocated structure
that is freed when the last user goes away.

This will be used by the irqfd code to unmap addresses after the last user
is gone.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:58 +02:00
Cornelia Huck
03cf077ac9 s390x: add I/O adapter registration
Register an I/O adapter interrupt source for when virtio-ccw devices start
using adapter interrupts.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:58 +02:00
Cornelia Huck
7b35d0c44c s390x: split flic into kvm and non-kvm parts
Introduce a common parent class for both cases, where kvm and non-kvm
can hook up callbacks. This will be used by follow-on patches for
adapter registration and mapping.

We now always have a flic, regardless of whether we use kvm; the
non-kvm implementation just doesn't do anything.

Reviewed-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:57 +02:00
Alexander Graf
61c7bbd236 kvm: Fix enable_cap helpers on older gcc
Commit 40f1ee27aa introduced handy helpers for enable_cap calls on
vcpu and vm level. Unfortunately some older gcc versions (4.7.1, 4.6)
seem to choke on signedness detection in inline created variables:

target-ppc/kvm.c: In function 'kvmppc_booke_watchdog_enable':
target-ppc/kvm.c:1302:21: error: comparison of unsigned expression < 0 is always false [-Werror=type-limits]
target-ppc/kvm.c: In function 'kvmppc_set_papr':
target-ppc/kvm.c:1504:21: error: comparison of unsigned expression < 0 is always false [-Werror=type-limits]

However - thanks to Thomas Huth for the suggestion - we can just cast the
offending potentially 0 value to a signed type, making the comparison signed.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-05-20 13:05:57 +02:00
Peter Maydell
ca8c0fab95 Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches

# gpg: Signature made Mon 19 May 2014 15:21:14 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (22 commits)
  block: optimize zero writes with bdrv_write_zeroes
  blockdev: add a function to parse enum ids from strings
  util: add qemu_iovec_is_zero
  qcow1: Stricter backing file length check
  qcow1: Validate image size (CVE-2014-0223)
  qcow1: Validate L2 table size (CVE-2014-0222)
  qcow1: Check maximum cluster size
  qcow1: Make padding in the header explicit
  curl: Add usage documentation
  curl: Add sslverify option
  curl: Remove broken parsing of options from url
  curl: Fix build when curl_multi_socket_action isn't available
  qemu-iotests: Fix blkdebug in VM drive in 030
  qemu-iotests: Fix core dump suppression in test 039
  iotests: Add test for the JSON protocol
  block: Allow JSON filenames
  check-qdict: Add test for qdict_join()
  qdict: Add qdict_join()
  block: add test for vhdx image created by Disk2VHD
  block: vhdx - account for identical header sections
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-20 11:57:52 +01:00
Jeff Cody
f2564d88fe block: iscsi build fix if LIBISCSI_FEATURE_IOVECTOR is not defined
Commit b03c380 introduced the function
iscsi_allocationmap_is_allocated(), however it is only used within a
code block that is conditionally compiled.  This produces a warning
(error with -werror) of "defined but not used" for the the function, if
LIBISCSI_FEATURE_IOVECTOR is not defined.

This wraps iscsi_allocationmap_is_allocated() in the same conditional.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-20 10:09:45 +02:00
Peter Maydell
b1fe60cd35 hw/audio/intel-hda: Avoid shift into sign bit
Add a U suffix to avoid shifting into the sign bit (which is
undefined behaviour in C).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-20 08:49:21 +02:00
Stanislav Vorobiov
a2554a334a audio/intel-hda: support FIFORDY
linux kernel 3.12 has changed intel-hda
driver to always check for FIFORDY, this
causes long hangs in guest since QEMU
always has this bit set to 0. We now simply set
it to 1 always, since we're synchronous anyway
and always ready to receive the stream

Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-20 08:49:21 +02:00
Peter Maydell
c5fa6c86d0 Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging
* remotes/qmp-unstable/queue/qmp:
  qapi: skip redundant includes
  monitor: Add netdev_del id argument completion.
  monitor: Add netdev_add type argument completion.
  monitor: Add set_link arguments completion.
  monitor: Add chardev-add backend argument completion.
  monitor: Add chardev-remove command completion.
  monitor: Convert sendkey to use command_completion.
  qapi: Show qapi-commands.py invocation in qapi-code-gen.txt
  qapi: Replace uncommon use of the error API by the common one
  tests: Don't call visit_end_struct() after visit_start_struct() fails
  hw: Don't call visit_end_struct() after visit_start_struct() fails
  hmp: Call visit_end_struct() after visit_start_struct() succeeds
  qapi: Un-inline visit of implicit struct
  qapi-visit.py: Clean up a sloppy use of field prefix
  qapi: Clean up shadowing of parameters and locals in inner scopes
  qapi-visit.py: Clean up confusing push_indent() / pop_indent() use
  qapi: Replace start_optional()/end_optional() by optional()
  qapi: Remove unused Visitor callbacks start_handle(), end_handle()
  qapi: Normalize marshalling's visitor initialization and cleanup
  qapi: Update qapi-code-gen.txt example to match current code

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-19 14:10:01 +01:00
Peter Maydell
5bc8f026dd Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-8' into staging
Input code update:
 - add keycode mapping helpers to core.
 - start switching devices to new input api.
 - misc bugfixes.

# gpg: Signature made Fri 16 May 2014 07:43:45 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-input-8:
  input: sparc32 kbd: claim en-us layout
  input: sparc32 kbd: fix some key mappings
  input: remove sparc keymap hack
  input: switch sparc32 kbd to new input api
  input: switch ps/2 mouse to new input api
  input: switch ps/2 kbd to new input api
  input: use KeyValue directly in sendkey monitor command
  input: add qemu_input_handler_deactivate
  input: key mapping helpers
  ps2: set ps/2 output buffer size as the same as kernel

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-19 12:53:07 +01:00
Peter Lieven
465bee1da8 block: optimize zero writes with bdrv_write_zeroes
this patch tries to optimize zero write requests
by automatically using bdrv_write_zeroes if it is
supported by the format.

This significantly speeds up file system initialization and
should speed zero write test used to test backend storage
performance.

I ran the following 2 tests on my internal SSD with a
50G QCOW2 container and on an attached iSCSI storage.

a) mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 /dev/vdX

QCOW2         [off]     [on]     [unmap]
-----
runtime:       14secs    1.1secs  1.1secs
filesize:      937M      18M      18M

iSCSI         [off]     [on]     [unmap]
----
runtime:       9.3s      0.9s     0.9s

b) dd if=/dev/zero of=/dev/vdX bs=1M oflag=direct

QCOW2         [off]     [on]     [unmap]
-----
runtime:       246secs   18secs   18secs
filesize:      51G       192K     192K
throughput:    203M/s    2.3G/s   2.3G/s

iSCSI*        [off]     [on]     [unmap]
----
runtime:       8mins     45secs   33secs
throughput:    106M/s    1.2G/s   1.6G/s
allocated:     100%      100%     0%

* The storage was connected via an 1Gbit interface.
  It seems to internally handle writing zeroes
  via WRITESAME16 very fast.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 13:42:27 +02:00
Peter Maydell
6a23082b4e Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging
* remotes/bonzini/scsi-next:
  [PATCH] block/iscsi: bump year in copyright notice
  block/iscsi: allow cluster_size of 4K and greater
  block/iscsi: clarify the meaning of ISCSI_CHECKALLOC_THRES
  block/iscsi: speed up read for unallocated sectors
  block/iscsi: allow fall back to WRITE SAME without UNMAP
  MAINTAINERS: mark megasas as maintained
  megasas: Add MSI support
  megasas: Enable MSI-X support
  megasas: Implement LD_LIST_QUERY
  scsi: Improve error messages more
  scsi-disk: Improve error messager if can't get version number

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-19 12:30:06 +01:00
Peter Lieven
82a402e99f blockdev: add a function to parse enum ids from strings
this adds a generic function to recover the enum id of a parameter
given as a string.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 12:21:17 +02:00
Peter Lieven
43f35cb5e0 util: add qemu_iovec_is_zero
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 12:20:19 +02:00
Kevin Wolf
d66e5cee00 qcow1: Stricter backing file length check
Like qcow2 since commit 6d33e8e7, error out on invalid lengths instead
of silently truncating them to 1023.

Also don't rely on bdrv_pread() catching integer overflows that make len
negative, but use unsigned variables in the first place.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-05-19 11:36:49 +02:00
Kevin Wolf
46485de0cb qcow1: Validate image size (CVE-2014-0223)
A huge image size could cause s->l1_size to overflow. Make sure that
images never require a L1 table larger than what fits in s->l1_size.

This cannot only cause unbounded allocations, but also the allocation of
a too small L1 table, resulting in out-of-bounds array accesses (both
reads and writes).

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Kevin Wolf
42eb58179b qcow1: Validate L2 table size (CVE-2014-0222)
Too large L2 table sizes cause unbounded allocations. Images actually
created by qemu-img only have 512 byte or 4k L2 tables.

To keep things consistent with cluster sizes, allow ranges between 512
bytes and 64k (in fact, down to 1 entry = 8 bytes is technically
working, but L2 table sizes smaller than a cluster don't make a lot of
sense).

This also means that the number of bytes on the virtual disk that are
described by the same L2 table is limited to at most 8k * 64k or 2^29,
preventively avoiding any integer overflows.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-05-19 11:36:49 +02:00
Kevin Wolf
7159a45b2b qcow1: Check maximum cluster size
Huge values for header.cluster_bits cause unbounded allocations (e.g.
for s->cluster_cache) and crash qemu this way. Less huge values may
survive those allocations, but can cause integer overflows later on.

The only cluster sizes that qemu can create are 4k (for standalone
images) and 512 (for images with backing files), so we can limit it
to 64k.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-05-19 11:36:49 +02:00
Kevin Wolf
ea54feff58 qcow1: Make padding in the header explicit
We were relying on all compilers inserting the same padding in the
header struct that is used for the on-disk format. Let's not do that.
Mark the struct as packed and insert an explicit padding field for
compatibility.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-05-19 11:36:49 +02:00
Matthew Booth
0a86cb7317 curl: Add usage documentation
Signed-off-by: Matthew Booth <mbooth@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Matthew Booth
97a3ea5719 curl: Add sslverify option
This allows qemu to use images over https with a self-signed certificate. It
defaults to verifying the certificate.

Signed-off-by: Matthew Booth <mbooth@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Matthew Booth
e3542c67af curl: Remove broken parsing of options from url
The block layer now supports a generic json syntax for passing option parameters
explicitly, making parsing of options from the url redundant.

Signed-off-by: Matthew Booth <mbooth@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Matthew Booth
9aedd5a5d6 curl: Fix build when curl_multi_socket_action isn't available
Signed-off-by: Matthew Booth <mbooth@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Fam Zheng
b5e51dd714 qemu-iotests: Fix blkdebug in VM drive in 030
The test test_stream_pause in this class uses vm.pause_drive, which
requires a blkdebug driver on top of image, otherwise it's no-op and the
test running is undeterministic.

So add it.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Markus Armbruster
d530e34232 qemu-iotests: Fix core dump suppression in test 039
The shell script attempts to suppress core dumps like this:

    old_ulimit=$(ulimit -c)
    ulimit -c 0
    $QEMU_IO arg...
    ulimit -c "$old_ulimit"

This breaks the test hard unless the limit was zero to begin with!
ulimit sets both hard and soft limit by default, and (re-)raising the
hard limit requires privileges.  Broken since it was added in commit
dc68afe.

Could be fixed by adding -S to set only the soft limit, but I'm not
sure how portable that is in practice.  Simply do it in a subshell
instead, like this:

    (ulimit -c 0; exec $QEMU_IO arg...)

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Max Reitz
4ad303369c iotests: Add test for the JSON protocol
Add a test for the JSON protocol driver.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Max Reitz
4993f7ea7e block: Allow JSON filenames
If the filename given to bdrv_open() is prefixed with "json:", parse the
rest as a JSON object and merge the result into the options QDict. If
there are conflicts, the options QDict takes precedence.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:49 +02:00
Max Reitz
8a5eb36a1c check-qdict: Add test for qdict_join()
Add some test cases for qdict_join().

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:48 +02:00
Max Reitz
9c52681277 qdict: Add qdict_join()
This function joins two QDicts by absorbing one into the other.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:48 +02:00
Jeff Cody
26e2da7279 block: add test for vhdx image created by Disk2VHD
This adds a test for VHDX images created by Microsoft's tool, Disk2VHD.

VHDX images created by this tool have 2 identical header sections, with
identical sequence numbers.  This makes sure we detect VHDX images with
identical headers, and do not flag them as corrupt.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:48 +02:00
Jeff Cody
6906046169 block: vhdx - account for identical header sections
The VHDX spec v1.00 declares that "a header is current if it is the only
valid header or if it is valid and its SequenceNumber field is greater
than the other header’s SequenceNumber field. The parser must only use
data from the current header. If there is no current header, then the
VHDX file is corrupt."

However, the Disk2VHD tool from Microsoft creates a VHDX image file that
has 2 identical headers, including matching checksums and matching
sequence numbers.  Likely, as a shortcut the tool is just writing the
header twice, for the active and inactive headers, during the image
creation.  Technically, this should be considered a corrupt VHDX file
(at least per the 1.00 spec, and that is how we currently treat it).

But in order to accomodate images created with Disk2VHD, we can safely
create an exception for this case.  If we find identical sequence
numbers, then we check the VHDXHeader-sized chunks of each 64KB header
sections (we won't rely just on the crc32c to indicate the headers are
the same).  If they are identical, then we go ahead and use the first
one.

Reported-by: Nerijus Baliūnas <nerijus@users.sourceforge.net>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:48 +02:00
Mike Day
395071a763 Remove g_sequence_lookup from qemu-img help function
g_sequence_lookup is not supported by glib < 2.28. The usage
of g_sequence_lookup is not essential in this context (it's a
safeguard against duplicate values in the help message).
Removing the call enables the build on all platforms and
does not change the operation of the help function.

Signed-off-by: Mike Day <ncmike@ncultra.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-05-19 11:36:48 +02:00
Kevin Wolf
e88ae2264d block: Fix bdrv_is_allocated() for short backing files
bdrv_is_allocated() shouldn't return true for sectors that are
unallocated, but after the end of a short backing file, even though
such sectors are (correctly) marked as containing zeros.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2014-05-19 11:36:48 +02:00
Markus Armbruster
91e7fcca47 virtio-scsi: Plug memory leak on virtio_scsi_push_event() error path
Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-16 17:52:28 +02:00
Markus Armbruster
c4ce4c4b1f scsi: Document intentional fall through in scsi_req_length()
For clarity, and to hush up Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-16 17:52:14 +02:00
Benoît Canet
24fd848950 qapi: skip redundant includes
The purpose of this change is to help create a json file containing
common definitions; each bit of generated C code must be emitted
only one time.

A second history global to all QAPISchema instances has been added
to detect when a file is included more than one time and skip these
includes.
It does not act as a stack and the changes made to it by the
__init__ function are propagated back to the caller so it's really
a global state.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-16 10:35:59 -04:00
Gerd Hoffmann
59e7a13005 input: sparc32 kbd: claim en-us layout
Reported-by: Olivier Danet <odanet@caramail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
97256073b1 input: sparc32 kbd: fix some key mappings
Reported-by: Olivier Danet <odanet@caramail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
2ada510698 input: remove sparc keymap hack
With sparc keyboard going directly from QKeyValue to sparc keycodes
this should not be needed any more.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
65e7545ea3 input: switch sparc32 kbd to new input api
Nasty 0xe0 logic is gone.  We map through QKeyCode now, giving us a
nice, readable mapping table.

Quick smoke test in OpenFirmware looks ok.  Careful check from arch
maintainers would be very nice, especially on the capslock and numlock
logic.  I'm not fully sure whenever I got it translated correctly and
also what it is supposed to do in the first place ...

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
2a766d294a input: switch ps/2 mouse to new input api
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
66e6536e0c input: switch ps/2 kbd to new input api
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
ce53f2f98f input: use KeyValue directly in sendkey monitor command
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
528728fd93 input: add qemu_input_handler_deactivate
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:12 +02:00
Gerd Hoffmann
02aa76c2ba input: key mapping helpers
Add helper functions to translate KeyValue (qapi key representation)
into other representations: traditional qemu key numbers, qapi key
codes (Q_KEY_CODE_*) and scancode sequences.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:11 +02:00
Gonglei
2858ab09e6 ps2: set ps/2 output buffer size as the same as kernel
According to the PS/2 Mouse/Keyboard Protocol, the keyboard outupt buffer size
is 16 bytes. And the PS2_QUEUE_SIZE 256 was introduced in Qemu from the very
beginning.

When I started a  redhat5.6 32bit guest, meanwhile tapped the keyboard as quickly as
possible, the screen would show me "i8042.c: No controller found". As a result,
I couldn't use the keyboard in the VNC client.

Previous discussion about the issue in maillist:
http://thread.gmane.org/gmane.comp.emulators.qemu/43294/focus=47180

This patch has been tested on redhat5.6 32-bit/suse11sp3 64-bit guests.
More easy meathod to reproduce:
1.boot a guest with libvirt.
2.connect to VNC client.
3.as you see the BIOS, bootloader, Linux booting, run the follow simply shell script:
for((i=0;i<10000000;i++)) do virsh send-key redhat5.6 KEY_A; done

Actual results:
dmesg show "i8042.c: No controller found." And the keyboard is out of work.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-16 08:30:11 +02:00
Hani Benhabiles
11b389f21e monitor: Add netdev_del id argument completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 15:16:02 -04:00
Hani Benhabiles
b162b49adc monitor: Add netdev_add type argument completion.
Also update the command's documentation.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 15:16:02 -04:00
Hani Benhabiles
40d19394b7 monitor: Add set_link arguments completion.
Make it possible to query all net clients without specifying an ID when calling
qemu_find_net_clients_except().

This also adds the add_completion_option() function which is to be used for
other commands completions as well.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 15:16:02 -04:00
Hani Benhabiles
13e315dada monitor: Add chardev-add backend argument completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 15:16:01 -04:00
Hani Benhabiles
6297d9a279 monitor: Add chardev-remove command completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 15:16:01 -04:00
Hani Benhabiles
29136cd8a4 monitor: Convert sendkey to use command_completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 15:16:01 -04:00
Markus Armbruster
87a560c455 qapi: Show qapi-commands.py invocation in qapi-code-gen.txt
While there, pare down the shell prompts.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 15:16:01 -04:00
Markus Armbruster
297a3646c2 qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this:

    err = NULL;
    foo(..., &err);
    if (err) {
        goto out;
    }
    bar(..., &err);

Every error source is checked separately.  The second function is only
called when the first one succeeds.  Both functions are free to pass
their argument to error_set().  Because error_set() asserts no error
has been set, this effectively means they must not be called with an
error set.

The qapi-generated code uses the error API differently:

    // *errp was initialized to NULL somewhere up the call chain
    frob(..., errp);
    gnat(..., errp);

Errors accumulate in *errp: first error wins, subsequent errors get
dropped.  To make this work, the second function does nothing when
called with an error set.  Requires non-null errp, or else the second
function can't see the first one fail.

This usage has also bled into visitor tests, and two device model
object property getters rtc_get_date() and balloon_stats_get_all().

With the "accumulate" technique, you need fewer error checks in
callers, and buy that with an error check in every callee.  Can be
nice.

However, mixing the two techniques is confusing.  You can't use the
"accumulate" technique with functions designed for the "check
separately" technique.  You can use the "check separately" technique
with functions designed for the "accumulate" technique, but then
error_set() can't catch you setting an error more than once.

Standardize on the "check separately" technique for now, because it's
overwhelmingly prevalent.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:46 -04:00
Markus Armbruster
cdaec3808e tests: Don't call visit_end_struct() after visit_start_struct() fails
When visit_start_struct() fails, visit_end_struct() must not be
called.  Three out of four visit_type_TestStruct() call it anyway.  As
far as I can tell, visit_start_struct() doesn't actually fail there.
Fix them anyway.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:46 -04:00
Markus Armbruster
2ddb16a95f hw: Don't call visit_end_struct() after visit_start_struct() fails
When visit_start_struct() fails, visit_end_struct() must not be
called.  rtc_get_date() and balloon_stats_all() call it anyway.  As
far as I can tell, they're only used with the string output visitor,
which doesn't care.  Fix them anyway.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:46 -04:00
Markus Armbruster
f9f3a5ecde hmp: Call visit_end_struct() after visit_start_struct() succeeds
When visit_start_struct() succeeds, visit_end_struct() must be called.
hmp_object_add() doesn't when a member visit fails.  As far as I can
tell, the opts visitor copes okay with the misuse.  Fix it anyway.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:46 -04:00
Markus Armbruster
be3c771796 qapi: Un-inline visit of implicit struct
In preparation of error handling changes.  Bonus: generates less
duplicated code.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:46 -04:00
Markus Armbruster
192cca60ae qapi-visit.py: Clean up a sloppy use of field prefix
generate_visit_struct_fields() generates the base type's struct member
name both with and without the field prefix.  Harmless, because the
field prefix is always empty there: only unboxed complex members have
a prefix, and those can't have a base type.

Clean it up anyway.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:46 -04:00
Markus Armbruster
4fa953f20d qapi: Clean up shadowing of parameters and locals in inner scopes
By un-inlining the visit of nested complex types.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:45 -04:00
Markus Armbruster
468866b816 qapi-visit.py: Clean up confusing push_indent() / pop_indent() use
Changing implicit indentation in the middle of generating a block
makes following the code being generated unnecessarily hard.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:45 -04:00
Markus Armbruster
e2cd0f4fb4 qapi: Replace start_optional()/end_optional() by optional()
Semantics of end_optional() differ subtly from the other end_FOO()
callbacks: when start_FOO() succeeds, the matching end_FOO() gets
called regardless of what happens in between.  end_optional() gets
called only when everything in between succeeds as well.  Entirely
undocumented, like all of the visitor API.

The only user of Visitor Callback end_optional() never did anything,
and was removed in commit 9f9ab46.

I'm about to clean up error handling in the generated visitor code,
and end_optional() is in my way.  No users mean no test cases, and
making non-trivial cleanup transformations without test cases doesn't
strike me as a good idea.

Drop end_optional(), and rename start_optional() to optional().  We
can always go back to a pair of callbacks when we have an actual need.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:45 -04:00
Markus Armbruster
cbc95538ed qapi: Remove unused Visitor callbacks start_handle(), end_handle()
These have never been called or implemented by anything, and their
intended use is undocumented, like all of the visitor API.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:45 -04:00
Markus Armbruster
f9bee751be qapi: Normalize marshalling's visitor initialization and cleanup
Input and output marshalling functions do it differently.  Change them
to work the same: initialize the I/O visitor, use it, clean it up,
initialize the dealloc visitor, use it, clean it up.

This delays dealloc visitor initialization in output marshalling
functions, and input visitor cleanup in input marshalling functions.
No functional change, but the latter will be convenient when I change
the error handling.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:45 -04:00
Markus Armbruster
6e2bb3ec70 qapi: Update qapi-code-gen.txt example to match current code
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-05-15 14:00:45 -04:00
Peter Maydell
1a381811b4 Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-s390-20140515' into staging
tcg/s390 updates

# gpg: Signature made Thu 15 May 2014 17:24:40 BST using RSA key ID 4DD0279B
# gpg: Can't check signature: public key not found

* remotes/rth/tags/pull-tcg-s390-20140515:
  tcg-s390: Implement direct chaining of TBs
  tcg-s390: Don't force -march=z990
  tcg-s390: Improve setcond
  tcg-s390: Allow immediate operands to add2 and sub2
  tcg-s390: Implement tcg_register_jit
  tcg-s390: Use more risbg in the tlb sequence
  tcg-s390: Move ldst helpers out of line
  tcg-s390: Convert to new ldst opcodes
  tcg-s390: Integrate endianness into TCGMemOp
  tcg-s390: Convert to TCGMemOp
  tcg-s390: Fix off-by-one in wraparound andi

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 18:56:08 +01:00
Peter Maydell
16a9189921 Merge remote-tracking branch 'remotes/kraxel/tags/pull-roms-2' into staging
seabios: update to 1.7.5-rc1
ipxe: update to current git

# gpg: Signature made Thu 15 May 2014 13:29:37 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-roms-2:
  ipxe: update to current git
  seabios: update to 1.7.5-rc1

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 18:32:16 +01:00
Peter Maydell
ba43bc25c9 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio update

looks like a quiet week
minor bugfix in virtio by myself

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

# gpg: Signature made Tue 13 May 2014 14:37:23 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  virtio: allow mapping up to max queue size

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 18:01:47 +01:00
Peter Maydell
895527eea5 Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20140515' into staging
migration/next for 20140515

# gpg: Signature made Thu 15 May 2014 02:32:25 BST using RSA key ID 5872D723
# gpg: Can't check signature: public key not found

* remotes/juanquintela/tags/migration/20140515:
  usb: fix up post load checks
  migration: show average throughput when migration finishes
  savevm: Remove all the unneeded version_minimum_id_old (rest)
  savevm: Remove all the unneeded version_minimum_id_old (usb)
  Split ram_save_block
  arch_init: Simplify code for load_xbzrle()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 17:29:03 +01:00
Richard Henderson
a10c64e0df tcg-s390: Implement direct chaining of TBs
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 09:22:32 -07:00
Richard Henderson
061cdd8182 tcg-s390: Don't force -march=z990
While we still require the LONG DISPLACEMENT facility, defaults
have moved on since then.  Don't override the system compiler,
whose default may be set to z9-109 or later.

Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 09:20:47 -07:00
Peter Maydell
50cb70d185 Merge remote-tracking branch 'remotes/rth/fix-mov' into staging
* remotes/rth/fix-mov:
  tcg: Fix tcg_reg_alloc_mov vs no-op truncation

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 17:05:20 +01:00
Peter Maydell
6b7aa99eb4 Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140513' into staging
target-arm queue:
 * update libvixl to 1.4
 * remove version_minimum_id_old from ARM devices
 * stellaris_enet tx/rx/migration overhaul
 * various minor fixes for coverity issues

# gpg: Signature made Tue 13 May 2014 16:25:12 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20140513:
  hw/arm/omap_gpmc: Avoid buffer overrun filling prefetch FIFO
  hw/arm/stellaris: Correct handling of GPTM TAR register
  hw/timer/exynos4210_mct: Avoid overflow in exynos4210_ltick_recalc_count
  hw/dma/omap_dma: Add (uint32_t) casts when shifting uint16_t by 16
  hw/arm/omap1: Avoid unintended sign extension writing omap_rtc YEARS_REG
  hw/net/cadence_gem: Remove dead code
  hw/intc/allwinner-a10-pic: Add missing 'break'
  target-arm/helper.c: Don't flush the TLB if SCTLR is rewritten unchanged
  hw/net/stellaris_enet: Convert to vmstate
  hw/net/stellaris_enet: Get rid of rx_fifo pointer
  hw/net/stellaris_enet: Fix debug format strings
  hw/net/stellaris_enet: Correctly implement the TR and THR registers
  hw/net/stellaris_enet: Rewrite tx fifo handling code
  hw/net/stellaris_enet: Correct handling of packet padding
  hw/net/stellaris_enet: Restructure tx_fifo code to avoid buffer overrun
  savevm: Remove all the unneeded version_minimum_id_old (arm)
  disas/libvixl: Update to libvixl 1.4

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 16:24:12 +01:00
Peter Maydell
ef3cb5ca82 Merge remote-tracking branch 'remotes/kvm/uq/master' into staging
* remotes/kvm/uq/master:
  pc: port 92 reset requires a low->high transition
  cpu: make CPU_INTERRUPT_RESET available on all targets
  apic: do not accept SIPI on the bootstrap processor
  target-i386: preserve FPU and MSR state on INIT
  target-i386: fix set of registers zeroed on reset
  kvm: forward INIT signals coming from the chipset
  kvm: reset state from the CPU's reset method
  target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly.
  target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c
  target-i386: set eflags and cr0 prior to calling cpu_x86_load_seg_cache() in smm_helper.c
  target-i386: set eflags prior to calling svm_load_seg_cache() in svm_helper.c
  pci-assign: limit # of msix vectors
  pci-assign: Fix a bug when map MSI-X table memory failed
  kvm: make one_reg helpers available for everyone
  target-i386: Remove unused data from local array

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 15:38:40 +01:00
Peter Maydell
06e33c1c3c Merge remote-tracking branch 'remotes/rth/tags/pull-tgt-i386-20140512' into staging
Fix BT zero flag for new Intel manuals

# gpg: Signature made Mon 12 May 2014 22:26:01 BST using RSA key ID 4DD0279B
# gpg: Can't check signature: public key not found

* remotes/rth/tags/pull-tgt-i386-20140512:
  target-i386: Preserve the Z bit for bt/bts/btr/btc

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-15 14:38:53 +01:00
Peter Maydell
7d983531c6 Revert "iotests: Use configured python"
This reverts commit f915db07ef.

This commit is broken because it does not account for the
build tree and the source tree being different, and can cause
build failures for out-of-tree builds. Revert it until we can
identify a better solution to the problem.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1400153676-30180-1-git-send-email-peter.maydell@linaro.org
Acked-by: Kevin Wolf <kwolf@redhat.com>
2014-05-15 13:41:19 +01:00
Richard Henderson
7b7066b1db tcg-s390: Improve setcond
There are a variety of common cases for which we can use carry tricks to
avoid a conditional branch.  On very new hardware, use LOAD ON CONDITION
instead of a conditional branch.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 01:33:35 -04:00
Richard Henderson
ad19b35808 tcg-s390: Allow immediate operands to add2 and sub2
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 01:33:29 -04:00
Richard Henderson
f167dc37da tcg-s390: Implement tcg_register_jit
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 00:12:25 -04:00
Richard Henderson
547ec12141 tcg-s390: Use more risbg in the tlb sequence
Elides two insns from the sequence.  The resulting tlb compare
sequence is satisfyingly minimal:

	risbg  %r2,%r8,51,186,56
	risbg  %r3,%r8,61,178,0
	cg     %r3,904(%r10,%r2)
	lg     %r2,920(%r10,%r2)
	jlh    tlb_miss

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 00:10:42 -04:00
Richard Henderson
fb5964152d tcg-s390: Move ldst helpers out of line
That is, the old LDST_OPTIMIZATION.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 00:10:00 -04:00
Richard Henderson
f24efee41e tcg-s390: Convert to new ldst opcodes
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 00:09:59 -04:00
Richard Henderson
b8dd88b85c tcg-s390: Integrate endianness into TCGMemOp
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 00:09:59 -04:00
Richard Henderson
a5a04f2830 tcg-s390: Convert to TCGMemOp
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 00:09:59 -04:00
Richard Henderson
a175689654 tcg-s390: Fix off-by-one in wraparound andi
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-15 00:09:47 -04:00
Richard Henderson
450445d543 tcg: Fix tcg_reg_alloc_mov vs no-op truncation
Commit af3cbfbe80 hoisted some "common"
loads of the temporary type, forgetting that the types could differ
during truncating moves.  This affects the correctness of the memory
offset on big-endian hosts.

Tested-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-14 09:56:13 -07:00
Michael S. Tsirkin
719ffe1f5f usb: fix up post load checks
Correct post load checks:
1. dev->setup_len == sizeof(dev->data_buf)
    seems fine, no need to fail migration
2. When state is DATA, passing index > len
   will cause memcpy with negative length,
   resulting in heap overflow

First of the issues was reported by dgilbert.

Reported-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-05-14 15:24:52 +02:00
Peter Lieven
d6ed7312d1 migration: show average throughput when migration finishes
currently the value of the throughput field contains whatever
was the last calculated throughput shortly before the migration
finished.

This patch updates the post migration contents of the field to
the average throughput.

Signed-off-by: Peter Lieven <pl@kamp.de>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-05-14 15:24:52 +02:00
Juan Quintela
35d08458a9 savevm: Remove all the unneeded version_minimum_id_old (rest)
After previous Peter patch, they are redundant.  This way we don't
assign them except when needed.  Once there, there were lots of case
where the ".fields" indentation was wrong:

     .fields = (VMStateField []) {
and
     .fields =      (VMStateField []) {

Change all the combinations to:

     .fields = (VMStateField[]){

The biggest problem (appart from aesthetics) was that checkpatch complained
when we copy&pasted the code from one place to another.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-14 15:24:51 +02:00
Juan Quintela
6e3d652ab2 savevm: Remove all the unneeded version_minimum_id_old (usb)
After previous Peter patch, they are redundant.  This way we don't
assign them except when needed.  Once there, there were lots of case
where the ".fields" indentation was wrong:

     .fields = (VMStateField []) {
and
     .fields =      (VMStateField []) {

Change all the combinations to:

     .fields = (VMStateField[]){

The biggest problem (appart from aesthetics) was that checkpatch complained
when we copy&pasted the code from one place to another.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-14 15:24:51 +02:00
Dr. David Alan Gilbert
14bcfdc7f1 Split ram_save_block
ram_save_block is getting a bit too complicated, and does two separate
things:
   1) Finds a page to send
   2) Sends the page (dealing with compression etc)

Split into 'ram_save_page' to send the page and deal with compression (2)
Rename remaining function to 'ram_find_and_save_block'

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-05-14 15:24:51 +02:00
Chen Gang
fb626663da arch_init: Simplify code for load_xbzrle()
For xbzrle_decode_buffer(), when decoding contents will exceed writing
buffer, it will return -1, so need not check the return value whether
large than writing buffer.

And when failure occurs within load_xbzrle(), it always return -1
without any resources which need release.

So can remove the related checking statements, and also can remove 'rc'
and 'ret' local variables,

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-05-14 15:24:51 +02:00
Peter Maydell
89f26e6b7b hw/arm/omap_gpmc: Avoid buffer overrun filling prefetch FIFO
In fill_prefetch_fifo(), if the device we are reading from is 16 bit,
then we must not try to transfer an odd number of bytes into the FIFO.
This could otherwise have resulted in our overrunning the prefetch.fifo
array by one byte.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-05-13 16:09:39 +01:00
Peter Maydell
1a7917210b hw/arm/stellaris: Correct handling of GPTM TAR register
We don't implement very much of the GPTM TAR register, and what we
do is wrong. The "are we in RT mode?" field is in s->config, not
s->control. Correct this, use LOG_UNIMP rather than hw_error()
for the cases we don't support, and avoid an unlabelled fallthrough
that makes Coverity complain.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-05-13 16:09:39 +01:00
Peter Maydell
c3a699be3c hw/timer/exynos4210_mct: Avoid overflow in exynos4210_ltick_recalc_count
Add casts to avoid potentially overflowing the multiplications
of 32 bit quantities in exynos4210_ltick_recalc_count().

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-05-13 16:09:39 +01:00
Peter Maydell
2a41c92854 hw/dma/omap_dma: Add (uint32_t) casts when shifting uint16_t by 16
Add missing (uint32_t) casts in cases where we're trying to
put a uint16_t value into the top half of a 32-bit field.
These were already present in some but not all places.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-05-13 16:09:39 +01:00
Peter Maydell
7e7e5858f8 hw/arm/omap1: Avoid unintended sign extension writing omap_rtc YEARS_REG
When writing to the YEARS_REG register, if the year value is
99 then the multiplication by 31536000 will overflow into
the sign bit of a 32 bit value and then be erroneously
sign-extended if time_t is 64 bits. Add a cast to avoid this.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-05-13 16:09:39 +01:00
Peter Maydell
c94239fe56 hw/net/cadence_gem: Remove dead code
Commit 191946c moved the code to handle padding to minimum
length from after the handling of the CRC to before it.
This means that the CRC code doesn't need to cope with the
possibility that the size is less than 60; remove this
dead code.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-05-13 16:09:38 +01:00
Peter Maydell
654039b42a hw/intc/allwinner-a10-pic: Add missing 'break'
Add missing 'break' after handling of AW_A10_PIC_BASE_ADDR write.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-05-13 16:09:38 +01:00
Peter Maydell
2f0d8631b7 target-arm/helper.c: Don't flush the TLB if SCTLR is rewritten unchanged
Linux makes a habit of writing the same value to the SCTLR that it
already holds. In a sample boot of the kernel to a shell prompt
it wrote the SCTLR with the value it already held 325465 times,
and wrote different values just 3 times.

Skip flushing the TLB if the SCTLR value isn't actually being changed;
this speeds up my sample boot by 3-5%.

Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1399560029-19007-1-git-send-email-peter.maydell@linaro.org
2014-05-13 16:09:38 +01:00
Peter Maydell
2e11986727 hw/net/stellaris_enet: Convert to vmstate
Convert this device to use vmstate for its save/load, including
providing a post_load function that sanitizes inbound data to
avoid possible buffer overflows if it is malicious.

The sanitizing fixes CVE-2013-4532 (though nobody should be
relying on the security properties of most of the unmaintained
ARM board models anyway, and migration doesn't actually
work on this board due to issues in other device models).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-13 16:09:38 +01:00
Peter Maydell
889ac2a32f hw/net/stellaris_enet: Get rid of rx_fifo pointer
The rx_fifo pointer is awkward to migrate, and is actually
redundant since it is always possible to determine it from
the current rx[].len/.data and rx_fifo_len. Remove both
rx_fifo and rx_fifo_len from the state, replacing them with
a simple rx_fifo_offset which points at the current location
in the RX fifo.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2014-05-13 16:09:37 +01:00
Peter Maydell
eacd606ca7 hw/net/stellaris_enet: Fix debug format strings
Fix various debug format strings which were incorrect for the
data type, so that building with debug enabled is possible.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2014-05-13 16:09:37 +01:00
Peter Maydell
a9171c4fb5 hw/net/stellaris_enet: Correctly implement the TR and THR registers
Packet transmission for the stellaris ethernet controller can be triggered
in one of two ways:
 * by setting a threshold value in the THR register; when the FIFO
   fill level reaches the threshold, the h/w starts transmitting.
   Software has to finish filling the FIFO before the transmit
   process completes to avoid a (silent) underrun
 * by software writing to the TR register to explicitly trigger
   transmission

Since QEMU transmits packets instantaneously (from the guest's
point of view), implement "transmit based on threshold" with
our existing mechanism of "transmit as soon as we have the whole
packet", with the additional wrinkle that we don't transmit if
the packet size is below the specified threshold, and implement
"transmit by specific request" properly.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2014-05-13 16:09:37 +01:00
Peter Maydell
c6fa443b3d hw/net/stellaris_enet: Rewrite tx fifo handling code
The datasheet is clear that the frame length written to the DATA
register is actually stored in the TX FIFO; this means we don't
need to keep both tx_frame_len and tx_fifo_len state separately.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2014-05-13 16:09:36 +01:00
Peter Maydell
7fd5f064d1 hw/net/stellaris_enet: Correct handling of packet padding
The PADEN bit in the transmit control register enables padding of short
data packets out to the required minimum length. However a typo here
meant we were adjusting tx_fifo_len rather than tx_frame_len, so the
padding didn't actually happen. Fix this bug.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: qemu-stable@nongnu.org
2014-05-13 16:09:36 +01:00
Peter Maydell
5c10495ab1 hw/net/stellaris_enet: Restructure tx_fifo code to avoid buffer overrun
The current tx_fifo code has a corner case where the guest can overrun
the fifo buffer: if automatic CRCs are disabled we allow the guest to write
the CRC word even if there isn't actually space for it in the FIFO.
The datasheet is unclear about exactly how the hardware deals with this
situation; the most plausible answer seems to be that the CRC word is
just lost.

Implement this fix by separating the "can we stuff another word in the
FIFO" logic from the "should we transmit the packet now" check. This
also moves us closer to the real hardware, which has a number of ways
it can be configured to trigger sending the packet, some of which we
don't implement.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: qemu-stable@nongnu.org
2014-05-13 16:09:36 +01:00
Juan Quintela
8f1e884b38 savevm: Remove all the unneeded version_minimum_id_old (arm)
After commit 767adce2d, they are redundant.  This way we don't assign them
except when needed.  Once there, there were lots of cases where the ".fields"
indentation was wrong:

     .fields = (VMStateField []) {
and
     .fields =      (VMStateField []) {

Change all the combinations to:

     .fields = (VMStateField[]){

The biggest problem (apart from aesthetics) was that checkpatch complained
when we copy&pasted the code from one place to another.

Signed-off-by: Juan Quintela <quintela@redhat.com>
[PMM: fixed minor conflict, corrected commit message typos]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-05-13 16:09:35 +01:00
Peter Maydell
09319b3041 disas/libvixl: Update to libvixl 1.4
Update our copy of libvixl to upstream's 1.4 release.
Note that we no longer need any local fixes for compilation
on 32 bit hosts -- they have all been integrated upstream.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1399040419-9227-1-git-send-email-peter.maydell@linaro.org
Acked-by: Richard Henderson <rth@twiddle.net>
2014-05-13 16:09:35 +01:00
Paolo Bonzini
4700a316df pc: port 92 reset requires a low->high transition
The PIIX datasheet says that "before another INIT pulse can be
generated via [port 92h], [bit 0] must be written back to a
zero.

This bug is masked right now because a full reset will clear the
value of port 92h.  But once we implement soft reset correctly,
the next attempt to enable the A20 line by setting bit 1 (and
leaving the others untouched) will cause another reset.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:22:29 +02:00
Paolo Bonzini
4a92a558f4 cpu: make CPU_INTERRUPT_RESET available on all targets
On the x86, some devices need access to the CPU reset pin (INIT#).
Provide a generic service to do this, using one of the internal
cpu_interrupt targets.  Generalize the PPC-specific code for
CPU_INTERRUPT_RESET to other targets.

Since PPC does not support migration across QEMU versions (its
machine types are not versioned yet), I picked the value that
is used on x86, CPU_INTERRUPT_TGT_INT_1.  Consequently, TGT_INT_2
and TGT_INT_3 are shifted down by one while keeping their value.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:21:51 +02:00
Paolo Bonzini
7b4d915e11 apic: do not accept SIPI on the bootstrap processor
SIPI interrupts are ignored on the bootstrap.  Never accept one.

Cc: Andreas Faerber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Paolo Bonzini
43175fa96a target-i386: preserve FPU and MSR state on INIT
Most MSRs, plus the FPU, MMX, MXCSR, XMM and YMM registers should not
be zeroed on INIT (Table 9-1 in the Intel SDM).  Copy them out of
CPUX86State and back in, instead of special casing env->pat.

The relevant fields are already consecutive except PAT and SMBASE.
However:

- KVM and Hyper-V MSRs should be reset because they include memory
locations written by the hypervisor.  These MSRs are moved together
at the end of the preserved area.

- SVM state can be moved out of the way since it is written by VMRUN.

Cc: Andreas Faerber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Paolo Bonzini
05e7e819d7 target-i386: fix set of registers zeroed on reset
BND0-3, BNDCFGU, BNDCFGS, BNDSTATUS were not zeroed on reset, but they
should be (Intel Instruction Set Extensions Programming Reference
319433-015, pages 9-4 and 9-6).  Same for YMM.

XCR0 should be reset to 1.

TSC and TSC_RESET were zeroed already by the memset, remove the explicit
assignments.

Cc: Andreas Faerber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Paolo Bonzini
e0723c4510 kvm: forward INIT signals coming from the chipset
Reviewed-by: Gleb Natapov <gnatapov@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Paolo Bonzini
50a2c6e55f kvm: reset state from the CPU's reset method
Now that we have a CPU object with a reset method, it is better to
keep the KVM reset close to the CPU reset.  Using qemu_register_reset
as we do now keeps them far apart.

With this patch, PPC no longer calls the kvm_arch_ function, so
it can get removed there.  Other arches call it from their CPU
reset handler, and the function gets an ARMCPU/X86CPU/S390CPU.

Note that ARM- and s390-specific functions are called kvm_arm_*
and kvm_s390_*, while x86-specific functions are called kvm_arch_*.
That follows the convention used by the different architectures.
Changing that is the topic of a separate patch.

Reviewed-by: Gleb Natapov <gnatapov@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Kevin O'Connor
7848c8d19f target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly.
Instead of manually calling cpu_x86_set_cpl() when the CPL changes,
check for CPL changes on calls to cpu_x86_load_seg_cache(R_CS).  Every
location that called cpu_x86_set_cpl() also called
cpu_x86_load_seg_cache(R_CS), so cpu_x86_set_cpl() is no longer
required.

This fixes the SMM handler code as it was not setting/restoring the
CPL level manually.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Kevin O'Connor
fd460606fd target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c
The cpu_x86_load_seg_cache() function inspects eflags, so make sure
all changes to eflags are done prior to loading the segment caches.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Kevin O'Connor
010e639a8d target-i386: set eflags and cr0 prior to calling cpu_x86_load_seg_cache() in smm_helper.c
The cpu_x86_load_seg_cache() function inspects cr0 and eflags, so make
sure all changes to eflags and cr0 are done prior to loading the
segment caches.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Kevin O'Connor
304520291a target-i386: set eflags prior to calling svm_load_seg_cache() in svm_helper.c
The svm_load_seg_cache() function calls cpu_x86_load_seg_cache() which
inspects env->eflags.  So, make sure all changes to eflags are done
prior to loading the segment cache.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Michael S. Tsirkin
639973a474 pci-assign: limit # of msix vectors
KVM only supports MSIX table size up to 256 vectors,
but some assigned devices support more vectors,
at the moment attempts to assign them fail with EINVAL.

Tweak the MSIX capability exposed to guest to limit table size
to a supported value.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Gonglei <arei.gonglei@huawei.com>
Cc: qemu-stable@nongnu.org
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:12:40 +02:00
Gonglei
ee11f7a822 pci-assign: Fix a bug when map MSI-X table memory failed
When mmapping memory for the MSI-X table failsthe dev->msix_table is
not set to NULL and assigned_dev_unregister_msix_mmio() will cause
a segfault when trying to munmap it.

Signed-off-by: Gonglei Arei <arei.gonglei@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
2014-05-13 13:12:04 +02:00
Cornelia Huck
ada4135f84 kvm: make one_reg helpers available for everyone
s390x introduced helper functions for getting/setting one_regs with
commit 860643bc. However, nothing about these is s390-specific.

Alexey Kardashevskiy had already posted a general version, so let's
merge the two patches and massage the code a bit.

CC: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:11:08 +02:00
Stefan Weil
8e03c100a7 target-i386: Remove unused data from local array
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-13 13:10:36 +02:00
Richard Henderson
dc1823ce26 target-i386: Preserve the Z bit for bt/bts/btr/btc
Older Intel manuals (pre-2010) and current AMD manuals describe Z as
undefined, but newer Intel manuals describe Z as unchanged.

Cc: qemu-stable@nongnu.org
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-05-12 14:20:04 -07:00
Michael S. Tsirkin
9372514080 virtio: allow mapping up to max queue size
It's a loop from i < num_sg  and the array is VIRTQUEUE_MAX_SIZE - so
it's OK if the value read is VIRTQUEUE_MAX_SIZE.

Not a big problem in practice as people don't use
such big queues, but it's inelegant.

Reported-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-12 12:07:21 +03:00
Peter Lieven
6a86dec619 [PATCH] block/iscsi: bump year in copyright notice
Signed-off-by: Peter Lieven <pl@kamp.de>
2014-05-05 10:04:30 +02:00
Peter Lieven
3d2acaa308 block/iscsi: allow cluster_size of 4K and greater
depending on the target the opt_unmap_gran might be as low
as 4K. As we know use this also as a knob to activate the allocationmap
feature lower the barrier. The limit 4K (and not 512) is choosen
to avoid a potentially too big allocationmap.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-29 11:15:01 +02:00
Peter Lieven
5917af812e block/iscsi: clarify the meaning of ISCSI_CHECKALLOC_THRES
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-29 11:14:41 +02:00
Peter Lieven
b03c38057b block/iscsi: speed up read for unallocated sectors
this patch implements a cache that tracks if a page on the
iscsi target is allocated or not. The cache is implemented in
a way that it allows for false positives
(e.g. pretending a page is allocated, but it isn't), but
no false negatives.

The cached allocation info is then used to speed up the
read process for unallocated sectors by issueing a GET_LBA_STATUS
request for all sectors that are not yet known to be allocated.
If the read request is confirmed to fall into an unallocated
range we directly return zeroes and do not transfer the
data over the wire.

Tests have shown that a relatively small amount of GET_LBA_STATUS
requests happens a vServer boot time to fill the allocation cache
(all those blocks are not queried again).

Not to transfer all the data of unallocated sectors saves a lot
of time, bandwidth and storage I/O load during block jobs or storage
migration and it saves a lot of bandwidth as well for any big sequential
read of the whole disk (e.g. block copy or speed tests) if a significant
number of blocks is unallocated.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-29 11:14:25 +02:00
Peter Lieven
dbe5c58f2a block/iscsi: allow fall back to WRITE SAME without UNMAP
if the iscsi driver receives a write zeroes request with
the BDRV_REQ_MAY_UNMAP flag set it fails with -ENOTSUP
if the iscsi target does not support WRITE SAME with
UNMAP. However, the BDRV_REQ_MAY_UNMAP is only a hint
and writing zeroes with WRITE SAME will still be
better than falling back to writing zeroes with WRITE16.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-28 15:04:17 +02:00
Hannes Reinecke
d383c625e2 MAINTAINERS: mark megasas as maintained
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-28 13:51:23 +02:00
Hannes Reinecke
4522b69c6c megasas: Add MSI support
Some hardware instances do support MSI, so we should do likewise.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-28 13:51:13 +02:00
Hannes Reinecke
23335f6273 megasas: Enable MSI-X support
MSI-X support has been fixed in qemu, so we can enable it again.

Signed-off-by: Hannes Reinecke <hare@suse.de>
[Do not change VMSTATE_PCI_DEVICE to PCIE. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-28 13:50:01 +02:00
Hannes Reinecke
34bb4d02e0 megasas: Implement LD_LIST_QUERY
Newer firmware implement a LD_LIST_QUERY command, and due to a driver
issue no drives might be detected if this command isn't supported.
So add emulation for this command, too.

Cc: qemu-stable@nongnu.org
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-28 13:48:41 +02:00
Paolo Bonzini
6ee143a0a4 scsi: Improve error messages more
Remove the "scsi-block:" prefix for error messages as suggested
by Markus.

Improve the previous patch by making the message the same for both
scsi-block and scsi-generic, including the strerror() output in both
and making an explicit reference to SG_IO.  Also s/can not/cannot/.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-28 13:38:00 +02:00
Fam Zheng
4bbeb8b173 scsi-disk: Improve error messager if can't get version number
More often it is that bdrv_ioctl fails due to not supported by driver or
whatever reason, in this case we should be specific, because "interface
too old" is very confusing.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-28 12:09:12 +02:00
554 changed files with 12767 additions and 6955 deletions

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@
/config-host.*
/config-target.*
/config.status
/config-temp
/trace/generated-tracers.h
/trace/generated-tracers.c
/trace/generated-tracers-dtrace.h

View File

@@ -243,8 +243,8 @@ S: Maintained
F: hw/*/exynos*
Calxeda Highbank
M: Mark Langsdorf <mark.langsdorf@calxeda.com>
S: Supported
M: Rob Herring <robh@kernel.org>
S: Maintained
F: hw/arm/highbank.c
F: hw/net/xgmac.c
@@ -659,6 +659,12 @@ S: Supported
F: hw/block/nvme*
F: tests/nvme-test.c
megasas
M: Hannes Reinecke <hare@suse.de>
S: Supported
F: hw/scsi/megasas.c
F: hw/scsi/mfi.h
Xilinx EDK
M: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>

View File

@@ -560,20 +560,93 @@ static void migration_bitmap_sync(void)
}
/*
* ram_save_block: Writes a page of memory to the stream f
* ram_save_page: Send the given page to the stream
*
* Returns: Number of bytes written.
*/
static int ram_save_page(QEMUFile *f, RAMBlock* block, ram_addr_t offset,
bool last_stage)
{
int bytes_sent;
int cont;
ram_addr_t current_addr;
MemoryRegion *mr = block->mr;
uint8_t *p;
int ret;
bool send_async = true;
cont = (block == last_sent_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
p = memory_region_get_ram_ptr(mr) + offset;
/* In doubt sent page as normal */
bytes_sent = -1;
ret = ram_control_save_page(f, block->offset,
offset, TARGET_PAGE_SIZE, &bytes_sent);
XBZRLE_cache_lock();
current_addr = block->offset + offset;
if (ret != RAM_SAVE_CONTROL_NOT_SUPP) {
if (ret != RAM_SAVE_CONTROL_DELAYED) {
if (bytes_sent > 0) {
acct_info.norm_pages++;
} else if (bytes_sent == 0) {
acct_info.dup_pages++;
}
}
} else if (is_zero_range(p, TARGET_PAGE_SIZE)) {
acct_info.dup_pages++;
bytes_sent = save_block_hdr(f, block, offset, cont,
RAM_SAVE_FLAG_COMPRESS);
qemu_put_byte(f, 0);
bytes_sent++;
/* Must let xbzrle know, otherwise a previous (now 0'd) cached
* page would be stale
*/
xbzrle_cache_zero_page(current_addr);
} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
bytes_sent = save_xbzrle_page(f, &p, current_addr, block,
offset, cont, last_stage);
if (!last_stage) {
/* Can't send this cached data async, since the cache page
* might get updated before it gets to the wire
*/
send_async = false;
}
}
/* XBZRLE overflow or normal page */
if (bytes_sent == -1) {
bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
if (send_async) {
qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE);
} else {
qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
}
bytes_sent += TARGET_PAGE_SIZE;
acct_info.norm_pages++;
}
XBZRLE_cache_unlock();
return bytes_sent;
}
/*
* ram_find_and_save_block: Finds a page to send and sends it to f
*
* Returns: The number of bytes written.
* 0 means no dirty pages
*/
static int ram_save_block(QEMUFile *f, bool last_stage)
static int ram_find_and_save_block(QEMUFile *f, bool last_stage)
{
RAMBlock *block = last_seen_block;
ram_addr_t offset = last_offset;
bool complete_round = false;
int bytes_sent = 0;
MemoryRegion *mr;
ram_addr_t current_addr;
if (!block)
block = QTAILQ_FIRST(&ram_list.blocks);
@@ -594,64 +667,8 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
ram_bulk_stage = false;
}
} else {
int ret;
uint8_t *p;
bool send_async = true;
int cont = (block == last_sent_block) ?
RAM_SAVE_FLAG_CONTINUE : 0;
bytes_sent = ram_save_page(f, block, offset, last_stage);
p = memory_region_get_ram_ptr(mr) + offset;
/* In doubt sent page as normal */
bytes_sent = -1;
ret = ram_control_save_page(f, block->offset,
offset, TARGET_PAGE_SIZE, &bytes_sent);
XBZRLE_cache_lock();
current_addr = block->offset + offset;
if (ret != RAM_SAVE_CONTROL_NOT_SUPP) {
if (ret != RAM_SAVE_CONTROL_DELAYED) {
if (bytes_sent > 0) {
acct_info.norm_pages++;
} else if (bytes_sent == 0) {
acct_info.dup_pages++;
}
}
} else if (is_zero_range(p, TARGET_PAGE_SIZE)) {
acct_info.dup_pages++;
bytes_sent = save_block_hdr(f, block, offset, cont,
RAM_SAVE_FLAG_COMPRESS);
qemu_put_byte(f, 0);
bytes_sent++;
/* Must let xbzrle know, otherwise a previous (now 0'd) cached
* page would be stale
*/
xbzrle_cache_zero_page(current_addr);
} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
bytes_sent = save_xbzrle_page(f, &p, current_addr, block,
offset, cont, last_stage);
if (!last_stage) {
/* Can't send this cached data async, since the cache page
* might get updated before it gets to the wire
*/
send_async = false;
}
}
/* XBZRLE overflow or normal page */
if (bytes_sent == -1) {
bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
if (send_async) {
qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE);
} else {
qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
}
bytes_sent += TARGET_PAGE_SIZE;
acct_info.norm_pages++;
}
XBZRLE_cache_unlock();
/* if page is unmodified, continue to the next */
if (bytes_sent > 0) {
last_sent_block = block;
@@ -850,7 +867,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
while ((ret = qemu_file_rate_limit(f)) == 0) {
int bytes_sent;
bytes_sent = ram_save_block(f, false);
bytes_sent = ram_find_and_save_block(f, false);
/* no more blocks to sent */
if (bytes_sent == 0) {
break;
@@ -912,7 +929,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
while (true) {
int bytes_sent;
bytes_sent = ram_save_block(f, true);
bytes_sent = ram_find_and_save_block(f, true);
/* no more blocks to sent */
if (bytes_sent == 0) {
break;
@@ -946,7 +963,6 @@ static uint64_t ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
{
int ret, rc = 0;
unsigned int xh_len;
int xh_flags;
@@ -959,30 +975,25 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
xh_len = qemu_get_be16(f);
if (xh_flags != ENCODING_FLAG_XBZRLE) {
fprintf(stderr, "Failed to load XBZRLE page - wrong compression!\n");
error_report("Failed to load XBZRLE page - wrong compression!");
return -1;
}
if (xh_len > TARGET_PAGE_SIZE) {
fprintf(stderr, "Failed to load XBZRLE page - len overflow!\n");
error_report("Failed to load XBZRLE page - len overflow!");
return -1;
}
/* load data and decode */
qemu_get_buffer(f, xbzrle_decoded_buf, xh_len);
/* decode RLE */
ret = xbzrle_decode_buffer(xbzrle_decoded_buf, xh_len, host,
TARGET_PAGE_SIZE);
if (ret == -1) {
fprintf(stderr, "Failed to load XBZRLE page - decode error!\n");
rc = -1;
} else if (ret > TARGET_PAGE_SIZE) {
fprintf(stderr, "Failed to load XBZRLE page - size %d exceeds %d!\n",
ret, TARGET_PAGE_SIZE);
abort();
if (xbzrle_decode_buffer(xbzrle_decoded_buf, xh_len, host,
TARGET_PAGE_SIZE) == -1) {
error_report("Failed to load XBZRLE page - decode error!");
return -1;
}
return rc;
return 0;
}
static inline void *host_from_stream_offset(QEMUFile *f,
@@ -995,7 +1006,7 @@ static inline void *host_from_stream_offset(QEMUFile *f,
if (flags & RAM_SAVE_FLAG_CONTINUE) {
if (!block) {
fprintf(stderr, "Ack, bad migration stream!\n");
error_report("Ack, bad migration stream!");
return NULL;
}
@@ -1011,7 +1022,7 @@ static inline void *host_from_stream_offset(QEMUFile *f,
return memory_region_get_ram_ptr(block->mr) + offset;
}
fprintf(stderr, "Can't find block %s!\n", id);
error_report("Can't find block %s!", id);
return NULL;
}
@@ -1064,10 +1075,9 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
if (!strncmp(id, block->idstr, sizeof(id))) {
if (block->length != length) {
fprintf(stderr,
"Length mismatch: %s: " RAM_ADDR_FMT
" in != " RAM_ADDR_FMT "\n", id, length,
block->length);
error_report("Length mismatch: %s: " RAM_ADDR_FMT
" in != " RAM_ADDR_FMT, id, length,
block->length);
ret = -EINVAL;
goto done;
}
@@ -1076,8 +1086,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
}
if (!block) {
fprintf(stderr, "Unknown ramblock \"%s\", cannot "
"accept migration\n", id);
error_report("Unknown ramblock \"%s\", cannot "
"accept migration", id);
ret = -EINVAL;
goto done;
}
@@ -1232,12 +1242,11 @@ void select_soundhw(const char *optarg)
if (!c->name) {
if (l > 80) {
fprintf(stderr,
"Unknown sound card name (too big to show)\n");
error_report("Unknown sound card name (too big to show)");
}
else {
fprintf(stderr, "Unknown sound card name `%.*s'\n",
(int) l, p);
error_report("Unknown sound card name `%.*s'",
(int) l, p);
}
bad_card = 1;
}
@@ -1260,13 +1269,13 @@ void audio_init(void)
if (c->enabled) {
if (c->isa) {
if (!isa_bus) {
fprintf(stderr, "ISA bus not available for %s\n", c->name);
error_report("ISA bus not available for %s", c->name);
exit(1);
}
c->init.init_isa(isa_bus);
} else {
if (!pci_bus) {
fprintf(stderr, "PCI bus not available for %s\n", c->name);
error_report("PCI bus not available for %s", c->name);
exit(1);
}
c->init.init_pci(pci_bus);

View File

@@ -1812,8 +1812,7 @@ static const VMStateDescription vmstate_audio = {
.name = "audio",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_END_OF_LIST()
}
};

View File

@@ -105,7 +105,7 @@ static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ());
samples = (bytes - rate->bytes_sent) >> info->shift;
if (samples < 0 || samples > 65536) {
fprintf (stderr, "Resetting rate control (%" PRId64 " samples)\n", samples);
error_report("Resetting rate control (%" PRId64 " samples)", samples);
rate_start (rate);
samples = 0;
}

View File

@@ -63,8 +63,7 @@ static void wav_destroy (void *opaque)
}
doclose:
if (fclose (wav->f)) {
fprintf (stderr, "wav_destroy: fclose failed: %s",
strerror (errno));
error_report("wav_destroy: fclose failed: %s", strerror(errno));
}
}

View File

@@ -59,6 +59,7 @@ typedef struct BlkMigDevState {
unsigned long *aio_bitmap;
int64_t completed_sectors;
BdrvDirtyBitmap *dirty_bitmap;
Error *blocker;
} BlkMigDevState;
typedef struct BlkMigBlock {
@@ -361,7 +362,8 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
bmds->completed_sectors = 0;
bmds->shared_base = block_mig_state.shared_base;
alloc_aio_bitmap(bmds);
bdrv_set_in_use(bs, 1);
error_setg(&bmds->blocker, "block device is in use by migration");
bdrv_op_block_all(bs, bmds->blocker);
bdrv_ref(bs);
block_mig_state.total_sector_sum += sectors;
@@ -599,7 +601,8 @@ static void blk_mig_cleanup(void)
blk_mig_lock();
while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry);
bdrv_set_in_use(bmds->bs, 0);
bdrv_op_unblock_all(bmds->bs, bmds->blocker);
error_free(bmds->blocker);
bdrv_unref(bmds->bs);
g_free(bmds->aio_bitmap);
g_free(bmds);

213
block.c
View File

@@ -335,6 +335,7 @@ void bdrv_register(BlockDriver *bdrv)
BlockDriverState *bdrv_new(const char *device_name, Error **errp)
{
BlockDriverState *bs;
int i;
if (bdrv_find(device_name)) {
error_setg(errp, "Device with id '%s' already exists",
@@ -353,6 +354,9 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
if (device_name[0] != '\0') {
QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
}
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
QLIST_INIT(&bs->op_blockers[i]);
}
bdrv_iostatus_disable(bs);
notifier_list_init(&bs->close_notifiers);
notifier_with_return_list_init(&bs->before_write_notifiers);
@@ -1090,6 +1094,37 @@ fail:
return ret;
}
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
{
if (bs->backing_hd) {
assert(bs->backing_blocker);
bdrv_op_unblock_all(bs->backing_hd, bs->backing_blocker);
} else if (backing_hd) {
error_setg(&bs->backing_blocker,
"device is used as backing hd of '%s'",
bs->device_name);
}
bs->backing_hd = backing_hd;
if (!backing_hd) {
error_free(bs->backing_blocker);
bs->backing_blocker = NULL;
goto out;
}
bs->open_flags &= ~BDRV_O_NO_BACKING;
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_hd->filename);
pstrcpy(bs->backing_format, sizeof(bs->backing_format),
backing_hd->drv ? backing_hd->drv->format_name : "");
bdrv_op_block_all(bs->backing_hd, bs->backing_blocker);
/* Otherwise we won't be able to commit due to check in bdrv_commit */
bdrv_op_unblock(bs->backing_hd, BLOCK_OP_TYPE_COMMIT,
bs->backing_blocker);
out:
bdrv_refresh_limits(bs);
}
/*
* Opens the backing file for a BlockDriverState if not yet open
*
@@ -1103,6 +1138,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
char *backing_filename = g_malloc0(PATH_MAX);
int ret = 0;
BlockDriver *back_drv = NULL;
BlockDriverState *backing_hd;
Error *local_err = NULL;
if (bs->backing_hd != NULL) {
@@ -1125,30 +1161,26 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
bdrv_get_full_backing_filename(bs, backing_filename, PATH_MAX);
}
backing_hd = bdrv_new("", errp);
if (bs->backing_format[0] != '\0') {
back_drv = bdrv_find_format(bs->backing_format);
}
assert(bs->backing_hd == NULL);
ret = bdrv_open(&bs->backing_hd,
ret = bdrv_open(&backing_hd,
*backing_filename ? backing_filename : NULL, NULL, options,
bdrv_backing_flags(bs->open_flags), back_drv, &local_err);
if (ret < 0) {
bs->backing_hd = NULL;
bdrv_unref(backing_hd);
backing_hd = NULL;
bs->open_flags |= BDRV_O_NO_BACKING;
error_setg(errp, "Could not open backing file: %s",
error_get_pretty(local_err));
error_free(local_err);
goto free_exit;
}
if (bs->backing_hd->file) {
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
bs->backing_hd->file->filename);
}
/* Recalculate the BlockLimits with the backing file */
bdrv_refresh_limits(bs);
bdrv_set_backing_hd(bs, backing_hd);
free_exit:
g_free(backing_filename);
@@ -1196,6 +1228,7 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename,
bdref_key);
ret = -EINVAL;
}
QDECREF(image_options);
goto done;
}
@@ -1274,6 +1307,33 @@ out:
g_free(tmp_filename);
}
static QDict *parse_json_filename(const char *filename, Error **errp)
{
QObject *options_obj;
QDict *options;
int ret;
ret = strstart(filename, "json:", &filename);
assert(ret);
options_obj = qobject_from_json(filename);
if (!options_obj) {
error_setg(errp, "Could not parse the JSON options");
return NULL;
}
if (qobject_type(options_obj) != QTYPE_QDICT) {
qobject_decref(options_obj);
error_setg(errp, "Invalid JSON object given");
return NULL;
}
options = qobject_to_qdict(options_obj);
qdict_flatten(options);
return options;
}
/*
* Opens a disk image (raw, qcow2, vmdk, ...)
*
@@ -1337,6 +1397,20 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
options = qdict_new();
}
if (filename && g_str_has_prefix(filename, "json:")) {
QDict *json_options = parse_json_filename(filename, &local_err);
if (local_err) {
ret = -EINVAL;
goto fail;
}
/* Options given in the filename have lower priority than options
* specified directly */
qdict_join(options, json_options, false);
QDECREF(json_options);
filename = NULL;
}
bs->options = options;
options = qdict_clone_shallow(options);
@@ -1743,8 +1817,9 @@ void bdrv_close(BlockDriverState *bs)
if (bs->drv) {
if (bs->backing_hd) {
bdrv_unref(bs->backing_hd);
bs->backing_hd = NULL;
BlockDriverState *backing_hd = bs->backing_hd;
bdrv_set_backing_hd(bs, NULL);
bdrv_unref(backing_hd);
}
bs->drv->bdrv_close(bs);
g_free(bs->opaque);
@@ -1904,13 +1979,14 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
bs_dest->refcnt = bs_src->refcnt;
/* job */
bs_dest->in_use = bs_src->in_use;
bs_dest->job = bs_src->job;
/* keep the same entry in bdrv_states */
pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name),
bs_src->device_name);
bs_dest->device_list = bs_src->device_list;
memcpy(bs_dest->op_blockers, bs_src->op_blockers,
sizeof(bs_dest->op_blockers));
}
/*
@@ -1945,7 +2021,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
assert(bs_new->job == NULL);
assert(bs_new->dev == NULL);
assert(bs_new->in_use == 0);
assert(bs_new->io_limits_enabled == false);
assert(!throttle_have_timer(&bs_new->throttle_state));
@@ -1964,7 +2039,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
/* Check a few fields that should remain attached to the device */
assert(bs_new->dev == NULL);
assert(bs_new->job == NULL);
assert(bs_new->in_use == 0);
assert(bs_new->io_limits_enabled == false);
assert(!throttle_have_timer(&bs_new->throttle_state));
@@ -1997,19 +2071,14 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
/* The contents of 'tmp' will become bs_top, as we are
* swapping bs_new and bs_top contents. */
bs_top->backing_hd = bs_new;
bs_top->open_flags &= ~BDRV_O_NO_BACKING;
pstrcpy(bs_top->backing_file, sizeof(bs_top->backing_file),
bs_new->filename);
pstrcpy(bs_top->backing_format, sizeof(bs_top->backing_format),
bs_new->drv ? bs_new->drv->format_name : "");
bdrv_set_backing_hd(bs_top, bs_new);
}
static void bdrv_delete(BlockDriverState *bs)
{
assert(!bs->dev);
assert(!bs->job);
assert(!bs->in_use);
assert(bdrv_op_blocker_is_empty(bs));
assert(!bs->refcnt);
assert(QLIST_EMPTY(&bs->dirty_bitmaps));
@@ -2191,7 +2260,8 @@ int bdrv_commit(BlockDriverState *bs)
return -ENOTSUP;
}
if (bdrv_in_use(bs) || bdrv_in_use(bs->backing_hd)) {
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT, NULL) ||
bdrv_op_is_blocked(bs->backing_hd, BLOCK_OP_TYPE_COMMIT, NULL)) {
return -EBUSY;
}
@@ -2595,13 +2665,11 @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
if (ret) {
goto exit;
}
new_top_bs->backing_hd = base_bs;
bdrv_refresh_limits(new_top_bs);
bdrv_set_backing_hd(new_top_bs, base_bs);
QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) {
/* so that bdrv_close() does not recursively close the chain */
intermediate_state->bs->backing_hd = NULL;
bdrv_set_backing_hd(intermediate_state->bs, NULL);
bdrv_unref(intermediate_state->bs);
}
ret = 0;
@@ -3248,6 +3316,15 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF &&
!(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_write_zeroes &&
qemu_iovec_is_zero(qiov)) {
flags |= BDRV_REQ_ZERO_WRITE;
if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
flags |= BDRV_REQ_MAY_UNMAP;
}
}
if (ret < 0) {
/* Do nothing, write notifier decided to fail this request */
} else if (flags & BDRV_REQ_ZERO_WRITE) {
@@ -3444,8 +3521,9 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
return -ENOTSUP;
if (bs->read_only)
return -EACCES;
if (bdrv_in_use(bs))
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_RESIZE, NULL)) {
return -EBUSY;
}
ret = drv->bdrv_truncate(bs, offset);
if (ret == 0) {
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
@@ -3864,7 +3942,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
if (!bs->drv->bdrv_co_get_block_status) {
*pnum = nb_sectors;
ret = BDRV_BLOCK_DATA;
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
if (bs->drv->protocol_name) {
ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
}
@@ -3883,6 +3961,10 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
*pnum, pnum);
}
if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
ret |= BDRV_BLOCK_ALLOCATED;
}
if (!(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO)) {
if (bdrv_unallocated_blocks_are_zero(bs)) {
ret |= BDRV_BLOCK_ZERO;
@@ -3959,9 +4041,7 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,
if (ret < 0) {
return ret;
}
return
(ret & BDRV_BLOCK_DATA) ||
((ret & BDRV_BLOCK_ZERO) && !bdrv_has_zero_init(bs));
return (ret & BDRV_BLOCK_ALLOCATED);
}
/*
@@ -5273,15 +5353,74 @@ void bdrv_unref(BlockDriverState *bs)
}
}
void bdrv_set_in_use(BlockDriverState *bs, int in_use)
struct BdrvOpBlocker {
Error *reason;
QLIST_ENTRY(BdrvOpBlocker) list;
};
bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
{
assert(bs->in_use != in_use);
bs->in_use = in_use;
BdrvOpBlocker *blocker;
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
if (!QLIST_EMPTY(&bs->op_blockers[op])) {
blocker = QLIST_FIRST(&bs->op_blockers[op]);
if (errp) {
error_setg(errp, "Device '%s' is busy: %s",
bs->device_name, error_get_pretty(blocker->reason));
}
return true;
}
return false;
}
int bdrv_in_use(BlockDriverState *bs)
void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason)
{
return bs->in_use;
BdrvOpBlocker *blocker;
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
blocker = g_malloc0(sizeof(BdrvOpBlocker));
blocker->reason = reason;
QLIST_INSERT_HEAD(&bs->op_blockers[op], blocker, list);
}
void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason)
{
BdrvOpBlocker *blocker, *next;
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
QLIST_FOREACH_SAFE(blocker, &bs->op_blockers[op], list, next) {
if (blocker->reason == reason) {
QLIST_REMOVE(blocker, list);
g_free(blocker);
}
}
}
void bdrv_op_block_all(BlockDriverState *bs, Error *reason)
{
int i;
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
bdrv_op_block(bs, i, reason);
}
}
void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason)
{
int i;
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
bdrv_op_unblock(bs, i, reason);
}
}
bool bdrv_op_blocker_is_empty(BlockDriverState *bs)
{
int i;
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
if (!QLIST_EMPTY(&bs->op_blockers[i])) {
return false;
}
}
return true;
}
void bdrv_iostatus_enable(BlockDriverState *bs)

View File

@@ -23,6 +23,7 @@
*/
#include "qemu-common.h"
#include "block/block_int.h"
#include "qapi/qmp/qbool.h"
#include <curl/curl.h>
// #define DEBUG
@@ -37,6 +38,21 @@
#if LIBCURL_VERSION_NUM >= 0x071000
/* The multi interface timer callback was introduced in 7.16.0 */
#define NEED_CURL_TIMER_CALLBACK
#define HAVE_SOCKET_ACTION
#endif
#ifndef HAVE_SOCKET_ACTION
/* If curl_multi_socket_action isn't available, define it statically here in
* terms of curl_multi_socket. Note that ev_bitmask will be ignored, which is
* less efficient but still safe. */
static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
curl_socket_t sockfd,
int ev_bitmask,
int *running_handles)
{
return curl_multi_socket(multi_handle, sockfd, running_handles);
}
#define curl_multi_socket_action __curl_multi_socket_action
#endif
#define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \
@@ -46,12 +62,16 @@
#define CURL_NUM_STATES 8
#define CURL_NUM_ACB 8
#define SECTOR_SIZE 512
#define READ_AHEAD_SIZE (256 * 1024)
#define READ_AHEAD_DEFAULT (256 * 1024)
#define FIND_RET_NONE 0
#define FIND_RET_OK 1
#define FIND_RET_WAIT 2
#define CURL_BLOCK_OPT_URL "url"
#define CURL_BLOCK_OPT_READAHEAD "readahead"
#define CURL_BLOCK_OPT_SSLVERIFY "sslverify"
struct BDRVCURLState;
typedef struct CURLAIOCB {
@@ -88,6 +108,7 @@ typedef struct BDRVCURLState {
CURLState states[CURL_NUM_STATES];
char *url;
size_t readahead_size;
bool sslverify;
bool accept_range;
} BDRVCURLState;
@@ -354,6 +375,8 @@ static CURLState *curl_init_state(BDRVCURLState *s)
return NULL;
}
curl_easy_setopt(state->curl, CURLOPT_URL, s->url);
curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYPEER,
(long) s->sslverify);
curl_easy_setopt(state->curl, CURLOPT_TIMEOUT, 5);
curl_easy_setopt(state->curl, CURLOPT_WRITEFUNCTION,
(void *)curl_read_cb);
@@ -396,43 +419,7 @@ static void curl_clean_state(CURLState *s)
static void curl_parse_filename(const char *filename, QDict *options,
Error **errp)
{
#define RA_OPTSTR ":readahead="
char *file;
char *ra;
const char *ra_val;
int parse_state = 0;
file = g_strdup(filename);
/* Parse a trailing ":readahead=#:" param, if present. */
ra = file + strlen(file) - 1;
while (ra >= file) {
if (parse_state == 0) {
if (*ra == ':') {
parse_state++;
} else {
break;
}
} else if (parse_state == 1) {
if (*ra > '9' || *ra < '0') {
char *opt_start = ra - strlen(RA_OPTSTR) + 1;
if (opt_start > file &&
strncmp(opt_start, RA_OPTSTR, strlen(RA_OPTSTR)) == 0) {
ra_val = ra + 1;
ra -= strlen(RA_OPTSTR) - 1;
*ra = '\0';
qdict_put(options, "readahead", qstring_from_str(ra_val));
}
break;
}
}
ra--;
}
qdict_put(options, "url", qstring_from_str(file));
g_free(file);
qdict_put(options, CURL_BLOCK_OPT_URL, qstring_from_str(filename));
}
static QemuOptsList runtime_opts = {
@@ -440,15 +427,20 @@ static QemuOptsList runtime_opts = {
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "url",
.name = CURL_BLOCK_OPT_URL,
.type = QEMU_OPT_STRING,
.help = "URL to open",
},
{
.name = "readahead",
.name = CURL_BLOCK_OPT_READAHEAD,
.type = QEMU_OPT_SIZE,
.help = "Readahead size",
},
{
.name = CURL_BLOCK_OPT_SSLVERIFY,
.type = QEMU_OPT_BOOL,
.help = "Verify SSL certificate"
},
{ /* end of list */ }
},
};
@@ -477,14 +469,17 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
goto out_noclean;
}
s->readahead_size = qemu_opt_get_size(opts, "readahead", READ_AHEAD_SIZE);
s->readahead_size = qemu_opt_get_size(opts, CURL_BLOCK_OPT_READAHEAD,
READ_AHEAD_DEFAULT);
if ((s->readahead_size & 0x1ff) != 0) {
error_setg(errp, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512",
s->readahead_size);
goto out_noclean;
}
file = qemu_opt_get(opts, "url");
s->sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY, true);
file = qemu_opt_get(opts, CURL_BLOCK_OPT_URL);
if (file == NULL) {
error_setg(errp, "curl block driver requires an 'url' option");
goto out_noclean;

View File

@@ -30,6 +30,8 @@
#include "qemu-common.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/bitops.h"
#include "qemu/bitmap.h"
#include "block/block_int.h"
#include "trace.h"
#include "block/scsi.h"
@@ -59,6 +61,8 @@ typedef struct IscsiLun {
struct scsi_inquiry_logical_block_provisioning lbp;
struct scsi_inquiry_block_limits bl;
unsigned char *zeroblock;
unsigned long *allocationmap;
int cluster_sectors;
} IscsiLun;
typedef struct IscsiTask {
@@ -92,6 +96,15 @@ typedef struct IscsiAIOCB {
#define MAX_NOP_FAILURES 3
#define ISCSI_CMD_RETRIES 5
/* this threshhold is a trade-off knob to choose between
* the potential additional overhead of an extra GET_LBA_STATUS request
* vs. unnecessarily reading a lot of zero sectors over the wire.
* If a read request is greater or equal than ISCSI_CHECKALLOC_THRES
* sectors we check the allocation status of the area covered by the
* request first if the allocationmap indicates that the area might be
* unallocated. */
#define ISCSI_CHECKALLOC_THRES 64
static void
iscsi_bh_cb(void *p)
{
@@ -273,6 +286,32 @@ static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors,
return 1;
}
static void iscsi_allocationmap_set(IscsiLun *iscsilun, int64_t sector_num,
int nb_sectors)
{
if (iscsilun->allocationmap == NULL) {
return;
}
bitmap_set(iscsilun->allocationmap,
sector_num / iscsilun->cluster_sectors,
DIV_ROUND_UP(nb_sectors, iscsilun->cluster_sectors));
}
static void iscsi_allocationmap_clear(IscsiLun *iscsilun, int64_t sector_num,
int nb_sectors)
{
int64_t cluster_num, nb_clusters;
if (iscsilun->allocationmap == NULL) {
return;
}
cluster_num = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);
nb_clusters = (sector_num + nb_sectors) / iscsilun->cluster_sectors
- cluster_num;
if (nb_clusters > 0) {
bitmap_clear(iscsilun->allocationmap, cluster_num, nb_clusters);
}
}
static int coroutine_fn iscsi_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov)
@@ -336,9 +375,125 @@ retry:
return -EIO;
}
iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors);
return 0;
}
#if defined(LIBISCSI_FEATURE_IOVECTOR)
static bool iscsi_allocationmap_is_allocated(IscsiLun *iscsilun,
int64_t sector_num, int nb_sectors)
{
unsigned long size;
if (iscsilun->allocationmap == NULL) {
return true;
}
size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
return !(find_next_bit(iscsilun->allocationmap, size,
sector_num / iscsilun->cluster_sectors) == size);
}
static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum)
{
IscsiLun *iscsilun = bs->opaque;
struct scsi_get_lba_status *lbas = NULL;
struct scsi_lba_status_descriptor *lbasd = NULL;
struct IscsiTask iTask;
int64_t ret;
iscsi_co_init_iscsitask(iscsilun, &iTask);
if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
ret = -EINVAL;
goto out;
}
/* default to all sectors allocated */
ret = BDRV_BLOCK_DATA;
ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID;
*pnum = nb_sectors;
/* LUN does not support logical block provisioning */
if (iscsilun->lbpme == 0) {
goto out;
}
retry:
if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,
sector_qemu2lun(sector_num, iscsilun),
8 + 16, iscsi_co_generic_cb,
&iTask) == NULL) {
ret = -ENOMEM;
goto out;
}
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_coroutine_yield();
}
if (iTask.do_retry) {
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
iTask.task = NULL;
}
iTask.complete = 0;
goto retry;
}
if (iTask.status != SCSI_STATUS_GOOD) {
/* in case the get_lba_status_callout fails (i.e.
* because the device is busy or the cmd is not
* supported) we pretend all blocks are allocated
* for backwards compatibility */
goto out;
}
lbas = scsi_datain_unmarshall(iTask.task);
if (lbas == NULL) {
ret = -EIO;
goto out;
}
lbasd = &lbas->descriptors[0];
if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) {
ret = -EIO;
goto out;
}
*pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun);
if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
ret &= ~BDRV_BLOCK_DATA;
if (iscsilun->lbprz) {
ret |= BDRV_BLOCK_ZERO;
}
}
if (ret & BDRV_BLOCK_ZERO) {
iscsi_allocationmap_clear(iscsilun, sector_num, *pnum);
} else {
iscsi_allocationmap_set(iscsilun, sector_num, *pnum);
}
if (*pnum > nb_sectors) {
*pnum = nb_sectors;
}
out:
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
}
return ret;
}
#endif /* LIBISCSI_FEATURE_IOVECTOR */
static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov)
@@ -355,6 +510,22 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
return -EINVAL;
}
#if defined(LIBISCSI_FEATURE_IOVECTOR)
if (iscsilun->lbprz && nb_sectors >= ISCSI_CHECKALLOC_THRES &&
!iscsi_allocationmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
int64_t ret;
int pnum;
ret = iscsi_co_get_block_status(bs, sector_num, INT_MAX, &pnum);
if (ret < 0) {
return ret;
}
if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors) {
qemu_iovec_memset(iov, 0, 0x00, iov->size);
return 0;
}
}
#endif
lba = sector_qemu2lun(sector_num, iscsilun);
num_sectors = sector_qemu2lun(nb_sectors, iscsilun);
@@ -643,101 +814,6 @@ iscsi_getlength(BlockDriverState *bs)
return len;
}
#if defined(LIBISCSI_FEATURE_IOVECTOR)
static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum)
{
IscsiLun *iscsilun = bs->opaque;
struct scsi_get_lba_status *lbas = NULL;
struct scsi_lba_status_descriptor *lbasd = NULL;
struct IscsiTask iTask;
int64_t ret;
iscsi_co_init_iscsitask(iscsilun, &iTask);
if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
ret = -EINVAL;
goto out;
}
/* default to all sectors allocated */
ret = BDRV_BLOCK_DATA;
ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID;
*pnum = nb_sectors;
/* LUN does not support logical block provisioning */
if (iscsilun->lbpme == 0) {
goto out;
}
retry:
if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,
sector_qemu2lun(sector_num, iscsilun),
8 + 16, iscsi_co_generic_cb,
&iTask) == NULL) {
ret = -ENOMEM;
goto out;
}
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_coroutine_yield();
}
if (iTask.do_retry) {
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
iTask.task = NULL;
}
iTask.complete = 0;
goto retry;
}
if (iTask.status != SCSI_STATUS_GOOD) {
/* in case the get_lba_status_callout fails (i.e.
* because the device is busy or the cmd is not
* supported) we pretend all blocks are allocated
* for backwards compatibility */
goto out;
}
lbas = scsi_datain_unmarshall(iTask.task);
if (lbas == NULL) {
ret = -EIO;
goto out;
}
lbasd = &lbas->descriptors[0];
if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) {
ret = -EIO;
goto out;
}
*pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun);
if (*pnum > nb_sectors) {
*pnum = nb_sectors;
}
if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
ret &= ~BDRV_BLOCK_DATA;
if (iscsilun->lbprz) {
ret |= BDRV_BLOCK_ZERO;
}
}
out:
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
}
return ret;
}
#endif /* LIBISCSI_FEATURE_IOVECTOR */
static int
coroutine_fn iscsi_co_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
@@ -791,6 +867,8 @@ retry:
return -EIO;
}
iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors);
return 0;
}
@@ -809,13 +887,14 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
return -EINVAL;
}
if (!(flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->has_write_same) {
/* WRITE SAME without UNMAP is not supported by the target */
return -ENOTSUP;
if ((flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->lbp.lbpws) {
/* WRITE SAME with UNMAP is not supported by the target,
* fall back and try WRITE SAME without UNMAP */
flags &= ~BDRV_REQ_MAY_UNMAP;
}
if ((flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->lbp.lbpws) {
/* WRITE SAME with UNMAP is not supported by the target */
if (!(flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->has_write_same) {
/* WRITE SAME without UNMAP is not supported by the target */
return -ENOTSUP;
}
@@ -864,6 +943,12 @@ retry:
return -EIO;
}
if (flags & BDRV_REQ_MAY_UNMAP) {
iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors);
} else {
iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors);
}
return 0;
}
@@ -1295,6 +1380,22 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
#endif
/* Guess the internal cluster (page) size of the iscsi target by the means
* of opt_unmap_gran. Transfer the unmap granularity only if it has a
* reasonable size */
if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
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 defined(LIBISCSI_FEATURE_IOVECTOR)
if (iscsilun->lbprz && !(bs->open_flags & BDRV_O_NOCACHE)) {
iscsilun->allocationmap =
bitmap_new(DIV_ROUND_UP(bs->total_sectors,
iscsilun->cluster_sectors));
}
#endif
}
out:
qemu_opts_del(opts);
if (initiator_name != NULL) {
@@ -1328,6 +1429,7 @@ static void iscsi_close(BlockDriverState *bs)
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
iscsi_destroy_context(iscsi);
g_free(iscsilun->zeroblock);
g_free(iscsilun->allocationmap);
memset(iscsilun, 0, sizeof(IscsiLun));
}
@@ -1388,6 +1490,13 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
return -EINVAL;
}
if (iscsilun->allocationmap != NULL) {
g_free(iscsilun->allocationmap);
iscsilun->allocationmap =
bitmap_new(DIV_ROUND_UP(bs->total_sectors,
iscsilun->cluster_sectors));
}
return 0;
}
@@ -1450,13 +1559,7 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
IscsiLun *iscsilun = bs->opaque;
bdi->unallocated_blocks_are_zero = !!iscsilun->lbprz;
bdi->can_write_zeroes_with_unmap = iscsilun->lbprz && iscsilun->lbp.lbpws;
/* Guess the internal cluster (page) size of the iscsi target by the means
* of opt_unmap_gran. Transfer the unmap granularity only if it has a
* reasonable size for bdi->cluster_size */
if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 64 * 1024 &&
iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
bdi->cluster_size = iscsilun->bl.opt_unmap_gran * iscsilun->block_size;
}
bdi->cluster_size = iscsilun->cluster_sectors * BDRV_SECTOR_SIZE;
return 0;
}

View File

@@ -498,7 +498,7 @@ immediate_exit:
/* drop the bs loop chain formed by the swap: break the loop then
* trigger the unref from the top one */
BlockDriverState *p = s->base->backing_hd;
s->base->backing_hd = NULL;
bdrv_set_backing_hd(s->base, NULL);
bdrv_unref(p);
}
}

View File

@@ -50,6 +50,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
}
info->backing_file_depth = bdrv_get_backing_file_depth(bs);
info->detect_zeroes = bs->detect_zeroes;
if (bs->io_limits_enabled) {
ThrottleConfig cfg;
@@ -474,6 +475,7 @@ static void dump_qobject(fprintf_function func_fprintf, void *f,
case QTYPE_QERROR: {
QString *value = qerror_human((QError *)obj);
func_fprintf(f, "%s", qstring_get_str(value));
QDECREF(value);
break;
}
case QTYPE_NONE:

View File

@@ -48,9 +48,10 @@ typedef struct QCowHeader {
uint64_t size; /* in bytes */
uint8_t cluster_bits;
uint8_t l2_bits;
uint16_t padding;
uint32_t crypt_method;
uint64_t l1_table_offset;
} QCowHeader;
} QEMU_PACKED QCowHeader;
#define L2_CACHE_SIZE 16
@@ -60,7 +61,7 @@ typedef struct BDRVQcowState {
int cluster_sectors;
int l2_bits;
int l2_size;
int l1_size;
unsigned int l1_size;
uint64_t cluster_offset_mask;
uint64_t l1_table_offset;
uint64_t *l1_table;
@@ -96,7 +97,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
BDRVQcowState *s = bs->opaque;
int len, i, shift, ret;
unsigned int len, i, shift;
int ret;
QCowHeader header;
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
@@ -127,11 +129,25 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
if (header.size <= 1 || header.cluster_bits < 9) {
error_setg(errp, "invalid value in qcow header");
if (header.size <= 1) {
error_setg(errp, "Image size is too small (must be at least 2 bytes)");
ret = -EINVAL;
goto fail;
}
if (header.cluster_bits < 9 || header.cluster_bits > 16) {
error_setg(errp, "Cluster size must be between 512 and 64k");
ret = -EINVAL;
goto fail;
}
/* l2_bits specifies number of entries; storing a uint64_t in each entry,
* so bytes = num_entries << 3. */
if (header.l2_bits < 9 - 3 || header.l2_bits > 16 - 3) {
error_setg(errp, "L2 table size must be between 512 and 64k");
ret = -EINVAL;
goto fail;
}
if (header.crypt_method > QCOW_CRYPT_AES) {
error_setg(errp, "invalid encryption method in qcow header");
ret = -EINVAL;
@@ -151,7 +167,19 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
/* read the level 1 table */
shift = s->cluster_bits + s->l2_bits;
s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
if (header.size > UINT64_MAX - (1LL << shift)) {
error_setg(errp, "Image too large");
ret = -EINVAL;
goto fail;
} else {
uint64_t l1_size = (header.size + (1LL << shift) - 1) >> shift;
if (l1_size > INT_MAX / sizeof(uint64_t)) {
error_setg(errp, "Image too large");
ret = -EINVAL;
goto fail;
}
s->l1_size = l1_size;
}
s->l1_table_offset = header.l1_table_offset;
s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t));
@@ -175,7 +203,9 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
if (header.backing_file_offset != 0) {
len = header.backing_file_size;
if (len > 1023) {
len = 1023;
error_setg(errp, "Backing file name too long");
ret = -EINVAL;
goto fail;
}
ret = bdrv_pread(bs->file, header.backing_file_offset,
bs->backing_file, len);

View File

@@ -379,7 +379,8 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
if (!bs->drv) {
return -ENOMEDIUM;
ret = -ENOMEDIUM;
goto out;
}
/* Call .bdrv_co_readv() directly instead of using the public block-layer

View File

@@ -1308,6 +1308,7 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
options = qdict_clone_shallow(bs->options);
ret = qcow2_open(bs, options, flags, &local_err);
QDECREF(options);
if (local_err) {
error_setg(errp, "Could not reopen qcow2 layer: %s",
error_get_pretty(local_err));
@@ -1318,8 +1319,6 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
return;
}
QDECREF(options);
if (crypt_method) {
s->crypt_method = crypt_method;
memcpy(&s->aes_encrypt_key, &aes_encrypt_key, sizeof(aes_encrypt_key));

View File

@@ -1192,7 +1192,7 @@ again:
if (size == 0)
#endif
#if defined(__APPLE__) && defined(__MACH__)
size = LONG_LONG_MAX;
size = LLONG_MAX;
#else
size = lseek(fd, 0LL, SEEK_END);
#endif

View File

@@ -105,7 +105,7 @@ typedef struct BDRVRBDState {
static int qemu_rbd_next_tok(char *dst, int dst_len,
char *src, char delim,
const char *name,
char **p)
char **p, Error **errp)
{
int l;
char *end;
@@ -128,10 +128,10 @@ static int qemu_rbd_next_tok(char *dst, int dst_len,
}
l = strlen(src);
if (l >= dst_len) {
error_report("%s too long", name);
error_setg(errp, "%s too long", name);
return -EINVAL;
} else if (l == 0) {
error_report("%s too short", name);
error_setg(errp, "%s too short", name);
return -EINVAL;
}
@@ -157,13 +157,15 @@ static int qemu_rbd_parsename(const char *filename,
char *pool, int pool_len,
char *snap, int snap_len,
char *name, int name_len,
char *conf, int conf_len)
char *conf, int conf_len,
Error **errp)
{
const char *start;
char *p, *buf;
int ret;
if (!strstart(filename, "rbd:", &start)) {
error_setg(errp, "File name must start with 'rbd:'");
return -EINVAL;
}
@@ -172,7 +174,8 @@ static int qemu_rbd_parsename(const char *filename,
*snap = '\0';
*conf = '\0';
ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p);
ret = qemu_rbd_next_tok(pool, pool_len, p,
'/', "pool name", &p, errp);
if (ret < 0 || !p) {
ret = -EINVAL;
goto done;
@@ -180,21 +183,25 @@ static int qemu_rbd_parsename(const char *filename,
qemu_rbd_unescape(pool);
if (strchr(p, '@')) {
ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p);
ret = qemu_rbd_next_tok(name, name_len, p,
'@', "object name", &p, errp);
if (ret < 0) {
goto done;
}
ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p);
ret = qemu_rbd_next_tok(snap, snap_len, p,
':', "snap name", &p, errp);
qemu_rbd_unescape(snap);
} else {
ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p);
ret = qemu_rbd_next_tok(name, name_len, p,
':', "object name", &p, errp);
}
qemu_rbd_unescape(name);
if (ret < 0 || !p) {
goto done;
}
ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p);
ret = qemu_rbd_next_tok(conf, conf_len, p,
'\0', "configuration", &p, errp);
done:
g_free(buf);
@@ -229,7 +236,7 @@ static char *qemu_rbd_parse_clientname(const char *conf, char *clientname)
return NULL;
}
static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
static int qemu_rbd_set_conf(rados_t cluster, const char *conf, Error **errp)
{
char *p, *buf;
char name[RBD_MAX_CONF_NAME_SIZE];
@@ -241,20 +248,20 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
while (p) {
ret = qemu_rbd_next_tok(name, sizeof(name), p,
'=', "conf option name", &p);
'=', "conf option name", &p, errp);
if (ret < 0) {
break;
}
qemu_rbd_unescape(name);
if (!p) {
error_report("conf option %s has no value", name);
error_setg(errp, "conf option %s has no value", name);
ret = -EINVAL;
break;
}
ret = qemu_rbd_next_tok(value, sizeof(value), p,
':', "conf option value", &p);
':', "conf option value", &p, errp);
if (ret < 0) {
break;
}
@@ -263,7 +270,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
if (strcmp(name, "conf") == 0) {
ret = rados_conf_read_file(cluster, value);
if (ret < 0) {
error_report("error reading conf file %s", value);
error_setg(errp, "error reading conf file %s", value);
break;
}
} else if (strcmp(name, "id") == 0) {
@@ -271,7 +278,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
} else {
ret = rados_conf_set(cluster, name, value);
if (ret < 0) {
error_report("invalid conf option %s", name);
error_setg(errp, "invalid conf option %s", name);
ret = -EINVAL;
break;
}
@@ -285,6 +292,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
{
Error *local_err = NULL;
int64_t bytes = 0;
int64_t objsize;
int obj_order = 0;
@@ -301,7 +309,8 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
if (qemu_rbd_parsename(filename, pool, sizeof(pool),
snap_buf, sizeof(snap_buf),
name, sizeof(name),
conf, sizeof(conf)) < 0) {
conf, sizeof(conf), &local_err) < 0) {
error_propagate(errp, local_err);
return -EINVAL;
}
@@ -313,11 +322,11 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
if (options->value.n) {
objsize = options->value.n;
if ((objsize - 1) & objsize) { /* not a power of 2? */
error_report("obj size needs to be power of 2");
error_setg(errp, "obj size needs to be power of 2");
return -EINVAL;
}
if (objsize < 4096) {
error_report("obj size too small");
error_setg(errp, "obj size too small");
return -EINVAL;
}
obj_order = ffs(objsize) - 1;
@@ -328,7 +337,7 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
if (rados_create(&cluster, clientname) < 0) {
error_report("error initializing");
error_setg(errp, "error initializing");
return -EIO;
}
@@ -338,20 +347,20 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
}
if (conf[0] != '\0' &&
qemu_rbd_set_conf(cluster, conf) < 0) {
error_report("error setting config options");
qemu_rbd_set_conf(cluster, conf, &local_err) < 0) {
rados_shutdown(cluster);
error_propagate(errp, local_err);
return -EIO;
}
if (rados_connect(cluster) < 0) {
error_report("error connecting");
error_setg(errp, "error connecting");
rados_shutdown(cluster);
return -EIO;
}
if (rados_ioctx_create(cluster, pool, &io_ctx) < 0) {
error_report("error opening pool %s", pool);
error_setg(errp, "error opening pool %s", pool);
rados_shutdown(cluster);
return -EIO;
}
@@ -441,8 +450,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
qemu_opts_del(opts);
return -EINVAL;
}
@@ -452,7 +460,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
if (qemu_rbd_parsename(filename, pool, sizeof(pool),
snap_buf, sizeof(snap_buf),
s->name, sizeof(s->name),
conf, sizeof(conf)) < 0) {
conf, sizeof(conf), errp) < 0) {
r = -EINVAL;
goto failed_opts;
}
@@ -460,7 +468,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
r = rados_create(&s->cluster, clientname);
if (r < 0) {
error_report("error initializing");
error_setg(&local_err, "error initializing");
goto failed_opts;
}
@@ -488,28 +496,27 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
}
if (conf[0] != '\0') {
r = qemu_rbd_set_conf(s->cluster, conf);
r = qemu_rbd_set_conf(s->cluster, conf, errp);
if (r < 0) {
error_report("error setting config options");
goto failed_shutdown;
}
}
r = rados_connect(s->cluster);
if (r < 0) {
error_report("error connecting");
error_setg(&local_err, "error connecting");
goto failed_shutdown;
}
r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
if (r < 0) {
error_report("error opening pool %s", pool);
error_setg(&local_err, "error opening pool %s", pool);
goto failed_shutdown;
}
r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
if (r < 0) {
error_report("error reading header from %s", s->name);
error_setg(&local_err, "error reading header from %s", s->name);
goto failed_open;
}

View File

@@ -526,17 +526,16 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
return acb;
}
static int connect_to_sdog(BDRVSheepdogState *s)
static int connect_to_sdog(BDRVSheepdogState *s, Error **errp)
{
int fd;
Error *err = NULL;
if (s->is_unix) {
fd = unix_connect(s->host_spec, &err);
fd = unix_connect(s->host_spec, errp);
} else {
fd = inet_connect(s->host_spec, &err);
fd = inet_connect(s->host_spec, errp);
if (err == NULL) {
if (fd >= 0) {
int ret = socket_set_nodelay(fd);
if (ret < 0) {
error_report("%s", strerror(errno));
@@ -544,10 +543,7 @@ static int connect_to_sdog(BDRVSheepdogState *s)
}
}
if (err != NULL) {
qerror_report_err(err);
error_free(err);
} else {
if (fd >= 0) {
qemu_set_nonblock(fd);
}
@@ -672,7 +668,7 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
enum AIOCBState aiocb_type);
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req);
static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag);
static int get_sheep_fd(BDRVSheepdogState *s);
static int get_sheep_fd(BDRVSheepdogState *s, Error **errp);
static void co_write_request(void *opaque);
static AIOReq *find_pending_req(BDRVSheepdogState *s, uint64_t oid)
@@ -709,6 +705,7 @@ static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
static coroutine_fn void reconnect_to_sdog(void *opaque)
{
Error *local_err = NULL;
BDRVSheepdogState *s = opaque;
AIOReq *aio_req, *next;
@@ -723,9 +720,11 @@ static coroutine_fn void reconnect_to_sdog(void *opaque)
/* Try to reconnect the sheepdog server every one second. */
while (s->fd < 0) {
s->fd = get_sheep_fd(s);
s->fd = get_sheep_fd(s, &local_err);
if (s->fd < 0) {
DPRINTF("Wait for connection to be established\n");
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
co_aio_sleep_ns(bdrv_get_aio_context(s->bs), QEMU_CLOCK_REALTIME,
1000000000ULL);
}
@@ -914,11 +913,11 @@ static void co_write_request(void *opaque)
* We cannot use this descriptor for other operations because
* the block driver may be on waiting response from the server.
*/
static int get_sheep_fd(BDRVSheepdogState *s)
static int get_sheep_fd(BDRVSheepdogState *s, Error **errp)
{
int fd;
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, errp);
if (fd < 0) {
return fd;
}
@@ -1061,7 +1060,7 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
static int find_vdi_name(BDRVSheepdogState *s, const char *filename,
uint32_t snapid, const char *tag, uint32_t *vid,
bool lock)
bool lock, Error **errp)
{
int ret, fd;
SheepdogVdiReq hdr;
@@ -1069,7 +1068,7 @@ static int find_vdi_name(BDRVSheepdogState *s, const char *filename,
unsigned int wlen, rlen = 0;
char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, errp);
if (fd < 0) {
return fd;
}
@@ -1095,12 +1094,13 @@ static int find_vdi_name(BDRVSheepdogState *s, const char *filename,
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
if (ret) {
error_setg_errno(errp, -ret, "cannot get vdi info");
goto out;
}
if (rsp->result != SD_RES_SUCCESS) {
error_report("cannot get vdi info, %s, %s %" PRIu32 " %s",
sd_strerror(rsp->result), filename, snapid, tag);
error_setg(errp, "cannot get vdi info, %s, %s %" PRIu32 " %s",
sd_strerror(rsp->result), filename, snapid, tag);
if (rsp->result == SD_RES_NO_VDI) {
ret = -ENOENT;
} else {
@@ -1263,19 +1263,24 @@ static int write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
/* update inode with the latest state */
static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag)
{
Error *local_err = NULL;
SheepdogInode *inode;
int ret = 0, fd;
uint32_t vid = 0;
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
return -EIO;
}
inode = g_malloc(sizeof(s->inode));
ret = find_vdi_name(s, s->name, snapid, tag, &vid, false);
ret = find_vdi_name(s, s->name, snapid, tag, &vid, false, &local_err);
if (ret) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
goto out;
}
@@ -1386,8 +1391,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
ret = -EINVAL;
goto out;
}
@@ -1408,15 +1412,16 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
ret = parse_vdiname(s, filename, vdi, &snapid, tag);
}
if (ret < 0) {
error_setg(errp, "Can't parse filename");
goto out;
}
s->fd = get_sheep_fd(s);
s->fd = get_sheep_fd(s, errp);
if (s->fd < 0) {
ret = s->fd;
goto out;
}
ret = find_vdi_name(s, vdi, snapid, tag, &vid, true);
ret = find_vdi_name(s, vdi, snapid, tag, &vid, true, errp);
if (ret) {
goto out;
}
@@ -1436,7 +1441,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
s->is_snapshot = true;
}
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, errp);
if (fd < 0) {
ret = fd;
goto out;
@@ -1449,6 +1454,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
closesocket(fd);
if (ret) {
error_setg(errp, "Can't read snapshot inode");
goto out;
}
@@ -1472,7 +1478,8 @@ out:
return ret;
}
static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot)
static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot,
Error **errp)
{
SheepdogVdiReq hdr;
SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
@@ -1480,7 +1487,7 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot)
unsigned int wlen, rlen = 0;
char buf[SD_MAX_VDI_LEN];
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, errp);
if (fd < 0) {
return fd;
}
@@ -1510,11 +1517,12 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot)
closesocket(fd);
if (ret) {
error_setg_errno(errp, -ret, "create failed");
return ret;
}
if (rsp->result != SD_RES_SUCCESS) {
error_report("%s, %s", sd_strerror(rsp->result), s->inode.name);
error_setg(errp, "%s, %s", sd_strerror(rsp->result), s->inode.name);
return -EIO;
}
@@ -1525,21 +1533,18 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot)
return 0;
}
static int sd_prealloc(const char *filename)
static int sd_prealloc(const char *filename, Error **errp)
{
BlockDriverState *bs = NULL;
uint32_t idx, max_idx;
int64_t vdi_size;
void *buf = g_malloc0(SD_DATA_OBJ_SIZE);
Error *local_err = NULL;
int ret;
ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
NULL, &local_err);
NULL, errp);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto out;
goto out_with_err_set;
}
vdi_size = bdrv_getlength(bs);
@@ -1563,7 +1568,12 @@ static int sd_prealloc(const char *filename)
goto out;
}
}
out:
if (ret < 0) {
error_setg_errno(errp, -ret, "Can't pre-allocate");
}
out_with_err_set:
if (bs) {
bdrv_unref(bs);
}
@@ -1636,7 +1646,6 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
char tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid;
bool prealloc = false;
Error *local_err = NULL;
s = g_malloc0(sizeof(BDRVSheepdogState));
@@ -1647,6 +1656,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
ret = parse_vdiname(s, filename, s->name, &snapid, tag);
}
if (ret < 0) {
error_setg(errp, "Can't parse filename");
goto out;
}
@@ -1661,8 +1671,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
} else if (!strcmp(options->value.s, "full")) {
prealloc = true;
} else {
error_report("Invalid preallocation mode: '%s'",
options->value.s);
error_setg(errp, "Invalid preallocation mode: '%s'",
options->value.s);
ret = -EINVAL;
goto out;
}
@@ -1670,6 +1680,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
if (options->value.s) {
ret = parse_redundancy(s, options->value.s);
if (ret < 0) {
error_setg(errp, "Invalid redundancy mode: '%s'",
options->value.s);
goto out;
}
}
@@ -1678,7 +1690,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
}
if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {
error_report("too big image size");
error_setg(errp, "too big image size");
ret = -EINVAL;
goto out;
}
@@ -1691,24 +1703,22 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
/* Currently, only Sheepdog backing image is supported. */
drv = bdrv_find_protocol(backing_file, true);
if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
error_report("backing_file must be a sheepdog image");
error_setg(errp, "backing_file must be a sheepdog image");
ret = -EINVAL;
goto out;
}
bs = NULL;
ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL,
&local_err);
errp);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto out;
}
base = bs->opaque;
if (!is_snapshot(&base->inode)) {
error_report("cannot clone from a non snapshot vdi");
error_setg(errp, "cannot clone from a non snapshot vdi");
bdrv_unref(bs);
ret = -EINVAL;
goto out;
@@ -1717,12 +1727,14 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
bdrv_unref(bs);
}
ret = do_sd_create(s, &vid, 0);
if (!prealloc || ret) {
ret = do_sd_create(s, &vid, 0, errp);
if (ret) {
goto out;
}
ret = sd_prealloc(filename);
if (prealloc) {
ret = sd_prealloc(filename, errp);
}
out:
g_free(s);
return ret;
@@ -1730,6 +1742,7 @@ out:
static void sd_close(BlockDriverState *bs)
{
Error *local_err = NULL;
BDRVSheepdogState *s = bs->opaque;
SheepdogVdiReq hdr;
SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
@@ -1738,8 +1751,10 @@ static void sd_close(BlockDriverState *bs)
DPRINTF("%s\n", s->name);
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
return;
}
@@ -1774,6 +1789,7 @@ static int64_t sd_getlength(BlockDriverState *bs)
static int sd_truncate(BlockDriverState *bs, int64_t offset)
{
Error *local_err = NULL;
BDRVSheepdogState *s = bs->opaque;
int ret, fd;
unsigned int datalen;
@@ -1786,8 +1802,10 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
return -EINVAL;
}
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
return fd;
}
@@ -1846,6 +1864,7 @@ static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
/* Delete current working VDI on the snapshot chain */
static bool sd_delete(BDRVSheepdogState *s)
{
Error *local_err = NULL;
unsigned int wlen = SD_MAX_VDI_LEN, rlen = 0;
SheepdogVdiReq hdr = {
.opcode = SD_OP_DEL_VDI,
@@ -1856,8 +1875,10 @@ static bool sd_delete(BDRVSheepdogState *s)
SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
int fd, ret;
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
return false;
}
@@ -1885,6 +1906,7 @@ static bool sd_delete(BDRVSheepdogState *s)
*/
static int sd_create_branch(BDRVSheepdogState *s)
{
Error *local_err = NULL;
int ret, fd;
uint32_t vid;
char *buf;
@@ -1900,15 +1922,19 @@ static int sd_create_branch(BDRVSheepdogState *s)
* false bail out.
*/
deleted = sd_delete(s);
ret = do_sd_create(s, &vid, !deleted);
ret = do_sd_create(s, &vid, !deleted, &local_err);
if (ret) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
goto out;
}
DPRINTF("%" PRIx32 " is created.\n", vid);
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
ret = fd;
goto out;
}
@@ -2122,6 +2148,7 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
{
Error *local_err = NULL;
BDRVSheepdogState *s = bs->opaque;
int ret, fd;
uint32_t new_vid;
@@ -2149,10 +2176,13 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
strncpy(s->inode.tag, sn_info->name, sizeof(s->inode.tag));
/* we don't need to update entire object */
datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
inode = g_malloc(datalen);
/* refresh inode. */
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
ret = fd;
goto cleanup;
}
@@ -2164,15 +2194,15 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto cleanup;
}
ret = do_sd_create(s, &new_vid, 1);
ret = do_sd_create(s, &new_vid, 1, &local_err);
if (ret < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
error_report("failed to create inode for snapshot. %s",
strerror(errno));
goto cleanup;
}
inode = (SheepdogInode *)g_malloc(datalen);
ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),
s->inode.nr_copies, datalen, 0, s->cache_flags);
@@ -2186,6 +2216,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
s->inode.name, s->inode.snap_id, s->inode.vdi_id);
cleanup:
g_free(inode);
closesocket(fd);
return ret;
}
@@ -2249,6 +2280,7 @@ static int sd_snapshot_delete(BlockDriverState *bs,
static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
{
Error *local_err = NULL;
BDRVSheepdogState *s = bs->opaque;
SheepdogReq req;
int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);
@@ -2263,8 +2295,10 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
vdi_inuse = g_malloc(max);
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
ret = fd;
goto out;
}
@@ -2290,8 +2324,10 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);
start_nr = hval & (SD_NR_VDIS - 1);
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
ret = fd;
goto out;
}
@@ -2341,6 +2377,7 @@ out:
static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
int64_t pos, int size, int load)
{
Error *local_err = NULL;
bool create;
int fd, ret = 0, remaining = size;
unsigned int data_len;
@@ -2349,8 +2386,10 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
uint32_t vdi_index;
uint32_t vdi_id = load ? s->inode.parent_vdi_id : s->inode.vdi_id;
fd = connect_to_sdog(s);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
error_report("%s", error_get_pretty(local_err));;
error_free(local_err);
return fd;
}

View File

@@ -106,30 +106,59 @@ static void ssh_state_free(BDRVSSHState *s)
}
}
/* Wrappers around error_report which make sure to dump as much
* information from libssh2 as possible.
*/
static void GCC_FMT_ATTR(2, 3)
session_error_report(BDRVSSHState *s, const char *fs, ...)
static void GCC_FMT_ATTR(3, 4)
session_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...)
{
va_list args;
char *msg;
va_start(args, fs);
error_vprintf(fs, args);
msg = g_strdup_vprintf(fs, args);
va_end(args);
if ((s)->session) {
if (s->session) {
char *ssh_err;
int ssh_err_code;
libssh2_session_last_error((s)->session, &ssh_err, NULL, 0);
/* This is not an errno. See <libssh2.h>. */
ssh_err_code = libssh2_session_last_errno((s)->session);
error_printf(": %s (libssh2 error code: %d)", ssh_err, ssh_err_code);
ssh_err_code = libssh2_session_last_error(s->session,
&ssh_err, NULL, 0);
error_setg(errp, "%s: %s (libssh2 error code: %d)",
msg, ssh_err, ssh_err_code);
} else {
error_setg(errp, "%s", msg);
}
g_free(msg);
}
static void GCC_FMT_ATTR(3, 4)
sftp_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...)
{
va_list args;
char *msg;
va_start(args, fs);
msg = g_strdup_vprintf(fs, args);
va_end(args);
error_printf("\n");
if (s->sftp) {
char *ssh_err;
int ssh_err_code;
unsigned long sftp_err_code;
/* This is not an errno. See <libssh2.h>. */
ssh_err_code = libssh2_session_last_error(s->session,
&ssh_err, NULL, 0);
/* See <libssh2_sftp.h>. */
sftp_err_code = libssh2_sftp_last_error((s)->sftp);
error_setg(errp,
"%s: %s (libssh2 error code: %d, sftp error code: %lu)",
msg, ssh_err, ssh_err_code, sftp_err_code);
} else {
error_setg(errp, "%s", msg);
}
g_free(msg);
}
static void GCC_FMT_ATTR(2, 3)
@@ -145,9 +174,9 @@ sftp_error_report(BDRVSSHState *s, const char *fs, ...)
int ssh_err_code;
unsigned long sftp_err_code;
libssh2_session_last_error((s)->session, &ssh_err, NULL, 0);
/* This is not an errno. See <libssh2.h>. */
ssh_err_code = libssh2_session_last_errno((s)->session);
ssh_err_code = libssh2_session_last_error(s->session,
&ssh_err, NULL, 0);
/* See <libssh2_sftp.h>. */
sftp_err_code = libssh2_sftp_last_error((s)->sftp);
@@ -243,7 +272,7 @@ static void ssh_parse_filename(const char *filename, QDict *options,
}
static int check_host_key_knownhosts(BDRVSSHState *s,
const char *host, int port)
const char *host, int port, Error **errp)
{
const char *home;
char *knh_file = NULL;
@@ -257,14 +286,15 @@ static int check_host_key_knownhosts(BDRVSSHState *s,
hostkey = libssh2_session_hostkey(s->session, &len, &type);
if (!hostkey) {
ret = -EINVAL;
session_error_report(s, "failed to read remote host key");
session_error_setg(errp, s, "failed to read remote host key");
goto out;
}
knh = libssh2_knownhost_init(s->session);
if (!knh) {
ret = -EINVAL;
session_error_report(s, "failed to initialize known hosts support");
session_error_setg(errp, s,
"failed to initialize known hosts support");
goto out;
}
@@ -289,21 +319,23 @@ static int check_host_key_knownhosts(BDRVSSHState *s,
break;
case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
ret = -EINVAL;
session_error_report(s, "host key does not match the one in known_hosts (found key %s)",
found->key);
session_error_setg(errp, s,
"host key does not match the one in known_hosts"
" (found key %s)", found->key);
goto out;
case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
ret = -EINVAL;
session_error_report(s, "no host key was found in known_hosts");
session_error_setg(errp, s, "no host key was found in known_hosts");
goto out;
case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
ret = -EINVAL;
session_error_report(s, "failure matching the host key with known_hosts");
session_error_setg(errp, s,
"failure matching the host key with known_hosts");
goto out;
default:
ret = -EINVAL;
session_error_report(s, "unknown error matching the host key with known_hosts (%d)",
r);
session_error_setg(errp, s, "unknown error matching the host key"
" with known_hosts (%d)", r);
goto out;
}
@@ -358,20 +390,20 @@ static int compare_fingerprint(const unsigned char *fingerprint, size_t len,
static int
check_host_key_hash(BDRVSSHState *s, const char *hash,
int hash_type, size_t fingerprint_len)
int hash_type, size_t fingerprint_len, Error **errp)
{
const char *fingerprint;
fingerprint = libssh2_hostkey_hash(s->session, hash_type);
if (!fingerprint) {
session_error_report(s, "failed to read remote host key");
session_error_setg(errp, s, "failed to read remote host key");
return -EINVAL;
}
if(compare_fingerprint((unsigned char *) fingerprint, fingerprint_len,
hash) != 0) {
error_report("remote host key does not match host_key_check '%s'",
hash);
error_setg(errp, "remote host key does not match host_key_check '%s'",
hash);
return -EPERM;
}
@@ -379,7 +411,7 @@ check_host_key_hash(BDRVSSHState *s, const char *hash,
}
static int check_host_key(BDRVSSHState *s, const char *host, int port,
const char *host_key_check)
const char *host_key_check, Error **errp)
{
/* host_key_check=no */
if (strcmp(host_key_check, "no") == 0) {
@@ -389,25 +421,25 @@ static int check_host_key(BDRVSSHState *s, const char *host, int port,
/* host_key_check=md5:xx:yy:zz:... */
if (strncmp(host_key_check, "md5:", 4) == 0) {
return check_host_key_hash(s, &host_key_check[4],
LIBSSH2_HOSTKEY_HASH_MD5, 16);
LIBSSH2_HOSTKEY_HASH_MD5, 16, errp);
}
/* host_key_check=sha1:xx:yy:zz:... */
if (strncmp(host_key_check, "sha1:", 5) == 0) {
return check_host_key_hash(s, &host_key_check[5],
LIBSSH2_HOSTKEY_HASH_SHA1, 20);
LIBSSH2_HOSTKEY_HASH_SHA1, 20, errp);
}
/* host_key_check=yes */
if (strcmp(host_key_check, "yes") == 0) {
return check_host_key_knownhosts(s, host, port);
return check_host_key_knownhosts(s, host, port, errp);
}
error_report("unknown host_key_check setting (%s)", host_key_check);
error_setg(errp, "unknown host_key_check setting (%s)", host_key_check);
return -EINVAL;
}
static int authenticate(BDRVSSHState *s, const char *user)
static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
{
int r, ret;
const char *userauthlist;
@@ -418,7 +450,8 @@ static int authenticate(BDRVSSHState *s, const char *user)
userauthlist = libssh2_userauth_list(s->session, user, strlen(user));
if (strstr(userauthlist, "publickey") == NULL) {
ret = -EPERM;
error_report("remote server does not support \"publickey\" authentication");
error_setg(errp,
"remote server does not support \"publickey\" authentication");
goto out;
}
@@ -426,17 +459,18 @@ static int authenticate(BDRVSSHState *s, const char *user)
agent = libssh2_agent_init(s->session);
if (!agent) {
ret = -EINVAL;
session_error_report(s, "failed to initialize ssh-agent support");
session_error_setg(errp, s, "failed to initialize ssh-agent support");
goto out;
}
if (libssh2_agent_connect(agent)) {
ret = -ECONNREFUSED;
session_error_report(s, "failed to connect to ssh-agent");
session_error_setg(errp, s, "failed to connect to ssh-agent");
goto out;
}
if (libssh2_agent_list_identities(agent)) {
ret = -EINVAL;
session_error_report(s, "failed requesting identities from ssh-agent");
session_error_setg(errp, s,
"failed requesting identities from ssh-agent");
goto out;
}
@@ -447,7 +481,8 @@ static int authenticate(BDRVSSHState *s, const char *user)
}
if (r < 0) {
ret = -EINVAL;
session_error_report(s, "failed to obtain identity from ssh-agent");
session_error_setg(errp, s,
"failed to obtain identity from ssh-agent");
goto out;
}
r = libssh2_agent_userauth(agent, user, identity);
@@ -461,8 +496,8 @@ static int authenticate(BDRVSSHState *s, const char *user)
}
ret = -EPERM;
error_report("failed to authenticate using publickey authentication "
"and the identities held by your ssh-agent");
error_setg(errp, "failed to authenticate using publickey authentication "
"and the identities held by your ssh-agent");
out:
if (agent != NULL) {
@@ -476,10 +511,9 @@ static int authenticate(BDRVSSHState *s, const char *user)
}
static int connect_to_ssh(BDRVSSHState *s, QDict *options,
int ssh_flags, int creat_mode)
int ssh_flags, int creat_mode, Error **errp)
{
int r, ret;
Error *err = NULL;
const char *host, *user, *path, *host_key_check;
int port;
@@ -498,6 +532,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
} else {
user = g_get_user_name();
if (!user) {
error_setg_errno(errp, errno, "Can't get user name");
ret = -errno;
goto err;
}
@@ -514,11 +549,9 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
s->hostport = g_strdup_printf("%s:%d", host, port);
/* Open the socket and connect. */
s->sock = inet_connect(s->hostport, &err);
if (err != NULL) {
s->sock = inet_connect(s->hostport, errp);
if (s->sock < 0) {
ret = -errno;
qerror_report_err(err);
error_free(err);
goto err;
}
@@ -526,7 +559,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
s->session = libssh2_session_init();
if (!s->session) {
ret = -EINVAL;
session_error_report(s, "failed to initialize libssh2 session");
session_error_setg(errp, s, "failed to initialize libssh2 session");
goto err;
}
@@ -537,18 +570,18 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
r = libssh2_session_handshake(s->session, s->sock);
if (r != 0) {
ret = -EINVAL;
session_error_report(s, "failed to establish SSH session");
session_error_setg(errp, s, "failed to establish SSH session");
goto err;
}
/* Check the remote host's key against known_hosts. */
ret = check_host_key(s, host, port, host_key_check);
ret = check_host_key(s, host, port, host_key_check, errp);
if (ret < 0) {
goto err;
}
/* Authenticate. */
ret = authenticate(s, user);
ret = authenticate(s, user, errp);
if (ret < 0) {
goto err;
}
@@ -556,7 +589,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
/* Start SFTP. */
s->sftp = libssh2_sftp_init(s->session);
if (!s->sftp) {
session_error_report(s, "failed to initialize sftp handle");
session_error_setg(errp, s, "failed to initialize sftp handle");
ret = -EINVAL;
goto err;
}
@@ -566,14 +599,14 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
path, ssh_flags, creat_mode);
s->sftp_handle = libssh2_sftp_open(s->sftp, path, ssh_flags, creat_mode);
if (!s->sftp_handle) {
session_error_report(s, "failed to open remote file '%s'", path);
session_error_setg(errp, s, "failed to open remote file '%s'", path);
ret = -EINVAL;
goto err;
}
r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs);
if (r < 0) {
sftp_error_report(s, "failed to read file attributes");
sftp_error_setg(errp, s, "failed to read file attributes");
return -EINVAL;
}
@@ -623,7 +656,7 @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
}
/* Start up SSH. */
ret = connect_to_ssh(s, options, ssh_flags, 0);
ret = connect_to_ssh(s, options, ssh_flags, 0, errp);
if (ret < 0) {
goto err;
}
@@ -655,7 +688,6 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
{
int r, ret;
Error *local_err = NULL;
int64_t total_size = 0;
QDict *uri_options = NULL;
BDRVSSHState s;
@@ -674,17 +706,16 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options,
DPRINTF("total_size=%" PRIi64, total_size);
uri_options = qdict_new();
r = parse_uri(filename, uri_options, &local_err);
r = parse_uri(filename, uri_options, errp);
if (r < 0) {
qerror_report_err(local_err);
error_free(local_err);
ret = r;
goto out;
}
r = connect_to_ssh(&s, uri_options,
LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE|
LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, 0644);
LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
0644, errp);
if (r < 0) {
ret = r;
goto out;
@@ -694,7 +725,7 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options,
libssh2_sftp_seek64(s.sftp_handle, total_size-1);
r2 = libssh2_sftp_write(s.sftp_handle, c, 1);
if (r2 < 0) {
sftp_error_report(&s, "truncate failed");
sftp_error_setg(errp, &s, "truncate failed");
ret = -EINVAL;
goto out;
}

View File

@@ -60,7 +60,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
/* Must assign before bdrv_delete() to prevent traversing dangling pointer
* while we delete backing image instances.
*/
top->backing_hd = base;
bdrv_set_backing_hd(top, base);
while (intermediate) {
BlockDriverState *unused;
@@ -72,7 +72,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
unused = intermediate;
intermediate = intermediate->backing_hd;
unused->backing_hd = NULL;
bdrv_set_backing_hd(unused, NULL);
bdrv_unref(unused);
}

View File

@@ -473,7 +473,14 @@ static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,
} else if (h2_seq > h1_seq) {
s->curr_header = 1;
} else {
goto fail;
/* The Microsoft Disk2VHD tool will create 2 identical
* headers, with identical sequence numbers. If the headers are
* identical, don't consider the file corrupt */
if (!memcmp(header1, header2, sizeof(VHDXHeader))) {
s->curr_header = 0;
} else {
goto fail;
}
}
}

View File

@@ -1534,7 +1534,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
int ret, i;
BlockDriverState *bs = NULL;
VMDK4Header header;
Error *local_err;
Error *local_err = NULL;
uint32_t tmp, magic, grains, gd_sectors, gt_size, gt_count;
uint32_t *gd_buf = NULL;
int gd_buf_size;
@@ -1700,7 +1700,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
{
int idx = 0;
BlockDriverState *new_bs = NULL;
Error *local_err;
Error *local_err = NULL;
char *desc = NULL;
int64_t total_size = 0, filesize;
const char *adapter_type = NULL;
@@ -1881,7 +1881,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
} else {
ret = bdrv_create_file(filename, options, &local_err);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create image file");
error_propagate(errp, local_err);
goto exit;
}
}
@@ -1889,7 +1889,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
ret = bdrv_open(&new_bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not write description");
error_propagate(errp, local_err);
goto exit;
}
ret = bdrv_pwrite(new_bs, desc_offset, desc, desc_len);

View File

@@ -787,7 +787,9 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
s->current_mapping->path=buffer;
s->current_mapping->read_only =
(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
}
} else {
g_free(buffer);
}
}
closedir(dir);
@@ -831,7 +833,8 @@ static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
}
static int init_directories(BDRVVVFATState* s,
const char *dirname, int heads, int secs)
const char *dirname, int heads, int secs,
Error **errp)
{
bootsector_t* bootsector;
mapping_t* mapping;
@@ -892,8 +895,8 @@ static int init_directories(BDRVVVFATState* s,
if (mapping->mode & MODE_DIRECTORY) {
mapping->begin = cluster;
if(read_directory(s, i)) {
fprintf(stderr, "Could not read directory %s\n",
mapping->path);
error_setg(errp, "Could not read directory %s",
mapping->path);
return -1;
}
mapping = array_get(&(s->mapping), i);
@@ -919,9 +922,10 @@ static int init_directories(BDRVVVFATState* s,
cluster = mapping->end;
if(cluster > s->cluster_count) {
fprintf(stderr,"Directory does not fit in FAT%d (capacity %.2f MB)\n",
s->fat_type, s->sector_count / 2000.0);
return -EINVAL;
error_setg(errp,
"Directory does not fit in FAT%d (capacity %.2f MB)",
s->fat_type, s->sector_count / 2000.0);
return -1;
}
/* fix fat for entry */
@@ -979,7 +983,7 @@ static int init_directories(BDRVVVFATState* s,
static BDRVVVFATState *vvv = NULL;
#endif
static int enable_write_target(BDRVVVFATState *s);
static int enable_write_target(BDRVVVFATState *s, Error **errp);
static int is_consistent(BDRVVVFATState *s);
static void vvfat_rebind(BlockDriverState *bs)
@@ -1160,7 +1164,7 @@ DLOG(if (stderr == NULL) {
s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
if (qemu_opt_get_bool(opts, "rw", false)) {
ret = enable_write_target(s);
ret = enable_write_target(s, errp);
if (ret < 0) {
goto fail;
}
@@ -1169,7 +1173,7 @@ DLOG(if (stderr == NULL) {
bs->total_sectors = cyls * heads * secs;
if (init_directories(s, dirname, heads, secs)) {
if (init_directories(s, dirname, heads, secs, errp)) {
ret = -EIO;
goto fail;
}
@@ -1864,7 +1868,7 @@ static int check_directory_consistency(BDRVVVFATState *s,
if (s->used_clusters[cluster_num] & USED_ANY) {
fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
return 0;
goto fail;
}
s->used_clusters[cluster_num] = USED_DIRECTORY;
@@ -2904,11 +2908,10 @@ static BlockDriver vvfat_write_target = {
.bdrv_close = write_target_close,
};
static int enable_write_target(BDRVVVFATState *s)
static int enable_write_target(BDRVVVFATState *s, Error **errp)
{
BlockDriver *bdrv_qcow;
QEMUOptionParameter *options;
Error *local_err = NULL;
int ret;
int size = sector2cluster(s, s->sector_count);
s->used_clusters = calloc(size, 1);
@@ -2918,6 +2921,7 @@ static int enable_write_target(BDRVVVFATState *s)
s->qcow_filename = g_malloc(1024);
ret = get_tmp_filename(s->qcow_filename, 1024);
if (ret < 0) {
error_setg_errno(errp, -ret, "can't create temporary file");
goto err;
}
@@ -2926,20 +2930,17 @@ static int enable_write_target(BDRVVVFATState *s)
set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, &local_err);
ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, errp);
free_option_parameters(options);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto err;
}
s->qcow = NULL;
ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow,
&local_err);
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH,
bdrv_qcow, errp);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto err;
}
@@ -2947,7 +2948,7 @@ static int enable_write_target(BDRVVVFATState *s)
unlink(s->qcow_filename);
#endif
s->bs->backing_hd = bdrv_new("", &error_abort);
bdrv_set_backing_hd(s->bs, bdrv_new("", &error_abort));
s->bs->backing_hd->drv = &vvfat_write_target;
s->bs->backing_hd->opaque = g_malloc(sizeof(void*));
*(void**)s->bs->backing_hd->opaque = s;

View File

@@ -27,8 +27,8 @@ static void nbd_accept(void *opaque)
socklen_t addr_len = sizeof(addr);
int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
if (fd >= 0) {
nbd_client_new(NULL, fd, nbd_client_put);
if (fd >= 0 && !nbd_client_new(NULL, fd, nbd_client_put)) {
close(fd);
}
}

View File

@@ -34,7 +34,6 @@
#include "hw/block/block.h"
#include "block/blockjob.h"
#include "monitor/monitor.h"
#include "qapi/qmp/qerror.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qapi/qmp/types.h"
@@ -288,6 +287,25 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp)
}
}
static inline int parse_enum_option(const char *lookup[], const char *buf,
int max, int def, Error **errp)
{
int i;
if (!buf) {
return def;
}
for (i = 0; i < max; i++) {
if (!strcmp(buf, lookup[i])) {
return i;
}
}
error_setg(errp, "invalid parameter value: %s", buf);
return def;
}
static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
{
if (throttle_conflicting(cfg)) {
@@ -324,6 +342,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
QemuOpts *opts;
const char *id;
bool has_driver_specific_opts;
BlockdevDetectZeroesOptions detect_zeroes;
BlockDriver *drv = NULL;
/* Check common options by copying from bs_opts to opts, all other options
@@ -332,7 +351,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);
if (error) {
error_propagate(errp, error);
return NULL;
goto err_no_opts;
}
qemu_opts_absorb_qdict(opts, bs_opts, &error);
@@ -452,6 +471,24 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
}
}
detect_zeroes =
parse_enum_option(BlockdevDetectZeroesOptions_lookup,
qemu_opt_get(opts, "detect-zeroes"),
BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
&error);
if (error) {
error_propagate(errp, error);
goto early_err;
}
if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&
!(bdrv_flags & BDRV_O_UNMAP)) {
error_setg(errp, "setting detect-zeroes to unmap is not allowed "
"without setting discard operation to unmap");
goto early_err;
}
/* init */
dinfo = g_malloc0(sizeof(*dinfo));
dinfo->id = g_strdup(qemu_opts_id(opts));
@@ -462,6 +499,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
}
dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
dinfo->bdrv->read_only = ro;
dinfo->bdrv->detect_zeroes = detect_zeroes;
dinfo->refcount = 1;
if (serial != NULL) {
dinfo->serial = g_strdup(serial);
@@ -526,8 +564,9 @@ bdrv_new_err:
g_free(dinfo->id);
g_free(dinfo);
early_err:
QDECREF(bs_opts);
qemu_opts_del(opts);
err_no_opts:
QDECREF(bs_opts);
return NULL;
}
@@ -691,7 +730,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
&error_abort);
qemu_opts_absorb_qdict(legacy_opts, bs_opts, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
goto fail;
}
@@ -901,9 +940,10 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
/* Actual block device init: Functionality shared with blockdev-add */
dinfo = blockdev_init(filename, bs_opts, &local_err);
bs_opts = NULL;
if (dinfo == NULL) {
if (local_err) {
qerror_report_err(local_err);
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
}
goto fail;
@@ -938,6 +978,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
fail:
qemu_opts_del(legacy_opts);
QDECREF(bs_opts);
return dinfo;
}
@@ -1295,8 +1336,8 @@ static void external_snapshot_prepare(BlkTransactionState *common,
return;
}
if (bdrv_in_use(state->old_bs)) {
error_set(errp, QERR_DEVICE_IN_USE, device);
if (bdrv_op_is_blocked(state->old_bs,
BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, errp)) {
return;
}
@@ -1518,8 +1559,7 @@ exit:
static void eject_device(BlockDriverState *bs, int force, Error **errp)
{
if (bdrv_in_use(bs)) {
error_set(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
return;
}
if (!bdrv_dev_has_removable_media(bs)) {
@@ -1721,14 +1761,16 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *id = qdict_get_str(qdict, "id");
BlockDriverState *bs;
Error *local_err = NULL;
bs = bdrv_find(id);
if (!bs) {
qerror_report(QERR_DEVICE_NOT_FOUND, id);
error_report("Device '%s' not found", id);
return -1;
}
if (bdrv_in_use(bs)) {
qerror_report(QERR_DEVICE_IN_USE, id);
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
return -1;
}
@@ -1849,6 +1891,10 @@ void qmp_block_stream(const char *device, bool has_base,
return;
}
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_STREAM, errp)) {
return;
}
if (base) {
base_bs = bdrv_find_backing_image(bs, base);
if (base_bs == NULL) {
@@ -1893,6 +1939,10 @@ void qmp_block_commit(const char *device,
return;
}
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT, errp)) {
return;
}
/* default top_bs is the active layer */
top_bs = bs;
@@ -1984,8 +2034,7 @@ void qmp_drive_backup(const char *device, const char *target,
}
}
if (bdrv_in_use(bs)) {
error_set(errp, QERR_DEVICE_IN_USE, device);
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
return;
}
@@ -2118,8 +2167,7 @@ void qmp_drive_mirror(const char *device, const char *target,
}
}
if (bdrv_in_use(bs)) {
error_set(errp, QERR_DEVICE_IN_USE, device);
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR, errp)) {
return;
}
@@ -2455,6 +2503,10 @@ QemuOptsList qemu_common_drive_opts = {
.name = "copy-on-read",
.type = QEMU_OPT_BOOL,
.help = "copy read data from backing file into image file",
},{
.name = "detect-zeroes",
.type = QEMU_OPT_STRING,
.help = "try to optimize zero writes (off, on, unmap)",
},
{ /* end of list */ }
},

View File

@@ -41,14 +41,16 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
{
BlockJob *job;
if (bs->job || bdrv_in_use(bs)) {
if (bs->job) {
error_set(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
return NULL;
}
bdrv_ref(bs);
bdrv_set_in_use(bs, 1);
job = g_malloc0(driver->instance_size);
error_setg(&job->blocker, "block device is in use by block job: %s",
BlockJobType_lookup[driver->job_type]);
bdrv_op_block_all(bs, job->blocker);
job->driver = driver;
job->bs = bs;
job->cb = cb;
@@ -63,8 +65,9 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
block_job_set_speed(job, speed, &local_err);
if (local_err) {
bs->job = NULL;
bdrv_op_unblock_all(bs, job->blocker);
error_free(job->blocker);
g_free(job);
bdrv_set_in_use(bs, 0);
error_propagate(errp, local_err);
return NULL;
}
@@ -79,8 +82,9 @@ void block_job_completed(BlockJob *job, int ret)
assert(bs->job == job);
job->cb(job->opaque, ret);
bs->job = NULL;
bdrv_op_unblock_all(bs, job->blocker);
error_free(job->blocker);
g_free(job);
bdrv_set_in_use(bs, 0);
}
void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)

View File

@@ -1003,8 +1003,6 @@ int main(int argc, char **argv)
cpu->opaque = ts;
#if defined(TARGET_I386)
cpu_x86_set_cpl(env, 3);
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
env->hflags |= HF_PE_MASK;
if (env->features[FEAT_1_EDX] & CPUID_SSE) {

68
configure vendored
View File

@@ -2,26 +2,28 @@
#
# qemu configure script (c) 2003 Fabrice Bellard
#
# set temporary file name
if test ! -z "$TMPDIR" ; then
TMPDIR1="${TMPDIR}"
elif test ! -z "$TEMPDIR" ; then
TMPDIR1="${TEMPDIR}"
else
TMPDIR1="/tmp"
# Temporary directory used for files created while
# configure runs. Since it is in the build directory
# we can safely blow away any previous version of it
# (and we need not jump through hoops to try to delete
# it when configure exits.)
TMPDIR1="config-temp"
rm -rf "${TMPDIR1}"
mkdir -p "${TMPDIR1}"
if [ $? -ne 0 ]; then
echo "ERROR: failed to create temporary directory"
exit 1
fi
TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c"
TMPB="qemu-conf-${RANDOM}-$$-${RANDOM}"
TMPB="qemu-conf"
TMPC="${TMPDIR1}/${TMPB}.c"
TMPO="${TMPDIR1}/${TMPB}.o"
TMPCXX="${TMPDIR1}/${TMPB}.cxx"
TMPL="${TMPDIR1}/${TMPB}.lo"
TMPA="${TMPDIR1}/lib${TMPB}.la"
TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
TMPE="${TMPDIR1}/${TMPB}.exe"
# NB: do not call "exit" in the trap handler; this is buggy with some shells;
# see <1285349658-3122-1-git-send-email-loic.minier@linaro.org>
trap "rm -f $TMPC $TMPO $TMPCXX $TMPE" EXIT INT QUIT TERM
rm -f config.log
# Print a helpful header at the top of config.log
@@ -317,7 +319,7 @@ glusterfs_discard="no"
glusterfs_zerofill="no"
virtio_blk_data_plane=""
gtk=""
gtkabi="2.0"
gtkabi=""
vte=""
tpm="no"
libssh2=""
@@ -1137,11 +1139,11 @@ case "$cpu" in
CPU_CFLAGS="-m64 -mcpu=ultrasparc"
;;
s390)
CPU_CFLAGS="-m31 -march=z990"
CPU_CFLAGS="-m31"
LDFLAGS="-m31 $LDFLAGS"
;;
s390x)
CPU_CFLAGS="-m64 -march=z990"
CPU_CFLAGS="-m64"
LDFLAGS="-m64 $LDFLAGS"
;;
i386)
@@ -1970,6 +1972,18 @@ fi
##########################################
# GTK probe
if test "$gtkabi" = ""; then
# The GTK ABI was not specified explicitly, so try whether 2.0 is available.
# Use 3.0 as a fallback if that is available.
if $pkg_config --exists "gtk+-2.0 >= 2.18.0"; then
gtkabi=2.0
elif $pkg_config --exists "gtk+-3.0 >= 3.0.0"; then
gtkabi=3.0
else
gtkabi=2.0
fi
fi
if test "$gtk" != "no"; then
gtkpackage="gtk+-$gtkabi"
if test "$gtkabi" = "3.0" ; then
@@ -1983,7 +1997,7 @@ if test "$gtk" != "no"; then
libs_softmmu="$gtk_libs $libs_softmmu"
gtk="yes"
elif test "$gtk" = "yes"; then
feature_not_found "gtk" "Install gtk2 or gtk3 (requires --with-gtkabi=3.0 option to configure) devel"
feature_not_found "gtk" "Install gtk2 or gtk3 devel"
else
gtk="no"
fi
@@ -2006,7 +2020,11 @@ if test "$vte" != "no"; then
libs_softmmu="$vte_libs $libs_softmmu"
vte="yes"
elif test "$vte" = "yes"; then
feature_not_found "vte" "Install libvte or libvte-2.90 (requires --with-gtkabi=3.0 option to configure) devel"
if test "$gtkabi" = "3.0"; then
feature_not_found "vte" "Install libvte-2.90 devel"
else
feature_not_found "vte" "Install libvte devel"
fi
else
vte="no"
fi
@@ -4029,11 +4047,14 @@ fi
if test "$pie" = "no" ; then
textseg_addr=
case "$cpu" in
arm | hppa | i386 | m68k | ppc | ppc64 | s390* | sparc | sparc64 | x86_64 | x32)
arm | i386 | ppc* | s390* | sparc* | x86_64 | x32)
# ??? Rationale for choosing this address
textseg_addr=0x60000000
;;
mips)
textseg_addr=0x400000
# A 256M aligned address, high in the address space, with enough
# room for the code_gen_buffer above it before the stack.
textseg_addr=0x60000000
;;
esac
if [ -n "$textseg_addr" ]; then
@@ -4768,12 +4789,6 @@ if test "$gcov" = "yes" ; then
echo "GCOV=$gcov_tool" >> $config_host_mak
fi
iotests_common_env="tests/qemu-iotests/common.env"
echo "# Automatically generated by configure - do not modify" > $iotests_common_env
echo >> $iotests_common_env
echo "PYTHON='$python'" >> $iotests_common_env
# use included Linux headers
if test "$linux" = "yes" ; then
mkdir -p linux-headers
@@ -5225,3 +5240,4 @@ printf " '%s'" "$0" "$@" >>config.status
echo >>config.status
chmod +x config.status
rm -r "$TMPDIR1"

View File

@@ -335,6 +335,18 @@ int cpu_exec(CPUArchState *env)
cpu_loop_exit(cpu);
}
#endif
#if defined(TARGET_I386)
if (interrupt_request & CPU_INTERRUPT_INIT) {
cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);
do_cpu_init(x86_cpu);
cpu->exception_index = EXCP_HALTED;
cpu_loop_exit(cpu);
}
#else
if (interrupt_request & CPU_INTERRUPT_RESET) {
cpu_reset(cpu);
}
#endif
#if defined(TARGET_I386)
#if !defined(CONFIG_USER_ONLY)
if (interrupt_request & CPU_INTERRUPT_POLL) {
@@ -342,13 +354,7 @@ int cpu_exec(CPUArchState *env)
apic_poll_irq(x86_cpu->apic_state);
}
#endif
if (interrupt_request & CPU_INTERRUPT_INIT) {
cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
0);
do_cpu_init(x86_cpu);
cpu->exception_index = EXCP_HALTED;
cpu_loop_exit(cpu);
} else if (interrupt_request & CPU_INTERRUPT_SIPI) {
if (interrupt_request & CPU_INTERRUPT_SIPI) {
do_cpu_sipi(x86_cpu);
} else if (env->hflags2 & HF2_GIF_MASK) {
if ((interrupt_request & CPU_INTERRUPT_SMI) &&
@@ -405,9 +411,6 @@ int cpu_exec(CPUArchState *env)
}
}
#elif defined(TARGET_PPC)
if ((interrupt_request & CPU_INTERRUPT_RESET)) {
cpu_reset(cpu);
}
if (interrupt_request & CPU_INTERRUPT_HARD) {
ppc_hw_interrupt(env);
if (env->pending_interrupts == 0) {

3
cpus.c
View File

@@ -430,8 +430,7 @@ static const VMStateDescription vmstate_timers = {
.name = "timer",
.version_id = 2,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_INT64(cpu_ticks_offset, TimersState),
VMSTATE_INT64(dummy, TimersState),
VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),

View File

@@ -1,3 +1,4 @@
CONFIG_VIRTIO=y
CONFIG_SCLPCONSOLE=y
CONFIG_S390_FLIC=$(CONFIG_KVM)
CONFIG_S390_FLIC=y
CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)

File diff suppressed because it is too large Load Diff

View File

@@ -116,6 +116,8 @@ V_(ImmCmpBranch, 23, 5, SignedBits) \
V_(ImmLLiteral, 23, 5, SignedBits) \
V_(ImmException, 20, 5, Bits) \
V_(ImmHint, 11, 5, Bits) \
V_(ImmBarrierDomain, 11, 10, Bits) \
V_(ImmBarrierType, 9, 8, Bits) \
\
/* System (MRS, MSR) */ \
V_(ImmSystemRegister, 19, 5, Bits) \
@@ -181,7 +183,7 @@ enum Condition {
inline Condition InvertCondition(Condition cond) {
// Conditions al and nv behave identically, as "always true". They can't be
// inverted, because there is no "always false" condition.
ASSERT((cond != al) && (cond != nv));
VIXL_ASSERT((cond != al) && (cond != nv));
return static_cast<Condition>(cond ^ 1);
}
@@ -246,6 +248,20 @@ enum SystemHint {
SEVL = 5
};
enum BarrierDomain {
OuterShareable = 0,
NonShareable = 1,
InnerShareable = 2,
FullSystem = 3
};
enum BarrierType {
BarrierOther = 0,
BarrierReads = 1,
BarrierWrites = 2,
BarrierAll = 3
};
// System/special register names.
// This information is not encoded as one field but as the concatenation of
// multiple fields (Op0<0>, Op1, Crn, Crm, Op2).
@@ -274,7 +290,7 @@ enum SystemRegister {
//
// The enumerations can be used like this:
//
// ASSERT(instr->Mask(PCRelAddressingFMask) == PCRelAddressingFixed);
// VIXL_ASSERT(instr->Mask(PCRelAddressingFMask) == PCRelAddressingFixed);
// switch(instr->Mask(PCRelAddressingMask)) {
// case ADR: Format("adr 'Xd, 'AddrPCRelByte"); break;
// case ADRP: Format("adrp 'Xd, 'AddrPCRelPage"); break;
@@ -560,6 +576,15 @@ enum ExceptionOp {
DCPS3 = ExceptionFixed | 0x00A00003
};
enum MemBarrierOp {
MemBarrierFixed = 0xD503309F,
MemBarrierFMask = 0xFFFFF09F,
MemBarrierMask = 0xFFFFF0FF,
DSB = MemBarrierFixed | 0x00000000,
DMB = MemBarrierFixed | 0x00000020,
ISB = MemBarrierFixed | 0x00000040
};
// Any load or store.
enum LoadStoreAnyOp {
LoadStoreAnyFMask = 0x0a000000,
@@ -927,17 +952,22 @@ enum FPDataProcessing1SourceOp {
FRINTN = FRINTN_s,
FRINTP_s = FPDataProcessing1SourceFixed | 0x00048000,
FRINTP_d = FPDataProcessing1SourceFixed | FP64 | 0x00048000,
FRINTP = FRINTP_s,
FRINTM_s = FPDataProcessing1SourceFixed | 0x00050000,
FRINTM_d = FPDataProcessing1SourceFixed | FP64 | 0x00050000,
FRINTM = FRINTM_s,
FRINTZ_s = FPDataProcessing1SourceFixed | 0x00058000,
FRINTZ_d = FPDataProcessing1SourceFixed | FP64 | 0x00058000,
FRINTZ = FRINTZ_s,
FRINTA_s = FPDataProcessing1SourceFixed | 0x00060000,
FRINTA_d = FPDataProcessing1SourceFixed | FP64 | 0x00060000,
FRINTA = FRINTA_s,
FRINTX_s = FPDataProcessing1SourceFixed | 0x00070000,
FRINTX_d = FPDataProcessing1SourceFixed | FP64 | 0x00070000,
FRINTX = FRINTX_s,
FRINTI_s = FPDataProcessing1SourceFixed | 0x00078000,
FRINTI_d = FPDataProcessing1SourceFixed | FP64 | 0x00078000
FRINTI_d = FPDataProcessing1SourceFixed | FP64 | 0x00078000,
FRINTI = FRINTI_s
};
// Floating point data processing 2 source.

View File

@@ -132,7 +132,7 @@ void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,
}
// We reached the end of the list. The last element must be
// registered_visitor.
ASSERT(*it == registered_visitor);
VIXL_ASSERT(*it == registered_visitor);
visitors_.insert(it, new_visitor);
}
@@ -150,7 +150,7 @@ void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,
}
// We reached the end of the list. The last element must be
// registered_visitor.
ASSERT(*it == registered_visitor);
VIXL_ASSERT(*it == registered_visitor);
visitors_.push_back(new_visitor);
}
@@ -161,16 +161,16 @@ void Decoder::RemoveVisitor(DecoderVisitor* visitor) {
void Decoder::DecodePCRelAddressing(Instruction* instr) {
ASSERT(instr->Bits(27, 24) == 0x0);
VIXL_ASSERT(instr->Bits(27, 24) == 0x0);
// We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level
// decode.
ASSERT(instr->Bit(28) == 0x1);
VIXL_ASSERT(instr->Bit(28) == 0x1);
VisitPCRelAddressing(instr);
}
void Decoder::DecodeBranchSystemException(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0x4) ||
VIXL_ASSERT((instr->Bits(27, 24) == 0x4) ||
(instr->Bits(27, 24) == 0x5) ||
(instr->Bits(27, 24) == 0x6) ||
(instr->Bits(27, 24) == 0x7) );
@@ -271,7 +271,7 @@ void Decoder::DecodeBranchSystemException(Instruction* instr) {
void Decoder::DecodeLoadStore(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0x8) ||
VIXL_ASSERT((instr->Bits(27, 24) == 0x8) ||
(instr->Bits(27, 24) == 0x9) ||
(instr->Bits(27, 24) == 0xC) ||
(instr->Bits(27, 24) == 0xD) );
@@ -390,7 +390,7 @@ void Decoder::DecodeLoadStore(Instruction* instr) {
void Decoder::DecodeLogical(Instruction* instr) {
ASSERT(instr->Bits(27, 24) == 0x2);
VIXL_ASSERT(instr->Bits(27, 24) == 0x2);
if (instr->Mask(0x80400000) == 0x00400000) {
VisitUnallocated(instr);
@@ -409,7 +409,7 @@ void Decoder::DecodeLogical(Instruction* instr) {
void Decoder::DecodeBitfieldExtract(Instruction* instr) {
ASSERT(instr->Bits(27, 24) == 0x3);
VIXL_ASSERT(instr->Bits(27, 24) == 0x3);
if ((instr->Mask(0x80400000) == 0x80000000) ||
(instr->Mask(0x80400000) == 0x00400000) ||
@@ -434,7 +434,7 @@ void Decoder::DecodeBitfieldExtract(Instruction* instr) {
void Decoder::DecodeAddSubImmediate(Instruction* instr) {
ASSERT(instr->Bits(27, 24) == 0x1);
VIXL_ASSERT(instr->Bits(27, 24) == 0x1);
if (instr->Bit(23) == 1) {
VisitUnallocated(instr);
} else {
@@ -444,8 +444,8 @@ void Decoder::DecodeAddSubImmediate(Instruction* instr) {
void Decoder::DecodeDataProcessing(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0xA) ||
(instr->Bits(27, 24) == 0xB) );
VIXL_ASSERT((instr->Bits(27, 24) == 0xA) ||
(instr->Bits(27, 24) == 0xB));
if (instr->Bit(24) == 0) {
if (instr->Bit(28) == 0) {
@@ -559,8 +559,8 @@ void Decoder::DecodeDataProcessing(Instruction* instr) {
void Decoder::DecodeFP(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0xE) ||
(instr->Bits(27, 24) == 0xF) );
VIXL_ASSERT((instr->Bits(27, 24) == 0xE) ||
(instr->Bits(27, 24) == 0xF));
if (instr->Bit(28) == 0) {
DecodeAdvSIMDDataProcessing(instr);
@@ -665,14 +665,14 @@ void Decoder::DecodeFP(Instruction* instr) {
VisitFPConditionalSelect(instr);
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
}
}
}
} else {
// Bit 30 == 1 has been handled earlier.
ASSERT(instr->Bit(30) == 0);
VIXL_ASSERT(instr->Bit(30) == 0);
if (instr->Mask(0xA0800000) != 0) {
VisitUnallocated(instr);
} else {
@@ -687,21 +687,21 @@ void Decoder::DecodeFP(Instruction* instr) {
void Decoder::DecodeAdvSIMDLoadStore(Instruction* instr) {
// TODO: Implement Advanced SIMD load/store instruction decode.
ASSERT(instr->Bits(29, 25) == 0x6);
VIXL_ASSERT(instr->Bits(29, 25) == 0x6);
VisitUnimplemented(instr);
}
void Decoder::DecodeAdvSIMDDataProcessing(Instruction* instr) {
// TODO: Implement Advanced SIMD data processing instruction decode.
ASSERT(instr->Bits(27, 25) == 0x7);
VIXL_ASSERT(instr->Bits(27, 25) == 0x7);
VisitUnimplemented(instr);
}
#define DEFINE_VISITOR_CALLERS(A) \
void Decoder::Visit##A(Instruction *instr) { \
ASSERT(instr->Mask(A##FMask) == A##Fixed); \
VIXL_ASSERT(instr->Mask(A##FMask) == A##Fixed); \
std::list<DecoderVisitor*>::iterator it; \
for (it = visitors_.begin(); it != visitors_.end(); it++) { \
(*it)->Visit##A(instr); \

View File

@@ -95,7 +95,7 @@ void Disassembler::VisitAddSubImmediate(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -142,7 +142,7 @@ void Disassembler::VisitAddSubShifted(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -180,7 +180,7 @@ void Disassembler::VisitAddSubExtended(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -215,7 +215,7 @@ void Disassembler::VisitAddSubWithCarry(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -258,30 +258,30 @@ void Disassembler::VisitLogicalImmediate(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
bool Disassembler::IsMovzMovnImm(unsigned reg_size, uint64_t value) {
ASSERT((reg_size == kXRegSize) ||
((reg_size == kWRegSize) && (value <= 0xffffffff)));
VIXL_ASSERT((reg_size == kXRegSize) ||
((reg_size == kWRegSize) && (value <= 0xffffffff)));
// Test for movz: 16 bits set at positions 0, 16, 32 or 48.
if (((value & 0xffffffffffff0000ULL) == 0ULL) ||
((value & 0xffffffff0000ffffULL) == 0ULL) ||
((value & 0xffff0000ffffffffULL) == 0ULL) ||
((value & 0x0000ffffffffffffULL) == 0ULL)) {
if (((value & UINT64_C(0xffffffffffff0000)) == 0) ||
((value & UINT64_C(0xffffffff0000ffff)) == 0) ||
((value & UINT64_C(0xffff0000ffffffff)) == 0) ||
((value & UINT64_C(0x0000ffffffffffff)) == 0)) {
return true;
}
// Test for movn: NOT(16 bits set at positions 0, 16, 32 or 48).
if ((reg_size == kXRegSize) &&
(((value & 0xffffffffffff0000ULL) == 0xffffffffffff0000ULL) ||
((value & 0xffffffff0000ffffULL) == 0xffffffff0000ffffULL) ||
((value & 0xffff0000ffffffffULL) == 0xffff0000ffffffffULL) ||
((value & 0x0000ffffffffffffULL) == 0x0000ffffffffffffULL))) {
(((~value & UINT64_C(0xffffffffffff0000)) == 0) ||
((~value & UINT64_C(0xffffffff0000ffff)) == 0) ||
((~value & UINT64_C(0xffff0000ffffffff)) == 0) ||
((~value & UINT64_C(0x0000ffffffffffff)) == 0))) {
return true;
}
if ((reg_size == kWRegSize) &&
@@ -337,7 +337,7 @@ void Disassembler::VisitLogicalShifted(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
@@ -353,7 +353,7 @@ void Disassembler::VisitConditionalCompareRegister(Instruction* instr) {
case CCMN_x: mnemonic = "ccmn"; break;
case CCMP_w:
case CCMP_x: mnemonic = "ccmp"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -368,7 +368,7 @@ void Disassembler::VisitConditionalCompareImmediate(Instruction* instr) {
case CCMN_x_imm: mnemonic = "ccmn"; break;
case CCMP_w_imm:
case CCMP_x_imm: mnemonic = "ccmp"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -421,7 +421,7 @@ void Disassembler::VisitConditionalSelect(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -520,7 +520,7 @@ void Disassembler::VisitExtract(Instruction* instr) {
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -538,7 +538,7 @@ void Disassembler::VisitPCRelAddressing(Instruction* instr) {
void Disassembler::VisitConditionalBranch(Instruction* instr) {
switch (instr->Mask(ConditionalBranchMask)) {
case B_cond: Format(instr, "b.'CBrn", "'BImmCond"); break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
}
@@ -570,7 +570,7 @@ void Disassembler::VisitUnconditionalBranch(Instruction* instr) {
switch (instr->Mask(UnconditionalBranchMask)) {
case B: mnemonic = "b"; break;
case BL: mnemonic = "bl"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -591,7 +591,7 @@ void Disassembler::VisitDataProcessing1Source(Instruction* instr) {
FORMAT(CLS, "cls");
#undef FORMAT
case REV32_x: mnemonic = "rev32"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -690,7 +690,7 @@ void Disassembler::VisitDataProcessing3Source(Instruction* instr) {
form = form_xxx;
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -705,7 +705,7 @@ void Disassembler::VisitCompareBranch(Instruction* instr) {
case CBZ_x: mnemonic = "cbz"; break;
case CBNZ_w:
case CBNZ_x: mnemonic = "cbnz"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -722,7 +722,7 @@ void Disassembler::VisitTestBranch(Instruction* instr) {
switch (instr->Mask(TestBranchMask)) {
case TBZ: mnemonic = "tbz"; break;
case TBNZ: mnemonic = "tbnz"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -742,7 +742,7 @@ void Disassembler::VisitMoveWideImmediate(Instruction* instr) {
case MOVZ_x: mnemonic = "movz"; break;
case MOVK_w:
case MOVK_x: mnemonic = "movk"; form = "'Rd, 'IMoveLSL"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -981,7 +981,7 @@ void Disassembler::VisitFPConditionalSelect(Instruction* instr) {
switch (instr->Mask(FPConditionalSelectMask)) {
case FCSEL_s:
case FCSEL_d: mnemonic = "fcsel"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -1033,7 +1033,7 @@ void Disassembler::VisitFPDataProcessing2Source(Instruction* instr) {
FORMAT(FMINNM, "fminnm");
FORMAT(FNMUL, "fnmul");
#undef FORMAT
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -1052,7 +1052,7 @@ void Disassembler::VisitFPDataProcessing3Source(Instruction* instr) {
FORMAT(FNMADD, "fnmadd");
FORMAT(FNMSUB, "fnmsub");
#undef FORMAT
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -1065,7 +1065,7 @@ void Disassembler::VisitFPImmediate(Instruction* instr) {
switch (instr->Mask(FPImmediateMask)) {
case FMOV_s_imm: mnemonic = "fmov"; form = "'Sd, 'IFPSingle"; break;
case FMOV_d_imm: mnemonic = "fmov"; form = "'Dd, 'IFPDouble"; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -1082,6 +1082,14 @@ void Disassembler::VisitFPIntegerConvert(Instruction* instr) {
case FMOV_xd: mnemonic = "fmov"; form = form_rf; break;
case FMOV_sw:
case FMOV_dx: mnemonic = "fmov"; form = form_fr; break;
case FCVTAS_ws:
case FCVTAS_xs:
case FCVTAS_wd:
case FCVTAS_xd: mnemonic = "fcvtas"; form = form_rf; break;
case FCVTAU_ws:
case FCVTAU_xs:
case FCVTAU_wd:
case FCVTAU_xd: mnemonic = "fcvtau"; form = form_rf; break;
case FCVTMS_ws:
case FCVTMS_xs:
case FCVTMS_wd:
@@ -1141,7 +1149,7 @@ void Disassembler::VisitFPFixedPointConvert(Instruction* instr) {
case UCVTF_sx_fixed:
case UCVTF_dw_fixed:
case UCVTF_dx_fixed: mnemonic = "ucvtf"; form = form_fr; break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
Format(instr, mnemonic, form);
}
@@ -1176,7 +1184,7 @@ void Disassembler::VisitSystem(Instruction* instr) {
}
}
} else if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
ASSERT(instr->Mask(SystemHintMask) == HINT);
VIXL_ASSERT(instr->Mask(SystemHintMask) == HINT);
switch (instr->ImmHint()) {
case NOP: {
mnemonic = "nop";
@@ -1184,6 +1192,24 @@ void Disassembler::VisitSystem(Instruction* instr) {
break;
}
}
} else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) {
switch (instr->Mask(MemBarrierMask)) {
case DMB: {
mnemonic = "dmb";
form = "'M";
break;
}
case DSB: {
mnemonic = "dsb";
form = "'M";
break;
}
case ISB: {
mnemonic = "isb";
form = NULL;
break;
}
}
}
Format(instr, mnemonic, form);
@@ -1226,7 +1252,7 @@ void Disassembler::ProcessOutput(Instruction* /*instr*/) {
void Disassembler::Format(Instruction* instr, const char* mnemonic,
const char* format) {
ASSERT(mnemonic != NULL);
VIXL_ASSERT(mnemonic != NULL);
ResetOutput();
Substitute(instr, mnemonic);
if (format != NULL) {
@@ -1268,8 +1294,9 @@ int Disassembler::SubstituteField(Instruction* instr, const char* format) {
case 'A': return SubstitutePCRelAddressField(instr, format);
case 'B': return SubstituteBranchTargetField(instr, format);
case 'O': return SubstituteLSRegOffsetField(instr, format);
case 'M': return SubstituteBarrierField(instr, format);
default: {
UNREACHABLE();
VIXL_UNREACHABLE();
return 1;
}
}
@@ -1294,7 +1321,7 @@ int Disassembler::SubstituteRegisterField(Instruction* instr,
}
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
// Increase field length for registers tagged as stack.
@@ -1331,7 +1358,7 @@ int Disassembler::SubstituteRegisterField(Instruction* instr,
int Disassembler::SubstituteImmediateField(Instruction* instr,
const char* format) {
ASSERT(format[0] == 'I');
VIXL_ASSERT(format[0] == 'I');
switch (format[1]) {
case 'M': { // IMoveImm or IMoveLSL.
@@ -1339,10 +1366,10 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
uint64_t imm = instr->ImmMoveWide() << (16 * instr->ShiftMoveWide());
AppendToOutput("#0x%" PRIx64, imm);
} else {
ASSERT(format[5] == 'L');
VIXL_ASSERT(format[5] == 'L');
AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide());
if (instr->ShiftMoveWide() > 0) {
AppendToOutput(", lsl #%" PRId64, 16 * instr->ShiftMoveWide());
AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide());
}
}
return 8;
@@ -1384,14 +1411,14 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
return 6;
}
case 'A': { // IAddSub.
ASSERT(instr->ShiftAddSub() <= 1);
VIXL_ASSERT(instr->ShiftAddSub() <= 1);
int64_t imm = instr->ImmAddSub() << (12 * instr->ShiftAddSub());
AppendToOutput("#0x%" PRIx64 " (%" PRId64 ")", imm, imm);
return 7;
}
case 'F': { // IFPSingle, IFPDouble or IFPFBits.
if (format[3] == 'F') { // IFPFbits.
AppendToOutput("#%" PRId64, 64 - instr->FPScale());
AppendToOutput("#%d", 64 - instr->FPScale());
return 8;
} else {
AppendToOutput("#0x%" PRIx64 " (%.4f)", instr->ImmFP(),
@@ -1412,27 +1439,27 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
return 5;
}
case 'P': { // IP - Conditional compare.
AppendToOutput("#%" PRId64, instr->ImmCondCmp());
AppendToOutput("#%d", instr->ImmCondCmp());
return 2;
}
case 'B': { // Bitfields.
return SubstituteBitfieldImmediateField(instr, format);
}
case 'E': { // IExtract.
AppendToOutput("#%" PRId64, instr->ImmS());
AppendToOutput("#%d", instr->ImmS());
return 8;
}
case 'S': { // IS - Test and branch bit.
AppendToOutput("#%" PRId64, (instr->ImmTestBranchBit5() << 5) |
instr->ImmTestBranchBit40());
AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) |
instr->ImmTestBranchBit40());
return 2;
}
case 'D': { // IDebug - HLT and BRK instructions.
AppendToOutput("#0x%" PRIx64, instr->ImmException());
AppendToOutput("#0x%x", instr->ImmException());
return 6;
}
default: {
UNIMPLEMENTED();
VIXL_UNIMPLEMENTED();
return 0;
}
}
@@ -1441,7 +1468,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
int Disassembler::SubstituteBitfieldImmediateField(Instruction* instr,
const char* format) {
ASSERT((format[0] == 'I') && (format[1] == 'B'));
VIXL_ASSERT((format[0] == 'I') && (format[1] == 'B'));
unsigned r = instr->ImmR();
unsigned s = instr->ImmS();
@@ -1455,19 +1482,19 @@ int Disassembler::SubstituteBitfieldImmediateField(Instruction* instr,
AppendToOutput("#%d", s + 1);
return 5;
} else {
ASSERT(format[3] == '-');
VIXL_ASSERT(format[3] == '-');
AppendToOutput("#%d", s - r + 1);
return 7;
}
}
case 'Z': { // IBZ-r.
ASSERT((format[3] == '-') && (format[4] == 'r'));
VIXL_ASSERT((format[3] == '-') && (format[4] == 'r'));
unsigned reg_size = (instr->SixtyFourBits() == 1) ? kXRegSize : kWRegSize;
AppendToOutput("#%d", reg_size - r);
return 5;
}
default: {
UNREACHABLE();
VIXL_UNREACHABLE();
return 0;
}
}
@@ -1476,7 +1503,7 @@ int Disassembler::SubstituteBitfieldImmediateField(Instruction* instr,
int Disassembler::SubstituteLiteralField(Instruction* instr,
const char* format) {
ASSERT(strncmp(format, "LValue", 6) == 0);
VIXL_ASSERT(strncmp(format, "LValue", 6) == 0);
USE(format);
switch (instr->Mask(LoadLiteralMask)) {
@@ -1484,7 +1511,7 @@ int Disassembler::SubstituteLiteralField(Instruction* instr,
case LDR_x_lit:
case LDR_s_lit:
case LDR_d_lit: AppendToOutput("(addr %p)", instr->LiteralAddress()); break;
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
return 6;
@@ -1492,12 +1519,12 @@ int Disassembler::SubstituteLiteralField(Instruction* instr,
int Disassembler::SubstituteShiftField(Instruction* instr, const char* format) {
ASSERT(format[0] == 'H');
ASSERT(instr->ShiftDP() <= 0x3);
VIXL_ASSERT(format[0] == 'H');
VIXL_ASSERT(instr->ShiftDP() <= 0x3);
switch (format[1]) {
case 'D': { // HDP.
ASSERT(instr->ShiftDP() != ROR);
VIXL_ASSERT(instr->ShiftDP() != ROR);
} // Fall through.
case 'L': { // HLo.
if (instr->ImmDPShift() != 0) {
@@ -1508,7 +1535,7 @@ int Disassembler::SubstituteShiftField(Instruction* instr, const char* format) {
return 3;
}
default:
UNIMPLEMENTED();
VIXL_UNIMPLEMENTED();
return 0;
}
}
@@ -1516,7 +1543,7 @@ int Disassembler::SubstituteShiftField(Instruction* instr, const char* format) {
int Disassembler::SubstituteConditionField(Instruction* instr,
const char* format) {
ASSERT(format[0] == 'C');
VIXL_ASSERT(format[0] == 'C');
const char* condition_code[] = { "eq", "ne", "hs", "lo",
"mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt",
@@ -1538,27 +1565,27 @@ int Disassembler::SubstituteConditionField(Instruction* instr,
int Disassembler::SubstitutePCRelAddressField(Instruction* instr,
const char* format) {
USE(format);
ASSERT(strncmp(format, "AddrPCRel", 9) == 0);
VIXL_ASSERT(strncmp(format, "AddrPCRel", 9) == 0);
int offset = instr->ImmPCRel();
// Only ADR (AddrPCRelByte) is supported.
ASSERT(strcmp(format, "AddrPCRelByte") == 0);
VIXL_ASSERT(strcmp(format, "AddrPCRelByte") == 0);
char sign = '+';
if (offset < 0) {
offset = -offset;
sign = '-';
}
// TODO: Extend this to support printing the target address.
AppendToOutput("#%c0x%x", sign, offset);
VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
AppendToOutput("#%c0x%x (addr %p)", sign, offset, instr + offset);
return 13;
}
int Disassembler::SubstituteBranchTargetField(Instruction* instr,
const char* format) {
ASSERT(strncmp(format, "BImm", 4) == 0);
VIXL_ASSERT(strncmp(format, "BImm", 4) == 0);
int64_t offset = 0;
switch (format[5]) {
@@ -1570,7 +1597,7 @@ int Disassembler::SubstituteBranchTargetField(Instruction* instr,
case 'm': offset = instr->ImmCmpBranch(); break;
// BImmTest - test and branch immediate.
case 'e': offset = instr->ImmTestBranch(); break;
default: UNIMPLEMENTED();
default: VIXL_UNIMPLEMENTED();
}
offset <<= kInstructionSizeLog2;
char sign = '+';
@@ -1578,15 +1605,16 @@ int Disassembler::SubstituteBranchTargetField(Instruction* instr,
offset = -offset;
sign = '-';
}
AppendToOutput("#%c0x%" PRIx64, sign, offset);
VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset, instr + offset);
return 8;
}
int Disassembler::SubstituteExtendField(Instruction* instr,
const char* format) {
ASSERT(strncmp(format, "Ext", 3) == 0);
ASSERT(instr->ExtendMode() <= 7);
VIXL_ASSERT(strncmp(format, "Ext", 3) == 0);
VIXL_ASSERT(instr->ExtendMode() <= 7);
USE(format);
const char* extend_mode[] = { "uxtb", "uxth", "uxtw", "uxtx",
@@ -1598,12 +1626,12 @@ int Disassembler::SubstituteExtendField(Instruction* instr,
(((instr->ExtendMode() == UXTW) && (instr->SixtyFourBits() == 0)) ||
(instr->ExtendMode() == UXTX))) {
if (instr->ImmExtendShift() > 0) {
AppendToOutput(", lsl #%" PRId64, instr->ImmExtendShift());
AppendToOutput(", lsl #%d", instr->ImmExtendShift());
}
} else {
AppendToOutput(", %s", extend_mode[instr->ExtendMode()]);
if (instr->ImmExtendShift() > 0) {
AppendToOutput(" #%" PRId64, instr->ImmExtendShift());
AppendToOutput(" #%d", instr->ImmExtendShift());
}
}
return 3;
@@ -1612,7 +1640,7 @@ int Disassembler::SubstituteExtendField(Instruction* instr,
int Disassembler::SubstituteLSRegOffsetField(Instruction* instr,
const char* format) {
ASSERT(strncmp(format, "Offsetreg", 9) == 0);
VIXL_ASSERT(strncmp(format, "Offsetreg", 9) == 0);
const char* extend_mode[] = { "undefined", "undefined", "uxtw", "lsl",
"undefined", "undefined", "sxtw", "sxtx" };
USE(format);
@@ -1632,7 +1660,7 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr,
if (!((ext == UXTX) && (shift == 0))) {
AppendToOutput(", %s", extend_mode[ext]);
if (shift != 0) {
AppendToOutput(" #%" PRId64, instr->SizeLS());
AppendToOutput(" #%d", instr->SizeLS());
}
}
return 9;
@@ -1641,7 +1669,7 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr,
int Disassembler::SubstitutePrefetchField(Instruction* instr,
const char* format) {
ASSERT(format[0] == 'P');
VIXL_ASSERT(format[0] == 'P');
USE(format);
int prefetch_mode = instr->PrefetchMode();
@@ -1654,6 +1682,23 @@ int Disassembler::SubstitutePrefetchField(Instruction* instr,
return 6;
}
int Disassembler::SubstituteBarrierField(Instruction* instr,
const char* format) {
VIXL_ASSERT(format[0] == 'M');
USE(format);
static const char* options[4][4] = {
{ "sy (0b0000)", "oshld", "oshst", "osh" },
{ "sy (0b0100)", "nshld", "nshst", "nsh" },
{ "sy (0b1000)", "ishld", "ishst", "ish" },
{ "sy (0b1100)", "ld", "st", "sy" }
};
int domain = instr->ImmBarrierDomain();
int type = instr->ImmBarrierType();
AppendToOutput("%s", options[domain][type]);
return 1;
}
void Disassembler::ResetOutput() {
buffer_pos_ = 0;

View File

@@ -64,6 +64,7 @@ class Disassembler: public DecoderVisitor {
int SubstituteBranchTargetField(Instruction* instr, const char* format);
int SubstituteLSRegOffsetField(Instruction* instr, const char* format);
int SubstitutePrefetchField(Instruction* instr, const char* format);
int SubstituteBarrierField(Instruction* instr, const char* format);
inline bool RdIsZROrSP(Instruction* instr) const {
return (instr->Rd() == kZeroRegCode);

View File

@@ -33,20 +33,20 @@ namespace vixl {
static uint64_t RotateRight(uint64_t value,
unsigned int rotate,
unsigned int width) {
ASSERT(width <= 64);
VIXL_ASSERT(width <= 64);
rotate &= 63;
return ((value & ((1UL << rotate) - 1UL)) << (width - rotate)) |
(value >> rotate);
return ((value & ((UINT64_C(1) << rotate) - 1)) <<
(width - rotate)) | (value >> rotate);
}
static uint64_t RepeatBitsAcrossReg(unsigned reg_size,
uint64_t value,
unsigned width) {
ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) ||
(width == 32));
ASSERT((reg_size == kWRegSize) || (reg_size == kXRegSize));
uint64_t result = value & ((1UL << width) - 1UL);
VIXL_ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) ||
(width == 32));
VIXL_ASSERT((reg_size == kWRegSize) || (reg_size == kXRegSize));
uint64_t result = value & ((UINT64_C(1) << width) - 1);
for (unsigned i = width; i < reg_size; i *= 2) {
result |= (result << i);
}
@@ -84,7 +84,7 @@ uint64_t Instruction::ImmLogical() {
if (imm_s == 0x3F) {
return 0;
}
uint64_t bits = (1UL << (imm_s + 1)) - 1;
uint64_t bits = (UINT64_C(1) << (imm_s + 1)) - 1;
return RotateRight(bits, imm_r, 64);
} else {
if ((imm_s >> 1) == 0x1F) {
@@ -96,14 +96,14 @@ uint64_t Instruction::ImmLogical() {
if ((imm_s & mask) == mask) {
return 0;
}
uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1;
uint64_t bits = (UINT64_C(1) << ((imm_s & mask) + 1)) - 1;
return RepeatBitsAcrossReg(reg_size,
RotateRight(bits, imm_r & mask, width),
width);
}
}
}
UNREACHABLE();
VIXL_UNREACHABLE();
return 0;
}
@@ -155,7 +155,7 @@ Instruction* Instruction::ImmPCOffsetTarget() {
offset = ImmPCRel();
} else {
// All PC-relative branches.
ASSERT(BranchType() != UnknownBranchType);
VIXL_ASSERT(BranchType() != UnknownBranchType);
// Relative branch offsets are instruction-size-aligned.
offset = ImmBranch() << kInstructionSizeLog2;
}
@@ -169,7 +169,7 @@ inline int Instruction::ImmBranch() const {
case UncondBranchType: return ImmUncondBranch();
case CompareBranchType: return ImmCmpBranch();
case TestBranchType: return ImmTestBranch();
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
return 0;
}
@@ -186,7 +186,7 @@ void Instruction::SetImmPCOffsetTarget(Instruction* target) {
void Instruction::SetPCRelImmTarget(Instruction* target) {
// ADRP is not supported, so 'this' must point to an ADR instruction.
ASSERT(Mask(PCRelAddressingMask) == ADR);
VIXL_ASSERT(Mask(PCRelAddressingMask) == ADR);
Instr imm = Assembler::ImmPCRelAddress(target - this);
@@ -195,7 +195,7 @@ void Instruction::SetPCRelImmTarget(Instruction* target) {
void Instruction::SetBranchImmTarget(Instruction* target) {
ASSERT(((target - this) & 3) == 0);
VIXL_ASSERT(((target - this) & 3) == 0);
Instr branch_imm = 0;
uint32_t imm_mask = 0;
int offset = (target - this) >> kInstructionSizeLog2;
@@ -220,14 +220,14 @@ void Instruction::SetBranchImmTarget(Instruction* target) {
imm_mask = ImmTestBranch_mask;
break;
}
default: UNREACHABLE();
default: VIXL_UNREACHABLE();
}
SetInstructionBits(Mask(~imm_mask) | branch_imm);
}
void Instruction::SetImmLLiteral(Instruction* source) {
ASSERT(((source - this) & 3) == 0);
VIXL_ASSERT(((source - this) & 3) == 0);
int offset = (source - this) >> kLiteralEntrySizeLog2;
Instr imm = Assembler::ImmLLiteral(offset);
Instr mask = ImmLLiteral_mask;

View File

@@ -44,30 +44,36 @@ const unsigned kMaxLoadLiteralRange = 1 * MBytes;
const unsigned kWRegSize = 32;
const unsigned kWRegSizeLog2 = 5;
const unsigned kWRegSizeInBytes = kWRegSize / 8;
const unsigned kWRegSizeInBytesLog2 = kWRegSizeLog2 - 3;
const unsigned kXRegSize = 64;
const unsigned kXRegSizeLog2 = 6;
const unsigned kXRegSizeInBytes = kXRegSize / 8;
const unsigned kXRegSizeInBytesLog2 = kXRegSizeLog2 - 3;
const unsigned kSRegSize = 32;
const unsigned kSRegSizeLog2 = 5;
const unsigned kSRegSizeInBytes = kSRegSize / 8;
const unsigned kSRegSizeInBytesLog2 = kSRegSizeLog2 - 3;
const unsigned kDRegSize = 64;
const unsigned kDRegSizeLog2 = 6;
const unsigned kDRegSizeInBytes = kDRegSize / 8;
const int64_t kWRegMask = 0x00000000ffffffffLL;
const int64_t kXRegMask = 0xffffffffffffffffLL;
const int64_t kSRegMask = 0x00000000ffffffffLL;
const int64_t kDRegMask = 0xffffffffffffffffLL;
const int64_t kXSignMask = 0x1LL << 63;
const int64_t kWSignMask = 0x1LL << 31;
const int64_t kByteMask = 0xffL;
const int64_t kHalfWordMask = 0xffffL;
const int64_t kWordMask = 0xffffffffLL;
const uint64_t kXMaxUInt = 0xffffffffffffffffULL;
const uint64_t kWMaxUInt = 0xffffffffULL;
const int64_t kXMaxInt = 0x7fffffffffffffffLL;
const int64_t kXMinInt = 0x8000000000000000LL;
const int32_t kWMaxInt = 0x7fffffff;
const int32_t kWMinInt = 0x80000000;
const unsigned kDRegSizeInBytesLog2 = kDRegSizeLog2 - 3;
const uint64_t kWRegMask = UINT64_C(0xffffffff);
const uint64_t kXRegMask = UINT64_C(0xffffffffffffffff);
const uint64_t kSRegMask = UINT64_C(0xffffffff);
const uint64_t kDRegMask = UINT64_C(0xffffffffffffffff);
const uint64_t kSSignMask = UINT64_C(0x80000000);
const uint64_t kDSignMask = UINT64_C(0x8000000000000000);
const uint64_t kWSignMask = UINT64_C(0x80000000);
const uint64_t kXSignMask = UINT64_C(0x8000000000000000);
const uint64_t kByteMask = UINT64_C(0xff);
const uint64_t kHalfWordMask = UINT64_C(0xffff);
const uint64_t kWordMask = UINT64_C(0xffffffff);
const uint64_t kXMaxUInt = UINT64_C(0xffffffffffffffff);
const uint64_t kWMaxUInt = UINT64_C(0xffffffff);
const int64_t kXMaxInt = INT64_C(0x7fffffffffffffff);
const int64_t kXMinInt = INT64_C(0x8000000000000000);
const int32_t kWMaxInt = INT32_C(0x7fffffff);
const int32_t kWMinInt = INT32_C(0x80000000);
const unsigned kLinkRegCode = 30;
const unsigned kZeroRegCode = 31;
const unsigned kSPRegInternalCode = 63;
@@ -81,18 +87,28 @@ const unsigned kFloatExponentBits = 8;
const float kFP32PositiveInfinity = rawbits_to_float(0x7f800000);
const float kFP32NegativeInfinity = rawbits_to_float(0xff800000);
const double kFP64PositiveInfinity = rawbits_to_double(0x7ff0000000000000ULL);
const double kFP64NegativeInfinity = rawbits_to_double(0xfff0000000000000ULL);
const double kFP64PositiveInfinity =
rawbits_to_double(UINT64_C(0x7ff0000000000000));
const double kFP64NegativeInfinity =
rawbits_to_double(UINT64_C(0xfff0000000000000));
// This value is a signalling NaN as both a double and as a float (taking the
// least-significant word).
static const double kFP64SignallingNaN = rawbits_to_double(0x7ff000007f800001ULL);
static const double kFP64SignallingNaN =
rawbits_to_double(UINT64_C(0x7ff000007f800001));
static const float kFP32SignallingNaN = rawbits_to_float(0x7f800001);
// A similar value, but as a quiet NaN.
static const double kFP64QuietNaN = rawbits_to_double(0x7ff800007fc00001ULL);
static const double kFP64QuietNaN =
rawbits_to_double(UINT64_C(0x7ff800007fc00001));
static const float kFP32QuietNaN = rawbits_to_float(0x7fc00001);
// The default NaN values (for FPCR.DN=1).
static const double kFP64DefaultNaN =
rawbits_to_double(UINT64_C(0x7ff8000000000000));
static const float kFP32DefaultNaN = rawbits_to_float(0x7fc00000);
enum LSDataSize {
LSByte = 0,
LSHalfword = 1,
@@ -325,7 +341,7 @@ class Instruction {
}
inline Instruction* InstructionAtOffset(int64_t offset) {
ASSERT(IsWordAligned(this + offset));
VIXL_ASSERT(IsWordAligned(this + offset));
return this + offset;
}

View File

@@ -27,8 +27,20 @@
#ifndef VIXL_GLOBALS_H
#define VIXL_GLOBALS_H
// Get the standard printf format macros for C99 stdint types.
// Get standard C99 macros for integer types.
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>
@@ -45,21 +57,29 @@ typedef uint8_t byte;
const int KBytes = 1024;
const int MBytes = 1024 * KBytes;
#define ABORT() printf("in %s, line %i", __FILE__, __LINE__); abort()
#define VIXL_ABORT() printf("in %s, line %i", __FILE__, __LINE__); abort()
#ifdef DEBUG
#define ASSERT(condition) assert(condition)
#define CHECK(condition) ASSERT(condition)
#define UNIMPLEMENTED() printf("UNIMPLEMENTED\t"); ABORT()
#define UNREACHABLE() printf("UNREACHABLE\t"); ABORT()
#define VIXL_ASSERT(condition) assert(condition)
#define VIXL_CHECK(condition) VIXL_ASSERT(condition)
#define VIXL_UNIMPLEMENTED() printf("UNIMPLEMENTED\t"); VIXL_ABORT()
#define VIXL_UNREACHABLE() printf("UNREACHABLE\t"); VIXL_ABORT()
#else
#define ASSERT(condition) ((void) 0)
#define CHECK(condition) assert(condition)
#define UNIMPLEMENTED() ((void) 0)
#define UNREACHABLE() ((void) 0)
#define VIXL_ASSERT(condition) ((void) 0)
#define VIXL_CHECK(condition) assert(condition)
#define VIXL_UNIMPLEMENTED() ((void) 0)
#define VIXL_UNREACHABLE() ((void) 0)
#endif
// This is not as powerful as template based assertions, but it is simple.
// It assumes that the descriptions are unique. If this starts being a problem,
// we can switch to a different implemention.
#define VIXL_CONCAT(a, b) a##b
#define VIXL_STATIC_ASSERT_LINE(line, condition) \
typedef char VIXL_CONCAT(STATIC_ASSERT_LINE_, line)[(condition) ? 1 : -1] \
__attribute__((unused))
#define VIXL_STATIC_ASSERT(condition) VIXL_STATIC_ASSERT_LINE(__LINE__, condition) //NOLINT
template <typename T> inline void USE(T) {}
#define ALIGNMENT_EXCEPTION() printf("ALIGNMENT EXCEPTION\t"); ABORT()
#define VIXL_ALIGNMENT_EXCEPTION() printf("ALIGNMENT EXCEPTION\t"); VIXL_ABORT()
#endif // VIXL_GLOBALS_H

View File

@@ -34,9 +34,7 @@ namespace vixl {
// Currently we assume running the simulator implies running on x86 hardware.
inline void HostBreakpoint() { asm("int3"); }
#else
inline void HostBreakpoint() {
// TODO: Implement HostBreakpoint on a64.
}
inline void HostBreakpoint() { asm("brk"); }
#endif
} // namespace vixl

View File

@@ -58,9 +58,9 @@ double rawbits_to_double(uint64_t bits) {
int CountLeadingZeros(uint64_t value, int width) {
ASSERT((width == 32) || (width == 64));
VIXL_ASSERT((width == 32) || (width == 64));
int count = 0;
uint64_t bit_test = 1UL << (width - 1);
uint64_t bit_test = UINT64_C(1) << (width - 1);
while ((count < width) && ((bit_test & value) == 0)) {
count++;
bit_test >>= 1;
@@ -70,7 +70,7 @@ int CountLeadingZeros(uint64_t value, int width) {
int CountLeadingSignBits(int64_t value, int width) {
ASSERT((width == 32) || (width == 64));
VIXL_ASSERT((width == 32) || (width == 64));
if (value >= 0) {
return CountLeadingZeros(value, width) - 1;
} else {
@@ -80,7 +80,7 @@ int CountLeadingSignBits(int64_t value, int width) {
int CountTrailingZeros(uint64_t value, int width) {
ASSERT((width == 32) || (width == 64));
VIXL_ASSERT((width == 32) || (width == 64));
int count = 0;
while ((count < width) && (((value >> count) & 1) == 0)) {
count++;
@@ -92,10 +92,10 @@ int CountTrailingZeros(uint64_t value, int width) {
int CountSetBits(uint64_t value, int width) {
// TODO: Other widths could be added here, as the implementation already
// supports them.
ASSERT((width == 32) || (width == 64));
VIXL_ASSERT((width == 32) || (width == 64));
// Mask out unused bits to ensure that they are not counted.
value &= (0xffffffffffffffffULL >> (64-width));
value &= (UINT64_C(0xffffffffffffffff) >> (64-width));
// Add up the set bits.
// The algorithm works by adding pairs of bit fields together iteratively,
@@ -108,18 +108,19 @@ int CountSetBits(uint64_t value, int width) {
// value = h+g+f+e d+c+b+a
// \ |
// value = h+g+f+e+d+c+b+a
value = ((value >> 1) & 0x5555555555555555ULL) +
(value & 0x5555555555555555ULL);
value = ((value >> 2) & 0x3333333333333333ULL) +
(value & 0x3333333333333333ULL);
value = ((value >> 4) & 0x0f0f0f0f0f0f0f0fULL) +
(value & 0x0f0f0f0f0f0f0f0fULL);
value = ((value >> 8) & 0x00ff00ff00ff00ffULL) +
(value & 0x00ff00ff00ff00ffULL);
value = ((value >> 16) & 0x0000ffff0000ffffULL) +
(value & 0x0000ffff0000ffffULL);
value = ((value >> 32) & 0x00000000ffffffffULL) +
(value & 0x00000000ffffffffULL);
const uint64_t kMasks[] = {
UINT64_C(0x5555555555555555),
UINT64_C(0x3333333333333333),
UINT64_C(0x0f0f0f0f0f0f0f0f),
UINT64_C(0x00ff00ff00ff00ff),
UINT64_C(0x0000ffff0000ffff),
UINT64_C(0x00000000ffffffff),
};
for (unsigned i = 0; i < (sizeof(kMasks) / sizeof(kMasks[0])); i++) {
int shift = 1 << i;
value = ((value >> shift) & kMasks[i]) + (value & kMasks[i]);
}
return value;
}

View File

@@ -27,7 +27,7 @@
#ifndef VIXL_UTILS_H
#define VIXL_UTILS_H
#include <math.h>
#include <string.h>
#include "globals.h"
@@ -35,19 +35,19 @@ namespace vixl {
// Check number width.
inline bool is_intn(unsigned n, int64_t x) {
ASSERT((0 < n) && (n < 64));
int64_t limit = 1ULL << (n - 1);
VIXL_ASSERT((0 < n) && (n < 64));
int64_t limit = INT64_C(1) << (n - 1);
return (-limit <= x) && (x < limit);
}
inline bool is_uintn(unsigned n, int64_t x) {
ASSERT((0 < n) && (n < 64));
VIXL_ASSERT((0 < n) && (n < 64));
return !(x >> n);
}
inline unsigned truncate_to_intn(unsigned n, int64_t x) {
ASSERT((0 < n) && (n < 64));
return (x & ((1ULL << n) - 1));
VIXL_ASSERT((0 < n) && (n < 64));
return (x & ((INT64_C(1) << n) - 1));
}
#define INT_1_TO_63_LIST(V) \
@@ -90,13 +90,67 @@ inline int64_t signed_bitextract_64(int msb, int lsb, int64_t x) {
return (x << (63 - msb)) >> (lsb + 63 - msb);
}
// floating point representation
// Floating point representation.
uint32_t float_to_rawbits(float value);
uint64_t double_to_rawbits(double value);
float rawbits_to_float(uint32_t bits);
double rawbits_to_double(uint64_t bits);
// Bits counting.
// NaN tests.
inline bool IsSignallingNaN(double num) {
const uint64_t kFP64QuietNaNMask = UINT64_C(0x0008000000000000);
uint64_t raw = double_to_rawbits(num);
if (isnan(num) && ((raw & kFP64QuietNaNMask) == 0)) {
return true;
}
return false;
}
inline bool IsSignallingNaN(float num) {
const uint32_t kFP32QuietNaNMask = 0x00400000;
uint32_t raw = float_to_rawbits(num);
if (isnan(num) && ((raw & kFP32QuietNaNMask) == 0)) {
return true;
}
return false;
}
template <typename T>
inline bool IsQuietNaN(T num) {
return isnan(num) && !IsSignallingNaN(num);
}
// Convert the NaN in 'num' to a quiet NaN.
inline double ToQuietNaN(double num) {
const uint64_t kFP64QuietNaNMask = UINT64_C(0x0008000000000000);
VIXL_ASSERT(isnan(num));
return rawbits_to_double(double_to_rawbits(num) | kFP64QuietNaNMask);
}
inline float ToQuietNaN(float num) {
const uint32_t kFP32QuietNaNMask = 0x00400000;
VIXL_ASSERT(isnan(num));
return rawbits_to_float(float_to_rawbits(num) | kFP32QuietNaNMask);
}
// Fused multiply-add.
inline double FusedMultiplyAdd(double op1, double op2, double a) {
return fma(op1, op2, a);
}
inline float FusedMultiplyAdd(float op1, float op2, float a) {
return fmaf(op1, op2, a);
}
// Bit counting.
int CountLeadingZeros(uint64_t value, int width);
int CountLeadingSignBits(int64_t value, int width);
int CountTrailingZeros(uint64_t value, int width);
@@ -106,20 +160,30 @@ int CountSetBits(uint64_t value, int width);
// TODO: rename/refactor to make it specific to instructions.
template<typename T>
bool IsWordAligned(T pointer) {
ASSERT(sizeof(pointer) == sizeof(intptr_t)); // NOLINT(runtime/sizeof)
VIXL_ASSERT(sizeof(pointer) == sizeof(intptr_t)); // NOLINT(runtime/sizeof)
return (reinterpret_cast<intptr_t>(pointer) & 3) == 0;
}
// Increment a pointer until it has the specified alignment.
template<class T>
T AlignUp(T pointer, size_t alignment) {
ASSERT(sizeof(pointer) == sizeof(uintptr_t));
VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(uintptr_t));
uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
size_t align_step = (alignment - pointer_raw) % alignment;
ASSERT((pointer_raw + align_step) % alignment == 0);
VIXL_ASSERT((pointer_raw + align_step) % alignment == 0);
return reinterpret_cast<T>(pointer_raw + align_step);
}
// Decrement a pointer until it has the specified alignment.
template<class T>
T AlignDown(T pointer, size_t alignment) {
VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(uintptr_t));
uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
size_t align_step = pointer_raw % alignment;
VIXL_ASSERT((pointer_raw - align_step) % alignment == 0);
return reinterpret_cast<T>(pointer_raw - align_step);
}
} // namespace vixl

View File

@@ -143,12 +143,12 @@ static void dma_bdrv_cb(void *opaque, int ret)
dbs->acb = NULL;
dbs->sector_num += dbs->iov.size / 512;
dma_bdrv_unmap(dbs);
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
dma_complete(dbs, ret);
return;
}
dma_bdrv_unmap(dbs);
while (dbs->sg_cur_index < dbs->sg->nsg) {
cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;

View File

@@ -139,7 +139,7 @@ static const VMStateDescription vmstate_kbd = {
.name = "pckbd",
.version_id = 3,
.minimum_version_id = 3,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(write_cmd, KBDState),
VMSTATE_UINT8(status, KBDState),
VMSTATE_UINT8(mode, KBDState),
@@ -257,7 +257,7 @@ const VMStateDescription vmstate_ide_drive_pio_state = {
.minimum_version_id = 1,
.pre_save = ide_drive_pio_pre_save,
.post_load = ide_drive_pio_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_INT32(req_nb_sectors, IDEState),
VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
vmstate_info_uint8, uint8_t),
@@ -275,7 +275,7 @@ const VMStateDescription vmstate_ide_drive = {
.version_id = 3,
.minimum_version_id = 0,
.post_load = ide_drive_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
.... several fields ....
VMSTATE_END_OF_LIST()
},

102
docs/multiseat.txt Normal file
View File

@@ -0,0 +1,102 @@
multiseat howto (with some multihead coverage)
==============================================
host side
---------
First you must compile qemu with a user interface supporting
multihead/multiseat and input event routing. Right now this
list includes sdl2 and gtk (both 2+3):
./configure --enable-sdl --with-sdlabi=2.0
or
./configure --enable-gtk
Next put together the qemu command line:
qemu -enable-kvm -usb $memory $disk $whatever \
-display [ sdl | gtk ] \
-vga std \
-device usb-tablet
That is it for the first head, which will use the standard vga, the
standard ps/2 keyboard (implicitly there) and the usb-tablet. Now the
additional switches for the second head:
-device pci-bridge,addr=12.0,chassis_nr=2,id=head.2 \
-device secondary-vga,bus=head.2,addr=02.0,id=video.2 \
-device nec-usb-xhci,bus=head.2,addr=0f.0,id=usb.2 \
-device usb-kbd,bus=usb.2.0,port=1,display=video.2 \
-device usb-tablet,bus=usb.2.0,port=2,display=video.2
This places a pci bridge in slot 12, connects a display adapter and
xhci (usb) controller to the bridge. Then it adds a usb keyboard and
usb mouse, both connected to the xhci and linked to the display.
The "display=video2" sets up the input routing. Any input coming from
the window which belongs to the video.2 display adapter will be routed
to these input devices.
The sdl2 ui will start up with two windows, one for each display
device. The gtk ui will start with a single window and each display
in a separate tab. You can either simply switch tabs to switch heads,
or use the "View / Detach tab" menu item to move one of the displays
to its own window so you can see both display devices side-by-side.
Note on spice: Spice handles multihead just fine. But it can't do
multiseat. For tablet events the event source is sent to the spice
agent. But qemu can't figure it, so it can't do input routing.
Fixing this needs a new or extended input interface between
libspice-server and qemu. For keyboard events it is even worse: The
event source isn't included in the spice protocol, so the wire
protocol must be extended to support this.
guest side
----------
You need a pretty recent linux guest. systemd with loginctl. kernel
3.14+ with CONFIG_DRM_BOCHS enabled. Fedora 20 will do. Must be
fully updated for the new kernel though, i.e. the live iso doesn't cut
it.
Now we'll have to configure the guest. Boot and login. "lspci -vt"
should list the pci bridge with the display adapter and usb controller:
[root@fedora ~]# lspci -vt
-[0000:00]-+-00.0 Intel Corporation 440FX - 82441FX PMC [Natoma]
[ ... ]
\-12.0-[01]--+-02.0 Device 1234:1111
\-0f.0 NEC Corporation USB 3.0 Host Controller
Good. Now lets tell the system that the pci bridge and all devices
below it belong to a separate seat by dropping a file into
/etc/udev/rules.d:
[root@fedora ~]# cat /etc/udev/rules.d/70-qemu-autoseat.rules
SUBSYSTEMS=="pci", DEVPATH=="*/0000:00:12.0", TAG+="seat", ENV{ID_AUTOSEAT}="1"
Reboot. System should come up with two seats. With loginctl you can
check the configuration:
[root@fedora ~]# loginctl list-seats
SEAT
seat0
seat-pci-pci-0000_00_12_0
2 seats listed.
You can use "loginctl seat-status seat-pci-pci-0000_00_12_0" to list
the devices attached to the seat.
Background info is here:
http://www.freedesktop.org/wiki/Software/systemd/multiseat/
Enjoy!
--
Gerd Hoffmann <kraxel@redhat.com>

View File

@@ -48,7 +48,7 @@ The QAPI schema definitions can be modularized using the 'include' directive:
{ 'include': 'path/to/file.json'}
The directive is evaluated recursively, and include paths are relative to the
file using the directive.
file using the directive. Multiple includes of the same file are safe.
=== Complex types ===
@@ -230,14 +230,13 @@ node structure that can be used to chain together a list of such types in
case we want to accept/return a list of this type with a command), and a
command which takes that type as a parameter and returns the same type:
mdroth@illuin:~/w/qemu2.git$ cat example-schema.json
$ cat example-schema.json
{ 'type': 'UserDefOne',
'data': { 'integer': 'int', 'string': 'str' } }
{ 'command': 'my-command',
'data': {'arg1': 'UserDefOne'},
'returns': 'UserDefOne' }
mdroth@illuin:~/w/qemu2.git$
=== scripts/qapi-types.py ===
@@ -255,14 +254,25 @@ created code.
Example:
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
--output-dir="qapi-generated" --prefix="example-" --input-file=example-schema.json
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
$ python scripts/qapi-types.py --output-dir="qapi-generated" \
--prefix="example-" --input-file=example-schema.json
$ cat qapi-generated/example-qapi-types.c
[Uninteresting stuff omitted...]
#include "qapi/qapi-dealloc-visitor.h"
#include "example-qapi-types.h"
#include "example-qapi-visit.h"
void qapi_free_UserDefOneList(UserDefOneList * obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_UserDefOneList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_UserDefOne(UserDefOne * obj)
{
@@ -279,32 +289,38 @@ Example:
qapi_dealloc_visitor_cleanup(md);
}
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.h
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
#ifndef QAPI_GENERATED_EXAMPLE_QAPI_TYPES
#define QAPI_GENERATED_EXAMPLE_QAPI_TYPES
$ cat qapi-generated/example-qapi-types.h
[Uninteresting stuff omitted...]
#include "qapi/qapi-types-core.h"
#ifndef EXAMPLE_QAPI_TYPES_H
#define EXAMPLE_QAPI_TYPES_H
[Builtin types omitted...]
typedef struct UserDefOne UserDefOne;
typedef struct UserDefOneList
{
UserDefOne *value;
union {
UserDefOne *value;
uint64_t padding;
};
struct UserDefOneList *next;
} UserDefOneList;
[Functions on builtin types omitted...]
struct UserDefOne
{
int64_t integer;
char * string;
};
void qapi_free_UserDefOneList(UserDefOneList * obj);
void qapi_free_UserDefOne(UserDefOne * obj);
#endif
=== scripts/qapi-visit.py ===
Used to generate the visitor functions used to walk through and convert
@@ -325,51 +341,78 @@ $(prefix)qapi-visit.h: declarations for previously mentioned visitor
Example:
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
--output-dir="qapi-generated" --prefix="example-" --input-file=example-schema.json
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
$ python scripts/qapi-visit.py --output-dir="qapi-generated"
--prefix="example-" --input-file=example-schema.json
$ cat qapi-generated/example-qapi-visit.c
[Uninteresting stuff omitted...]
#include "example-qapi-visit.h"
static void visit_type_UserDefOne_fields(Visitor *m, UserDefOne ** obj, Error **errp)
{
Error *err = NULL;
visit_type_int(m, &(*obj)->integer, "integer", &err);
if (err) {
goto out;
}
visit_type_str(m, &(*obj)->string, "string", &err);
if (err) {
goto out;
}
out:
error_propagate(errp, err);
}
void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp)
{
visit_start_struct(m, (void **)obj, "UserDefOne", name, sizeof(UserDefOne), errp);
visit_type_int(m, (obj && *obj) ? &(*obj)->integer : NULL, "integer", errp);
visit_type_str(m, (obj && *obj) ? &(*obj)->string : NULL, "string", errp);
visit_end_struct(m, errp);
Error *err = NULL;
visit_start_struct(m, (void **)obj, "UserDefOne", name, sizeof(UserDefOne), &err);
if (!err) {
if (*obj) {
visit_type_UserDefOne_fields(m, obj, errp);
}
visit_end_struct(m, &err);
}
error_propagate(errp, err);
}
void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp)
{
GenericList *i, **prev = (GenericList **)obj;
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, errp);
for (; (i = visit_next_list(m, prev, errp)) != NULL; prev = &i) {
UserDefOneList *native_i = (UserDefOneList *)i;
visit_type_UserDefOne(m, &native_i->value, NULL, errp);
visit_start_list(m, name, &err);
if (err) {
goto out;
}
visit_end_list(m, errp);
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
UserDefOneList *native_i = (UserDefOneList *)i;
visit_type_UserDefOne(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.h
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
$ python scripts/qapi-commands.py --output-dir="qapi-generated" \
--prefix="example-" --input-file=example-schema.json
$ cat qapi-generated/example-qapi-visit.h
[Uninteresting stuff omitted...]
#ifndef QAPI_GENERATED_EXAMPLE_QAPI_VISIT
#define QAPI_GENERATED_EXAMPLE_QAPI_VISIT
#ifndef EXAMPLE_QAPI_VISIT_H
#define EXAMPLE_QAPI_VISIT_H
#include "qapi/qapi-visit-core.h"
#include "example-qapi-types.h"
[Visitors for builtin types omitted...]
void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp);
void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp);
#endif
mdroth@illuin:~/w/qemu2.git$
(The actual structure of the visit_type_* functions is a bit more complex
in order to propagate errors correctly and avoid leaking memory).
=== scripts/qapi-commands.py ===
@@ -390,77 +433,80 @@ $(prefix)qmp-commands.h: Function prototypes for the QMP commands
Example:
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qmp-marshal.c
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
$ cat qapi-generated/example-qmp-marshal.c
[Uninteresting stuff omitted...]
#include "qemu-objects.h"
#include "qapi/qmp-core.h"
#include "qapi/qapi-visit-core.h"
#include "qapi/qmp-output-visitor.h"
#include "qapi/qmp-input-visitor.h"
#include "qapi/qapi-dealloc-visitor.h"
#include "example-qapi-types.h"
#include "example-qapi-visit.h"
#include "example-qmp-commands.h"
static void qmp_marshal_output_my_command(UserDefOne * ret_in, QObject **ret_out, Error **errp)
{
QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
Error *local_err = NULL;
QmpOutputVisitor *mo = qmp_output_visitor_new();
QapiDeallocVisitor *md;
Visitor *v;
v = qmp_output_get_visitor(mo);
visit_type_UserDefOne(v, &ret_in, "unused", errp);
v = qapi_dealloc_get_visitor(md);
visit_type_UserDefOne(v, &ret_in, "unused", errp);
qapi_dealloc_visitor_cleanup(md);
visit_type_UserDefOne(v, &ret_in, "unused", &local_err);
if (local_err) {
goto out;
}
*ret_out = qmp_output_get_qobject(mo);
out:
error_propagate(errp, local_err);
qmp_output_visitor_cleanup(mo);
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_UserDefOne(v, &ret_in, "unused", NULL);
qapi_dealloc_visitor_cleanup(md);
}
static void qmp_marshal_input_my_command(QmpState *qmp__sess, QDict *args, QObject **ret, Error **errp)
static void qmp_marshal_input_my_command(QDict *args, QObject **ret, Error **errp)
{
Error *local_err = NULL;
UserDefOne * retval = NULL;
QmpInputVisitor *mi;
QmpInputVisitor *mi = qmp_input_visitor_new_strict(QOBJECT(args));
QapiDeallocVisitor *md;
Visitor *v;
UserDefOne * arg1 = NULL;
mi = qmp_input_visitor_new(QOBJECT(args));
v = qmp_input_get_visitor(mi);
visit_type_UserDefOne(v, &arg1, "arg1", errp);
if (error_is_set(errp)) {
visit_type_UserDefOne(v, &arg1, "arg1", &local_err);
if (local_err) {
goto out;
}
retval = qmp_my_command(arg1, errp);
qmp_marshal_output_my_command(retval, ret, errp);
retval = qmp_my_command(arg1, &local_err);
if (local_err) {
goto out;
}
qmp_marshal_output_my_command(retval, ret, &local_err);
out:
error_propagate(errp, local_err);
qmp_input_visitor_cleanup(mi);
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_UserDefOne(v, &arg1, "arg1", errp);
visit_type_UserDefOne(v, &arg1, "arg1", NULL);
qapi_dealloc_visitor_cleanup(md);
return;
}
static void qmp_init_marshal(void)
{
qmp_register_command("my-command", qmp_marshal_input_my_command);
qmp_register_command("my-command", qmp_marshal_input_my_command, QCO_NO_OPTIONS);
}
qapi_init(qmp_init_marshal);
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qmp-commands.h
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
$ cat qapi-generated/example-qmp-commands.h
[Uninteresting stuff omitted...]
#ifndef QAPI_GENERATED_EXAMPLE_QMP_COMMANDS
#define QAPI_GENERATED_EXAMPLE_QMP_COMMANDS
#ifndef EXAMPLE_QMP_COMMANDS_H
#define EXAMPLE_QMP_COMMANDS_H
#include "example-qapi-types.h"
#include "error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/error.h"
UserDefOne * qmp_my_command(UserDefOne * arg1, Error **errp);
#endif
mdroth@illuin:~/w/qemu2.git$

View File

@@ -107,8 +107,9 @@ in the description of a field.
96 - 99: refcount_order
Describes the width of a reference count block entry (width
in bits = 1 << refcount_order). For version 2 images, the
order is always assumed to be 4 (i.e. the width is 16 bits).
in bits: refcount_bits = 1 << refcount_order). For version 2
images, the order is always assumed to be 4
(i.e. refcount_bits = 16).
100 - 103: header_length
Length of the header structure in bytes. For version 2

3
exec.c
View File

@@ -429,9 +429,8 @@ const VMStateDescription vmstate_cpu_common = {
.name = "cpu_common",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.post_load = cpu_common_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(halted, CPUState),
VMSTATE_UINT32(interrupt_request, CPUState),
VMSTATE_END_OF_LIST()

View File

@@ -556,6 +556,7 @@ ETEXI
.params = "keys [hold_ms]",
.help = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)",
.mhandler.cmd = hmp_send_key,
.command_completion = sendkey_completion,
},
STEXI
@@ -1233,9 +1234,10 @@ ETEXI
{
.name = "netdev_add",
.args_type = "netdev:O",
.params = "[user|tap|socket|hubport|netmap],id=str[,prop=value][,...]",
.params = "[user|tap|socket|vde|bridge|hubport|netmap],id=str[,prop=value][,...]",
.help = "add host network device",
.mhandler.cmd = hmp_netdev_add,
.command_completion = netdev_add_completion,
},
STEXI
@@ -1250,6 +1252,7 @@ ETEXI
.params = "id",
.help = "remove host network device",
.mhandler.cmd = hmp_netdev_del,
.command_completion = netdev_del_completion,
},
STEXI
@@ -1339,6 +1342,7 @@ ETEXI
.params = "name on|off",
.help = "change the link status of a network adapter",
.mhandler.cmd = hmp_set_link,
.command_completion = set_link_completion,
},
STEXI
@@ -1622,6 +1626,7 @@ ETEXI
.params = "args",
.help = "add chardev",
.mhandler.cmd = hmp_chardev_add,
.command_completion = chardev_add_completion,
},
STEXI
@@ -1638,6 +1643,7 @@ ETEXI
.params = "id",
.help = "remove chardev",
.mhandler.cmd = hmp_chardev_remove,
.command_completion = chardev_remove_completion,
},
STEXI

21
hmp.c
View File

@@ -341,6 +341,11 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
info->value->inserted->backing_file_depth);
}
if (info->value->inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
monitor_printf(mon, " Detect zeroes: %s\n",
BlockdevDetectZeroesOptions_lookup[info->value->inserted->detect_zeroes]);
}
if (info->value->inserted->bps
|| info->value->inserted->bps_rd
|| info->value->inserted->bps_wr
@@ -1388,6 +1393,7 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
void hmp_object_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
Error *err_end = NULL;
QemuOpts *opts;
char *type = NULL;
char *id = NULL;
@@ -1411,24 +1417,23 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
qdict_del(pdict, "qom-type");
visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err);
if (err) {
goto out_clean;
goto out_end;
}
qdict_del(pdict, "id");
visit_type_str(opts_get_visitor(ov), &id, "id", &err);
if (err) {
goto out_clean;
goto out_end;
}
object_add(type, id, pdict, opts_get_visitor(ov), &err);
if (err) {
goto out_clean;
}
visit_end_struct(opts_get_visitor(ov), &err);
if (err) {
out_end:
visit_end_struct(opts_get_visitor(ov), &err_end);
if (!err && err_end) {
qmp_object_del(id, NULL);
}
error_propagate(&err, err_end);
out_clean:
opts_visitor_cleanup(ov);

6
hmp.h
View File

@@ -97,5 +97,11 @@ void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str);
void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
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);
#endif

View File

@@ -43,13 +43,13 @@ static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
return (slot + 1) * 4 + irq_num;
}
static void clipper_init(QEMUMachineInitArgs *args)
static void clipper_init(MachineState *machine)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ram_addr_t ram_size = machine->ram_size;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
AlphaCPU *cpus[4];
PCIBus *pci_bus;
ISABus *isa_bus;

View File

@@ -23,12 +23,12 @@ static struct arm_boot_info collie_binfo = {
.ram_size = 0x20000000,
};
static void collie_init(QEMUMachineInitArgs *args)
static void collie_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
StrongARMState *s;
DriveInfo *dinfo;
MemoryRegion *sysmem = get_system_memory();

View File

@@ -30,7 +30,7 @@ typedef struct CubieBoardState {
MemoryRegion sdram;
} CubieBoardState;
static void cubieboard_init(QEMUMachineInitArgs *args)
static void cubieboard_init(MachineState *machine)
{
CubieBoardState *s = g_new(CubieBoardState, 1);
Error *err = NULL;
@@ -63,14 +63,15 @@ static void cubieboard_init(QEMUMachineInitArgs *args)
exit(1);
}
memory_region_init_ram(&s->sdram, NULL, "cubieboard.ram", args->ram_size);
memory_region_init_ram(&s->sdram, NULL, "cubieboard.ram",
machine->ram_size);
vmstate_register_ram_global(&s->sdram);
memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
&s->sdram);
cubieboard_binfo.ram_size = args->ram_size;
cubieboard_binfo.kernel_filename = args->kernel_filename;
cubieboard_binfo.kernel_cmdline = args->kernel_cmdline;
cubieboard_binfo.ram_size = machine->ram_size;
cubieboard_binfo.kernel_filename = machine->kernel_filename;
cubieboard_binfo.kernel_cmdline = machine->kernel_cmdline;
arm_load_kernel(&s->a10->cpu, &cubieboard_binfo);
}

View File

@@ -143,7 +143,7 @@ static DigicBoard digic4_board_canon_a1100 = {
.rom1_def_filename = "canon-a1100-rom1.bin",
};
static void canon_a1100_init(QEMUMachineInitArgs *args)
static void canon_a1100_init(MachineState *machine)
{
digic4_board_init(&digic4_board_canon_a1100);
}

View File

@@ -94,7 +94,7 @@ static void lan9215_init(uint32_t base, qemu_irq irq)
}
}
static Exynos4210State *exynos4_boards_init_common(QEMUMachineInitArgs *args,
static Exynos4210State *exynos4_boards_init_common(MachineState *machine,
Exynos4BoardType board_type)
{
if (smp_cpus != EXYNOS4210_NCPUS && !qtest_enabled()) {
@@ -108,9 +108,9 @@ static Exynos4210State *exynos4_boards_init_common(QEMUMachineInitArgs *args,
exynos4_board_binfo.board_id = exynos4_board_id[board_type];
exynos4_board_binfo.smp_bootreg_addr =
exynos4_board_smp_bootreg_addr[board_type];
exynos4_board_binfo.kernel_filename = args->kernel_filename;
exynos4_board_binfo.initrd_filename = args->initrd_filename;
exynos4_board_binfo.kernel_cmdline = args->kernel_cmdline;
exynos4_board_binfo.kernel_filename = machine->kernel_filename;
exynos4_board_binfo.initrd_filename = machine->initrd_filename;
exynos4_board_binfo.kernel_cmdline = machine->kernel_cmdline;
exynos4_board_binfo.gic_cpu_if_addr =
EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;
@@ -120,24 +120,24 @@ static Exynos4210State *exynos4_boards_init_common(QEMUMachineInitArgs *args,
" initrd_filename: %s\n",
exynos4_board_ram_size[board_type] / 1048576,
exynos4_board_ram_size[board_type],
args->kernel_filename,
args->kernel_cmdline,
args->initrd_filename);
machine->kernel_filename,
machine->kernel_cmdline,
machine->initrd_filename);
return exynos4210_init(get_system_memory(),
exynos4_board_ram_size[board_type]);
}
static void nuri_init(QEMUMachineInitArgs *args)
static void nuri_init(MachineState *machine)
{
exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI);
exynos4_boards_init_common(machine, EXYNOS4_BOARD_NURI);
arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
}
static void smdkc210_init(QEMUMachineInitArgs *args)
static void smdkc210_init(MachineState *machine)
{
Exynos4210State *s = exynos4_boards_init_common(args,
Exynos4210State *s = exynos4_boards_init_common(machine,
EXYNOS4_BOARD_SMDKC210);
lan9215_init(SMDK_LAN9118_BASE_ADDR,

View File

@@ -46,7 +46,7 @@
static const int sector_len = 128 * 1024;
static void connex_init(QEMUMachineInitArgs *args)
static void connex_init(MachineState *machine)
{
PXA2xxState *cpu;
DriveInfo *dinfo;
@@ -83,9 +83,9 @@ static void connex_init(QEMUMachineInitArgs *args)
qdev_get_gpio_in(cpu->gpio, 36));
}
static void verdex_init(QEMUMachineInitArgs *args)
static void verdex_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *cpu_model = machine->cpu_model;
PXA2xxState *cpu;
DriveInfo *dinfo;
int be;

View File

@@ -134,7 +134,6 @@ static VMStateDescription vmstate_highbank_regs = {
.name = "highbank-regs",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, HighbankRegsState, NUM_REGS),
VMSTATE_END_OF_LIST(),
@@ -200,13 +199,13 @@ enum cxmachines {
* 32-bit host, set the reg value of memory to 0xf7ff00000 in the
* device tree and pass -m 2047 to QEMU.
*/
static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ram_addr_t ram_size = machine->ram_size;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
DeviceState *dev = NULL;
SysBusDevice *busdev;
qemu_irq pic[128];
@@ -218,7 +217,7 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
char *sysboot_filename;
if (!cpu_model) {
switch (machine) {
switch (machine_id) {
case CALXEDA_HIGHBANK:
cpu_model = "cortex-a9";
break;
@@ -275,7 +274,7 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
}
}
switch (machine) {
switch (machine_id) {
case CALXEDA_HIGHBANK:
dev = qdev_create(NULL, "l2x0");
qdev_init_nofail(dev);
@@ -360,14 +359,14 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
}
static void highbank_init(QEMUMachineInitArgs *args)
static void highbank_init(MachineState *machine)
{
calxeda_init(args, CALXEDA_HIGHBANK);
calxeda_init(machine, CALXEDA_HIGHBANK);
}
static void midway_init(QEMUMachineInitArgs *args)
static void midway_init(MachineState *machine)
{
calxeda_init(args, CALXEDA_MIDWAY);
calxeda_init(machine, CALXEDA_MIDWAY);
}
static QEMUMachine highbank_machine = {

View File

@@ -461,13 +461,13 @@ static struct arm_boot_info integrator_binfo = {
.board_id = 0x113,
};
static void integratorcp_init(QEMUMachineInitArgs *args)
static void integratorcp_init(MachineState *machine)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ram_addr_t ram_size = machine->ram_size;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
ARMCPU *cpu;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@@ -70,13 +70,13 @@ static struct arm_boot_info kzm_binfo = {
.board_id = 1722,
};
static void kzm_init(QEMUMachineInitArgs *args)
static void kzm_init(MachineState *machine)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ram_addr_t ram_size = machine->ram_size;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
ARMCPU *cpu;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@@ -105,7 +105,7 @@ static struct arm_boot_info mainstone_binfo = {
};
static void mainstone_common_init(MemoryRegion *address_space_mem,
QEMUMachineInitArgs *args,
MachineState *machine,
enum mainstone_model_e model, int arm_id)
{
uint32_t sector_len = 256 * 1024;
@@ -116,7 +116,7 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
int i;
int be;
MemoryRegion *rom = g_new(MemoryRegion, 1);
const char *cpu_model = args->cpu_model;
const char *cpu_model = machine->cpu_model;
if (!cpu_model)
cpu_model = "pxa270-c5";
@@ -175,16 +175,16 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
smc91c111_init(&nd_table[0], MST_ETH_PHYS,
qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));
mainstone_binfo.kernel_filename = args->kernel_filename;
mainstone_binfo.kernel_cmdline = args->kernel_cmdline;
mainstone_binfo.initrd_filename = args->initrd_filename;
mainstone_binfo.kernel_filename = machine->kernel_filename;
mainstone_binfo.kernel_cmdline = machine->kernel_cmdline;
mainstone_binfo.initrd_filename = machine->initrd_filename;
mainstone_binfo.board_id = arm_id;
arm_load_kernel(mpu->cpu, &mainstone_binfo);
}
static void mainstone_init(QEMUMachineInitArgs *args)
static void mainstone_init(MachineState *machine)
{
mainstone_common_init(get_system_memory(), args, mainstone, 0x196);
mainstone_common_init(get_system_memory(), machine, mainstone, 0x196);
}
static QEMUMachine mainstone2_machine = {

View File

@@ -405,7 +405,6 @@ static const VMStateDescription mv88w8618_eth_vmsd = {
.name = "mv88w8618_eth",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(smir, mv88w8618_eth_state),
VMSTATE_UINT32(icr, mv88w8618_eth_state),
@@ -642,7 +641,6 @@ static const VMStateDescription musicpal_lcd_vmsd = {
.name = "musicpal_lcd",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(brightness, musicpal_lcd_state),
VMSTATE_UINT32(mode, musicpal_lcd_state),
@@ -769,7 +767,6 @@ static const VMStateDescription mv88w8618_pic_vmsd = {
.name = "mv88w8618_pic",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(level, mv88w8618_pic_state),
VMSTATE_UINT32(enabled, mv88w8618_pic_state),
@@ -940,7 +937,6 @@ static const VMStateDescription mv88w8618_timer_vmsd = {
.name = "timer",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_PTIMER(ptimer, mv88w8618_timer_state),
VMSTATE_UINT32(limit, mv88w8618_timer_state),
@@ -952,7 +948,6 @@ static const VMStateDescription mv88w8618_pit_vmsd = {
.name = "mv88w8618_pit",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_STRUCT_ARRAY(timer, mv88w8618_pit_state, 4, 1,
mv88w8618_timer_vmsd, mv88w8618_timer_state),
@@ -1041,7 +1036,6 @@ static const VMStateDescription mv88w8618_flashcfg_vmsd = {
.name = "mv88w8618_flashcfg",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(cfgr0, mv88w8618_flashcfg_state),
VMSTATE_END_OF_LIST()
@@ -1381,7 +1375,6 @@ static const VMStateDescription musicpal_gpio_vmsd = {
.name = "musicpal_gpio",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(lcd_brightness, musicpal_gpio_state),
VMSTATE_UINT32(out_state, musicpal_gpio_state),
@@ -1548,7 +1541,6 @@ static const VMStateDescription musicpal_key_vmsd = {
.name = "musicpal_key",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(kbd_extended, musicpal_key_state),
VMSTATE_UINT32(pressed_keys, musicpal_key_state),
@@ -1577,12 +1569,12 @@ static struct arm_boot_info musicpal_binfo = {
.board_id = 0x20e,
};
static void musicpal_init(QEMUMachineInitArgs *args)
static void musicpal_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
ARMCPU *cpu;
qemu_irq pic[32];
DeviceState *dev;

View File

@@ -1278,14 +1278,14 @@ static int n810_atag_setup(const struct arm_boot_info *info, void *p)
return n8x0_atag_setup(p, 810);
}
static void n8x0_init(QEMUMachineInitArgs *args,
static void n8x0_init(MachineState *machine,
struct arm_boot_info *binfo, int model)
{
MemoryRegion *sysmem = get_system_memory();
struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
int sdram_size = binfo->ram_size;
s->mpu = omap2420_mpu_init(sysmem, sdram_size, args->cpu_model);
s->mpu = omap2420_mpu_init(sysmem, sdram_size, machine->cpu_model);
/* Setup peripherals
*
@@ -1329,18 +1329,18 @@ static void n8x0_init(QEMUMachineInitArgs *args,
n8x0_usb_setup(s);
}
if (args->kernel_filename) {
if (machine->kernel_filename) {
/* Or at the linux loader. */
binfo->kernel_filename = args->kernel_filename;
binfo->kernel_cmdline = args->kernel_cmdline;
binfo->initrd_filename = args->initrd_filename;
binfo->kernel_filename = machine->kernel_filename;
binfo->kernel_cmdline = machine->kernel_cmdline;
binfo->initrd_filename = machine->initrd_filename;
arm_load_kernel(s->mpu->cpu, binfo);
qemu_register_reset(n8x0_boot_init, s);
}
if (option_rom[0].name &&
(args->boot_order[0] == 'n' || !args->kernel_filename)) {
(machine->boot_order[0] == 'n' || !machine->kernel_filename)) {
uint8_t nolo_tags[0x10000];
/* No, wait, better start at the ROM. */
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
@@ -1382,14 +1382,14 @@ static struct arm_boot_info n810_binfo = {
.atag_board = n810_atag_setup,
};
static void n800_init(QEMUMachineInitArgs *args)
static void n800_init(MachineState *machine)
{
return n8x0_init(args, &n800_binfo, 800);
return n8x0_init(machine, &n800_binfo, 800);
}
static void n810_init(QEMUMachineInitArgs *args)
static void n810_init(MachineState *machine)
{
return n8x0_init(args, &n810_binfo, 810);
return n8x0_init(machine, &n810_binfo, 810);
}
static QEMUMachine n800_machine = {

View File

@@ -2709,8 +2709,8 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
s->ti += ti[1];
} else {
/* A less accurate version */
s->ti -= (s->current_tm.tm_year % 100) * 31536000;
s->ti += from_bcd(value) * 31536000;
s->ti -= (time_t)(s->current_tm.tm_year % 100) * 31536000;
s->ti += (time_t)from_bcd(value) * 31536000;
}
return;

View File

@@ -98,7 +98,7 @@ static struct arm_boot_info sx1_binfo = {
.board_id = 0x265,
};
static void sx1_init(QEMUMachineInitArgs *args, const int version)
static void sx1_init(MachineState *machine, const int version)
{
struct omap_mpu_state_s *mpu;
MemoryRegion *address_space = get_system_memory();
@@ -118,7 +118,8 @@ static void sx1_init(QEMUMachineInitArgs *args, const int version)
flash_size = flash2_size;
}
mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size, args->cpu_model);
mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size,
machine->cpu_model);
/* External Flash (EMIFS) */
memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size);
@@ -189,29 +190,29 @@ static void sx1_init(QEMUMachineInitArgs *args, const int version)
OMAP_CS1_BASE, &cs[1]);
}
if (!args->kernel_filename && !fl_idx && !qtest_enabled()) {
if (!machine->kernel_filename && !fl_idx && !qtest_enabled()) {
fprintf(stderr, "Kernel or Flash image must be specified\n");
exit(1);
}
/* Load the kernel. */
sx1_binfo.kernel_filename = args->kernel_filename;
sx1_binfo.kernel_cmdline = args->kernel_cmdline;
sx1_binfo.initrd_filename = args->initrd_filename;
sx1_binfo.kernel_filename = machine->kernel_filename;
sx1_binfo.kernel_cmdline = machine->kernel_cmdline;
sx1_binfo.initrd_filename = machine->initrd_filename;
arm_load_kernel(mpu->cpu, &sx1_binfo);
/* TODO: fix next line */
//~ qemu_console_resize(ds, 640, 480);
}
static void sx1_init_v1(QEMUMachineInitArgs *args)
static void sx1_init_v1(MachineState *machine)
{
sx1_init(args, 1);
sx1_init(machine, 1);
}
static void sx1_init_v2(QEMUMachineInitArgs *args)
static void sx1_init_v2(MachineState *machine)
{
sx1_init(args, 2);
sx1_init(machine, 2);
}
static QEMUMachine sx1_machine_v2 = {

View File

@@ -191,12 +191,12 @@ static struct arm_boot_info palmte_binfo = {
.board_id = 0x331,
};
static void palmte_init(QEMUMachineInitArgs *args)
static void palmte_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
MemoryRegion *address_space_mem = get_system_memory();
struct omap_mpu_state_s *mpu;
int flash_size = 0x00800000;

View File

@@ -148,8 +148,7 @@ static const VMStateDescription vmstate_pxa2xx_pm = {
.name = "pxa2xx_pm",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40),
VMSTATE_END_OF_LIST()
}
@@ -215,8 +214,7 @@ static const VMStateDescription vmstate_pxa2xx_cm = {
.name = "pxa2xx_cm",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4),
VMSTATE_UINT32(clkcfg, PXA2xxState),
VMSTATE_UINT32(pmnc, PXA2xxState),
@@ -440,8 +438,7 @@ static const VMStateDescription vmstate_pxa2xx_mm = {
.name = "pxa2xx_mm",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a),
VMSTATE_END_OF_LIST()
}
@@ -1172,7 +1169,6 @@ static const VMStateDescription vmstate_pxa2xx_rtc_regs = {
.name = "pxa2xx_rtc",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.pre_save = pxa2xx_rtc_pre_save,
.post_load = pxa2xx_rtc_post_load,
.fields = (VMStateField[]) {
@@ -1436,8 +1432,7 @@ static const VMStateDescription vmstate_pxa2xx_i2c_slave = {
.name = "pxa2xx_i2c_slave",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_I2C_SLAVE(parent_obj, PXA2xxI2CSlaveState),
VMSTATE_END_OF_LIST()
}
@@ -1447,8 +1442,7 @@ static const VMStateDescription vmstate_pxa2xx_i2c = {
.name = "pxa2xx_i2c",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT16(control, PXA2xxI2CState),
VMSTATE_UINT16(status, PXA2xxI2CState),
VMSTATE_UINT8(ibmr, PXA2xxI2CState),
@@ -1705,8 +1699,7 @@ static const VMStateDescription vmstate_pxa2xx_i2s = {
.name = "pxa2xx_i2s",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2),
VMSTATE_UINT32(status, PXA2xxI2SState),
VMSTATE_UINT32(mask, PXA2xxI2SState),

View File

@@ -313,8 +313,7 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
.name = "pxa2xx-gpio",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_INT32(lines, PXA2xxGPIOInfo),
VMSTATE_UINT32_ARRAY(ilevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(olevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),

View File

@@ -296,7 +296,6 @@ static VMStateDescription vmstate_pxa2xx_pic_regs = {
.name = "pxa2xx_pic",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.post_load = pxa2xx_pic_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(int_enabled, PXA2xxPICState, 2),

View File

@@ -45,7 +45,7 @@ static const int realview_board_id[] = {
0x76d
};
static void realview_init(QEMUMachineInitArgs *args,
static void realview_init(MachineState *machine,
enum realview_board_type board_type)
{
ARMCPU *cpu = NULL;
@@ -71,7 +71,7 @@ static void realview_init(QEMUMachineInitArgs *args,
uint32_t proc_id = 0;
uint32_t sys_id;
ram_addr_t low_ram_size;
ram_addr_t ram_size = args->ram_size;
ram_addr_t ram_size = machine->ram_size;
hwaddr periphbase = 0;
switch (board_type) {
@@ -91,7 +91,7 @@ static void realview_init(QEMUMachineInitArgs *args,
break;
}
cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, args->cpu_model);
cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model);
if (!cpu_oc) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
@@ -342,45 +342,45 @@ static void realview_init(QEMUMachineInitArgs *args,
memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack);
realview_binfo.ram_size = ram_size;
realview_binfo.kernel_filename = args->kernel_filename;
realview_binfo.kernel_cmdline = args->kernel_cmdline;
realview_binfo.initrd_filename = args->initrd_filename;
realview_binfo.kernel_filename = machine->kernel_filename;
realview_binfo.kernel_cmdline = machine->kernel_cmdline;
realview_binfo.initrd_filename = machine->initrd_filename;
realview_binfo.nb_cpus = smp_cpus;
realview_binfo.board_id = realview_board_id[board_type];
realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);
}
static void realview_eb_init(QEMUMachineInitArgs *args)
static void realview_eb_init(MachineState *machine)
{
if (!args->cpu_model) {
args->cpu_model = "arm926";
if (!machine->cpu_model) {
machine->cpu_model = "arm926";
}
realview_init(args, BOARD_EB);
realview_init(machine, BOARD_EB);
}
static void realview_eb_mpcore_init(QEMUMachineInitArgs *args)
static void realview_eb_mpcore_init(MachineState *machine)
{
if (!args->cpu_model) {
args->cpu_model = "arm11mpcore";
if (!machine->cpu_model) {
machine->cpu_model = "arm11mpcore";
}
realview_init(args, BOARD_EB_MPCORE);
realview_init(machine, BOARD_EB_MPCORE);
}
static void realview_pb_a8_init(QEMUMachineInitArgs *args)
static void realview_pb_a8_init(MachineState *machine)
{
if (!args->cpu_model) {
args->cpu_model = "cortex-a8";
if (!machine->cpu_model) {
machine->cpu_model = "cortex-a8";
}
realview_init(args, BOARD_PB_A8);
realview_init(machine, BOARD_PB_A8);
}
static void realview_pbx_a9_init(QEMUMachineInitArgs *args)
static void realview_pbx_a9_init(MachineState *machine)
{
if (!args->cpu_model) {
args->cpu_model = "cortex-a9";
if (!machine->cpu_model) {
machine->cpu_model = "cortex-a9";
}
realview_init(args, BOARD_PBX_A9);
realview_init(machine, BOARD_PBX_A9);
}
static QEMUMachine realview_eb_machine = {

View File

@@ -887,14 +887,14 @@ static struct arm_boot_info spitz_binfo = {
.ram_size = 0x04000000,
};
static void spitz_common_init(QEMUMachineInitArgs *args,
static void spitz_common_init(MachineState *machine,
enum spitz_model_e model, int arm_id)
{
PXA2xxState *mpu;
DeviceState *scp0, *scp1 = NULL;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *rom = g_new(MemoryRegion, 1);
const char *cpu_model = args->cpu_model;
const char *cpu_model = machine->cpu_model;
if (!cpu_model)
cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";
@@ -935,32 +935,32 @@ static void spitz_common_init(QEMUMachineInitArgs *args,
/* A 4.0 GB microdrive is permanently sitting in CF slot 0. */
spitz_microdrive_attach(mpu, 0);
spitz_binfo.kernel_filename = args->kernel_filename;
spitz_binfo.kernel_cmdline = args->kernel_cmdline;
spitz_binfo.initrd_filename = args->initrd_filename;
spitz_binfo.kernel_filename = machine->kernel_filename;
spitz_binfo.kernel_cmdline = machine->kernel_cmdline;
spitz_binfo.initrd_filename = machine->initrd_filename;
spitz_binfo.board_id = arm_id;
arm_load_kernel(mpu->cpu, &spitz_binfo);
sl_bootparam_write(SL_PXA_PARAM_BASE);
}
static void spitz_init(QEMUMachineInitArgs *args)
static void spitz_init(MachineState *machine)
{
spitz_common_init(args, spitz, 0x2c9);
spitz_common_init(machine, spitz, 0x2c9);
}
static void borzoi_init(QEMUMachineInitArgs *args)
static void borzoi_init(MachineState *machine)
{
spitz_common_init(args, borzoi, 0x33f);
spitz_common_init(machine, borzoi, 0x33f);
}
static void akita_init(QEMUMachineInitArgs *args)
static void akita_init(MachineState *machine)
{
spitz_common_init(args, akita, 0x2e8);
spitz_common_init(machine, akita, 0x2e8);
}
static void terrier_init(QEMUMachineInitArgs *args)
static void terrier_init(MachineState *machine)
{
spitz_common_init(args, terrier, 0x33f);
spitz_common_init(machine, terrier, 0x33f);
}
static QEMUMachine akitapda_machine = {
@@ -1006,8 +1006,7 @@ static VMStateDescription vmstate_sl_nand_info = {
.name = "sl-nand",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(ctl, SLNANDState),
VMSTATE_STRUCT(ecc, SLNANDState, 0, vmstate_ecc_state, ECCState),
VMSTATE_END_OF_LIST(),
@@ -1041,9 +1040,8 @@ static VMStateDescription vmstate_spitz_kbd = {
.name = "spitz-keyboard",
.version_id = 1,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.post_load = spitz_keyboard_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT16(sense_state, SpitzKeyboardState),
VMSTATE_UINT16(strobe_state, SpitzKeyboardState),
VMSTATE_UNUSED_TEST(is_version_0, 5),
@@ -1076,8 +1074,7 @@ static const VMStateDescription vmstate_corgi_ssp_regs = {
.name = "corgi-ssp",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_SSI_SLAVE(ssidev, CorgiSSPState),
VMSTATE_UINT32_ARRAY(enable, CorgiSSPState, 3),
VMSTATE_END_OF_LIST(),
@@ -1105,8 +1102,7 @@ static const VMStateDescription vmstate_spitz_lcdtg_regs = {
.name = "spitz-lcdtg",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_SSI_SLAVE(ssidev, SpitzLCDTG),
VMSTATE_UINT32(bl_intensity, SpitzLCDTG),
VMSTATE_UINT32(bl_power, SpitzLCDTG),

View File

@@ -185,12 +185,19 @@ static uint64_t gptm_read(void *opaque, hwaddr offset,
case 0x44: /* TBPMR */
return s->match_prescale[1];
case 0x48: /* TAR */
if (s->control == 1)
if (s->config == 1) {
return s->rtc;
}
qemu_log_mask(LOG_UNIMP,
"GPTM: read of TAR but timer read not supported");
return 0;
case 0x4c: /* TBR */
hw_error("TODO: Timer value read\n");
qemu_log_mask(LOG_UNIMP,
"GPTM: read of TBR but timer read not supported");
return 0;
default:
hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"GPTM: read at bad offset 0x%x\n", (int)offset);
return 0;
}
}
@@ -286,8 +293,7 @@ static const VMStateDescription vmstate_stellaris_gptm = {
.name = "stellaris_gptm",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(config, gptm_state),
VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
VMSTATE_UINT32(control, gptm_state),
@@ -643,9 +649,8 @@ static const VMStateDescription vmstate_stellaris_sys = {
.name = "stellaris_sys",
.version_id = 2,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.post_load = stellaris_sys_post_load,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(pborctl, ssys_state),
VMSTATE_UINT32(ldopctl, ssys_state),
VMSTATE_UINT32(int_mask, ssys_state),
@@ -851,8 +856,7 @@ static const VMStateDescription vmstate_stellaris_i2c = {
.name = "stellaris_i2c",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(msa, stellaris_i2c_state),
VMSTATE_UINT32(mcs, stellaris_i2c_state),
VMSTATE_UINT32(mdr, stellaris_i2c_state),
@@ -1121,8 +1125,7 @@ static const VMStateDescription vmstate_stellaris_adc = {
.name = "stellaris_adc",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(actss, stellaris_adc_state),
VMSTATE_UINT32(ris, stellaris_adc_state),
VMSTATE_UINT32(im, stellaris_adc_state),
@@ -1287,9 +1290,10 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
sddev = ssi_create_slave(bus, "ssi-sd");
ssddev = ssi_create_slave(bus, "ssd0323");
gpio_out[GPIO_D][0] = qemu_irq_split(qdev_get_gpio_in(sddev, 0),
qdev_get_gpio_in(ssddev, 0));
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 1);
gpio_out[GPIO_D][0] = qemu_irq_split(
qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
/* Make sure the select pin is high. */
qemu_irq_raise(gpio_out[GPIO_D][0]);
@@ -1330,17 +1334,17 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
}
/* FIXME: Figure out how to generate these from stellaris_boards. */
static void lm3s811evb_init(QEMUMachineInitArgs *args)
static void lm3s811evb_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
}
static void lm3s6965evb_init(QEMUMachineInitArgs *args)
static void lm3s6965evb_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
}

View File

@@ -199,7 +199,6 @@ static VMStateDescription vmstate_strongarm_pic_regs = {
.name = "strongarm_pic",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.post_load = strongarm_pic_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32(pending, StrongARMPICState),
@@ -424,7 +423,6 @@ static const VMStateDescription vmstate_strongarm_rtc_regs = {
.name = "strongarm-rtc",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.pre_save = strongarm_rtc_pre_save,
.post_load = strongarm_rtc_post_load,
.fields = (VMStateField[]) {
@@ -670,7 +668,6 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = {
.name = "strongarm-gpio",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(ilevel, StrongARMGPIOInfo),
VMSTATE_UINT32(olevel, StrongARMGPIOInfo),
@@ -842,7 +839,6 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = {
.name = "strongarm-ppc",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(ilevel, StrongARMPPCInfo),
VMSTATE_UINT32(olevel, StrongARMPPCInfo),
@@ -1293,7 +1289,6 @@ static const VMStateDescription vmstate_strongarm_uart_regs = {
.name = "strongarm-uart",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.post_load = strongarm_uart_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT8(utcr0, StrongARMUARTState),
@@ -1553,7 +1548,6 @@ static const VMStateDescription vmstate_strongarm_ssp_regs = {
.name = "strongarm-ssp",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.post_load = strongarm_ssp_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT16_ARRAY(sscr, StrongARMSSPState, 2),

View File

@@ -211,12 +211,12 @@ static struct arm_boot_info tosa_binfo = {
.ram_size = 0x04000000,
};
static void tosa_init(QEMUMachineInitArgs *args)
static void tosa_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *rom = g_new(MemoryRegion, 1);
PXA2xxState *mpu;

View File

@@ -173,7 +173,7 @@ static int vpb_sic_init(SysBusDevice *sbd)
static struct arm_boot_info versatile_binfo;
static void versatile_init(QEMUMachineInitArgs *args, int board_id)
static void versatile_init(MachineState *machine, int board_id)
{
ARMCPU *cpu;
MemoryRegion *sysmem = get_system_memory();
@@ -190,15 +190,15 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
int done_smc = 0;
DriveInfo *dinfo;
if (!args->cpu_model) {
args->cpu_model = "arm926";
if (!machine->cpu_model) {
machine->cpu_model = "arm926";
}
cpu = cpu_arm_init(args->cpu_model);
cpu = cpu_arm_init(machine->cpu_model);
if (!cpu) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}
memory_region_init_ram(ram, NULL, "versatile.ram", args->ram_size);
memory_region_init_ram(ram, NULL, "versatile.ram", machine->ram_size);
vmstate_register_ram_global(ram);
/* ??? RAM should repeat to fill physical memory space. */
/* SDRAM at address zero. */
@@ -344,22 +344,22 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
fprintf(stderr, "qemu: Error registering flash memory.\n");
}
versatile_binfo.ram_size = args->ram_size;
versatile_binfo.kernel_filename = args->kernel_filename;
versatile_binfo.kernel_cmdline = args->kernel_cmdline;
versatile_binfo.initrd_filename = args->initrd_filename;
versatile_binfo.ram_size = machine->ram_size;
versatile_binfo.kernel_filename = machine->kernel_filename;
versatile_binfo.kernel_cmdline = machine->kernel_cmdline;
versatile_binfo.initrd_filename = machine->initrd_filename;
versatile_binfo.board_id = board_id;
arm_load_kernel(cpu, &versatile_binfo);
}
static void vpb_init(QEMUMachineInitArgs *args)
static void vpb_init(MachineState *machine)
{
versatile_init(args, 0x183);
versatile_init(machine, 0x183);
}
static void vab_init(QEMUMachineInitArgs *args)
static void vab_init(MachineState *machine)
{
versatile_init(args, 0x25e);
versatile_init(machine, 0x25e);
}
static QEMUMachine versatilepb_machine = {

View File

@@ -509,7 +509,7 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
}
static void vexpress_common_init(VEDBoardInfo *daughterboard,
QEMUMachineInitArgs *args)
MachineState *machine)
{
DeviceState *dev, *sysctl, *pl041;
qemu_irq pic[64];
@@ -525,7 +525,8 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard,
const hwaddr *map = daughterboard->motherboard_map;
int i;
daughterboard->init(daughterboard, args->ram_size, args->cpu_model, pic);
daughterboard->init(daughterboard, machine->ram_size, machine->cpu_model,
pic);
/* Motherboard peripherals: the wiring is the same but the
* addresses vary between the legacy and A-Series memory maps.
@@ -639,10 +640,10 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard,
pic[40 + i]);
}
daughterboard->bootinfo.ram_size = args->ram_size;
daughterboard->bootinfo.kernel_filename = args->kernel_filename;
daughterboard->bootinfo.kernel_cmdline = args->kernel_cmdline;
daughterboard->bootinfo.initrd_filename = args->initrd_filename;
daughterboard->bootinfo.ram_size = machine->ram_size;
daughterboard->bootinfo.kernel_filename = machine->kernel_filename;
daughterboard->bootinfo.kernel_cmdline = machine->kernel_cmdline;
daughterboard->bootinfo.initrd_filename = machine->initrd_filename;
daughterboard->bootinfo.nb_cpus = smp_cpus;
daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID;
daughterboard->bootinfo.loader_start = daughterboard->loader_start;
@@ -653,14 +654,14 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard,
arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo);
}
static void vexpress_a9_init(QEMUMachineInitArgs *args)
static void vexpress_a9_init(MachineState *machine)
{
vexpress_common_init(&a9_daughterboard, args);
vexpress_common_init(&a9_daughterboard, machine);
}
static void vexpress_a15_init(QEMUMachineInitArgs *args)
static void vexpress_a15_init(MachineState *machine)
{
vexpress_common_init(&a15_daughterboard, args);
vexpress_common_init(&a15_daughterboard, machine);
}
static QEMUMachine vexpress_a9_machine = {

View File

@@ -383,13 +383,13 @@ static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
return board->fdt;
}
static void machvirt_init(QEMUMachineInitArgs *args)
static void machvirt_init(MachineState *machine)
{
qemu_irq pic[NUM_IRQS];
MemoryRegion *sysmem = get_system_memory();
int n;
MemoryRegion *ram = g_new(MemoryRegion, 1);
const char *cpu_model = args->cpu_model;
const char *cpu_model = machine->cpu_model;
VirtBoardInfo *vbi;
if (!cpu_model) {
@@ -415,7 +415,7 @@ static void machvirt_init(QEMUMachineInitArgs *args)
exit(1);
}
if (args->ram_size > vbi->memmap[VIRT_MEM].size) {
if (machine->ram_size > vbi->memmap[VIRT_MEM].size) {
error_report("mach-virt: cannot model more than 30GB RAM");
exit(1);
}
@@ -447,7 +447,7 @@ static void machvirt_init(QEMUMachineInitArgs *args)
}
fdt_add_cpu_nodes(vbi);
memory_region_init_ram(ram, NULL, "mach-virt.ram", args->ram_size);
memory_region_init_ram(ram, NULL, "mach-virt.ram", machine->ram_size);
vmstate_register_ram_global(ram);
memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
@@ -461,10 +461,10 @@ static void machvirt_init(QEMUMachineInitArgs *args)
*/
create_virtio_devices(vbi, pic);
vbi->bootinfo.ram_size = args->ram_size;
vbi->bootinfo.kernel_filename = args->kernel_filename;
vbi->bootinfo.kernel_cmdline = args->kernel_cmdline;
vbi->bootinfo.initrd_filename = args->initrd_filename;
vbi->bootinfo.ram_size = machine->ram_size;
vbi->bootinfo.kernel_filename = machine->kernel_filename;
vbi->bootinfo.kernel_cmdline = machine->kernel_cmdline;
vbi->bootinfo.initrd_filename = machine->initrd_filename;
vbi->bootinfo.nb_cpus = smp_cpus;
vbi->bootinfo.board_id = -1;
vbi->bootinfo.loader_start = vbi->memmap[VIRT_MEM].base;

View File

@@ -94,20 +94,20 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
for (j = 0; j < num_ss; ++j) {
flash_dev = ssi_create_slave(spi, "n25q128");
cs_line = qdev_get_gpio_in(flash_dev, 0);
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
sysbus_connect_irq(busdev, i * num_ss + j + 1, cs_line);
}
}
}
static void zynq_init(QEMUMachineInitArgs *args)
static void zynq_init(MachineState *machine)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ram_addr_t ram_size = machine->ram_size;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
ObjectClass *cpu_oc;
ARMCPU *cpu;
MemoryRegion *address_space_mem = get_system_memory();

View File

@@ -164,7 +164,6 @@ static VMStateDescription vmstate_zipit_lcd_state = {
.name = "zipit-lcd",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField[]) {
VMSTATE_SSI_SLAVE(ssidev, ZipitLCD),
VMSTATE_INT32(selected, ZipitLCD),
@@ -275,7 +274,6 @@ static VMStateDescription vmstate_aer915_state = {
.name = "aer915",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_INT32(len, AER915State),
VMSTATE_BUFFER(buf, AER915State),
@@ -302,12 +300,12 @@ static const TypeInfo aer915_info = {
.class_init = aer915_class_init,
};
static void z2_init(QEMUMachineInitArgs *args)
static void z2_init(MachineState *machine)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
MemoryRegion *address_space_mem = get_system_memory();
uint32_t sector_len = 0x10000;
PXA2xxState *mpu;

View File

@@ -245,7 +245,7 @@ static void intel_hda_update_int_sts(IntelHDAState *d)
/* update global status */
if (sts & d->int_ctl) {
sts |= (1 << 31);
sts |= (1U << 31);
}
d->int_sts = sts;
@@ -257,7 +257,7 @@ static void intel_hda_update_irq(IntelHDAState *d)
int level;
intel_hda_update_int_sts(d);
if (d->int_sts & (1 << 31) && d->int_ctl & (1 << 31)) {
if (d->int_sts & (1U << 31) && d->int_ctl & (1U << 31)) {
level = 1;
} else {
level = 0;
@@ -574,7 +574,7 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint3
if (st->ctl & 0x01) {
/* reset */
dprint(d, 1, "st #%d: reset\n", reg->stream);
st->ctl = 0;
st->ctl = SD_STS_FIFO_READY << 24;
}
if ((st->ctl & 0x02) != (old & 0x02)) {
uint32_t stnr = (st->ctl >> 20) & 0x0f;
@@ -829,6 +829,7 @@ static const struct IntelHDAReg regtab[] = {
.wclear = 0x1c000000, \
.offset = offsetof(IntelHDAState, st[_i].ctl), \
.whandler = intel_hda_set_st_ctl, \
.reset = SD_STS_FIFO_READY << 24 \
}, \
[ ST_REG(_i, ICH6_REG_SD_LPIB) ] = { \
.stream = _i, \

View File

@@ -324,9 +324,8 @@ const VMStateDescription vmstate_lm4549_state = {
.name = "lm4549_state",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.post_load = &lm4549_post_load,
.fields = (VMStateField[]) {
.post_load = lm4549_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32(voice_is_active, lm4549_state),
VMSTATE_UINT16_ARRAY(regfile, lm4549_state, 128),
VMSTATE_UINT16_ARRAY(buffer, lm4549_state, LM4549_BUFFER_SIZE),

View File

@@ -259,7 +259,6 @@ static const VMStateDescription mv88w8618_audio_vmsd = {
.name = "mv88w8618_audio",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(playback_mode, mv88w8618_audio_state),
VMSTATE_UINT32(status, mv88w8618_audio_state),

View File

@@ -316,9 +316,8 @@ static const VMStateDescription vmstate_milkymist_ac97 = {
.name = "milkymist-ac97",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.post_load = ac97_post_load,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, MilkymistAC97State, R_MAX),
VMSTATE_END_OF_LIST()
}

View File

@@ -561,8 +561,7 @@ static const VMStateDescription vmstate_pl041_regfile = {
.name = "pl041_regfile",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
#define REGISTER(name, offset) VMSTATE_UINT32(name, pl041_regfile),
#include "pl041.hx"
#undef REGISTER
@@ -574,8 +573,7 @@ static const VMStateDescription vmstate_pl041_fifo = {
.name = "pl041_fifo",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(level, pl041_fifo),
VMSTATE_UINT32_ARRAY(data, pl041_fifo, MAX_FIFO_DEPTH),
VMSTATE_END_OF_LIST()
@@ -586,8 +584,7 @@ static const VMStateDescription vmstate_pl041_channel = {
.name = "pl041_channel",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_STRUCT(tx_fifo, pl041_channel, 0,
vmstate_pl041_fifo, pl041_fifo),
VMSTATE_UINT8(tx_enabled, pl041_channel),

View File

@@ -583,10 +583,9 @@ static const VMStateDescription vmstate_wm8750 = {
.name = CODEC,
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.pre_save = wm8750_pre_save,
.post_load = wm8750_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT8_ARRAY(i2c_data, WM8750State, 2),
VMSTATE_INT32(i2c_len, WM8750State),
VMSTATE_INT32(enable, WM8750State),

View File

@@ -70,6 +70,9 @@ struct VirtIOBlockDataPlane {
queue */
unsigned int num_reqs;
/* Operation blocker on BDS */
Error *blocker;
};
/* Raise an interrupt to signal guest, if necessary */
@@ -350,6 +353,7 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
{
VirtIOBlockDataPlane *s;
int fd;
Error *local_err = NULL;
*dataplane = NULL;
@@ -372,9 +376,10 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
/* If dataplane is (re-)enabled while the guest is running there could be
* block jobs that can conflict.
*/
if (bdrv_in_use(blk->conf.bs)) {
error_setg(errp,
"cannot start dataplane thread while device is in use");
if (bdrv_op_is_blocked(blk->conf.bs, BLOCK_OP_TYPE_DATAPLANE, &local_err)) {
error_report("cannot start dataplane thread: %s",
error_get_pretty(local_err));
error_free(local_err);
return;
}
@@ -406,8 +411,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
}
s->ctx = iothread_get_aio_context(s->iothread);
/* Prevent block operations that conflict with data plane thread */
bdrv_set_in_use(blk->conf.bs, 1);
error_setg(&s->blocker, "block device is in use by data plane");
bdrv_op_block_all(blk->conf.bs, s->blocker);
*dataplane = s;
}
@@ -420,7 +425,8 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
}
virtio_blk_data_plane_stop(s);
bdrv_set_in_use(s->blk->conf.bs, 0);
bdrv_op_unblock_all(s->blk->conf.bs, s->blocker);
error_free(s->blocker);
object_unref(OBJECT(s->iothread));
g_free(s);
}

View File

@@ -81,8 +81,7 @@ VMStateDescription vmstate_ecc_state = {
.name = "ecc-state",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(cp, ECCState),
VMSTATE_UINT16_ARRAY(lp, ECCState, 2),
VMSTATE_UINT16(count, ECCState),

View File

@@ -653,7 +653,6 @@ static const VMStateDescription vmstate_m25p80 = {
.name = "xilinx_spi",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.pre_save = m25p80_pre_save,
.fields = (VMStateField[]) {
VMSTATE_UINT8(state, Flash),

View File

@@ -346,10 +346,9 @@ static const VMStateDescription vmstate_nand = {
.name = "nand",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.pre_save = nand_pre_save,
.post_load = nand_post_load,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(cle, NANDFlashState),
VMSTATE_UINT8(ale, NANDFlashState),
VMSTATE_UINT8(ce, NANDFlashState),

View File

@@ -169,7 +169,6 @@ static const VMStateDescription vmstate_onenand = {
.name = "onenand",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.pre_save = onenand_pre_save,
.post_load = onenand_post_load,
.fields = (VMStateField[]) {

View File

@@ -504,7 +504,6 @@ static const VMStateDescription vmstate_cadence_uart = {
.name = "cadence_uart",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.post_load = cadence_uart_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(r, UartState, R_MAX),

View File

@@ -162,7 +162,6 @@ static const VMStateDescription vmstate_digic_uart = {
.name = "digic-uart",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(reg_rx, DigicUartState),
VMSTATE_UINT32(reg_st, DigicUartState),

View File

@@ -27,6 +27,7 @@
#include "hw/char/escc.h"
#include "sysemu/char.h"
#include "ui/console.h"
#include "ui/input.h"
#include "trace.h"
/*
@@ -94,6 +95,7 @@ typedef struct ChannelState {
ChnID chn; // this channel, A (base+4) or B (base+0)
ChnType type;
uint8_t rx, tx;
QemuInputHandlerState *hs;
} ChannelState;
#define ESCC(obj) OBJECT_CHECK(ESCCState, (obj), TYPE_ESCC)
@@ -714,71 +716,181 @@ MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
return &d->mmio;
}
static const uint8_t keycodes[128] = {
127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX] = {
[Q_KEY_CODE_SHIFT] = 99,
[Q_KEY_CODE_SHIFT_R] = 110,
[Q_KEY_CODE_ALT] = 19,
[Q_KEY_CODE_ALT_R] = 13,
[Q_KEY_CODE_ALTGR] = 13,
[Q_KEY_CODE_CTRL] = 76,
[Q_KEY_CODE_CTRL_R] = 76,
[Q_KEY_CODE_ESC] = 29,
[Q_KEY_CODE_1] = 30,
[Q_KEY_CODE_2] = 31,
[Q_KEY_CODE_3] = 32,
[Q_KEY_CODE_4] = 33,
[Q_KEY_CODE_5] = 34,
[Q_KEY_CODE_6] = 35,
[Q_KEY_CODE_7] = 36,
[Q_KEY_CODE_8] = 37,
[Q_KEY_CODE_9] = 38,
[Q_KEY_CODE_0] = 39,
[Q_KEY_CODE_MINUS] = 40,
[Q_KEY_CODE_EQUAL] = 41,
[Q_KEY_CODE_BACKSPACE] = 43,
[Q_KEY_CODE_TAB] = 53,
[Q_KEY_CODE_Q] = 54,
[Q_KEY_CODE_W] = 55,
[Q_KEY_CODE_E] = 56,
[Q_KEY_CODE_R] = 57,
[Q_KEY_CODE_T] = 58,
[Q_KEY_CODE_Y] = 59,
[Q_KEY_CODE_U] = 60,
[Q_KEY_CODE_I] = 61,
[Q_KEY_CODE_O] = 62,
[Q_KEY_CODE_P] = 63,
[Q_KEY_CODE_BRACKET_LEFT] = 64,
[Q_KEY_CODE_BRACKET_RIGHT] = 65,
[Q_KEY_CODE_RET] = 89,
[Q_KEY_CODE_A] = 77,
[Q_KEY_CODE_S] = 78,
[Q_KEY_CODE_D] = 79,
[Q_KEY_CODE_F] = 80,
[Q_KEY_CODE_G] = 81,
[Q_KEY_CODE_H] = 82,
[Q_KEY_CODE_J] = 83,
[Q_KEY_CODE_K] = 84,
[Q_KEY_CODE_L] = 85,
[Q_KEY_CODE_SEMICOLON] = 86,
[Q_KEY_CODE_APOSTROPHE] = 87,
[Q_KEY_CODE_GRAVE_ACCENT] = 42,
[Q_KEY_CODE_BACKSLASH] = 88,
[Q_KEY_CODE_Z] = 100,
[Q_KEY_CODE_X] = 101,
[Q_KEY_CODE_C] = 102,
[Q_KEY_CODE_V] = 103,
[Q_KEY_CODE_B] = 104,
[Q_KEY_CODE_N] = 105,
[Q_KEY_CODE_M] = 106,
[Q_KEY_CODE_COMMA] = 107,
[Q_KEY_CODE_DOT] = 108,
[Q_KEY_CODE_SLASH] = 109,
[Q_KEY_CODE_ASTERISK] = 47,
[Q_KEY_CODE_SPC] = 121,
[Q_KEY_CODE_CAPS_LOCK] = 119,
[Q_KEY_CODE_F1] = 5,
[Q_KEY_CODE_F2] = 6,
[Q_KEY_CODE_F3] = 8,
[Q_KEY_CODE_F4] = 10,
[Q_KEY_CODE_F5] = 12,
[Q_KEY_CODE_F6] = 14,
[Q_KEY_CODE_F7] = 16,
[Q_KEY_CODE_F8] = 17,
[Q_KEY_CODE_F9] = 18,
[Q_KEY_CODE_F10] = 7,
[Q_KEY_CODE_NUM_LOCK] = 98,
[Q_KEY_CODE_SCROLL_LOCK] = 23,
[Q_KEY_CODE_KP_DIVIDE] = 46,
[Q_KEY_CODE_KP_MULTIPLY] = 47,
[Q_KEY_CODE_KP_SUBTRACT] = 71,
[Q_KEY_CODE_KP_ADD] = 125,
[Q_KEY_CODE_KP_ENTER] = 90,
[Q_KEY_CODE_KP_DECIMAL] = 50,
[Q_KEY_CODE_KP_0] = 94,
[Q_KEY_CODE_KP_1] = 112,
[Q_KEY_CODE_KP_2] = 113,
[Q_KEY_CODE_KP_3] = 114,
[Q_KEY_CODE_KP_4] = 91,
[Q_KEY_CODE_KP_5] = 92,
[Q_KEY_CODE_KP_6] = 93,
[Q_KEY_CODE_KP_7] = 68,
[Q_KEY_CODE_KP_8] = 69,
[Q_KEY_CODE_KP_9] = 70,
[Q_KEY_CODE_LESS] = 124,
[Q_KEY_CODE_F11] = 9,
[Q_KEY_CODE_F12] = 11,
[Q_KEY_CODE_HOME] = 52,
[Q_KEY_CODE_PGUP] = 96,
[Q_KEY_CODE_PGDN] = 123,
[Q_KEY_CODE_END] = 74,
[Q_KEY_CODE_LEFT] = 24,
[Q_KEY_CODE_UP] = 20,
[Q_KEY_CODE_DOWN] = 27,
[Q_KEY_CODE_RIGHT] = 28,
[Q_KEY_CODE_INSERT] = 44,
[Q_KEY_CODE_DELETE] = 66,
[Q_KEY_CODE_STOP] = 1,
[Q_KEY_CODE_AGAIN] = 3,
[Q_KEY_CODE_PROPS] = 25,
[Q_KEY_CODE_UNDO] = 26,
[Q_KEY_CODE_FRONT] = 49,
[Q_KEY_CODE_COPY] = 51,
[Q_KEY_CODE_OPEN] = 72,
[Q_KEY_CODE_PASTE] = 73,
[Q_KEY_CODE_FIND] = 95,
[Q_KEY_CODE_CUT] = 97,
[Q_KEY_CODE_LF] = 111,
[Q_KEY_CODE_HELP] = 118,
[Q_KEY_CODE_META_L] = 120,
[Q_KEY_CODE_META_R] = 122,
[Q_KEY_CODE_COMPOSE] = 67,
[Q_KEY_CODE_PRINT] = 22,
[Q_KEY_CODE_SYSRQ] = 21,
};
static const uint8_t e0_keycodes[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
};
static void sunkbd_event(void *opaque, int ch)
static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
InputEvent *evt)
{
ChannelState *s = opaque;
int release = ch & 0x80;
ChannelState *s = (ChannelState *)dev;
int qcode, keycode;
trace_escc_sunkbd_event_in(ch);
switch (ch) {
case 58: // Caps lock press
s->caps_lock_mode ^= 1;
if (s->caps_lock_mode == 2)
return; // Drop second press
break;
case 69: // Num lock press
s->num_lock_mode ^= 1;
if (s->num_lock_mode == 2)
return; // Drop second press
break;
case 186: // Caps lock release
s->caps_lock_mode ^= 2;
if (s->caps_lock_mode == 3)
return; // Drop first release
break;
case 197: // Num lock release
s->num_lock_mode ^= 2;
if (s->num_lock_mode == 3)
return; // Drop first release
break;
case 0xe0:
s->e0_mode = 1;
return;
default:
break;
assert(evt->kind == INPUT_EVENT_KIND_KEY);
qcode = qemu_input_key_value_to_qcode(evt->key->key);
trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode],
evt->key->down);
if (qcode == Q_KEY_CODE_CAPS_LOCK) {
if (evt->key->down) {
s->caps_lock_mode ^= 1;
if (s->caps_lock_mode == 2) {
return; /* Drop second press */
}
} else {
s->caps_lock_mode ^= 2;
if (s->caps_lock_mode == 3) {
return; /* Drop first release */
}
}
}
if (s->e0_mode) {
s->e0_mode = 0;
ch = e0_keycodes[ch & 0x7f];
} else {
ch = keycodes[ch & 0x7f];
if (qcode == Q_KEY_CODE_NUM_LOCK) {
if (evt->key->down) {
s->num_lock_mode ^= 1;
if (s->num_lock_mode == 2) {
return; /* Drop second press */
}
} else {
s->num_lock_mode ^= 2;
if (s->num_lock_mode == 3) {
return; /* Drop first release */
}
}
}
trace_escc_sunkbd_event_out(ch);
put_queue(s, ch | release);
keycode = qcode_to_keycode[qcode];
if (!evt->key->down) {
keycode |= 0x80;
}
trace_escc_sunkbd_event_out(keycode);
put_queue(s, keycode);
}
static QemuInputHandler sunkbd_handler = {
.name = "sun keyboard",
.mask = INPUT_EVENT_MASK_KEY,
.event = sunkbd_handle_event,
};
static void handle_kbd_command(ChannelState *s, int val)
{
trace_escc_kbd_command(val);
@@ -800,7 +912,7 @@ static void handle_kbd_command(ChannelState *s, int val)
case 0xf:
clear_queue(s);
put_queue(s, 0xfe);
put_queue(s, 0); // XXX, layout?
put_queue(s, 0x21); /* en-us layout */
break;
default:
break;
@@ -898,7 +1010,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
&sunkbd_handler);
}
return 0;

View File

@@ -560,7 +560,6 @@ static const VMStateDescription vmstate_exynos4210_uart_fifo = {
.name = "exynos4210.uart.fifo",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(sp, Exynos4210UartFIFO),
VMSTATE_UINT32(rp, Exynos4210UartFIFO),
@@ -573,7 +572,6 @@ static const VMStateDescription vmstate_exynos4210_uart = {
.name = "exynos4210.uart",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_STRUCT(rx, Exynos4210UartState, 1,
vmstate_exynos4210_uart_fifo, Exynos4210UartFIFO),

View File

@@ -76,7 +76,6 @@ static const VMStateDescription vmstate_imx_serial = {
.name = "imx-serial",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_INT32(readbuff, IMXSerialState),
VMSTATE_UINT32(usr1, IMXSerialState),

View File

@@ -124,8 +124,7 @@ static const VMStateDescription vmstate_scc2698_channel = {
.name = "scc2698_channel",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_BOOL(rx_enabled, SCC2698Channel),
VMSTATE_UINT8_ARRAY(mr, SCC2698Channel, 2),
VMSTATE_UINT8(mr_idx, SCC2698Channel),
@@ -141,8 +140,7 @@ static const VMStateDescription vmstate_scc2698_block = {
.name = "scc2698_block",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(imr, SCC2698Block),
VMSTATE_UINT8(isr, SCC2698Block),
VMSTATE_END_OF_LIST()
@@ -153,8 +151,7 @@ static const VMStateDescription vmstate_ipoctal = {
.name = "ipoctal232",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_IPACK_DEVICE(parent_obj, IPOctalState),
VMSTATE_STRUCT_ARRAY(ch, IPOctalState, N_CHANNELS, 1,
vmstate_scc2698_channel, SCC2698Channel),

View File

@@ -129,8 +129,7 @@ static const VMStateDescription vmstate_lm32_juart = {
.name = "lm32-juart",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(jtx, LM32JuartState),
VMSTATE_UINT32(jrx, LM32JuartState),
VMSTATE_END_OF_LIST()

View File

@@ -270,8 +270,7 @@ static const VMStateDescription vmstate_lm32_uart = {
.name = "lm32-uart",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, LM32UartState, R_MAX),
VMSTATE_END_OF_LIST()
}

View File

@@ -221,8 +221,7 @@ static const VMStateDescription vmstate_milkymist_uart = {
.name = "milkymist-uart",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, MilkymistUartState, R_MAX),
VMSTATE_END_OF_LIST()
}

View File

@@ -251,8 +251,7 @@ static const VMStateDescription vmstate_pl011 = {
.name = "pl011",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(readbuff, PL011State),
VMSTATE_UINT32(flags, PL011State),
VMSTATE_UINT32(lcr, PL011State),

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