Compare commits

...

658 Commits

Author SHA1 Message Date
Dave Airlie
47c03744b3 ui/sdl2 : initial port to SDL 2.0 (v2.0)
I've ported the SDL1.2 code over, and rewritten it to use the SDL2 interface.

The biggest changes were in the input handling, where SDL2 has done a major
overhaul, and I've had to include a generated translation file to get from
SDL2 codes back to qemu compatible ones. I'm still not sure how the keyboard
layout code works in qemu, so there may be further work if someone can point
me a test case that works with SDL1.2 and doesn't with SDL2.

Some SDL env vars we used to set are no longer used by SDL2,
Windows, OSX support is untested,

I don't think we can link to SDL1.2 and SDL2 at the same time, so I felt
using --with-sdlabi=2.0 to select the new code should be fine, like how
gtk does it.

v1.1: fix keys in text console
v1.2: fix shutdown, cleanups a bit of code, support ARGB cursor

v2.0: merge the SDL multihead patch into this, g_new the number of consoles
needed, wrap DCL inside per-console structure.

Signed-off-by: Dave Airlie <airlied@redhat.com>

Fixes & improvements by kraxel:
 * baum build fix
 * remove text console logic
 * adapt to new input core
 * codestyle fixups

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:05 +01:00
Gerd Hoffmann
6f90f3d786 console: add QemuUIInfo
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:04 +01:00
Gerd Hoffmann
5643706a09 console: add head to index to qemu consoles.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:04 +01:00
Gerd Hoffmann
5c07d00f1b input: remove index_from_keycode (no users)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:04 +01:00
Gerd Hoffmann
70b52f62b8 input: move do_mouse_set to new core
This removes the last user of the lecagy input mouse handler list,
so we can remove more legacy bits with this.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:04 +01:00
Gerd Hoffmann
e842c68d44 input: move qmp_query_mice to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:04 +01:00
Gerd Hoffmann
a8dfb1c34f input: add input_mouse_mode tracepoint
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:04 +01:00
Gerd Hoffmann
4a33f45e2e input: move mouse mode notifier to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:04 +01:00
Gerd Hoffmann
4798648e32 input-legacy: remove kbd_mouse_event
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
2d0755d21c input-legacy: remove kbd_mouse_is_absolute
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
16b0ecd168 input-legacy: remove kbd_mouse_has_absolute
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
faecd955ce input-legacy: remove kbd_put_keycode
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
c43ce5512f input: trace events
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
21bae11a39 input: mouse: switch cocoa ui to new core
Build fixes by Peter Maydell.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
2e08c665cc input: keyboard: switch cocoa ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
c751a74afe input: mouse: switch monitor to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
f100db385d input: mouse: switch spice ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:03 +01:00
Gerd Hoffmann
14768eba46 input: mouse: switch vnc ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:02 +01:00
Gerd Hoffmann
3ab193e662 input: mouse: switch sdl ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:02 +01:00
Gerd Hoffmann
192f81bfce input: mouse: switch gtk ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:02 +01:00
Gerd Hoffmann
edd85a3d9e input: mouse: switch legacy handlers to new core
legacy mouse event handlers are registered in the new core,
so they receive events submitted to the new input core.

legacy kbd_mouse_event() continues to use the old code paths.
So new-core event handlers wouldn't see events submitted via
kbd_mouse_event.

This leads to the constrain that we we must transition all
kbd_mouse_event() users first to keep things working.  But
that is easier to handle than translating legacy mouse events
into new-core mouse events ;)

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:02 +01:00
Gerd Hoffmann
502c8db5b4 input: mouse: add qemu_input_is_absolute()
Same as kbd_mouse_is_absolute(), but using new input core.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:02 +01:00
Gerd Hoffmann
d3535431e8 input: mouse: add graphic_rotate support
Transform absolute mouse events according to graphic_rotate.

Legacy input code does it for both absolute and relative events,
but the logic is broken for relative coordinates, so this is
most likely not used anyway.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:52:02 +01:00
Gerd Hoffmann
43579403a3 input: mouse: add helpers functions to core
Likewise a bunch of helper functions to manage mouse button
and movement events, again to make life easier for the ui code.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:18 +01:00
Gerd Hoffmann
cd10032888 input: keyboard: switch curses ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:18 +01:00
Gerd Hoffmann
de8f580b23 input: keyboard: switch spice ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:18 +01:00
Gerd Hoffmann
8d447d10b7 input: keyboard: switch vnc ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:18 +01:00
Gerd Hoffmann
a25f545d68 input: keyboard: switch sdl ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:18 +01:00
Gerd Hoffmann
af98ba92ac input: keyboard: switch gtk ui to new core
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
d2a9260335 input: keyboard: switch qmp_send_key() to new core.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
9784e57930 input: keyboard: switch legacy handlers to new core
legacy kbd event handlers are registered in the new core,
so they receive events from the new input core code.
keycode -> scancode translation needed here.

legacy kbd_put_keycode() sends events to the new core.
scancode -> keycode translation needed here.

So with this patch the new input core is fully functional
for keyboard events.  New + legacy interfaces can be mixed
in any way.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
6567147588 input: keyboard: add helper functions to core
A bunch of helper functions to manage keyboard events,
to make life simpler for the ui code when submitting
keyboard events.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
c8b405b679 input: add core bits of the new input layer
Register and unregister handlers.
Event dispatcher code.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
8b6b0c59a6 input: qapi: add pause key
It's missing.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
bbd1b1cc25 input: qapi: add unmapped key
Simplifies building something -> QkeyCode mapping tables.
Uninitialized entries can easily identified then.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
031fa96439 input: qapi: define event types
Define input event types, using qapi.  So we get nicely autogenerated
types for our input events.  And when it comes to qmp support some day
things will be a lot easier.

Types are modeled after the linux input layer.  There are separate
event types for each value.  There is a sync to indicate the end
of a event group.

Mouse events are split into motion events (one for each axis) and
button events, which are grouped by sync.

Keyboard events are using the existing KeyValue type.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
7ad95ff76c input: rename file to legacy
Rename ui/input.c to ui/input-legacy.c.
We are going to replace it step by step.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:17 +01:00
Gerd Hoffmann
d4c8533755 console: export QemuConsole index,width,height
Add functions to query QemuConsole properties.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-05 09:50:17 +01:00
Andreas Färber
f55ea6297c block/gluster: Add missing argument to qemu_gluster_init() call
Commit adccfbcd60 (block: gluster - add
reopen support.) did not supply the qemu_gluster_init() Error **
argument, needed since commit a7451cb850
(gluster: correctly propagate errors).

Pass through qemu_gluster_reopen_prepare()'s errp, as done in
qemu_gluster_open().

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 20:20:57 +00:00
Peter Maydell
ac458e121c Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-2014-03-04' into staging
trivial patches for 2014-03-04

# gpg: Signature made Tue 04 Mar 2014 06:13:56 GMT using RSA key ID 74F0C838
# gpg: Good signature from "Michael Tokarev <mjt@tls.msk.ru>"
# gpg:                 aka "Michael Tokarev <mjt@corpit.ru>"
# gpg:                 aka "Michael Tokarev <mjt@debian.org>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 8044 65C5
#      Subkey fingerprint: E190 8639 3B10 B51B AC2C  8B73 5253 C5AD 74F0 C838

* remotes/mjt/tags/trivial-patches-2014-03-04:
  vl: Remove unneeded include file
  qga: Remove unneeded include file
  qemu-img: Remove unneeded include files
  exec: Remove unneeded include files
  util/iov: Use qemu/sockets.h instead of conditional code
  qjson.h: Remove spurious GCC_FMT_ATTR markup from qobject_from_json() declaration
  tests/test-int128: Don't use __noclone__ attribute on clang
  stubs: Optimize dependencies for gdbstub.c
  tcg: Fix typo in comment (dependancies -> dependencies)
  bswap: Modify prototypes of st[wl]_{le, be}_p (avoid type conversions)
  bswap: Modify prototype of stb_p (avoid type conversions)
  object: Report type in error when not user creatable.
  include/qemu/host-utils.h: Trivial typo: ctz->cto

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 18:12:02 +00:00
Peter Maydell
e00ef747f0 Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging
* remotes/qmp-unstable/queue/qmp: (32 commits)
  qapi: Add missing null check to opts_start_struct()
  qapi: Clean up superfluous null check in qapi_dealloc_type_str()
  qapi: Clean up null checking in generated visitors
  qapi: Drop unused code in qapi-commands.py
  qapi: Drop nonsensical header guard in generated qapi-visit.c
  qapi: Fix licensing of scripts
  tests/qapi-schema: Cover flat union types
  tests/qapi-schema: Cover union types with base
  tests/qapi-schema: Cover complex types with base
  tests/qapi-schema: Cover anonymous union types
  tests/qapi-schema: Cover simple argument types
  tests/qapi-schema: Cover optional command arguments
  tests/qapi-schema: Actually check successful QMP command response
  monitor: Remove left-over code in do_info_profile.
  qerror: Improve QERR_DEVICE_NOT_ACTIVE message
  qmp: Check for returned data from __json_read in get_events
  dump: add 'query-dump-guest-memory-capability' command
  Define the architecture for compressed dump format
  dump: make kdump-compressed format available for 'dump-guest-memory'
  dump: add API to write dump pages
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 17:01:07 +00:00
Peter Maydell
4a29420ea1 Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request

# gpg: Signature made Fri 28 Feb 2014 18:27:24 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/block-pull-request:
  block/vmdk: do not report file offset for compressed extents
  discard rbd error output when not relevant in qemu-iotests
  block: use /var/tmp instead of /tmp for -snapshot
  qemu-io-test: Disable Quorum test when not compiled in.
  qmp: Make Quorum error events more palatable.
  qmp: Fix BlockdevOptionQuorum.
  block: gluster - add reopen support.
  block: gluster - code movements, state storage changes
  qemu-iotests: add more tests to the "quick" group

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 16:33:25 +00:00
Peter Maydell
4fd42afe61 Merge remote-tracking branch 'remotes/rth/i386-fix' into staging
* remotes/rth/i386-fix:
  target-i386: Fix ucomis and comis memory access
  target-i386: Fix SSE status flag corruption
  target-i386: Fix CC_OP_CLR vs PF

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 15:53:01 +00:00
Peter Maydell
c2cb92f9ea Merge remote-tracking branch 'remotes/borntraeger/tags/kvm-s390-20140227' into staging
Several features, fixes and cleanups for kvm/s390:

- sclp event facility: cleanup structure. This allows to use
  realize/unrealize   as well as migration support via vmsd
- reboot: Two fixes that make reboot much more reliable
- ipl: make elf loading more robust
- flic interrupt controller: This allows to migrate floating
  interrupts, as well as clear them on reset etc.
- enable async_pf feature of KVM on s390
- several sclp fixes and cleanups
- several sigp fixes and cleanups

* remotes/borntraeger/tags/kvm-s390-20140227: (22 commits)
  s390x/ipl: Fix crash of ELF images with arbitrary entry points
  s390x/kvm: Rework priv instruction handlers
  s390x/kvm: Add missing SIGP CPU RESET order
  s390x/kvm: Rework SIGP INITIAL CPU RESET handler
  s390x/cpu: Use ioctl to reset state in the kernel
  s390-ccw.img: new binary rom to match latest fixes
  s390-ccw.img: Fix sporadic errors with ccw boot image - initialize css
  s390-ccw.img: Fix sporadic reboot hangs: Initialize next_idx
  s390x/event-facility: exploit realize/unrealize
  s390x/event-facility: add support for live migration
  s390x/event-facility: code restructure
  s390x/event-facility: some renaming
  s390x/sclp: Fixed setting of condition code register
  s390x/sclp: Add missing checks to SCLP handler
  s390x/sclp: Fixed the size of sccb and code parameter
  s390x/eventfacility: mask out commands
  s390x/virtio-hcall: Specification exception for illegal subcodes
  s390x/virtio-hcall: Add range check for hypervisor call
  s390x/kvm: Fixed bad SIGP SET-ARCHITECTURE handler
  s390x/async_pf: Check for apf extension and enable pfault
  ...

Conflicts:
	linux-headers/linux/kvm.h

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 14:50:46 +00:00
Peter Maydell
739aa555b8 Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging
* remotes/bonzini/scsi-next:
  block/iscsi: fix segfault if writesame fails
  scsi-disk: Add support for port WWN and index descriptors in VPD page 83h
  block/iscsi: query for supported VPD pages
  block/iscsi: fix deadlock on scsi check condition
  scsi-bus: Fix transfer length for VERIFY with BYTCHK=11b
  scsi: report thin provisioning errors with werror=report
  scsi: Change scsi sense buf size to 252

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 14:25:34 +00:00
Peter Maydell
d47e95c0c8 Merge remote-tracking branch 'remotes/mcayland/qemu-sparc' into staging
* remotes/mcayland/qemu-sparc:
  sun4m: Add Sun CG3 framebuffer initialisation function
  sun4m: Add Sun CG3 framebuffer and corresponding OpenBIOS FCode ROM
  sun4m: fix slavio timer RUN/STOP bit
  sun4m: Set HostID in NVRAM

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 13:09:06 +00:00
Stefan Weil
57f45b6207 Makefile: Add missing dependency for system emulation (fix build)
Comment from Makefile.objs:

The system emulation needs this dependency (which was missing in Makefile),
otherwise builds without tools (or massive parallel builds) fail.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-04 13:02:23 +00:00
Markus Armbruster
b774539743 qapi: Add missing null check to opts_start_struct()
Argument is null when visiting an unboxed struct.  I can't see such a
visit in the current code.  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-03-03 11:17:45 -05:00
Markus Armbruster
25a7017555 qapi: Clean up superfluous null check in qapi_dealloc_type_str()
Argument can't be null.  No other Visitor method type_str() checks for
null.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:17:45 -05:00
Markus Armbruster
949ceeb31b qapi: Clean up null checking in generated visitors
Visitors get passed a pointer to the visited object.  The generated
visitors try to cope with this pointer being null in some places, for
instance like this:

    visit_start_optional(m, obj ? &(*obj)->has_name : NULL, "name", &err);

visit_start_optional() passes its second argument to Visitor method
start_optional.  Three out of three methods dereference it
unconditionally.

I fail to see how this pointer could legitimately be null.

All this useless null checking is highly redundant, which Coverity
duly reports.  About 200 times.

Remove the useless null checks.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:17:20 -05:00
Markus Armbruster
56bed4135f qapi: Drop unused code in qapi-commands.py
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:46 -05:00
Markus Armbruster
a105acbce3 qapi: Drop nonsensical header guard in generated qapi-visit.c
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:45 -05:00
Markus Armbruster
678e48a2e4 qapi: Fix licensing of scripts
The scripts carry this copyright notice:

    # This work is licensed under the terms of the GNU GPLv2.
    # See the COPYING.LIB file in the top-level directory.

The sentences contradict each other, as COPYING.LIB contains the LGPL
2.1.  Michael Roth says this was a simple pasto, and he meant to refer
COPYING.  Let's fix that.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:45 -05:00
Markus Armbruster
2fc0043283 tests/qapi-schema: Cover flat union types
The test demonstrates a generator bug: the generated struct
UserDefFlatUnion doesn't include members for the indirect base
UserDefZero.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:45 -05:00
Markus Armbruster
7ad993b480 tests/qapi-schema: Cover union types with base
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:45 -05:00
Markus Armbruster
aabbd472a0 tests/qapi-schema: Cover complex types with base
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:45 -05:00
Markus Armbruster
2c38b60010 tests/qapi-schema: Cover anonymous union 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-03-03 11:16:45 -05:00
Markus Armbruster
c2216a8a7a tests/qapi-schema: Cover simple argument 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-03-03 11:16:45 -05:00
Markus Armbruster
ab22ad96ce tests/qapi-schema: Cover optional command arguments
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:45 -05:00
Markus Armbruster
357765fed5 tests/qapi-schema: Actually check successful QMP command response
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-03-03 11:16:45 -05:00
Stefan Weil
25254a7191 vl: Remove unneeded include file
This file does not depend on windows.h.

Cc: Anthony Liguori <aliguori@amazon.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-03 09:46:27 +04:00
Stefan Weil
cae8a9289b qga: Remove unneeded include file
This file does not depend on windows.h.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-03 09:46:27 +04:00
Stefan Weil
67d065c3db qemu-img: Remove unneeded include files
There is no dependency on windows.h, and the standard include files are
already included by qemu-common.h.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-03 09:46:27 +04:00
Stefan Weil
777872e5c6 exec: Remove unneeded include files
This file does not depend on windows.h.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-03 09:46:27 +04:00
Stefan Weil
cc99c6f5ff util/iov: Use qemu/sockets.h instead of conditional code
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-03 09:46:27 +04:00
Peter Maydell
aa830cdc28 qjson.h: Remove spurious GCC_FMT_ATTR markup from qobject_from_json() declaration
The function qobject_from_json() doesn't actually allow its
argument to be a format string -- it passes a NULL va_list*
to qobject_from_jsonv(), and the parser code will then never
actually interpret %-escape sequences (it tests whether the
va_list pointer is NULL and will stop with a parse error).

The spurious attribute markup causes clang warnings in some
of the test cases where we programmatically construct JSON
to feed to qobject_from_json():

 tests/test-qmp-input-visitor.c:76:35: warning: format string is not a
 string literal (potentially insecure) [-Wformat-security]
    data->obj = qobject_from_json(json_string);
                                  ^~~~~~~~~~~

Remove the incorrect attribute.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-03 09:45:46 +04:00
Peter Maydell
7edd9ddc97 tests/test-int128: Don't use __noclone__ attribute on clang
clang doesn't support the __noclone__ attribute and emits a warning about
it. Fortunately clang also implements a mechanism for asking if a particular
attribute is implemented; use it. We assume that if the compiler doesn't
support __has_attribute() then it must be GCC and must support __noclone__.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-02 17:20:37 +04:00
Stefan Weil
8ead601883 stubs: Optimize dependencies for gdbstub.c
It does not need qemu-common.h. Including exec/gdbstub.h fixes a warning
from static code analyzers and avoids mismatching declarations for
xml_builtin.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-02 17:13:31 +04:00
Stefan Weil
c5d3c49896 tcg: Fix typo in comment (dependancies -> dependencies)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-02 17:12:51 +04:00
Stefan Weil
55e7c29e46 bswap: Modify prototypes of st[wl]_{le, be}_p (avoid type conversions)
The functions use uint16_t or uint32_t values, so show this in the function
prototypes. Non-optimizing compilers will avoid unnecessary type
conversions when generating calls of these inline functions.

stq_le_p, stq_be_p already use similar prototypes.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-02 17:12:41 +04:00
Stefan Weil
0064aceb29 bswap: Modify prototype of stb_p (avoid type conversions)
The function uses an uint8_t value, so show this in the function
prototype. Non-optimizing compilers will avoid unnecessary type
conversions from (u)int8_t to int and back to uint8_t when generating
calls of this inline function.

stw_p, stl_p and stq_p already use similar prototypes.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-02 17:12:41 +04:00
Hani Benhabiles
de580dafad object: Report type in error when not user creatable.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Hu Tao <hutao@cn.fujitsu.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-02 17:12:41 +04:00
Dr. David Alan Gilbert
1c884abede include/qemu/host-utils.h: Trivial typo: ctz->cto
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-02 17:12:41 +04:00
Hani Benhabiles
de92f3f86a monitor: Remove left-over code in do_info_profile.
This is a left-over from 4a1418e.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 13:49:42 -05:00
Hani Benhabiles
ffe9fe3a25 qerror: Improve QERR_DEVICE_NOT_ACTIVE message
The error message as currently used is confusing as there are no "balloon" or
"spice" devices.

(qemu) balloon 1024
balloon: Device 'balloon' has not been activated

With this patch:

(qemu) balloon 1024
balloon: No balloon device has been activated

Signed-off-by: Hani Benhabiles <hani@linux.com>
Suggested-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 13:39:25 -05:00
Fam Zheng
4864512389 qmp: Check for returned data from __json_read in get_events
When QEMU process aborts and socket is closed, qmp client will not
detect it. When this happens, some qemu-iotests scripts will enter an
endless loop waiting for qmp events.

It's better we raise an exception in qmp.py to catch this and make the
test script stop.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 13:35:53 -05:00
Peter Lieven
3eba13ec25 block/vmdk: do not report file offset for compressed extents
Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:07 +01:00
Loic Dachary
9147d019f3 discard rbd error output when not relevant in qemu-iotests
Suppress rbd progress messages with --no-progress so they are not
confused with an error output when comparing test results ( progress is
displayed on stderr ).

Signed-off-by: Loic Dachary <loic@dachary.org>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:07 +01:00
Amit Shah
69bef7931e block: use /var/tmp instead of /tmp for -snapshot
If TMPDIR is not specified, the default was to use /tmp for the working
copy of the block devices.  Update this to /var/tmp instead, so systems
using tmp-on-tmpfs don't end up inadvertently using RAM for the block
device.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:07 +01:00
Benoît Canet
4b350f1de1 qemu-io-test: Disable Quorum test when not compiled in.
Quorum is not compiled by default: make the quorum 081 test aware of this.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:07 +01:00
Benoît Canet
0c762736df qmp: Make Quorum error events more palatable.
Insert quorum QMP events documentation alphabetically.

Also change the "ret" errno value by an optional "error" being an strerror(-ret)
in the QUORUM_REPORT_BAD qmp event.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:06 +01:00
Benoît Canet
a9e6a0cbe2 qmp: Fix BlockdevOptionQuorum.
Fix some nits before QEMU 2.0 freeze.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:06 +01:00
Jeff Cody
adccfbcd60 block: gluster - add reopen support.
Gluster does parse open flags in its .bdrv_open() implementation,
and the .bdrv_reopen_* implementations need to do the same.

A new gluster connection to the image file to be created is established
in the .bdrv_reopen_prepare(), and the image file opened with the new
flags.

If this is successful, then the old image file is closed, and the
old connection torn down. The relevant structure pointers in the gluster
state structure are updated to the new connection.

If it is not successful, then the new file handle and connection is
abandoned (if it exists), while the old connection is not modified at
all.

With reopen supported, block-commit (and offline commit) is now also
supported for image files whose base image uses the native gluster
protocol driver.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:06 +01:00
Jeff Cody
1b37b3442f block: gluster - code movements, state storage changes
In preparation for supporting reopen on gluster, move flag
parsing out to a function.  Also, add a NULL check in the
gconf cleanup.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:06 +01:00
Paolo Bonzini
9a05feabd5 qemu-iotests: add more tests to the "quick" group
None of these needs QEMU_PROG, and they all take but a few seconds.
We need to point the launching script to qemu-nbd, though.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-28 18:59:06 +01:00
qiaonuohan
7d6dc7f30c dump: add 'query-dump-guest-memory-capability' command
'query-dump-guest-memory-capability' is used to query the available formats for
'dump-guest-memory'. The output of the command will be like:

-> { "execute": "query-dump-guest-memory-capability" }
<- { "return": { "formats":
                    ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
4ab23a9182 Define the architecture for compressed dump format
Signed-off-by: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
b53ccc30c4 dump: make kdump-compressed format available for 'dump-guest-memory'
Make monitor command 'dump-guest-memory' be able to dump in kdump-compressed
format. The command's usage:

  dump [-p] protocol [begin] [length] [format]

'format' is used to specified the format of vmcore and can be:
1. 'elf': ELF format, without compression
2. 'kdump-zlib': kdump-compressed format, with zlib-compressed
3. 'kdump-lzo': kdump-compressed format, with lzo-compressed
4. 'kdump-snappy': kdump-compressed format, with snappy-compressed
Without 'format' being set, it is same as 'elf'. And if non-elf format is
specified, paging and filter is not allowed.

Note:
  1. The kdump-compressed format is readable only with the crash utility and
     makedumpfile, and it can be smaller than the ELF format because of the
     compression support.
  2. The kdump-compressed format is the 6th edition.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
d12f57ec66 dump: add API to write dump pages
functions are used to write page to vmcore. vmcore is written page by page.
page desc is used to store the information of a page, including a page's size,
offset, compression format, etc.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
64cfba6a47 dump: add APIs to operate DataCache
DataCache is used to store data temporarily, then the data will be written to
vmcore. These functions will be called later when writing data of page to
vmcore.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
d0686c7291 dump: add API to write dump_bitmap
functions are used to write 1st and 2nd dump_bitmap of kdump-compressed format,
which is used to indicate whether the corresponded page is existed in vmcore.
1st and 2nd dump_bitmap are same, because dump level is specified to 1 here.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
298f116827 dump: add API to write dump header
the functions are used to write header of kdump-compressed format to vmcore.
Header of kdump-compressed format includes:
1. common header: DiskDumpHeader32 / DiskDumpHeader64
2. sub header: KdumpSubHeader32 / KdumpSubHeader64
3. extra information: only elf notes here

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
7aad248d35 dump: add members to DumpState and init some of them
add some members to DumpState that will be used in writing vmcore in
kdump-compressed format. some of them, like page_size, will be initialized
in the patch.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
607dacd0a0 dump: add support for lzo/snappy
kdump-compressed format supports three compression format, zlib/lzo/snappy.
Currently, only zlib is available. This patch is used to support lzo/snappy.
'--enable-lzo/--enable-snappy' is needed to be specified with configure to make
lzo/snappy available for qemu

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:52:03 -05:00
qiaonuohan
4835ef7784 dump: add API to write elf notes to buffer
the function can be used by write_elf32_notes/write_elf64_notes to write notes
to a buffer. If fd_write_vmcore is used, write_elf32_notes/write_elf64_notes
will write elf notes to vmcore directly. Instead, if buf_write_note is used,
elf notes will be written to opaque->note_buf at first.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:49:02 -05:00
qiaonuohan
5d31babe5c dump: add API to write vmcore
Function is used to write vmcore in flatten format. In flatten format, data is
written block by block, and in front of each block, a struct
MakedumpfileDataHeader is stored there to indicate the offset and size of the
data block.

struct MakedumpfileDataHeader {
    int64_t offset;
    int64_t buf_size;
};

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:49:02 -05:00
qiaonuohan
fda053875e dump: add API to write header of flatten format
flatten format will be used when writing kdump-compressed format. The format is
also used by makedumpfile, you can refer to the following URL to get more
detailed information about flatten format of kdump-compressed format:
http://sourceforge.net/projects/makedumpfile/

The two functions here are used to write start flat header and end flat header
to vmcore, and they will be called later when flatten format is used.

struct MakedumpfileHeader stored at the head of vmcore is used to indicate the
vmcore is in flatten format.

struct MakedumpfileHeader {
    char signature[16];     /* = "makedumpfile" */
    int64_t type;           /* = 1 */
    int64_t version;        /* = 1 */
};

And struct MakedumpfileDataHeader, with offset and buf_size set to -1, is used
to indicate the end of vmcore in flatten format.

struct MakedumpfileDataHeader {
    int64_t offset;         /* = -1 */
    int64_t buf_size;       /* = -1 */
};

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:49:02 -05:00
qiaonuohan
6a519918b3 dump: add argument to write_elfxx_notes
write_elf32_notes/wirte_elf64_notes use fd_write_vmcore to write elf notes to
vmcore. Adding parameter "WriteCoreDumpFunction f" makes it available to choose
the method of writing elf notes

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:49:02 -05:00
qiaonuohan
b5ba1cc626 dump: const-qualify the buf of WriteCoreDumpFunction
WriteCoreDumpFunction is a function pointer that points to the function used to
write content in "buf" into core file, so "buf" should be const-qualify.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:49:02 -05:00
Richard Henderson
cb48da7f81 target-i386: Fix ucomis and comis memory access
We were loading 16 bytes for both single and double-precision
scalar comparisons.

Reported-by: Alexander Bluhm <bluhm@openbsd.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-28 08:44:26 -08:00
Richard Henderson
4e47e39ab0 target-i386: Fix SSE status flag corruption
When we restore the mxcsr register with FXRSTOR, or set it with gdb,
we need to update the various SSE status flags in CPUX86State

Reported-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-28 08:44:01 -08:00
Richard Henderson
d2fe51bda8 target-i386: Fix CC_OP_CLR vs PF
Parity should be set for a zero result.

Cc: qemu-stable@nongnu.org
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-28 08:43:15 -08:00
Luiz Capitulino
fbb0621a0f MAINTAINERS: update status for HMP, QAPI and QMP trees
This commit updates the status for the HMP, QAPI and QMP trees from
"Supported" to "Maintained".

In practice this means that patch review and pull requests may take
longer. Also, I'll rely more on reviewers such as Eric Blake so that
I'm able to send pull requests regularly.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:41:43 -05:00
Fam Zheng
cd159d0954 QMP: Allow dot separated dict path arguments in qmp-shell
As another convenience to allow using commands that expect a dict as
argument, this patch adds support for foo.bar=value syntax, similar to
command line argument style:

  (QEMU) blockdev-add options.driver=file options.id=drive1 options.filename=...

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-28 11:41:43 -05:00
Fam Zheng
d844a7b656 modules: Fix building with --enable-modules
Compiling util/modules.c with modules enabled fails now.

Fix it by including qemu-common.h before #ifdef testing in module.c.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1393453893-12125-1-git-send-email-famz@redhat.com
Reviewed-by: Hu Tao <hutao@cn.fujitsu.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-28 12:30:13 +00:00
Peter Maydell
9fbee91a13 Merge remote-tracking branch 'remotes/kvm/uq/master' into staging
* remotes/kvm/uq/master:
  KVM: Use return value for error print

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-27 16:00:31 +00:00
Peter Maydell
73795cea96 Merge remote-tracking branch 'remotes/awilliam/tags/vfio-pci-for-qemu-20140226.0' into staging
Updates include:
 - Coverify fixes for vfio & pci-assign (Markus)
 - VFIO blacklisting support for known brokwn PCI option ROMs (Bandan)

# gpg: Signature made Wed 26 Feb 2014 18:15:28 GMT using RSA key ID 3BB08B22
# gpg: Can't check signature: public key not found

* remotes/awilliam/tags/vfio-pci-for-qemu-20140226.0:
  vfio: blacklist loading of unstable roms
  qdev-monitor: set DeviceState opts before calling realize
  pci-assign: Fix potential read beyond buffer on -EBUSY
  vfio: Fix overrun after readlink() fills buffer completely

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-27 11:31:52 +00:00
Mark Cave-Ayland
af87bf290f sun4m: Add Sun CG3 framebuffer initialisation function
In order to allow the user to choose the framebuffer for sparc-softmmu, add
-vga tcx and -vga cg3 options to the QEMU command line. If no option is
specified, the default TCX framebuffer is used.

Since proprietary FCode ROMs use a resolution of 1152x900, slightly relax the
validation rules to allow both displays to be initiated at the higher
resolution used by these ROMs upon request (OpenBIOS FCode ROMs default to
the normal QEMU sun4m default resolution of 1024x768).

Finally move any fprintf(stderr ...) statements in the areas affected by this
patch over to the new error_report() function.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: Blue Swirl <blauwirbel@gmail.com>
CC: Anthony Liguori <aliguori@amazon.com>
CC: Peter Maydell <peter.maydell@linaro.org>
CC: Bob Breuer <breuerr@mc.net>
CC: Artyom Tarasenko <atar4qemu@gmail.com>
2014-02-27 10:01:41 +00:00
Mark Cave-Ayland
9eb08a435a sun4m: Add Sun CG3 framebuffer and corresponding OpenBIOS FCode ROM
The CG3 framebuffer is a simple 8-bit framebuffer for use with operating
systems such as early Solaris that do not have drivers for TCX.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: Blue Swirl <blauwirbel@gmail.com>
CC: Anthony Liguori <aliguori@amazon.com>
CC: Peter Maydell <peter.maydell@linaro.org>
CC: Bob Breuer <breuerr@mc.net>
CC: Artyom Tarasenko <atar4qemu@gmail.com>
2014-02-27 10:01:41 +00:00
Mark Cave-Ayland
ead4cf04f8 sun4m: fix slavio timer RUN/STOP bit
The sun4m architecture has one 'system' timer and one timer per CPU.
The CPU timers can be configured in two modes:

  * 22 bits Counter/Timer. Periodic interrupts.
  * 54 bits User timer. For profiling. In this mode, the Run/Stop bit
    controls the timer.

The run/stop bit controls the timer only when it is in "User" mode, but
its state shall be persistent.

Signed-off-by: Olivier Danet <odanet@caramail.com>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-02-27 10:01:41 +00:00
Mark Cave-Ayland
f9681f116c sun4m: Set HostID in NVRAM
On SparcStations, the HostID field in the NVRAM is equal to the last
three bytes of the MAC address (which is also stored in the NVRAM).

This constant is used as an identification/serial number on Solaris.

Signed-off-by: Olivier Danet <odanet@caramail.com>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-02-27 10:01:40 +00:00
Thomas Huth
7f00eb30fe s390x/ipl: Fix crash of ELF images with arbitrary entry points
When loading S390 kernels, the current code expects an ELF file with the
start address 0x10000. Other ELF files cause a segmentation fault. To avoid
these crashes, we should get the start address from the ELF file instead
of always using a hard-coded address.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:26 +01:00
Frank Blaschka
1eecf41b3e s390x/kvm: Rework priv instruction handlers
The current implementation uses the second byte of the instruction
to identify the instruction handler. This is not sufficient to
support instructions not starting with 0xb2. This patch
adds separate handlers for 0xb2, 0xb9 and 0xeb to be able to
support the full instruction set.

Signed-off-by: Frank Blaschka <blaschka@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:26 +01:00
Thomas Huth
04c2b5168e s390x/kvm: Add missing SIGP CPU RESET order
The SIGP order CPU RESET was still missing in the list of our
supported handler. This patch now adds a simple implementation,
by using the cpu_reset() function that is already available in
target-s390x/cpu.c.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:26 +01:00
Thomas Huth
f7d3e46676 s390x/kvm: Rework SIGP INITIAL CPU RESET handler
The s390_cpu_initial_reset() function had two deficiencies: First, it
used an ioctl for the destination CPU, and this ioctl could block
nearly forever, as long as the destination CPU was running in the SIE
loop. Second, it also cleared the general purpose registers - something
it should not do according to the Principles of Operations.
Since we've already got another function for the initial CPU reset in
cpu.c, we can also use that function instead. And by using run_on_cpu()
for executing this code, we make sure that the destination CPU is
correctly kicked out of kernel mode now.

Suggested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:26 +01:00
Thomas Huth
49f5c9e98a s390x/cpu: Use ioctl to reset state in the kernel
Some of the state in the kernel can not be reset from QEMU yet.
For this we've got to use the KVM_S390_INITIAL_RESET ioctl to make
sure that the state in the kernel is set to the right values during
initial CPU reset, too.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:26 +01:00
Christian Borntraeger
0ca3611221 s390-ccw.img: new binary rom to match latest fixes
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:26 +01:00
Christian Borntraeger
5d739a4787 s390-ccw.img: Fix sporadic errors with ccw boot image - initialize css
We have to set the cssid to 0, otherwise the stsch code will
return an operand exception without the m bit. In the same way
we should set m=0.

This case was triggered in some cases during reboot, if for some
reason the location of blk_schid.cssid contains 1 and m was 0.
Turns out that the qemu elf loader does not zero out the bss section
on reboot.

The symptom was an dump of the old kernel with several areas
overwritten. The bootloader does not register a program check
handler, so bios exception jumped back into the old kernel.

Lets just use a local struct with a designed initializer. That
will guarantee that all other subelements are initialized to 0.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-02-27 09:51:26 +01:00
Christian Borntraeger
d1028f1b5b s390-ccw.img: Fix sporadic reboot hangs: Initialize next_idx
The current code does not initialize next_idx in the virtio ring.
As the ccw bios will always use guest memory at a fixed location,
this queue might != 0 after a reboot.
Lets make the initialization explicit.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-02-27 09:51:25 +01:00
Heinz Graalfs
c804c2a717 s390x/event-facility: exploit realize/unrealize
init/exit functionality of abstract SCLPEvent class is now exploiting
realize/unrealize.

Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Heinz Graalfs
6fbef18a4c s390x/event-facility: add support for live migration
Add support for live migration using VMStateDescription.

Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Heinz Graalfs
477a72a1ef s390x/event-facility: code restructure
Code restructure in order to simplify class hierarchy
  - remove S390SCLPDevice abstract base class
    and move function pointers into new SCLPEventFacilityClass
  - implement SCLPEventFacility as SysBusDevice
  - use define constants for instance creation strings

The following ascii-art shows the class structure wrt the SCLP EventFacility
before (CURRENT) and after the restructure (NEW):

----
CURRENT:

   "s390-sclp-events-bus"
   +-------------------------+
   |      SCLPEventsBus      |
   |-------------------------|
   |BusState qbus            |
   +-------------------------+

   +-------------------------+
   |   SCLPEventFacility     |  - to be replaced by new SCLPEventFacility,
   |-------------------------|    which will be a SysBusDevice
   |SCLPEventsBus sbus       |
   |DeviceState *qdev        |
   |unsigned int receive_mask|
   +-------------------------+

   +-------------------------+
   |   S390SCLPDeviceClass   |  - to be replaced by new SCLPEventFacilityClass
   |-------------------------|
   |DeviceClass qdev         |
   |*(init)()                |
   +-------------------------+

   "s390-sclp-event-facility"
             |
         instance-of
             |
             V
   "s390-sclp-device"           - this is an abstract class
   +-------------------------+
   |     S390SCLPDevice   (A)|  - to be replaced by new SCLPEventFacility
   |-------------------------|
   |SysBusDevice busdev      |
   |SCLPEventFacility *ef    |
   |                         |
   |*(sclp_command_handler)()|  - these 2 go to new SCLPEventFacilityClass
   |*(event_pending)()       |
   +-------------------------+

----
NEW:

   "s390-sclp-events-bus"
   +-------------------------+
   |      SCLPEventsBus      |
   |-------------------------|
   |BusState qbus            |
   +-------------------------+

   +-------------------------+
   | SCLPEventFacilityClass  |
   |-------------------------|
   |DeviceClass parent_class |
   |                         |
   |*(init)()                |
   |*(command_handler)()     |
   |*(event_pending)()       |
   +-------------------------+

   "s390-sclp-event-facility"
   +-------------------------+
   |   SCLPEventFacility     |
   |-------------------------|
   |SysBusDevice parent_class|
   |SCLPEventsBus sbus       |
   |unsigned int receive_mask|
   +-------------------------+

Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Heinz Graalfs
65e526c24e s390x/event-facility: some renaming
Do some renaming to shorten some identifiers and to emphasize sclp.

Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Thomas Huth
e8803d93df s390x/sclp: Fixed setting of condition code register
In the SCLP handler function, the condition code register must
only be set if no exception occured.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Thomas Huth
6e25280216 s390x/sclp: Add missing checks to SCLP handler
If the 51 most significant bits of the SCCB address are zero or equal to
the prefix, we should throw an specification exception, too.
Also moved the check for privileged mode to sclp_service_call() to have
all program checks in one place now.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Thomas Huth
a0fa2cb8cc s390x/sclp: Fixed the size of sccb and code parameter
The pointer to the SCCB should not be limited to 32 bits only.
In contrast to this, the command word parameter is only 32 bits
(the upper 32 bits should be ignored).

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Christian Borntraeger
9da45bb217 s390x/eventfacility: mask out commands
As a followup to commit 5f04c14a10
(s390-sclp: Define New SCLP Codes) we should mask the sclp command
not only in base sclp, but also in the event facility.

Based on an initial patch from Ralf Hoppe.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Thomas Huth
77319f2263 s390x/virtio-hcall: Specification exception for illegal subcodes
So far, the DIAG 500 hypervisor call was only setting -EINVAL in
R2 when a guest tried to call this function with an illegal subcode.
This patch now changes the behavior so that a specification exception
is thrown instead, since this is the common behavior of other DIAG
functions (and other CPU instructions) when being called with illegal
parameters.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Thomas Huth
f2c55d1735 s390x/virtio-hcall: Add range check for hypervisor call
The handler for diag 500 did not check whether the requested function
was in the supported range, so illegal values could crash QEMU in the
worst case.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: qemu-stable@nongnu.org
2014-02-27 09:51:25 +01:00
Thomas Huth
0788082a4b s390x/kvm: Fixed bad SIGP SET-ARCHITECTURE handler
The SET-ARCHITECTURE handler in QEMU caused a program interruption.
This is wrong according to the "Principles of Operations" specification
(since SIGP should never cause a program interrupt) and was likely only
introduced for debugging purposes. Since we handle SET-ARCHITECTURE in
the kernel already and only dropped to user space in case of bad mode
parameters, we should just report INVALID PARAMETER in QEMU instead.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Dominik Dingel
819bd3091e s390x/async_pf: Check for apf extension and enable pfault
S390 can also use async page faults, to enhance guest scheduling.
In case of live migration we want to disable the feature and let
all pending request finish.

Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Jens Freimann
3a553fc658 s390x/kvm: implement floating-interrupt controller device
This patch implements a floating-interrupt controller device (flic)
which interacts with the s390 flic kvm_device.

Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:51:25 +01:00
Christian Borntraeger
216db403d0 update linux headers to kvm/next
This updates the kvm headers to
commit d3714010c307d26df251c45be9cd12ab6d41f0c4
    KVM: x86: emulator_cmpxchg_emulated should mark_page_dirty
in kvm/next.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-02-27 09:50:45 +01:00
Peter Maydell
2ce5868ca1 Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140226' into staging
target-arm queue:
 * fixes for various Coverity-spotted bugs
 * support new KVM device control API for VGIC
 * support KVM VGIC save/restore/migration
 * more AArch64 system mode foundations
 * support ARMv8 CRC instructions for A32/T32
 * PL330 minor fixes and cleanup

# gpg: Signature made Wed 26 Feb 2014 17:51:32 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20140226: (45 commits)
  dma/pl330: implement dmaadnh instruction
  dma/pl330: Fix buffer depth
  dma/pl330: Add event debugging printfs
  dma/pl330: Rename parent_obj
  dma/pl330: printf format type sweep.
  dma/pl330: Fix misleading type
  dma/pl330: Delete overly verbose debug printf
  target-arm: Add support for AArch32 ARMv8 CRC32 instructions
  include/qemu/crc32c.h: Rename include guards to match filename
  target-arm: Add utility function for checking AA32/64 state of an EL
  target-arm: Implement AArch64 view of CPACR
  target-arm: A64: Implement MSR (immediate) instructions
  target-arm: Store AIF bits in env->pstate for AArch32
  target-arm: A64: Implement WFI
  target-arm: Get MMU index information correct for A64 code
  target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI
  target-arm: Implement AArch64 dummy breakpoint and watchpoint registers
  target-arm: Implement AArch64 ID and feature registers
  target-arm: Implement AArch64 generic timers
  target-arm: Implement AArch64 MPIDR
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 22:53:51 +00:00
Peter Maydell
6f6831f61a Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20140225' into staging
migration/next for 20140225

# gpg: Signature made Tue 25 Feb 2014 14:04:31 GMT using RSA key ID 5872D723
# gpg: Can't check signature: public key not found

* remotes/juanquintela/tags/migration/20140225:
  rdma: rename 'x-rdma' => 'rdma'
  Fix two XBZRLE corruption issues
  Fix vmstate_info_int32_le comparison/assign
  qemu_file: use fwrite() correctly

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 22:31:10 +00:00
Peter Maydell
bc3fbad816 Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
Net patches

# gpg: Signature made Tue 25 Feb 2014 13:32:33 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/net-pull-request:
  virtio-net: use qemu_get_queue() where possible
  vhost_net: use offload API instead of bypassing it
  net: remove implicit peer from offload API
  net: Disable netmap backend when not supported
  net: add offloading support to netmap backend
  net: make tap offloading callbacks static
  net: virtio-net and vmxnet3 use offloading API
  net: TAP uses NetClientInfo offloading callbacks
  net: extend NetClientInfo for offloading
  net: change vnet-hdr TAP prototypes
  opencores_eth: flush queue whenever can_receive can go from false to true

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 20:04:37 +00:00
Peter Maydell
28c05edff5 Merge remote-tracking branch 'remotes/kraxel/tags/pull-audio-3' into staging
hda-audio: qom cleanups

# gpg: Signature made Mon 24 Feb 2014 12:19:48 GMT 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-3:
  hda-audio: qom cleanups

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 18:22:11 +00:00
Bandan Das
4b9430294e vfio: blacklist loading of unstable roms
Certain cards such as the Broadcom BCM57810 have rom quirks
that exhibit unstable system behavior duing device assignment. In
the particular case of 57810, rom execution hangs and if a FLR
follows, the device becomes inoperable until a power cycle. This
change blacklists loading of rom for such cards unless the user
specifies a romfile or rombar=1 on the cmd line

Signed-off-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-02-26 10:33:45 -07:00
Bandan Das
52aa17cbd8 qdev-monitor: set DeviceState opts before calling realize
Setting opts before the realize property is set allows the
following patch to make decisions based on whether the user
specified "rombar". This also avoids having to create a new
tristate property especially for this purpose

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-02-26 10:32:40 -07:00
Markus Armbruster
82d0794565 pci-assign: Fix potential read beyond buffer on -EBUSY
readlink() doesn't write a terminating null byte.
assign_failed_examine() passes the unterminated string to strrchr().
Oops.  Terminate it.

Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-02-26 10:30:03 -07:00
Markus Armbruster
13665a2d2f vfio: Fix overrun after readlink() fills buffer completely
readlink() returns the number of bytes written to the buffer, and it
doesn't write a terminating null byte.  vfio_init() writes it itself.
Overruns the buffer when readlink() filled it completely.

Fix by treating readlink() filling the buffer completely as error,
like we do in pci-assign.c's assign_failed_examine().

Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2014-02-26 10:28:36 -07:00
Peter Crosthwaite
c04018e933 dma/pl330: implement dmaadnh instruction
Implement the missing DMAADNH instruction. This is a minor variant
of the DMAADDH instruction, so factor out to a common implementation
for both (dmaadxh).

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 73ab13532a7cae53441da89b46c279b5f50785e3.1393372019.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:09 +00:00
Peter Crosthwaite
a5ae7e3984 dma/pl330: Fix buffer depth
This is the product of the data-width and the depth arguments, I.e the
depth of the FIFO is in terms of data entries and not bytes (which is
what the original implementation was suggesting). Fix.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: c34de31031511538ccdb3164b48ee8a6a973ebd4.1393372019.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:08 +00:00
Peter Crosthwaite
432a0a130e dma/pl330: Add event debugging printfs
These are helpful to anyone trying to debug event sequencing.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: e82a0ad804db3de4f46839e55a9d287735ef870d.1393372019.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:08 +00:00
Peter Crosthwaite
1c8be73d4e dma/pl330: Rename parent_obj
As per current QOM conventions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: abb137347ea1ee9c31487b544f3d5435fb17f6a4.1393372019.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:08 +00:00
Peter Crosthwaite
c3143ba877 dma/pl330: printf format type sweep.
Use PRI formats as appropriate rather than raw %x and %d. This fixes
debug printfery on some host platforms. Fix types of debug only
variables as appropriate.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: dbb5f5fd048b2d4a3cb5c6357577d11211a7a585.1393372019.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:08 +00:00
Peter Crosthwaite
024c6e2ea5 dma/pl330: Fix misleading type
This type really should just be a regular int as no usages rely on it's
32 bitness (it's only meaningful as a bit position and not a bit mask).
This also fixes a printf which uses the variable with a regular %d.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 2a99d31f377aee371476d9da8fd0d1b7efa30f63.1393372019.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:08 +00:00
Peter Crosthwaite
63a31905cb dma/pl330: Delete overly verbose debug printf
When using event synchronisation, this particular debug printf floods.
Just delete it.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: dd94d19493f97c47497b9d8caf74ca43e70d58fd.1393372019.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:07 +00:00
Will Newton
eb0ecd5ad9 target-arm: Add support for AArch32 ARMv8 CRC32 instructions
Add support for AArch32 CRC32 and CRC32C instructions added in ARMv8
and add a CPU feature flag to enable these instructions.

The CRC32-C implementation used is the built-in qemu implementation
and The CRC-32 implementation is from zlib. This requires adding zlib
to LIBS to ensure it is linked for the linux-user binary.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1393411566-24104-3-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:07 +00:00
Will Newton
0956ff5a4e include/qemu/crc32c.h: Rename include guards to match filename
Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1393411566-24104-2-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:07 +00:00
Peter Maydell
1f79ee32b5 target-arm: Add utility function for checking AA32/64 state of an EL
There are various situations where we need to behave differently
depending on whether a given exception level is in AArch64 or
AArch32 state. The state of the current exception level is stored
in env->aarch64, but there's no equivalent guest-visible architected
state bits for the status of the exception levels "above" the
current one which may still affect execution. At the moment we
only support EL1 (ie no EL2 or EL3) and insist that AArch64
capable CPUs run with EL1 in AArch64 state, but these may change
in the future, so abstract out the "what state is this?" check
into a utility function which can be enhanced later if necessary.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:07 +00:00
Peter Maydell
34222fb810 target-arm: Implement AArch64 view of CPACR
Implement the AArch64 view of the CPACR. The AArch64
CPACR is defined to have a lot of RES0 bits, but since
the architecture defines that RES0 bits may be implemented
as reads-as-written and we know that a v8 CPU will have
no registered coprocessors for cp0..cp13 we can safely
implement the whole register this way.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:06 +00:00
Peter Maydell
9cfa0b4e4c target-arm: A64: Implement MSR (immediate) instructions
Implement the MSR (immediate) instructions, which can update the
PSTATE SP and DAIF fields.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:06 +00:00
Peter Maydell
4cc35614a0 target-arm: Store AIF bits in env->pstate for AArch32
To avoid complication in code that otherwise would not need to
care about whether EL1 is AArch32 or AArch64, we should store
the interrupt mask bits (CPSR.AIF in AArch32 and PSTATE.DAIF
in AArch64) in one place consistently regardless of EL1's mode.
Since AArch64 has an extra enable bit (D for debug exceptions)
which isn't visible in AArch32, this means we need to keep
the enables in env->pstate. (This is also consistent with the
general approach we're taking that we handle 32 bit CPUs as
being like AArch64/ARMv8 CPUs but which only run in 32 bit mode.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:06 +00:00
Peter Maydell
1ed69e82b8 target-arm: A64: Implement WFI
Implement the WFI instruction for A64; this just involves wiring
up the instruction, and adding a gen_a64_set_pc_im() which was
accidentally omitted from the A64 decoder top loop.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:06 +00:00
Peter Maydell
d9ea7d290b target-arm: Get MMU index information correct for A64 code
Emit the correct MMU index information for loads and stores from
A64 code, rather than hardwiring it to "always kernel mode",
by storing the exception level in the TB flags, and make
cpu_mmu_index() return the right answer when the CPU is in
AArch64 mode.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:05 +00:00
Peter Maydell
cd5c11b84b target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI
Define a dummy version of the AArch64 OSLAR_EL1 system register
which just ignores writes. Linux will always write to this (it
is the OS lock used for debugging), but we don't support debug.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:05 +00:00
Peter Maydell
0b45451e58 target-arm: Implement AArch64 dummy breakpoint and watchpoint registers
In AArch64 the breakpoint and watchpoint registers are mandatory, so the
kernel always accesses them on bootup. Implement dummy versions, which
read as written but have no actual effect.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:05 +00:00
Peter Maydell
e60cef860f target-arm: Implement AArch64 ID and feature registers
Implement the AArch64-specific ID and feature registers. Although
many of these are currently not used by the architecture (and so
always zero for all implementations), we define the full set of
fields in the ARMCPU struct for symmetry.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:05 +00:00
Peter Maydell
a7adc4b779 target-arm: Implement AArch64 generic timers
Implement the AArch64 view of the generic timer system registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:05 +00:00
Peter Maydell
4b7fff2fab target-arm: Implement AArch64 MPIDR
Implement the AArch64 MPIDR system register.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:04 +00:00
Peter Maydell
327ed10fa2 target-arm: Implement AArch64 TTBR*
Implement the AArch64 TTBR* registers. For v7 these were already 64 bits
to handle LPAE, but implemented as two separate uint32_t fields.
Combine them into a single uint64_t which can be used for all purposes.
Since this requires touching every use, take the opportunity to rename
the field to the architectural name.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:04 +00:00
Peter Maydell
a505d7fe5f target-arm: Implement AArch64 VBAR_EL1
Implement the A64 view of the VBAR system register.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:04 +00:00
Peter Maydell
cb2e37dffa target-arm: Implement AArch64 TCR_EL1
Implement the AArch64 TCR_EL1, which is the 64 bit view of
the AArch32 TTBCR. (The uses of the bits in the register are
completely different, but in any given situation the CPU will
always interpret them one way or the other. In fact for QEMU EL1
is always 64 bit, but we share the state field because this
is the correct mapping to permit a future implementation of EL2.)
We also make the AArch64 view the 'master' as far as migration
and reset is concerned.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:04 +00:00
Peter Maydell
5ebafdf31a target-arm: Implement AArch64 SCTLR_EL1
Implement the AArch64 view of the system control register SCTLR_EL1.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:03 +00:00
Peter Maydell
b0fe242751 target-arm: Implement AArch64 memory attribute registers
Implement the AArch64 memory attribute registers. Since QEMU doesn't
model caches it does not need to care about memory attributes at all,
and we can simply make these read-as-written.

We did not previously implement the AArch32 versions of the MAIR
registers, which went unnoticed because of the overbroad TLB_LOCKDOWN
reginfo definition; provide them now to keep the 64<->32 register
relationship clear.

We already provided AMAIR registers for 32 bit as simple RAZ/WI;
extend that to provide a 64 bit RAZ/WI AMAIR_EL1.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:03 +00:00
Peter Maydell
91e240698f target-arm: Implement AArch64 dummy MDSCR_EL1
We don't support letting the guest do debug, but Linux prods the
monitor debug system control register anyway, so implement a dummy
RAZ/WI version.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:03 +00:00
Peter Maydell
168aa23bb0 target-arm: Implement AArch64 TLB invalidate ops
Implement the AArch64 TLB invalidate operations. This is
the full set of TLBI ops defined for a CPU which doesn't
implement EL2 or EL3.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:03 +00:00
Peter Maydell
8af35c37d2 target-arm: Implement AArch64 cache invalidate/clean ops
Implement all the AArch64 cache invalidate and clean ops
(which are all NOPs since QEMU doesn't emulate the cache).
The only remaining unimplemented cache op is DC ZVA.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:02 +00:00
Peter Maydell
cd4da63177 target-arm: Implement AArch64 MIDR_EL1
Implement the AArch64 view of the MIDR system register
(for AArch64 it is a simple constant, unlike the complicated
mess that TI925 imposes on the 32-bit view).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:02 +00:00
Peter Maydell
0eef9d9833 target-arm: Implement AArch64 CurrentEL sysreg
Implement the CurrentEL sysreg.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:02 +00:00
Peter Maydell
7da845b0f4 target-arm: A64: Make cache ID registers visible to AArch64
Make the cache ID system registers (CLIDR, CSSELR, CCSIDR, CTR)
visible to AArch64. These are mostly simple 64-bit extensions of the
existing 32 bit system registers and so can share reginfo definitions.
CTR needs to have a split definition, but we can clean up the
temporary user-mode implementation in favour of using the CPU-specified
reset value, and implement the system-mode-required semantics of
restricting its EL0 accessibility if SCTLR.UCT is not set.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-26 17:20:01 +00:00
Peter Maydell
67ed771ded target-arm: Fix raw read and write functions on AArch64 registers
The raw read and write functions were using the ARM_CP_64BIT flag in
ri->type to determine whether to treat the register's state field as
uint32_t or uint64_t; however AArch64 register info structs don't use
that flag. Abstract out the "how big is the field?" test into a
function and fix it to work for AArch64 registers. For this to work
we must ensure that the reginfo structs put into the hashtable have
the correct state field for their use, not the placeholder STATE_BOTH.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:01 +00:00
Christoffer Dall
855011be05 hw: arm_gic_kvm: Add KVM VGIC save/restore logic
Save and restore the ARM KVM VGIC state from the kernel.  We rely on
QEMU to marshal the GICState data structure and therefore simply
synchronize the kernel state with the QEMU emulated state in both
directions.

We take some care on the restore path to check the VGIC has been
configured with enough IRQs and CPU interfaces that we can properly
restore the state, and for separate set/clear registers we first fully
clear the registers and then set the required bits.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1392687921-26921-1-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:01 +00:00
Christoffer Dall
1da41cc1c6 arm: vgic device control api support
Support creating the ARM vgic device through the device control API and
setting the base address for the distributor and cpu interfaces in KVM
VMs using this API.

Because the older KVM_CREATE_IRQCHIP interface needs the irq chip to be
created prior to creating the VCPUs, we first test if we can use the
device control API in kvm_arch_irqchip_create (using the test flag from
the device control API).  If we cannot, it means we have to fall back to
KVM_CREATE_IRQCHIP and use the older ioctl at this point in time.  If
however, we can use the device control API, we don't do anything and
wait until the arm_gic_kvm driver initializes and let that use the
device control API.

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1392687720-26806-5-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:00 +00:00
Christoffer Dall
0a6a7ccaae kvm: Common device control API functions
Introduces two simple functions:
    int kvm_device_ioctl(int fd, int type, ...);
    int kvm_create_device(KVMState *s, uint64_t type, bool test);

These functions wrap the basic ioctl-based interactions with KVM in a
way similar to other KVM ioctl wrappers.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1392687720-26806-4-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:00 +00:00
Christoffer Dall
d6032e06d1 kvm: Introduce kvm_arch_irqchip_create
Introduce kvm_arch_irqchip_create an arch-specific hook in preparation
for architecture-specific use of the device control API to create IRQ
chips.

Following patches will implement the ARM irqchip create method to prefer
the device control API over the older KVM_CREATE_IRQCHIP API.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1392687720-26806-3-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:00 +00:00
Christoffer Dall
876074c228 linux-headers: Update from v3.14-rc3
Update to tag v3.14-rc3 (6d0abeca3242a88cab8232e4acd7e2bf088f3bc2)

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1392687720-26806-2-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:20:00 +00:00
Christoffer Dall
6453fa998a hw/intc/arm_gic: Fix GIC_SET_LEVEL
The GIC_SET_LEVEL macro unfortunately overwrote the entire level
bitmask instead of just or'ing on the necessary bits, causing active
level PPIs on a core to clear PPIs on other cores.

Cc: qemu-stable@nongnu.org
Reported-by: Rob Herring <rob.herring@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1393031030-8692-1-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-26 17:19:59 +00:00
Peter Maydell
c10f7fc3d1 target-arm: Load correct access bits from ARMv5 level 2 page table descriptors
In ARMv5 level 2 page table descriptors, each 4K or 64K page is split into
four subpages, each of which can have different access permission settings,
which are specified by four two-bit fields in the l2 descriptor. A
long-standing cut-and-paste error meant we were using the wrong bits in
the virtual address to select the access-permission field for 4K pages.

The error has presumably not been noticed before because most guests don't
make use of the ability to set the access permissions differently for
each 1K subpage: if the guest gives the whole page the same access
permissions it doesn't matter which of the 4 AP fields we select.
(The whole issue is irrelevant for ARMv7 CPUs anyway because subpages
aren't supported there.)

Reported-by: Vivek Rai <Vivek.Rai@emulex.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1392667690-8731-1-git-send-email-peter.maydell@linaro.org
2014-02-26 17:19:59 +00:00
Peter Maydell
cf143ad350 hw/arm/musicpal: Remove nonexistent CDTP2, CDTP3 registers
The ethernet device in the musicpal only has two tx queues,
but we modelled it with four CTDP registers, presumably a
cut and paste from the rx queue registers. Since the tx_queue[]
array is only 2 entries long this allowed a guest to overrun
this buffer. Remove the nonexistent registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1392737293-10073-1-git-send-email-peter.maydell@linaro.org
Acked-by: Jan Kiszka <jan.kiszka@web.de>
Cc: qemu-stable@nongnu.org
2014-02-26 17:19:59 +00:00
Peter Maydell
fce0a82608 hw/intc/exynos4210_combiner: Don't overrun output_irq array in init
The Exynos4210 combiner has IIC_NIRQ inputs and IIC_NGRP outputs;
use the correct constant in the loop initializing our output
sysbus IRQs so that we don't overrun the output_irq[] array.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1392659611-8439-1-git-send-email-peter.maydell@linaro.org
Reviewed-by: Andreas Färber <afaerber@suse.de>
Cc: qemu-stable@nongnu.org
2014-02-26 17:19:58 +00:00
Peter Maydell
775fda92a1 target-arm: Fix incorrect arithmetic constructing short-form PAR for ATS ops
Correct some obviously nonsensical bit manipulation spotted by Coverity
when constructing the short-form PAR value for ATS operations.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1392659525-8335-1-git-send-email-peter.maydell@linaro.org
2014-02-26 17:19:58 +00:00
Peter Maydell
cba933b225 hw/timer/arm_timer: Avoid array overrun for bad addresses
The integrator's timer read/write functions log an error for
bad addresses in guest accesses, but were falling through and
using an out of bounds array index rather than returning early.
Fix this.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-id: 1392647854-8067-4-git-send-email-peter.maydell@linaro.org
Cc: qemu-stable@nongnu.org
2014-02-26 17:19:58 +00:00
Peter Maydell
106a73b6d2 hw/net/stellaris_enet: Avoid unintended sign extension
Add a cast to avoid an unintended sign extension that
would mean we returned 0xffffffff in the high 32 bits
for an IA0 read if bit 31 in the MAC address was 1.
(This is harmless since we'll only be doing 4 byte
reads, but it could be confusing, so best avoided.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-id: 1392647854-8067-3-git-send-email-peter.maydell@linaro.org
2014-02-26 17:19:58 +00:00
Peter Maydell
ec1efab957 hw/misc/arm_sysctl: Fix bad boundary check on mb clock accesses
Fix incorrect use of sizeof() rather than ARRAY_SIZE() to guard
accesses into the mb_clock[] array, which was allowing a malicious
guest to overwrite the end of the array.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-id: 1392647854-8067-2-git-send-email-peter.maydell@linaro.org
Cc: qemu-stable@nongnu.org
2014-02-26 17:19:57 +00:00
Peter Crosthwaite
d5001cf787 xilinx: Delete hw/include/xilinx.h
This is now obsolete - remove the header and all its inclusions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Peter Crosthwaite
d91a68a73b xilinx: Inline usages of xilinx_axi*_init()
Inline the only usage of each of xilinx_axiethernet_init and
xilinx_axidma_init. Converts this init to at least a semi-recent QOM
styling.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Peter Crosthwaite
b8d4e1c43b xilinx: Inline usage of xilinx_ethlite_create()
Inline the only usage. Converts this init to at least a semi-recent QOM
styling.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Peter Crosthwaite
29873712e6 xilinx: Inline usages of xilinx_timer_create()
Inline these usages. Converts these init to at least a semi-recent QOM
styling.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Peter Crosthwaite
13c9bfbfbb xilinx: Inline usages of xilinx_intc_create()
Inline these usages. Converts these init to at least a semi-recent QOM
styling.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Peter Crosthwaite
8174196b7f microblaze/ml605: Define macros for irq/memory maps
Define (missing) macros for the interrupt and memory maps for the sake
of self documentation.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Peter Crosthwaite
81cce07ec6 ppc/virtex_ml507: Define macros for irq/memory maps
Define macros for the interrupt and memory maps for the sake of self
documentation.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Peter Crosthwaite
05a738c4ec microblaze/s3adsp_1800: Define macros for irq map
Define macros for the interrupt map for the sake of self documentation.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-26 14:54:45 +10:00
Paolo Bonzini
aa0d1f4488 modules: do not include gmodule-2.0 in static builds
gmodule-2.0's pkg-config files include -Wl,--export-dynamic, which breaks
static builds.  It is a glib bug, but we need to support --static builds for
the linux-user targets, and in the end all that is needed to fix this is:

* outlaw --enable-modules --static, which makes little sense anyway

* only include gmodule-2.0's cflags and ldflags if --enable-modules is
specified on the command line.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1393346215-5636-1-git-send-email-pbonzini@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-25 18:34:28 +00:00
Peter Maydell
a89d97df1f Merge remote-tracking branch 'remotes/spice/tags/pull-spice-3' into staging
qxl: add sanity check

# gpg: Signature made Mon 24 Feb 2014 12:01:27 GMT using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/spice/tags/pull-spice-3:
  qxl: add sanity check

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-25 15:17:24 +00:00
Stefan Hajnoczi
ad37bb3b00 virtio-net: use qemu_get_queue() where possible
qemu_get_queue() is a shorthand for qemu_get_subqueue(n->nic, 0).  Use
the shorthand where possible.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 14:31:05 +01:00
Stefan Hajnoczi
e3e48565c1 vhost_net: use offload API instead of bypassing it
There is no need to access backend->info->has_vnet_hdr() and friends
anymore.  Use the qemu_has_vnet_hdr() API instead.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 14:31:05 +01:00
Stefan Hajnoczi
d6085e3ace net: remove implicit peer from offload API
The virtio_net offload APIs are used on the NIC's peer (i.e. the tap
device).  The API was defined to implicitly use nc->peer, saving the
caller the trouble.

This wasn't ideal because:
1. There are callers who have the peer but not the NIC.  Currently they
   are forced to bypass the API and access peer->info->... directly.
2. The rest of the net.h API uses nc, not nc->peer, so it is
   inconsistent.

This patch pushes nc->peer back up to callers.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 14:31:05 +01:00
Michael R. Hines
41310c6878 rdma: rename 'x-rdma' => 'rdma'
As far as we can tell, all known bugs have been fixed:

1. Parallel migrations are working
2. IPv6 migration is working
3. virt-test is working

I'm not comfortable sending the revised libvirt patch
until this is accepted or review suggestions are addressed,
(including pin-all support. It does not make sense to
remove experimental for one thing and not the other. That's
too many trips through the libvirt community).

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael R. Hines <mrhines@us.ibm.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-25 14:30:28 +01:00
Dr. David Alan Gilbert
6d3cb1f970 Fix two XBZRLE corruption issues
Push zero'd pages into the XBZRLE cache
    A page that was cached by XBZRLE, zero'd and then XBZRLE'd again
    was being compared against a stale cache value

Don't use 'qemu_put_buffer_async' to put pages from the XBZRLE cache
    Since the cache might change before the data hits the wire

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-25 14:30:28 +01:00
Dr. David Alan Gilbert
24a370ef23 Fix vmstate_info_int32_le comparison/assign
Fix comparison of vmstate_info_int32_le so that it succeeds if loaded
value is (l)ess than or (e)qual

When the comparison succeeds, assign the value loaded
  This is a change in behaviour but I think the original intent, since
  the idea is to check if the version/size of the thing you're loading is
  less than some limit, but you might well want to do something based on
  the actual version/size in the file

Fix up comment and name text

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-25 14:30:28 +01:00
Juan Quintela
aded6539d9 qemu_file: use fwrite() correctly
fwrite() returns the number of items written.  But when there is one
error, it can return a short write.

In the particular bug that I was tracking, I did a migration to a
read-only filesystem.  And it was able to finish the migration
correctly.  fwrite() never returned a negative error code, nor zero,
always 4096. (migration writes chunks of about 14000 bytes).  And it
was able to "complete" the migration with success (yes, reading the
file was a bit more difficult).

To add insult to injury, if your amount of memory was big enough (12GB
on my case), it overwrote some important structure, and from them,
malloc failed.  This check makes the problem go away.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-25 14:26:59 +01:00
Peter Maydell
0459650d94 Merge remote-tracking branch 'remotes/mdroth/qga-pull-2014-02-24' into staging
* remotes/mdroth/qga-pull-2014-02-24:
  qemu-ga: isa-serial support on Windows
  qga: Fix memory allocation pasto
  qga: Don't require 'time' argument in guest-set-time command
  qga: vss-win32: Fix interference with snapshot deletion by other VSS request
  qga: vss-win32: Fix interference with snapshot creation by other VSS requesters
  qga: vss-win32: Use NULL as an invalid pointer for OpenEvent and CreateEvent

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-25 12:30:01 +00:00
Peter Maydell
05fd3bf2a1 Merge remote-tracking branch 'remotes/xtensa/tags/20140224-xtensa' into staging
Xtensa fixes and improvements queue 2014-02-24:
- add support for ML605 and KC705 FPGA boards;
- flush opencores_eth queue when new RX descriptor is available;
- add basic checks to cache opcodes;
- make core configuration available to tests;
- implement HW config ID special registers.

# gpg: Signature made Mon 24 Feb 2014 00:52:42 GMT using RSA key ID F83FA044
# gpg: Good signature from "Max Filippov <max.filippov@cogentembedded.com>"
# gpg:                 aka "Max Filippov <jcmvbkbc@gmail.com>"

* remotes/xtensa/tags/20140224-xtensa:
  target-xtensa: provide HW confg ID registers
  target-xtensa: refactor standard core configuration
  target-xtensa: add basic tests for cache opcodes
  target-xtensa: allow using core configuration in tests
  target-xtensa: add overridable test_init macro
  target-xtensa: add basic checks to icache opcodes
  target-xtensa: add basic checks to dcache opcodes
  target-xtensa: add RRRI4 opcode format fields
  opencores_eth: flush queue whenever can_receive can go from false to true
  hw/xtensa: add support for ML605 and KC705 FPGA board

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-25 11:54:40 +00:00
Vincenzo Maffione
0a985b3727 net: Disable netmap backend when not supported
This patch fixes configure so that the netmap backend is not compiled in if the
host doesn't support an API version >= 11. A version upper bound (15) has been
added so that the netmap API can be extended with some minor features without
requiring QEMU code modifications.

Moreover, some changes have been done to net/netmap.c in order to reflect the
current netmap API/ABI (11).

The NETMAP_WITH_LIBS macro makes possible to include some utilities (e.g.
netmap ring macros, D(), RD() and other high level functions) through the netmap
headers. In this way we get rid of the D and RD macro definitions in the QEMU
code, and we open the way for further code simplifications that will be
introduced by future patches.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:17 +01:00
Vincenzo Maffione
f6c65bfb93 net: add offloading support to netmap backend
Whit this patch, the netmap backend supports TSO/UFO/CSUM
offloadings, and accepts the virtio-net header, similarly to what
happens with TAP. The offloading callbacks in the NetClientInfo
interface have been implemented.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:17 +01:00
Vincenzo Maffione
3bac80d31a net: make tap offloading callbacks static
Since TAP offloadings are manipulated through a new API, it's
not necessary to export them in include/net/tap.h anymore.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:17 +01:00
Vincenzo Maffione
cf528b8958 net: virtio-net and vmxnet3 use offloading API
With this patch, virtio-net and vmxnet3 frontends make
use of the qemu_peer_* API for backend offloadings manipulations,
instead of calling TAP-specific functions directly.
We also remove the existing checks which prevent those frontends
from using offloadings with backends different from TAP (e.g. netmap).

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:17 +01:00
Vincenzo Maffione
2e753bcc7d net: TAP uses NetClientInfo offloading callbacks
The TAP NetClientInfo structure is inizialized with the TAP-specific
functions that manipulates offloading features.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:17 +01:00
Vincenzo Maffione
1f55ac4586 net: extend NetClientInfo for offloading
Some new callbacks have been added to generalize the operations done
by virtio-net and vmxnet3 frontends to manipulate TAP offloadings.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:17 +01:00
Vincenzo Maffione
e96dfd110e net: change vnet-hdr TAP prototypes
The tap_has_vnet_hdr() and tap_has_vnet_hdr_len() functions used
to return int, even though they only return true/false values.
This patch changes the prototypes to return bool.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:16 +01:00
Max Filippov
6e50d18847 opencores_eth: flush queue whenever can_receive can go from false to true
The following registers control whether MAC can receive frames:
- MODER.RXEN bit that enables/disables receiver;
- TX_BD_NUM register that specifies number of RX descriptors.
Notify QEMU networking core when the MAC is ready to receive frames.
Discard frame and raise BUSY interrupt when the frame arrives but the
current RX descriptor is not empty.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-25 11:50:16 +01:00
Peter Maydell
e7a1d6c52a Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches

# gpg: Signature made Fri 21 Feb 2014 21:42:24 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (54 commits)
  iotests: Mixed quorum child device specifications
  quorum: Simplify quorum_open()
  quorum: Add unit test.
  quorum: Add quorum_open() and quorum_close().
  quorum: Implement recursive .bdrv_recurse_is_first_non_filter in quorum.
  quorum: Add quorum_co_flush().
  quorum: Add quorum_invalidate_cache().
  quorum: Add quorum_getlength().
  quorum: Add quorum mechanism.
  quorum: Add quorum_aio_readv.
  blkverify: Extract qemu_iovec_clone() and qemu_iovec_compare() from blkverify.
  quorum: Add quorum_aio_writev and its dependencies.
  quorum: Create BDRVQuorumState and BlkDriver and do init.
  quorum: Create quorum.c, add QuorumChildRequest and QuorumAIOCB.
  check-qdict: Test termination of qdict_array_split()
  check-qdict: Adjust test for qdict_array_split()
  qdict: Extract non-QDicts in qdict_array_split()
  qemu-config: Sections must consist of keys
  qemu-iotests: Check qemu-img command line parsing
  qemu-img: Allow -o help with incomplete argument list
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-25 10:50:11 +00:00
Peter Maydell
c58e291591 Merge remote-tracking branch 'remotes/sstabellini/xen-140220' into staging
* remotes/sstabellini/xen-140220:
  xen_disk: fix io accounting
  Call pci_piix3_xen_ide_unplug from unplug_disks

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-24 16:12:55 +00:00
Peter Maydell
6dedf0522c Merge remote-tracking branch 'remotes/bonzini/configure' into staging
* remotes/bonzini/configure:
  build: softmmu targets do not have a "main.o" file
  configure: Disable libtool if -fPIE does not work with it (bug #1257099)
  block: convert block drivers linked with libs to modules
  Makefile: introduce common-obj-m and block-obj-m for DSO
  Makefile: install modules with "make install"
  module: implement module loading
  rules.mak: introduce DSO rules
  darwin: do not use -mdynamic-no-pic
  block: use per-object cflags and libs
  rules.mak: allow per object cflags and libs
  rules.mak: fix $(obj) to a real relative path
  util: Split out exec_dir from os_find_datadir

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-24 15:38:00 +00:00
Peter Maydell
98b21dcdb3 configure: check that C++ compiler actually works
Check that the C++ compiler works with the C compiler; if it
does not, then don't pass CXX to the build process. This
fixes a regression where QEMU was no longer building if the
build environment didn't have a C++ compiler (introduced
in commit 3144f78b, which incorrectly assumed that rules.mak
would only see a non-empty $(CXX) if configure had actually
found a working C++ compiler).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reported-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Tested-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Message-id: 1392909016-14028-1-git-send-email-peter.maydell@linaro.org
2014-02-24 14:53:27 +00:00
Gerd Hoffmann
9c70434f82 qxl: add sanity check
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-02-24 13:00:52 +01:00
Gerd Hoffmann
cd6c88305f hda-audio: qom cleanups
Add HDA_AUDIO type and macro, drop DO_UPCAST().

Had to add a abstract hda audio class as parent
for all hda-* variants to make that fly.  Killed
some init code duplication while being at it.

Cc: Andreas Färber <afaerber@suse.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-24 10:42:09 +01:00
Max Filippov
604e1f9cd0 target-xtensa: provide HW confg ID registers
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:02 +04:00
Max Filippov
676056d4f1 target-xtensa: refactor standard core configuration
Coalesce all standard configuration sections into single
DEFAULT_SECTIONS macro for all cores. This allows to add new features in
a single place: overlay_tool.h

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:02 +04:00
Max Filippov
2c09eee112 target-xtensa: add basic tests for cache opcodes
Test that non-locking prefetch operations don't cause exceptions on
missing TLB and that other 'hit' cache operations do.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:02 +04:00
Max Filippov
a2e67072b7 target-xtensa: allow using core configuration in tests
Add path to the core configuration directory to test build command and
replace .include asm directive with #include to enable preprocessing.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:01 +04:00
Max Filippov
d0fa1f0df3 target-xtensa: add overridable test_init macro
Some test suites, like MMU, need per-test initialization. Don't make them
redefine test macro, add test_init for that purpose.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:01 +04:00
Max Filippov
e848dd4248 target-xtensa: add basic checks to icache opcodes
Check privilege level for privileged instructions (IHU, III, IIU and IPFL
are privileged), memory accessibility for instructions that reference memory
(IH* and IPFL) and windowed register validity for all instruction cache
instructions.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:01 +04:00
Max Filippov
7c84259019 target-xtensa: add basic checks to dcache opcodes
Check privilege level for privileged instructions (DHI, DHU, DII, DIU, DIWB,
DIWBI, DPFL are privileged), memory accessibility for instructions that
reference memory (all DH* and DPFL) and windowed register validity for all
data cache instructions.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:01 +04:00
Max Filippov
6502668237 target-xtensa: add RRRI4 opcode format fields
This encoding is used by cache instructions.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2014-02-24 04:47:01 +04:00
Max Filippov
b807b5ff89 opencores_eth: flush queue whenever can_receive can go from false to true
The following registers control whether MAC can receive frames:
- MODER.RXEN bit that enables/disables receiver;
- TX_BD_NUM register that specifies number of RX descriptors.
Notify QEMU networking core when the MAC is ready to receive frames.
Discard frame and raise BUSY interrupt when the frame arrives but the
current RX descriptor is not empty.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-24 04:47:01 +04:00
Max Filippov
e0db904d1d hw/xtensa: add support for ML605 and KC705 FPGA board
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
2014-02-24 04:47:01 +04:00
Miki Mishael
a749f42da5 qemu-ga: isa-serial support on Windows
Add support for isa-serial method for qemu-ga on Windows,
Added -p command line parameter for serial port name
specification, e.g. "-p COM15".

Signed-off-by: Miki Mishael <mmishael@redhat.com>
Signed-off-by: Dmitry Fleytman <dfleytma@redhat.com>

*added default isa-serial path to help output

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-02-23 18:38:18 -06:00
Markus Armbruster
10b7c5dd0d qga: Fix memory allocation pasto
qmp_guest_file_seek() allocates memory for a GuestFileRead object
instead of the GuestFileSeek object it actually uses.  Harmless,
because the GuestFileRead is slightly larger.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-02-23 13:13:52 -06:00
Michal Privoznik
2c958923bc qga: Don't require 'time' argument in guest-set-time command
As the description to the guest-set-time states, the command is
there to ease time synchronization after resume. If guest was
suspended for longer period of time, its system time can go off
so badly, that even NTP refuses to set it. That's why the command
was invented: to give users chance to set the time (not
necessarily 100% correct). However, there's is no real need for
us to require users to pass an arbitrary time. Especially if we
can read the correct value from RTC (boiling down to reading
host's time). Hence this commit enables logic:

guest-set-time() == guest-set-time($now_from_rtc)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-02-23 13:11:56 -06:00
Tomoki Sekiyama
d9e1f574cb qga: vss-win32: Fix interference with snapshot deletion by other VSS request
When a VSS requester such as vshadow.exe or diskshadow.exe requests to
delete snapshots, qemu-ga VSS provider's DeleteSnapshots() is also called
and returns E_NOTIMPL, that makes the deletion fail.
To avoid this issue, return S_OK and set values that represent no snapshots
are deleted by qemu-ga VSS provider.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@hds.com>
Reviewed-by: Gal Hammer <ghammer@redhat.com>
Reviewed-by: Yan Vugenfirer <yvugenfi@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-02-23 13:11:52 -06:00
Tomoki Sekiyama
ff8adbcfdb qga: vss-win32: Fix interference with snapshot creation by other VSS requesters
When a VSS requester such as vshadow.exe or diskshadow.exe requests to
create disk snapshots, Windows may choose qemu-ga VSS provider if it is
only provider registered on the system. However, because it provides only a
function to freeze the filesystem, the snapshotting fails.

This patch adds a check into CQGAVssProvider::IsVolumeSupported() to reject
the request from other VSS requesters, so that the other provider is chosen.

The check of requester is done by confirming event channels between
qemu-ga's requester and provider established. To ensure that the events are
initialized when CQGAVssProvider::IsVolumeSupported() is called, it moves
the initialization earlier.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@hds.com>
Reviewed-by: Gal Hammer <ghammer@redhat.com>
Reviewed-by: Yan Vugenfirer <yvugenfi@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-02-23 13:11:26 -06:00
Tomoki Sekiyama
4c1b8f1e83 qga: vss-win32: Use NULL as an invalid pointer for OpenEvent and CreateEvent
OpenEvent and CreateEvent WinAPI return NULL when failed to open/create
events handles, instead of INVALID_HANDLE_VALUE (although their return
types are HANDLE).
This replaces INVALID_HANDLE_VALUE related to event handles with NULL.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@hds.com>
Reviewed-by: Gal Hammer <ghammer@redhat.com>
Reviewed-by: Yan Vugenfirer <yvugenfi@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-02-23 13:10:20 -06:00
Peter Lieven
d9738fd246 block/iscsi: fix segfault if writesame fails
commit fa6252b0 introduced a segfault because it tries
to read iTask.task->sense after iTask.task has been
freed.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-22 15:59:24 +01:00
Roland Dreier
64cc22841e scsi-disk: Add support for port WWN and index descriptors in VPD page 83h
To make a VM more convincing to my application, it's useful to be able
to add a port WWN and relative target port index to the descriptors
returned for VPD page 83h.  Add device properties to allow setting
these, and return them from INQUIRY commands.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-22 10:02:24 +01:00
Peter Lieven
24d3bd67ac block/iscsi: query for supported VPD pages
this patch ensures that we only query for block provisioning and
block limits vpd pages if they are advertised. It also cleans
up the inquiry code and eliminates some redundant code.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-22 10:02:23 +01:00
Peter Lieven
837c390137 block/iscsi: fix deadlock on scsi check condition
the retry logic was broken because the complete status
of the task structure was not reset. this resulted in
an infinite loop retrying the command over and over.

CC: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-22 10:02:23 +01:00
Markus Armbruster
7ef8cf9a08 scsi-bus: Fix transfer length for VERIFY with BYTCHK=11b
The transfer length depends on field BYTCHK, which is encoded in byte
1, bits 1..2.  However, the guard for for case BYTCHK=11b doesn't
work, and we get case 01b instead.  Fix it.

Note that since emulated scsi-hd fails the command outright, it takes
SCSI passthrough of a device that actually implements VERIFY with
BYTCHK=11b to make the bug bite.

Screwed up in commit d12ad44.  Spotted by Coverity.

Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-22 10:02:23 +01:00
Paolo Bonzini
703dd81aca scsi: report thin provisioning errors with werror=report
SCSI defines a status code for when a thin-provisioned LUNs would
exceed the allocated space, map ENOSPC to it.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-22 10:02:23 +01:00
Fam Zheng
c5f52875b9 scsi: Change scsi sense buf size to 252
Current buffer size fails the assersion check in like

    hw/scsi/scsi-bus.c:1655:    assert(req->sense_len <= sizeof(req->sense));

when backend (block/iscsi.c) returns more data then 96.

Exercise the core dump path by booting an Gentoo ISO with scsi-generic
device backed with iscsi (built with libiscsi 1.7.0):

    x86_64-softmmu/qemu-system-x86_64 \
    -drive file=iscsi://localhost:3260/iqn.foobar/0,if=none,id=drive-disk \
    -device virtio-scsi-pci,id=scsi1,bus=pci.0,addr=0x6 \
    -device scsi-generic,drive=drive-disk,bus=scsi1.0,id=iscsi-disk \
    -boot d \
    -cdrom gentoo.iso

    qemu-system-x86_64: hw/scsi/scsi-bus.c:1655: scsi_req_complete:
    Assertion `req->sense_len <= sizeof(req->sense)' failed.

According to SPC-4, section 4.5.2.1, 252 is the limit of sense data. So
increase the value to fix it.

Also remove duplicated define for the macro.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-22 10:02:23 +01:00
Max Reitz
6141f3bd69 iotests: Mixed quorum child device specifications
Add a test case to test 081 for mixing full option dicts and reference
strings of specifying the quorum child block devices through QMP.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:40:19 +01:00
Max Reitz
8a87f3d722 quorum: Simplify quorum_open()
Although it may not look like it, this patch simplifies quorum_open().
qdict_array_split() is now able to return QLists with different objects
than only QDicts, therefore it will now do all the work and
quorum_open() does not have to handle reference strings by itself.

This allows mixing full option dicts and reference strings for
specifying the child block devices of quorum; furthermore, it improves
handling of malformed specifications.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:32:24 +01:00
Benoît Canet
c7fc5bc2a4 quorum: Add unit test.
Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:51 +01:00
Benoît Canet
c88a1de51a quorum: Add quorum_open() and quorum_close().
Example of command line:

-drive if=virtio,driver=quorum,\
children.0.file.filename=1.raw,\
children.0.node-name=1.raw,\
children.0.driver=raw,\
children.1.file.filename=2.raw,\
children.1.node-name=2.raw,\
children.1.driver=raw,\
children.2.file.filename=3.raw,\
children.2.node-name=3.raw,\
children.2.driver=raw,\
vote-threshold=2

blkverify=on with vote-threshold=2 and two files can be passed to
emulate blkverify.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:51 +01:00
Benoît Canet
98a7a38f81 quorum: Implement recursive .bdrv_recurse_is_first_non_filter in quorum.
This is used to activate quorum snapshot.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:51 +01:00
Benoît Canet
1c508d174d quorum: Add quorum_co_flush().
Makes a vote to select error if any.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:51 +01:00
Benoît Canet
a28e4c408b quorum: Add quorum_invalidate_cache().
We really want that live migration works with quorum so implement
quorum_invalidate_cache().

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:50 +01:00
Benoît Canet
d55dee2044 quorum: Add quorum_getlength().
Check that every bs file returns the same length.
Otherwise, return -EIO to disable the quorum and
avoid length discrepancy.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:50 +01:00
Benoît Canet
95c6bff356 quorum: Add quorum mechanism.
This patchset enables the core of the quorum mechanism.
The num_children reads are compared to get the majority version and if this
version exists more than threshold times the guest won't see the error at all.

If a block is corrupted or if an error occurs during an IO or if the quorum
cannot be established QMP events are used to report to the management.

Use gnutls's SHA-256 to compare versions.

--enable-quorum must be used to enable the feature.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:50 +01:00
Benoît Canet
7db6982a19 quorum: Add quorum_aio_readv.
Add code to do num_children reads in parallel and cleanup the structures
afterwards.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:49 +01:00
Benoît Canet
f70d7f7e4d blkverify: Extract qemu_iovec_clone() and qemu_iovec_compare() from blkverify.
qemu_iovec_compare() will be used to compare IOs vectors in quorum blkverify
mode. The patch extracts these functions in order to factorize the code.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:49 +01:00
Benoît Canet
13e7956e31 quorum: Add quorum_aio_writev and its dependencies.
Writes are mirrored num_children times on num_children devices.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:49 +01:00
Benoît Canet
cadebd7a2a quorum: Create BDRVQuorumState and BlkDriver and do init.
Create the structure holding the quorum settings and write the minimal block
driver instanciation boilerplate.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:48 +01:00
Benoît Canet
27cec15e4e quorum: Create quorum.c, add QuorumChildRequest and QuorumAIOCB.
Quorum is a block filter mirroring writes to num_children children.
For reads quorum reads each children and does a vote.
If more than vote_threshold versions are identical the quorum is reached and
this winning version is returned to the guest. So quorum prevents bit corruption.
For high availability purpose minority errors are reported via QMP but the guest
does not see them.

This patch creates the driver C source file and introduces the structures that
will be used in asynchronous reads and writes.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:29:48 +01:00
Max Reitz
64757582da check-qdict: Test termination of qdict_array_split()
qdict_array_split() should terminate if it encounters both an entry with
a key of "%u" and entries with keys prefixed "%u." for the same index.

This patch adds a test for this case.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:18:26 +01:00
Max Reitz
7841c76884 check-qdict: Adjust test for qdict_array_split()
Test the new functionality of qdict_array_split(), that is, splitting
off single objects.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:11:26 +01:00
Max Reitz
bae3f92a01 qdict: Extract non-QDicts in qdict_array_split()
Currently, qdict_array_split() only splits off entries with a key prefix
of "%u.", packing them into a new QDict. This patch makes it support
entries with the plain key "%u" as well, directly putting them into the
new QList without creating a QDict.

If there is both an entry with a key of "%u" and other entries with keys
prefixed "%u." (for the same index), the function simply terminates.

To do this, this patch also adds a static function which tests whether a
given QDict contains any keys with the given prefix. This is used to test
whether entries with a key prefixed "%u." do exist in the source QDict
without modifying it.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:11:23 +01:00
Max Reitz
ae39c4b201 qemu-config: Sections must consist of keys
In config_parse_qdict_section(), the QList returned by
qdict_array_split() is assumed to only contain QDicts. Currently, this
is true but it may (and will) change in the future. Therefore, check
whether the assumption actually holds.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 22:11:17 +01:00
Kevin Wolf
a33cc31d08 qemu-iotests: Check qemu-img command line parsing
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-02-21 22:10:31 +01:00
Kevin Wolf
a283cb6e58 qemu-img: Allow -o help with incomplete argument list
This patch allows using 'qemu-img $subcmd -o help' for the create,
convert and amend subcommands, without specifying the previously
required filename arguments.

Note that it's still allowed and meaningful to specify a filename: An
invocation like 'qemu-img create -o help sheepdog:foo' will also display
options that are provided by the Sheepdog driver.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-02-21 22:10:28 +01:00
Kevin Wolf
626f84f39d qemu-img amend: Support multiple -o options
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.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-02-21 22:10:26 +01:00
Kevin Wolf
2dc8328b4c qemu-img convert: Support multiple -o options
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.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-02-21 22:10:24 +01:00
Kevin Wolf
77386bf6eb qemu-img create: Support multiple -o options
If you specified multiple -o options for qemu-img create, it would
silently ignore all but the last one. This patch fixes the problem.

Now multiple -o options has the same meaning as having a single option
with all settings in the order of their respective -o options.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-02-21 22:10:21 +01:00
Kevin Wolf
7cc07ab8da qemu-option: has_help_option() and is_valid_option_list()
has_help_option() checks if any help option ('help' or '?') occurs
anywhere in an option string, so that things like 'cluster_size=4k,help'
are recognised.

is_valid_option_list() ensures that the option list doesn't have options
with leading commas or trailing unescaped commas.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-02-21 22:10:17 +01:00
Paolo Bonzini
5b7aa9b56d vdi: say why an image is bad
Instead of just putting it in debugging output, we can now put the
value in an Error.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:24 +01:00
Paolo Bonzini
76abe4071d block: do not abuse EMEDIUMTYPE
Returning "Wrong medium type" for an image that does not have a valid
header is a bit weird.  Improve the error by mentioning what format
was trying to open it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:24 +01:00
Paolo Bonzini
89ac8480a8 vmdk: correctly propagate errors
Now that we can return the "right" errors, use the Error** parameter
to pass them back instead of just printing them.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:24 +01:00
Paolo Bonzini
37f09e5e3d vmdk: do not try opening a file as both image and descriptor
This prepares for propagating errors from vmdk_open_sparse and
vmdk_open_desc_file up to the caller of vmdk_open.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:24 +01:00
Paolo Bonzini
d1833ef52b vmdk: push vmdk_read_desc up to caller
Currently, we just try reading a VMDK file as both image and descriptor.
This makes it hard to choose which of the two attempts gave the best error.
We'll decide in advance if the file looks like an image or a descriptor,
and this patch is the first step to that end.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:24 +01:00
Paolo Bonzini
a8842e6d2a vmdk: extract vmdk_read_desc
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:24 +01:00
Paolo Bonzini
c0f92b526d vvfat: correctly propagate errors
Before:
    $ ./qemu-io-old
    qemu-io-old> open -r -o driver=vvfat,fat-type=24,dir=i386-softmmu
    Valid FAT types are only 12, 16 and 32
    qemu-io-old: can't open device (null): Could not open image: Invalid argument

After:
    $ ./qemu-io
    qemu-io> open -r -o driver=vvfat,fat-type=24,dir=i386-softmmu
    qemu-io: can't open device (null): Valid FAT types are only 12, 16 and 32

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
6890aad46b vhdx: correctly propagate errors
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
0fea6b7972 qed: correctly propagate errors
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
b6d5066d32 qcow: correctly propagate errors
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
2a94fee3f6 curl: correctly propagate errors
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
f8d924e481 cow: correctly propagate errors
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
a7451cb850 gluster: correctly propagate errors
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
24897a767b gluster: default scheme to gluster:// and host to localhost.
Currently, "gluster:///volname/img" and (using file. options)
"file.driver=gluster,file.filename=foo" will segfault.  Also,
"//host/volname/img" will be rejected, but it is a valid URL
that should be accepted just fine with "file.driver=gluster".
Accept all of these, by inferring missing transport and host
as TCP and localhost respectively.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
f2917853f7 iscsi: correctly propagate errors in iscsi_open
Before:
    $ ./qemu-io-old
    qemu-io-old> open -r -o file.driver=iscsi,file.filename=foo
    Failed to parse URL : foo
    qemu-io-old: can't open device (null): Could not open 'foo': Invalid argument

After:
    $ ./qemu-io
    qemu-io> open -r -o file.driver=iscsi,file.filename=foo
    qemu-io: can't open device (null): Failed to parse URL : foo

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
35cb1748d5 iscsi: fix indentation
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
537b41f501 nbd: move socket wrappers to qemu-nbd
qemu-nbd is one of the few valid users of qerror_report_err.  Move
the error-reporting socket wrappers there.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:23 +01:00
Paolo Bonzini
c06b72781d nbd: inline tcp_socket_incoming_spec into sole caller
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Paolo Bonzini
77e8b9ca64 nbd: correctly propagate errors
Before:
    $ ./qemu-io-old
    qemu-io-old> open -r -o file.driver=nbd
    one of path and host must be specified.
    qemu-io-old: can't open device (null): Could not open image: Invalid argument
    $ ./qemu-io-old
    qemu-io-old> open -r -o file.driver=nbd,file.host=foo,file.path=bar
    path and host may not be used at the same time.
    qemu-io-old: can't open device (null): Could not open image: Invalid argument

After:
    $ ./qemu-io
    qemu-io> open -r -o file.driver=nbd
    qemu-io: can't open device (null): one of path and host must be specified.
    $ ./qemu-io
    qemu-io> open -r -o file.driver=nbd,file.host=foo,file.path=bar
    qemu-io: can't open device (null): path and host may not be used at the same time.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Paolo Bonzini
a69d9af449 nbd: produce a better error if neither host nor port is passed
Before:
    $ qemu-io-old
    qemu-io-old> open -r -o file.driver=nbd
    qemu-io-old: can't open device (null): Could not open image: Invalid argument
    $ ./qemu-io-old
    qemu-io-old> open -r -o file.driver=nbd,file.host=foo,file.path=bar
    path and host may not be used at the same time.
    qemu-io-old: can't open device (null): Could not open image: Invalid argument

After:
    $ ./qemu-io
    qemu-io> open -r -o file.driver=nbd
    one of path and host must be specified.
    qemu-io: can't open device (null): Could not open image: Invalid argument
    $ ./qemu-io
    qemu-io> open -r -o file.driver=nbd,file.host=foo,file.path=bar
    path and host may not be used at the same time.
    qemu-io: can't open device (null): Could not open image: Invalid argument

Next patch will fix the error propagation.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
f7d9fd8c72 block: Remove bdrv_open_image()'s force_raw option
This option is now unnecessary since specifying BDRV_O_PROTOCOL as flag
will do exactly the same.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
5acd9d81e1 block: Reuse success path from bdrv_open()
The fail and success paths of bdrv_file_open() may be further shortened
by reusing code already existent in bdrv_open(). This includes
bdrv_file_open() not taking the reference to options which allows the
removal of QDECREF(options) in that function.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
5469a2a688 block: Handle bs->options in bdrv_open() only
The fail paths of bdrv_file_open() and bdrv_open() naturally exhibit
similarities, thus it is possible to reuse the one from bdrv_open() and
shorten the one in bdrv_file_open() accordingly.

Also, setting bs->options in bdrv_file_open() is not necessary if it is
already done in bdrv_open().

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
d4446eae63 block: Remove bdrv_new() from bdrv_file_open()
Change bdrv_file_open() to take a simple pointer to an already existing
BDS instead of an indirect one. The BDS will be created in bdrv_open()
if necessary.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
5d12aa63c7 block: Reuse reference handling from bdrv_open()
Remove the reference parameter and the related handling code from
bdrv_file_open(), since it exists in bdrv_open() now as well.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
2e40134bfd block: Make bdrv_file_open() static
Add the bdrv_open() option BDRV_O_PROTOCOL which results in passing the
call to bdrv_file_open(). Additionally, make bdrv_file_open() static and
therefore bdrv_open() the only way to call it.

Consequently, all existing calls to bdrv_file_open() have to be adjusted
to use bdrv_open() with the BDRV_O_PROTOCOL flag instead.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
ddf5636dc9 block: Add reference parameter to bdrv_open()
Allow bdrv_open() to handle references to existing block devices just as
bdrv_file_open() is already capable of.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:22 +01:00
Max Reitz
f67503e5bd block: Change BDS parameter of bdrv_open() to **
Make bdrv_open() take a pointer to a BDS pointer, similarly to
bdrv_file_open(). If a pointer to a NULL pointer is given, bdrv_open()
will create a new BDS with an empty name; if the BDS pointer is not
NULL, that existing BDS will be reused (in the same way as bdrv_open()
already did).

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-21 21:02:21 +01:00
Kevin Wolf
e6dc8a1f83 block: Fix bdrv_is_first_non_filter()
Consider top level BlockDriverStates as well.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Tested-by: Benoit Canet <benoit@irqsave.net>
2014-02-21 21:02:21 +01:00
Kevin Wolf
a71835a0cc qcow2: Set zero flag for discarded clusters
Instead of making the backing file contents visible again after a discard
request, set the zero flag if possible (i.e. on version >= 3).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-02-21 21:02:21 +01:00
Peter Maydell
105a060188 Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140220' into staging
target-arm queue:
 * Fix a bug causing an assertion in the NVIC on ARMv7M models
 * More A64 Neon instructions
 * Refactor cpreg API to separate out access check functions, as
   groundwork for AArch64 system mode
 * Fix bug in linux-user A64 store-exclusive of XZR

# gpg: Signature made Thu 20 Feb 2014 11:12:57 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20140220: (30 commits)
  linux-user: AArch64: Fix exclusive store of the zero register
  target-arm: A64: Implement unprivileged load/store
  target-arm: A64: Implement narrowing three-reg-diff operations
  target-arm: A64: Implement the wide 3-reg-different operations
  target-arm: A64: Add most remaining three-reg-diff widening ops
  target-arm: A64: Add opcode comments to disas_simd_three_reg_diff
  target-arm: A64: Implement store-exclusive for system mode
  target-arm: Fix incorrect type for value argument to write_raw_cp_reg
  target-arm: Remove failure status return from read/write_raw_cp_reg
  target-arm: Remove unnecessary code now read/write fns can't fail
  target-arm: Drop success/fail return from cpreg read and write functions
  target-arm: Convert miscellaneous reginfo structs to accessfn
  target-arm: Convert generic timer reginfo to accessfn
  target-arm: Convert performance monitor reginfo to accessfn
  target-arm: Split cpreg access checks out from read/write functions
  target-arm: Stop underdecoding ARM946 PRBS registers
  target-arm: Log bad system register accesses with LOG_UNIMP
  target-arm: Remove unused ARMCPUState sr substruct
  target-arm: Restrict check_ap() use of S and R bits to v6 and earlier
  target-arm: Define names for SCTLR bits
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-21 15:04:58 +00:00
Peter Maydell
3e890c77cf Merge remote-tracking branch 'remotes/stefanha/tags/qtest-monitor-process-pull-request' into staging
qtest resource cleanup pull request

# gpg: Signature made Wed 19 Feb 2014 14:46:34 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/qtest-monitor-process-pull-request:
  qtest: kill QEMU process on g_assert() failure
  qtest: make QEMU our direct child process
  qtest: drop unused child_pid field

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-21 14:54:05 +00:00
Peter Maydell
7a87a7b3e4 Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging
Tracing pull request

# gpg: Signature made Wed 19 Feb 2014 15:42:20 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/tracing-pull-request:
  trace-events: Fix typo in "offset"
  Add ust generated files to .gitignore
  Update documentation for LTTng ust tracing
  Adapt Makefiles to the new LTTng ust interface
  Modified the tracetool framework for LTTng 2.x
  Fix configure script for LTTng 2.x

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-21 14:38:23 +00:00
Peter Maydell
e607784fed Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
This fixes a target-i386 emulation regression

# gpg: Signature made Wed 19 Feb 2014 15:42:12 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  target-i386: Fix I/O bitmap checks for in/out

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-21 14:31:05 +00:00
Peter Maydell
9bd9d5e357 Merge remote-tracking branch 'remotes/riku/linux-user-for-upstream' into staging
* remotes/riku/linux-user-for-upstream:
  linux-user: Fix error handling in target_to_host_semarray()
  linux-user: Implement BLKPG ioctl
  linux-user: Fix error handling in lock_iovec()
  linux-user/signal.c: Don't pass sigaction uninitialised sa_flags
  linux-user/elfload.c: Avoid calling g_free() on uninitialized data
  linux-user: sync syscall numbers upto 3.13

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-21 11:47:28 +00:00
Peter Maydell
774d566cdb tcg/i386: Fix build for systems without working cpuid.h (MacOSX, Win32)
Win32 doesn't have a cpuid.h, and MacOSX may have one but without
the __cpuid() function we use, which means that commit 9d2eec20
broke the build for those platforms. Fix this by tightening up
our configure cpuid.h check to test that the functions we need
are present, and adding some missing #ifdef guards in
tcg/i386/tcg-target.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-21 10:39:10 +00:00
Alexander Graf
521f438e36 KVM: Use return value for error print
Commit 94ccff13 introduced a more verbose failure message and retry
operations on KVM VM creation. However, it ended up using a variable
for its failure message that hasn't been initialized yet.

Fix it to use the value it meant to set.

Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-21 11:19:34 +01:00
Olaf Hering
58da5b1e01 xen_disk: fix io accounting
bdrv_acct_done was called unconditional. But in case the ioreq has no
segments there is no matching bdrv_acct_start call. This could lead to
bogus accounting values.

Found by code inspection.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
2014-02-20 17:57:13 +00:00
Stefano Stabellini
15e8159e76 Call pci_piix3_xen_ide_unplug from unplug_disks
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 17:28:08 +00:00
Peter Maydell
2ca92bb993 Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-3' into staging
- xhci improvements and fixes.
- uhci bugfix.
- cleanups.

# gpg: Signature made Tue 18 Feb 2014 15:48:10 GMT 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-3:
  xhci: use DPRINTF() instead of fprintf(stderr, ...)
  xhci: switch debug printf to tracepoint
  xhci iso: allow for some latency
  xhci iso: fix time calculation
  uhci: invalidate queue on device address changes
  xhci: fix overflow in usb_xhci_post_load
  usb: Remove magic constants from device bmAttributes

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 15:25:05 +00:00
Peter Maydell
3d2bb5cc81 Merge remote-tracking branch 'remotes/rth/tcg-next' into staging
* remotes/rth/tcg-next:
  tcg/i386: Use SHLX/SHRX/SARX instructions
  tcg/i386: Use ANDN instruction
  tcg/i386: Add tcg_out_vex_modrm
  tcg/i386: Move TCG_CT_CONST_* to tcg-target.c
  disas/i386: Disassemble ANDN/SHLX/SHRX/SHAX
  tcg/optimize: Add more identity simplifications
  tcg/optimize: Optmize ANDC X,Y,Y to MOV X,0
  tcg/optimize: Simply some logical ops to NOT
  tcg/optimize: Handle known-zeros masks for ANDC
  tcg/optimize: add known-zero bits compute for load ops
  tcg/optimize: improve known-zero bits for 32-bit ops
  tcg/optimize: fix known-zero bits optimization
  tcg/optimize: fix known-zero bits for right shift ops
  tcg-arm: The shift count of op_rotl_i32 is in args[2] not args[1].
  TCG: Fix 32-bit host allocation typo

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 15:02:07 +00:00
Peter Maydell
61e8a92364 Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-peter' into staging
QOM infrastructure fixes and device conversions

* QTest cleanups and test cases for PCI NICs
* NAND fix for "info qtree"
* Cleanup and extension of QOM machine tests
* IndustryPack test cases and conversion to QOM realize
* I2C cleanups
* Cleanups of legacy qdev properties

# gpg: Signature made Mon 17 Feb 2014 22:15:37 GMT using RSA key ID 3E7E013F
# gpg: Good signature from "Andreas Färber <afaerber@suse.de>"
# gpg:                 aka "Andreas Färber <afaerber@suse.com>"

* remotes/afaerber/tags/qom-devices-for-peter: (49 commits)
  qtest: Include system headers before user headers
  qapi: Refine human printing of sizes
  qdev: Use QAPI type names for properties
  qdev: Add enum property types to QAPI schema
  block: Handle "rechs" and "large" translation options
  qdev: Remove hex8/32/64 property types
  qdev: Remove most legacy printers
  qdev: Use human mode in "info qtree"
  qapi: Add human mode to StringOutputVisitor
  qdev: Inline qdev_prop_parse()
  qdev: Legacy properties are just strings
  qdev: Legacy properties are now read-only
  qdev: Remove legacy parsers for hex8/32/64
  qdev: Sizes are now parsed by StringInputVisitor
  qapi: Add size parser to StringInputVisitor
  qtest: Don't segfault with invalid -qtest option
  ipack: Move IndustryPack out of hw/char/
  ipoctal232: QOM parent field cleanup
  ipack: QOM parent field cleanup for IPackDevice
  ipack: QOM parent field cleanup for IPackBus
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 13:05:48 +00:00
Paolo Bonzini
f966f9ddd1 build: softmmu targets do not have a "main.o" file
Thus this rule is useless.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:14:18 +01:00
Don Slutz
66518bf668 configure: Disable libtool if -fPIE does not work with it (bug #1257099)
Adjust TMPO and added TMPB, TMPL, and TMPA.  libtool needs the names
to be fixed (TMPB).

Add new functions do_libtool and libtool_prog.

Add check for broken gcc and libtool.

Signed-off-by: Don Slutz <dslutz@verizon.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:14:18 +01:00
Fam Zheng
d3399d7cf8 block: convert block drivers linked with libs to modules
The converted block drivers are:

    curl
    iscsi
    rbd
    ssh
    glusterfs

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:14:18 +01:00
Fam Zheng
cc47569881 Makefile: introduce common-obj-m and block-obj-m for DSO
$(common-obj-m) will include $(block-obj-m), like $(common-obj-y) does
for $(block-obj-y).

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:14:18 +01:00
Fam Zheng
e3be6f0ecc Makefile: install modules with "make install"
Install all the modules to ${MODDIR}.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:14:18 +01:00
Fam Zheng
e26110cfc6 module: implement module loading
This patch adds loading, stamp checking and initialization of modules.

The init function of dynamic module is no longer directly called as
__attribute__((constructor)) in static linked version, it is called
only after passed the checking of presense of stamp symbol:

    qemu_stamp_$RELEASEHASH

where $RELEASEHASH is generated by hashing version strings and content
of configure script.

With this, modules built from a different tree/version/configure will
not be loaded.

The module loading code requires gmodule-2.0.

Modules are searched under
 - CONFIG_MODDIR
 - executable folder (to allow running qemu-{img,io} in the build
   directory)
 - ../ of executable folder (to allow running system emulator in the
   build directory)

Modules are linked under their subdir respectively, then copied to top
level of build directory for above convinience, e.g.:
    $(BUILD_DIR)/block/curl.so -> $(BUILD_DIR)/block-curl.so

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:14:18 +01:00
Fam Zheng
17969268f5 rules.mak: introduce DSO rules
Add necessary rules and flags for shared object generation.
The new rules introduced here are:

1) %.o in $(common-obj-m) is compiled to %.o, then linked to %.so.

2) %.mo in $(common-obj-m) is the placeholder for %.so for pattern
matching in Makefile. It's linked to "-shared" with all its dependencies
(multiple *.o) as input. Which means the list of depended objects must
be specified in each sub-Makefile.objs:

    foo.mo-objs := bar.o baz.o qux.o

in the same style with foo.o-cflags and foo.o-libs. The objects here
will be prefixed with "$(obj)/" if it's a subdirectory Makefile.objs.

3) For all files ending up in %.so, the following is added automatically:

    foo.o-cflags += -fPIC -DBUILD_DSO

Also introduce --enable-modules in configure, the option will enable
support of shared object build. Otherwise objects are static linked to
executables.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:14:18 +01:00
Paolo Bonzini
13b6ce0ec9 darwin: do not use -mdynamic-no-pic
While -mdynamic-no-pic can speed up the code somewhat, it is only used
on the legacy PowerPC Mac OS X, and I am not sure if anyone is still
testing that.  Disabling PIC can cause problems when enabling modules,
so do not do that.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:12:54 +01:00
Fam Zheng
6ebc91e5d0 block: use per-object cflags and libs
No longer adds flags and libs for them to global variables, instead
create config-host.mak variables like FOO_CFLAGS and FOO_LIBS, which is
used as per object cflags and libs.

This removes unwanted dependencies from libcacard.

Signed-off-by: Fam Zheng <famz@redhat.com>
[Split from Fam's patch to enable modules. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:12:54 +01:00
Fam Zheng
5c0d52bcd3 rules.mak: allow per object cflags and libs
Adds extract-libs in LINK to expand any "per object libs", the syntax to define
such a libs options is like:

        foo.o-libs := $(CURL_LIBS)

in block/Makefile.objs.

Similarly,

        foo.o-cflags := $(FOO_CFLAGS)

is also supported.

"foo.o" must be listed in a nested var (e.g. common-obj-y) to make the
option variables effective.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:12:54 +01:00
Fam Zheng
ba1183da9a rules.mak: fix $(obj) to a real relative path
Makefile.target includes rule.mak and unnested common-obj-y, then prefix
them with '../', this will ignore object specific QEMU_CFLAGS in subdir
Makefile.objs:

    $(obj)/curl.o: QEMU_CFLAGS += $(CURL_CFLAGS)

Because $(obj) here is './block', instead of '../block'. This doesn't
hurt compiling because we basically build all .o from top Makefile,
before entering Makefile.target, but it will affact arriving per-object
libs support.

The starting point of $(obj) is passed in as argument of unnest-vars, as
well as nested variables, so that different Makefiles can pass in a
right value.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:12:54 +01:00
Fam Zheng
10f5bff622 util: Split out exec_dir from os_find_datadir
With this change, main() calls qemu_init_exec_dir and uses argv[0] to
init exec_dir. The saved value can be retrieved with
qemu_get_exec_dir later. It will be reused by module loading.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-20 13:12:54 +01:00
Peter Maydell
4c0c9bbe78 Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging
* remotes/qmp-unstable/queue/qmp:
  monitor: Add object_add class argument completion.
  monitor: Add object_del id argument completion.
  monitor: Add device_add device argument completion.
  monitor: Add device_del id argument completion.
  qmp: expose list of supported character device backends
  Use error_is_set() only when necessary
  QMP: allow JSON dict arguments in qmp-shell
  hmp: migrate command (without -d) now blocks correctly

Conflicts:
	blockdev.c

[PMM: resolved trivial conflict in blockdev.c]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 12:10:23 +00:00
Janne Grunau
2ea5a2ca1f linux-user: AArch64: Fix exclusive store of the zero register
Signed-off-by: Janne Grunau <j@jannau.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 10:35:56 +00:00
Peter Maydell
60510aed69 target-arm: A64: Implement unprivileged load/store
Implement the unprivileged load and store instructions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:56 +00:00
Peter Maydell
e4b998d47d target-arm: A64: Implement narrowing three-reg-diff operations
Implement the narrowing three-reg-diff operations: ADDHN,
RADDHN, SUBHN and RSUBHN.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:56 +00:00
Peter Maydell
dfc15c7ceb target-arm: A64: Implement the wide 3-reg-different operations
Implement the wide three-reg-different operations:
SADDW, UADDW, SSUBW and USUBW.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:56 +00:00
Peter Maydell
70d7f984a0 target-arm: A64: Add most remaining three-reg-diff widening ops
Add the remainder of the 64x64->128 operations in the three-reg-diff
category except for PMULL, PMULL2.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:55 +00:00
Peter Maydell
13caf1fd2b target-arm: A64: Add opcode comments to disas_simd_three_reg_diff
The opcode switch in disas_simd_three_reg_diff() is missing the
customary comments indicating which cases correspond to which
instructions. Add them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:55 +00:00
Peter Maydell
d324b36ad9 target-arm: A64: Implement store-exclusive for system mode
System mode store-exclusive use a different code path to usermode ones;
implement this missing code, in a similar way to the 32 bit version.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:55 +00:00
Peter Maydell
7900e9f1f9 target-arm: Fix incorrect type for value argument to write_raw_cp_reg
The write_raw_cp_reg's value argument should be a uint64_t, since
that's what all its callers hand it and what all the functions it
calls take. A (harmless) typo meant we were accidentally declaring
it as int64_t.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:54 +00:00
Peter Maydell
59a1c327d7 target-arm: Remove failure status return from read/write_raw_cp_reg
The read_raw_cp_reg and write_raw_cp_reg functions can now never
fail (in fact they should never have failed previously unless
there was a bug in a reginfo that meant no raw accessor was
provided for a might-trap register). This allows us to clean up
their prototypes so the write function returns void and the
read function returns the value read, which in turn lets us
simplify the callers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:54 +00:00
Peter Maydell
ea4571eb87 target-arm: Remove unnecessary code now read/write fns can't fail
Now that cpreg read and write functions can't fail and throw an
exception, we can remove the code from the translator that synchronises
the guest PC in case an exception is thrown.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 10:35:54 +00:00
Peter Maydell
c4241c7d38 target-arm: Drop success/fail return from cpreg read and write functions
All cpreg read and write functions now return 0, so we can clean up
their prototypes:
 * write functions return void
 * read functions return the value rather than taking a pointer
   to write the value to

This is a fairly mechanical change which makes only the bare
minimum set of changes to the callers of read and write functions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:54 +00:00
Peter Maydell
92611c0019 target-arm: Convert miscellaneous reginfo structs to accessfn
Convert the remaining miscellaneous cases of reginfo read/write
functions returning EXCP_UDEF to use an accessfn instead:
TEEHBR, and the ATS address-translation operations.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 10:35:53 +00:00
Peter Maydell
00108f2d4d target-arm: Convert generic timer reginfo to accessfn
Convert the reginfo structs for the generic timer registers
to use access functions rather than returning EXCP_UDEF from
their read handlers. In some cases this allows us to remove
a read handler completely.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:53 +00:00
Peter Maydell
fcd252062a target-arm: Convert performance monitor reginfo to accessfn
Convert the performance monitor reginfo definitions to use
an accessfn rather than returning EXCP_UDEF from read and
write functions. This also allows us to fix a couple of XXX
cases where we weren't imposing the access restrictions on
RAZ/WI or constant registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 10:35:52 +00:00
Peter Maydell
f59df3f235 target-arm: Split cpreg access checks out from read/write functions
Several of the system registers handled via the ARMCPRegInfo
mechanism have access trap control bits controlling whether the
registers are accessible to lower privilege levels. Replace
the existing mechanism (allowing the read and write functions
to return EXCP_UDEF if access is denied) with a dedicated
"check access rights" function pointer in the ARMCPRegInfo.
This will allow us to simplify some of the register definitions,
which no longer need read/write functions purely to handle
the access checks.

We take the opportunity to define the return value from the
access checking function in a way that allows us to set the
correct exception syndrome information for exceptions taken
to AArch64 (which may need to distinguish access failures due
to a configurable trap or enable from other kinds of access
failure).

This commit defines the new mechanism but does not move any
of the registers across to use it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:52 +00:00
Peter Maydell
e508a92b62 target-arm: Stop underdecoding ARM946 PRBS registers
The ARM946 has 8 PRBS (protection region base and size) registers.
Currently we implement these with a CP_ANY reginfo; however this
underdecodes (since there are 16 possible values of CRm but only
8 registers) and we catch the invalid values in the read and
write functions. However this causes issues with migration since
we only migrate the first of a wildcard register set, so we only
migrate c6_region[0]. It also makes it awkward to pull reginfo
access checks out into their own function.

Avoid all these problems by just defining separate reginfo structs
for each of the 8 registers; this also lets us avoid having any
read or write functions and will result in more efficient direct
field accesses from generated code.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 10:35:52 +00:00
Peter Maydell
626187d86b target-arm: Log bad system register accesses with LOG_UNIMP
Log guest attempts to access unimplemented system registers via
the LOG_UNIMP reporting mechanism (for both the 32 bit and 64 bit
instruction sets). This is particularly useful for debugging
problems where the guest is trying to use a system register that
QEMU doesn't implement.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:52 +00:00
Peter Maydell
1456364ff0 target-arm: Remove unused ARMCPUState sr substruct
Remove the 'struct sr' from ARMCPUState -- it isn't actually used and is
a hangover from the original separate system register implementation used
by the SuSE linux-user-mode-only AArch64 target.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:51 +00:00
Peter Maydell
99f678a679 target-arm: Restrict check_ap() use of S and R bits to v6 and earlier
The SCTLR bits S and R (8 and 9) only exist in ARMv6 and earlier.
In ARMv7 these bits RAZ, and in ARMv8 they are reassigned. Guard
the use of them in check_ap() so that we don't get incorrect results
for ARMv8 CPUs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
2014-02-20 10:35:51 +00:00
Peter Maydell
76e3e1bcae target-arm: Define names for SCTLR bits
The SCTLR is full of bits for enabling or disabling various things, and so
there are many places in the code which check if certain bits are set.
Define some named constants for the SCTLR bits so these checks are easier
to read.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 10:35:51 +00:00
Peter Maydell
83e9a4aec9 target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs
Extend the set of CPUs for which we provide a QEMU_KVM_ARM_TARGET_*
constant to include all the ones currently supported by the kernel
headers we are using.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-20 10:35:50 +00:00
Peter Maydell
057d5f62f8 target-arm: A64: Implement remaining 3-same instructions
Implement the remaining instructions in the SIMD 3-reg-same
and scalar-3-reg-same groups: FMULX, FRECPS, FRSQRTS, FACGE,
FACGT, FMLA and FMLS.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:50 +00:00
Peter Maydell
67d43538ae softfloat: Support halving the result of muladd operation
The ARMv8 instruction set includes a fused floating point
reciprocal square root step instruction which demands an
"(x * y + z) / 2" fused operation. Support this by adding
a flag to the softfloat muladd operations which requests
that the result is halved before rounding.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:50 +00:00
Alex Bennée
bc242f9bb6 target-arm: A64: Implement floating point pairwise insns
Add support for the floating-point pairwise operations
FADDP, FMAXP, FMAXNMP, FMINP and FMINNMP. To do this we use the
code which was previously handling only integer pairwise operations,
and push the integer-specific decode and handling of unallocated
cases up one level in the call tree, so we can also call it from
the floating-point section of the decoder.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:50 +00:00
Alex Bennée
8908f4d185 target-arm: A64: Implement SIMD FP compare and set insns
This adds all forms of the SIMD floating point and set instructions:

  FCM(GT|GE|EQ|LE|LT)

Most of the heavy lifting is done by either the existing neon helpers or
some new helpers for the 64bit double cases. Most of the code paths are
common although the 2misc versions are a little special as they compare
against zero.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
[PMM: fixed some minor bugs, added the 2-misc-scalar encoding]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:49 +00:00
Peter Maydell
b033cd3d00 target-arm: A64: Implement scalar three different instructions
Implement the scalar three different instruction group:
it only has three instructions in it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:49 +00:00
Peter Maydell
9f82e0ff4b target-arm: A64: Implement SIMD scalar indexed instructions
Implement the SIMD scalar indexed instructions. The encoding
here is nearly identical to the vector indexed grouping, so
we combine the two.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:49 +00:00
Peter Maydell
c44ad1fddc target-arm: A64: Implement long vector x indexed insns
Implement the 'long' operations in the vector x indexed
element category.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:49 +00:00
Peter Maydell
f5e51e7f10 target-arm: A64: Implement plain vector SIMD indexed element insns
Implement all the SIMD vector x indexed element instructions
in the subcategory which are not 'long' ops.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-20 10:35:48 +00:00
Peter Maydell
873169022a hw/intc/arm_gic: Fix NVIC assertion failure
Commit 40d225009e accidentally changed the behaviour of
gic_acknowledge_irq() for the NVIC. The NVIC doesn't have SGIs,
so this meant we hit an assertion:
  gic_acknowledge_irq: Assertion `s->sgi_pending[irq][cpu] != 0' failed.

Return NVIC acknowledge-irq to its previous behaviour, like 11MPCore.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
2014-02-20 10:35:48 +00:00
Kevin Wolf
6d093a4f49 target-i386: Fix I/O bitmap checks for in/out
Commit 1b90d56e changed the implementation of in/out imm to not assign
the accessed port number to cpu_T[0] as it appeared unnecessary.
However, currently gen_check_io() makes use of cpu_T[0] to implement the
I/O bitmap checks, so it's in fact still used and the change broke the
check, leading to #GP in legitimate cases (and probably also allowing
access to ports that shouldn't be allowed).

This patch reintroduces the missing assignment for these cases.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-19 16:40:19 +01:00
Stefan Hajnoczi
b15d422a23 qtest: kill QEMU process on g_assert() failure
The QEMU process stays running if the test case fails.  This patch fixes
the leak by installing a SIGABRT signal handler which invokes
qtest_end().

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-19 15:45:51 +01:00
Stefan Hajnoczi
cef60c925c qtest: make QEMU our direct child process
qtest_init() cannot use exec*p() to launch QEMU since the exec*p()
functions take an argument array while qtest_init() takes char
*extra_args.  Therefore we execute /bin/sh -c <command-line> and let the
shell parse the argument string.

This left /bin/sh as our child process and our child's child was QEMU.
We still want QEMU's pid so the -pidfile option was used to let QEMU
report its pid.

The pidfile needs to be unlinked when the test case exits or fails.  In
other words, the pidfile creates a new problem for us!

Simplify all this using the shell 'exec' command.  It allows us to
replace the /bin/sh process with QEMU.  Then we no longer need to use
-pidfile because we already know our fork child's pid.

Note: Yes, it seems silly to exec /bin/sh when we could just exec QEMU
directly.  But remember qtest_init() takes a single char *extra_args
command-line fragment instead of a real argv[] array, so we need
/bin/sh's argument parsing behavior.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
2014-02-19 15:44:34 +01:00
Stefan Hajnoczi
98f9e35bef qtest: drop unused child_pid field
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
2014-02-19 15:43:54 +01:00
Peter Maydell
69d4c703a5 linux-user: Fix error handling in target_to_host_semarray()
Fix two issues in error handling in target_to_host_semarray():
 * don't leak the host_array buffer if lock_user fails
 * return an error if malloc() fails

v2: added missing * -Riku Voipio

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-02-19 12:29:23 +02:00
Andreas Färber
fff8c539bd linux-user: Implement BLKPG ioctl
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-02-19 12:29:23 +02:00
Kevin Wolf
94783de6fe trace-events: Fix typo in "offset"
s/offet/offset/

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-19 11:14:08 +01:00
Mohamad Gebai
5d59fd998f Add ust generated files to .gitignore
Signed-off-by: Mohamad Gebai <mohamad.gebai@polymtl.ca>
Reviewed-by: Alex Bennée <alex@bennee.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-19 11:09:35 +01:00
Mohamad Gebai
ef3ef4a040 Update documentation for LTTng ust tracing
Signed-off-by: Mohamad Gebai <mohamad.gebai@polymtl.ca>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-19 11:08:54 +01:00
Mohamad Gebai
e6bf23f82d Adapt Makefiles to the new LTTng ust interface
Add generation of new files for LTTng ust.

Signed-off-by: Mohamad Gebai <mohamad.gebai@polymtl.ca>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-19 11:08:53 +01:00
Mohamad Gebai
9530570fa5 Modified the tracetool framework for LTTng 2.x
* A new format is required to generate definitions for ust tracepoints.
  Files ust_events_h.py and ust_events_c.py define common macros, while
  new function ust_events_h in events.py does the actual definition of
  each tracepoint.
* ust.py generates the new interface for calling userspace tracepoints
  with LTTng 2.x, replacing trace_name(args) to tracepoint(name, args).
* As explained in ust_events_c.py, -Wredundant-decls gives a warning
  when compiling with gcc 4.7 or older. This is specific to lttng-ust so
  for now use a pragma clause to avoid getting a warning.

Signed-off-by: Mohamad Gebai <mohamad.gebai@polymtl.ca>
Reviewed-by: Alex Bennée <alex@bennee.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-19 11:08:53 +01:00
Mohamad Gebai
bf15f63cad Fix configure script for LTTng 2.x
Signed-off-by: Mohamad Gebai <mohamad.gebai@polymtl.ca>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-19 11:08:53 +01:00
Peter Maydell
501bb4b0cb linux-user: Fix error handling in lock_iovec()
In lock_iovec() if lock_user() failed we were doing an unlock_user
but not a free(vec), which is the wrong way round. We were also
assuming that free() and unlock_user() don't touch errno, which
is not guaranteed. Fix both these problems.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-02-18 16:54:06 +02:00
Peter Maydell
3a5d30bf27 linux-user/signal.c: Don't pass sigaction uninitialised sa_flags
When forcing a fatal signal, we weren't initialising the sa_flags
field in the struct sigaction we used to reset the signal handler
to SIG_DFL.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-02-18 16:54:06 +02:00
Peter Maydell
6afafa86f3 linux-user/elfload.c: Avoid calling g_free() on uninitialized data
Avoid calling g_free() on unintialized data in the error-handling
paths in elf_core_dump() by splitting the initialization of the
elf_note_info struct out of fill_note_info() so that it's always
valid to call free_note_info() whether we got to the point of
being able to fill_note_info() or not.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-02-18 16:54:06 +02:00
Riku Voipio
4fc4732047 linux-user: sync syscall numbers upto 3.13
All others updated except unicore, which doesn't look right to
begin with.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-02-18 16:45:55 +02:00
Gerd Hoffmann
d6bb65fcd2 xhci: use DPRINTF() instead of fprintf(stderr, ...)
So we don't spam stderr with (guest-triggerable) messages by default.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-18 15:39:13 +01:00
Gerd Hoffmann
4f9cc73422 xhci: switch debug printf to tracepoint
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-18 15:39:13 +01:00
Gerd Hoffmann
cc03ff9d0a xhci iso: allow for some latency
Allow the scheduled transfer time be a bit behind, to
compensate for latencies.  Without this xhci will wait
way to often for the mfindex wraparound, assuming the
scheduled time is in the future just because qemu is
a bit behind in processing the iso transfer requests.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-18 15:39:13 +01:00
Gerd Hoffmann
786ad214c7 xhci iso: fix time calculation
Frameid specifies frames not microframes, so we
need to shift it to get the microframe index.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-18 15:39:13 +01:00
Gerd Hoffmann
c348e48175 uhci: invalidate queue on device address changes
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-18 15:39:13 +01:00
Gerd Hoffmann
f6969b9fef xhci: fix overflow in usb_xhci_post_load
Found by Coverity.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-18 15:39:12 +01:00
Pantelis Koukousoulas
bd93976a1a usb: Remove magic constants from device bmAttributes
Replace magic constants in device bmAttributes with symbolic ones
from Linux kernel ch9.h

Signed-off-by: Pantelis Koukousoulas <pktoss@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-18 15:39:12 +01:00
Stefan Hajnoczi
91f32b0c92 qtest: Include system headers before user headers
It is dangerous to include user headers before system headers since user
macros can affect system headers.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-17 23:10:02 +01:00
Hani Benhabiles
1094fd3a62 monitor: Add object_add class argument completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:23 -05:00
Hani Benhabiles
b48fa074b5 monitor: Add object_del id argument completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:23 -05:00
Hani Benhabiles
992d3e64c8 monitor: Add device_add device argument completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:23 -05:00
Hani Benhabiles
fca72d9b49 monitor: Add device_del id argument completion.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:23 -05:00
Martin Kletzander
77d1c3c63f qmp: expose list of supported character device backends
Introduce 'query-chardev-backends' QMP command which lists all
supported character device backends.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:23 -05:00
Markus Armbruster
84d18f065f Use error_is_set() only when necessary
error_is_set(&var) is the same as var != NULL, but it takes
whole-program analysis to figure that out.  Unnecessarily hard for
optimizers, static checkers, and human readers.  Dumb it down to
obvious.

Gets rid of several dozen Coverity false positives.

Note that the obvious form is already used in many places.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:23 -05:00
Stefan Hajnoczi
ff9ec34de8 QMP: allow JSON dict arguments in qmp-shell
qmp-shell hides the QMP wire protocol JSON encoding from the user.  Most
of the time this is helpful and makes the command-line human-friendly.

Some QMP commands take a dict as an argument.  In order to express this
we need to revert back to JSON notation.

This patch allows JSON dict arguments in qmp-shell so commands like
blockdev-add and nbd-server-start can be invoked:

  (QEMU) blockdev-add options={"driver":"file","id":"drive1",...}

Note that spaces are not allowed since str.split() is used to break up
the command-line arguments first.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:23 -05:00
Soramichi AKIYAMA
dde3a21840 hmp: migrate command (without -d) now blocks correctly
This patch fixes a timing issue that migrate command (without -d) does not
block in some cases.

The original version of hmp.c:hmp_migrate_status_cb checks if the
migration status is 'active' or not to detect the completion of a migration.

However, if this function is executed when the migration status is stil
'setup' (the status before 'active'), migration command returns
immediately even if the user does not specify -d option.

Signed-off-by: Soramichi Akiyama <akiyama@nii.ac.jp>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-02-17 11:57:22 -05:00
Richard Henderson
6399ab3325 tcg/i386: Use SHLX/SHRX/SARX instructions
These three-operand shift instructions do not require the shift count
to be placed into ECX.  This reduces the number of mov insns required,
with the mere addition of a new register constraint.

Don't attempt to get rid of the matching constraint, as that's impossible
to manipulate with just a new constraint.  In addition, constant shifts
still need the matching constraint.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
9d2eec202f tcg/i386: Use ANDN instruction
Note that the optimizer cannot simplify ANDC X,Y,C to AND X,Y,~C
so we must handle constants in the implementation of andc.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
ecc7e84327 tcg/i386: Add tcg_out_vex_modrm
Prepare for emitting BMI insns which require VEX encoding.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
a1b29c9ae0 tcg/i386: Move TCG_CT_CONST_* to tcg-target.c
These are not needed by users of tcg-target.h.  No need to recompile
when we adjust them.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
189f792dc5 disas/i386: Disassemble ANDN/SHLX/SHRX/SHAX
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
464a1441c1 tcg/optimize: Add more identity simplifications
Recognize 0 operand to andc, and -1 operands to and, orc, eqv.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
e64e958e20 tcg/optimize: Optmize ANDC X,Y,Y to MOV X,0
Like we already do for SUB and XOR.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
e201b56418 tcg/optimize: Simply some logical ops to NOT
Given, of course, an appropriate constant.  These could be generated
from the "canonical" operation for inversion on the guest, or via
other optimizations.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Richard Henderson
23ec69ed37 tcg/optimize: Handle known-zeros masks for ANDC
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:29 -06:00
Aurelien Jarno
c8d7027253 tcg/optimize: add known-zero bits compute for load ops
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:28 -06:00
Aurelien Jarno
f096dc9618 tcg/optimize: improve known-zero bits for 32-bit ops
The shl_i32 op might set some bits of the unused 32 high bits of the
mask. Fix that by clearing the unused 32 high bits for all 32-bit ops
except load/store which operate on tl values.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:28 -06:00
Aurelien Jarno
3031244b01 tcg/optimize: fix known-zero bits optimization
Known-zero bits optimization is a great idea that helps to generate more
optimized code. However the current implementation only works in very few
cases as the computed mask is not saved.

Fix this to make it really working.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:28 -06:00
Aurelien Jarno
e46b225a31 tcg/optimize: fix known-zero bits for right shift ops
32-bit versions of sar and shr ops should not propagate known-zero bits
from the unused 32 high bits. For sar it could even lead to wrong code
being generated.

Cc: qemu-stable@nongnu.org
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:28 -06:00
Huw Davies
7a3a00979d tcg-arm: The shift count of op_rotl_i32 is in args[2] not args[1].
It's this that should be subtracted from 0x20 when converting to a right rotate.

Cc: qemu-stable@nongnu.org
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-17 10:12:08 -06:00
Brad
46eef33b89 Fix QEMU build on OpenBSD on x86 archs
This resolves the build issue with building the ROMs on OpenBSD on x86 archs.
As of OpenBSD 5.3 the compiler builds PIE binaries by default and thus the
whole OS/packages and so forth. The ROMs need to have PIE disabled.
Check in configure whether the compiler supports the flags for disabling
PIE, and if it does then use them for building the ROMs. This fixes the
following buildbot failure:

>From the OpenBSD buildbots..
  Building optionrom/multiboot.img
ld: multiboot.o: relocation R_X86_64_16 can not be used when making a shared object; recompile with -fPIC

Signed-off by: Brad Smith <brad@comstyle.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-17 11:44:00 +00:00
Richard Henderson
f6aa2f7dee TCG: Fix 32-bit host allocation typo
The second half register of a 64-bit temp on a 32-bit host
was allocated with the wrong base_type.

The base_type of the second half register is never checked,
but for consistency it should be the same as the first half.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-02-15 15:20:17 -08:00
Michael Tokarev
0dbcf95a1e libvixl: fix 64bit constants usage
Since commit 999b53ec87:
 Author: Claudio Fontana <claudio.fontana@linaro.org>
 Date:   Wed Feb 5 17:27:28 2014 +0000

    disas: Implement disassembly output for A64

    Use libvixl to implement disassembly output in debug
    logs for A64, for use with both AArch64 hosts and targets.

disas/libvixl/ contains functions which uses 64bit constants
without using appropriate suffixes, which fails on 32bits.

Fix this by using ULL suffix.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-15 20:26:30 +00:00
Peter Maydell
078a1c37ca Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-2014-02-15' into staging
trivial patches for 2014-02-15

# gpg: Signature made Sat 15 Feb 2014 12:10:46 GMT using RSA key ID 74F0C838
# gpg: Good signature from "Michael Tokarev <mjt@tls.msk.ru>"
# gpg:                 aka "Michael Tokarev <mjt@corpit.ru>"
# gpg:                 aka "Michael Tokarev <mjt@debian.org>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 8044 65C5
#      Subkey fingerprint: E190 8639 3B10 B51B AC2C  8B73 5253 C5AD 74F0 C838

* remotes/mjt/tags/trivial-patches-2014-02-15:
  char/serial: Fix emptyness check
  gitignore: anchor all ignored names
  vl: trim includes
  vl: remove old, long-unused defines
  net: declare struct iovec in checksum.h to fix compiler warning
  linux-user: refactor do_socketcall()
  configure: add hints to a remedy for feature_not_found errors
  configure: add hint of libfdt to DTC dependency not found message
  sparc/leon3: Initialize stack pointer
  misc: Fix case Qemu -> QEMU

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-15 16:36:40 +00:00
Peter Maydell
44e3a39f30 Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request

# gpg: Signature made Fri 14 Feb 2014 17:26:30 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/block-pull-request:
  block: Open by reference will try device then node_name.
  block: Relax bdrv_lookup_bs constraints.
  blockdev: Fix wrong usage of QDECREF causing snapshoted quorum to crash on close.
  block: mirror - use local_err to avoid NULL errp
  qemu-iotests: Don't run 005 on vmdk split formats
  block: qemu-iotests - add vhdx log replay tests for qemu-img
  block: qemu-iotests - fix test 070 (vhdx)
  block: Don't throw away errno via error_setg
  block: Add notes to iSCSI's .bdrv_open and .bdrv_reopen_prepare
  blockdev: Remove 'type' parameter from blockdev_init()
  sdhci: Drop unnecessary #include

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-15 16:15:52 +00:00
Peter Maydell
90ce3d76eb Merge remote-tracking branch 'remotes/jliu/or32-ld-st' into staging
* remotes/jliu/or32-ld-st:
  target-openrisc: Use new qemu_ld/st opcodes

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-15 15:20:08 +00:00
Peter Maydell
a50f98b066 Merge remote-tracking branch 'remotes/jovanovic/mips-ufrp' into staging
* remotes/jovanovic/mips-ufrp:
  target-mips: add user-mode FR switch support for MIPS32r5
  target-mips: add support for CP0_Config5
  target-mips: add support for CP0_Config4
  target-mips: add CPU definition for MIPS32R5

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-15 15:07:00 +00:00
Peter Crosthwaite
88c1ee73d3 char/serial: Fix emptyness check
This was guarding against a full fifo rather than an empty fifo when
popping. Fix.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Michael Tokarev
5556332aba gitignore: anchor all ignored names
by default, patterns/names in .gitignore are applied
recursively to all subdirectories.  So any name mentioned
in .gitignore is ignored in all subdirectores.  This is good
for, say. object files (*.o), but not good for particular
names which should be ignored only in one directory.  For
example, qemu-img.1 file is generated in the top directory,
and it should be ignored only there, not in some subdir.

At first, this might not matter much, but we have lots of
examples already where it actually does not help at all.
For example, top-level .gitignore ignores a file/dir named
"patches" (which is very questionable by itself), but it
is applied recursively, so git also ignores, for example,
debian/patches/ which should not be ignored.

So anchor all the names where appropriate.  .gitignore
should be cleaned up further, which will be addressed in
a subsequent patch.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Michael Tokarev
b33276a7a8 vl: trim includes
Over time, lots of stuff moved from vl.c into separate
files.  But include statements has never been cleaned,
and they continue to carry lots of anymore-unused stuff.

Remove includes which are not relevant for vl.c anymore.
Apparently there are more includes like this, because
many are included from qemu-common.h and the like, or,
for example, I don't see were we use win32-specific
stuff in vl.c (so that maybe #include <windows.h> might
be removed too).

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Michael Tokarev
24c84e687e vl: remove old, long-unused defines
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Michael Tokarev
262471794d net: declare struct iovec in checksum.h to fix compiler warning
The checksum calculation header exports a function that refers to
struct iov defined in iov.h.  Without including the former, build
fails like this:

  In file included from hw/net/fsl_etsec/rings.c:24:0:
  include/net/checksum.h:51:31: error: ‘struct iovec’ declared inside parameter list [-Werror]
  include/net/checksum.h:51:31: error: its scope is only this definition or declaration, which is probably not what you want [-Werror]

Mention struct iovec there.

Reported-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Michael Tokarev
62dc90c668 linux-user: refactor do_socketcall()
Refactor do_socketcall() to do argument conversion/checking first,
according to a lookup table (which call has how many args) and
by calling the right function second with ready-to-go arguments.

This ensures that all arguments are handled as abi_long, according
to socketcall prototype, and simplifies argument handling alot too.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-15 16:10:25 +04:00
Stewart Smith
21684af023 configure: add hints to a remedy for feature_not_found errors
Modify feature_not_found to accept an optional second parameter to be
printed after the generic feature not found error.

Modify most calls to feature_not_found to provide hints as to the
packages that may be missing. The few calls remaining without a remedy
are ones I couldn't work out how to remedy myself.

Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Stewart Smith
3f281822b2 configure: add hint of libfdt to DTC dependency not found message
Most distros package it as libfdt, and mentioning libfdt here makes it
much easier to find the package you're missing.

Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Sebastian Huber
c1570e2a1f sparc/leon3: Initialize stack pointer
A lot of real world LEON3 systems are shipped with the GRMON boot
loader.  This boot loader initializes the stack pointer with the end of
RAM address.  The application can use this to detect the RAM size of a
particular board variant.

Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
Reviewed-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Stefan Weil
a63e5e0c0d misc: Fix case Qemu -> QEMU
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-15 16:10:25 +04:00
Paolo Bonzini
e41b509d68 qapi: Refine human printing of sizes
This fixes several bugs or shortcomings of the previous pretty-printer.
In particular:

* use PRIu64 instead of casting to long long

* the exact value is included too

* the correct unit of measure (MiB, GiB, etc.) is used.  PiB and EiB
are added too.

* due to an off-by-one error, 512*2^30 was printed as 0.500MiB rather than
512MiB.  floor(log2(val)) is equal to 63 - clz(val), while the code used 64.

* The desired specification is %g rather than %f, which always uses three
decimals in the current code.  However %g would switch to scientific
notation when the integer part is >= 1000 (e.g. 1000*2^30).  To keep the
code simple, switch to the higher power when the integer part is >= 1000;
overflow is avoided by using frexp instead of clz.

Suggested-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:05 +01:00
Paolo Bonzini
85ca1202d1 qdev: Use QAPI type names for properties
Use "drive", "chr", etc. only for legacy_name (which shows up
in -device foo,? output).

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:05 +01:00
Paolo Bonzini
104059da54 qdev: Add enum property types to QAPI schema
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:05 +01:00
Paolo Bonzini
f31c41ff5e block: Handle "rechs" and "large" translation options
Sure, CHS translation is an obscure topic, and legacy options for
hard-disk geometries are obscure as well.  But since QEMU does nothing
with it except telling the BIOS, and since there "large" and "rechs"
are listed in the enums, parsing them seems to be the bare minimum.

Acked-by: Stefan Hajnoczi <stefanha@gmail.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:04 +01:00
Paolo Bonzini
c7bcc85d66 qdev: Remove hex8/32/64 property types
Replace them with uint8/32/64.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:04 +01:00
Paolo Bonzini
515f23462b qdev: Remove most legacy printers
Their functionality is either aesthetic only (e.g. on/off vs. true/false)
or obtained by the "human mode" of StringOutputVisitor.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:03 +01:00
Paolo Bonzini
dae3bda422 qdev: Use human mode in "info qtree"
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:03 +01:00
Paolo Bonzini
0b7593e085 qapi: Add human mode to StringOutputVisitor
This will be used by "info qtree".  For numbers it prints both the
decimal and hex values.  For sizes it rounds to the nearest power
of 2^10.  For strings, it puts quotes around the string and separates
NULL and empty string.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:03 +01:00
Paolo Bonzini
98a6528461 qdev: Inline qdev_prop_parse()
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:02 +01:00
Paolo Bonzini
7ce7ffe027 qdev: Legacy properties are just strings
prop->info->legacy_name is still used by "-device foo,?".

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:02 +01:00
Paolo Bonzini
03ff777048 qdev: Legacy properties are now read-only
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:02 +01:00
Paolo Bonzini
9e4d9620c4 qdev: Remove legacy parsers for hex8/32/64
The hexNN property types have not been accepting values not prefixed
by "0x" since QEMU 1.2.  Parse those values as decimals now.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:02 +01:00
Paolo Bonzini
7d9268647c qdev: Sizes are now parsed by StringInputVisitor
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:02 +01:00
Paolo Bonzini
a5829ccfc3 qapi: Add size parser to StringInputVisitor
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:01 +01:00
Fam Zheng
23802b4fe0 qtest: Don't segfault with invalid -qtest option
This prints an error message, instead of core dump, when "-qtest"
option value is invalid, e.g.:

    $ ./x86_64-softmmu/qemu-system-x86_64 -qtest unknown
        qemu-system-x86_64: Failed to initialize device for qtest:
        "unknown"

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:12:01 +01:00
Andreas Färber
1f9c4cfda4 ipack: Move IndustryPack out of hw/char/
Move the header defining an IPackBus and IPackDevice base class into
a new include/ directory and move their implementation and a
PCI-IndustryPack bridge out of hw/char/ directory into a new hw/ipack/.

Acked-by: Alberto Garcia <agarcia@igalia.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:11:53 +01:00
Andreas Färber
08c9cacf0e ipoctal232: QOM parent field cleanup
Clean up accesses to IPOctalState::dev field and rename it.

Acked-by: Alberto Garcia <agarcia@igalia.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:07:20 +01:00
Andreas Färber
227d327252 ipack: QOM parent field cleanup for IPackDevice
Rename the IPackDevice::qdev field to avoid accidental use.

Acked-by: Alberto Garcia <agarcia@igalia.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:07:20 +01:00
Andreas Färber
a21ac343d1 ipack: QOM parent field cleanup for IPackBus
Clean up the only user of IPackBus::qbus field and rename it.

Acked-by: Alberto Garcia <agarcia@igalia.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:07:20 +01:00
Andreas Färber
5c57090255 ipack: Convert to QOM realize
Acked-by: Alberto Garcia <agarcia@igalia.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:07:20 +01:00
Andreas Färber
371468297c tests: Add ipoctal232 qtest
Acked-by: Alberto Garcia <agarcia@igalia.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:07:13 +01:00
Andreas Färber
76491071b3 tests: Add tpci200 qtest
Acked-by: Alberto Garcia <agarcia@igalia.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:02:27 +01:00
Andreas Färber
b815ec5eea tests: Add virtio-net qtest
Cc: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 21:01:03 +01:00
Andreas Färber
5297ea6fb8 tests: Add ne2000 qtest
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 20:50:19 +01:00
Benoît Canet
0c5e94ee83 block: Open by reference will try device then node_name.
Since we introduced node_name for named bs of the graph modify the opening by
reference to use it as a fallback.

This patch also enforce the separation of the device id and graph node
namespaces.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:39 +01:00
Benoît Canet
dd67fa5052 block: Relax bdrv_lookup_bs constraints.
The following patch will reuse bdrv_lookup_bs in order to open images by
references so the rules of usage of bdrv_lookup_bs must be relaxed a bit.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:39 +01:00
Benoît Canet
57b6bdf37c blockdev: Fix wrong usage of QDECREF causing snapshoted quorum to crash on close.
As bdrv_open() documentation states:
"The reference to the QDict belongs to the block layer
 * after the call (even on failure), so if the caller intends to reuse the
 * dictionary, it needs to use QINCREF() before calling bdrv_open."

the optional options dict will not be reused after bdrv_open() and should
belong to the block layer so remove the extra QDECREF(options).

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:39 +01:00
Jeff Cody
cc67f4d1f9 block: mirror - use local_err to avoid NULL errp
When starting a block job, commit_active_start() relies on whether *errp
is set by mirror_start_job.  This allows it to determine if the mirror
job start failed, so that it can clean up any changes to open flags from
the bdrv_reopen().  If errp is NULL, then it will not be able to
determine if mirror_start_job failed or not.

To avoid this, use a local Error variable, and then propagate the error
(if any) to errp.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:39 +01:00
Fam Zheng
2aa4a86f59 qemu-iotests: Don't run 005 on vmdk split formats
There would be too many extents that VMDK driver can't open all of them:

    005 0s ... - output mismatch (see 005.out.bad)
    --- 005.out     2013-12-24 09:27:27.608181030 +0800
    +++ 005.out.bad 2014-02-13 10:00:15.282184557 +0800
    @@ -4,10 +4,10 @@
     Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=5368709120000

     small read
    -read 4096/4096 bytes at offset 1024
    -4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
    +qemu-io: can't open device /tmp/qemu-iotests/t.vmdk: Could not open '/tmp/qemu-iotests/t-s1016.vmdk': Too many open files
    +no file open, try 'help open'

     small write
    -wrote 4096/4096 bytes at offset 8192
    -4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
    +qemu-io: can't open device /tmp/qemu-iotests/t.vmdk: Could not open '/tmp/qemu-iotests/t-s1016.vmdk': Too many open files
    +no file open, try 'help open'
     *** done

So disable the two subformats.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:39 +01:00
Jeff Cody
18968ca1a3 block: qemu-iotests - add vhdx log replay tests for qemu-img
VHDX logs can now be replayed via 'qemu-img check -r all'.  Add
tests to verify that the log replay is successful when using qemu-img.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:39 +01:00
Jeff Cody
e001807847 block: qemu-iotests - fix test 070 (vhdx)
VHDX test 070 failed, due to different output from qemu-io / qemu
when opening an image read-only that contains a log file.  Filter
the output, and update the expected results to match the correct
output.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:38 +01:00
Jeff Cody
39a611a3e0 block: Don't throw away errno via error_setg
There are a handful of places in the block layer where a failure path
has a valid -errno value, yet error_setg() is used.  Those instances
should instead use error_setg_errno(), to preserve as much error
information as possible.

This patch replaces those instances with error_setg_errno(), so that
errno is passed up the stack in the error message.

Reported-By: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 18:05:38 +01:00
Andreas Färber
92838a19c1 tests: Add eepro100 qtest
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:33 +01:00
Andreas Färber
85f68d552b tests: Add pcnet qtest
Test PCI only for now.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:33 +01:00
Andreas Färber
74769fe7c8 tests: Add rtl8139 qtest
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:33 +01:00
Andreas Färber
4a053e7f71 tests: Add vmxnet3 qtest
Note that this will emit a warning:
[vmxnet3][WR][vmxnet3_peer_has_vnet_hdr]: Peer has no virtio extension.
Task offloads will be emulated.

Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:33 +01:00
Andreas Färber
a21baf7999 tests: Add e1000 qtest
Cc: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:33 +01:00
Andreas Färber
9fe451a08e i2c: Drop FROM_I2C_SLAVE() macro
We now use type-specific QOM cast macros instead.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
dd37dfa9e7 twl92230: QOM'ify
Replace usages of FROM_I2C_SLAVE() and direct parent field accesses with
QOM cast macro. Rename parent field.

Add missing braces while at it.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
59ab56b9ad ds1338: QOM'ify
Replace usages of FROM_I2C_SLAVE() with QOM cast macro.
Rename parent field.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
933069eb53 lm832x: QOM'ify
Replace usages of FROM_I2C_SLAVE() and direct parent field accesses with
QOM cast macro. Rename parent field.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
b8bcf811bf max7310: QOM'ify
Replace FROM_I2C_SLAVE() usages with QOM cast macro.
Rename parent field.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
b1be45153e ssd0303: QOM'ify
Replace usages of FROM_I2C_SLAVE() with QOM cast macro.
Rename parent field.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
bc229b0f90 wm8750: QOM'ify
Replace usages of FROM_I2C_SLAVE() and direct parent field accesses with
QOM cast macro. Rename parent field.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
a5f96db7e8 z2: QOM'ify AER915
Replace usages of FROM_I2C_SLAVE() with QOM cast macro.
Rename the parent field. Reuse the type constant in z2_init().

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
[AF: Use TYPE_AER915 in z2_init() too]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
70b5169032 tosa: QOM'ify DAC
Replace usages of FROM_I2C_SLAVE() with QOM cast macro.
Rename parent field. Use type constant in tosa_tg_init().

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:32 +01:00
Andreas Färber
96dca6b9a9 pxa2xx: QOM'ify I2C slave
Replace usages of FROM_I2C_SLAVE() and direct parent field accesses with
QOM cast macro. Rename parent field to assure we caught all. Reuse type
constant in pxa2xx_i2c_init().

Add some missing braces while at it.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:31 +01:00
Andreas Färber
a5c828525e i2c: Rename i2c_bus to I2CBus
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:31 +01:00
Andreas Färber
6749695eaa nand: Don't use qdev_create() in nand_init()
Commit 7426aa72c3 (nand: Don't inherit
from Sysbus) changed the parent type of TYPE_NAND but continued to use
qdev_create(), which handled a NULL BusState as SysBus.

Use object_new() instead, and reuse the TYPE_NAND define while at it.

Reported-by: Markus Armbruster <armbru@redhat.com>
Cc: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:31 +01:00
Peter Maydell
3687d53259 tests: Run qom-test for every architecture
Rather than requiring every new architecture to remember to add a line
to the Makefile to say that qom-test will work on it, autogenerate
the list of supported architectures by looking at the files in
default-configs (as configure does), and add qom-test to the
test list for all of them automatically.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:22:27 +01:00
Markus Armbruster
bb6c5e3c3a qom-test: Test shutdown in addition to startup
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:21:08 +01:00
Markus Armbruster
5c1904f103 qom-test: Run for all available machines
Get available machines via QMP instead of hardcoding a list that's
perpetually out of date.

Xen machines can work only when running under the Xen hypervisor.
Blacklist them.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:21:08 +01:00
Andreas Färber
5ec889b4b1 tests: Fix gcov paths for relocated device sources
Commit 49ab747f66 moved
fdc.c, hd-geometry.c, m48t59.c, tmp105.c into hw/ subdirectories;
commit 0ddfaf7fe4 did for mc146818rtc.c.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-14 16:21:03 +01:00
Jeff Cody
28f106afb3 block: Add notes to iSCSI's .bdrv_open and .bdrv_reopen_prepare
iSCSI currently does not need to do any actions to support the
current usage of bdrv_reopen().  However, it is important to note
a couple of things: 1.) A connection will not be re-established to
an iSCSI target, and 2.) If iscsi_open() is changed to parse 'flags',
then iscsi_reopen_prepare() may need to be more than a stub.

In light of the above, this commit adds comments above both of the
functions to bring attention to these facts.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 13:38:35 +01:00
Kevin Wolf
ee13ed1cbc blockdev: Remove 'type' parameter from blockdev_init()
blockdev-add doesn't know about the device that the backend will be
attached to, this is a legacy -drive concept. Move the remaining checks
that use it to drive_init().

[Fam Zheng <famz@redhat.com> suggested line-wrapping to 80 chars as
required by the coding standard.  I have fixed this.
--Stefan]

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 13:04:56 +01:00
Kevin Wolf
1a838745b8 sdhci: Drop unnecessary #include
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-14 13:04:56 +01:00
Alexander Graf
933b19ea97 PPC: KVM: Add missing address space to ldl_phys helper
We now have to pass an address space to our _phys helpers. During the
transition apparently the EPR exit path missed out, so let's put it there.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-14 10:42:31 +00:00
Andreas Färber
292363e15c target-ppc: Make ppc40x CPUs available in ppcemb
Not only 44x CPUs (BookE) but also 40x CPUs can run with 1k page size.

Move the criteria to a central inline function to avoid repetition
and #ifdef'fery. Update qom-test to no longer exempt them.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-13 17:47:43 +01:00
Andreas Färber
aaab89a68e ppcemb-softmmu: Drop Mac and e500 emulation
They are still available in ppc-softmmu and ppc64-softmmu.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-13 17:47:43 +01:00
Michael S. Tsirkin
b3be57c358 qtest: don't report signals if qtest driver enabled
qtest driver always uses signals to kill qemu
no need to report it, whatever the accelerator state.

Add API to detect qtest driver, and suppress reporting
signals in this case.

Reported-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2014-02-13 17:47:43 +01:00
Peter Maydell
0888a29caa Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
acpi,pc,pci fixes and enhancements

Most changes here are hotplug related:

This merges hotplug infrastructure changes by Igor,
some acpi related fixes, and PC fixes.

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

# gpg: Signature made Mon 10 Feb 2014 09:13:26 GMT using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  ACPI: Remove commented-out code from HPET._CRS
  hw/pci: switch to a generic hotplug handling for PCIDevice
  pci/pcie: convert PCIE hotplug to use hotplug-handler API
  pci/shpc: convert SHPC hotplug to use hotplug-handler API
  acpi/piix4pm: convert ACPI PCI hotplug to use hotplug-handler API
  qdev:pci: refactor PCIDevice to use generic "hotpluggable" property
  hw/acpi: move typeinfo to the file end
  qdev: add "hotpluggable" property to Device
  qdev: add to BusState "hotplug-handler" link
  define hotplug interface
  loader: document that errno is set
  pc.c: better error message on initrd sizing failure
  pc_piix: enable legacy hotplug for Xen
  qtest: don't report signals if qtest driver enabled
  hw:piix4:acpi: reuse pcihp code for legacy PCI hotplug
  pcihp: remove unused AcpiPciHpPciStatus.device_present field
  pcihp: make pci_read() mmio calback compatible with legacy ACPI hotplug
  pcihp: make PCI hotplug mmio handlers indifferent to PCI_HOTPLUG_ADDR
  pcihp: replace enable|disable_device() with oneliners
  pcihp: reduce number of device check events

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-13 15:02:04 +00:00
Peter Maydell
f673e70ccc Merge remote-tracking branch 'remotes/afaerber/tags/prep-for-upstream' into staging
PReP machine and devices

* Cleanups for Raven PCI host bridge
* Removal of PReP machine and devices from qemu-system-ppcemb

# gpg: Signature made Mon 10 Feb 2014 16:19:03 GMT using RSA key ID 3E7E013F
# gpg: Good signature from "Andreas Färber <afaerber@suse.de>"
# gpg:                 aka "Andreas Färber <afaerber@suse.com>"

* remotes/afaerber/tags/prep-for-upstream:
  prep: Drop from ppcemb-softmmu
  raven: Use constant PCI_NUM_PINS instead of 4
  prep: Kill get_system_io() usage

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-13 14:52:06 +00:00
Peter Maydell
9d74f6fef0 Merge remote-tracking branch 'remotes/alon/pull-libcacard.glusterfs' into staging
* remotes/alon/pull-libcacard.glusterfs:
  libcacard: Don't link with all libraries QEMU links to

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-12 17:53:31 +00:00
Peter Maydell
628a746cf0 Merge remote-tracking branch 'remotes/kevin/tags/for-anthony' into staging
Block patches

# gpg: Signature made Sun 09 Feb 2014 08:12:51 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-anthony:
  block: Fix 32 bit truncation in mark_request_serialising()
  blkdebug: Don't leak bs->file on failure
  block: Don't call ROUND_UP with negative values
  block: bdrv_aligned_pwritev: Assert overlap range
  block: Fix memory leaks in bdrv_co_do_pwritev()
  raw: Fix BlockLimits passthrough
  qemu-iotests: add test for qcow2 preallocation with different cluster sizes
  qcow2: check for NULL l2meta
  qcow2: fix offset overflow in qcow2_alloc_clusters_at()
  qcow2: remove n_start and n_end of qcow2_alloc_cluster_offset()
  block/iscsi: always fill bs->bl.opt_transfer_length
  block: Fail gracefully with missing filename
  qemu-iotests: enable support for NFS protocol
  qemu-iotests: enable test 016 and 025 to work with NFS protocol
  qemu-iotests: blacklist test 020 for NFS protocol
  qemu-iotests: change _supported_proto to file for various tests
  block: add native support for NFS
  qemu-iotest: Make 077 raw-only

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-12 16:42:50 +00:00
Richard Henderson
5631e69c26 target-openrisc: Use new qemu_ld/st opcodes
Signed-off-by: Richard Henderson <rth@twiddle.net>
Acked-by: Jia Liu <proljc@gmail.com>
Signed-off-by: Jia Liu <proljc@gmail.com>
2014-02-12 08:47:57 +08:00
Edgar E. Iglesias
a4550442b9 petalogix-ml605: Create the CPU with object_new()
This is to allow future patches to set properties before cpu::realize().

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:57 +10:00
Edgar E. Iglesias
2e38847b8d exec: Make cpu_memory_rw_debug use the CPUs AS
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:49 +10:00
Edgar E. Iglesias
2a22165194 exec: Make cpu_physical_memory_write_rom input an AS
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:44 +10:00
Edgar E. Iglesias
db3be60deb exec: Make stb_phys input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:38 +10:00
Edgar E. Iglesias
5ce5944dc0 exec: Make stw_*_phys input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:32 +10:00
Edgar E. Iglesias
2198a12143 exec: Make stl_phys_notdirty input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:24 +10:00
Edgar E. Iglesias
ab1da85791 exec: Make stl_*_phys input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:18 +10:00
Edgar E. Iglesias
f606604f1c exec: Make stq_*_phys input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:12 +10:00
Edgar E. Iglesias
41701aa4ee exec: Make lduw_*_phys input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:06 +10:00
Edgar E. Iglesias
2c17449b30 exec: Make ldq/ldub_*_phys input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:57:00 +10:00
Edgar E. Iglesias
fdfba1a298 exec: Make ldl_*_phys input an AddressSpace
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:56:54 +10:00
Edgar E. Iglesias
33bde2e13f exec: On AS changes, only flush affected CPU TLBs
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:56:43 +10:00
Edgar E. Iglesias
09daed848c cpu: Add per-cpu address space
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:56:37 +10:00
Edgar E. Iglesias
c6c6958c98 memory: Add MemoryListener to typedefs.h
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:56:31 +10:00
Edgar E. Iglesias
1b3fb98ff0 exec: Make memory_region_section_get_iotlb use section AS
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:56:23 +10:00
Edgar E. Iglesias
3be91e862a exec: Always initialize MemorySection address spaces
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:56:16 +10:00
Edgar E. Iglesias
777170946f exec: Make iotlb_to_region input an AS
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:56:09 +10:00
Edgar E. Iglesias
29d8ec7bee exec: Make tb_invalidate_phys_addr input an AS
No functional change.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-11 22:55:55 +10:00
Peter Maydell
8fa7574904 Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140208' into staging
target-arm queue:
 * more A64 Neon instructions
 * AArch32 VCVTB and VCVTT ARMv8 instructions
 * fixes to inaccuracies in GIC emulation
 * libvixl disassembler for A64
 * Allwinner SoC ethernet controller
 * zynq software system reset support

# gpg: Signature made Sat 08 Feb 2014 15:53:05 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20140208: (29 commits)
  arm/zynq: Add software system reset via SCLR
  hw/arm/allwinner-a10: initialize EMAC
  hw/net: add support for Allwinner EMAC Fast Ethernet controller
  util/fifo8: clear fifo head upon reset
  util/fifo8: implement push/pop of multiple bytes
  disas: Implement disassembly output for A64
  disas/libvixl: Fix upstream libvixl compilation issues
  disas: Add subset of libvixl sources for A64 disassembler
  rules.mak: Link with C++ if we have a C++ compiler
  rules.mak: Support .cc as a C++ source file suffix
  arm_gic: Add GICC_APRn state to the GICState
  vmstate: Add uint32 2D-array support
  arm_gic: Support setting/getting binary point reg
  arm_gic: Keep track of SGI sources
  arm_gic: Fix GIC pending behavior
  target-arm: Add support for AArch32 64bit VCVTB and VCVTT
  target-arm: A64: Add FNEG and FABS to the SIMD 2-reg-misc group
  target-arm: A64: Add 2-reg-misc REV* instructions
  target-arm: A64: Add narrowing 2-reg-misc instructions
  target-arm: A64: Implement 2-reg-misc CNT, NOT and RBIT
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-11 11:26:36 +00:00
Peter Maydell
702f6df960 Merge remote-tracking branch 'remotes/kvaneesh/for-upstream' into staging
* remotes/kvaneesh/for-upstream:
  hw/9pfs: fix P9_STATS_GEN handling
  hw/9pfs: make get_st_gen() return ENOTTY error on special files
  hw/9pfs: handle undefined FS_IOC_GETVERSION case in handle_ioc_getversion()
  hw/9pfs: fix error handing in local_ioc_getversion()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-10 18:31:06 +00:00
Paolo Bonzini
a87f39543a memory: fix limiting of translation at a page boundary
Commit 360e607 (address_space_translate: do not cross page boundaries,
2014-01-30) broke MMIO accesses in cases where the section is shorter
than the full register width.  This can happen for example with the
Bochs DISPI registers, which are 16 bits wide but have only a 1-byte
long MemoryRegion (if you write to the "second byte" of the register
your access is discarded; it doesn't write only to half of the register).

Restrict the action of commit 360e607 to direct RAM accesses.  This
is enough for Xen, since MMIO will not go through the mapcache.

Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-10 18:10:43 +00:00
Andreas Färber
ea81ce06a4 prep: Drop from ppcemb-softmmu
ppcemb covers only embedded processors, which does not include PReP.

Signed-off-by: Andreas Färber <andreas.faerber@web.de>
2014-02-10 17:06:26 +01:00
Petar Jovanovic
736d120af4 target-mips: add user-mode FR switch support for MIPS32r5
Description of UFR feature:

Required in MIPS32r5 if floating point is implemented and user-mode FR
switching is supported. The UFR register allows user-mode to clear StatusFR
by executing a CTC1 to UFR with GPR[0] as input, and read StatusFR by
executing a CFC1 to UFR.

helper_ctc1 has been extended with an additional parameter rt to check
requirements for UFR feature.
Definition of mips32r5-generic has been modified to include support for UFR.

Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
Reviewed-by: Eric Johnson <eric.johnson@imgtec.com>
2014-02-10 16:46:38 +01:00
Petar Jovanovic
b4dd99a363 target-mips: add support for CP0_Config5
Add CP0_Config5, define rw_bitmask and enable modifications.

Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
Reviewed-by: Eric Johnson <eric.johnson@imgtec.com>
2014-02-10 16:46:28 +01:00
Petar Jovanovic
b4160af160 target-mips: add support for CP0_Config4
Add CP0_Config4, define rw_bitmask.

Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
Reviewed-by: Eric Johnson <eric.johnson@imgtec.com>
2014-02-10 16:46:12 +01:00
Petar Jovanovic
e527526d35 target-mips: add CPU definition for MIPS32R5
Add mips32r5-generic among CPU definitions for MIPS.
Define ISA_MIPS32R3 and ISA_MIPS32R5.

Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
Reviewed-by: Eric Johnson <eric.johnson@imgtec.com>
2014-02-10 16:45:53 +01:00
Gabriel L. Somlo
417c45ab2f ACPI: Remove commented-out code from HPET._CRS
IRQNoFlags on HPET._CRS crashes WinXP because it causes the HPET
to conflict with the system timer and/or the RTC. It only occurs
on Apple hardware, and even there it is exposed fully only when
OS X is detected (via _OSI). Recent OS X versions work on QEMU
without this statement, so at this time there is no need to find
a better way to conditionally include the statement. This patch
removes the commented out (and wrong, should have been {0, 8})
statement from HPET._CRS.

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-By: Igor Mammedov <imammedo@redhat.com>
2014-02-10 11:09:33 +02:00
Igor Mammedov
5e95494380 hw/pci: switch to a generic hotplug handling for PCIDevice
make qdev_unplug()/device_set_realized() to call hotplug handler's
plug/unplug methods if available and remove not needed anymore
hot(un)plug handling from PCIDevice.

In case if hotplug handler is not available, revert to the legacy
hotplug method for compatibility with not yet converted buses.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:27:00 +02:00
Igor Mammedov
a66e657e18 pci/pcie: convert PCIE hotplug to use hotplug-handler API
Split pcie_cap_slot_hotplug() into hotplug/unplug callbacks
and register them as "hotplug-handler" interface implementation of
PCIE_SLOT device.

Replace pci_bus_hotplug() wiring with setting link on PCI BUS
"hotplug-handler" property to PCI_BRIDGE_DEV device.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:27:00 +02:00
Igor Mammedov
5d268704d7 pci/shpc: convert SHPC hotplug to use hotplug-handler API
Split shpc_device_hotplug() into hotplug/unplug callbacks
and register them as "hotplug-handler" interface implementation of
PCI_BRIDGE_DEV device.

Replace pci_bus_hotplug() wiring with setting link on PCI BUS
"hotplug-handler" property to PCI_BRIDGE_DEV device.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:27:00 +02:00
Igor Mammedov
c24d5e0b91 acpi/piix4pm: convert ACPI PCI hotplug to use hotplug-handler API
Split piix4_device_hotplug() into hotplug/unplug callbacks
and register them as "hotplug-handler" interface implementation of
PIIX4_PM device.

Replace pci_bus_hotplug() wiring with setting link on
PCI BUS "hotplug-handler" property to PIIX4_PM device.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:27:00 +02:00
Igor Mammedov
2897ae0267 qdev:pci: refactor PCIDevice to use generic "hotpluggable" property
Get rid of PCIDevice specific PCIDeviceClass.no_hotplug and use
generic DeviceClass.hotpluggable field instead.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:26:56 +02:00
Igor Mammedov
5fdae20cef hw/acpi: move typeinfo to the file end
do so to avoid not necessary forward declarations and
place typeinfo registration at the file end where it's
usually expected.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:23:36 +02:00
Igor Mammedov
1a37eca107 qdev: add "hotpluggable" property to Device
Currently it's possible to make PCIDevice not hotpluggable
by using no_hotplug field of PCIDeviceClass. However it
limits this only to PCI devices and prevents from
generalizing hotplug code.

So add similar field to DeviceClass so it could be reused
with other Devices and would allow to replace PCI specific
hotplug callbacks with generic implementation. Following
patches will replace PCIDeviceClass.no_hotplug with this
new property.

In addition expose field as "hotpluggable" readonly property,
to make it possible to read its value via QOM interface.

Make DeviceClass hotpluggable by default as it was assumed
before.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:23:35 +02:00
Igor Mammedov
0ee4de6ce1 qdev: add to BusState "hotplug-handler" link
It will allow to reuse field with different BUSes,
reducing code duplication. Field is intended for
replacing 'hotplug_qdev' field in PCIBus and also
will allow to avoid adding equivalent field to
DimmBus with possiblitity to refactor other BUSes
to use it instead of custom field.
In addition once all users of allow_hotplug field
are converted to new API, link could replace
allow_hotplug field in qdev hotplug code.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:23:35 +02:00
Igor Mammedov
9f117d4184 define hotplug interface
Provide a generic hotplug interface for hotplug handlers.
Intended for replacing hotplug mechanism used by
PCI/PCIE/SHPC code and will be used for memory hotplug.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:23:35 +02:00
Michael S. Tsirkin
a1483f88b6 loader: document that errno is set
Document that get_image_size sets errno
on failure.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-10 10:23:35 +02:00
Hervé Poussineau
963116b0b3 raven: Use constant PCI_NUM_PINS instead of 4
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
2014-02-09 15:49:01 +01:00
Hervé Poussineau
c0f2bf9b3f prep: Kill get_system_io() usage
While ISA address space in prep machine is currently the one returned
by get_system_io(), this depends of the implementation of i82378/raven
devices, and this may not be the case forever.

Use the right ISA address space when adding some more ports to it.
We can use whatever ISA device on the right ISA bus, as all ISA devices
on the same ISA bus share the same ISA address space.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
2014-02-09 15:49:00 +01:00
Christophe Fergeau
73db416ae7 libcacard: Don't link with all libraries QEMU links to
As described in https://bugzilla.redhat.com/show_bug.cgi?id=987441 ,
libcacard currently links to all the libraries QEMU is linking to,
including glusterfs libraries, libiscsi, ... libcacard does not need all of
these. This patch ensures it's only linked with the libraries it needs.

Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Signed-off-by: Alon Levy <alevy@redhat.com>
2014-02-09 13:06:02 +02:00
Kevin Wolf
e96126ffa5 block: Fix 32 bit truncation in mark_request_serialising()
On 32 bit hosts, size_t is too small for align as the bitmask
~(align - 1) will zero out the higher 32 bits of the offset.

While at it, change the local overlap_bytes variable to unsigned to
match the field in BdrvTrackedRequest.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-02-09 09:12:39 +01:00
Kevin Wolf
eaf944a438 blkdebug: Don't leak bs->file on failure
Reported-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-02-09 09:12:39 +01:00
Kevin Wolf
5f5bcd80f8 block: Don't call ROUND_UP with negative values
The behaviour of the ROUND_UP macro with negative numbers isn't obvious.
It happens to do the right thing in this please, but better avoid it.

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-02-09 09:12:39 +01:00
Kevin Wolf
af91f9a73c block: bdrv_aligned_pwritev: Assert overlap range
This adds assertions that the request that we actually end up passing to
the block driver (which includes RMW data and has therefore potentially
been rounded to alignment boundaries) is fully covered by the
overlap_{offset,size} fields of the associated BdrvTrackedRequest.

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-02-09 09:12:39 +01:00
Kevin Wolf
99c4a85ce6 block: Fix memory leaks in bdrv_co_do_pwritev()
The error path for a failure in one of the two bdrv_aligned_preadv()
calls leaked head_buf or tail_buf, respectively. This fixes the memory
leak.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-02-09 09:12:39 +01:00
Kevin Wolf
ad6aef43d3 raw: Fix BlockLimits passthrough
raw copies over the BlockLimits of bs->file during bdrv_open().
However, since commit d34682cd it is immediately overwritten during
bdrv_refresh_limits(). This caused all fields except for
opt_transfer_length and opt_mem_alignment (which happen to be correctly
inherited in generic code) to be zeroed.

Move the BlockLimit assignment to a .bdrv_refresh_limits() callback to
make it work again for all fields.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-02-09 09:12:39 +01:00
Hu Tao
693a50ade3 qemu-iotests: add test for qcow2 preallocation with different cluster sizes
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:39 +01:00
Hu Tao
7c2bbf4aa6 qcow2: check for NULL l2meta
In the case of a metadata preallocation with a large cluster size,
qcow2_alloc_cluster_offset() can allocate nothing and returns a
NULL l2meta. This patch checks for it and link2 l2 with only valid
l2meta.

Replace 9 and 512 with BDRV_SECTOR_BITS, BDRV_SECTOR_SIZE
respectively while at the function.

Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:39 +01:00
Hu Tao
33304ec9fa qcow2: fix offset overflow in qcow2_alloc_clusters_at()
When cluster size is big enough it can lead to an offset overflow
in qcow2_alloc_clusters_at(). This patch fixes it.

The allocation is stopped each time at L2 table boundary
(see handle_alloc()), so the possible maximum bytes could be

  2^(cluster_bits - 3 + cluster_bits)

cluster_bits - 3 is used to compute the number of entry by L2
and the additional cluster_bits is to take into account each
clusters referenced by the L2 entries.

so int is safe for cluster_bits<=17, unsafe otherwise.

Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:39 +01:00
Hu Tao
16f0587e0a qcow2: remove n_start and n_end of qcow2_alloc_cluster_offset()
n_start can be actually calculated from offset. The number of
sectors to be allocated(n_end - n_start) can be passed in in
num. By removing n_start and n_end, we can save two parameters.

The side effect is there is a bug in qcow2.c:preallocate() that
passes incorrect n_start to qcow2_alloc_cluster_offset() is
fixed. The bug can be triggerred by a larger cluster size than
the default value(65536), for example:

./qemu-img create -f qcow2 \
  -o 'cluster_size=131072,preallocation=metadata' file.img 4G

Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:39 +01:00
Peter Lieven
5d259fc7da block/iscsi: always fill bs->bl.opt_transfer_length
the opt_transfer_length has nothing to do with logical
block provisioning stuff so always copy it from
the block limits VPD page.

Reported-By: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:38 +01:00
Kevin Wolf
765003db02 block: Fail gracefully with missing filename
This fixes a regression introduced in commit 2a05cbe42 ('block: Allow
block devices without files'):

$ qemu-system-x86_64 -drive driver=file
qemu-system-x86_64: block.c:892: bdrv_open_common: Assertion
`!drv->bdrv_needs_filename || filename != ((void *)0)' failed.

Now the respective check must be performed not only in bdrv_file_open(),
but also in bdrv_open().

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-09 09:12:38 +01:00
Peter Lieven
170632dbc9 qemu-iotests: enable support for NFS protocol
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:38 +01:00
Peter Lieven
a19737f1bd qemu-iotests: enable test 016 and 025 to work with NFS protocol
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:38 +01:00
Peter Lieven
ecd792fd21 qemu-iotests: blacklist test 020 for NFS protocol
reopening is currently not supported.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:38 +01:00
Peter Lieven
1f7bf7d068 qemu-iotests: change _supported_proto to file for various tests
all these tests do anything of the following and thus fail with any
protocol other than file:
 - the tests use rm, cp or mv shell commands which only work on file
 - the tests use qcow2.py
 - the images construct new filenames (e.g. backing file names) and
   the logic is broken for anything else than file

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:38 +01:00
Peter Lieven
6542aa9c75 block: add native support for NFS
This patch adds native support for accessing images on NFS
shares without the requirement to actually mount the entire
NFS share on the host.

NFS Images can simply be specified by an url of the form:
nfs://<host>/<export>/<filename>[?param=value[&param2=value2[&...]]]

For example:
qemu-img create -f qcow2 nfs://10.0.0.1/qemu-images/test.qcow2

You need LibNFS from Ronnie Sahlberg available at:
   git://github.com/sahlberg/libnfs.git
for this to work.

During configure it is automatically probed for libnfs and support
is enabled on-the-fly. You can forbid or enforce libnfs support
with --disable-libnfs or --enable-libnfs respectively.

Due to NFS restrictions you might need to execute your binaries
as root, allow them to open priviledged ports (<1024) or specify
insecure option on the NFS server.

For additional information on ROOT vs. non-ROOT operation and URL
format + parameters see:
   https://raw.github.com/sahlberg/libnfs/master/README

Supported by qemu are the uid, gid and tcp-syncnt URL parameters.

LibNFS currently support NFS version 3 only.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-02-09 09:12:38 +01:00
Kevin Wolf
f51062061e qemu-iotest: Make 077 raw-only
The qemu-io command sequences make the assumption that an unaligned
request on the format layer will be unaligned on the blkdebug layer as
well. This doesn't necessarily hold true for drivers other than raw.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoît Canet <benoit@irqsave.net>
2014-02-09 09:12:38 +01:00
Peter Maydell
1f6b12f75f Merge remote-tracking branch 'remotes/mwalle/tags/lm32-fixes/20140204' into staging
target-lm32: fixes

# gpg: Signature made Tue 04 Feb 2014 18:47:56 GMT using DSA key ID 3F98A378
# gpg: Can't check signature: public key not found

* remotes/mwalle/tags/lm32-fixes/20140204:
  hw/lm32: print error if cpu model is not found
  target-lm32: stop VM on illegal or unknown instruction
  lm32_sys: dump cpu state if test case fails
  lm32_sys: print test result on stderr
  target-lm32: add breakpoint/watchpoint support
  target-lm32: move model features to LM32CPU
  target-lm32: kill cpu_abort() calls
  milkymist-vgafb: swap pixel data in source buffer
  lm32_uart/lm32_juart: use qemu_chr_fe_write_all()
  milkymist-uart: use qemu_chr_fe_write_all() instead of qemu_chr_fe_write()
  tests: lm32: new rule for single test cases
  lm32_sys: increase test case name length limit

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 15:57:51 +00:00
Sebastian Huber
69991d7dcb arm/zynq: Add software system reset via SCLR
Support software-driven system reset via the register in the SCLR.

Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Beniamino Galvani
db7dfd4c7e hw/arm/allwinner-a10: initialize EMAC
Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Beniamino Galvani
22f90bcb2b hw/net: add support for Allwinner EMAC Fast Ethernet controller
This patch adds support for the Fast Ethernet MAC found on Allwinner
SoCs, together with a basic emulation of Realtek RTL8201CP PHY.

Since there is no public documentation of the Allwinner controller, the
implementation is based on Linux kernel driver.

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Beniamino Galvani
58892d4782 util/fifo8: clear fifo head upon reset
To improve the predictability of fifo8_pop_buf(), the fifo head is set
to the start of data buffer upon a reset so that the first call to the
function will be able to retrieve all data in the fifo.

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Beniamino Galvani
c4e57af852 util/fifo8: implement push/pop of multiple bytes
The patch adds functions fifo8_push_all() and fifo8_pop_buf() which
can be used respectively to push the content of a memory buffer to the
fifo and to pop multiple bytes obtaining a pointer to the fifo backing
buffer.

In addition, it implements fifo8_num_free() and fifo8_num_used() which
allow to check if a multi-byte operation can be performed.

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Claudio Fontana
999b53ec87 disas: Implement disassembly output for A64
Use libvixl to implement disassembly output in debug
logs for A64, for use with both AArch64 hosts and targets.

Signed-off-by: Claudio Fontana <claudio.fontana@linaro.org>
[PMM:
 * added support for target disassembly
 * switched to custom QEMUDisassembler so the output format
   matches what QEMU expects
 * make sure we correctly fall back to "just print hex"
   if we didn't build the AArch64 disassembler because of
   lack of a C++ compiler
 * rename from 'aarch64' to 'arm-a64' because this is a
   disassembler for the A64 instruction set
 * merge aarch64.c and aarch64-cxx.cc into one C++ file
 * simplify the aarch64.c<->aarch64-cxx.cc interface]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Peter Maydell
37fd5b53ba disas/libvixl: Fix upstream libvixl compilation issues
Fix various minor issues with upstream libvixl so that it will compile
successfully on the platforms QEMU cares about:
 * remove unused GBytes constant (it clashes with the glib headers)
 * fix suffixes on constants to use 'LL' for 64 bit constants so
   we can compile on 32 bit hosts

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:50:48 +00:00
Peter Maydell
878a735d00 disas: Add subset of libvixl sources for A64 disassembler
Add the subset of the libvixl sources that are needed for the
A64 disassembler support. These sources come from
https://github.com/armvixl/vixl commit 578645f14e122d2b
which is VIXL release 1.1.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:50:48 +00:00
Peter Maydell
3144f78b3f rules.mak: Link with C++ if we have a C++ compiler
If we have a C++ compiler available, link with it, because we might be
linking some C++ files in. This allows us to include C++ object files
in the QEMU binary proper.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:50:48 +00:00
Peter Maydell
c3dc9fd5ac rules.mak: Support .cc as a C++ source file suffix
The A64 disassembler libvixl uses .cc as its suffix for
C++ source files, so add support for it (we already support
.cpp).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:50:48 +00:00
Christoffer Dall
a9d477c4e3 arm_gic: Add GICC_APRn state to the GICState
The GICC_APRn registers are not currently supported by the ARM GIC v2.0
emulation.  This patch adds the missing state.

Note that we also change the number of APRs to use a define GIC_NR_APRS
based on the maximum number of preemption levels.  This patch also adds
RAZ/WI accessors for the four registers on the emulated CPU interface.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Christoffer Dall
a1b1d277cd vmstate: Add uint32 2D-array support
Add support for saving VMState of 2D arrays of uint32 values.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Christoffer Dall
aa7d461ae9 arm_gic: Support setting/getting binary point reg
Add a binary_point field to the gic emulation structure and support
setting/getting this register now when we have it.  We don't actually
support interrupt grouping yet, oh well.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:50:48 +00:00
Christoffer Dall
40d225009e arm_gic: Keep track of SGI sources
Right now the arm gic emulation doesn't keep track of the source of an
SGI (which apparently Linux guests don't use, or they're fine with
assuming CPU 0 always).

Add the necessary matrix on the GICState structure and maintain the data
when setting and clearing the pending state of an IRQ and make the state
visible to the guest.

Note that we always choose to present the source as the lowest-numbered
CPU in case multiple cores have signalled the same SGI number to a core
on the system.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:47:28 +00:00
Christoffer Dall
8d999995e4 arm_gic: Fix GIC pending behavior
The existing implementation of the pending behavior in gic_set_irq,
gic_complete_irq, and the distributor pending set/clear registers does
not follow the semantics of the GICv2.0 specs, but may implement the
11MPCore support.  Therefore, maintain the existing semantics for
11MPCore and v7M NVIC and change the behavior to be in accordance with
the GICv2.0 specs for "generic implementations" (s->revision == 1 ||
s->revision == 2).

Generic implementations distinguish between setting a level-triggered
interrupt pending through writes to the GICD_ISPENDR and when hardware
raises the interrupt line.  Writing to the GICD_ICPENDR will not cause
the interrupt to become non-pending if the line is still active, and
conversely, if the line is deactivated but the interrupt is marked as
pending through a write to GICD_ISPENDR, the interrupt remains pending.
Handle this situation in the GIC_TEST_PENDING (which now becomes a
static inline named gic_test_pending) and let the 'pending' field
correspond only to the latched state of the D-flip flop in the GICv2.0
specs Figure 4-10.

The following changes are added:

gic_test_pending:
Make this a static inline and split out the 11MPCore from the generic
behavior.  For the generic behavior, consider interrupts pending if:
    ((s->irq_state[irq].pending & (cm) != 0) ||
       (!GIC_TEST_EDGE_TRIGGER(irq) && GIC_TEST_LEVEL(irq, cm))

gic_set_irq:
Split out the 11MPCore from the generic behavior.  For the generic
behavior, always GIC_SET_LEVEL() on positive level, but only
GIC_SET_PENDING for edge-triggered interrupts and always simply
GIC_CLEAR_LEVEL() on negative level.

gic_complete_irq:
Only resample the line for line-triggered interrupts on an 11MPCore.
Generic implementations will sample the line directly in
gic_test_pending().

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:47:28 +00:00
Will Newton
239c20c7c8 target-arm: Add support for AArch32 64bit VCVTB and VCVTT
Add support for the AArch32 floating-point half-precision to double-
precision conversion VCVTB and VCVTT instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
[PMM: fixed a minor missing-braces style issue]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 14:47:28 +00:00
Peter Maydell
f93d013895 target-arm: A64: Add FNEG and FABS to the SIMD 2-reg-misc group
Add the SIMD FNEG and FABS instructions in the SIMD 2-reg-misc group.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:47:28 +00:00
Alex Bennée
39d8211893 target-arm: A64: Add 2-reg-misc REV* instructions
Add the byte-reverse operations REV64, REV32 and REV16 from the
two-reg-misc group.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:47:28 +00:00
Peter Maydell
d980fd59a4 target-arm: A64: Add narrowing 2-reg-misc instructions
Add the narrowing integer instructions in the 2-reg-misc class.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:47:28 +00:00
Peter Maydell
86cbc418ce target-arm: A64: Implement 2-reg-misc CNT, NOT and RBIT
Implement the 2-reg-misc CNT, NOT and RBIT instructions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:47:28 +00:00
Peter Maydell
94b6c911c6 target-arm: A64: Implement 2-register misc compares, ABS, NEG
Implement the simple 2-register-misc operations we can share
with the scalar-two-register-misc code. (SUQADD, USQADD, SQABS,
SQNEG also fall into this category, but aren't implemented in
the scalar-2-register case yet either.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:47:28 +00:00
Peter Maydell
45aecc6dbb target-arm: A64: Add skeleton decode for SIMD 2-reg misc group
Add a skeleton decode for the SIMD 2-reg misc group.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:56 +00:00
Peter Maydell
effa8e0643 target-arm: A64: Add SIMD simple 64 bit insns from scalar 2-reg misc
Implement the simple 64 bit integer operations from the SIMD
scalar 2-register misc group (C3.6.12): the comparisons against
zero, plus ABS and NEG.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:56 +00:00
Peter Maydell
c0b2b5fa36 target-arm: A64: Implement remaining integer scalar-3-same insns
Implement the remaining integer instructions in the scalar-three-reg-same
group: SQADD, UQADD, SQSUB, UQSUB, SQSHL, UQSHL, SQRSHL, UQRSHL,
SQDMULH, SQRDMULH.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:56 +00:00
Peter Maydell
3720a7ea36 target-arm: A64: Implement scalar pairwise ops
Implement the instructions in the scalar pairwise group (C3.6.8).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:56 +00:00
Peter Maydell
c1de788ab9 tcg: Add TCGV_UNUSED_PTR, TCGV_IS_UNUSED_PTR, TCGV_EQUAL_PTR
We have macros for marking TCGv values as unused, checking if they
are unused and comparing them to each other. However these only exist
for TCGv_i32 and TCGv_i64; add them for TCGv_ptr as well.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:55 +00:00
Peter Maydell
0173a00521 target-arm: A64: Implement pairwise integer ops from 3-reg-same SIMD
Implement the pairwise integer operations in the 3-reg-same SIMD group:
ADDP, SMAXP, SMINP, UMAXP and UMINP.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:55 +00:00
Peter Maydell
8b12a0cfc1 target-arm: A64: Implement remaining non-pairwise int SIMD 3-reg-same insns
Implement the SIMD 3-reg-same instructions where the size == 3 case
is reserved: SHADD, UHADD, SRHADD, URHADD, SHSUB, UHSUB, SMAX,
UMAX, SMIN, UMIN, SABD, UABD, SABA, UABA, MLA, MLS, MUL, PMUL,
SQRDMULH, SQDMULH. (None of these have scalar-3-same versions.)
This completes the non-pairwise integer instructions in this category.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:55 +00:00
Peter Maydell
6d9571f7d8 target-arm: A64: Implement SIMD 3-reg-same shift and saturate insns
Implement the SIMD 3-reg-same instructions SQADD, UQADD,
SQSUB, UQSUB, SSHL, USHL, SQSHl, UQSHL, SRSHL, URSHL,
SQRSHL, UQRSHL; these are all simple calls to existing
Neon helpers. We also enable SSHL, USHL, SRSHL and URSHL
for the 3-reg-same-scalar category (but not the others
because they can have non-size-64 operands and the
scalar_3reg_same function doesn't support that yet.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-02-08 14:46:55 +00:00
Peter Maydell
3ea3bd6245 Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20140204-1' into staging
migration/next for 20140204

# gpg: Signature made Tue 04 Feb 2014 15:52:00 GMT using RSA key ID 5872D723
# gpg: Can't check signature: public key not found

* remotes/juanquintela/tags/migration/20140204-1:
  Don't abort on memory allocation error
  Don't abort on out of memory when creating page cache
  XBZRLE cache size should not be larger than guest memory size
  migration:fix free XBZRLE decoded_buf wrong
  Add check for cache size smaller than page size
  Set xbzrle buffers to NULL after freeing them to avoid double free errors
  exec: fix ram_list dirty map optimization
  vmstate: Make VMSTATE_STRUCT_POINTER take type, not ptr-to-type

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-08 13:12:50 +00:00
Peter Maydell
4db0014521 Merge remote-tracking branch 'remotes/kraxel/tags/pull-roms-1' into staging
Update seabios to 1.7.4

# gpg: Signature made Mon 03 Feb 2014 14:42:44 GMT 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-1:
  Update seabios binaries to 1.7.4
  Update seabios submodule to 1.7.4
  roms: remove explicit MAKEFLAGS from recursive make invocations

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-07 16:42:13 +00:00
Peter Maydell
91abb80b5f Merge remote-tracking branch 'remotes/stefanha/tags/qtest-for-peter' into staging
qtest resource cleanup patches

# gpg: Signature made Tue 04 Feb 2014 08:29:12 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/qtest-for-peter:
  qtest: unlink UNIX domain sockets after connecting
  qtest: unlink QEMU pid file after startup

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-07 16:03:13 +00:00
Peter Maydell
bc1c72171c Merge remote-tracking branch 'remotes/kvm/uq/master' into staging
* remotes/kvm/uq/master:
  target-i386: Move KVM default-vendor hack to instance_init
  target-i386: Don't change x86_def_t struct on cpu_x86_register()
  target-i386: Eliminate CONFIG_KVM #ifdefs
  kvm: add support for hyper-v timers
  kvm: make hyperv vapic assist page migratable
  kvm: make hyperv hypercall and guest os id MSRs migratable.
  kvm: make availability of Hyper-V enlightenments dependent on KVM_CAP_HYPERV
  KVM: fix coexistence of KVM and Hyper-V leaves
  kvm: print suberror on all internal errors
  target-i386: kvm_check_features_against_host(): Kill feature word array
  target-i386: kvm_cpu_fill_host(): Fill feature words in a loop
  target-i386: kvm_cpu_fill_host(): Set all feature words at end of function
  target-i386: kvm_cpu_fill_host(): No need to check xlevel2
  target-i386: kvm_cpu_fill_host(): No need to check CPU vendor
  target-i386: kvm_cpu_fill_host(): No need to check level
  target-i386: kvm_cpu_fill_host(): Kill unused code

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-06 23:51:24 +00:00
Peter Maydell
26530780c2 Merge remote-tracking branch 'remotes/spice/tags/pull-spice-2' into staging
misc spice patches

# gpg: Signature made Mon 03 Feb 2014 15:05:29 GMT using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/spice/tags/pull-spice-2:
  spice: hook qemu_chr_fe_set_open() event to ports
  Add the ability to vary Spice playback and record rates, to facilitate Opus support.
  hw/display/qxl: fix signed to unsigned comparison
  qxl: clear irq on reset

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-06 10:21:12 +00:00
Peter Maydell
31db5b3638 Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-2014-02-02' into staging
trivial patches for 2014-02-02

# gpg: Signature made Sun 02 Feb 2014 16:11:37 GMT using RSA key ID 74F0C838
# gpg: Good signature from "Michael Tokarev <mjt@tls.msk.ru>"
# gpg:                 aka "Michael Tokarev <mjt@corpit.ru>"
# gpg:                 aka "Michael Tokarev <mjt@debian.org>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 8044 65C5
#      Subkey fingerprint: E190 8639 3B10 B51B AC2C  8B73 5253 C5AD 74F0 C838

* remotes/mjt/tags/trivial-patches-2014-02-02:
  tests/.gitignore: Ignore tests/check-qom-interface
  hw/ppc: Remove unused defines
  readline: Add missing GCC_FMT_ATTR
  tcg/s390: Remove sigill_handler
  i386: Add missing include file for QEMU_PACKED
  osdep: drop unused #include "trace.h"
  qemu 1.7.0 does not build on NetBSD

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-05 16:37:26 +00:00
Peter Maydell
e5d3df6deb Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request

# gpg: Signature made Fri 31 Jan 2014 21:16:43 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/block-pull-request:
  qemu-iotests: only run 071 on qcow2
  dataplane: Comment fix
  block/vhdx: Error checking fixes
  qemu-iotests: Drop assert_no_active_commit in case 040
  block/vmdk: add basic .bdrv_check support
  block: remove qcow2 .bdrv_make_empty implementation
  block: remove QED .bdrv_make_empty implementation
  Describe flaws in qcow/qcow2 encryption in the docs

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-05 16:29:01 +00:00
Michael S. Tsirkin
7454e51d2b pc.c: better error message on initrd sizing failure
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:50 +02:00
Michael S. Tsirkin
d160024fe5 pc_piix: enable legacy hotplug for Xen
xenfv has no fwcfg and so does not load acpi from QEMU.
as such new acpi features don't work.

Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:50 +02:00
Michael S. Tsirkin
35b307126c qtest: don't report signals if qtest driver enabled
qtest driver always uses signals to kill qemu
no need to report it, whatever the accelerator state.

Add API to detect qtest driver, and suppress reporting
signals in this case.

Reported-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:50 +02:00
Igor Mammedov
e358edc8e9 hw:piix4:acpi: reuse pcihp code for legacy PCI hotplug
reduces acpi PCI hotplug code duplication by ~200LOC

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:50 +02:00
Igor Mammedov
a1b4d9eff9 pcihp: remove unused AcpiPciHpPciStatus.device_present field
Remove now unused 'device_present' field wich was obsoleted by
patch "pcihp: reduce number of device check events"

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:50 +02:00
Igor Mammedov
99d09dd328 pcihp: make pci_read() mmio calback compatible with legacy ACPI hotplug
due to recent change introduced by:
"pcihp: reduce number of device check events"

'up' field is cleared right after it's read.
This is incompatible with legacy BIOS ACPI code
where PCNF ACPI method reads this field 32 times.

To make pci_read mmio callback compatible with legacy
'up' behavior, pcihp code will need to know in which
mode it runs add 'legacy_piix' field to AcpiPciHpState
structure and alter register behavior accordingly.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:49 +02:00
Igor Mammedov
a7b613cf68 pcihp: make PCI hotplug mmio handlers indifferent to PCI_HOTPLUG_ADDR
... removes dependency of mmio handler on PCI_HOTPLUG_ADDR.
It will be needed in case of Q35 where base could be different.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:49 +02:00
Igor Mammedov
8f5001f9ed pcihp: replace enable|disable_device() with oneliners
enable_device() and disable_device() functions aren't reused anywere,
so replace them with respective oneliners at call sites.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:49 +02:00
Michael S. Tsirkin
5a2223ca26 pcihp: reduce number of device check events
PIIX created a made-up value for the UP register since it was read by
guest 32 times for each interrupt.
There's no reason to do this for the new PCIHP: register is only read
once for each interrupt, so clean up code by making read act as an
interrupt acknowledgement: the new UP register clear on read.

In this way we cut down the number of bus rescans
by a factor of 32, and drop a bunch of code that's
now unused.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-02-05 16:55:49 +02:00
Michael Walle
f41152bd9d hw/lm32: print error if cpu model is not found
QEMU crashed if a the given cpu_model is not found.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-04 19:47:39 +01:00
Michael Walle
667ff9612b target-lm32: stop VM on illegal or unknown instruction
Instead of translating the instruction to a no-op, pause the VM and display
a message to the user.

As a side effect, this also works for instructions where the operands are
only known at runtime.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-02-04 19:47:39 +01:00
Michael Walle
8c5edce5b7 lm32_sys: dump cpu state if test case fails
This will ease debugging the test cases.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-02-04 19:47:39 +01:00
Michael Walle
9a59e6e307 lm32_sys: print test result on stderr
Do not use qemu_log().

Signed-off-by: Michael Walle <michael@walle.cc>
2014-02-04 19:47:27 +01:00
Michael Walle
3dd3a2b965 target-lm32: add breakpoint/watchpoint support
This patch adds in-target breakpoint and watchpoint support.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-02-04 19:47:06 +01:00
Peter Maydell
2b2449f7e4 Merge remote-tracking branch 'remotes/borntraeger/tags/kvm-s390-20140131' into staging
This patch set contains the sclp defines and events for cpu hotplug,
the initial sclp defines (without code yet) for standby memory (some
sort of memory hotplug) as well as a cleanup of the kvm register
synchronization.

# gpg: Signature made Fri 31 Jan 2014 08:54:29 GMT using RSA key ID B5A61C7C
# gpg: Can't check signature: public key not found

* remotes/borntraeger/tags/kvm-s390-20140131:
  s390x/kvm: cleanup partial register handling
  sclp-s390: Define new SCLP codes and structures
  s390-sclp: SCLP Event integration
  s390-sclp: SCLP CPU Info
  s390-sclp: Define New SCLP Codes

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-04 18:46:33 +00:00
Michael Walle
34f4aa83f9 target-lm32: move model features to LM32CPU
This allows us to completely remove CPULM32State from DisasContext.
Instead, copy the fields we need to DisasContext.

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Walle <michael@walle.cc>
2014-02-04 19:34:30 +01:00
Michael Walle
3604a76fea target-lm32: kill cpu_abort() calls
Instead of killing QEMU, translate instructions which are not available on
the CPU model as a noop and issue a log message at translation time.

On the real hardware CPU unknown opcodes results in undefined behaviour.

These changes prepare the removal of CPULM32State from DisasContext.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Andreas Färber <afaerber@suse.de>
2014-02-04 19:34:30 +01:00
Michael Walle
2f45356427 milkymist-vgafb: swap pixel data in source buffer
In commit fc97bb5ba3 the lduw_raw() call was
eliminated. But we are reading from the target buffer a 16-bit value, which
is in big-endian format. Therefore, use lduw_be_p() to read the value.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Walle <michael@walle.cc>
2014-02-04 19:34:30 +01:00
Michael Walle
02d3bf7fe7 lm32_uart/lm32_juart: use qemu_chr_fe_write_all()
qemu_chr_fe_write() may return EAGAIN. Therefore, use
qemu_chr_fe_write_all().

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-04 19:34:30 +01:00
Antony Pavlov
b2c623a3d9 milkymist-uart: use qemu_chr_fe_write_all() instead of qemu_chr_fe_write()
qemu_chr_fe_write() is capable of returning 0
to indicate EAGAIN (and friends) and we don't
handle this.

Just change it to qemu_chr_fe_write_all() to fix.

Reported-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Acked-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-04 19:34:29 +01:00
Michael Walle
f40c49ac9f tests: lm32: new rule for single test cases
Introduce new target "check_%" to run individual test caes, eg.
  make check_mmu

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-04 19:34:29 +01:00
Michael Walle
e67b3ca53a lm32_sys: increase test case name length limit
The new MMU tests use longer names.

Signed-off-by: Michael Walle <michael@walle.cc>
2014-02-04 19:34:29 +01:00
Peter Maydell
9396b05a5a Merge remote-tracking branch 'remotes/mcayland/qemu-openbios' into staging
* remotes/mcayland/qemu-openbios:
  Update OpenBIOS images

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-02-04 16:16:37 +00:00
Orit Wasserman
89db9987c0 Don't abort on memory allocation error
It is better to fail migration in case of failure to
allocate new cache item

Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 16:50:37 +01:00
Orit Wasserman
a17b2fd358 Don't abort on out of memory when creating page cache
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 16:50:22 +01:00
Orit Wasserman
a5615b14a6 XBZRLE cache size should not be larger than guest memory size
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 16:49:28 +01:00
Gonglei (Arei)
905f26f222 migration:fix free XBZRLE decoded_buf wrong
When qemu do live migration with xbzrle, qemu malloc decoded_buf
at destination end but free it at source end. It will crash qemu
by double free error in some scenarios. Splitting the XBZRLE structure
for clear logic distinguishing src/dst side.

Signed-off-by: ChenLiang <chenliang88@huawei.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: GongLei <arei.gonglei@huawei.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 16:49:24 +01:00
Orit Wasserman
c91e681a55 Add check for cache size smaller than page size
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 16:49:24 +01:00
Orit Wasserman
f6c6483b25 Set xbzrle buffers to NULL after freeing them to avoid double free errors
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 16:48:49 +01:00
Alexey Kardashevskiy
f9ee9f9ac2 exec: fix ram_list dirty map optimization
The ae2810c4bb patch introduced
optimization for ram_list.dirty_memory update. However it can only
work correctly if hpratio is 1 as the @bitmap parameter stores 1 bits
per system page size (may vary, 4K or 64K on PPC64) and
ram_list.dirty_memory stores 1 bit per TARGET_PAGE_SIZE
(which is hardcoded to 4K).

This fixes hpratio!=1 case to fall back to the slow path.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 16:45:22 +01:00
Peter Maydell
20bcf73fa8 vmstate: Make VMSTATE_STRUCT_POINTER take type, not ptr-to-type
The VMSTATE_STRUCT_POINTER macros are a bit odd in that they
must be passed an argument "FooType *" rather than just taking
the FooType. They're only used in one place, so it's easy to
tidy this up. This also lets us use the macro to replace the
hand-rolled VMSTATE_PTIMER.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-02-04 15:51:45 +01:00
Eduardo Habkost
7c08db30e6 target-i386: Move KVM default-vendor hack to instance_init
As we will not have a cpu_x86_find_by_name() function anymore,
move the KVM default-vendor hack to instance_init.

Unfortunately we can't move that code to class_init because it depends
on KVM being initialized.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Eduardo Habkost
82beb53633 target-i386: Don't change x86_def_t struct on cpu_x86_register()
As eventually the x86_def_t data is going to be provided by the CPU
class, it's better to not touch it, and handle the special cases on the
X86CPU object itself.

Current behavior of the code should stay exactly the same.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Eduardo Habkost
c1f412260b target-i386: Eliminate CONFIG_KVM #ifdefs
The compiler is already able to eliminate the kvm_arch_get_supported_cpuid()
calls in kvm_cpu_fill_host() and filter_features_for_kvm(), so we can
eliminate the CONFIG_KVM #ifdefs there.

Also, kvm_cpu_fill_host() and host_cpuid() don't need to check
CONFIG_KVM, as they don't have any KVM-specific function calls.

Tested to build successfully with CONFIG_KVM disabled, using the
following CFLAGS combinations: "-DNDEBUG", "-DNDEBUG -O', "-DNDEBUG
-O0", "-DNDEBUG -O1", "-DNDEBUG -O2".

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Vadim Rozenfeld
48a5f3bcbb kvm: add support for hyper-v timers
http://msdn.microsoft.com/en-us/library/windows/hardware/ff541625%28v=vs.85%29.aspx

This code is generic for activating reference time counter or virtual reference time stamp counter

Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Vadim Rozenfeld
5ef68987e5 kvm: make hyperv vapic assist page migratable
Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Vadim Rozenfeld
1c90ef2619 kvm: make hyperv hypercall and guest os id MSRs migratable.
Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Paolo Bonzini
7bc3d711b4 kvm: make availability of Hyper-V enlightenments dependent on KVM_CAP_HYPERV
The MS docs specify HV_X64_MSR_HYPERCALL as a mandatory interface,
thus we must provide the MSRs even if the user only specified
features that, like relaxed timing, in principle don't require them.
And the MSRs are only there if the hypervisor has KVM_CAP_HYPERV.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Paolo Bonzini
234cc64796 KVM: fix coexistence of KVM and Hyper-V leaves
kvm_arch_init_vcpu's initialization of the KVM leaves at 0x40000100
is broken, because KVM_CPUID_FEATURES is left at 0x40000001.  Move
it to 0x40000101 if Hyper-V is enabled.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:55 +01:00
Radim Krčmář
977c7b6d89 kvm: print suberror on all internal errors
KVM introduced internal error exit reason and suberror at the same time,
and later extended it with internal error data.
QEMU does not report suberror on hosts between these two events because
we check for the extension. (half a year in 2009, but it is misleading)

Fix by removing KVM_CAP_INTERNAL_ERROR_DATA condition on printf.

(partially improved by bb44e0d12d and ba4047cf84 in the past)

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Eduardo Habkost
f0b9b11164 target-i386: kvm_check_features_against_host(): Kill feature word array
We don't need the ft[] array on kvm_check_features_against_host()
anymore, as we can simply use the feature_word_info[] array, that has
everything we need.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Eduardo Habkost
2bc65d2b02 target-i386: kvm_cpu_fill_host(): Fill feature words in a loop
Now that the kvm_cpu_fill_host() code is simplified, we can simply set
the feature word array using a simple loop.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Eduardo Habkost
2a573259eb target-i386: kvm_cpu_fill_host(): Set all feature words at end of function
Reorder the code so all the code that sets x86_cpu_def->features is at
the end of the function.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Eduardo Habkost
803a932706 target-i386: kvm_cpu_fill_host(): No need to check xlevel2
There's no need to check CPU xlevel2 before calling
kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX), because:

 * The kernel won't return any entry for 0xC0000000 if host CPU vendor
   is not Centaur (See kvm_dev_ioctl_get_supported_cpuid() on the kernel
   code)
 * Similarly, the kernel won't return any entry for 0xC0000001 if
   CPUID[0xC0000000].EAX is < 0xC0000001
 * kvm_arch_get_supported_cpuid() will return 0 if no entry is returned
   by the kernel for the requested leaf

For similar reasons, we can simply set x86_cpu_def->xlevel2 directly
instead of making it conditional, because it will be set to 0 CPU vendor
is not Centaur.

This will simplify the kvm_cpu_fill_host() code a little.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
[Remove unparseable comment. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Eduardo Habkost
b73dcfb16f target-i386: kvm_cpu_fill_host(): No need to check CPU vendor
There's no need to check CPU vendor before calling
kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX), because:

 * The kernel won't return any entry for 0xC0000000 if host CPU vendor
   is not Centaur (See kvm_dev_ioctl_get_cpuid() on the kernel code);
 * kvm_arch_get_supported_cpuid() will return 0 if no entry is returned
   by the kernel for the requested leaf.

This will simplify the kvm_cpu_fill_host() code a little.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Eduardo Habkost
7171a3933f target-i386: kvm_cpu_fill_host(): No need to check level
There's no need to check level (CPUID[0].EAX) before calling
kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX), because:

 * The kernel won't return any entry for CPUID 7 if CPUID[0].EAX is < 7
   on the host (See kvm_dev_ioctl_get_cpuid() on the kernel code);
 * kvm_arch_get_supported_cpuid() will return 0 if no entry is returned
   by the kernel for the requested leaf.

This will simplify the kvm_cpu_fill_host() code a little.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Eduardo Habkost
81e207707e target-i386: kvm_cpu_fill_host(): Kill unused code
Those host_cpuid() calls are useless. They are leftovers from when the
old code using host_cpuid() was removed.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-02-03 17:33:54 +01:00
Stefan Hajnoczi
56db2e5843 qtest: unlink UNIX domain sockets after connecting
UNIX domain sockets are leaked when tests call abort(3) (indirectly via
glib assert functions).

Unlink the files immediately after the connection has been established
to avoid leaks.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-03 16:06:24 +01:00
Stefan Hajnoczi
1ad3c6abc0 qtest: unlink QEMU pid file after startup
After starting the QEMU process and initializing the QMP connection, we
can read the pid file and unlink it.

Just stash away the pid instead of the pid filename.  This way we can
avoid pid file leaks since running tests may abort(3) without cleanup.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-02-03 16:06:24 +01:00
Stefan Weil
8cfc114a2f linux-user: Fix trampoline code for CRIS
__put_user can write bytes, words (2 bytes) or longwords (4 bytes).
Here obviously words should have been written, but bytes were written,
so values like 0x9c5f were truncated to 0x5f.

Fix this by changing retcode from uint8_t to to uint16_t in
target_signal_frame and also in the unused rt_signal_frame.

This problem was reported by static code analysis (smatch).

Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Acked-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-03 14:04:00 +00:00
Edgar E. Iglesias
ce603d8ef1 cris: Remove the CRIS PIC glue
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-03 14:04:00 +00:00
Edgar E. Iglesias
4a6da670f8 axis-dev88: Connect the PIC upstream IRQs directly to the CPU
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-03 14:03:59 +00:00
Edgar E. Iglesias
3065839c72 cris: Add interrupt signals to the CPU device
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-03 14:03:59 +00:00
Edgar E. Iglesias
d66433ffdc cris: Abort when a v10 takes interrupts while in a delayslot
This is an internal error as the CRISv10 should mask interrupts
while executing delay slots. Bail out sooner rather than later.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-03 14:03:59 +00:00
Edgar E. Iglesias
fd5d5afad8 cris: Add "any" as alias for "crisv32" in user emulation
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-02-03 14:03:49 +00:00
Marc-André Lureau
8909114649 spice: hook qemu_chr_fe_set_open() event to ports
This wires up a spice port event on virtio-ports open/close, so the
client is notified when the other end is ready.

Signed-off-by: Marc-André Lureau <marcandre.lureau@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-03 11:05:15 +01:00
Jeremy White
795ca114d3 Add the ability to vary Spice playback and record rates, to facilitate Opus support.
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-03 11:05:15 +01:00
Alon Levy
3761abb167 hw/display/qxl: fix signed to unsigned comparison
Several small signedness / overflow corrections to qxl_create_guest_primary:
1. use 64 bit unsigned for size to avoid overflow possible from two 32
bit multiplicants.
2. correct sign for requested_height
3. add a more verbose error message when setting guest bug state (which
causes a complete guess blackout until reset, so it helps if it is
verbose).

Signed-off-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-03 11:05:15 +01:00
Alon Levy
f06b85218a qxl: clear irq on reset
Without this we occasionally trigger an assert at
hw/pci/pci.c:pcibus_reset that asserts the irq_count is zero on reset.

This has become a problem with the new drm driver for linux, since doing
a reboot from console causes a race between console updates that set the
irq and the reset assertion that the irq is clear.

Signed-off-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-02-03 11:05:15 +01:00
Kirill A. Shutemov
f8b7ee38b3 hw/9pfs: fix P9_STATS_GEN handling
Currently we fail getattr request altogether if we can't read
P9_STATS_GEN for some reason. It breaks valid use cases:

E.g let's assume we have non-readable directory with execution bit set
on host and we export it to client over 9p On host we can chdir into
directory, but not open directory on read and list content.

But if client will try to call getattr (as part of chdir(2)) for the
directory it will fail with -EACCES. It happens because we try to open
the directory on read to call ioctl(FS_IOC_GETVERSION), it fails and we
return the error code to client.

It's excessive. The solution is to make P9_STATS_GEN failure non-fatal
for getattr request. Just don't set P9_STATS_GEN flag in result mask on
failure.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
2014-02-02 22:09:16 +05:30
Kirill A. Shutemov
1a9978a51a hw/9pfs: make get_st_gen() return ENOTTY error on special files
Currently we silently ignore getversion requests for anything except
file or directory. Let's instead return ENOTTY error to indicate that
getversion is not supported. It makes implementation consistent on
all not-supported cases.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
2014-02-02 22:09:04 +05:30
Kirill A. Shutemov
b9317661d1 hw/9pfs: handle undefined FS_IOC_GETVERSION case in handle_ioc_getversion()
All get_st_gen() implementations except handle_ioc_getversion() have
guard for undefined FS_IOC_GETVERSION. Let's add it there too.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
2014-02-02 22:08:54 +05:30
Kirill A. Shutemov
0e5fc994d2 hw/9pfs: fix error handing in local_ioc_getversion()
v9fs_co_st_gen() expects to see error code in errno, not in return code.

Let's fix this.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
2014-02-02 22:08:41 +05:30
Fam Zheng
b76afd1072 tests/.gitignore: Ignore tests/check-qom-interface
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-01 13:56:31 +04:00
Stefan Weil
5eaac2f828 hw/ppc: Remove unused defines
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-01 13:47:35 +04:00
Stefan Weil
d5d1507b34 readline: Add missing GCC_FMT_ATTR
This fixes a compiler warning with -Werror=missing-format-attribute
and allows improved compiler checks for variable argument lists.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-01 13:46:06 +04:00
Richard Henderson
c6830cdb2c tcg/s390: Remove sigill_handler
Commit c9baa30f42 failed to
delete all of the relevant code, leading to Werrors about
unused symbols.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-01 13:45:20 +04:00
Stefan Weil
c428c5a21c i386: Add missing include file for QEMU_PACKED
Instead of packing BiosLinkerLoaderEntry, an unused global variable called
QEMU_PACKED was created (detected by smatch static code analysis).

Including qemu-common.h gets the right definition and also includes some
standard include files which now can be removed here.

Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-01 13:43:52 +04:00
Stefan Hajnoczi
1165ae613d osdep: drop unused #include "trace.h"
osdep.c does not use trace_*() so we can just drop the include.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-01 13:42:38 +04:00
Martin Husemann
dc9a353cf7 qemu 1.7.0 does not build on NetBSD
Do not rely on int8_t (and friends) not being preprocessor
 symbols (or symbols expanding to themselves). On NetBSD (for example) the
 glue(u, SDATA_TYPE) results in u__int8_t, which is undefined. There is no way
 to stop cpp expanding inner macros, so just add the few lines explicitly and
 get rid of the magic.

Signed-off-by: Martin Husemann <martin@NetBSD.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-02-01 13:42:38 +04:00
Stefan Hajnoczi
1b7650ef2f qemu-iotests: only run 071 on qcow2
The 071 test is designed for IMGFMT=qcow2 because it uses the l2_load
blkdebug event.  Its output filtering also assumes that IMGFMT is not
raw since 071.out contains "format=raw" but IMGFMT=raw would filter the
output to "format=IMGFMT".

Perhaps the test case can be rewritten to be more generic, but for now
let's document that it was only supposed to work with qcow2.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-01-31 22:05:03 +01:00
Markus Armbruster
170a60345e dataplane: Comment fix
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-01-31 22:05:03 +01:00
Markus Armbruster
f50159fa9b block/vhdx: Error checking fixes
Errors are inadvertently ignored in a few places.  Has always been
broken.  Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-01-31 22:05:03 +01:00
Fam Zheng
fb0a078f3a qemu-iotests: Drop assert_no_active_commit in case 040
It is exactly assert_no_active_block_jobs in iotests.py

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-01-31 22:05:03 +01:00
Peter Lieven
f43aa8e18a block/vmdk: add basic .bdrv_check support
this adds a basic vmdk corruption check. it should detect severe
table corruptions and file truncation.

Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-01-31 22:05:03 +01:00
Jeff Cody
14b4a8b9c6 block: remove qcow2 .bdrv_make_empty implementation
The QCOW2 .bdrv_make_empty implementation always returns 0 for success,
but does not actually do anything.

The proper way to not support an optional driver function stub is to
just not implement it, so let's remove the stub.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-01-31 22:05:03 +01:00
Jeff Cody
55aff7f133 block: remove QED .bdrv_make_empty implementation
The QED .bdrv_make_empty() implementation does nothing but return
-ENOTSUP, which causes problems in bdrv_commit().  Since the function
stub exists for QED, it is called, which then always returns an error.

The proper way to not support an optional driver function stub is to
just not implement it, so let's remove the stub.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-01-31 22:05:03 +01:00
Daniel P. Berrange
136cd19d05 Describe flaws in qcow/qcow2 encryption in the docs
The qemu-img.texi / qemu-doc.texi files currently describe the
qcow2/qcow2 encryption thus

  "Encryption uses the AES format which is very secure (128 bit
   keys). Use a long password (16 characters) to get maximum
   protection."

While AES is indeed a strong encryption system, the way that
QCow/QCow2 use it results in a poor/weak encryption system.
Due to the use of predictable IVs, based on the sector number
extended to 128 bits, it is vulnerable to chosen plaintext
attacks which can reveal the existence of encrypted data.

The direct use of the user passphrase as the encryption key
also leads to an inability to change the passphrase of an
image. If passphrase is ever compromised the image data will
all be vulnerable, since it cannot be re-encrypted. The admin
has to clone the image files with a new passphrase and then
use a program like shred to secure erase all the old files.

Recommend against any use of QCow/QCow2 encryption, directing
users to dm-crypt / LUKS which can meet modern cryptography
best practices.

[Changed "Qcow" to "qcow" for consistency.
--Stefan]

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-01-31 22:05:03 +01:00
Dominik Dingel
44c68de044 s390x/kvm: cleanup partial register handling
The partial register handling (introduced with commits
420840e58b and
3474b67948 ) aimed to improve intercept
handling performance.

It made the code more complicated though. During development for life
migration/init/reset etc it turned out that this might cause several
hard to debug programming errors. With the introduction of ioeventfd
(and future irqfd patches) the qemu intercept handlers are no longer
hot-path. And therefore the partial register handling can be
removed to simplify the code.

Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
CC: Jason J. Herne <jjherne@us.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Alexander Graf <agraf@suse.de>
2014-01-31 09:43:44 +01:00
Matthew Rosato
234eef51a1 sclp-s390: Define new SCLP codes and structures
Define new SCLP codes and structures that will be needed for
s390 memory hotplug.

Signed-off-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-01-28 12:22:33 +01:00
Jason J. Herne
492044581c s390-sclp: SCLP Event integration
Add an sclp event for "cpu was hot plugged".  This allows Qemu to deliver an
SCLP interrupt to the guest stating that the requested cpu hotplug was
completed.

Signed-off-by: Jason J. Herne <jjherne@us.ibm.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-01-21 16:48:39 +01:00
Jason J. Herne
8cc3aecf84 s390-sclp: SCLP CPU Info
Implement the CPU data in SCLP "Read SCP Info".  And implement "Read CPU Info"
SCLP command. This data will be used by the guest to get information about hot
plugged cpus.

Signed-off-by: Jason J. Herne <jjherne@us.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-01-21 16:20:57 +01:00
Jason J. Herne
5f04c14a10 s390-sclp: Define New SCLP Codes
Define new SCLP codes to improve code readability.

Signed-off-by: Jason J. Herne <jjherne@us.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
2014-01-21 16:20:54 +01:00
Mark Cave-Ayland
fbb9c590ca Update OpenBIOS images
Update OpenBIOS images to SVN r1246 built from submodule.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-01-12 07:52:44 +00:00
675 changed files with 28393 additions and 7075 deletions

155
.gitignore vendored
View File

@@ -1,69 +1,74 @@
config-devices.* /config-devices.*
config-all-devices.* /config-all-devices.*
config-all-disas.* /config-all-disas.*
config-host.* /config-host.*
config-target.* /config-target.*
config.status /config.status
trace/generated-tracers.h /trace/generated-tracers.h
trace/generated-tracers.c /trace/generated-tracers.c
trace/generated-tracers-dtrace.h /trace/generated-tracers-dtrace.h
trace/generated-tracers.dtrace /trace/generated-tracers.dtrace
trace/generated-events.h /trace/generated-events.h
trace/generated-events.c /trace/generated-events.c
libcacard/trace/generated-tracers.c /trace/generated-ust-provider.h
/trace/generated-ust.c
/libcacard/trace/generated-tracers.c
*-timestamp *-timestamp
*-softmmu /*-softmmu
*-darwin-user /*-darwin-user
*-linux-user /*-linux-user
*-bsd-user /*-bsd-user
libdis* libdis*
libuser libuser
linux-headers/asm /linux-headers/asm
qapi-generated /qapi-generated
qapi-types.[ch] /qapi-types.[ch]
qapi-visit.[ch] /qapi-visit.[ch]
qmp-commands.h /qmp-commands.h
qmp-marshal.c /qmp-marshal.c
qemu-doc.html /qemu-doc.html
qemu-tech.html /qemu-tech.html
qemu-doc.info /qemu-doc.info
qemu-tech.info /qemu-tech.info
qemu.1 /qemu.1
qemu.pod /qemu.pod
qemu-img.1 /qemu-img.1
qemu-img.pod /qemu-img.pod
qemu-img /qemu-img
qemu-nbd /qemu-nbd
qemu-nbd.8 /qemu-nbd.8
qemu-nbd.pod /qemu-nbd.pod
qemu-options.def /qemu-options.def
qemu-options.texi /qemu-options.texi
qemu-img-cmds.texi /qemu-img-cmds.texi
qemu-img-cmds.h /qemu-img-cmds.h
qemu-io /qemu-io
qemu-ga /qemu-ga
qemu-bridge-helper /qemu-bridge-helper
qemu-monitor.texi /qemu-monitor.texi
vscclient /qmp-commands.txt
qmp-commands.txt /vscclient
test-bitops /test-bitops
test-coroutine /test-coroutine
test-int128 /test-int128
test-opts-visitor /test-opts-visitor
test-qmp-input-visitor /test-qmp-input-visitor
test-qmp-output-visitor /test-qmp-output-visitor
test-string-input-visitor /test-string-input-visitor
test-string-output-visitor /test-string-output-visitor
test-visitor-serialization /test-visitor-serialization
fsdev/virtfs-proxy-helper /fsdev/virtfs-proxy-helper
fsdev/virtfs-proxy-helper.1 /fsdev/virtfs-proxy-helper.1
fsdev/virtfs-proxy-helper.pod /fsdev/virtfs-proxy-helper.pod
.gdbinit /.gdbinit
*.a *.a
*.aux *.aux
*.cp *.cp
*.dvi *.dvi
*.exe *.exe
*.dll
*.so
*.mo
*.fn *.fn
*.ky *.ky
*.log *.log
@@ -77,7 +82,7 @@ fsdev/virtfs-proxy-helper.pod
*.tp *.tp
*.vr *.vr
*.d *.d
!scripts/qemu-guest-agent/fsfreeze-hook.d !/scripts/qemu-guest-agent/fsfreeze-hook.d
*.o *.o
*.lo *.lo
*.la *.la
@@ -90,22 +95,22 @@ fsdev/virtfs-proxy-helper.pod
*.gcda *.gcda
*.gcno *.gcno
patches patches
pc-bios/bios-pq/status /pc-bios/bios-pq/status
pc-bios/vgabios-pq/status /pc-bios/vgabios-pq/status
pc-bios/optionrom/linuxboot.asm /pc-bios/optionrom/linuxboot.asm
pc-bios/optionrom/linuxboot.bin /pc-bios/optionrom/linuxboot.bin
pc-bios/optionrom/linuxboot.raw /pc-bios/optionrom/linuxboot.raw
pc-bios/optionrom/linuxboot.img /pc-bios/optionrom/linuxboot.img
pc-bios/optionrom/multiboot.asm /pc-bios/optionrom/multiboot.asm
pc-bios/optionrom/multiboot.bin /pc-bios/optionrom/multiboot.bin
pc-bios/optionrom/multiboot.raw /pc-bios/optionrom/multiboot.raw
pc-bios/optionrom/multiboot.img /pc-bios/optionrom/multiboot.img
pc-bios/optionrom/kvmvapic.asm /pc-bios/optionrom/kvmvapic.asm
pc-bios/optionrom/kvmvapic.bin /pc-bios/optionrom/kvmvapic.bin
pc-bios/optionrom/kvmvapic.raw /pc-bios/optionrom/kvmvapic.raw
pc-bios/optionrom/kvmvapic.img /pc-bios/optionrom/kvmvapic.img
pc-bios/s390-ccw/s390-ccw.elf /pc-bios/s390-ccw/s390-ccw.elf
pc-bios/s390-ccw/s390-ccw.img /pc-bios/s390-ccw/s390-ccw.img
.stgit-* .stgit-*
cscope.* cscope.*
tags tags

View File

@@ -726,7 +726,7 @@ F: vl.c
Human Monitor (HMP) Human Monitor (HMP)
M: Luiz Capitulino <lcapitulino@redhat.com> M: Luiz Capitulino <lcapitulino@redhat.com>
S: Supported S: Maintained
F: monitor.c F: monitor.c
F: hmp.c F: hmp.c
F: hmp-commands.hx F: hmp-commands.hx
@@ -758,7 +758,7 @@ T: git git://github.com/bonzini/qemu.git nbd-next
QAPI QAPI
M: Luiz Capitulino <lcapitulino@redhat.com> M: Luiz Capitulino <lcapitulino@redhat.com>
M: Michael Roth <mdroth@linux.vnet.ibm.com> M: Michael Roth <mdroth@linux.vnet.ibm.com>
S: Supported S: Maintained
F: qapi/ F: qapi/
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
@@ -772,7 +772,7 @@ T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
QMP QMP
M: Luiz Capitulino <lcapitulino@redhat.com> M: Luiz Capitulino <lcapitulino@redhat.com>
S: Supported S: Maintained
F: qmp.c F: qmp.c
F: monitor.c F: monitor.c
F: qmp-commands.hx F: qmp-commands.hx
@@ -937,6 +937,11 @@ M: Peter Lieven <pl@kamp.de>
S: Supported S: Supported
F: block/iscsi.c F: block/iscsi.c
NFS
M: Peter Lieven <pl@kamp.de>
S: Maintained
F: block/nfs.c
SSH SSH
M: Richard W.M. Jones <rjones@redhat.com> M: Richard W.M. Jones <rjones@redhat.com>
S: Supported S: Supported

View File

@@ -57,6 +57,11 @@ GENERATED_HEADERS += trace/generated-tracers-dtrace.h
endif endif
GENERATED_SOURCES += trace/generated-tracers.c GENERATED_SOURCES += trace/generated-tracers.c
ifeq ($(TRACE_BACKEND),ust)
GENERATED_HEADERS += trace/generated-ust-provider.h
GENERATED_SOURCES += trace/generated-ust.c
endif
# Don't try to regenerate Makefile or configure # Don't try to regenerate Makefile or configure
# We don't generate any of them # We don't generate any of them
Makefile: ; Makefile: ;
@@ -122,13 +127,29 @@ defconfig:
ifneq ($(wildcard config-host.mak),) ifneq ($(wildcard config-host.mak),)
include $(SRC_PATH)/Makefile.objs include $(SRC_PATH)/Makefile.objs
endif
dummy := $(call unnest-vars,, \
stub-obj-y \
util-obj-y \
qga-obj-y \
block-obj-y \
block-obj-m \
common-obj-y \
common-obj-m)
ifneq ($(wildcard config-host.mak),)
include $(SRC_PATH)/tests/Makefile include $(SRC_PATH)/tests/Makefile
endif endif
ifeq ($(CONFIG_SMARTCARD_NSS),y) ifeq ($(CONFIG_SMARTCARD_NSS),y)
include $(SRC_PATH)/libcacard/Makefile include $(SRC_PATH)/libcacard/Makefile
endif endif
all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
config-host.h: config-host.h-timestamp config-host.h: config-host.h-timestamp
config-host.h-timestamp: config-host.mak config-host.h-timestamp: config-host.mak
@@ -138,6 +159,7 @@ qemu-options.def: $(SRC_PATH)/qemu-options.hx
SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS)) SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES)) SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES))
$(SOFTMMU_SUBDIR_RULES): $(block-obj-y)
$(SOFTMMU_SUBDIR_RULES): config-all-devices.mak $(SOFTMMU_SUBDIR_RULES): config-all-devices.mak
subdir-%: subdir-%:
@@ -187,6 +209,9 @@ Makefile: $(version-obj-y) $(version-lobj-y)
libqemustub.a: $(stub-obj-y) libqemustub.a: $(stub-obj-y)
libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o
block-modules = $(foreach o,$(block-obj-m),"$(basename $(subst /,-,$o))",) NULL
util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)'
###################################################################### ######################################################################
qemu-img.o: qemu-img-cmds.h qemu-img.o: qemu-img-cmds.h
@@ -242,6 +267,8 @@ clean:
rm -f qemu-options.def rm -f qemu-options.def
find . -name '*.[oda]' -type f -exec rm -f {} + find . -name '*.[oda]' -type f -exec rm -f {} +
find . -name '*.l[oa]' -type f -exec rm -f {} + find . -name '*.l[oa]' -type f -exec rm -f {} +
find . -name '*$(DSOSUF)' -type f -exec rm -f {} +
find . -name '*.mo' -type f -exec rm -f {} +
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
rm -f fsdev/*.pod rm -f fsdev/*.pod
rm -rf .libs */.libs rm -rf .libs */.libs
@@ -293,7 +320,7 @@ ifdef INSTALL_BLOBS
BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \ vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
acpi-dsdt.aml q35-acpi-dsdt.aml \ acpi-dsdt.aml q35-acpi-dsdt.aml \
ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin \ ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin QEMU,cgthree.bin \
pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \ pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \ pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \ efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
@@ -349,6 +376,12 @@ install-datadir install-localstatedir
ifneq ($(TOOLS),) ifneq ($(TOOLS),)
$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)" $(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
endif endif
ifneq ($(CONFIG_MODULES),)
$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
for s in $(patsubst %.mo,%$(DSOSUF),$(modules-m)); do \
$(INSTALL_PROG) $(STRIP_OPT) $$s "$(DESTDIR)$(qemu_moddir)/$${s//\//-}"; \
done
endif
ifneq ($(HELPERS-y),) ifneq ($(HELPERS-y),)
$(INSTALL_DIR) "$(DESTDIR)$(libexecdir)" $(INSTALL_DIR) "$(DESTDIR)$(libexecdir)"
$(INSTALL_PROG) $(STRIP_OPT) $(HELPERS-y) "$(DESTDIR)$(libexecdir)" $(INSTALL_PROG) $(STRIP_OPT) $(HELPERS-y) "$(DESTDIR)$(libexecdir)"

View File

@@ -19,6 +19,8 @@ block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
block-obj-y += qemu-coroutine-sleep.o block-obj-y += qemu-coroutine-sleep.o
block-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o block-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
block-obj-m = block/
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy) ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
# Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add. # Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
# only pull in the actual virtio-9p device if we also enabled virtio. # only pull in the actual virtio-9p device if we also enabled virtio.
@@ -41,7 +43,7 @@ libcacard-y += libcacard/vcardt.o
# single QEMU executable should support all CPUs and machines. # single QEMU executable should support all CPUs and machines.
ifeq ($(CONFIG_SOFTMMU),y) ifeq ($(CONFIG_SOFTMMU),y)
common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/ common-obj-y = blockdev.o blockdev-nbd.o block/
common-obj-y += net/ common-obj-y += net/
common-obj-y += qdev-monitor.o device-hotplug.o common-obj-y += qdev-monitor.o device-hotplug.o
common-obj-$(CONFIG_WIN32) += os-win32.o common-obj-$(CONFIG_WIN32) += os-win32.o
@@ -111,18 +113,3 @@ version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo
# by libqemuutil.a. These should be moved to a separate .json schema. # by libqemuutil.a. These should be moved to a separate .json schema.
qga-obj-y = qga/ qapi-types.o qapi-visit.o qga-obj-y = qga/ qapi-types.o qapi-visit.o
qga-vss-dll-obj-y = qga/ qga-vss-dll-obj-y = qga/
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
QEMU_CFLAGS+=$(GLIB_CFLAGS)
nested-vars += \
stub-obj-y \
util-obj-y \
qga-obj-y \
qga-vss-dll-obj-y \
block-obj-y \
common-obj-y
dummy := $(call unnest-vars)

View File

@@ -130,8 +130,6 @@ else
obj-y += hw/$(TARGET_BASE_ARCH)/ obj-y += hw/$(TARGET_BASE_ARCH)/
endif endif
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h
endif # CONFIG_SOFTMMU endif # CONFIG_SOFTMMU
@@ -139,13 +137,26 @@ endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure. # Workaround for http://gcc.gnu.org/PR55489, see configure.
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS) %/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
nested-vars += obj-y dummy := $(call unnest-vars,,obj-y)
# This resolves all nested paths, so it must come last # we are making another call to unnest-vars with different vars, protect obj-y,
# it can be overriden in subdir Makefile.objs
obj-y-save := $(obj-y)
block-obj-y :=
common-obj-y :=
include $(SRC_PATH)/Makefile.objs include $(SRC_PATH)/Makefile.objs
dummy := $(call unnest-vars,.., \
block-obj-y \
block-obj-m \
common-obj-y \
common-obj-m)
all-obj-y = $(obj-y) # Now restore obj-y
all-obj-y += $(addprefix ../, $(common-obj-y)) obj-y := $(obj-y-save)
all-obj-y = $(obj-y) $(common-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
ifndef CONFIG_HAIKU ifndef CONFIG_HAIKU
LIBS+=-lm LIBS+=-lm

View File

@@ -122,7 +122,6 @@ static void check_guest_throttling(void);
#define RAM_SAVE_FLAG_XBZRLE 0x40 #define RAM_SAVE_FLAG_XBZRLE 0x40
/* 0x80 is reserved in migration.h start with 0x100 next */ /* 0x80 is reserved in migration.h start with 0x100 next */
static struct defconfig_file { static struct defconfig_file {
const char *filename; const char *filename;
/* Indicates it is an user config file (disabled by -no-user-config) */ /* Indicates it is an user config file (disabled by -no-user-config) */
@@ -133,6 +132,7 @@ static struct defconfig_file {
{ NULL }, /* end of list */ { NULL }, /* end of list */
}; };
static const uint8_t ZERO_TARGET_PAGE[TARGET_PAGE_SIZE];
int qemu_read_default_config_files(bool userconfig) int qemu_read_default_config_files(bool userconfig)
{ {
@@ -164,20 +164,22 @@ static struct {
uint8_t *encoded_buf; uint8_t *encoded_buf;
/* buffer for storing page content */ /* buffer for storing page content */
uint8_t *current_buf; uint8_t *current_buf;
/* buffer used for XBZRLE decoding */
uint8_t *decoded_buf;
/* Cache for XBZRLE */ /* Cache for XBZRLE */
PageCache *cache; PageCache *cache;
} XBZRLE = { } XBZRLE = {
.encoded_buf = NULL, .encoded_buf = NULL,
.current_buf = NULL, .current_buf = NULL,
.decoded_buf = NULL,
.cache = NULL, .cache = NULL,
}; };
/* buffer used for XBZRLE decoding */
static uint8_t *xbzrle_decoded_buf;
int64_t xbzrle_cache_resize(int64_t new_size) int64_t xbzrle_cache_resize(int64_t new_size)
{ {
if (new_size < TARGET_PAGE_SIZE) {
return -1;
}
if (XBZRLE.cache != NULL) { if (XBZRLE.cache != NULL) {
return cache_resize(XBZRLE.cache, new_size / TARGET_PAGE_SIZE) * return cache_resize(XBZRLE.cache, new_size / TARGET_PAGE_SIZE) *
TARGET_PAGE_SIZE; TARGET_PAGE_SIZE;
@@ -271,6 +273,34 @@ static size_t save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
return size; return size;
} }
/* This is the last block that we have visited serching for dirty pages
*/
static RAMBlock *last_seen_block;
/* This is the last block from where we have sent data */
static RAMBlock *last_sent_block;
static ram_addr_t last_offset;
static unsigned long *migration_bitmap;
static uint64_t migration_dirty_pages;
static uint32_t last_version;
static bool ram_bulk_stage;
/* Update the xbzrle cache to reflect a page that's been sent as all 0.
* The important thing is that a stale (not-yet-0'd) page be replaced
* by the new data.
* As a bonus, if the page wasn't in the cache it gets added so that
* when a small write is made into the 0'd page it gets XBZRLE sent
*/
static void xbzrle_cache_zero_page(ram_addr_t current_addr)
{
if (ram_bulk_stage || !migrate_use_xbzrle()) {
return;
}
/* We don't care if this fails to allocate a new cache page
* as long as it updated an old one */
cache_insert(XBZRLE.cache, current_addr, ZERO_TARGET_PAGE);
}
#define ENCODING_FLAG_XBZRLE 0x1 #define ENCODING_FLAG_XBZRLE 0x1
static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data, static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
@@ -282,7 +312,9 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
if (!cache_is_cached(XBZRLE.cache, current_addr)) { if (!cache_is_cached(XBZRLE.cache, current_addr)) {
if (!last_stage) { if (!last_stage) {
cache_insert(XBZRLE.cache, current_addr, current_data); if (cache_insert(XBZRLE.cache, current_addr, current_data) == -1) {
return -1;
}
} }
acct_info.xbzrle_cache_miss++; acct_info.xbzrle_cache_miss++;
return -1; return -1;
@@ -325,18 +357,6 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
return bytes_sent; return bytes_sent;
} }
/* This is the last block that we have visited serching for dirty pages
*/
static RAMBlock *last_seen_block;
/* This is the last block from where we have sent data */
static RAMBlock *last_sent_block;
static ram_addr_t last_offset;
static unsigned long *migration_bitmap;
static uint64_t migration_dirty_pages;
static uint32_t last_version;
static bool ram_bulk_stage;
static inline static inline
ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr, ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr,
ram_addr_t start) ram_addr_t start)
@@ -508,6 +528,7 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
} else { } else {
int ret; int ret;
uint8_t *p; uint8_t *p;
bool send_async = true;
int cont = (block == last_sent_block) ? int cont = (block == last_sent_block) ?
RAM_SAVE_FLAG_CONTINUE : 0; RAM_SAVE_FLAG_CONTINUE : 0;
@@ -518,6 +539,7 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
ret = ram_control_save_page(f, block->offset, ret = ram_control_save_page(f, block->offset,
offset, TARGET_PAGE_SIZE, &bytes_sent); offset, TARGET_PAGE_SIZE, &bytes_sent);
current_addr = block->offset + offset;
if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { if (ret != RAM_SAVE_CONTROL_NOT_SUPP) {
if (ret != RAM_SAVE_CONTROL_DELAYED) { if (ret != RAM_SAVE_CONTROL_DELAYED) {
if (bytes_sent > 0) { if (bytes_sent > 0) {
@@ -532,19 +554,35 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
RAM_SAVE_FLAG_COMPRESS); RAM_SAVE_FLAG_COMPRESS);
qemu_put_byte(f, 0); qemu_put_byte(f, 0);
bytes_sent++; 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()) { } else if (!ram_bulk_stage && migrate_use_xbzrle()) {
current_addr = block->offset + offset;
bytes_sent = save_xbzrle_page(f, p, current_addr, block, bytes_sent = save_xbzrle_page(f, p, current_addr, block,
offset, cont, last_stage); offset, cont, last_stage);
if (!last_stage) { if (!last_stage) {
/* We must send exactly what's in the xbzrle cache
* even if the page wasn't xbzrle compressed, so that
* it's right next time.
*/
p = get_cached_data(XBZRLE.cache, current_addr); p = get_cached_data(XBZRLE.cache, current_addr);
/* 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 */ /* XBZRLE overflow or normal page */
if (bytes_sent == -1) { if (bytes_sent == -1) {
bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE); bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE); 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; bytes_sent += TARGET_PAGE_SIZE;
acct_info.norm_pages++; acct_info.norm_pages++;
} }
@@ -602,6 +640,12 @@ uint64_t ram_bytes_total(void)
return total; return total;
} }
void free_xbzrle_decoded_buf(void)
{
g_free(xbzrle_decoded_buf);
xbzrle_decoded_buf = NULL;
}
static void migration_end(void) static void migration_end(void)
{ {
if (migration_bitmap) { if (migration_bitmap) {
@@ -615,8 +659,9 @@ static void migration_end(void)
g_free(XBZRLE.cache); g_free(XBZRLE.cache);
g_free(XBZRLE.encoded_buf); g_free(XBZRLE.encoded_buf);
g_free(XBZRLE.current_buf); g_free(XBZRLE.current_buf);
g_free(XBZRLE.decoded_buf);
XBZRLE.cache = NULL; XBZRLE.cache = NULL;
XBZRLE.encoded_buf = NULL;
XBZRLE.current_buf = NULL;
} }
} }
@@ -655,8 +700,22 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
DPRINTF("Error creating cache\n"); DPRINTF("Error creating cache\n");
return -1; return -1;
} }
XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);
XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE); /* We prefer not to abort if there is no memory */
XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);
if (!XBZRLE.encoded_buf) {
DPRINTF("Error allocating encoded_buf\n");
return -1;
}
XBZRLE.current_buf = g_try_malloc(TARGET_PAGE_SIZE);
if (!XBZRLE.current_buf) {
DPRINTF("Error allocating current_buf\n");
g_free(XBZRLE.encoded_buf);
XBZRLE.encoded_buf = NULL;
return -1;
}
acct_clear(); acct_clear();
} }
@@ -807,8 +866,8 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
unsigned int xh_len; unsigned int xh_len;
int xh_flags; int xh_flags;
if (!XBZRLE.decoded_buf) { if (!xbzrle_decoded_buf) {
XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE); xbzrle_decoded_buf = g_malloc(TARGET_PAGE_SIZE);
} }
/* extract RLE header */ /* extract RLE header */
@@ -825,10 +884,10 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
return -1; return -1;
} }
/* load data and decode */ /* load data and decode */
qemu_get_buffer(f, XBZRLE.decoded_buf, xh_len); qemu_get_buffer(f, xbzrle_decoded_buf, xh_len);
/* decode RLE */ /* decode RLE */
ret = xbzrle_decode_buffer(XBZRLE.decoded_buf, xh_len, host, ret = xbzrle_decode_buffer(xbzrle_decoded_buf, xh_len, host,
TARGET_PAGE_SIZE); TARGET_PAGE_SIZE);
if (ret == -1) { if (ret == -1) {
fprintf(stderr, "Failed to load XBZRLE page - decode error!\n"); fprintf(stderr, "Failed to load XBZRLE page - decode error!\n");

View File

@@ -25,8 +25,17 @@
#include "audio.h" #include "audio.h"
#include "audio_int.h" #include "audio_int.h"
#define LINE_IN_SAMPLES 1024 #if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
#define LINE_OUT_SAMPLES 1024 #define LINE_OUT_SAMPLES (480 * 4)
#else
#define LINE_OUT_SAMPLES (256 * 4)
#endif
#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
#define LINE_IN_SAMPLES (480 * 4)
#else
#define LINE_IN_SAMPLES (256 * 4)
#endif
typedef struct SpiceRateCtl { typedef struct SpiceRateCtl {
int64_t start_ticks; int64_t start_ticks;
@@ -111,7 +120,11 @@ static int line_out_init (HWVoiceOut *hw, struct audsettings *as)
SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
struct audsettings settings; struct audsettings settings;
#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
settings.freq = spice_server_get_best_playback_rate(NULL);
#else
settings.freq = SPICE_INTERFACE_PLAYBACK_FREQ; settings.freq = SPICE_INTERFACE_PLAYBACK_FREQ;
#endif
settings.nchannels = SPICE_INTERFACE_PLAYBACK_CHAN; settings.nchannels = SPICE_INTERFACE_PLAYBACK_CHAN;
settings.fmt = AUD_FMT_S16; settings.fmt = AUD_FMT_S16;
settings.endianness = AUDIO_HOST_ENDIANNESS; settings.endianness = AUDIO_HOST_ENDIANNESS;
@@ -122,6 +135,9 @@ static int line_out_init (HWVoiceOut *hw, struct audsettings *as)
out->sin.base.sif = &playback_sif.base; out->sin.base.sif = &playback_sif.base;
qemu_spice_add_interface (&out->sin.base); qemu_spice_add_interface (&out->sin.base);
#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
spice_server_set_playback_rate(&out->sin, settings.freq);
#endif
return 0; return 0;
} }
@@ -232,7 +248,11 @@ static int line_in_init (HWVoiceIn *hw, struct audsettings *as)
SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
struct audsettings settings; struct audsettings settings;
#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
settings.freq = spice_server_get_best_record_rate(NULL);
#else
settings.freq = SPICE_INTERFACE_RECORD_FREQ; settings.freq = SPICE_INTERFACE_RECORD_FREQ;
#endif
settings.nchannels = SPICE_INTERFACE_RECORD_CHAN; settings.nchannels = SPICE_INTERFACE_RECORD_CHAN;
settings.fmt = AUD_FMT_S16; settings.fmt = AUD_FMT_S16;
settings.endianness = AUDIO_HOST_ENDIANNESS; settings.endianness = AUDIO_HOST_ENDIANNESS;
@@ -243,6 +263,9 @@ static int line_in_init (HWVoiceIn *hw, struct audsettings *as)
in->sin.base.sif = &record_sif.base; in->sin.base.sif = &record_sif.base;
qemu_spice_add_interface (&in->sin.base); qemu_spice_add_interface (&in->sin.base);
#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
spice_server_set_record_rate(&in->sin, settings.freq);
#endif
return 0; return 0;
} }

View File

@@ -566,7 +566,7 @@ CharDriverState *chr_baum_init(void)
BaumDriverState *baum; BaumDriverState *baum;
CharDriverState *chr; CharDriverState *chr;
brlapi_handle_t *handle; brlapi_handle_t *handle;
#ifdef CONFIG_SDL #if defined(CONFIG_SDL) && SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
SDL_SysWMinfo info; SDL_SysWMinfo info;
#endif #endif
int tty; int tty;
@@ -595,7 +595,7 @@ CharDriverState *chr_baum_init(void)
goto fail; goto fail;
} }
#ifdef CONFIG_SDL #if defined(CONFIG_SDL) && SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
SDL_VERSION(&info.version); SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info)) if (SDL_GetWMInfo(&info))

314
block.c
View File

@@ -421,7 +421,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
assert(cco->drv); assert(cco->drv);
ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err); ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(&cco->err, local_err); error_propagate(&cco->err, local_err);
} }
cco->ret = ret; cco->ret = ret;
@@ -460,7 +460,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
ret = cco.ret; ret = cco.ret;
if (ret < 0) { if (ret < 0) {
if (error_is_set(&cco.err)) { if (cco.err) {
error_propagate(errp, cco.err); error_propagate(errp, cco.err);
} else { } else {
error_setg_errno(errp, -ret, "Could not create image"); error_setg_errno(errp, -ret, "Could not create image");
@@ -486,7 +486,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
} }
ret = bdrv_create(drv, filename, options, &local_err); ret = bdrv_create(drv, filename, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
@@ -547,8 +547,9 @@ int get_tmp_filename(char *filename, int size)
int fd; int fd;
const char *tmpdir; const char *tmpdir;
tmpdir = getenv("TMPDIR"); tmpdir = getenv("TMPDIR");
if (!tmpdir) if (!tmpdir) {
tmpdir = "/tmp"; tmpdir = "/var/tmp";
}
if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) { if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) {
return -EOVERFLOW; return -EOVERFLOW;
} }
@@ -796,6 +797,13 @@ static int bdrv_assign_node_name(BlockDriverState *bs,
return -EINVAL; return -EINVAL;
} }
/* takes care of avoiding namespaces collisions */
if (bdrv_find(node_name)) {
error_setg(errp, "node-name=%s is conflicting with a device id",
node_name);
return -EINVAL;
}
/* takes care of avoiding duplicates node names */ /* takes care of avoiding duplicates node names */
if (bdrv_find_node(node_name)) { if (bdrv_find_node(node_name)) {
error_setg(errp, "Duplicate node name"); error_setg(errp, "Duplicate node name");
@@ -832,6 +840,12 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
filename = qdict_get_try_str(options, "filename"); filename = qdict_get_try_str(options, "filename");
} }
if (drv->bdrv_needs_filename && !filename) {
error_setg(errp, "The '%s' block driver requires a file name",
drv->format_name);
return -EINVAL;
}
trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name); trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name);
node_name = qdict_get_try_str(options, "node-name"); node_name = qdict_get_try_str(options, "node-name");
@@ -903,7 +917,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
} }
if (ret < 0) { if (ret < 0) {
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} else if (bs->filename[0]) { } else if (bs->filename[0]) {
error_setg_errno(errp, -ret, "Could not open '%s'", bs->filename); error_setg_errno(errp, -ret, "Could not open '%s'", bs->filename);
@@ -942,54 +956,27 @@ free_and_fail:
/* /*
* Opens a file using a protocol (file, host_device, nbd, ...) * Opens a file using a protocol (file, host_device, nbd, ...)
* *
* options is a QDict of options to pass to the block drivers, or NULL for an * options is an indirect pointer to a QDict of options to pass to the block
* empty set of options. The reference to the QDict belongs to the block layer * drivers, or pointer to NULL for an empty set of options. If this function
* after the call (even on failure), so if the caller intends to reuse the * takes ownership of the QDict reference, it will set *options to NULL;
* dictionary, it needs to use QINCREF() before calling bdrv_file_open. * otherwise, it will contain unused/unrecognized options after this function
* returns. Then, the caller is responsible for freeing it. If it intends to
* reuse the QDict, QINCREF() should be called beforehand.
*/ */
int bdrv_file_open(BlockDriverState **pbs, const char *filename, static int bdrv_file_open(BlockDriverState *bs, const char *filename,
const char *reference, QDict *options, int flags, QDict **options, int flags, Error **errp)
Error **errp)
{ {
BlockDriverState *bs = NULL;
BlockDriver *drv; BlockDriver *drv;
const char *drvname; const char *drvname;
bool allow_protocol_prefix = false; bool allow_protocol_prefix = false;
Error *local_err = NULL; Error *local_err = NULL;
int ret; int ret;
/* NULL means an empty set of options */
if (options == NULL) {
options = qdict_new();
}
if (reference) {
if (filename || qdict_size(options)) {
error_setg(errp, "Cannot reference an existing block device with "
"additional options or a new filename");
return -EINVAL;
}
QDECREF(options);
bs = bdrv_find(reference);
if (!bs) {
error_setg(errp, "Cannot find block device '%s'", reference);
return -ENODEV;
}
bdrv_ref(bs);
*pbs = bs;
return 0;
}
bs = bdrv_new("");
bs->options = options;
options = qdict_clone_shallow(options);
/* Fetch the file name from the options QDict if necessary */ /* Fetch the file name from the options QDict if necessary */
if (!filename) { if (!filename) {
filename = qdict_get_try_str(options, "filename"); filename = qdict_get_try_str(*options, "filename");
} else if (filename && !qdict_haskey(options, "filename")) { } else if (filename && !qdict_haskey(*options, "filename")) {
qdict_put(options, "filename", qstring_from_str(filename)); qdict_put(*options, "filename", qstring_from_str(filename));
allow_protocol_prefix = true; allow_protocol_prefix = true;
} else { } else {
error_setg(errp, "Can't specify 'file' and 'filename' options at the " error_setg(errp, "Can't specify 'file' and 'filename' options at the "
@@ -999,13 +986,13 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
} }
/* Find the right block driver */ /* Find the right block driver */
drvname = qdict_get_try_str(options, "driver"); drvname = qdict_get_try_str(*options, "driver");
if (drvname) { if (drvname) {
drv = bdrv_find_format(drvname); drv = bdrv_find_format(drvname);
if (!drv) { if (!drv) {
error_setg(errp, "Unknown driver '%s'", drvname); error_setg(errp, "Unknown driver '%s'", drvname);
} }
qdict_del(options, "driver"); qdict_del(*options, "driver");
} else if (filename) { } else if (filename) {
drv = bdrv_find_protocol(filename, allow_protocol_prefix); drv = bdrv_find_protocol(filename, allow_protocol_prefix);
if (!drv) { if (!drv) {
@@ -1024,51 +1011,30 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
/* Parse the filename and open it */ /* Parse the filename and open it */
if (drv->bdrv_parse_filename && filename) { if (drv->bdrv_parse_filename && filename) {
drv->bdrv_parse_filename(filename, options, &local_err); drv->bdrv_parse_filename(filename, *options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
qdict_del(options, "filename"); qdict_del(*options, "filename");
} else if (drv->bdrv_needs_filename && !filename) {
error_setg(errp, "The '%s' block driver requires a file name",
drv->format_name);
ret = -EINVAL;
goto fail;
} }
if (!drv->bdrv_file_open) { if (!drv->bdrv_file_open) {
ret = bdrv_open(bs, filename, options, flags, drv, &local_err); ret = bdrv_open(&bs, filename, NULL, *options, flags, drv, &local_err);
options = NULL; *options = NULL;
} else { } else {
ret = bdrv_open_common(bs, NULL, options, flags, drv, &local_err); ret = bdrv_open_common(bs, NULL, *options, flags, drv, &local_err);
} }
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto fail; goto fail;
} }
/* Check if any unknown options were used */
if (options && (qdict_size(options) != 0)) {
const QDictEntry *entry = qdict_first(options);
error_setg(errp, "Block protocol '%s' doesn't support the option '%s'",
drv->format_name, entry->key);
ret = -EINVAL;
goto fail;
}
QDECREF(options);
bs->growable = 1; bs->growable = 1;
*pbs = bs;
return 0; return 0;
fail: fail:
QDECREF(options);
if (!bs->drv) {
QDECREF(bs->options);
}
bdrv_unref(bs);
return ret; return ret;
} }
@@ -1108,8 +1074,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
sizeof(backing_filename)); sizeof(backing_filename));
} }
bs->backing_hd = bdrv_new("");
if (bs->backing_format[0] != '\0') { if (bs->backing_format[0] != '\0') {
back_drv = bdrv_find_format(bs->backing_format); back_drv = bdrv_find_format(bs->backing_format);
} }
@@ -1118,11 +1082,11 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT |
BDRV_O_COPY_ON_READ); BDRV_O_COPY_ON_READ);
ret = bdrv_open(bs->backing_hd, assert(bs->backing_hd == NULL);
*backing_filename ? backing_filename : NULL, options, ret = bdrv_open(&bs->backing_hd,
*backing_filename ? backing_filename : NULL, NULL, options,
back_flags, back_drv, &local_err); back_flags, back_drv, &local_err);
if (ret < 0) { if (ret < 0) {
bdrv_unref(bs->backing_hd);
bs->backing_hd = NULL; bs->backing_hd = NULL;
bs->open_flags |= BDRV_O_NO_BACKING; bs->open_flags |= BDRV_O_NO_BACKING;
error_setg(errp, "Could not open backing file: %s", error_setg(errp, "Could not open backing file: %s",
@@ -1146,10 +1110,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
* Opens a disk image whose options are given as BlockdevRef in another block * Opens a disk image whose options are given as BlockdevRef in another block
* device's options. * device's options.
* *
* If force_raw is true, bdrv_file_open() will be used, thereby preventing any
* image format auto-detection. If it is false and a filename is given,
* bdrv_open() will be used for auto-detection.
*
* If allow_none is true, no image will be opened if filename is false and no * If allow_none is true, no image will be opened if filename is false and no
* BlockdevRef is given. *pbs will remain unchanged and 0 will be returned. * BlockdevRef is given. *pbs will remain unchanged and 0 will be returned.
* *
@@ -1159,16 +1119,21 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
* BlockdevRef. * BlockdevRef.
* *
* The BlockdevRef will be removed from the options QDict. * The BlockdevRef will be removed from the options QDict.
*
* To conform with the behavior of bdrv_open(), *pbs has to be NULL.
*/ */
int bdrv_open_image(BlockDriverState **pbs, const char *filename, int bdrv_open_image(BlockDriverState **pbs, const char *filename,
QDict *options, const char *bdref_key, int flags, QDict *options, const char *bdref_key, int flags,
bool force_raw, bool allow_none, Error **errp) bool allow_none, Error **errp)
{ {
QDict *image_options; QDict *image_options;
int ret; int ret;
char *bdref_key_dot; char *bdref_key_dot;
const char *reference; const char *reference;
assert(pbs);
assert(*pbs == NULL);
bdref_key_dot = g_strdup_printf("%s.", bdref_key); bdref_key_dot = g_strdup_printf("%s.", bdref_key);
qdict_extract_subqdict(options, &image_options, bdref_key_dot); qdict_extract_subqdict(options, &image_options, bdref_key_dot);
g_free(bdref_key_dot); g_free(bdref_key_dot);
@@ -1185,30 +1150,7 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename,
goto done; goto done;
} }
if (filename && !force_raw) { ret = bdrv_open(pbs, filename, reference, image_options, flags, NULL, errp);
/* If a filename is given and the block driver should be detected
automatically (instead of using none), use bdrv_open() in order to do
that auto-detection. */
BlockDriverState *bs;
if (reference) {
error_setg(errp, "Cannot reference an existing block device while "
"giving a filename");
ret = -EINVAL;
goto done;
}
bs = bdrv_new("");
ret = bdrv_open(bs, filename, image_options, flags, NULL, errp);
if (ret < 0) {
bdrv_unref(bs);
} else {
*pbs = bs;
}
} else {
ret = bdrv_file_open(pbs, filename, reference, image_options, flags,
errp);
}
done: done:
qdict_del(options, bdref_key); qdict_del(options, bdref_key);
@@ -1222,17 +1164,58 @@ done:
* empty set of options. The reference to the QDict belongs to the block layer * empty set of options. The reference to the QDict belongs to the block layer
* after the call (even on failure), so if the caller intends to reuse the * after the call (even on failure), so if the caller intends to reuse the
* dictionary, it needs to use QINCREF() before calling bdrv_open. * dictionary, it needs to use QINCREF() before calling bdrv_open.
*
* If *pbs is NULL, a new BDS will be created with a pointer to it stored there.
* If it is not NULL, the referenced BDS will be reused.
*
* The reference parameter may be used to specify an existing block device which
* should be opened. If specified, neither options nor a filename may be given,
* nor can an existing BDS be reused (that is, *pbs has to be NULL).
*/ */
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, int bdrv_open(BlockDriverState **pbs, const char *filename,
int flags, BlockDriver *drv, Error **errp) const char *reference, QDict *options, int flags,
BlockDriver *drv, Error **errp)
{ {
int ret; int ret;
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
char tmp_filename[PATH_MAX + 1]; char tmp_filename[PATH_MAX + 1];
BlockDriverState *file = NULL; BlockDriverState *file = NULL, *bs;
const char *drvname; const char *drvname;
Error *local_err = NULL; Error *local_err = NULL;
assert(pbs);
if (reference) {
bool options_non_empty = options ? qdict_size(options) : false;
QDECREF(options);
if (*pbs) {
error_setg(errp, "Cannot reuse an existing BDS when referencing "
"another block device");
return -EINVAL;
}
if (filename || options_non_empty) {
error_setg(errp, "Cannot reference an existing block device with "
"additional options or a new filename");
return -EINVAL;
}
bs = bdrv_lookup_bs(reference, reference, errp);
if (!bs) {
return -ENODEV;
}
bdrv_ref(bs);
*pbs = bs;
return 0;
}
if (*pbs) {
bs = *pbs;
} else {
bs = bdrv_new("");
}
/* NULL means an empty set of options */ /* NULL means an empty set of options */
if (options == NULL) { if (options == NULL) {
options = qdict_new(); options = qdict_new();
@@ -1241,6 +1224,19 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
bs->options = options; bs->options = options;
options = qdict_clone_shallow(options); options = qdict_clone_shallow(options);
if (flags & BDRV_O_PROTOCOL) {
assert(!drv);
ret = bdrv_file_open(bs, filename, &options, flags & ~BDRV_O_PROTOCOL,
&local_err);
if (!ret) {
goto done;
} else if (bs->drv) {
goto close_and_fail;
} else {
goto fail;
}
}
/* For snapshot=on, create a temporary qcow2 overlay */ /* For snapshot=on, create a temporary qcow2 overlay */
if (flags & BDRV_O_SNAPSHOT) { if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1; BlockDriverState *bs1;
@@ -1253,12 +1249,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
instead of opening 'filename' directly */ instead of opening 'filename' directly */
/* Get the required size from the image */ /* Get the required size from the image */
bs1 = bdrv_new("");
QINCREF(options); QINCREF(options);
ret = bdrv_open(bs1, filename, options, BDRV_O_NO_BACKING, bs1 = NULL;
ret = bdrv_open(&bs1, filename, NULL, options, BDRV_O_NO_BACKING,
drv, &local_err); drv, &local_err);
if (ret < 0) { if (ret < 0) {
bdrv_unref(bs1);
goto fail; goto fail;
} }
total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK; total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
@@ -1315,9 +1310,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
flags |= BDRV_O_ALLOW_RDWR; flags |= BDRV_O_ALLOW_RDWR;
} }
assert(file == NULL);
ret = bdrv_open_image(&file, filename, options, "file", ret = bdrv_open_image(&file, filename, options, "file",
bdrv_open_flags(bs, flags | BDRV_O_UNMAP), true, true, bdrv_open_flags(bs, flags | BDRV_O_UNMAP) |
&local_err); BDRV_O_PROTOCOL, true, &local_err);
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;
} }
@@ -1370,12 +1366,18 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
} }
} }
done:
/* Check if any unknown options were used */ /* Check if any unknown options were used */
if (qdict_size(options) != 0) { if (options && (qdict_size(options) != 0)) {
const QDictEntry *entry = qdict_first(options); const QDictEntry *entry = qdict_first(options);
error_setg(errp, "Block format '%s' used by device '%s' doesn't " if (flags & BDRV_O_PROTOCOL) {
"support the option '%s'", drv->format_name, bs->device_name, error_setg(errp, "Block protocol '%s' doesn't support the option "
entry->key); "'%s'", drv->format_name, entry->key);
} else {
error_setg(errp, "Block format '%s' used by device '%s' doesn't "
"support the option '%s'", drv->format_name,
bs->device_name, entry->key);
}
ret = -EINVAL; ret = -EINVAL;
goto close_and_fail; goto close_and_fail;
@@ -1386,6 +1388,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
bdrv_dev_change_media_cb(bs, true); bdrv_dev_change_media_cb(bs, true);
} }
*pbs = bs;
return 0; return 0;
unlink_and_fail: unlink_and_fail:
@@ -1399,15 +1402,26 @@ fail:
QDECREF(bs->options); QDECREF(bs->options);
QDECREF(options); QDECREF(options);
bs->options = NULL; bs->options = NULL;
if (error_is_set(&local_err)) { if (!*pbs) {
/* If *pbs is NULL, a new BDS has been created in this function and
needs to be freed now. Otherwise, it does not need to be closed,
since it has not really been opened yet. */
bdrv_unref(bs);
}
if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
close_and_fail: close_and_fail:
bdrv_close(bs); /* See fail path, but now the BDS has to be always closed */
if (*pbs) {
bdrv_close(bs);
} else {
bdrv_unref(bs);
}
QDECREF(options); QDECREF(options);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
@@ -2239,11 +2253,11 @@ static void tracked_request_begin(BdrvTrackedRequest *req,
QLIST_INSERT_HEAD(&bs->tracked_requests, req, list); QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
} }
static void mark_request_serialising(BdrvTrackedRequest *req, size_t align) static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
{ {
int64_t overlap_offset = req->offset & ~(align - 1); int64_t overlap_offset = req->offset & ~(align - 1);
int overlap_bytes = ROUND_UP(req->offset + req->bytes, align) unsigned int overlap_bytes = ROUND_UP(req->offset + req->bytes, align)
- overlap_offset; - overlap_offset;
if (!req->serialising) { if (!req->serialising) {
req->bs->serialising_in_flight++; req->bs->serialising_in_flight++;
@@ -2914,8 +2928,8 @@ static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs,
} }
total_sectors = DIV_ROUND_UP(len, BDRV_SECTOR_SIZE); total_sectors = DIV_ROUND_UP(len, BDRV_SECTOR_SIZE);
max_nb_sectors = MAX(0, ROUND_UP(total_sectors - sector_num, max_nb_sectors = ROUND_UP(MAX(0, total_sectors - sector_num),
align >> BDRV_SECTOR_BITS)); align >> BDRV_SECTOR_BITS);
if (max_nb_sectors > 0) { if (max_nb_sectors > 0) {
ret = drv->bdrv_co_readv(bs, sector_num, ret = drv->bdrv_co_readv(bs, sector_num,
MIN(nb_sectors, max_nb_sectors), qiov); MIN(nb_sectors, max_nb_sectors), qiov);
@@ -3133,6 +3147,8 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
waited = wait_serialising_requests(req); waited = wait_serialising_requests(req);
assert(!waited || !req->serialising); assert(!waited || !req->serialising);
assert(req->overlap_offset <= offset);
assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req); ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
@@ -3278,9 +3294,9 @@ fail:
if (use_local_qiov) { if (use_local_qiov) {
qemu_iovec_destroy(&local_qiov); qemu_iovec_destroy(&local_qiov);
qemu_vfree(head_buf);
qemu_vfree(tail_buf);
} }
qemu_vfree(head_buf);
qemu_vfree(tail_buf);
return ret; return ret;
} }
@@ -3571,30 +3587,26 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
{ {
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
if ((!device && !node_name) || (device && node_name)) {
error_setg(errp, "Use either device or node-name but not both");
return NULL;
}
if (device) { if (device) {
bs = bdrv_find(device); bs = bdrv_find(device);
if (!bs) { if (bs) {
error_set(errp, QERR_DEVICE_NOT_FOUND, device); return bs;
return NULL;
} }
return bs;
} }
bs = bdrv_find_node(node_name); if (node_name) {
bs = bdrv_find_node(node_name);
if (!bs) { if (bs) {
error_set(errp, QERR_DEVICE_NOT_FOUND, node_name); return bs;
return NULL; }
} }
return bs; error_setg(errp, "Cannot find device=%s nor node_name=%s",
device ? device : "",
node_name ? node_name : "");
return NULL;
} }
BlockDriverState *bdrv_next(BlockDriverState *bs) BlockDriverState *bdrv_next(BlockDriverState *bs)
@@ -5285,9 +5297,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
back_flags = back_flags =
flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
bs = bdrv_new(""); bs = NULL;
ret = bdrv_open(&bs, backing_file->value.s, NULL, NULL, back_flags,
ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
backing_drv, &local_err); backing_drv, &local_err);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not open '%s': %s", error_setg_errno(errp, -ret, "Could not open '%s': %s",
@@ -5295,7 +5306,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
error_get_pretty(local_err)); error_get_pretty(local_err));
error_free(local_err); error_free(local_err);
local_err = NULL; local_err = NULL;
bdrv_unref(bs);
goto out; goto out;
} }
bdrv_get_geometry(bs, &size); bdrv_get_geometry(bs, &size);
@@ -5335,7 +5345,7 @@ out:
free_option_parameters(create_options); free_option_parameters(create_options);
free_option_parameters(param); free_option_parameters(param);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
} }
@@ -5411,11 +5421,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate)
QTAILQ_FOREACH(bs, &bdrv_states, device_list) { QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
bool perm; bool perm;
if (!bs->file) { perm = bdrv_recurse_is_first_non_filter(bs, candidate);
continue;
}
perm = bdrv_recurse_is_first_non_filter(bs->file, candidate);
/* candidate is the first non filter */ /* candidate is the first non filter */
if (perm) { if (perm) {

View File

@@ -3,6 +3,7 @@ block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-c
block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o block-obj-y += qed-check.o
block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
block-obj-$(CONFIG_QUORUM) += quorum.o
block-obj-y += parallels.o blkdebug.o blkverify.o block-obj-y += parallels.o blkdebug.o blkverify.o
block-obj-y += snapshot.o qapi.o block-obj-y += snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
@@ -12,6 +13,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
ifeq ($(CONFIG_POSIX),y) ifeq ($(CONFIG_POSIX),y)
block-obj-y += nbd.o nbd-client.o sheepdog.o block-obj-y += nbd.o nbd-client.o sheepdog.o
block-obj-$(CONFIG_LIBISCSI) += iscsi.o block-obj-$(CONFIG_LIBISCSI) += iscsi.o
block-obj-$(CONFIG_LIBNFS) += nfs.o
block-obj-$(CONFIG_CURL) += curl.o block-obj-$(CONFIG_CURL) += curl.o
block-obj-$(CONFIG_RBD) += rbd.o block-obj-$(CONFIG_RBD) += rbd.o
block-obj-$(CONFIG_GLUSTERFS) += gluster.o block-obj-$(CONFIG_GLUSTERFS) += gluster.o
@@ -23,4 +25,15 @@ common-obj-y += commit.o
common-obj-y += mirror.o common-obj-y += mirror.o
common-obj-y += backup.o common-obj-y += backup.o
$(obj)/curl.o: QEMU_CFLAGS+=$(CURL_CFLAGS) iscsi.o-cflags := $(LIBISCSI_CFLAGS)
iscsi.o-libs := $(LIBISCSI_LIBS)
curl.o-cflags := $(CURL_CFLAGS)
curl.o-libs := $(CURL_LIBS)
rbd.o-cflags := $(RBD_CFLAGS)
rbd.o-libs := $(RBD_LIBS)
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
gluster.o-libs := $(GLUSTERFS_LIBS)
ssh.o-cflags := $(LIBSSH2_CFLAGS)
ssh.o-libs := $(LIBSSH2_LIBS)
qcow.o-libs := -lz
linux-aio.o-libs := -laio

View File

@@ -303,7 +303,7 @@ static int read_config(BDRVBlkdebugState *s, const char *filename,
} }
qemu_config_parse_qdict(options, config_groups, &local_err); qemu_config_parse_qdict(options, config_groups, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
@@ -393,28 +393,29 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto out;
} }
/* Read rules from config file or command line options */ /* Read rules from config file or command line options */
config = qemu_opt_get(opts, "config"); config = qemu_opt_get(opts, "config");
ret = read_config(s, config, options, errp); ret = read_config(s, config, options, errp);
if (ret) { if (ret) {
goto fail; goto out;
} }
/* Set initial state */ /* Set initial state */
s->state = 1; s->state = 1;
/* Open the backing file */ /* Open the backing file */
assert(bs->file == NULL);
ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-image"), options, "image", ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-image"), options, "image",
flags, true, false, &local_err); flags | BDRV_O_PROTOCOL, false, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto fail; goto out;
} }
/* Set request alignment */ /* Set request alignment */
@@ -424,11 +425,15 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
} else { } else {
error_setg(errp, "Invalid alignment"); error_setg(errp, "Invalid alignment");
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail_unref;
} }
ret = 0; ret = 0;
fail: goto out;
fail_unref:
bdrv_unref(bs->file);
out:
qemu_opts_del(opts); qemu_opts_del(opts);
return ret; return ret;
} }

View File

@@ -128,23 +128,25 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
/* Open the raw file */ /* Open the raw file */
assert(bs->file == NULL);
ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-raw"), options, ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-raw"), options,
"raw", flags, true, false, &local_err); "raw", flags | BDRV_O_PROTOCOL, false, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto fail; goto fail;
} }
/* Open the test file */ /* Open the test file */
assert(s->test_file == NULL);
ret = bdrv_open_image(&s->test_file, qemu_opt_get(opts, "x-image"), options, ret = bdrv_open_image(&s->test_file, qemu_opt_get(opts, "x-image"), options,
"test", flags, false, false, &local_err); "test", flags, false, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
s->test_file = NULL; s->test_file = NULL;
@@ -171,110 +173,6 @@ static int64_t blkverify_getlength(BlockDriverState *bs)
return bdrv_getlength(s->test_file); return bdrv_getlength(s->test_file);
} }
/**
* Check that I/O vector contents are identical
*
* @a: I/O vector
* @b: I/O vector
* @ret: Offset to first mismatching byte or -1 if match
*/
static ssize_t blkverify_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
{
int i;
ssize_t offset = 0;
assert(a->niov == b->niov);
for (i = 0; i < a->niov; i++) {
size_t len = 0;
uint8_t *p = (uint8_t *)a->iov[i].iov_base;
uint8_t *q = (uint8_t *)b->iov[i].iov_base;
assert(a->iov[i].iov_len == b->iov[i].iov_len);
while (len < a->iov[i].iov_len && *p++ == *q++) {
len++;
}
offset += len;
if (len != a->iov[i].iov_len) {
return offset;
}
}
return -1;
}
typedef struct {
int src_index;
struct iovec *src_iov;
void *dest_base;
} IOVectorSortElem;
static int sortelem_cmp_src_base(const void *a, const void *b)
{
const IOVectorSortElem *elem_a = a;
const IOVectorSortElem *elem_b = b;
/* Don't overflow */
if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base) {
return -1;
} else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base) {
return 1;
} else {
return 0;
}
}
static int sortelem_cmp_src_index(const void *a, const void *b)
{
const IOVectorSortElem *elem_a = a;
const IOVectorSortElem *elem_b = b;
return elem_a->src_index - elem_b->src_index;
}
/**
* Copy contents of I/O vector
*
* The relative relationships of overlapping iovecs are preserved. This is
* necessary to ensure identical semantics in the cloned I/O vector.
*/
static void blkverify_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src,
void *buf)
{
IOVectorSortElem sortelems[src->niov];
void *last_end;
int i;
/* Sort by source iovecs by base address */
for (i = 0; i < src->niov; i++) {
sortelems[i].src_index = i;
sortelems[i].src_iov = &src->iov[i];
}
qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_base);
/* Allocate buffer space taking into account overlapping iovecs */
last_end = NULL;
for (i = 0; i < src->niov; i++) {
struct iovec *cur = sortelems[i].src_iov;
ptrdiff_t rewind = 0;
/* Detect overlap */
if (last_end && last_end > cur->iov_base) {
rewind = last_end - cur->iov_base;
}
sortelems[i].dest_base = buf - rewind;
buf += cur->iov_len - MIN(rewind, cur->iov_len);
last_end = MAX(cur->iov_base + cur->iov_len, last_end);
}
/* Sort by source iovec index and build destination iovec */
qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_index);
for (i = 0; i < src->niov; i++) {
qemu_iovec_add(dest, sortelems[i].dest_base, src->iov[i].iov_len);
}
}
static BlkverifyAIOCB *blkverify_aio_get(BlockDriverState *bs, bool is_write, static BlkverifyAIOCB *blkverify_aio_get(BlockDriverState *bs, bool is_write,
int64_t sector_num, QEMUIOVector *qiov, int64_t sector_num, QEMUIOVector *qiov,
int nb_sectors, int nb_sectors,
@@ -338,7 +236,7 @@ static void blkverify_aio_cb(void *opaque, int ret)
static void blkverify_verify_readv(BlkverifyAIOCB *acb) static void blkverify_verify_readv(BlkverifyAIOCB *acb)
{ {
ssize_t offset = blkverify_iovec_compare(acb->qiov, &acb->raw_qiov); ssize_t offset = qemu_iovec_compare(acb->qiov, &acb->raw_qiov);
if (offset != -1) { if (offset != -1) {
blkverify_err(acb, "contents mismatch in sector %" PRId64, blkverify_err(acb, "contents mismatch in sector %" PRId64,
acb->sector_num + (int64_t)(offset / BDRV_SECTOR_SIZE)); acb->sector_num + (int64_t)(offset / BDRV_SECTOR_SIZE));
@@ -356,7 +254,7 @@ static BlockDriverAIOCB *blkverify_aio_readv(BlockDriverState *bs,
acb->verify = blkverify_verify_readv; acb->verify = blkverify_verify_readv;
acb->buf = qemu_blockalign(bs->file, qiov->size); acb->buf = qemu_blockalign(bs->file, qiov->size);
qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov); qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);
blkverify_iovec_clone(&acb->raw_qiov, qiov, acb->buf); qemu_iovec_clone(&acb->raw_qiov, qiov, acb->buf);
bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors, bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors,
blkverify_aio_cb, acb); blkverify_aio_cb, acb);

View File

@@ -129,7 +129,8 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
strcmp(bochs.subtype, GROWING_TYPE) || strcmp(bochs.subtype, GROWING_TYPE) ||
((le32_to_cpu(bochs.version) != HEADER_VERSION) && ((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
(le32_to_cpu(bochs.version) != HEADER_V1))) { (le32_to_cpu(bochs.version) != HEADER_V1))) {
return -EMEDIUMTYPE; error_setg(errp, "Image not in Bochs format");
return -EINVAL;
} }
if (le32_to_cpu(bochs.version) == HEADER_V1) { if (le32_to_cpu(bochs.version) == HEADER_V1) {

View File

@@ -74,7 +74,8 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags,
} }
if (be32_to_cpu(cow_header.magic) != COW_MAGIC) { if (be32_to_cpu(cow_header.magic) != COW_MAGIC) {
ret = -EMEDIUMTYPE; error_setg(errp, "Image not in COW format");
ret = -EINVAL;
goto fail; goto fail;
} }
@@ -82,7 +83,7 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags,
char version[64]; char version[64];
snprintf(version, sizeof(version), snprintf(version, sizeof(version),
"COW version %d", cow_header.version); "COW version %d", cow_header.version);
qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "cow", version); bs->device_name, "cow", version);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
@@ -346,16 +347,15 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
ret = bdrv_create_file(filename, options, &local_err); ret = bdrv_create_file(filename, options, &local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
return ret; return ret;
} }
ret = bdrv_file_open(&cow_bs, filename, NULL, NULL, BDRV_O_RDWR, cow_bs = NULL;
&local_err); ret = bdrv_open(&cow_bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
return ret; return ret;
} }

View File

@@ -456,30 +456,27 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
static int inited = 0; static int inited = 0;
if (flags & BDRV_O_RDWR) { if (flags & BDRV_O_RDWR) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, error_setg(errp, "curl block device does not support writes");
"curl block device does not support writes");
return -EROFS; return -EROFS;
} }
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
goto out_noclean; goto out_noclean;
} }
s->readahead_size = qemu_opt_get_size(opts, "readahead", READ_AHEAD_SIZE); s->readahead_size = qemu_opt_get_size(opts, "readahead", READ_AHEAD_SIZE);
if ((s->readahead_size & 0x1ff) != 0) { if ((s->readahead_size & 0x1ff) != 0) {
fprintf(stderr, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512\n", error_setg(errp, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512",
s->readahead_size); s->readahead_size);
goto out_noclean; goto out_noclean;
} }
file = qemu_opt_get(opts, "url"); file = qemu_opt_get(opts, "url");
if (file == NULL) { if (file == NULL) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "curl block driver requires " error_setg(errp, "curl block driver requires an 'url' option");
"an 'url' option");
goto out_noclean; goto out_noclean;
} }

View File

@@ -45,11 +45,13 @@ typedef struct GlusterConf {
static void qemu_gluster_gconf_free(GlusterConf *gconf) static void qemu_gluster_gconf_free(GlusterConf *gconf)
{ {
g_free(gconf->server); if (gconf) {
g_free(gconf->volname); g_free(gconf->server);
g_free(gconf->image); g_free(gconf->volname);
g_free(gconf->transport); g_free(gconf->image);
g_free(gconf); g_free(gconf->transport);
g_free(gconf);
}
} }
static int parse_volume_options(GlusterConf *gconf, char *path) static int parse_volume_options(GlusterConf *gconf, char *path)
@@ -127,7 +129,7 @@ static int qemu_gluster_parseuri(GlusterConf *gconf, const char *filename)
} }
/* transport */ /* transport */
if (!strcmp(uri->scheme, "gluster")) { if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
gconf->transport = g_strdup("tcp"); gconf->transport = g_strdup("tcp");
} else if (!strcmp(uri->scheme, "gluster+tcp")) { } else if (!strcmp(uri->scheme, "gluster+tcp")) {
gconf->transport = g_strdup("tcp"); gconf->transport = g_strdup("tcp");
@@ -163,7 +165,7 @@ static int qemu_gluster_parseuri(GlusterConf *gconf, const char *filename)
} }
gconf->server = g_strdup(qp->p[0].value); gconf->server = g_strdup(qp->p[0].value);
} else { } else {
gconf->server = g_strdup(uri->server); gconf->server = g_strdup(uri->server ? uri->server : "localhost");
gconf->port = uri->port; gconf->port = uri->port;
} }
@@ -175,7 +177,8 @@ out:
return ret; return ret;
} }
static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename) static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename,
Error **errp)
{ {
struct glfs *glfs = NULL; struct glfs *glfs = NULL;
int ret; int ret;
@@ -183,8 +186,8 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename)
ret = qemu_gluster_parseuri(gconf, filename); ret = qemu_gluster_parseuri(gconf, filename);
if (ret < 0) { if (ret < 0) {
error_report("Usage: file=gluster[+transport]://[server[:port]]/" error_setg(errp, "Usage: file=gluster[+transport]://[server[:port]]/"
"volname/image[?socket=...]"); "volname/image[?socket=...]");
errno = -ret; errno = -ret;
goto out; goto out;
} }
@@ -211,9 +214,11 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename)
ret = glfs_init(glfs); ret = glfs_init(glfs);
if (ret) { if (ret) {
error_report("Gluster connection failed for server=%s port=%d " error_setg_errno(errp, errno,
"volume=%s image=%s transport=%s", gconf->server, gconf->port, "Gluster connection failed for server=%s port=%d "
gconf->volname, gconf->image, gconf->transport); "volume=%s image=%s transport=%s", gconf->server,
gconf->port, gconf->volname, gconf->image,
gconf->transport);
goto out; goto out;
} }
return glfs; return glfs;
@@ -269,11 +274,28 @@ static QemuOptsList runtime_opts = {
}, },
}; };
static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
{
assert(open_flags != NULL);
*open_flags |= O_BINARY;
if (bdrv_flags & BDRV_O_RDWR) {
*open_flags |= O_RDWR;
} else {
*open_flags |= O_RDONLY;
}
if ((bdrv_flags & BDRV_O_NOCACHE)) {
*open_flags |= O_DIRECT;
}
}
static int qemu_gluster_open(BlockDriverState *bs, QDict *options, static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
int bdrv_flags, Error **errp) int bdrv_flags, Error **errp)
{ {
BDRVGlusterState *s = bs->opaque; BDRVGlusterState *s = bs->opaque;
int open_flags = O_BINARY; int open_flags = 0;
int ret = 0; int ret = 0;
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf)); GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
QemuOpts *opts; QemuOpts *opts;
@@ -282,30 +304,21 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
filename = qemu_opt_get(opts, "filename"); filename = qemu_opt_get(opts, "filename");
s->glfs = qemu_gluster_init(gconf, filename); s->glfs = qemu_gluster_init(gconf, filename, errp);
if (!s->glfs) { if (!s->glfs) {
ret = -errno; ret = -errno;
goto out; goto out;
} }
if (bdrv_flags & BDRV_O_RDWR) { qemu_gluster_parse_flags(bdrv_flags, &open_flags);
open_flags |= O_RDWR;
} else {
open_flags |= O_RDONLY;
}
if ((bdrv_flags & BDRV_O_NOCACHE)) {
open_flags |= O_DIRECT;
}
s->fd = glfs_open(s->glfs, gconf->image, open_flags); s->fd = glfs_open(s->glfs, gconf->image, open_flags);
if (!s->fd) { if (!s->fd) {
@@ -327,6 +340,96 @@ out:
return ret; return ret;
} }
typedef struct BDRVGlusterReopenState {
struct glfs *glfs;
struct glfs_fd *fd;
} BDRVGlusterReopenState;
static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
BlockReopenQueue *queue, Error **errp)
{
int ret = 0;
BDRVGlusterReopenState *reop_s;
GlusterConf *gconf = NULL;
int open_flags = 0;
assert(state != NULL);
assert(state->bs != NULL);
state->opaque = g_malloc0(sizeof(BDRVGlusterReopenState));
reop_s = state->opaque;
qemu_gluster_parse_flags(state->flags, &open_flags);
gconf = g_malloc0(sizeof(GlusterConf));
reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename, errp);
if (reop_s->glfs == NULL) {
ret = -errno;
goto exit;
}
reop_s->fd = glfs_open(reop_s->glfs, gconf->image, open_flags);
if (reop_s->fd == NULL) {
/* reops->glfs will be cleaned up in _abort */
ret = -errno;
goto exit;
}
exit:
/* state->opaque will be freed in either the _abort or _commit */
qemu_gluster_gconf_free(gconf);
return ret;
}
static void qemu_gluster_reopen_commit(BDRVReopenState *state)
{
BDRVGlusterReopenState *reop_s = state->opaque;
BDRVGlusterState *s = state->bs->opaque;
/* close the old */
if (s->fd) {
glfs_close(s->fd);
}
if (s->glfs) {
glfs_fini(s->glfs);
}
/* use the newly opened image / connection */
s->fd = reop_s->fd;
s->glfs = reop_s->glfs;
g_free(state->opaque);
state->opaque = NULL;
return;
}
static void qemu_gluster_reopen_abort(BDRVReopenState *state)
{
BDRVGlusterReopenState *reop_s = state->opaque;
if (reop_s == NULL) {
return;
}
if (reop_s->fd) {
glfs_close(reop_s->fd);
}
if (reop_s->glfs) {
glfs_fini(reop_s->glfs);
}
g_free(state->opaque);
state->opaque = NULL;
return;
}
#ifdef CONFIG_GLUSTERFS_ZEROFILL #ifdef CONFIG_GLUSTERFS_ZEROFILL
static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs, static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
@@ -389,9 +492,9 @@ static int qemu_gluster_create(const char *filename,
int64_t total_size = 0; int64_t total_size = 0;
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf)); GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
glfs = qemu_gluster_init(gconf, filename); glfs = qemu_gluster_init(gconf, filename, errp);
if (!glfs) { if (!glfs) {
ret = -errno; ret = -EINVAL;
goto out; goto out;
} }
@@ -617,6 +720,9 @@ static BlockDriver bdrv_gluster = {
.instance_size = sizeof(BDRVGlusterState), .instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true, .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open, .bdrv_file_open = qemu_gluster_open,
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
.bdrv_close = qemu_gluster_close, .bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create, .bdrv_create = qemu_gluster_create,
.bdrv_getlength = qemu_gluster_getlength, .bdrv_getlength = qemu_gluster_getlength,
@@ -641,6 +747,9 @@ static BlockDriver bdrv_gluster_tcp = {
.instance_size = sizeof(BDRVGlusterState), .instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true, .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open, .bdrv_file_open = qemu_gluster_open,
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
.bdrv_close = qemu_gluster_close, .bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create, .bdrv_create = qemu_gluster_create,
.bdrv_getlength = qemu_gluster_getlength, .bdrv_getlength = qemu_gluster_getlength,
@@ -665,6 +774,9 @@ static BlockDriver bdrv_gluster_unix = {
.instance_size = sizeof(BDRVGlusterState), .instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true, .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open, .bdrv_file_open = qemu_gluster_open,
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
.bdrv_close = qemu_gluster_close, .bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create, .bdrv_create = qemu_gluster_create,
.bdrv_getlength = qemu_gluster_getlength, .bdrv_getlength = qemu_gluster_getlength,
@@ -689,6 +801,9 @@ static BlockDriver bdrv_gluster_rdma = {
.instance_size = sizeof(BDRVGlusterState), .instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true, .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open, .bdrv_file_open = qemu_gluster_open,
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
.bdrv_close = qemu_gluster_close, .bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create, .bdrv_create = qemu_gluster_create,
.bdrv_getlength = qemu_gluster_getlength, .bdrv_getlength = qemu_gluster_getlength,

View File

@@ -145,12 +145,13 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
if (iTask->retries-- > 0 && status == SCSI_STATUS_CHECK_CONDITION if (iTask->retries-- > 0 && status == SCSI_STATUS_CHECK_CONDITION
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION) { && task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {
error_report("iSCSI CheckCondition: %s", iscsi_get_error(iscsi));
iTask->do_retry = 1; iTask->do_retry = 1;
goto out; goto out;
} }
if (status != SCSI_STATUS_GOOD) { if (status != SCSI_STATUS_GOOD) {
error_report("iSCSI: Failure. %s", iscsi_get_error(iscsi)); error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));
} }
out: out:
@@ -325,6 +326,7 @@ retry:
} }
if (iTask.do_retry) { if (iTask.do_retry) {
iTask.complete = 0;
goto retry; goto retry;
} }
@@ -399,6 +401,7 @@ retry:
} }
if (iTask.do_retry) { if (iTask.do_retry) {
iTask.complete = 0;
goto retry; goto retry;
} }
@@ -433,6 +436,7 @@ retry:
} }
if (iTask.do_retry) { if (iTask.do_retry) {
iTask.complete = 0;
goto retry; goto retry;
} }
@@ -683,6 +687,7 @@ retry:
scsi_free_scsi_task(iTask.task); scsi_free_scsi_task(iTask.task);
iTask.task = NULL; iTask.task = NULL;
} }
iTask.complete = 0;
goto retry; goto retry;
} }
@@ -767,6 +772,7 @@ retry:
} }
if (iTask.do_retry) { if (iTask.do_retry) {
iTask.complete = 0;
goto retry; goto retry;
} }
@@ -830,24 +836,26 @@ retry:
qemu_coroutine_yield(); qemu_coroutine_yield();
} }
if (iTask.status == SCSI_STATUS_CHECK_CONDITION &&
iTask.task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST &&
iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
/* WRITE SAME is not supported by the target */
iscsilun->has_write_same = false;
scsi_free_scsi_task(iTask.task);
return -ENOTSUP;
}
if (iTask.task != NULL) { if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task); scsi_free_scsi_task(iTask.task);
iTask.task = NULL; iTask.task = NULL;
} }
if (iTask.do_retry) { if (iTask.do_retry) {
iTask.complete = 0;
goto retry; goto retry;
} }
if (iTask.status != SCSI_STATUS_GOOD) { if (iTask.status != SCSI_STATUS_GOOD) {
if (iTask.status == SCSI_STATUS_CHECK_CONDITION &&
iTask.task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST &&
iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
/* WRITE SAME is not supported by the target */
iscsilun->has_write_same = false;
return -ENOTSUP;
}
return -EIO; return -EIO;
} }
@@ -856,7 +864,8 @@ retry:
#endif /* SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED */ #endif /* SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED */
static int parse_chap(struct iscsi_context *iscsi, const char *target) static void parse_chap(struct iscsi_context *iscsi, const char *target,
Error **errp)
{ {
QemuOptsList *list; QemuOptsList *list;
QemuOpts *opts; QemuOpts *opts;
@@ -865,37 +874,35 @@ static int parse_chap(struct iscsi_context *iscsi, const char *target)
list = qemu_find_opts("iscsi"); list = qemu_find_opts("iscsi");
if (!list) { if (!list) {
return 0; return;
} }
opts = qemu_opts_find(list, target); opts = qemu_opts_find(list, target);
if (opts == NULL) { if (opts == NULL) {
opts = QTAILQ_FIRST(&list->head); opts = QTAILQ_FIRST(&list->head);
if (!opts) { if (!opts) {
return 0; return;
} }
} }
user = qemu_opt_get(opts, "user"); user = qemu_opt_get(opts, "user");
if (!user) { if (!user) {
return 0; return;
} }
password = qemu_opt_get(opts, "password"); password = qemu_opt_get(opts, "password");
if (!password) { if (!password) {
error_report("CHAP username specified but no password was given"); error_setg(errp, "CHAP username specified but no password was given");
return -1; return;
} }
if (iscsi_set_initiator_username_pwd(iscsi, user, password)) { if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
error_report("Failed to set initiator username and password"); error_setg(errp, "Failed to set initiator username and password");
return -1;
} }
return 0;
} }
static void parse_header_digest(struct iscsi_context *iscsi, const char *target) static void parse_header_digest(struct iscsi_context *iscsi, const char *target,
Error **errp)
{ {
QemuOptsList *list; QemuOptsList *list;
QemuOpts *opts; QemuOpts *opts;
@@ -928,7 +935,7 @@ static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
} else if (!strcmp(digest, "NONE-CRC32C")) { } else if (!strcmp(digest, "NONE-CRC32C")) {
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
} else { } else {
error_report("Invalid header-digest setting : %s", digest); error_setg(errp, "Invalid header-digest setting : %s", digest);
} }
} }
@@ -986,12 +993,11 @@ static void iscsi_nop_timed_event(void *opaque)
} }
#endif #endif
static int iscsi_readcapacity_sync(IscsiLun *iscsilun) static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
{ {
struct scsi_task *task = NULL; struct scsi_task *task = NULL;
struct scsi_readcapacity10 *rc10 = NULL; struct scsi_readcapacity10 *rc10 = NULL;
struct scsi_readcapacity16 *rc16 = NULL; struct scsi_readcapacity16 *rc16 = NULL;
int ret = 0;
int retries = ISCSI_CMD_RETRIES; int retries = ISCSI_CMD_RETRIES;
do { do {
@@ -1006,8 +1012,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
if (task != NULL && task->status == SCSI_STATUS_GOOD) { if (task != NULL && task->status == SCSI_STATUS_GOOD) {
rc16 = scsi_datain_unmarshall(task); rc16 = scsi_datain_unmarshall(task);
if (rc16 == NULL) { if (rc16 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity16 data."); error_setg(errp, "iSCSI: Failed to unmarshall readcapacity16 data.");
ret = -EINVAL;
} else { } else {
iscsilun->block_size = rc16->block_length; iscsilun->block_size = rc16->block_length;
iscsilun->num_blocks = rc16->returned_lba + 1; iscsilun->num_blocks = rc16->returned_lba + 1;
@@ -1021,8 +1026,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
if (task != NULL && task->status == SCSI_STATUS_GOOD) { if (task != NULL && task->status == SCSI_STATUS_GOOD) {
rc10 = scsi_datain_unmarshall(task); rc10 = scsi_datain_unmarshall(task);
if (rc10 == NULL) { if (rc10 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity10 data."); error_setg(errp, "iSCSI: Failed to unmarshall readcapacity10 data.");
ret = -EINVAL;
} else { } else {
iscsilun->block_size = rc10->block_size; iscsilun->block_size = rc10->block_size;
if (rc10->lba == 0) { if (rc10->lba == 0) {
@@ -1035,20 +1039,18 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
} }
break; break;
default: default:
return 0; return;
} }
} while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION } while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION && task->sense.key == SCSI_SENSE_UNIT_ATTENTION
&& retries-- > 0); && retries-- > 0);
if (task == NULL || task->status != SCSI_STATUS_GOOD) { if (task == NULL || task->status != SCSI_STATUS_GOOD) {
error_report("iSCSI: failed to send readcapacity10 command."); error_setg(errp, "iSCSI: failed to send readcapacity10 command.");
ret = -EINVAL;
} }
if (task) { if (task) {
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
} }
return ret;
} }
/* TODO Convert to fine grained options */ /* TODO Convert to fine grained options */
@@ -1065,40 +1067,50 @@ static QemuOptsList runtime_opts = {
}, },
}; };
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
int lun, int evpd, int pc) { int evpd, int pc, void **inq, Error **errp)
int full_size; {
struct scsi_task *task = NULL; int full_size;
task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, 64); struct scsi_task *task = NULL;
task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, 64);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
goto fail;
}
full_size = scsi_datain_getfullsize(task);
if (full_size > task->datain.size) {
scsi_free_scsi_task(task);
/* we need more data for the full list */
task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, full_size);
if (task == NULL || task->status != SCSI_STATUS_GOOD) { if (task == NULL || task->status != SCSI_STATUS_GOOD) {
goto fail; goto fail;
} }
full_size = scsi_datain_getfullsize(task); }
if (full_size > task->datain.size) {
scsi_free_scsi_task(task);
/* we need more data for the full list */ *inq = scsi_datain_unmarshall(task);
task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, full_size); if (*inq == NULL) {
if (task == NULL || task->status != SCSI_STATUS_GOOD) { error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
goto fail; goto fail;
} }
}
return task; return task;
fail: fail:
error_report("iSCSI: Inquiry command failed : %s", error_setg(errp, "iSCSI: Inquiry command failed : %s",
iscsi_get_error(iscsi)); iscsi_get_error(iscsi));
if (task) { if (task != NULL) {
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
return NULL; }
} return NULL;
return NULL;
} }
/* /*
* We support iscsi url's on the form * We support iscsi url's on the form
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun> * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
*
* Note: flags are currently not used by iscsi_open. If this function
* is changed such that flags are used, please examine iscsi_reopen_prepare()
* to see if needs to be changed as well.
*/ */
static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) Error **errp)
@@ -1108,34 +1120,33 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
struct iscsi_url *iscsi_url = NULL; struct iscsi_url *iscsi_url = NULL;
struct scsi_task *task = NULL; struct scsi_task *task = NULL;
struct scsi_inquiry_standard *inq = NULL; struct scsi_inquiry_standard *inq = NULL;
struct scsi_inquiry_supported_pages *inq_vpd;
char *initiator_name = NULL; char *initiator_name = NULL;
QemuOpts *opts; QemuOpts *opts;
Error *local_err = NULL; Error *local_err = NULL;
const char *filename; const char *filename;
int ret; int i, ret;
if ((BDRV_SECTOR_SIZE % 512) != 0) { if ((BDRV_SECTOR_SIZE % 512) != 0) {
error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. " error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
"BDRV_SECTOR_SIZE(%lld) is not a multiple " "BDRV_SECTOR_SIZE(%lld) is not a multiple "
"of 512", BDRV_SECTOR_SIZE); "of 512", BDRV_SECTOR_SIZE);
return -EINVAL; return -EINVAL;
} }
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
filename = qemu_opt_get(opts, "filename"); filename = qemu_opt_get(opts, "filename");
iscsi_url = iscsi_parse_full_url(iscsi, filename); iscsi_url = iscsi_parse_full_url(iscsi, filename);
if (iscsi_url == NULL) { if (iscsi_url == NULL) {
error_report("Failed to parse URL : %s", filename); error_setg(errp, "Failed to parse URL : %s", filename);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
@@ -1146,13 +1157,13 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsi = iscsi_create_context(initiator_name); iscsi = iscsi_create_context(initiator_name);
if (iscsi == NULL) { if (iscsi == NULL) {
error_report("iSCSI: Failed to create iSCSI context."); error_setg(errp, "iSCSI: Failed to create iSCSI context.");
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
if (iscsi_set_targetname(iscsi, iscsi_url->target)) { if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
error_report("iSCSI: Failed to set target name."); error_setg(errp, "iSCSI: Failed to set target name.");
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
@@ -1161,21 +1172,22 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
iscsi_url->passwd); iscsi_url->passwd);
if (ret != 0) { if (ret != 0) {
error_report("Failed to set initiator username and password"); error_setg(errp, "Failed to set initiator username and password");
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
} }
/* check if we got CHAP username/password via the options */ /* check if we got CHAP username/password via the options */
if (parse_chap(iscsi, iscsi_url->target) != 0) { parse_chap(iscsi, iscsi_url->target, &local_err);
error_report("iSCSI: Failed to set CHAP user/password"); if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) { if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
error_report("iSCSI: Failed to set session type to normal."); error_setg(errp, "iSCSI: Failed to set session type to normal.");
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
@@ -1183,10 +1195,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
/* check if we got HEADER_DIGEST via the options */ /* check if we got HEADER_DIGEST via the options */
parse_header_digest(iscsi, iscsi_url->target); parse_header_digest(iscsi, iscsi_url->target, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto out;
}
if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
error_report("iSCSI: Failed to connect to LUN : %s", error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
iscsi_get_error(iscsi)); iscsi_get_error(iscsi));
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
@@ -1194,26 +1211,21 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsilun->iscsi = iscsi; iscsilun->iscsi = iscsi;
iscsilun->lun = iscsi_url->lun; iscsilun->lun = iscsi_url->lun;
task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
error_report("iSCSI: failed to send inquiry command.");
ret = -EINVAL;
goto out;
}
inq = scsi_datain_unmarshall(task);
if (inq == NULL) {
error_report("iSCSI: Failed to unmarshall inquiry data.");
ret = -EINVAL;
goto out;
}
iscsilun->type = inq->periperal_device_type;
iscsilun->has_write_same = true; iscsilun->has_write_same = true;
if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) { task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
(void **) &inq, errp);
if (task == NULL) {
ret = -EINVAL;
goto out;
}
iscsilun->type = inq->periperal_device_type;
scsi_free_scsi_task(task);
task = NULL;
iscsi_readcapacity_sync(iscsilun, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
goto out; goto out;
} }
bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun); bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
@@ -1228,45 +1240,48 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
bs->sg = 1; bs->sg = 1;
} }
if (iscsilun->lbpme) { task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
(void **) &inq_vpd, errp);
if (task == NULL) {
ret = -EINVAL;
goto out;
}
for (i = 0; i < inq_vpd->num_pages; i++) {
struct scsi_task *inq_task;
struct scsi_inquiry_logical_block_provisioning *inq_lbp; struct scsi_inquiry_logical_block_provisioning *inq_lbp;
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING);
if (task == NULL) {
ret = -EINVAL;
goto out;
}
inq_lbp = scsi_datain_unmarshall(task);
if (inq_lbp == NULL) {
error_report("iSCSI: failed to unmarshall inquiry datain blob");
ret = -EINVAL;
goto out;
}
memcpy(&iscsilun->lbp, inq_lbp,
sizeof(struct scsi_inquiry_logical_block_provisioning));
scsi_free_scsi_task(task);
task = NULL;
}
if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
struct scsi_inquiry_block_limits *inq_bl; struct scsi_inquiry_block_limits *inq_bl;
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, switch (inq_vpd->pages[i]) {
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS); case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
if (task == NULL) { inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
ret = -EINVAL; SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
goto out; (void **) &inq_lbp, errp);
if (inq_task == NULL) {
ret = -EINVAL;
goto out;
}
memcpy(&iscsilun->lbp, inq_lbp,
sizeof(struct scsi_inquiry_logical_block_provisioning));
scsi_free_scsi_task(inq_task);
break;
case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
(void **) &inq_bl, errp);
if (inq_task == NULL) {
ret = -EINVAL;
goto out;
}
memcpy(&iscsilun->bl, inq_bl,
sizeof(struct scsi_inquiry_block_limits));
scsi_free_scsi_task(inq_task);
break;
default:
break;
} }
inq_bl = scsi_datain_unmarshall(task);
if (inq_bl == NULL) {
error_report("iSCSI: failed to unmarshall inquiry datain blob");
ret = -EINVAL;
goto out;
}
memcpy(&iscsilun->bl, inq_bl,
sizeof(struct scsi_inquiry_block_limits));
scsi_free_scsi_task(task);
task = NULL;
} }
scsi_free_scsi_task(task);
task = NULL;
#if defined(LIBISCSI_FEATURE_NOP_COUNTER) #if defined(LIBISCSI_FEATURE_NOP_COUNTER)
/* Set up a timer for sending out iSCSI NOPs */ /* Set up a timer for sending out iSCSI NOPs */
@@ -1330,32 +1345,35 @@ static int iscsi_refresh_limits(BlockDriverState *bs)
} }
bs->bl.write_zeroes_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran, bs->bl.write_zeroes_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran,
iscsilun); iscsilun);
bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len,
iscsilun);
} }
bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len,
iscsilun);
return 0; return 0;
} }
/* We have nothing to do for iSCSI reopen, stub just returns /* Since iscsi_open() ignores bdrv_flags, there is nothing to do here in
* success */ * prepare. Note that this will not re-establish a connection with an iSCSI
* target - it is effectively a NOP. */
static int iscsi_reopen_prepare(BDRVReopenState *state, static int iscsi_reopen_prepare(BDRVReopenState *state,
BlockReopenQueue *queue, Error **errp) BlockReopenQueue *queue, Error **errp)
{ {
/* NOP */
return 0; return 0;
} }
static int iscsi_truncate(BlockDriverState *bs, int64_t offset) static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
{ {
IscsiLun *iscsilun = bs->opaque; IscsiLun *iscsilun = bs->opaque;
int ret = 0; Error *local_err = NULL;
if (iscsilun->type != TYPE_DISK) { if (iscsilun->type != TYPE_DISK) {
return -ENOTSUP; return -ENOTSUP;
} }
if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) { iscsi_readcapacity_sync(iscsilun, &local_err);
return ret; if (local_err != NULL) {
error_free(local_err);
return -EIO;
} }
if (offset > iscsi_getlength(bs)) { if (offset > iscsi_getlength(bs)) {

View File

@@ -633,6 +633,8 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
{ {
int64_t length, base_length; int64_t length, base_length;
int orig_base_flags; int orig_base_flags;
int ret;
Error *local_err = NULL;
orig_base_flags = bdrv_get_flags(base); orig_base_flags = bdrv_get_flags(base);
@@ -642,19 +644,23 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
length = bdrv_getlength(bs); length = bdrv_getlength(bs);
if (length < 0) { if (length < 0) {
error_setg(errp, "Unable to determine length of %s", bs->filename); error_setg_errno(errp, -length,
"Unable to determine length of %s", bs->filename);
goto error_restore_flags; goto error_restore_flags;
} }
base_length = bdrv_getlength(base); base_length = bdrv_getlength(base);
if (base_length < 0) { if (base_length < 0) {
error_setg(errp, "Unable to determine length of %s", base->filename); error_setg_errno(errp, -base_length,
"Unable to determine length of %s", base->filename);
goto error_restore_flags; goto error_restore_flags;
} }
if (length > base_length) { if (length > base_length) {
if (bdrv_truncate(base, length) < 0) { ret = bdrv_truncate(base, length);
error_setg(errp, "Top image %s is larger than base image %s, and " if (ret < 0) {
error_setg_errno(errp, -ret,
"Top image %s is larger than base image %s, and "
"resize of base image failed", "resize of base image failed",
bs->filename, base->filename); bs->filename, base->filename);
goto error_restore_flags; goto error_restore_flags;
@@ -663,9 +669,10 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
bdrv_ref(base); bdrv_ref(base);
mirror_start_job(bs, base, speed, 0, 0, mirror_start_job(bs, base, speed, 0, 0,
on_error, on_error, cb, opaque, errp, on_error, on_error, cb, opaque, &local_err,
&commit_active_job_driver, false, base); &commit_active_job_driver, false, base);
if (error_is_set(errp)) { if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
goto error_restore_flags; goto error_restore_flags;
} }

View File

@@ -188,31 +188,28 @@ out:
g_free(file); g_free(file);
} }
static int nbd_config(BDRVNBDState *s, QDict *options, char **export) static void nbd_config(BDRVNBDState *s, QDict *options, char **export,
Error **errp)
{ {
Error *local_err = NULL; Error *local_err = NULL;
if (qdict_haskey(options, "path")) { if (qdict_haskey(options, "path") == qdict_haskey(options, "host")) {
if (qdict_haskey(options, "host")) { if (qdict_haskey(options, "path")) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "path and host may not " error_setg(errp, "path and host may not be used at the same time.");
"be used at the same time."); } else {
return -EINVAL; error_setg(errp, "one of path and host must be specified.");
} }
s->client.is_unix = true; return;
} else if (qdict_haskey(options, "host")) {
s->client.is_unix = false;
} else {
return -EINVAL;
} }
s->client.is_unix = qdict_haskey(options, "path");
s->socket_opts = qemu_opts_create(&socket_optslist, NULL, 0, s->socket_opts = qemu_opts_create(&socket_optslist, NULL, 0,
&error_abort); &error_abort);
qemu_opts_absorb_qdict(s->socket_opts, options, &local_err); qemu_opts_absorb_qdict(s->socket_opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err); return;
return -EINVAL;
} }
if (!qemu_opt_get(s->socket_opts, "port")) { if (!qemu_opt_get(s->socket_opts, "port")) {
@@ -223,19 +220,17 @@ static int nbd_config(BDRVNBDState *s, QDict *options, char **export)
if (*export) { if (*export) {
qdict_del(options, "export"); qdict_del(options, "export");
} }
return 0;
} }
static int nbd_establish_connection(BlockDriverState *bs) static int nbd_establish_connection(BlockDriverState *bs, Error **errp)
{ {
BDRVNBDState *s = bs->opaque; BDRVNBDState *s = bs->opaque;
int sock; int sock;
if (s->client.is_unix) { if (s->client.is_unix) {
sock = unix_socket_outgoing(qemu_opt_get(s->socket_opts, "path")); sock = unix_connect_opts(s->socket_opts, errp, NULL, NULL);
} else { } else {
sock = tcp_socket_outgoing_opts(s->socket_opts); sock = inet_connect_opts(s->socket_opts, errp, NULL, NULL);
if (sock >= 0) { if (sock >= 0) {
socket_set_nodelay(sock); socket_set_nodelay(sock);
} }
@@ -256,17 +251,19 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
BDRVNBDState *s = bs->opaque; BDRVNBDState *s = bs->opaque;
char *export = NULL; char *export = NULL;
int result, sock; int result, sock;
Error *local_err = NULL;
/* Pop the config into our state object. Exit if invalid. */ /* Pop the config into our state object. Exit if invalid. */
result = nbd_config(s, options, &export); nbd_config(s, options, &export, &local_err);
if (result != 0) { if (local_err) {
return result; error_propagate(errp, local_err);
return -EINVAL;
} }
/* establish TCP connection, return error if it fails /* establish TCP connection, return error if it fails
* TODO: Configurable retry-until-timeout behaviour. * TODO: Configurable retry-until-timeout behaviour.
*/ */
sock = nbd_establish_connection(bs); sock = nbd_establish_connection(bs, errp);
if (sock < 0) { if (sock < 0) {
return sock; return sock;
} }

439
block/nfs.c Normal file
View File

@@ -0,0 +1,439 @@
/*
* QEMU Block driver for native access to files on NFS shares
*
* Copyright (c) 2014 Peter Lieven <pl@kamp.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "config-host.h"
#include <poll.h>
#include "qemu-common.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "block/block_int.h"
#include "trace.h"
#include "qemu/iov.h"
#include "qemu/uri.h"
#include "sysemu/sysemu.h"
#include <nfsc/libnfs.h>
typedef struct NFSClient {
struct nfs_context *context;
struct nfsfh *fh;
int events;
bool has_zero_init;
} NFSClient;
typedef struct NFSRPC {
int ret;
int complete;
QEMUIOVector *iov;
struct stat *st;
Coroutine *co;
QEMUBH *bh;
} NFSRPC;
static void nfs_process_read(void *arg);
static void nfs_process_write(void *arg);
static void nfs_set_events(NFSClient *client)
{
int ev = nfs_which_events(client->context);
if (ev != client->events) {
qemu_aio_set_fd_handler(nfs_get_fd(client->context),
(ev & POLLIN) ? nfs_process_read : NULL,
(ev & POLLOUT) ? nfs_process_write : NULL,
client);
}
client->events = ev;
}
static void nfs_process_read(void *arg)
{
NFSClient *client = arg;
nfs_service(client->context, POLLIN);
nfs_set_events(client);
}
static void nfs_process_write(void *arg)
{
NFSClient *client = arg;
nfs_service(client->context, POLLOUT);
nfs_set_events(client);
}
static void nfs_co_init_task(NFSClient *client, NFSRPC *task)
{
*task = (NFSRPC) {
.co = qemu_coroutine_self(),
};
}
static void nfs_co_generic_bh_cb(void *opaque)
{
NFSRPC *task = opaque;
qemu_bh_delete(task->bh);
qemu_coroutine_enter(task->co, NULL);
}
static void
nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
void *private_data)
{
NFSRPC *task = private_data;
task->complete = 1;
task->ret = ret;
if (task->ret > 0 && task->iov) {
if (task->ret <= task->iov->size) {
qemu_iovec_from_buf(task->iov, 0, data, task->ret);
} else {
task->ret = -EIO;
}
}
if (task->ret == 0 && task->st) {
memcpy(task->st, data, sizeof(struct stat));
}
if (task->co) {
task->bh = qemu_bh_new(nfs_co_generic_bh_cb, task);
qemu_bh_schedule(task->bh);
}
}
static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov)
{
NFSClient *client = bs->opaque;
NFSRPC task;
nfs_co_init_task(client, &task);
task.iov = iov;
if (nfs_pread_async(client->context, client->fh,
sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE,
nfs_co_generic_cb, &task) != 0) {
return -ENOMEM;
}
while (!task.complete) {
nfs_set_events(client);
qemu_coroutine_yield();
}
if (task.ret < 0) {
return task.ret;
}
/* zero pad short reads */
if (task.ret < iov->size) {
qemu_iovec_memset(iov, task.ret, 0, iov->size - task.ret);
}
return 0;
}
static int coroutine_fn nfs_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov)
{
NFSClient *client = bs->opaque;
NFSRPC task;
char *buf = NULL;
nfs_co_init_task(client, &task);
buf = g_malloc(nb_sectors * BDRV_SECTOR_SIZE);
qemu_iovec_to_buf(iov, 0, buf, nb_sectors * BDRV_SECTOR_SIZE);
if (nfs_pwrite_async(client->context, client->fh,
sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE,
buf, nfs_co_generic_cb, &task) != 0) {
g_free(buf);
return -ENOMEM;
}
while (!task.complete) {
nfs_set_events(client);
qemu_coroutine_yield();
}
g_free(buf);
if (task.ret != nb_sectors * BDRV_SECTOR_SIZE) {
return task.ret < 0 ? task.ret : -EIO;
}
return 0;
}
static int coroutine_fn nfs_co_flush(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
NFSRPC task;
nfs_co_init_task(client, &task);
if (nfs_fsync_async(client->context, client->fh, nfs_co_generic_cb,
&task) != 0) {
return -ENOMEM;
}
while (!task.complete) {
nfs_set_events(client);
qemu_coroutine_yield();
}
return task.ret;
}
/* TODO Convert to fine grained options */
static QemuOptsList runtime_opts = {
.name = "nfs",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "URL to the NFS file",
},
{ /* end of list */ }
},
};
static void nfs_client_close(NFSClient *client)
{
if (client->context) {
if (client->fh) {
nfs_close(client->context, client->fh);
}
qemu_aio_set_fd_handler(nfs_get_fd(client->context), NULL, NULL, NULL);
nfs_destroy_context(client->context);
}
memset(client, 0, sizeof(NFSClient));
}
static void nfs_file_close(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
nfs_client_close(client);
}
static int64_t nfs_client_open(NFSClient *client, const char *filename,
int flags, Error **errp)
{
int ret = -EINVAL, i;
struct stat st;
URI *uri;
QueryParams *qp = NULL;
char *file = NULL, *strp = NULL;
uri = uri_parse(filename);
if (!uri) {
error_setg(errp, "Invalid URL specified");
goto fail;
}
strp = strrchr(uri->path, '/');
if (strp == NULL) {
error_setg(errp, "Invalid URL specified");
goto fail;
}
file = g_strdup(strp);
*strp = 0;
client->context = nfs_init_context();
if (client->context == NULL) {
error_setg(errp, "Failed to init NFS context");
goto fail;
}
qp = query_params_parse(uri->query);
for (i = 0; i < qp->n; i++) {
if (!qp->p[i].value) {
error_setg(errp, "Value for NFS parameter expected: %s",
qp->p[i].name);
goto fail;
}
if (!strncmp(qp->p[i].name, "uid", 3)) {
nfs_set_uid(client->context, atoi(qp->p[i].value));
} else if (!strncmp(qp->p[i].name, "gid", 3)) {
nfs_set_gid(client->context, atoi(qp->p[i].value));
} else if (!strncmp(qp->p[i].name, "tcp-syncnt", 10)) {
nfs_set_tcp_syncnt(client->context, atoi(qp->p[i].value));
} else {
error_setg(errp, "Unknown NFS parameter name: %s",
qp->p[i].name);
goto fail;
}
}
ret = nfs_mount(client->context, uri->server, uri->path);
if (ret < 0) {
error_setg(errp, "Failed to mount nfs share: %s",
nfs_get_error(client->context));
goto fail;
}
if (flags & O_CREAT) {
ret = nfs_creat(client->context, file, 0600, &client->fh);
if (ret < 0) {
error_setg(errp, "Failed to create file: %s",
nfs_get_error(client->context));
goto fail;
}
} else {
ret = nfs_open(client->context, file, flags, &client->fh);
if (ret < 0) {
error_setg(errp, "Failed to open file : %s",
nfs_get_error(client->context));
goto fail;
}
}
ret = nfs_fstat(client->context, client->fh, &st);
if (ret < 0) {
error_setg(errp, "Failed to fstat file: %s",
nfs_get_error(client->context));
goto fail;
}
ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);
client->has_zero_init = S_ISREG(st.st_mode);
goto out;
fail:
nfs_client_close(client);
out:
if (qp) {
query_params_free(qp);
}
uri_free(uri);
g_free(file);
return ret;
}
static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) {
NFSClient *client = bs->opaque;
int64_t ret;
QemuOpts *opts;
Error *local_err = NULL;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
return -EINVAL;
}
ret = nfs_client_open(client, qemu_opt_get(opts, "filename"),
(flags & BDRV_O_RDWR) ? O_RDWR : O_RDONLY,
errp);
if (ret < 0) {
return ret;
}
bs->total_sectors = ret;
return 0;
}
static int nfs_file_create(const char *url, QEMUOptionParameter *options,
Error **errp)
{
int ret = 0;
int64_t total_size = 0;
NFSClient *client = g_malloc0(sizeof(NFSClient));
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, "size")) {
total_size = options->value.n;
}
options++;
}
ret = nfs_client_open(client, url, O_CREAT, errp);
if (ret < 0) {
goto out;
}
ret = nfs_ftruncate(client->context, client->fh, total_size);
nfs_client_close(client);
out:
g_free(client);
return ret;
}
static int nfs_has_zero_init(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
return client->has_zero_init;
}
static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
NFSRPC task = {0};
struct stat st;
task.st = &st;
if (nfs_fstat_async(client->context, client->fh, nfs_co_generic_cb,
&task) != 0) {
return -ENOMEM;
}
while (!task.complete) {
nfs_set_events(client);
qemu_aio_wait();
}
return (task.ret < 0 ? task.ret : st.st_blocks * st.st_blksize);
}
static int nfs_file_truncate(BlockDriverState *bs, int64_t offset)
{
NFSClient *client = bs->opaque;
return nfs_ftruncate(client->context, client->fh, offset);
}
static BlockDriver bdrv_nfs = {
.format_name = "nfs",
.protocol_name = "nfs",
.instance_size = sizeof(NFSClient),
.bdrv_needs_filename = true,
.bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
.bdrv_truncate = nfs_file_truncate,
.bdrv_file_open = nfs_file_open,
.bdrv_close = nfs_file_close,
.bdrv_create = nfs_file_create,
.bdrv_co_readv = nfs_co_readv,
.bdrv_co_writev = nfs_co_writev,
.bdrv_co_flush_to_disk = nfs_co_flush,
};
static void nfs_block_init(void)
{
bdrv_register(&bdrv_nfs);
}
block_init(nfs_block_init);

View File

@@ -85,7 +85,8 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
if (memcmp(ph.magic, HEADER_MAGIC, 16) || if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
(le32_to_cpu(ph.version) != HEADER_VERSION)) { (le32_to_cpu(ph.version) != HEADER_VERSION)) {
ret = -EMEDIUMTYPE; error_setg(errp, "Image not in Parallels format");
ret = -EINVAL;
goto fail; goto fail;
} }

View File

@@ -271,7 +271,7 @@ void bdrv_query_info(BlockDriverState *bs,
p_image_info = &info->inserted->image; p_image_info = &info->inserted->image;
while (1) { while (1) {
bdrv_query_image_info(bs0, p_image_info, &local_err); bdrv_query_image_info(bs0, p_image_info, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto err; goto err;
} }
@@ -336,7 +336,7 @@ BlockInfoList *qmp_query_block(Error **errp)
while ((bs = bdrv_next(bs))) { while ((bs = bdrv_next(bs))) {
BlockInfoList *info = g_malloc0(sizeof(*info)); BlockInfoList *info = g_malloc0(sizeof(*info));
bdrv_query_info(bs, &info->value, &local_err); bdrv_query_info(bs, &info->value, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto err; goto err;
} }

View File

@@ -113,23 +113,26 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
be64_to_cpus(&header.l1_table_offset); be64_to_cpus(&header.l1_table_offset);
if (header.magic != QCOW_MAGIC) { if (header.magic != QCOW_MAGIC) {
ret = -EMEDIUMTYPE; error_setg(errp, "Image not in qcow format");
ret = -EINVAL;
goto fail; goto fail;
} }
if (header.version != QCOW_VERSION) { if (header.version != QCOW_VERSION) {
char version[64]; char version[64];
snprintf(version, sizeof(version), "QCOW version %d", header.version); snprintf(version, sizeof(version), "QCOW version %d", header.version);
qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "qcow", version); bs->device_name, "qcow", version);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} }
if (header.size <= 1 || header.cluster_bits < 9) { if (header.size <= 1 || header.cluster_bits < 9) {
error_setg(errp, "invalid value in qcow header");
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
if (header.crypt_method > QCOW_CRYPT_AES) { if (header.crypt_method > QCOW_CRYPT_AES) {
error_setg(errp, "invalid encryption method in qcow header");
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
@@ -686,16 +689,15 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
ret = bdrv_create_file(filename, options, &local_err); ret = bdrv_create_file(filename, options, &local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
return ret; return ret;
} }
ret = bdrv_file_open(&qcow_bs, filename, NULL, NULL, BDRV_O_RDWR, qcow_bs = NULL;
&local_err); ret = bdrv_open(&qcow_bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
return ret; return ret;
} }

View File

@@ -1182,7 +1182,7 @@ fail:
* Return 0 on success and -errno in error cases * Return 0 on success and -errno in error cases
*/ */
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m) int *num, uint64_t *host_offset, QCowL2Meta **m)
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
uint64_t start, remaining; uint64_t start, remaining;
@@ -1190,15 +1190,13 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
uint64_t cur_bytes; uint64_t cur_bytes;
int ret; int ret;
trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, *num);
n_start, n_end);
assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset)); assert((offset & ~BDRV_SECTOR_MASK) == 0);
offset = start_of_cluster(s, offset);
again: again:
start = offset + (n_start << BDRV_SECTOR_BITS); start = offset;
remaining = (n_end - n_start) << BDRV_SECTOR_BITS; remaining = *num << BDRV_SECTOR_BITS;
cluster_offset = 0; cluster_offset = 0;
*host_offset = 0; *host_offset = 0;
cur_bytes = 0; cur_bytes = 0;
@@ -1284,7 +1282,7 @@ again:
} }
} }
*num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS); *num -= remaining >> BDRV_SECTOR_BITS;
assert(*num > 0); assert(*num > 0);
assert(*host_offset != 0); assert(*host_offset != 0);
@@ -1369,13 +1367,31 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
uint64_t old_offset; uint64_t old_offset;
old_offset = be64_to_cpu(l2_table[l2_index + i]); old_offset = be64_to_cpu(l2_table[l2_index + i]);
if ((old_offset & L2E_OFFSET_MASK) == 0) {
/*
* Make sure that a discarded area reads back as zeroes for v3 images
* (we cannot do it for v2 without actually writing a zero-filled
* buffer). We can skip the operation if the cluster is already marked
* as zero, or if it's unallocated and we don't have a backing file.
*
* TODO We might want to use bdrv_get_block_status(bs) here, but we're
* holding s->lock, so that doesn't work today.
*/
if (old_offset & QCOW_OFLAG_ZERO) {
continue;
}
if ((old_offset & L2E_OFFSET_MASK) == 0 && !bs->backing_hd) {
continue; continue;
} }
/* First remove L2 entries */ /* First remove L2 entries */
qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
l2_table[l2_index + i] = cpu_to_be64(0); if (s->qcow_version >= 3) {
l2_table[l2_index + i] = cpu_to_be64(QCOW_OFLAG_ZERO);
} else {
l2_table[l2_index + i] = cpu_to_be64(0);
}
/* Then decrease the refcount */ /* Then decrease the refcount */
qcow2_free_any_clusters(bs, old_offset, 1, type); qcow2_free_any_clusters(bs, old_offset, 1, type);

View File

@@ -676,7 +676,13 @@ int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
uint64_t cluster_index; uint64_t cluster_index;
uint64_t old_free_cluster_index; uint64_t old_free_cluster_index;
int i, refcount, ret; uint64_t i;
int refcount, ret;
assert(nb_clusters >= 0);
if (nb_clusters == 0) {
return 0;
}
/* Check how many clusters there are free */ /* Check how many clusters there are free */
cluster_index = offset >> s->cluster_bits; cluster_index = offset >> s->cluster_bits;

View File

@@ -606,7 +606,8 @@ int qcow2_snapshot_delete(BlockDriverState *bs,
s->nb_snapshots--; s->nb_snapshots--;
ret = qcow2_write_snapshots(bs); ret = qcow2_write_snapshots(bs);
if (ret < 0) { if (ret < 0) {
error_setg(errp, "Failed to remove snapshot from snapshot list"); error_setg_errno(errp, -ret,
"Failed to remove snapshot from snapshot list");
return ret; return ret;
} }
@@ -624,7 +625,7 @@ int qcow2_snapshot_delete(BlockDriverState *bs,
ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset, ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset,
sn.l1_size, -1); sn.l1_size, -1);
if (ret < 0) { if (ret < 0) {
error_setg(errp, "Failed to free the cluster and L1 table"); error_setg_errno(errp, -ret, "Failed to free the cluster and L1 table");
return ret; return ret;
} }
qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t), qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t),
@@ -633,7 +634,8 @@ int qcow2_snapshot_delete(BlockDriverState *bs,
/* must update the copied flag on the current cluster offsets */ /* must update the copied flag on the current cluster offsets */
ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
if (ret < 0) { if (ret < 0) {
error_setg(errp, "Failed to update snapshot status in disk"); error_setg_errno(errp, -ret,
"Failed to update snapshot status in disk");
return ret; return ret;
} }

View File

@@ -449,7 +449,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
if (header.magic != QCOW_MAGIC) { if (header.magic != QCOW_MAGIC) {
error_setg(errp, "Image is not in qcow2 format"); error_setg(errp, "Image is not in qcow2 format");
ret = -EMEDIUMTYPE; ret = -EINVAL;
goto fail; goto fail;
} }
if (header.version < 2 || header.version > 3) { if (header.version < 2 || header.version > 3) {
@@ -671,7 +671,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
/* Enable lazy_refcounts according to image and command line options */ /* Enable lazy_refcounts according to image and command line options */
opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
@@ -1000,7 +1000,6 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
int index_in_cluster; int index_in_cluster;
int n_end;
int ret; int ret;
int cur_nr_sectors; /* number of sectors in current iteration */ int cur_nr_sectors; /* number of sectors in current iteration */
uint64_t cluster_offset; uint64_t cluster_offset;
@@ -1024,14 +1023,16 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
trace_qcow2_writev_start_part(qemu_coroutine_self()); trace_qcow2_writev_start_part(qemu_coroutine_self());
index_in_cluster = sector_num & (s->cluster_sectors - 1); index_in_cluster = sector_num & (s->cluster_sectors - 1);
n_end = index_in_cluster + remaining_sectors; cur_nr_sectors = remaining_sectors;
if (s->crypt_method && if (s->crypt_method &&
n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) { cur_nr_sectors >
n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors - index_in_cluster) {
cur_nr_sectors =
QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors - index_in_cluster;
} }
ret = qcow2_alloc_cluster_offset(bs, sector_num << 9, ret = qcow2_alloc_cluster_offset(bs, sector_num << 9,
index_in_cluster, n_end, &cur_nr_sectors, &cluster_offset, &l2meta); &cur_nr_sectors, &cluster_offset, &l2meta);
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;
} }
@@ -1403,34 +1404,34 @@ static int preallocate(BlockDriverState *bs)
int ret; int ret;
QCowL2Meta *meta; QCowL2Meta *meta;
nb_sectors = bdrv_getlength(bs) >> 9; nb_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
offset = 0; offset = 0;
while (nb_sectors) { while (nb_sectors) {
num = MIN(nb_sectors, INT_MAX >> 9); num = MIN(nb_sectors, INT_MAX >> BDRV_SECTOR_BITS);
ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, ret = qcow2_alloc_cluster_offset(bs, offset, &num,
&host_offset, &meta); &host_offset, &meta);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
ret = qcow2_alloc_cluster_link_l2(bs, meta);
if (ret < 0) {
qcow2_free_any_clusters(bs, meta->alloc_offset, meta->nb_clusters,
QCOW2_DISCARD_NEVER);
return ret;
}
/* There are no dependent requests, but we need to remove our request
* from the list of in-flight requests */
if (meta != NULL) { if (meta != NULL) {
ret = qcow2_alloc_cluster_link_l2(bs, meta);
if (ret < 0) {
qcow2_free_any_clusters(bs, meta->alloc_offset,
meta->nb_clusters, QCOW2_DISCARD_NEVER);
return ret;
}
/* There are no dependent requests, but we need to remove our
* request from the list of in-flight requests */
QLIST_REMOVE(meta, next_in_flight); QLIST_REMOVE(meta, next_in_flight);
} }
/* TODO Preallocate data if requested */ /* TODO Preallocate data if requested */
nb_sectors -= num; nb_sectors -= num;
offset += num << 9; offset += num << BDRV_SECTOR_BITS;
} }
/* /*
@@ -1439,9 +1440,10 @@ static int preallocate(BlockDriverState *bs)
* EOF). Extend the image to the last allocated sector. * EOF). Extend the image to the last allocated sector.
*/ */
if (host_offset != 0) { if (host_offset != 0) {
uint8_t buf[512]; uint8_t buf[BDRV_SECTOR_SIZE];
memset(buf, 0, 512); memset(buf, 0, BDRV_SECTOR_SIZE);
ret = bdrv_write(bs->file, (host_offset >> 9) + num - 1, buf, 1); ret = bdrv_write(bs->file, (host_offset >> BDRV_SECTOR_BITS) + num - 1,
buf, 1);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@@ -1491,7 +1493,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
return ret; return ret;
} }
ret = bdrv_file_open(&bs, filename, NULL, NULL, BDRV_O_RDWR, &local_err); bs = NULL;
ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
NULL, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return ret; return ret;
@@ -1541,7 +1545,8 @@ static int qcow2_create2(const char *filename, int64_t total_size,
goto out; goto out;
} }
bdrv_close(bs); bdrv_unref(bs);
bs = NULL;
/* /*
* And now open the image and make it consistent first (i.e. increase the * And now open the image and make it consistent first (i.e. increase the
@@ -1550,7 +1555,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
*/ */
BlockDriver* drv = bdrv_find_format("qcow2"); BlockDriver* drv = bdrv_find_format("qcow2");
assert(drv != NULL); assert(drv != NULL);
ret = bdrv_open(bs, filename, NULL, ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err); BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
@@ -1597,20 +1602,23 @@ static int qcow2_create2(const char *filename, int64_t total_size,
} }
} }
bdrv_close(bs); bdrv_unref(bs);
bs = NULL;
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */ /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
ret = bdrv_open(bs, filename, NULL, ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
drv, &local_err); drv, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto out; goto out;
} }
ret = 0; ret = 0;
out: out:
bdrv_unref(bs); if (bs) {
bdrv_unref(bs);
}
return ret; return ret;
} }
@@ -1683,32 +1691,12 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options,
ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags, ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
cluster_size, prealloc, options, version, &local_err); cluster_size, prealloc, options, version, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
} }
static int qcow2_make_empty(BlockDriverState *bs)
{
#if 0
/* XXX: not correct */
BDRVQcowState *s = bs->opaque;
uint32_t l1_length = s->l1_size * sizeof(uint64_t);
int ret;
memset(s->l1_table, 0, l1_length);
if (bdrv_pwrite(bs->file, s->l1_table_offset, s->l1_table, l1_length) < 0)
return -1;
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
if (ret < 0)
return ret;
l2_cache_reset(bs);
#endif
return 0;
}
static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs, static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
{ {
@@ -2252,7 +2240,6 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_co_get_block_status = qcow2_co_get_block_status, .bdrv_co_get_block_status = qcow2_co_get_block_status,
.bdrv_set_key = qcow2_set_key, .bdrv_set_key = qcow2_set_key,
.bdrv_make_empty = qcow2_make_empty,
.bdrv_co_readv = qcow2_co_readv, .bdrv_co_readv = qcow2_co_readv,
.bdrv_co_writev = qcow2_co_writev, .bdrv_co_writev = qcow2_co_writev,

View File

@@ -468,7 +468,7 @@ void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
int *num, uint64_t *cluster_offset); int *num, uint64_t *cluster_offset);
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m); int *num, uint64_t *host_offset, QCowL2Meta **m);
uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
uint64_t offset, uint64_t offset,
int compressed_size); int compressed_size);

View File

@@ -391,14 +391,15 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
qed_header_le_to_cpu(&le_header, &s->header); qed_header_le_to_cpu(&le_header, &s->header);
if (s->header.magic != QED_MAGIC) { if (s->header.magic != QED_MAGIC) {
return -EMEDIUMTYPE; error_setg(errp, "Image not in QED format");
return -EINVAL;
} }
if (s->header.features & ~QED_FEATURE_MASK) { if (s->header.features & ~QED_FEATURE_MASK) {
/* image uses unsupported feature bits */ /* image uses unsupported feature bits */
char buf[64]; char buf[64];
snprintf(buf, sizeof(buf), "%" PRIx64, snprintf(buf, sizeof(buf), "%" PRIx64,
s->header.features & ~QED_FEATURE_MASK); s->header.features & ~QED_FEATURE_MASK);
qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "QED", buf); bs->device_name, "QED", buf);
return -ENOTSUP; return -ENOTSUP;
} }
@@ -545,7 +546,8 @@ static void bdrv_qed_close(BlockDriverState *bs)
static int qed_create(const char *filename, uint32_t cluster_size, static int qed_create(const char *filename, uint32_t cluster_size,
uint64_t image_size, uint32_t table_size, uint64_t image_size, uint32_t table_size,
const char *backing_file, const char *backing_fmt) const char *backing_file, const char *backing_fmt,
Error **errp)
{ {
QEDHeader header = { QEDHeader header = {
.magic = QED_MAGIC, .magic = QED_MAGIC,
@@ -562,20 +564,20 @@ static int qed_create(const char *filename, uint32_t cluster_size,
size_t l1_size = header.cluster_size * header.table_size; size_t l1_size = header.cluster_size * header.table_size;
Error *local_err = NULL; Error *local_err = NULL;
int ret = 0; int ret = 0;
BlockDriverState *bs = NULL; BlockDriverState *bs;
ret = bdrv_create_file(filename, NULL, &local_err); ret = bdrv_create_file(filename, NULL, &local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
return ret; return ret;
} }
ret = bdrv_file_open(&bs, filename, NULL, NULL, bs = NULL;
BDRV_O_RDWR | BDRV_O_CACHE_WB, &local_err); ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_PROTOCOL, NULL,
&local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
return ret; return ret;
} }
@@ -665,7 +667,7 @@ static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options,
} }
return qed_create(filename, cluster_size, image_size, table_size, return qed_create(filename, cluster_size, image_size, table_size,
backing_file, backing_fmt); backing_file, backing_fmt, errp);
} }
typedef struct { typedef struct {
@@ -731,11 +733,6 @@ static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs,
return cb.status; return cb.status;
} }
static int bdrv_qed_make_empty(BlockDriverState *bs)
{
return -ENOTSUP;
}
static BDRVQEDState *acb_to_s(QEDAIOCB *acb) static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
{ {
return acb->common.bs->opaque; return acb->common.bs->opaque;
@@ -1617,7 +1614,6 @@ static BlockDriver bdrv_qed = {
.bdrv_create = bdrv_qed_create, .bdrv_create = bdrv_qed_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_co_get_block_status = bdrv_qed_co_get_block_status, .bdrv_co_get_block_status = bdrv_qed_co_get_block_status,
.bdrv_make_empty = bdrv_qed_make_empty,
.bdrv_aio_readv = bdrv_qed_aio_readv, .bdrv_aio_readv = bdrv_qed_aio_readv,
.bdrv_aio_writev = bdrv_qed_aio_writev, .bdrv_aio_writev = bdrv_qed_aio_writev,
.bdrv_co_write_zeroes = bdrv_qed_co_write_zeroes, .bdrv_co_write_zeroes = bdrv_qed_co_write_zeroes,

873
block/quorum.c Normal file
View File

@@ -0,0 +1,873 @@
/*
* Quorum Block filter
*
* Copyright (C) 2012-2014 Nodalink, EURL.
*
* Author:
* Benoît Canet <benoit.canet@irqsave.net>
*
* Based on the design and code of blkverify.c (Copyright (C) 2010 IBM, Corp)
* and blkmirror.c (Copyright (C) 2011 Red Hat, Inc).
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include "block/block_int.h"
#include "qapi/qmp/qjson.h"
#define HASH_LENGTH 32
#define QUORUM_OPT_VOTE_THRESHOLD "vote-threshold"
#define QUORUM_OPT_BLKVERIFY "blkverify"
/* This union holds a vote hash value */
typedef union QuorumVoteValue {
char h[HASH_LENGTH]; /* SHA-256 hash */
int64_t l; /* simpler 64 bits hash */
} QuorumVoteValue;
/* A vote item */
typedef struct QuorumVoteItem {
int index;
QLIST_ENTRY(QuorumVoteItem) next;
} QuorumVoteItem;
/* this structure is a vote version. A version is the set of votes sharing the
* same vote value.
* The set of votes will be tracked with the items field and its cardinality is
* vote_count.
*/
typedef struct QuorumVoteVersion {
QuorumVoteValue value;
int index;
int vote_count;
QLIST_HEAD(, QuorumVoteItem) items;
QLIST_ENTRY(QuorumVoteVersion) next;
} QuorumVoteVersion;
/* this structure holds a group of vote versions together */
typedef struct QuorumVotes {
QLIST_HEAD(, QuorumVoteVersion) vote_list;
bool (*compare)(QuorumVoteValue *a, QuorumVoteValue *b);
} QuorumVotes;
/* the following structure holds the state of one quorum instance */
typedef struct BDRVQuorumState {
BlockDriverState **bs; /* children BlockDriverStates */
int num_children; /* children count */
int threshold; /* if less than threshold children reads gave the
* same result a quorum error occurs.
*/
bool is_blkverify; /* true if the driver is in blkverify mode
* Writes are mirrored on two children devices.
* On reads the two children devices' contents are
* compared and if a difference is spotted its
* location is printed and the code aborts.
* It is useful to debug other block drivers by
* comparing them with a reference one.
*/
} BDRVQuorumState;
typedef struct QuorumAIOCB QuorumAIOCB;
/* Quorum will create one instance of the following structure per operation it
* performs on its children.
* So for each read/write operation coming from the upper layer there will be
* $children_count QuorumChildRequest.
*/
typedef struct QuorumChildRequest {
BlockDriverAIOCB *aiocb;
QEMUIOVector qiov;
uint8_t *buf;
int ret;
QuorumAIOCB *parent;
} QuorumChildRequest;
/* Quorum will use the following structure to track progress of each read/write
* operation received by the upper layer.
* This structure hold pointers to the QuorumChildRequest structures instances
* used to do operations on each children and track overall progress.
*/
struct QuorumAIOCB {
BlockDriverAIOCB common;
/* Request metadata */
uint64_t sector_num;
int nb_sectors;
QEMUIOVector *qiov; /* calling IOV */
QuorumChildRequest *qcrs; /* individual child requests */
int count; /* number of completed AIOCB */
int success_count; /* number of successfully completed AIOCB */
QuorumVotes votes;
bool is_read;
int vote_ret;
};
static void quorum_vote(QuorumAIOCB *acb);
static void quorum_aio_cancel(BlockDriverAIOCB *blockacb)
{
QuorumAIOCB *acb = container_of(blockacb, QuorumAIOCB, common);
BDRVQuorumState *s = acb->common.bs->opaque;
int i;
/* cancel all callbacks */
for (i = 0; i < s->num_children; i++) {
bdrv_aio_cancel(acb->qcrs[i].aiocb);
}
g_free(acb->qcrs);
qemu_aio_release(acb);
}
static AIOCBInfo quorum_aiocb_info = {
.aiocb_size = sizeof(QuorumAIOCB),
.cancel = quorum_aio_cancel,
};
static void quorum_aio_finalize(QuorumAIOCB *acb)
{
BDRVQuorumState *s = acb->common.bs->opaque;
int i, ret = 0;
if (acb->vote_ret) {
ret = acb->vote_ret;
}
acb->common.cb(acb->common.opaque, ret);
if (acb->is_read) {
for (i = 0; i < s->num_children; i++) {
qemu_vfree(acb->qcrs[i].buf);
qemu_iovec_destroy(&acb->qcrs[i].qiov);
}
}
g_free(acb->qcrs);
qemu_aio_release(acb);
}
static bool quorum_sha256_compare(QuorumVoteValue *a, QuorumVoteValue *b)
{
return !memcmp(a->h, b->h, HASH_LENGTH);
}
static bool quorum_64bits_compare(QuorumVoteValue *a, QuorumVoteValue *b)
{
return a->l == b->l;
}
static QuorumAIOCB *quorum_aio_get(BDRVQuorumState *s,
BlockDriverState *bs,
QEMUIOVector *qiov,
uint64_t sector_num,
int nb_sectors,
BlockDriverCompletionFunc *cb,
void *opaque)
{
QuorumAIOCB *acb = qemu_aio_get(&quorum_aiocb_info, bs, cb, opaque);
int i;
acb->common.bs->opaque = s;
acb->sector_num = sector_num;
acb->nb_sectors = nb_sectors;
acb->qiov = qiov;
acb->qcrs = g_new0(QuorumChildRequest, s->num_children);
acb->count = 0;
acb->success_count = 0;
acb->votes.compare = quorum_sha256_compare;
QLIST_INIT(&acb->votes.vote_list);
acb->is_read = false;
acb->vote_ret = 0;
for (i = 0; i < s->num_children; i++) {
acb->qcrs[i].buf = NULL;
acb->qcrs[i].ret = 0;
acb->qcrs[i].parent = acb;
}
return acb;
}
static void quorum_report_bad(QuorumAIOCB *acb, char *node_name, int ret)
{
QObject *data;
assert(node_name);
data = qobject_from_jsonf("{ 'node-name': %s"
", 'sector-num': %" PRId64
", 'sectors-count': %d }",
node_name, acb->sector_num, acb->nb_sectors);
if (ret < 0) {
QDict *dict = qobject_to_qdict(data);
qdict_put(dict, "error", qstring_from_str(strerror(-ret)));
}
monitor_protocol_event(QEVENT_QUORUM_REPORT_BAD, data);
qobject_decref(data);
}
static void quorum_report_failure(QuorumAIOCB *acb)
{
QObject *data;
const char *reference = acb->common.bs->device_name[0] ?
acb->common.bs->device_name :
acb->common.bs->node_name;
data = qobject_from_jsonf("{ 'reference': %s"
", 'sector-num': %" PRId64
", 'sectors-count': %d }",
reference, acb->sector_num, acb->nb_sectors);
monitor_protocol_event(QEVENT_QUORUM_FAILURE, data);
qobject_decref(data);
}
static int quorum_vote_error(QuorumAIOCB *acb);
static bool quorum_has_too_much_io_failed(QuorumAIOCB *acb)
{
BDRVQuorumState *s = acb->common.bs->opaque;
if (acb->success_count < s->threshold) {
acb->vote_ret = quorum_vote_error(acb);
quorum_report_failure(acb);
return true;
}
return false;
}
static void quorum_aio_cb(void *opaque, int ret)
{
QuorumChildRequest *sacb = opaque;
QuorumAIOCB *acb = sacb->parent;
BDRVQuorumState *s = acb->common.bs->opaque;
sacb->ret = ret;
acb->count++;
if (ret == 0) {
acb->success_count++;
} else {
quorum_report_bad(acb, sacb->aiocb->bs->node_name, ret);
}
assert(acb->count <= s->num_children);
assert(acb->success_count <= s->num_children);
if (acb->count < s->num_children) {
return;
}
/* Do the vote on read */
if (acb->is_read) {
quorum_vote(acb);
} else {
quorum_has_too_much_io_failed(acb);
}
quorum_aio_finalize(acb);
}
static void quorum_report_bad_versions(BDRVQuorumState *s,
QuorumAIOCB *acb,
QuorumVoteValue *value)
{
QuorumVoteVersion *version;
QuorumVoteItem *item;
QLIST_FOREACH(version, &acb->votes.vote_list, next) {
if (acb->votes.compare(&version->value, value)) {
continue;
}
QLIST_FOREACH(item, &version->items, next) {
quorum_report_bad(acb, s->bs[item->index]->node_name, 0);
}
}
}
static void quorum_copy_qiov(QEMUIOVector *dest, QEMUIOVector *source)
{
int i;
assert(dest->niov == source->niov);
assert(dest->size == source->size);
for (i = 0; i < source->niov; i++) {
assert(dest->iov[i].iov_len == source->iov[i].iov_len);
memcpy(dest->iov[i].iov_base,
source->iov[i].iov_base,
source->iov[i].iov_len);
}
}
static void quorum_count_vote(QuorumVotes *votes,
QuorumVoteValue *value,
int index)
{
QuorumVoteVersion *v = NULL, *version = NULL;
QuorumVoteItem *item;
/* look if we have something with this hash */
QLIST_FOREACH(v, &votes->vote_list, next) {
if (votes->compare(&v->value, value)) {
version = v;
break;
}
}
/* It's a version not yet in the list add it */
if (!version) {
version = g_new0(QuorumVoteVersion, 1);
QLIST_INIT(&version->items);
memcpy(&version->value, value, sizeof(version->value));
version->index = index;
version->vote_count = 0;
QLIST_INSERT_HEAD(&votes->vote_list, version, next);
}
version->vote_count++;
item = g_new0(QuorumVoteItem, 1);
item->index = index;
QLIST_INSERT_HEAD(&version->items, item, next);
}
static void quorum_free_vote_list(QuorumVotes *votes)
{
QuorumVoteVersion *version, *next_version;
QuorumVoteItem *item, *next_item;
QLIST_FOREACH_SAFE(version, &votes->vote_list, next, next_version) {
QLIST_REMOVE(version, next);
QLIST_FOREACH_SAFE(item, &version->items, next, next_item) {
QLIST_REMOVE(item, next);
g_free(item);
}
g_free(version);
}
}
static int quorum_compute_hash(QuorumAIOCB *acb, int i, QuorumVoteValue *hash)
{
int j, ret;
gnutls_hash_hd_t dig;
QEMUIOVector *qiov = &acb->qcrs[i].qiov;
ret = gnutls_hash_init(&dig, GNUTLS_DIG_SHA256);
if (ret < 0) {
return ret;
}
for (j = 0; j < qiov->niov; j++) {
ret = gnutls_hash(dig, qiov->iov[j].iov_base, qiov->iov[j].iov_len);
if (ret < 0) {
break;
}
}
gnutls_hash_deinit(dig, (void *) hash);
return ret;
}
static QuorumVoteVersion *quorum_get_vote_winner(QuorumVotes *votes)
{
int max = 0;
QuorumVoteVersion *candidate, *winner = NULL;
QLIST_FOREACH(candidate, &votes->vote_list, next) {
if (candidate->vote_count > max) {
max = candidate->vote_count;
winner = candidate;
}
}
return winner;
}
/* qemu_iovec_compare is handy for blkverify mode because it returns the first
* differing byte location. Yet it is handcoded to compare vectors one byte
* after another so it does not benefit from the libc SIMD optimizations.
* quorum_iovec_compare is written for speed and should be used in the non
* blkverify mode of quorum.
*/
static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
{
int i;
int result;
assert(a->niov == b->niov);
for (i = 0; i < a->niov; i++) {
assert(a->iov[i].iov_len == b->iov[i].iov_len);
result = memcmp(a->iov[i].iov_base,
b->iov[i].iov_base,
a->iov[i].iov_len);
if (result) {
return false;
}
}
return true;
}
static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "quorum: sector_num=%" PRId64 " nb_sectors=%d ",
acb->sector_num, acb->nb_sectors);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(1);
}
static bool quorum_compare(QuorumAIOCB *acb,
QEMUIOVector *a,
QEMUIOVector *b)
{
BDRVQuorumState *s = acb->common.bs->opaque;
ssize_t offset;
/* This driver will replace blkverify in this particular case */
if (s->is_blkverify) {
offset = qemu_iovec_compare(a, b);
if (offset != -1) {
quorum_err(acb, "contents mismatch in sector %" PRId64,
acb->sector_num +
(uint64_t)(offset / BDRV_SECTOR_SIZE));
}
return true;
}
return quorum_iovec_compare(a, b);
}
/* Do a vote to get the error code */
static int quorum_vote_error(QuorumAIOCB *acb)
{
BDRVQuorumState *s = acb->common.bs->opaque;
QuorumVoteVersion *winner = NULL;
QuorumVotes error_votes;
QuorumVoteValue result_value;
int i, ret = 0;
bool error = false;
QLIST_INIT(&error_votes.vote_list);
error_votes.compare = quorum_64bits_compare;
for (i = 0; i < s->num_children; i++) {
ret = acb->qcrs[i].ret;
if (ret) {
error = true;
result_value.l = ret;
quorum_count_vote(&error_votes, &result_value, i);
}
}
if (error) {
winner = quorum_get_vote_winner(&error_votes);
ret = winner->value.l;
}
quorum_free_vote_list(&error_votes);
return ret;
}
static void quorum_vote(QuorumAIOCB *acb)
{
bool quorum = true;
int i, j, ret;
QuorumVoteValue hash;
BDRVQuorumState *s = acb->common.bs->opaque;
QuorumVoteVersion *winner;
if (quorum_has_too_much_io_failed(acb)) {
return;
}
/* get the index of the first successful read */
for (i = 0; i < s->num_children; i++) {
if (!acb->qcrs[i].ret) {
break;
}
}
assert(i < s->num_children);
/* compare this read with all other successful reads stopping at quorum
* failure
*/
for (j = i + 1; j < s->num_children; j++) {
if (acb->qcrs[j].ret) {
continue;
}
quorum = quorum_compare(acb, &acb->qcrs[i].qiov, &acb->qcrs[j].qiov);
if (!quorum) {
break;
}
}
/* Every successful read agrees */
if (quorum) {
quorum_copy_qiov(acb->qiov, &acb->qcrs[i].qiov);
return;
}
/* compute hashes for each successful read, also store indexes */
for (i = 0; i < s->num_children; i++) {
if (acb->qcrs[i].ret) {
continue;
}
ret = quorum_compute_hash(acb, i, &hash);
/* if ever the hash computation failed */
if (ret < 0) {
acb->vote_ret = ret;
goto free_exit;
}
quorum_count_vote(&acb->votes, &hash, i);
}
/* vote to select the most represented version */
winner = quorum_get_vote_winner(&acb->votes);
/* if the winner count is smaller than threshold the read fails */
if (winner->vote_count < s->threshold) {
quorum_report_failure(acb);
acb->vote_ret = -EIO;
goto free_exit;
}
/* we have a winner: copy it */
quorum_copy_qiov(acb->qiov, &acb->qcrs[winner->index].qiov);
/* some versions are bad print them */
quorum_report_bad_versions(s, acb, &winner->value);
free_exit:
/* free lists */
quorum_free_vote_list(&acb->votes);
}
static BlockDriverAIOCB *quorum_aio_readv(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
BlockDriverCompletionFunc *cb,
void *opaque)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(s, bs, qiov, sector_num,
nb_sectors, cb, opaque);
int i;
acb->is_read = true;
for (i = 0; i < s->num_children; i++) {
acb->qcrs[i].buf = qemu_blockalign(s->bs[i], qiov->size);
qemu_iovec_init(&acb->qcrs[i].qiov, qiov->niov);
qemu_iovec_clone(&acb->qcrs[i].qiov, qiov, acb->qcrs[i].buf);
}
for (i = 0; i < s->num_children; i++) {
bdrv_aio_readv(s->bs[i], sector_num, &acb->qcrs[i].qiov, nb_sectors,
quorum_aio_cb, &acb->qcrs[i]);
}
return &acb->common;
}
static BlockDriverAIOCB *quorum_aio_writev(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
BlockDriverCompletionFunc *cb,
void *opaque)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(s, bs, qiov, sector_num, nb_sectors,
cb, opaque);
int i;
for (i = 0; i < s->num_children; i++) {
acb->qcrs[i].aiocb = bdrv_aio_writev(s->bs[i], sector_num, qiov,
nb_sectors, &quorum_aio_cb,
&acb->qcrs[i]);
}
return &acb->common;
}
static int64_t quorum_getlength(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
int64_t result;
int i;
/* check that all file have the same length */
result = bdrv_getlength(s->bs[0]);
if (result < 0) {
return result;
}
for (i = 1; i < s->num_children; i++) {
int64_t value = bdrv_getlength(s->bs[i]);
if (value < 0) {
return value;
}
if (value != result) {
return -EIO;
}
}
return result;
}
static void quorum_invalidate_cache(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
int i;
for (i = 0; i < s->num_children; i++) {
bdrv_invalidate_cache(s->bs[i]);
}
}
static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
QuorumVoteVersion *winner = NULL;
QuorumVotes error_votes;
QuorumVoteValue result_value;
int i;
int result = 0;
QLIST_INIT(&error_votes.vote_list);
error_votes.compare = quorum_64bits_compare;
for (i = 0; i < s->num_children; i++) {
result = bdrv_co_flush(s->bs[i]);
result_value.l = result;
quorum_count_vote(&error_votes, &result_value, i);
}
winner = quorum_get_vote_winner(&error_votes);
result = winner->value.l;
quorum_free_vote_list(&error_votes);
return result;
}
static bool quorum_recurse_is_first_non_filter(BlockDriverState *bs,
BlockDriverState *candidate)
{
BDRVQuorumState *s = bs->opaque;
int i;
for (i = 0; i < s->num_children; i++) {
bool perm = bdrv_recurse_is_first_non_filter(s->bs[i],
candidate);
if (perm) {
return true;
}
}
return false;
}
static int quorum_valid_threshold(int threshold, int num_children, Error **errp)
{
if (threshold < 1) {
error_set(errp, QERR_INVALID_PARAMETER_VALUE,
"vote-threshold", "value >= 1");
return -ERANGE;
}
if (threshold > num_children) {
error_setg(errp, "threshold may not exceed children count");
return -ERANGE;
}
return 0;
}
static QemuOptsList quorum_runtime_opts = {
.name = "quorum",
.head = QTAILQ_HEAD_INITIALIZER(quorum_runtime_opts.head),
.desc = {
{
.name = QUORUM_OPT_VOTE_THRESHOLD,
.type = QEMU_OPT_NUMBER,
.help = "The number of vote needed for reaching quorum",
},
{
.name = QUORUM_OPT_BLKVERIFY,
.type = QEMU_OPT_BOOL,
.help = "Trigger block verify mode if set",
},
{ /* end of list */ }
},
};
static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
BDRVQuorumState *s = bs->opaque;
Error *local_err = NULL;
QemuOpts *opts;
bool *opened;
QDict *sub = NULL;
QList *list = NULL;
const QListEntry *lentry;
int i;
int ret = 0;
qdict_flatten(options);
qdict_extract_subqdict(options, &sub, "children.");
qdict_array_split(sub, &list);
if (qdict_size(sub)) {
error_setg(&local_err, "Invalid option children.%s",
qdict_first(sub)->key);
ret = -EINVAL;
goto exit;
}
/* count how many different children are present */
s->num_children = qlist_size(list);
if (s->num_children < 2) {
error_setg(&local_err,
"Number of provided children must be greater than 1");
ret = -EINVAL;
goto exit;
}
opts = qemu_opts_create(&quorum_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) {
ret = -EINVAL;
goto exit;
}
s->threshold = qemu_opt_get_number(opts, QUORUM_OPT_VOTE_THRESHOLD, 0);
/* and validate it against s->num_children */
ret = quorum_valid_threshold(s->threshold, s->num_children, &local_err);
if (ret < 0) {
goto exit;
}
/* is the driver in blkverify mode */
if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
s->num_children == 2 && s->threshold == 2) {
s->is_blkverify = true;
} else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
fprintf(stderr, "blkverify mode is set by setting blkverify=on "
"and using two files with vote_threshold=2\n");
}
/* allocate the children BlockDriverState array */
s->bs = g_new0(BlockDriverState *, s->num_children);
opened = g_new0(bool, s->num_children);
for (i = 0, lentry = qlist_first(list); lentry;
lentry = qlist_next(lentry), i++) {
QDict *d;
QString *string;
switch (qobject_type(lentry->value))
{
/* List of options */
case QTYPE_QDICT:
d = qobject_to_qdict(lentry->value);
QINCREF(d);
ret = bdrv_open(&s->bs[i], NULL, NULL, d, flags, NULL,
&local_err);
break;
/* QMP reference */
case QTYPE_QSTRING:
string = qobject_to_qstring(lentry->value);
ret = bdrv_open(&s->bs[i], NULL, qstring_get_str(string), NULL,
flags, NULL, &local_err);
break;
default:
error_setg(&local_err, "Specification of child block device %i "
"is invalid", i);
ret = -EINVAL;
}
if (ret < 0) {
goto close_exit;
}
opened[i] = true;
}
g_free(opened);
goto exit;
close_exit:
/* cleanup on error */
for (i = 0; i < s->num_children; i++) {
if (!opened[i]) {
continue;
}
bdrv_unref(s->bs[i]);
}
g_free(s->bs);
g_free(opened);
exit:
/* propagate error */
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
}
QDECREF(list);
QDECREF(sub);
return ret;
}
static void quorum_close(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
int i;
for (i = 0; i < s->num_children; i++) {
bdrv_unref(s->bs[i]);
}
g_free(s->bs);
}
static BlockDriver bdrv_quorum = {
.format_name = "quorum",
.protocol_name = "quorum",
.instance_size = sizeof(BDRVQuorumState),
.bdrv_file_open = quorum_open,
.bdrv_close = quorum_close,
.authorizations = { true, true },
.bdrv_co_flush_to_disk = quorum_co_flush,
.bdrv_getlength = quorum_getlength,
.bdrv_aio_readv = quorum_aio_readv,
.bdrv_aio_writev = quorum_aio_writev,
.bdrv_invalidate_cache = quorum_invalidate_cache,
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
};
static void bdrv_quorum_init(void)
{
bdrv_register(&bdrv_quorum);
}
block_init(bdrv_quorum_init);

View File

@@ -361,7 +361,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
@@ -448,7 +448,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
s->type = FTYPE_FILE; s->type = FTYPE_FILE;
ret = raw_open_common(bs, options, flags, 0, &local_err); ret = raw_open_common(bs, options, flags, 0, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
@@ -1597,7 +1597,7 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
ret = raw_open_common(bs, options, flags, 0, &local_err); ret = raw_open_common(bs, options, flags, 0, &local_err);
if (ret < 0) { if (ret < 0) {
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
@@ -1832,7 +1832,7 @@ static int floppy_open(BlockDriverState *bs, QDict *options, int flags,
/* open will not fail even if no floppy is inserted, so add O_NONBLOCK */ /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err); ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
if (ret) { if (ret) {
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
@@ -1961,7 +1961,7 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
/* open will not fail even if no CD is inserted, so add O_NONBLOCK */ /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err); ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
@@ -2078,7 +2078,7 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
ret = raw_open_common(bs, options, flags, 0, &local_err); ret = raw_open_common(bs, options, flags, 0, &local_err);
if (ret) { if (ret) {
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;

View File

@@ -279,7 +279,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
@@ -594,7 +594,7 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
QemuOpts *opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, QemuOpts *opts = qemu_opts_create(&raw_runtime_opts, NULL, 0,
&error_abort); &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
ret = -EINVAL; ret = -EINVAL;
goto done; goto done;

View File

@@ -90,6 +90,12 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return bdrv_get_info(bs->file, bdi); return bdrv_get_info(bs->file, bdi);
} }
static int raw_refresh_limits(BlockDriverState *bs)
{
bs->bl = bs->file->bl;
return 0;
}
static int raw_truncate(BlockDriverState *bs, int64_t offset) static int raw_truncate(BlockDriverState *bs, int64_t offset)
{ {
return bdrv_truncate(bs->file, offset); return bdrv_truncate(bs->file, offset);
@@ -140,7 +146,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
int ret; int ret;
ret = bdrv_create_file(filename, options, &local_err); ret = bdrv_create_file(filename, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
return ret; return ret;
@@ -150,7 +156,6 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) Error **errp)
{ {
bs->sg = bs->file->sg; bs->sg = bs->file->sg;
bs->bl = bs->file->bl;
return 0; return 0;
} }
@@ -182,6 +187,7 @@ static BlockDriver bdrv_raw = {
.bdrv_getlength = &raw_getlength, .bdrv_getlength = &raw_getlength,
.has_variable_length = true, .has_variable_length = true,
.bdrv_get_info = &raw_get_info, .bdrv_get_info = &raw_get_info,
.bdrv_refresh_limits = &raw_refresh_limits,
.bdrv_is_inserted = &raw_is_inserted, .bdrv_is_inserted = &raw_is_inserted,
.bdrv_media_changed = &raw_media_changed, .bdrv_media_changed = &raw_media_changed,
.bdrv_eject = &raw_eject, .bdrv_eject = &raw_eject,

View File

@@ -440,7 +440,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); qerror_report_err(local_err);
error_free(local_err); error_free(local_err);
qemu_opts_del(opts); qemu_opts_del(opts);

View File

@@ -1385,7 +1385,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); qerror_report_err(local_err);
error_free(local_err); error_free(local_err);
ret = -EINVAL; ret = -EINVAL;
@@ -1534,7 +1534,8 @@ static int sd_prealloc(const char *filename)
Error *local_err = NULL; Error *local_err = NULL;
int ret; int ret;
ret = bdrv_file_open(&bs, filename, NULL, NULL, BDRV_O_RDWR, &local_err); ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
NULL, &local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); qerror_report_err(local_err);
error_free(local_err); error_free(local_err);
@@ -1695,7 +1696,9 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
goto out; goto out;
} }
ret = bdrv_file_open(&bs, backing_file, NULL, NULL, 0, &local_err); bs = NULL;
ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL,
&local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); qerror_report_err(local_err);
error_free(local_err); error_free(local_err);

View File

@@ -345,7 +345,7 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err); ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
} }
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }

View File

@@ -395,43 +395,50 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
} }
if (header.signature != VDI_SIGNATURE) { if (header.signature != VDI_SIGNATURE) {
logout("bad vdi signature %08x\n", header.signature); error_setg(errp, "Image not in VDI format (bad signature %08x)", header.signature);
ret = -EMEDIUMTYPE; ret = -EINVAL;
goto fail; goto fail;
} else if (header.version != VDI_VERSION_1_1) { } else if (header.version != VDI_VERSION_1_1) {
logout("unsupported version %u.%u\n", error_setg(errp, "unsupported VDI image (version %u.%u)",
header.version >> 16, header.version & 0xffff); header.version >> 16, header.version & 0xffff);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (header.offset_bmap % SECTOR_SIZE != 0) { } else if (header.offset_bmap % SECTOR_SIZE != 0) {
/* We only support block maps which start on a sector boundary. */ /* We only support block maps which start on a sector boundary. */
logout("unsupported block map offset 0x%x B\n", header.offset_bmap); error_setg(errp, "unsupported VDI image (unaligned block map offset "
"0x%x)", header.offset_bmap);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (header.offset_data % SECTOR_SIZE != 0) { } else if (header.offset_data % SECTOR_SIZE != 0) {
/* We only support data blocks which start on a sector boundary. */ /* We only support data blocks which start on a sector boundary. */
logout("unsupported data offset 0x%x B\n", header.offset_data); error_setg(errp, "unsupported VDI image (unaligned data offset 0x%x)",
header.offset_data);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (header.sector_size != SECTOR_SIZE) { } else if (header.sector_size != SECTOR_SIZE) {
logout("unsupported sector size %u B\n", header.sector_size); error_setg(errp, "unsupported VDI image (sector size %u is not %u)",
header.sector_size, SECTOR_SIZE);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (header.block_size != 1 * MiB) { } else if (header.block_size != 1 * MiB) {
logout("unsupported block size %u B\n", header.block_size); error_setg(errp, "unsupported VDI image (sector size %u is not %u)",
header.block_size, 1 * MiB);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (header.disk_size > } else if (header.disk_size >
(uint64_t)header.blocks_in_image * header.block_size) { (uint64_t)header.blocks_in_image * header.block_size) {
logout("unsupported disk size %" PRIu64 " B\n", header.disk_size); error_setg(errp, "unsupported VDI image (disk size %" PRIu64 ", "
"image bitmap has room for %" PRIu64 ")",
header.disk_size,
(uint64_t)header.blocks_in_image * header.block_size);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (!uuid_is_null(header.uuid_link)) { } else if (!uuid_is_null(header.uuid_link)) {
logout("link uuid != 0, unsupported\n"); error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} else if (!uuid_is_null(header.uuid_parent)) { } else if (!uuid_is_null(header.uuid_parent)) {
logout("parent uuid != 0, unsupported\n"); error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
} }

View File

@@ -965,8 +965,8 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
cpu_to_le32s((uint32_t *)(buffer + 4)); cpu_to_le32s((uint32_t *)(buffer + 4));
/* now write to the log */ /* now write to the log */
vhdx_log_write_sectors(bs, &s->log, &sectors_written, buffer, ret = vhdx_log_write_sectors(bs, &s->log, &sectors_written, buffer,
desc_sectors + sectors); desc_sectors + sectors);
if (ret < 0) { if (ret < 0) {
goto exit; goto exit;
} }

View File

@@ -374,7 +374,7 @@ static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
inactive_header->log_guid = *log_guid; inactive_header->log_guid = *log_guid;
} }
vhdx_write_header(bs->file, inactive_header, header_offset, true); ret = vhdx_write_header(bs->file, inactive_header, header_offset, true);
if (ret < 0) { if (ret < 0) {
goto exit; goto exit;
} }
@@ -402,9 +402,10 @@ int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
} }
/* opens the specified header block from the VHDX file header section */ /* opens the specified header block from the VHDX file header section */
static int vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s) static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,
Error **errp)
{ {
int ret = 0; int ret;
VHDXHeader *header1; VHDXHeader *header1;
VHDXHeader *header2; VHDXHeader *header2;
bool h1_valid = false; bool h1_valid = false;
@@ -462,7 +463,6 @@ static int vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s)
} else if (!h1_valid && h2_valid) { } else if (!h1_valid && h2_valid) {
s->curr_header = 1; s->curr_header = 1;
} else if (!h1_valid && !h2_valid) { } else if (!h1_valid && !h2_valid) {
ret = -EINVAL;
goto fail; goto fail;
} else { } else {
/* If both headers are valid, then we choose the active one by the /* If both headers are valid, then we choose the active one by the
@@ -473,27 +473,22 @@ static int vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s)
} else if (h2_seq > h1_seq) { } else if (h2_seq > h1_seq) {
s->curr_header = 1; s->curr_header = 1;
} else { } else {
ret = -EINVAL;
goto fail; goto fail;
} }
} }
vhdx_region_register(s, s->headers[s->curr_header]->log_offset, vhdx_region_register(s, s->headers[s->curr_header]->log_offset,
s->headers[s->curr_header]->log_length); s->headers[s->curr_header]->log_length);
ret = 0;
goto exit; goto exit;
fail: fail:
qerror_report(ERROR_CLASS_GENERIC_ERROR, "No valid VHDX header found"); error_setg_errno(errp, -ret, "No valid VHDX header found");
qemu_vfree(header1); qemu_vfree(header1);
qemu_vfree(header2); qemu_vfree(header2);
s->headers[0] = NULL; s->headers[0] = NULL;
s->headers[1] = NULL; s->headers[1] = NULL;
exit: exit:
qemu_vfree(buffer); qemu_vfree(buffer);
return ret;
} }
@@ -878,7 +873,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
int ret = 0; int ret = 0;
uint32_t i; uint32_t i;
uint64_t signature; uint64_t signature;
Error *local_err = NULL;
s->bat = NULL; s->bat = NULL;
s->first_visible_write = true; s->first_visible_write = true;
@@ -901,8 +896,10 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
* header update */ * header update */
vhdx_guid_generate(&s->session_guid); vhdx_guid_generate(&s->session_guid);
ret = vhdx_parse_header(bs, s); vhdx_parse_header(bs, s, &local_err);
if (ret < 0) { if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail; goto fail;
} }
@@ -1797,7 +1794,9 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
goto exit; goto exit;
} }
ret = bdrv_file_open(&bs, filename, NULL, NULL, BDRV_O_RDWR, &local_err); bs = NULL;
ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
NULL, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto exit; goto exit;
@@ -1810,13 +1809,13 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL, creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL,
&creator_items, NULL); &creator_items, NULL);
signature = cpu_to_le64(VHDX_FILE_SIGNATURE); signature = cpu_to_le64(VHDX_FILE_SIGNATURE);
bdrv_pwrite(bs, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature)); ret = bdrv_pwrite(bs, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature));
if (ret < 0) { if (ret < 0) {
goto delete_and_exit; goto delete_and_exit;
} }
if (creator) { if (creator) {
bdrv_pwrite(bs, VHDX_FILE_ID_OFFSET + sizeof(signature), creator, ret = bdrv_pwrite(bs, VHDX_FILE_ID_OFFSET + sizeof(signature),
creator_items * sizeof(gunichar2)); creator, creator_items * sizeof(gunichar2));
if (ret < 0) { if (ret < 0) {
goto delete_and_exit; goto delete_and_exit;
} }

View File

@@ -526,8 +526,34 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
return ret; return ret;
} }
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
uint64_t desc_offset, Error **errp); Error **errp);
static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
Error **errp)
{
int64_t size;
char *buf;
int ret;
size = bdrv_getlength(file);
if (size < 0) {
error_setg_errno(errp, -size, "Could not access file");
return NULL;
}
size = MIN(size, 1 << 20); /* avoid unbounded allocation */
buf = g_malloc0(size + 1);
ret = bdrv_pread(file, desc_offset, buf, size);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read from file");
g_free(buf);
return NULL;
}
return buf;
}
static int vmdk_open_vmdk4(BlockDriverState *bs, static int vmdk_open_vmdk4(BlockDriverState *bs,
BlockDriverState *file, BlockDriverState *file,
@@ -546,11 +572,18 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
error_setg_errno(errp, -ret, error_setg_errno(errp, -ret,
"Could not read header from file '%s'", "Could not read header from file '%s'",
file->filename); file->filename);
return -EINVAL;
} }
if (header.capacity == 0) { if (header.capacity == 0) {
uint64_t desc_offset = le64_to_cpu(header.desc_offset); uint64_t desc_offset = le64_to_cpu(header.desc_offset);
if (desc_offset) { if (desc_offset) {
return vmdk_open_desc_file(bs, flags, desc_offset << 9, errp); char *buf = vmdk_read_desc(file, desc_offset << 9, errp);
if (!buf) {
return -EINVAL;
}
ret = vmdk_open_desc_file(bs, flags, buf, errp);
g_free(buf);
return ret;
} }
} }
@@ -609,8 +642,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
char buf[64]; char buf[64];
snprintf(buf, sizeof(buf), "VMDK version %d", snprintf(buf, sizeof(buf), "VMDK version %d",
le32_to_cpu(header.version)); le32_to_cpu(header.version));
qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "vmdk", buf); bs->device_name, "vmdk", buf);
return -ENOTSUP; return -ENOTSUP;
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) { } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
/* VMware KB 2064959 explains that version 3 added support for /* VMware KB 2064959 explains that version 3 added support for
@@ -622,7 +655,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
} }
if (le32_to_cpu(header.num_gtes_per_gt) > 512) { if (le32_to_cpu(header.num_gtes_per_gt) > 512) {
error_report("L2 table size too big"); error_setg(errp, "L2 table size too big");
return -EINVAL; return -EINVAL;
} }
@@ -638,8 +671,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
} }
if (bdrv_getlength(file) < if (bdrv_getlength(file) <
le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE) { le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE) {
error_report("File truncated, expecting at least %lld bytes", error_setg(errp, "File truncated, expecting at least %lld bytes",
le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE); le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE);
return -EINVAL; return -EINVAL;
} }
@@ -701,16 +734,12 @@ static int vmdk_parse_description(const char *desc, const char *opt_name,
/* Open an extent file and append to bs array */ /* Open an extent file and append to bs array */
static int vmdk_open_sparse(BlockDriverState *bs, static int vmdk_open_sparse(BlockDriverState *bs,
BlockDriverState *file, BlockDriverState *file, int flags,
int flags, Error **errp) char *buf, Error **errp)
{ {
uint32_t magic; uint32_t magic;
if (bdrv_pread(file, 0, &magic, sizeof(magic)) != sizeof(magic)) { magic = ldl_be_p(buf);
return -EIO;
}
magic = be32_to_cpu(magic);
switch (magic) { switch (magic) {
case VMDK3_MAGIC: case VMDK3_MAGIC:
return vmdk_open_vmfs_sparse(bs, file, flags, errp); return vmdk_open_vmfs_sparse(bs, file, flags, errp);
@@ -719,7 +748,8 @@ static int vmdk_open_sparse(BlockDriverState *bs,
return vmdk_open_vmdk4(bs, file, flags, errp); return vmdk_open_vmdk4(bs, file, flags, errp);
break; break;
default: default:
return -EMEDIUMTYPE; error_setg(errp, "Image not in VMDK format");
return -EINVAL;
break; break;
} }
} }
@@ -776,8 +806,9 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
path_combine(extent_path, sizeof(extent_path), path_combine(extent_path, sizeof(extent_path),
desc_file_path, fname); desc_file_path, fname);
ret = bdrv_file_open(&extent_file, extent_path, NULL, NULL, extent_file = NULL;
bs->open_flags, errp); ret = bdrv_open(&extent_file, extent_path, NULL, NULL,
bs->open_flags | BDRV_O_PROTOCOL, NULL, errp);
if (ret) { if (ret) {
return ret; return ret;
} }
@@ -794,8 +825,14 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
extent->flat_start_offset = flat_offset << 9; extent->flat_start_offset = flat_offset << 9;
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) { } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
/* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/ /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, errp); char *buf = vmdk_read_desc(extent_file, 0, errp);
if (!buf) {
ret = -EINVAL;
} else {
ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, buf, errp);
}
if (ret) { if (ret) {
g_free(buf);
bdrv_unref(extent_file); bdrv_unref(extent_file);
return ret; return ret;
} }
@@ -818,29 +855,16 @@ next_line:
return 0; return 0;
} }
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
uint64_t desc_offset, Error **errp) Error **errp)
{ {
int ret; int ret;
char *buf = NULL;
char ct[128]; char ct[128];
BDRVVmdkState *s = bs->opaque; BDRVVmdkState *s = bs->opaque;
int64_t size;
size = bdrv_getlength(bs->file);
if (size < 0) {
return -EINVAL;
}
size = MIN(size, 1 << 20); /* avoid unbounded allocation */
buf = g_malloc0(size + 1);
ret = bdrv_pread(bs->file, desc_offset, buf, size);
if (ret < 0) {
goto exit;
}
if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) { if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
ret = -EMEDIUMTYPE; error_setg(errp, "invalid VMDK image descriptor");
ret = -EINVAL;
goto exit; goto exit;
} }
if (strcmp(ct, "monolithicFlat") && if (strcmp(ct, "monolithicFlat") &&
@@ -856,24 +880,37 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
s->desc_offset = 0; s->desc_offset = 0;
ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp); ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp);
exit: exit:
g_free(buf);
return ret; return ret;
} }
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags, static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) Error **errp)
{ {
char *buf = NULL;
int ret; int ret;
BDRVVmdkState *s = bs->opaque; BDRVVmdkState *s = bs->opaque;
uint32_t magic;
if (vmdk_open_sparse(bs, bs->file, flags, errp) == 0) { buf = vmdk_read_desc(bs->file, 0, errp);
s->desc_offset = 0x200; if (!buf) {
} else { return -EINVAL;
ret = vmdk_open_desc_file(bs, flags, 0, errp);
if (ret) {
goto fail;
}
} }
magic = ldl_be_p(buf);
switch (magic) {
case VMDK3_MAGIC:
case VMDK4_MAGIC:
ret = vmdk_open_sparse(bs, bs->file, flags, buf, errp);
s->desc_offset = 0x200;
break;
default:
ret = vmdk_open_desc_file(bs, flags, buf, errp);
break;
}
if (ret) {
goto fail;
}
/* try to open parent images, if exist */ /* try to open parent images, if exist */
ret = vmdk_parent_open(bs); ret = vmdk_parent_open(bs);
if (ret) { if (ret) {
@@ -888,10 +925,11 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vmdk", bs->device_name, "live migration"); "vmdk", bs->device_name, "live migration");
migrate_add_blocker(s->migration_blocker); migrate_add_blocker(s->migration_blocker);
g_free(buf);
return 0; return 0;
fail: fail:
g_free(buf);
g_free(s->create_type); g_free(s->create_type);
s->create_type = NULL; s->create_type = NULL;
vmdk_free_extents(bs); vmdk_free_extents(bs);
@@ -1146,7 +1184,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
break; break;
case VMDK_OK: case VMDK_OK:
ret = BDRV_BLOCK_DATA; ret = BDRV_BLOCK_DATA;
if (extent->file == bs->file) { if (extent->file == bs->file && !extent->compressed) {
ret |= BDRV_BLOCK_OFFSET_VALID | offset; ret |= BDRV_BLOCK_OFFSET_VALID | offset;
} }
@@ -1493,7 +1531,9 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
goto exit; goto exit;
} }
ret = bdrv_file_open(&bs, filename, NULL, NULL, BDRV_O_RDWR, &local_err); assert(bs == NULL);
ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
NULL, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto exit; goto exit;
@@ -1502,7 +1542,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
if (flat) { if (flat) {
ret = bdrv_truncate(bs, filesize); ret = bdrv_truncate(bs, filesize);
if (ret < 0) { if (ret < 0) {
error_setg(errp, "Could not truncate file"); error_setg_errno(errp, -ret, "Could not truncate file");
} }
goto exit; goto exit;
} }
@@ -1562,7 +1602,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
ret = bdrv_truncate(bs, le64_to_cpu(header.grain_offset) << 9); ret = bdrv_truncate(bs, le64_to_cpu(header.grain_offset) << 9);
if (ret < 0) { if (ret < 0) {
error_setg(errp, "Could not truncate file"); error_setg_errno(errp, -ret, "Could not truncate file");
goto exit; goto exit;
} }
@@ -1755,10 +1795,10 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
goto exit; goto exit;
} }
if (backing_file) { if (backing_file) {
BlockDriverState *bs = bdrv_new(""); BlockDriverState *bs = NULL;
ret = bdrv_open(bs, backing_file, NULL, BDRV_O_NO_BACKING, NULL, errp); ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_NO_BACKING, NULL,
errp);
if (ret != 0) { if (ret != 0) {
bdrv_unref(bs);
goto exit; goto exit;
} }
if (strcmp(bs->drv->format_name, "vmdk")) { if (strcmp(bs->drv->format_name, "vmdk")) {
@@ -1831,7 +1871,9 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
goto exit; goto exit;
} }
} }
ret = bdrv_file_open(&new_bs, filename, NULL, NULL, BDRV_O_RDWR, &local_err); assert(new_bs == NULL);
ret = bdrv_open(&new_bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not write description"); error_setg_errno(errp, -ret, "Could not write description");
goto exit; goto exit;
@@ -1846,7 +1888,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
if (desc_offset == 0) { if (desc_offset == 0) {
ret = bdrv_truncate(new_bs, desc_len); ret = bdrv_truncate(new_bs, desc_len);
if (ret < 0) { if (ret < 0) {
error_setg(errp, "Could not truncate file"); error_setg_errno(errp, -ret, "Could not truncate file");
} }
} }
exit: exit:
@@ -1942,6 +1984,53 @@ static ImageInfo *vmdk_get_extent_info(VmdkExtent *extent)
return info; return info;
} }
static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
{
BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent = NULL;
int64_t sector_num = 0;
int64_t total_sectors = bdrv_getlength(bs) / BDRV_SECTOR_SIZE;
int ret;
uint64_t cluster_offset;
if (fix) {
return -ENOTSUP;
}
for (;;) {
if (sector_num >= total_sectors) {
return 0;
}
extent = find_extent(s, sector_num, extent);
if (!extent) {
fprintf(stderr,
"ERROR: could not find extent for sector %" PRId64 "\n",
sector_num);
break;
}
ret = get_cluster_offset(bs, extent, NULL,
sector_num << BDRV_SECTOR_BITS,
0, &cluster_offset);
if (ret == VMDK_ERROR) {
fprintf(stderr,
"ERROR: could not get cluster_offset for sector %"
PRId64 "\n", sector_num);
break;
}
if (ret == VMDK_OK && cluster_offset >= bdrv_getlength(extent->file)) {
fprintf(stderr,
"ERROR: cluster offset for sector %"
PRId64 " points after EOF\n", sector_num);
break;
}
sector_num += extent->cluster_sectors;
}
result->corruptions++;
return 0;
}
static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs) static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
{ {
int i; int i;
@@ -2015,6 +2104,7 @@ static BlockDriver bdrv_vmdk = {
.instance_size = sizeof(BDRVVmdkState), .instance_size = sizeof(BDRVVmdkState),
.bdrv_probe = vmdk_probe, .bdrv_probe = vmdk_probe,
.bdrv_open = vmdk_open, .bdrv_open = vmdk_open,
.bdrv_check = vmdk_check,
.bdrv_reopen_prepare = vmdk_reopen_prepare, .bdrv_reopen_prepare = vmdk_reopen_prepare,
.bdrv_read = vmdk_co_read, .bdrv_read = vmdk_co_read,
.bdrv_write = vmdk_co_write, .bdrv_write = vmdk_co_write,

View File

@@ -190,7 +190,8 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
goto fail; goto fail;
} }
if (strncmp(footer->creator, "conectix", 8)) { if (strncmp(footer->creator, "conectix", 8)) {
ret = -EMEDIUMTYPE; error_setg(errp, "invalid VPC image");
ret = -EINVAL;
goto fail; goto fail;
} }
disk_type = VHD_FIXED; disk_type = VHD_FIXED;

View File

@@ -1085,17 +1085,15 @@ DLOG(if (stderr == NULL) {
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
dirname = qemu_opt_get(opts, "dir"); dirname = qemu_opt_get(opts, "dir");
if (!dirname) { if (!dirname) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "vvfat block driver requires " error_setg(errp, "vvfat block driver requires a 'dir' option");
"a 'dir' option");
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
@@ -1135,8 +1133,7 @@ DLOG(if (stderr == NULL) {
case 12: case 12:
break; break;
default: default:
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Valid FAT types are only " error_setg(errp, "Valid FAT types are only 12, 16 and 32");
"12, 16 and 32");
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
@@ -2936,15 +2933,13 @@ static int enable_write_target(BDRVVVFATState *s)
goto err; goto err;
} }
s->qcow = bdrv_new(""); s->qcow = NULL;
ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, NULL,
ret = bdrv_open(s->qcow, s->qcow_filename, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow,
&local_err); &local_err);
if (ret < 0) { if (ret < 0) {
qerror_report_err(local_err); qerror_report_err(local_err);
error_free(local_err); error_free(local_err);
bdrv_unref(s->qcow);
goto err; goto err;
} }

View File

@@ -308,7 +308,6 @@ typedef enum { MEDIA_DISK, MEDIA_CDROM } DriveMediaType;
/* Takes the ownership of bs_opts */ /* Takes the ownership of bs_opts */
static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
BlockInterfaceType type,
Error **errp) Error **errp)
{ {
const char *buf; const char *buf;
@@ -331,13 +330,13 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
* stay in bs_opts for processing by bdrv_open(). */ * stay in bs_opts for processing by bdrv_open(). */
id = qdict_get_try_str(bs_opts, "id"); id = qdict_get_try_str(bs_opts, "id");
opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error); opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);
if (error_is_set(&error)) { if (error) {
error_propagate(errp, error); error_propagate(errp, error);
return NULL; return NULL;
} }
qemu_opts_absorb_qdict(opts, bs_opts, &error); qemu_opts_absorb_qdict(opts, bs_opts, &error);
if (error_is_set(&error)) { if (error) {
error_propagate(errp, error); error_propagate(errp, error);
goto early_err; goto early_err;
} }
@@ -437,13 +436,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) { if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) {
error_setg(errp, "werror is not supported by this bus type");
goto early_err;
}
on_write_error = parse_block_error_action(buf, 0, &error); on_write_error = parse_block_error_action(buf, 0, &error);
if (error_is_set(&error)) { if (error) {
error_propagate(errp, error); error_propagate(errp, error);
goto early_err; goto early_err;
} }
@@ -451,25 +445,25 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
on_read_error = BLOCKDEV_ON_ERROR_REPORT; on_read_error = BLOCKDEV_ON_ERROR_REPORT;
if ((buf = qemu_opt_get(opts, "rerror")) != NULL) { if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
if (type != IF_IDE && type != IF_VIRTIO && type != IF_SCSI && type != IF_NONE) {
error_report("rerror is not supported by this bus type");
goto early_err;
}
on_read_error = parse_block_error_action(buf, 1, &error); on_read_error = parse_block_error_action(buf, 1, &error);
if (error_is_set(&error)) { if (error) {
error_propagate(errp, error); error_propagate(errp, error);
goto early_err; goto early_err;
} }
} }
if (bdrv_find_node(qemu_opts_id(opts))) {
error_setg(errp, "device id=%s is conflicting with a node-name",
qemu_opts_id(opts));
goto early_err;
}
/* init */ /* init */
dinfo = g_malloc0(sizeof(*dinfo)); dinfo = g_malloc0(sizeof(*dinfo));
dinfo->id = g_strdup(qemu_opts_id(opts)); dinfo->id = g_strdup(qemu_opts_id(opts));
dinfo->bdrv = bdrv_new(dinfo->id); dinfo->bdrv = bdrv_new(dinfo->id);
dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0; dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
dinfo->bdrv->read_only = ro; dinfo->bdrv->read_only = ro;
dinfo->type = type;
dinfo->refcount = 1; dinfo->refcount = 1;
if (serial != NULL) { if (serial != NULL) {
dinfo->serial = g_strdup(serial); dinfo->serial = g_strdup(serial);
@@ -510,7 +504,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
bdrv_flags |= ro ? 0 : BDRV_O_RDWR; bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
QINCREF(bs_opts); QINCREF(bs_opts);
ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv, &error); ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error);
if (ret < 0) { if (ret < 0) {
error_setg(errp, "could not open disk image %s: %s", error_setg(errp, "could not open disk image %s: %s",
@@ -608,6 +602,14 @@ QemuOptsList qemu_legacy_drive_opts = {
.name = "read-only", .name = "read-only",
.type = QEMU_OPT_BOOL, .type = QEMU_OPT_BOOL,
.help = "open drive file as read-only", .help = "open drive file as read-only",
},{
.name = "rerror",
.type = QEMU_OPT_STRING,
.help = "read error action",
},{
.name = "werror",
.type = QEMU_OPT_STRING,
.help = "write error action",
},{ },{
.name = "copy-on-read", .name = "copy-on-read",
.type = QEMU_OPT_BOOL, .type = QEMU_OPT_BOOL,
@@ -629,6 +631,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
int cyls, heads, secs, translation; int cyls, heads, secs, translation;
int max_devs, bus_id, unit_id, index; int max_devs, bus_id, unit_id, index;
const char *devaddr; const char *devaddr;
const char *werror, *rerror;
bool read_only = false; bool read_only = false;
bool copy_on_read; bool copy_on_read;
const char *filename; const char *filename;
@@ -688,7 +691,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
legacy_opts = qemu_opts_create(&qemu_legacy_drive_opts, NULL, 0, legacy_opts = qemu_opts_create(&qemu_legacy_drive_opts, NULL, 0,
&error_abort); &error_abort);
qemu_opts_absorb_qdict(legacy_opts, bs_opts, &local_err); qemu_opts_absorb_qdict(legacy_opts, bs_opts, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); qerror_report_err(local_err);
error_free(local_err); error_free(local_err);
goto fail; goto fail;
@@ -776,6 +779,10 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
translation = BIOS_ATA_TRANSLATION_NONE; translation = BIOS_ATA_TRANSLATION_NONE;
} else if (!strcmp(value, "lba")) { } else if (!strcmp(value, "lba")) {
translation = BIOS_ATA_TRANSLATION_LBA; translation = BIOS_ATA_TRANSLATION_LBA;
} else if (!strcmp(value, "large")) {
translation = BIOS_ATA_TRANSLATION_LARGE;
} else if (!strcmp(value, "rechs")) {
translation = BIOS_ATA_TRANSLATION_RECHS;
} else if (!strcmp(value, "auto")) { } else if (!strcmp(value, "auto")) {
translation = BIOS_ATA_TRANSLATION_AUTO; translation = BIOS_ATA_TRANSLATION_AUTO;
} else { } else {
@@ -872,16 +879,37 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
filename = qemu_opt_get(legacy_opts, "file"); filename = qemu_opt_get(legacy_opts, "file");
/* Check werror/rerror compatibility with if=... */
werror = qemu_opt_get(legacy_opts, "werror");
if (werror != NULL) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO &&
type != IF_NONE) {
error_report("werror is not supported by this bus type");
goto fail;
}
qdict_put(bs_opts, "werror", qstring_from_str(werror));
}
rerror = qemu_opt_get(legacy_opts, "rerror");
if (rerror != NULL) {
if (type != IF_IDE && type != IF_VIRTIO && type != IF_SCSI &&
type != IF_NONE) {
error_report("rerror is not supported by this bus type");
goto fail;
}
qdict_put(bs_opts, "rerror", qstring_from_str(rerror));
}
/* Actual block device init: Functionality shared with blockdev-add */ /* Actual block device init: Functionality shared with blockdev-add */
dinfo = blockdev_init(filename, bs_opts, type, &local_err); dinfo = blockdev_init(filename, bs_opts, &local_err);
if (dinfo == NULL) { if (dinfo == NULL) {
if (error_is_set(&local_err)) { if (local_err) {
qerror_report_err(local_err); qerror_report_err(local_err);
error_free(local_err); error_free(local_err);
} }
goto fail; goto fail;
} else { } else {
assert(!error_is_set(&local_err)); assert(!local_err);
} }
/* Set legacy DriveInfo fields */ /* Set legacy DriveInfo fields */
@@ -893,6 +921,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
dinfo->secs = secs; dinfo->secs = secs;
dinfo->trans = translation; dinfo->trans = translation;
dinfo->type = type;
dinfo->bus = bus_id; dinfo->bus = bus_id;
dinfo->unit = unit_id; dinfo->unit = unit_id;
dinfo->devaddr = devaddr; dinfo->devaddr = devaddr;
@@ -1017,7 +1046,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
} }
ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err); ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return NULL; return NULL;
} }
@@ -1030,7 +1059,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
} }
bdrv_snapshot_delete(bs, id, name, &local_err); bdrv_snapshot_delete(bs, id, name, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return NULL; return NULL;
} }
@@ -1244,7 +1273,7 @@ static void external_snapshot_prepare(BlkTransactionState *common,
state->old_bs = bdrv_lookup_bs(has_device ? device : NULL, state->old_bs = bdrv_lookup_bs(has_device ? device : NULL,
has_node_name ? node_name : NULL, has_node_name ? node_name : NULL,
&local_err); &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -1289,7 +1318,7 @@ static void external_snapshot_prepare(BlkTransactionState *common,
state->old_bs->filename, state->old_bs->filename,
state->old_bs->drv->format_name, state->old_bs->drv->format_name,
NULL, -1, flags, &local_err, false); NULL, -1, flags, &local_err, false);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -1301,17 +1330,15 @@ static void external_snapshot_prepare(BlkTransactionState *common,
qstring_from_str(snapshot_node_name)); qstring_from_str(snapshot_node_name));
} }
/* We will manually add the backing_hd field to the bs later */
state->new_bs = bdrv_new("");
/* TODO Inherit bs->options or only take explicit options with an /* TODO Inherit bs->options or only take explicit options with an
* extended QMP command? */ * extended QMP command? */
ret = bdrv_open(state->new_bs, new_image_file, options, assert(state->new_bs == NULL);
ret = bdrv_open(&state->new_bs, new_image_file, NULL, options,
flags | BDRV_O_NO_BACKING, drv, &local_err); flags | BDRV_O_NO_BACKING, drv, &local_err);
/* We will manually add the backing_hd field to the bs later */
if (ret != 0) { if (ret != 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
} }
QDECREF(options);
} }
static void external_snapshot_commit(BlkTransactionState *common) static void external_snapshot_commit(BlkTransactionState *common)
@@ -1360,7 +1387,7 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
backup->has_on_source_error, backup->on_source_error, backup->has_on_source_error, backup->on_source_error,
backup->has_on_target_error, backup->on_target_error, backup->has_on_target_error, backup->on_target_error,
&local_err); &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
state->bs = NULL; state->bs = NULL;
state->job = NULL; state->job = NULL;
@@ -1452,7 +1479,7 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry); QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry);
state->ops->prepare(state, &local_err); state->ops->prepare(state, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto delete_and_fail; goto delete_and_fail;
} }
@@ -1533,7 +1560,7 @@ void qmp_block_passwd(bool has_device, const char *device,
bs = bdrv_lookup_bs(has_device ? device : NULL, bs = bdrv_lookup_bs(has_device ? device : NULL,
has_node_name ? node_name : NULL, has_node_name ? node_name : NULL,
&local_err); &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -1555,7 +1582,7 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
Error *local_err = NULL; Error *local_err = NULL;
int ret; int ret;
ret = bdrv_open(bs, filename, NULL, bdrv_flags, drv, &local_err); ret = bdrv_open(&bs, filename, NULL, NULL, bdrv_flags, drv, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
@@ -1598,7 +1625,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
} }
eject_device(bs, 0, &err); eject_device(bs, 0, &err);
if (error_is_set(&err)) { if (err) {
error_propagate(errp, err); error_propagate(errp, err);
return; return;
} }
@@ -1735,7 +1762,7 @@ void qmp_block_resize(bool has_device, const char *device,
bs = bdrv_lookup_bs(has_device ? device : NULL, bs = bdrv_lookup_bs(has_device ? device : NULL,
has_node_name ? node_name : NULL, has_node_name ? node_name : NULL,
&local_err); &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -1828,7 +1855,7 @@ void qmp_block_stream(const char *device, bool has_base,
stream_start(bs, base_bs, base, has_speed ? speed : 0, stream_start(bs, base_bs, base, has_speed ? speed : 0,
on_error, block_job_cb, bs, &local_err); on_error, block_job_cb, bs, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -1986,15 +2013,14 @@ void qmp_drive_backup(const char *device, const char *target,
} }
} }
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
target_bs = bdrv_new(""); target_bs = NULL;
ret = bdrv_open(target_bs, target, NULL, flags, drv, &local_err); ret = bdrv_open(&target_bs, target, NULL, NULL, flags, drv, &local_err);
if (ret < 0) { if (ret < 0) {
bdrv_unref(target_bs);
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -2127,7 +2153,7 @@ void qmp_drive_mirror(const char *device, const char *target,
} }
} }
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -2135,11 +2161,10 @@ void qmp_drive_mirror(const char *device, const char *target,
/* Mirroring takes care of copy-on-write using the source's backing /* Mirroring takes care of copy-on-write using the source's backing
* file. * file.
*/ */
target_bs = bdrv_new(""); target_bs = NULL;
ret = bdrv_open(target_bs, target, NULL, flags | BDRV_O_NO_BACKING, drv, ret = bdrv_open(&target_bs, target, NULL, NULL, flags | BDRV_O_NO_BACKING,
&local_err); drv, &local_err);
if (ret < 0) { if (ret < 0) {
bdrv_unref(target_bs);
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }
@@ -2266,7 +2291,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
visit_type_BlockdevOptions(qmp_output_get_visitor(ov), visit_type_BlockdevOptions(qmp_output_get_visitor(ov),
&options, NULL, &local_err); &options, NULL, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto fail; goto fail;
} }
@@ -2276,8 +2301,8 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
qdict_flatten(qdict); qdict_flatten(qdict);
blockdev_init(NULL, qdict, IF_NONE, &local_err); blockdev_init(NULL, qdict, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto fail; goto fail;
} }

View File

@@ -61,7 +61,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
Error *local_err = NULL; Error *local_err = NULL;
block_job_set_speed(job, speed, &local_err); block_job_set_speed(job, speed, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
bs->job = NULL; bs->job = NULL;
g_free(job); g_free(job);
bdrv_set_in_use(bs, 0); bdrv_set_in_use(bs, 0);
@@ -92,7 +92,7 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
return; return;
} }
job->driver->set_speed(job, speed, &local_err); job->driver->set_speed(job, speed, &local_err);
if (error_is_set(&local_err)) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }

459
configure vendored
View File

@@ -12,7 +12,10 @@ else
fi fi
TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c" TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c"
TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o" TMPB="qemu-conf-${RANDOM}-$$-${RANDOM}"
TMPO="${TMPDIR1}/${TMPB}.o"
TMPL="${TMPDIR1}/${TMPB}.lo"
TMPA="${TMPDIR1}/lib${TMPB}.la"
TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe" TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
# NB: do not call "exit" in the trap handler; this is buggy with some shells; # NB: do not call "exit" in the trap handler; this is buggy with some shells;
@@ -86,6 +89,38 @@ compile_prog() {
do_cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags do_cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags
} }
do_libtool() {
local mode=$1
shift
# Run the compiler, capturing its output to the log.
echo $libtool $mode --tag=CC $cc "$@" >> config.log
$libtool $mode --tag=CC $cc "$@" >> config.log 2>&1 || return $?
# Test passed. If this is an --enable-werror build, rerun
# the test with -Werror and bail out if it fails. This
# makes warning-generating-errors in configure test code
# obvious to developers.
if test "$werror" != "yes"; then
return 0
fi
# Don't bother rerunning the compile if we were already using -Werror
case "$*" in
*-Werror*)
return 0
;;
esac
echo $libtool $mode --tag=CC $cc -Werror "$@" >> config.log
$libtool $mode --tag=CC $cc -Werror "$@" >> config.log 2>&1 && return $?
error_exit "configure test passed without -Werror but failed with -Werror." \
"This is probably a bug in the configure script. The failing command" \
"will be at the bottom of config.log." \
"You can run configure with --disable-werror to bypass this check."
}
libtool_prog() {
do_libtool --mode=compile $QEMU_CFLAGS -c -fPIE -DPIE -o $TMPO $TMPC || return $?
do_libtool --mode=link $LDFLAGS -o $TMPA $TMPL -rpath /usr/local/lib
}
# symbolically link $1 to $2. Portable version of "ln -sf". # symbolically link $1 to $2. Portable version of "ln -sf".
symlink() { symlink() {
rm -rf "$2" rm -rf "$2"
@@ -172,6 +207,7 @@ fdt=""
netmap="no" netmap="no"
pixman="" pixman=""
sdl="" sdl=""
sdlabi="1.2"
virtfs="" virtfs=""
vnc="yes" vnc="yes"
sparse="no" sparse="no"
@@ -205,6 +241,9 @@ mingw32="no"
gcov="no" gcov="no"
gcov_tool="gcov" gcov_tool="gcov"
EXESUF="" EXESUF=""
DSOSUF=".so"
LDFLAGS_SHARED="-shared"
modules="no"
prefix="/usr/local" prefix="/usr/local"
mandir="\${prefix}/share/man" mandir="\${prefix}/share/man"
datadir="\${prefix}/share" datadir="\${prefix}/share"
@@ -245,12 +284,15 @@ libusb=""
usb_redir="" usb_redir=""
glx="" glx=""
zlib="yes" zlib="yes"
lzo="no"
snappy="no"
guest_agent="" guest_agent=""
guest_agent_with_vss="no" guest_agent_with_vss="no"
vss_win32_sdk="" vss_win32_sdk=""
win_sdk="no" win_sdk="no"
want_tools="yes" want_tools="yes"
libiscsi="" libiscsi=""
libnfs=""
coroutine="" coroutine=""
coroutine_pool="" coroutine_pool=""
seccomp="" seccomp=""
@@ -263,6 +305,7 @@ gtkabi="2.0"
tpm="no" tpm="no"
libssh2="" libssh2=""
vhdx="" vhdx=""
quorum="no"
# parse CC options first # parse CC options first
for opt do for opt do
@@ -324,6 +367,7 @@ query_pkg_config() {
} }
pkg_config=query_pkg_config pkg_config=query_pkg_config
sdl_config="${SDL_CONFIG-${cross_prefix}sdl-config}" sdl_config="${SDL_CONFIG-${cross_prefix}sdl-config}"
sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
# If the user hasn't specified ARFLAGS, default to 'rv', just as make does. # If the user hasn't specified ARFLAGS, default to 'rv', just as make does.
ARFLAGS="${ARFLAGS-rv}" ARFLAGS="${ARFLAGS-rv}"
@@ -514,11 +558,10 @@ OpenBSD)
Darwin) Darwin)
bsd="yes" bsd="yes"
darwin="yes" darwin="yes"
LDFLAGS_SHARED="-bundle -undefined dynamic_lookup"
if [ "$cpu" = "x86_64" ] ; then if [ "$cpu" = "x86_64" ] ; then
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS" QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
LDFLAGS="-arch x86_64 $LDFLAGS" LDFLAGS="-arch x86_64 $LDFLAGS"
else
QEMU_CFLAGS="-mdynamic-no-pic $QEMU_CFLAGS"
fi fi
cocoa="yes" cocoa="yes"
audio_drv_list="coreaudio" audio_drv_list="coreaudio"
@@ -609,6 +652,7 @@ fi
if test "$mingw32" = "yes" ; then if test "$mingw32" = "yes" ; then
EXESUF=".exe" EXESUF=".exe"
DSOSUF=".dll"
QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS" QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS"
# enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) # enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later)
QEMU_CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS" QEMU_CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS"
@@ -675,6 +719,9 @@ for opt do
;; ;;
--disable-debug-info) --disable-debug-info)
;; ;;
--enable-modules)
modules="yes"
;;
--cpu=*) --cpu=*)
;; ;;
--target-list=*) target_list="$optarg" --target-list=*) target_list="$optarg"
@@ -730,6 +777,8 @@ for opt do
;; ;;
--enable-sdl) sdl="yes" --enable-sdl) sdl="yes"
;; ;;
--with-sdlabi=*) sdlabi="$optarg"
;;
--disable-qom-cast-debug) qom_cast_debug="no" --disable-qom-cast-debug) qom_cast_debug="no"
;; ;;
--enable-qom-cast-debug) qom_cast_debug="yes" --enable-qom-cast-debug) qom_cast_debug="yes"
@@ -840,6 +889,10 @@ for opt do
;; ;;
--enable-libiscsi) libiscsi="yes" --enable-libiscsi) libiscsi="yes"
;; ;;
--disable-libnfs) libnfs="no"
;;
--enable-libnfs) libnfs="yes"
;;
--enable-profiler) profiler="yes" --enable-profiler) profiler="yes"
;; ;;
--disable-cocoa) cocoa="no" --disable-cocoa) cocoa="no"
@@ -948,6 +1001,10 @@ for opt do
;; ;;
--disable-zlib-test) zlib="no" --disable-zlib-test) zlib="no"
;; ;;
--enable-lzo) lzo="yes"
;;
--enable-snappy) snappy="yes"
;;
--enable-guest-agent) guest_agent="yes" --enable-guest-agent) guest_agent="yes"
;; ;;
--disable-guest-agent) guest_agent="no" --disable-guest-agent) guest_agent="no"
@@ -1000,6 +1057,10 @@ for opt do
;; ;;
--disable-vhdx) vhdx="no" --disable-vhdx) vhdx="no"
;; ;;
--disable-quorum) quorum="no"
;;
--enable-quorum) quorum="yes"
;;
*) echo "ERROR: unknown option $opt"; show_help="yes" *) echo "ERROR: unknown option $opt"; show_help="yes"
;; ;;
esac esac
@@ -1126,7 +1187,8 @@ Advanced options (experts only):
--libdir=PATH install libraries in PATH --libdir=PATH install libraries in PATH
--sysconfdir=PATH install config in PATH$confsuffix --sysconfdir=PATH install config in PATH$confsuffix
--localstatedir=PATH install local state in PATH (set at runtime on win32) --localstatedir=PATH install local state in PATH (set at runtime on win32)
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix] --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
--enable-modules enable modules support
--enable-debug-tcg enable TCG debugging --enable-debug-tcg enable TCG debugging
--disable-debug-tcg disable TCG debugging (default) --disable-debug-tcg disable TCG debugging (default)
--enable-debug-info enable debugging information (default) --enable-debug-info enable debugging information (default)
@@ -1138,6 +1200,7 @@ Advanced options (experts only):
--disable-werror disable compilation abort on warning --disable-werror disable compilation abort on warning
--disable-sdl disable SDL --disable-sdl disable SDL
--enable-sdl enable SDL --enable-sdl enable SDL
--with-sdlabi select preferred SDL ABI 1.2 or 2.0
--disable-gtk disable gtk UI --disable-gtk disable gtk UI
--enable-gtk enable gtk UI --enable-gtk enable gtk UI
--disable-virtfs disable VirtFS --disable-virtfs disable VirtFS
@@ -1229,12 +1292,16 @@ Advanced options (experts only):
--enable-rbd enable building the rados block device (rbd) --enable-rbd enable building the rados block device (rbd)
--disable-libiscsi disable iscsi support --disable-libiscsi disable iscsi support
--enable-libiscsi enable iscsi support --enable-libiscsi enable iscsi support
--disable-libnfs disable nfs support
--enable-libnfs enable nfs support
--disable-smartcard-nss disable smartcard nss support --disable-smartcard-nss disable smartcard nss support
--enable-smartcard-nss enable smartcard nss support --enable-smartcard-nss enable smartcard nss support
--disable-libusb disable libusb (for usb passthrough) --disable-libusb disable libusb (for usb passthrough)
--enable-libusb enable libusb (for usb passthrough) --enable-libusb enable libusb (for usb passthrough)
--disable-usb-redir disable usb network redirection support --disable-usb-redir disable usb network redirection support
--enable-usb-redir enable usb network redirection support --enable-usb-redir enable usb network redirection support
--enable-lzo enable the support of lzo compression library
--enable-snappy enable the support of snappy compression library
--disable-guest-agent disable building of the QEMU Guest Agent --disable-guest-agent disable building of the QEMU Guest Agent
--enable-guest-agent enable building of the QEMU Guest Agent --enable-guest-agent enable building of the QEMU Guest Agent
--with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent --with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent
@@ -1254,6 +1321,8 @@ Advanced options (experts only):
--enable-libssh2 enable ssh block device support --enable-libssh2 enable ssh block device support
--disable-vhdx disables support for the Microsoft VHDX image format --disable-vhdx disables support for the Microsoft VHDX image format
--enable-vhdx enable support for the Microsoft VHDX image format --enable-vhdx enable support for the Microsoft VHDX image format
--disable-quorum disable quorum block filter support
--enable-quorum enable quorum block filter support
NOTE: The object files are built at the place where configure is launched NOTE: The object files are built at the place where configure is launched
EOF EOF
@@ -1282,6 +1351,35 @@ else
error_exit "\"$cc\" either does not exist or does not work" error_exit "\"$cc\" either does not exist or does not work"
fi fi
# Check that the C++ compiler exists and works with the C compiler
if has $cxx; then
cat > $TMPC <<EOF
int c_function(void);
int main(void) { return c_function(); }
EOF
compile_object
cat > $TMPC <<EOF
extern "C" {
int c_function(void);
}
int c_function(void) { return 42; }
EOF
if (cc=$cxx do_cc $QEMU_CFLAGS -o $TMPE $TMPC $TMPO $LDFLAGS); then
# C++ compiler $cxx works ok with C compiler $cc
:
else
echo "C++ compiler $cxx does not work with C compiler $cc"
echo "Disabling C++ specific optional code"
cxx=
fi
else
echo "No C++ compiler available; disabling C++ specific optional code"
cxx=
fi
# Consult white-list to determine whether to enable werror # Consult white-list to determine whether to enable werror
# by default. Only enable by default for git builds # by default. Only enable by default for git builds
z_version=`cut -f3 -d. $source_path/VERSION` z_version=`cut -f3 -d. $source_path/VERSION`
@@ -1339,6 +1437,9 @@ if compile_prog "-Werror -fno-gcse" "" ; then
fi fi
if test "$static" = "yes" ; then if test "$static" = "yes" ; then
if test "$modules" = "yes" ; then
error_exit "static and modules are mutually incompatible"
fi
if test "$pie" = "yes" ; then if test "$pie" = "yes" ; then
error_exit "static and pie are mutually incompatible" error_exit "static and pie are mutually incompatible"
else else
@@ -1385,6 +1486,37 @@ EOF
pie="no" pie="no"
fi fi
fi fi
if compile_prog "-fno-pie" "-nopie"; then
CFLAGS_NOPIE="-fno-pie"
LDFLAGS_NOPIE="-nopie"
fi
fi
# check for broken gcc and libtool in RHEL5
if test -n "$libtool" -a "$pie" != "no" ; then
cat > $TMPC <<EOF
void *f(unsigned char *buf, int len);
void *g(unsigned char *buf, int len);
void *
f(unsigned char *buf, int len)
{
return (void*)0L;
}
void *
g(unsigned char *buf, int len)
{
return f(buf, len);
}
EOF
if ! libtool_prog; then
echo "Disabling libtool due to broken toolchain support"
libtool=
fi
fi fi
########################################## ##########################################
@@ -1467,9 +1599,11 @@ esac
feature_not_found() { feature_not_found() {
feature=$1 feature=$1
remedy=$2
error_exit "User requested feature $feature" \ error_exit "User requested feature $feature" \
"configure was not able to find it" "configure was not able to find it." \
"$remedy"
} }
# --- # ---
@@ -1517,7 +1651,7 @@ int main(void) {
} }
EOF EOF
if ! compile_object ; then if ! compile_object ; then
feature_not_found "nptl" feature_not_found "nptl" "Install glibc and linux kernel headers."
fi fi
fi fi
@@ -1536,7 +1670,43 @@ EOF
"Make sure to have the zlib libs and headers installed." "Make sure to have the zlib libs and headers installed."
fi fi
fi fi
libs_softmmu="$libs_softmmu -lz" LIBS="$LIBS -lz"
##########################################
# lzo check
if test "$lzo" != "no" ; then
cat > $TMPC << EOF
#include <lzo/lzo1x.h>
int main(void) { lzo_version(); return 0; }
EOF
if compile_prog "" "-llzo2" ; then
:
else
error_exit "lzo check failed" \
"Make sure to have the lzo libs and headers installed."
fi
libs_softmmu="$libs_softmmu -llzo2"
fi
##########################################
# snappy check
if test "$snappy" != "no" ; then
cat > $TMPC << EOF
#include <snappy-c.h>
int main(void) { snappy_max_compressed_length(4096); return 0; }
EOF
if compile_prog "" "-lsnappy" ; then
:
else
error_exit "snappy check failed" \
"Make sure to have the snappy libs and headers installed."
fi
libs_softmmu="$libs_softmmu -lsnappy"
fi
########################################## ##########################################
# libseccomp check # libseccomp check
@@ -1548,7 +1718,7 @@ if test "$seccomp" != "no" ; then
seccomp="yes" seccomp="yes"
else else
if test "$seccomp" = "yes"; then if test "$seccomp" = "yes"; then
feature_not_found "libseccomp" feature_not_found "libseccomp" "Install libseccomp devel >= 2.1.0"
fi fi
seccomp="no" seccomp="no"
fi fi
@@ -1573,7 +1743,7 @@ EOF
if ! compile_prog "" "$xen_libs" ; then if ! compile_prog "" "$xen_libs" ; then
# Xen not found # Xen not found
if test "$xen" = "yes" ; then if test "$xen" = "yes" ; then
feature_not_found "xen" feature_not_found "xen" "Install xen devel"
fi fi
xen=no xen=no
@@ -1696,7 +1866,7 @@ EOF
# Xen version unsupported # Xen version unsupported
else else
if test "$xen" = "yes" ; then if test "$xen" = "yes" ; then
feature_not_found "xen (unsupported version)" feature_not_found "xen (unsupported version)" "Install supported xen (e.g. 4.0, 3.4, 3.3)"
fi fi
xen=no xen=no
fi fi
@@ -1745,7 +1915,7 @@ if test "$sparse" != "no" ; then
sparse=yes sparse=yes
else else
if test "$sparse" = "yes" ; then if test "$sparse" = "yes" ; then
feature_not_found "sparse" feature_not_found "sparse" "Install sparse binary"
fi fi
sparse=no sparse=no
fi fi
@@ -1767,7 +1937,7 @@ if test "$gtk" != "no"; then
fi fi
if ! $pkg_config --exists "$gtkpackage >= $gtkversion"; then if ! $pkg_config --exists "$gtkpackage >= $gtkversion"; then
if test "$gtk" = "yes" ; then if test "$gtk" = "yes" ; then
feature_not_found "gtk" feature_not_found "gtk" "Install gtk2 or gtk3 (requires --with-gtkabi=3.0 option to configure) devel"
fi fi
gtk="no" gtk="no"
elif ! $pkg_config --exists "$vtepackage >= $vteversion"; then elif ! $pkg_config --exists "$vtepackage >= $vteversion"; then
@@ -1790,19 +1960,29 @@ fi
# Look for sdl configuration program (pkg-config or sdl-config). Try # Look for sdl configuration program (pkg-config or sdl-config). Try
# sdl-config even without cross prefix, and favour pkg-config over sdl-config. # sdl-config even without cross prefix, and favour pkg-config over sdl-config.
if test "`basename $sdl_config`" != sdl-config && ! has ${sdl_config}; then
sdl_config=sdl-config if test $sdlabi = "2.0"; then
sdl_config=$sdl2_config
sdlname=sdl2
sdlconfigname=sdl2_config
else
sdlname=sdl
sdlconfigname=sdl_config
fi fi
if $pkg_config sdl --exists; then if test "`basename $sdl_config`" != $sdlconfigname && ! has ${sdl_config}; then
sdlconfig="$pkg_config sdl" sdl_config=$sdlconfigname
fi
if $pkg_config $sdlname --exists; then
sdlconfig="$pkg_config $sdlname"
_sdlversion=`$sdlconfig --modversion 2>/dev/null | sed 's/[^0-9]//g'` _sdlversion=`$sdlconfig --modversion 2>/dev/null | sed 's/[^0-9]//g'`
elif has ${sdl_config}; then elif has ${sdl_config}; then
sdlconfig="$sdl_config" sdlconfig="$sdl_config"
_sdlversion=`$sdlconfig --version | sed 's/[^0-9]//g'` _sdlversion=`$sdlconfig --version | sed 's/[^0-9]//g'`
else else
if test "$sdl" = "yes" ; then if test "$sdl" = "yes" ; then
feature_not_found "sdl" feature_not_found "sdl" "Install SDL devel"
fi fi
sdl=no sdl=no
fi fi
@@ -1846,7 +2026,7 @@ EOF
fi # static link fi # static link
else # sdl not found else # sdl not found
if test "$sdl" = "yes" ; then if test "$sdl" = "yes" ; then
feature_not_found "sdl" feature_not_found "sdl" "Install SDL devel"
fi fi
sdl=no sdl=no
fi # sdl compile test fi # sdl compile test
@@ -1912,16 +2092,40 @@ EOF
QEMU_CFLAGS="$QEMU_CFLAGS $vnc_tls_cflags" QEMU_CFLAGS="$QEMU_CFLAGS $vnc_tls_cflags"
else else
if test "$vnc_tls" = "yes" ; then if test "$vnc_tls" = "yes" ; then
feature_not_found "vnc-tls" feature_not_found "vnc-tls" "Install gnutls devel"
fi fi
if test "$vnc_ws" = "yes" ; then if test "$vnc_ws" = "yes" ; then
feature_not_found "vnc-ws" feature_not_found "vnc-ws" "Install gnutls devel"
fi fi
vnc_tls=no vnc_tls=no
vnc_ws=no vnc_ws=no
fi fi
fi fi
##########################################
# Quorum probe (check for gnutls)
if test "$quorum" != "no" ; then
cat > $TMPC <<EOF
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
int main(void) {char data[4096], digest[32];
gnutls_hash_fast(GNUTLS_DIG_SHA256, data, 4096, digest);
return 0;
}
EOF
quorum_tls_cflags=`$pkg_config --cflags gnutls 2> /dev/null`
quorum_tls_libs=`$pkg_config --libs gnutls 2> /dev/null`
if compile_prog "$quorum_tls_cflags" "$quorum_tls_libs" ; then
qcow_tls=yes
libs_softmmu="$quorum_tls_libs $libs_softmmu"
libs_tools="$quorum_tls_libs $libs_softmmu"
QEMU_CFLAGS="$QEMU_CFLAGS $quorum_tls_cflags"
else
echo "gnutls > 2.10.0 required to compile Quorum"
exit 1
fi
fi
########################################## ##########################################
# VNC SASL detection # VNC SASL detection
if test "$vnc" = "yes" -a "$vnc_sasl" != "no" ; then if test "$vnc" = "yes" -a "$vnc_sasl" != "no" ; then
@@ -1939,7 +2143,7 @@ EOF
QEMU_CFLAGS="$QEMU_CFLAGS $vnc_sasl_cflags" QEMU_CFLAGS="$QEMU_CFLAGS $vnc_sasl_cflags"
else else
if test "$vnc_sasl" = "yes" ; then if test "$vnc_sasl" = "yes" ; then
feature_not_found "vnc-sasl" feature_not_found "vnc-sasl" "Install Cyrus SASL devel"
fi fi
vnc_sasl=no vnc_sasl=no
fi fi
@@ -1961,7 +2165,7 @@ EOF
QEMU_CFLAGS="$QEMU_CFLAGS $vnc_jpeg_cflags" QEMU_CFLAGS="$QEMU_CFLAGS $vnc_jpeg_cflags"
else else
if test "$vnc_jpeg" = "yes" ; then if test "$vnc_jpeg" = "yes" ; then
feature_not_found "vnc-jpeg" feature_not_found "vnc-jpeg" "Install libjpeg-turbo devel"
fi fi
vnc_jpeg=no vnc_jpeg=no
fi fi
@@ -1993,7 +2197,7 @@ EOF
QEMU_CFLAGS="$QEMU_CFLAGS $vnc_png_cflags" QEMU_CFLAGS="$QEMU_CFLAGS $vnc_png_cflags"
else else
if test "$vnc_png" = "yes" ; then if test "$vnc_png" = "yes" ; then
feature_not_found "vnc-png" feature_not_found "vnc-png" "Install libpng devel"
fi fi
vnc_png=no vnc_png=no
fi fi
@@ -2037,7 +2241,7 @@ EOF
libs_tools="$uuid_libs $libs_tools" libs_tools="$uuid_libs $libs_tools"
else else
if test "$uuid" = "yes" ; then if test "$uuid" = "yes" ; then
feature_not_found "uuid" feature_not_found "uuid" "Install libuuid devel"
fi fi
uuid=no uuid=no
fi fi
@@ -2071,7 +2275,7 @@ EOF
xfs="yes" xfs="yes"
else else
if test "$xfs" = "yes" ; then if test "$xfs" = "yes" ; then
feature_not_found "xfs" feature_not_found "xfs" "Instal xfsprogs/xfslibs devel"
fi fi
xfs=no xfs=no
fi fi
@@ -2097,20 +2301,28 @@ EOF
libs_tools="$vde_libs $libs_tools" libs_tools="$vde_libs $libs_tools"
else else
if test "$vde" = "yes" ; then if test "$vde" = "yes" ; then
feature_not_found "vde" feature_not_found "vde" "Install vde (Virtual Distributed Ethernet) devel"
fi fi
vde=no vde=no
fi fi
fi fi
########################################## ##########################################
# netmap headers probe # netmap support probe
# Apart from looking for netmap headers, we make sure that the host API version
# supports the netmap backend (>=11). The upper bound (15) is meant to simulate
# a minor/major version number. Minor new features will be marked with values up
# to 15, and if something happens that requires a change to the backend we will
# move above 15, submit the backend fixes and modify this two bounds.
if test "$netmap" != "no" ; then if test "$netmap" != "no" ; then
cat > $TMPC << EOF cat > $TMPC << EOF
#include <inttypes.h> #include <inttypes.h>
#include <net/if.h> #include <net/if.h>
#include <net/netmap.h> #include <net/netmap.h>
#include <net/netmap_user.h> #include <net/netmap_user.h>
#if (NETMAP_API < 11) || (NETMAP_API > 15)
#error
#endif
int main(void) { return 0; } int main(void) { return 0; }
EOF EOF
if compile_prog "" "" ; then if compile_prog "" "" ; then
@@ -2140,7 +2352,7 @@ EOF
libs_tools="$cap_libs $libs_tools" libs_tools="$cap_libs $libs_tools"
else else
if test "$cap_ng" = "yes" ; then if test "$cap_ng" = "yes" ; then
feature_not_found "cap_ng" feature_not_found "cap_ng" "Install libcap-ng devel"
fi fi
cap_ng=no cap_ng=no
fi fi
@@ -2245,7 +2457,7 @@ EOF
libs_softmmu="$brlapi_libs $libs_softmmu" libs_softmmu="$brlapi_libs $libs_softmmu"
else else
if test "$brlapi" = "yes" ; then if test "$brlapi" = "yes" ; then
feature_not_found "brlapi" feature_not_found "brlapi" "Install brlapi devel"
fi fi
brlapi=no brlapi=no
fi fi
@@ -2282,7 +2494,7 @@ EOF
curses=yes curses=yes
else else
if test "$curses" = "yes" ; then if test "$curses" = "yes" ; then
feature_not_found "curses" feature_not_found "curses" "Install ncurses devel"
fi fi
curses=no curses=no
fi fi
@@ -2304,11 +2516,9 @@ EOF
curl_libs=`$curlconfig --libs 2>/dev/null` curl_libs=`$curlconfig --libs 2>/dev/null`
if compile_prog "$curl_cflags" "$curl_libs" ; then if compile_prog "$curl_cflags" "$curl_libs" ; then
curl=yes curl=yes
libs_tools="$curl_libs $libs_tools"
libs_softmmu="$curl_libs $libs_softmmu"
else else
if test "$curl" = "yes" ; then if test "$curl" = "yes" ; then
feature_not_found "curl" feature_not_found "curl" "Install libcurl devel"
fi fi
curl=no curl=no
fi fi
@@ -2328,7 +2538,7 @@ EOF
libs_softmmu="$bluez_libs $libs_softmmu" libs_softmmu="$bluez_libs $libs_softmmu"
else else
if test "$bluez" = "yes" ; then if test "$bluez" = "yes" ; then
feature_not_found "bluez" feature_not_found "bluez" "Install bluez-libs/libbluetooth devel"
fi fi
bluez="no" bluez="no"
fi fi
@@ -2343,13 +2553,36 @@ if test "$mingw32" = yes; then
else else
glib_req_ver=2.12 glib_req_ver=2.12
fi fi
if $pkg_config --atleast-version=$glib_req_ver gthread-2.0; then glib_modules=gthread-2.0
glib_cflags=`$pkg_config --cflags gthread-2.0` if test "$modules" = yes; then
glib_libs=`$pkg_config --libs gthread-2.0` glib_modules="$glib_modules gmodule-2.0"
LIBS="$glib_libs $LIBS" fi
libs_qga="$glib_libs $libs_qga"
else for i in $glib_modules; do
error_exit "glib-$glib_req_ver required to compile QEMU" if $pkg_config --atleast-version=$glib_req_ver $i; then
glib_cflags=`$pkg_config --cflags $i`
glib_libs=`$pkg_config --libs $i`
CFLAGS="$glib_cflags $CFLAGS"
LIBS="$glib_libs $LIBS"
libs_qga="$glib_libs $libs_qga"
else
error_exit "glib-$glib_req_ver $i is required to compile QEMU"
fi
done
##########################################
# SHA command probe for modules
if test "$modules" = yes; then
shacmd_probe="sha1sum sha1 shasum"
for c in $shacmd_probe; do
if which $c &>/dev/null; then
shacmd="$c"
break
fi
done
if test "$shacmd" = ""; then
error_exit "one of the checksum commands is required to enable modules: $shacmd_probe"
fi
fi fi
########################################## ##########################################
@@ -2460,11 +2693,9 @@ EOF
rbd_libs="-lrbd -lrados" rbd_libs="-lrbd -lrados"
if compile_prog "" "$rbd_libs" ; then if compile_prog "" "$rbd_libs" ; then
rbd=yes rbd=yes
libs_tools="$rbd_libs $libs_tools"
libs_softmmu="$rbd_libs $libs_softmmu"
else else
if test "$rbd" = "yes" ; then if test "$rbd" = "yes" ; then
feature_not_found "rados block device" feature_not_found "rados block device" "Install librbd/ceph devel"
fi fi
rbd=no rbd=no
fi fi
@@ -2478,9 +2709,6 @@ if test "$libssh2" != "no" ; then
libssh2_cflags=`$pkg_config libssh2 --cflags` libssh2_cflags=`$pkg_config libssh2 --cflags`
libssh2_libs=`$pkg_config libssh2 --libs` libssh2_libs=`$pkg_config libssh2 --libs`
libssh2=yes libssh2=yes
libs_tools="$libssh2_libs $libs_tools"
libs_softmmu="$libssh2_libs $libs_softmmu"
QEMU_CFLAGS="$QEMU_CFLAGS $libssh2_cflags"
else else
if test "$libssh2" = "yes" ; then if test "$libssh2" = "yes" ; then
error_exit "libssh2 >= $min_libssh2_version required for --enable-libssh2" error_exit "libssh2 >= $min_libssh2_version required for --enable-libssh2"
@@ -2526,11 +2754,9 @@ int main(void) { io_setup(0, NULL); io_set_eventfd(NULL, 0); eventfd(0, 0); retu
EOF EOF
if compile_prog "" "-laio" ; then if compile_prog "" "-laio" ; then
linux_aio=yes linux_aio=yes
libs_softmmu="$libs_softmmu -laio"
libs_tools="$libs_tools -laio"
else else
if test "$linux_aio" = "yes" ; then if test "$linux_aio" = "yes" ; then
feature_not_found "linux AIO" feature_not_found "linux AIO" "Install libaio devel"
fi fi
linux_aio=no linux_aio=no
fi fi
@@ -2578,7 +2804,7 @@ EOF
libattr=yes libattr=yes
else else
if test "$attr" = "yes" ; then if test "$attr" = "yes" ; then
feature_not_found "ATTR" feature_not_found "ATTR" "Install libc6 or libattr devel"
fi fi
attr=no attr=no
fi fi
@@ -2655,8 +2881,8 @@ EOF
fdt_libs="-L\$(BUILD_DIR)/dtc/libfdt $fdt_libs" fdt_libs="-L\$(BUILD_DIR)/dtc/libfdt $fdt_libs"
elif test "$fdt" = "yes" ; then elif test "$fdt" = "yes" ; then
# have neither and want - prompt for system/submodule install # have neither and want - prompt for system/submodule install
error_exit "DTC not present. Your options:" \ error_exit "DTC (libfdt) not present. Your options:" \
" (1) Preferred: Install the DTC devel package" \ " (1) Preferred: Install the DTC (libfdt) devel package" \
" (2) Fetch the DTC submodule, using:" \ " (2) Fetch the DTC submodule, using:" \
" git submodule update --init dtc" " git submodule update --init dtc"
else else
@@ -2682,7 +2908,7 @@ EOF
glx=yes glx=yes
else else
if test "$glx" = "yes" ; then if test "$glx" = "yes" ; then
feature_not_found "glx" feature_not_found "glx" "Install GL devel (e.g. MESA)"
fi fi
glx_libs= glx_libs=
glx=no glx=no
@@ -2696,9 +2922,6 @@ if test "$glusterfs" != "no" ; then
glusterfs="yes" glusterfs="yes"
glusterfs_cflags=`$pkg_config --cflags glusterfs-api` glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
glusterfs_libs=`$pkg_config --libs glusterfs-api` glusterfs_libs=`$pkg_config --libs glusterfs-api`
CFLAGS="$CFLAGS $glusterfs_cflags"
libs_tools="$glusterfs_libs $libs_tools"
libs_softmmu="$glusterfs_libs $libs_softmmu"
if $pkg_config --atleast-version=5 glusterfs-api; then if $pkg_config --atleast-version=5 glusterfs-api; then
glusterfs_discard="yes" glusterfs_discard="yes"
fi fi
@@ -2707,7 +2930,7 @@ if test "$glusterfs" != "no" ; then
fi fi
else else
if test "$glusterfs" = "yes" ; then if test "$glusterfs" = "yes" ; then
feature_not_found "GlusterFS backend support" feature_not_found "GlusterFS backend support" "Install glusterfs-api devel"
fi fi
glusterfs="no" glusterfs="no"
fi fi
@@ -3027,7 +3250,7 @@ if test "$docs" != "no" ; then
docs=yes docs=yes
else else
if test "$docs" = "yes" ; then if test "$docs" = "yes" ; then
feature_not_found "docs" feature_not_found "docs" "Install texinfo and Perl/perl-podlators"
fi fi
docs=no docs=no
fi fi
@@ -3069,14 +3292,12 @@ EOF
libiscsi="yes" libiscsi="yes"
libiscsi_cflags=$($pkg_config --cflags libiscsi) libiscsi_cflags=$($pkg_config --cflags libiscsi)
libiscsi_libs=$($pkg_config --libs libiscsi) libiscsi_libs=$($pkg_config --libs libiscsi)
CFLAGS="$CFLAGS $libiscsi_cflags"
LIBS="$LIBS $libiscsi_libs"
elif compile_prog "" "-liscsi" ; then elif compile_prog "" "-liscsi" ; then
libiscsi="yes" libiscsi="yes"
LIBS="$LIBS -liscsi" libiscsi_libs="-liscsi"
else else
if test "$libiscsi" = "yes" ; then if test "$libiscsi" = "yes" ; then
feature_not_found "libiscsi" feature_not_found "libiscsi" "Install libiscsi devel"
fi fi
libiscsi="no" libiscsi="no"
fi fi
@@ -3160,7 +3381,7 @@ EOF
spice_server_version=$($pkg_config --modversion spice-server) spice_server_version=$($pkg_config --modversion spice-server)
else else
if test "$spice" = "yes" ; then if test "$spice" = "yes" ; then
feature_not_found "spice" feature_not_found "spice" "Install spice-server and spice-protocol devel"
fi fi
spice="no" spice="no"
fi fi
@@ -3210,7 +3431,7 @@ if test "$libusb" != "no" ; then
libs_softmmu="$libs_softmmu $libusb_libs" libs_softmmu="$libs_softmmu $libusb_libs"
else else
if test "$libusb" = "yes"; then if test "$libusb" = "yes"; then
feature_not_found "libusb" feature_not_found "libusb" "Install libusb devel"
fi fi
libusb="no" libusb="no"
fi fi
@@ -3226,7 +3447,7 @@ if test "$usb_redir" != "no" ; then
libs_softmmu="$libs_softmmu $usb_redir_libs" libs_softmmu="$libs_softmmu $usb_redir_libs"
else else
if test "$usb_redir" = "yes"; then if test "$usb_redir" = "yes"; then
feature_not_found "usb-redir" feature_not_found "usb-redir" "Install usbredir devel"
fi fi
usb_redir="no" usb_redir="no"
fi fi
@@ -3365,15 +3586,25 @@ fi
# For 'ust' backend, test if ust headers are present # For 'ust' backend, test if ust headers are present
if test "$trace_backend" = "ust"; then if test "$trace_backend" = "ust"; then
cat > $TMPC << EOF cat > $TMPC << EOF
#include <ust/tracepoint.h> #include <lttng/tracepoint.h>
#include <ust/marker.h>
int main(void) { return 0; } int main(void) { return 0; }
EOF EOF
if compile_prog "" "" ; then if compile_prog "" "" ; then
LIBS="-lust -lurcu-bp $LIBS" if $pkg_config lttng-ust --exists; then
libs_qga="-lust -lurcu-bp $libs_qga" lttng_ust_libs=`$pkg_config --libs lttng-ust`
else
lttng_ust_libs="-llttng-ust"
fi
if $pkg_config liburcu-bp --exists; then
urcu_bp_libs=`$pkg_config --libs liburcu-bp`
else
urcu_bp_libs="-lurcu-bp"
fi
LIBS="$lttng_ust_libs $urcu_bp_libs $LIBS"
libs_qga="$lttng_ust_libs $urcu_bp_libs $libs_qga"
else else
error_exit "Trace backend 'ust' missing libust header files" error_exit "Trace backend 'ust' missing lttng-ust header files"
fi fi
fi fi
@@ -3550,7 +3781,18 @@ cpuid_h=no
cat > $TMPC << EOF cat > $TMPC << EOF
#include <cpuid.h> #include <cpuid.h>
int main(void) { int main(void) {
return 0; unsigned a, b, c, d;
int max = __get_cpuid_max(0, 0);
if (max >= 1) {
__cpuid(1, a, b, c, d);
}
if (max >= 7) {
__cpuid_count(7, 0, a, b, c, d);
}
return 0;
} }
EOF EOF
if compile_prog "" "" ; then if compile_prog "" "" ; then
@@ -3600,6 +3842,20 @@ elif test "$debug" = "no" ; then
CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS" CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
fi fi
##########################################
# Do we have libnfs
if test "$libnfs" != "no" ; then
if $pkg_config --atleast-version=1.9.2 libnfs; then
libnfs="yes"
libnfs_libs=$($pkg_config --libs libnfs)
LIBS="$LIBS $libnfs_libs"
else
if test "$libnfs" = "yes" ; then
feature_not_found "libnfs"
fi
libnfs="no"
fi
fi
# Disable zero malloc errors for official releases unless explicitly told to # Disable zero malloc errors for official releases unless explicitly told to
# enable/disable # enable/disable
@@ -3639,6 +3895,7 @@ if test "$mingw32" = "yes" ; then
fi fi
qemu_confdir=$sysconfdir$confsuffix qemu_confdir=$sysconfdir$confsuffix
qemu_moddir=$libdir$confsuffix
qemu_datadir=$datadir$confsuffix qemu_datadir=$datadir$confsuffix
qemu_localedir="$datadir/locale" qemu_localedir="$datadir/locale"
@@ -3729,6 +3986,7 @@ echo "Install prefix $prefix"
echo "BIOS directory `eval echo $qemu_datadir`" echo "BIOS directory `eval echo $qemu_datadir`"
echo "binary directory `eval echo $bindir`" echo "binary directory `eval echo $bindir`"
echo "library directory `eval echo $libdir`" echo "library directory `eval echo $libdir`"
echo "module directory `eval echo $qemu_moddir`"
echo "libexec directory `eval echo $libexecdir`" echo "libexec directory `eval echo $libexecdir`"
echo "include directory `eval echo $includedir`" echo "include directory `eval echo $includedir`"
echo "config directory `eval echo $sysconfdir`" echo "config directory `eval echo $sysconfdir`"
@@ -3755,6 +4013,7 @@ echo "python $python"
if test "$slirp" = "yes" ; then if test "$slirp" = "yes" ; then
echo "smbd $smbd" echo "smbd $smbd"
fi fi
echo "module support $modules"
echo "host CPU $cpu" echo "host CPU $cpu"
echo "host big endian $bigendian" echo "host big endian $bigendian"
echo "target list $target_list" echo "target list $target_list"
@@ -3829,6 +4088,7 @@ echo "libiscsi support $libiscsi (1.4.0)"
else else
echo "libiscsi support $libiscsi" echo "libiscsi support $libiscsi"
fi fi
echo "libnfs support $libnfs"
echo "build guest agent $guest_agent" echo "build guest agent $guest_agent"
echo "QGA VSS support $guest_agent_with_vss" echo "QGA VSS support $guest_agent_with_vss"
echo "seccomp support $seccomp" echo "seccomp support $seccomp"
@@ -3843,6 +4103,9 @@ echo "libssh2 support $libssh2"
echo "TPM passthrough $tpm_passthrough" echo "TPM passthrough $tpm_passthrough"
echo "QOM debugging $qom_cast_debug" echo "QOM debugging $qom_cast_debug"
echo "vhdx $vhdx" echo "vhdx $vhdx"
echo "Quorum $quorum"
echo "lzo support $lzo"
echo "snappy support $snappy"
if test "$sdl_too_old" = "yes"; then if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support" echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -3866,6 +4129,7 @@ echo "sysconfdir=$sysconfdir" >> $config_host_mak
echo "qemu_confdir=$qemu_confdir" >> $config_host_mak echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
echo "qemu_datadir=$qemu_datadir" >> $config_host_mak echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
echo "qemu_docdir=$qemu_docdir" >> $config_host_mak echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
echo "qemu_moddir=$qemu_moddir" >> $config_host_mak
if test "$mingw32" = "no" ; then if test "$mingw32" = "no" ; then
echo "qemu_localstatedir=$local_statedir" >> $config_host_mak echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
fi fi
@@ -3998,6 +4262,12 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
if [ "$docs" = "yes" ] ; then if [ "$docs" = "yes" ] ; then
echo "BUILD_DOCS=yes" >> $config_host_mak echo "BUILD_DOCS=yes" >> $config_host_mak
fi fi
if test "$modules" = "yes"; then
# $shacmd can generate a hash started with digit, which the compiler doesn't
# like as an symbol. So prefix it with an underscore
echo "CONFIG_STAMP=_`(echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ `" >> $config_host_mak
echo "CONFIG_MODULES=y" >> $config_host_mak
fi
if test "$sdl" = "yes" ; then if test "$sdl" = "yes" ; then
echo "CONFIG_SDL=y" >> $config_host_mak echo "CONFIG_SDL=y" >> $config_host_mak
echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak
@@ -4069,8 +4339,9 @@ if test "$bswap_h" = "yes" ; then
echo "CONFIG_MACHINE_BSWAP_H=y" >> $config_host_mak echo "CONFIG_MACHINE_BSWAP_H=y" >> $config_host_mak
fi fi
if test "$curl" = "yes" ; then if test "$curl" = "yes" ; then
echo "CONFIG_CURL=y" >> $config_host_mak echo "CONFIG_CURL=m" >> $config_host_mak
echo "CURL_CFLAGS=$curl_cflags" >> $config_host_mak echo "CURL_CFLAGS=$curl_cflags" >> $config_host_mak
echo "CURL_LIBS=$curl_libs" >> $config_host_mak
fi fi
if test "$brlapi" = "yes" ; then if test "$brlapi" = "yes" ; then
echo "CONFIG_BRLAPI=y" >> $config_host_mak echo "CONFIG_BRLAPI=y" >> $config_host_mak
@@ -4158,11 +4429,25 @@ if test "$glx" = "yes" ; then
echo "GLX_LIBS=$glx_libs" >> $config_host_mak echo "GLX_LIBS=$glx_libs" >> $config_host_mak
fi fi
if test "$lzo" = "yes" ; then
echo "CONFIG_LZO=y" >> $config_host_mak
fi
if test "$snappy" = "yes" ; then
echo "CONFIG_SNAPPY=y" >> $config_host_mak
fi
if test "$libiscsi" = "yes" ; then if test "$libiscsi" = "yes" ; then
echo "CONFIG_LIBISCSI=y" >> $config_host_mak echo "CONFIG_LIBISCSI=m" >> $config_host_mak
if test "$libiscsi_version" = "1.4.0"; then if test "$libiscsi_version" = "1.4.0"; then
echo "CONFIG_LIBISCSI_1_4=y" >> $config_host_mak echo "CONFIG_LIBISCSI_1_4=y" >> $config_host_mak
fi fi
echo "LIBISCSI_CFLAGS=$libiscsi_cflags" >> $config_host_mak
echo "LIBISCSI_LIBS=$libiscsi_libs" >> $config_host_mak
fi
if test "$libnfs" = "yes" ; then
echo "CONFIG_LIBNFS=y" >> $config_host_mak
fi fi
if test "$seccomp" = "yes"; then if test "$seccomp" = "yes"; then
@@ -4183,7 +4468,9 @@ if test "$qom_cast_debug" = "yes" ; then
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
fi fi
if test "$rbd" = "yes" ; then if test "$rbd" = "yes" ; then
echo "CONFIG_RBD=y" >> $config_host_mak echo "CONFIG_RBD=m" >> $config_host_mak
echo "RBD_CFLAGS=$rbd_cflags" >> $config_host_mak
echo "RBD_LIBS=$rbd_libs" >> $config_host_mak
fi fi
echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
@@ -4226,7 +4513,9 @@ if test "$getauxval" = "yes" ; then
fi fi
if test "$glusterfs" = "yes" ; then if test "$glusterfs" = "yes" ; then
echo "CONFIG_GLUSTERFS=y" >> $config_host_mak echo "CONFIG_GLUSTERFS=m" >> $config_host_mak
echo "GLUSTERFS_CFLAGS=$glusterfs_cflags" >> $config_host_mak
echo "GLUSTERFS_LIBS=$glusterfs_libs" >> $config_host_mak
fi fi
if test "$glusterfs_discard" = "yes" ; then if test "$glusterfs_discard" = "yes" ; then
@@ -4238,7 +4527,13 @@ if test "$glusterfs_zerofill" = "yes" ; then
fi fi
if test "$libssh2" = "yes" ; then if test "$libssh2" = "yes" ; then
echo "CONFIG_LIBSSH2=y" >> $config_host_mak echo "CONFIG_LIBSSH2=m" >> $config_host_mak
echo "LIBSSH2_CFLAGS=$libssh2_cflags" >> $config_host_mak
echo "LIBSSH2_LIBS=$libssh2_libs" >> $config_host_mak
fi
if test "$quorum" = "yes" ; then
echo "CONFIG_QUORUM=y" >> $config_host_mak
fi fi
if test "$virtio_blk_data_plane" = "yes" ; then if test "$virtio_blk_data_plane" = "yes" ; then
@@ -4294,7 +4589,7 @@ if test "$trace_backend" = "ftrace"; then
echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak
trace_default=no trace_default=no
else else
feature_not_found "ftrace(trace backend)" feature_not_found "ftrace(trace backend)" "ftrace requires Linux"
fi fi
fi fi
echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
@@ -4350,6 +4645,7 @@ echo "LD=$ld" >> $config_host_mak
echo "WINDRES=$windres" >> $config_host_mak echo "WINDRES=$windres" >> $config_host_mak
echo "LIBTOOL=$libtool" >> $config_host_mak echo "LIBTOOL=$libtool" >> $config_host_mak
echo "CFLAGS=$CFLAGS" >> $config_host_mak echo "CFLAGS=$CFLAGS" >> $config_host_mak
echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
echo "QEMU_INCLUDES=$QEMU_INCLUDES" >> $config_host_mak echo "QEMU_INCLUDES=$QEMU_INCLUDES" >> $config_host_mak
if test "$sparse" = "yes" ; then if test "$sparse" = "yes" ; then
@@ -4363,10 +4659,13 @@ else
echo "AUTOCONF_HOST := " >> $config_host_mak echo "AUTOCONF_HOST := " >> $config_host_mak
fi fi
echo "LDFLAGS=$LDFLAGS" >> $config_host_mak echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
echo "LIBTOOLFLAGS=$LIBTOOLFLAGS" >> $config_host_mak echo "LIBTOOLFLAGS=$LIBTOOLFLAGS" >> $config_host_mak
echo "LIBS+=$LIBS" >> $config_host_mak echo "LIBS+=$LIBS" >> $config_host_mak
echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak
echo "EXESUF=$EXESUF" >> $config_host_mak echo "EXESUF=$EXESUF" >> $config_host_mak
echo "DSOSUF=$DSOSUF" >> $config_host_mak
echo "LDFLAGS_SHARED=$LDFLAGS_SHARED" >> $config_host_mak
echo "LIBS_QGA+=$libs_qga" >> $config_host_mak echo "LIBS_QGA+=$libs_qga" >> $config_host_mak
echo "POD2MAN=$POD2MAN" >> $config_host_mak echo "POD2MAN=$POD2MAN" >> $config_host_mak
echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak
@@ -4641,6 +4940,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
arm) arm)
echo "CONFIG_ARM_DIS=y" >> $config_target_mak echo "CONFIG_ARM_DIS=y" >> $config_target_mak
echo "CONFIG_ARM_DIS=y" >> config-all-disas.mak echo "CONFIG_ARM_DIS=y" >> config-all-disas.mak
if test -n "${cxx}"; then
echo "CONFIG_ARM_A64_DIS=y" >> $config_target_mak
echo "CONFIG_ARM_A64_DIS=y" >> config-all-disas.mak
fi
;; ;;
cris) cris)
echo "CONFIG_CRIS_DIS=y" >> $config_target_mak echo "CONFIG_CRIS_DIS=y" >> $config_target_mak

View File

@@ -395,7 +395,10 @@ int cpu_exec(CPUArchState *env)
/* FIXME: this should respect TPR */ /* FIXME: this should respect TPR */
cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR,
0); 0);
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); intno = ldl_phys(cpu->as,
env->vm_vmcb
+ offsetof(struct vmcb,
control.int_vector));
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1); do_interrupt_x86_hardirq(env, intno, 1);
cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ; cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
@@ -474,7 +477,7 @@ int cpu_exec(CPUArchState *env)
} }
#elif defined(TARGET_ARM) #elif defined(TARGET_ARM)
if (interrupt_request & CPU_INTERRUPT_FIQ if (interrupt_request & CPU_INTERRUPT_FIQ
&& !(env->uncached_cpsr & CPSR_F)) { && !(env->daif & PSTATE_F)) {
env->exception_index = EXCP_FIQ; env->exception_index = EXCP_FIQ;
cc->do_interrupt(cpu); cc->do_interrupt(cpu);
next_tb = 0; next_tb = 0;
@@ -490,7 +493,7 @@ int cpu_exec(CPUArchState *env)
pc contains a magic address. */ pc contains a magic address. */
if (interrupt_request & CPU_INTERRUPT_HARD if (interrupt_request & CPU_INTERRUPT_HARD
&& ((IS_M(env) && env->regs[15] < 0xfffffff0) && ((IS_M(env) && env->regs[15] < 0xfffffff0)
|| !(env->uncached_cpsr & CPSR_I))) { || !(env->daif & PSTATE_I))) {
env->exception_index = EXCP_IRQ; env->exception_index = EXCP_IRQ;
cc->do_interrupt(cpu); cc->do_interrupt(cpu);
next_tb = 0; next_tb = 0;

2
cpus.c
View File

@@ -1119,6 +1119,8 @@ void resume_all_vcpus(void)
static void qemu_tcg_init_vcpu(CPUState *cpu) static void qemu_tcg_init_vcpu(CPUState *cpu)
{ {
tcg_cpu_address_space_init(cpu, cpu->as);
/* share a single thread for all cpus with TCG */ /* share a single thread for all cpus with TCG */
if (!tcg_cpu_thread) { if (!tcg_cpu_thread) {
cpu->thread = g_malloc0(sizeof(QemuThread)); cpu->thread = g_malloc0(sizeof(QemuThread));

View File

@@ -232,6 +232,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
uintptr_t addend; uintptr_t addend;
CPUTLBEntry *te; CPUTLBEntry *te;
hwaddr iotlb, xlat, sz; hwaddr iotlb, xlat, sz;
CPUState *cpu = ENV_GET_CPU(env);
assert(size >= TARGET_PAGE_SIZE); assert(size >= TARGET_PAGE_SIZE);
if (size != TARGET_PAGE_SIZE) { if (size != TARGET_PAGE_SIZE) {
@@ -239,7 +240,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
} }
sz = size; sz = size;
section = address_space_translate_for_iotlb(&address_space_memory, paddr, section = address_space_translate_for_iotlb(cpu->as, paddr,
&xlat, &sz); &xlat, &sz);
assert(sz >= TARGET_PAGE_SIZE); assert(sz >= TARGET_PAGE_SIZE);
@@ -305,6 +306,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
int mmu_idx, page_index, pd; int mmu_idx, page_index, pd;
void *p; void *p;
MemoryRegion *mr; MemoryRegion *mr;
CPUState *cpu = ENV_GET_CPU(env1);
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = cpu_mmu_index(env1); mmu_idx = cpu_mmu_index(env1);
@@ -313,9 +315,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
cpu_ldub_code(env1, addr); cpu_ldub_code(env1, addr);
} }
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK; pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(pd); mr = iotlb_to_region(cpu->as, pd);
if (memory_region_is_unassigned(mr)) { if (memory_region_is_unassigned(mr)) {
CPUState *cpu = ENV_GET_CPU(env1);
CPUClass *cc = CPU_GET_CLASS(cpu); CPUClass *cc = CPU_GET_CLASS(cpu);
if (cc->do_unassigned_access) { if (cc->do_unassigned_access) {

View File

@@ -27,6 +27,7 @@ CONFIG_SSI_SD=y
CONFIG_SSI_M25P80=y CONFIG_SSI_M25P80=y
CONFIG_LAN9118=y CONFIG_LAN9118=y
CONFIG_SMC91C111=y CONFIG_SMC91C111=y
CONFIG_ALLWINNER_EMAC=y
CONFIG_DS1338=y CONFIG_DS1338=y
CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y CONFIG_PFLASH_CFI02=y

View File

@@ -41,6 +41,8 @@ CONFIG_I8259=y
CONFIG_XILINX=y CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y CONFIG_XILINX_ETHLITE=y
CONFIG_OPENPIC=y CONFIG_OPENPIC=y
CONFIG_PREP=y
CONFIG_MAC=y
CONFIG_E500=y CONFIG_E500=y
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM)) CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
# For PReP # For PReP

View File

@@ -42,6 +42,8 @@ CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y CONFIG_XILINX_ETHLITE=y
CONFIG_OPENPIC=y CONFIG_OPENPIC=y
CONFIG_PSERIES=y CONFIG_PSERIES=y
CONFIG_PREP=y
CONFIG_MAC=y
CONFIG_E500=y CONFIG_E500=y
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM)) CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
# For pSeries # For pSeries

View File

@@ -3,32 +3,12 @@
include pci.mak include pci.mak
include sound.mak include sound.mak
include usb.mak include usb.mak
CONFIG_ISA_MMIO=y
CONFIG_ESCC=y
CONFIG_M48T59=y CONFIG_M48T59=y
CONFIG_VGA=y CONFIG_VGA=y
CONFIG_VGA_PCI=y CONFIG_VGA_PCI=y
CONFIG_SERIAL=y CONFIG_SERIAL=y
CONFIG_I8254=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_I8257=y CONFIG_I8257=y
CONFIG_OPENPIC=y CONFIG_OPENPIC=y
CONFIG_PREP_PCI=y
CONFIG_MACIO=y
CONFIG_CUDA=y
CONFIG_ADB=y
CONFIG_MAC_NVRAM=y
CONFIG_MAC_DBDMA=y
CONFIG_HEATHROW_PIC=y
CONFIG_GRACKLE_PCI=y
CONFIG_UNIN_PCI=y
CONFIG_DEC_PCI=y
CONFIG_PPCE500_PCI=y
CONFIG_IDE_ISA=y
CONFIG_IDE_CMD646=y
CONFIG_IDE_MACIO=y
CONFIG_NE2000_ISA=y
CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y CONFIG_PFLASH_CFI02=y
CONFIG_PTIMER=y CONFIG_PTIMER=y
@@ -36,8 +16,3 @@ CONFIG_I8259=y
CONFIG_XILINX=y CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y CONFIG_XILINX_ETHLITE=y
CONFIG_OPENPIC=y CONFIG_OPENPIC=y
CONFIG_E500=y
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
# For PReP
CONFIG_MC146818RTC=y
CONFIG_ISA_TESTDEV=y

View File

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

View File

@@ -10,6 +10,7 @@ CONFIG_EMPTY_SLOT=y
CONFIG_PCNET_COMMON=y CONFIG_PCNET_COMMON=y
CONFIG_LANCE=y CONFIG_LANCE=y
CONFIG_TCX=y CONFIG_TCX=y
CONFIG_CG3=y
CONFIG_SLAVIO=y CONFIG_SLAVIO=y
CONFIG_CS4231=y CONFIG_CS4231=y
CONFIG_GRLIB=y CONFIG_GRLIB=y

14
disas.c
View File

@@ -190,7 +190,7 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
/* Disassemble this for me please... (debugging). 'flags' has the following /* Disassemble this for me please... (debugging). 'flags' has the following
values: values:
i386 - 1 means 16 bit code, 2 means 64 bit code i386 - 1 means 16 bit code, 2 means 64 bit code
arm - bit 0 = thumb, bit 1 = reverse endian arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64
ppc - nonzero means little endian ppc - nonzero means little endian
other targets - unused other targets - unused
*/ */
@@ -225,7 +225,15 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
} }
print_insn = print_insn_i386; print_insn = print_insn_i386;
#elif defined(TARGET_ARM) #elif defined(TARGET_ARM)
if (flags & 1) { if (flags & 4) {
/* We might not be compiled with the A64 disassembler
* because it needs a C++ compiler; in that case we will
* fall through to the default print_insn_od case.
*/
#if defined(CONFIG_ARM_A64_DIS)
print_insn = print_insn_arm_a64;
#endif
} else if (flags & 1) {
print_insn = print_insn_thumb1; print_insn = print_insn_thumb1;
} else { } else {
print_insn = print_insn_arm; print_insn = print_insn_arm;
@@ -356,6 +364,8 @@ void disas(FILE *out, void *code, unsigned long size)
#elif defined(_ARCH_PPC) #elif defined(_ARCH_PPC)
s.info.disassembler_options = (char *)"any"; s.info.disassembler_options = (char *)"any";
print_insn = print_insn_ppc; print_insn = print_insn_ppc;
#elif defined(__aarch64__) && defined(CONFIG_ARM_A64_DIS)
print_insn = print_insn_arm_a64;
#elif defined(__alpha__) #elif defined(__alpha__)
print_insn = print_insn_alpha; print_insn = print_insn_alpha;
#elif defined(__sparc__) #elif defined(__sparc__)

View File

@@ -1,5 +1,10 @@
common-obj-$(CONFIG_ALPHA_DIS) += alpha.o common-obj-$(CONFIG_ALPHA_DIS) += alpha.o
common-obj-$(CONFIG_ARM_DIS) += arm.o common-obj-$(CONFIG_ARM_DIS) += arm.o
common-obj-$(CONFIG_ARM_A64_DIS) += arm-a64.o
common-obj-$(CONFIG_ARM_A64_DIS) += libvixl/
libvixldir = $(SRC_PATH)/disas/libvixl
$(obj)/arm-a64.o: QEMU_CFLAGS += -I$(libvixldir)
common-obj-$(CONFIG_CRIS_DIS) += cris.o common-obj-$(CONFIG_CRIS_DIS) += cris.o
common-obj-$(CONFIG_HPPA_DIS) += hppa.o common-obj-$(CONFIG_HPPA_DIS) += hppa.o
common-obj-$(CONFIG_I386_DIS) += i386.o common-obj-$(CONFIG_I386_DIS) += i386.o

87
disas/arm-a64.cc Normal file
View File

@@ -0,0 +1,87 @@
/*
* ARM A64 disassembly output wrapper to libvixl
* Copyright (c) 2013 Linaro Limited
* Written by Claudio Fontana
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "a64/disasm-a64.h"
extern "C" {
#include "disas/bfd.h"
}
using namespace vixl;
static Decoder *vixl_decoder = NULL;
static Disassembler *vixl_disasm = NULL;
/* We don't use libvixl's PrintDisassembler because its output
* is a little unhelpful (trailing newlines, for example).
* Instead we use our own very similar variant so we have
* control over the format.
*/
class QEMUDisassembler : public Disassembler {
public:
explicit QEMUDisassembler(FILE *stream) : stream_(stream) { }
~QEMUDisassembler() { }
protected:
void ProcessOutput(Instruction *instr) {
fprintf(stream_, "%08" PRIx32 " %s",
instr->InstructionBits(), GetOutput());
}
private:
FILE *stream_;
};
static int vixl_is_initialized(void)
{
return vixl_decoder != NULL;
}
static void vixl_init(FILE *f) {
vixl_decoder = new Decoder();
vixl_disasm = new QEMUDisassembler(f);
vixl_decoder->AppendVisitor(vixl_disasm);
}
#define INSN_SIZE 4
/* Disassemble ARM A64 instruction. This is our only entry
* point from QEMU's C code.
*/
int print_insn_arm_a64(uint64_t addr, disassemble_info *info)
{
uint8_t bytes[INSN_SIZE];
uint32_t instr;
int status;
status = info->read_memory_func(addr, bytes, INSN_SIZE, info);
if (status != 0) {
info->memory_error_func(status, addr, info);
return -1;
}
if (!vixl_is_initialized()) {
vixl_init(info->stream);
}
instr = bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24;
vixl_decoder->Decode(reinterpret_cast<Instruction*>(&instr));
return INSN_SIZE;
}

View File

@@ -171,6 +171,7 @@ static void print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma dis
static void print_displacement (char *, bfd_vma); static void print_displacement (char *, bfd_vma);
static void OP_E (int, int); static void OP_E (int, int);
static void OP_G (int, int); static void OP_G (int, int);
static void OP_vvvv (int, int);
static bfd_vma get64 (void); static bfd_vma get64 (void);
static bfd_signed_vma get32 (void); static bfd_signed_vma get32 (void);
static bfd_signed_vma get32s (void); static bfd_signed_vma get32s (void);
@@ -264,6 +265,9 @@ static int rex_used;
current instruction. */ current instruction. */
static int used_prefixes; static int used_prefixes;
/* The VEX.vvvv register, unencoded. */
static int vex_reg;
/* Flags stored in PREFIXES. */ /* Flags stored in PREFIXES. */
#define PREFIX_REPZ 1 #define PREFIX_REPZ 1
#define PREFIX_REPNZ 2 #define PREFIX_REPNZ 2
@@ -278,6 +282,10 @@ static int used_prefixes;
#define PREFIX_ADDR 0x400 #define PREFIX_ADDR 0x400
#define PREFIX_FWAIT 0x800 #define PREFIX_FWAIT 0x800
#define PREFIX_VEX_0F 0x1000
#define PREFIX_VEX_0F38 0x2000
#define PREFIX_VEX_0F3A 0x4000
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
to ADDR (exclusive) are valid. Returns 1 for success, longjmps to ADDR (exclusive) are valid. Returns 1 for success, longjmps
on error. */ on error. */
@@ -323,6 +331,7 @@ fetch_data(struct disassemble_info *info, bfd_byte *addr)
#define XX { NULL, 0 } #define XX { NULL, 0 }
#define Bv { OP_vvvv, v_mode }
#define Eb { OP_E, b_mode } #define Eb { OP_E, b_mode }
#define Ev { OP_E, v_mode } #define Ev { OP_E, v_mode }
#define Ed { OP_E, d_mode } #define Ed { OP_E, d_mode }
@@ -671,7 +680,8 @@ fetch_data(struct disassemble_info *info, bfd_byte *addr)
#define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } } #define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
#define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } } #define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
#define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } } #define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } } #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
#define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } } #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
@@ -1449,7 +1459,7 @@ static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
/* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */ /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */ /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
/* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */ /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
/* ------------------------------- */ /* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
}; };
@@ -1473,7 +1483,7 @@ static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
/* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */ /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */ /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
/* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */ /* f0 */ 1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
/* ------------------------------- */ /* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
}; };
@@ -1497,7 +1507,7 @@ static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
/* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */ /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */ /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
/* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */ /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
/* ------------------------------- */ /* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
}; };
@@ -2774,6 +2784,22 @@ static const struct dis386 prefix_user_table[][4] = {
{ "(bad)", { XX } }, { "(bad)", { XX } },
}, },
/* PREGRP105 */
{
{ "andnS", { Gv, Bv, Ev } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
},
/* PREGRP106 */
{
{ "bextrS", { Gv, Ev, Bv } },
{ "sarxS", { Gv, Ev, Bv } },
{ "shlxS", { Gv, Ev, Bv } },
{ "shrxS", { Gv, Ev, Bv } },
},
}; };
static const struct dis386 x86_64_table[][2] = { static const struct dis386 x86_64_table[][2] = {
@@ -3071,12 +3097,12 @@ static const struct dis386 three_byte_table[][256] = {
/* f0 */ /* f0 */
{ PREGRP87 }, { PREGRP87 },
{ PREGRP88 }, { PREGRP88 },
{ PREGRP105 },
{ "(bad)", { XX } }, { "(bad)", { XX } },
{ "(bad)", { XX } }, { "(bad)", { XX } },
{ "(bad)", { XX } }, { "(bad)", { XX } },
{ "(bad)", { XX } }, { "(bad)", { XX } },
{ "(bad)", { XX } }, { PREGRP106 },
{ "(bad)", { XX } },
/* f8 */ /* f8 */
{ "(bad)", { XX } }, { "(bad)", { XX } },
{ "(bad)", { XX } }, { "(bad)", { XX } },
@@ -3477,6 +3503,74 @@ ckprefix (void)
} }
} }
static void
ckvexprefix (void)
{
int op, vex2, vex3, newrex = 0, newpfx = prefixes;
if (address_mode == mode_16bit) {
return;
}
fetch_data(the_info, codep + 1);
op = *codep;
if (op != 0xc4 && op != 0xc5) {
return;
}
fetch_data(the_info, codep + 2);
vex2 = codep[1];
if (address_mode == mode_32bit && (vex2 & 0xc0) != 0xc0) {
return;
}
if (op == 0xc4) {
/* Three byte VEX prefix. */
fetch_data(the_info, codep + 3);
vex3 = codep[2];
newrex |= (vex2 & 0x80 ? 0 : REX_R);
newrex |= (vex2 & 0x40 ? 0 : REX_X);
newrex |= (vex2 & 0x20 ? 0 : REX_B);
newrex |= (vex3 & 0x80 ? REX_W : 0);
switch (vex2 & 0x1f) { /* VEX.m-mmmm */
case 1:
newpfx |= PREFIX_VEX_0F;
break;
case 2:
newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F38;
break;
case 3:
newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F3A;
break;
}
vex2 = vex3;
codep += 3;
} else {
/* Two byte VEX prefix. */
newrex |= (vex2 & 0x80 ? 0 : REX_R);
codep += 2;
}
vex_reg = (~vex2 >> 3) & 15; /* VEX.vvvv */
switch (vex2 & 3) { /* VEX.pp */
case 1:
newpfx |= PREFIX_DATA; /* 0x66 */
break;
case 2:
newpfx |= PREFIX_REPZ; /* 0xf3 */
break;
case 3:
newpfx |= PREFIX_REPNZ; /* 0xf2 */
break;
}
rex = newrex;
prefixes = newpfx;
}
/* Return the name of the prefix byte PREF, or NULL if PREF is not a /* Return the name of the prefix byte PREF, or NULL if PREF is not a
prefix byte. */ prefix byte. */
@@ -3598,6 +3692,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
const char *p; const char *p;
struct dis_private priv; struct dis_private priv;
unsigned char op; unsigned char op;
unsigned char threebyte;
if (info->mach == bfd_mach_x86_64_intel_syntax if (info->mach == bfd_mach_x86_64_intel_syntax
|| info->mach == bfd_mach_x86_64) || info->mach == bfd_mach_x86_64)
@@ -3752,6 +3847,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
obufp = obuf; obufp = obuf;
ckprefix (); ckprefix ();
ckvexprefix ();
insn_codep = codep; insn_codep = codep;
sizeflag = priv.orig_sizeflag; sizeflag = priv.orig_sizeflag;
@@ -3775,18 +3871,29 @@ print_insn (bfd_vma pc, disassemble_info *info)
} }
op = 0; op = 0;
if (prefixes & PREFIX_VEX_0F)
{
used_prefixes |= PREFIX_VEX_0F | PREFIX_VEX_0F38 | PREFIX_VEX_0F3A;
if (prefixes & PREFIX_VEX_0F38)
threebyte = 0x38;
else if (prefixes & PREFIX_VEX_0F3A)
threebyte = 0x3a;
else
threebyte = *codep++;
goto vex_opcode;
}
if (*codep == 0x0f) if (*codep == 0x0f)
{ {
unsigned char threebyte;
fetch_data(info, codep + 2); fetch_data(info, codep + 2);
threebyte = *++codep; threebyte = codep[1];
codep += 2;
vex_opcode:
dp = &dis386_twobyte[threebyte]; dp = &dis386_twobyte[threebyte];
need_modrm = twobyte_has_modrm[*codep]; need_modrm = twobyte_has_modrm[threebyte];
uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep]; uses_DATA_prefix = twobyte_uses_DATA_prefix[threebyte];
uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep]; uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[threebyte];
uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep]; uses_REPZ_prefix = twobyte_uses_REPZ_prefix[threebyte];
uses_LOCK_prefix = (*codep & ~0x02) == 0x20; uses_LOCK_prefix = (threebyte & ~0x02) == 0x20;
codep++;
if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE) if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
{ {
fetch_data(info, codep + 2); fetch_data(info, codep + 2);
@@ -5291,6 +5398,17 @@ OP_G (int bytemode, int sizeflag)
} }
} }
static void
OP_vvvv (int bytemode, int sizeflags)
{
USED_REX (REX_W);
if (rex & REX_W) {
oappend(names64[vex_reg]);
} else {
oappend(names32[vex_reg]);
}
}
static bfd_vma static bfd_vma
get64 (void) get64 (void)
{ {

30
disas/libvixl/LICENCE Normal file
View File

@@ -0,0 +1,30 @@
LICENCE
=======
The software in this repository is covered by the following licence.
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,8 @@
libvixl_OBJS = utils.o \
a64/instructions-a64.o \
a64/decoder-a64.o \
a64/disasm-a64.o
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS += -I$(SRC_PATH)/disas/libvixl
common-obj-$(CONFIG_ARM_A64_DIS) += $(libvixl_OBJS)

12
disas/libvixl/README Normal file
View File

@@ -0,0 +1,12 @@
The code in this directory is a subset of libvixl:
https://github.com/armvixl/vixl
(specifically, it is the set of files needed for disassembly only,
taken from libvixl 1.1).
Bugfixes should preferably be sent upstream initially.
The disassembler does not currently support the entire A64 instruction
set. Notably:
* No Advanced SIMD support.
* Limited support for system instructions.
* A few miscellaneous integer and floating point instructions are missing.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_CPU_A64_H
#define VIXL_CPU_A64_H
#include "globals.h"
namespace vixl {
class CPU {
public:
// Initialise CPU support.
static void SetUp();
// Ensures the data at a given address and with a given size is the same for
// the I and D caches. I and D caches are not automatically coherent on ARM
// so this operation is required before any dynamically generated code can
// safely run.
static void EnsureIAndDCacheCoherency(void *address, size_t length);
private:
// Return the content of the cache type register.
static uint32_t GetCacheType();
// I and D cache line size in bytes.
static unsigned icache_line_size_;
static unsigned dcache_line_size_;
};
} // namespace vixl
#endif // VIXL_CPU_A64_H

View File

@@ -0,0 +1,712 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "globals.h"
#include "utils.h"
#include "a64/decoder-a64.h"
namespace vixl {
// Top-level instruction decode function.
void Decoder::Decode(Instruction *instr) {
if (instr->Bits(28, 27) == 0) {
VisitUnallocated(instr);
} else {
switch (instr->Bits(27, 24)) {
// 0: PC relative addressing.
case 0x0: DecodePCRelAddressing(instr); break;
// 1: Add/sub immediate.
case 0x1: DecodeAddSubImmediate(instr); break;
// A: Logical shifted register.
// Add/sub with carry.
// Conditional compare register.
// Conditional compare immediate.
// Conditional select.
// Data processing 1 source.
// Data processing 2 source.
// B: Add/sub shifted register.
// Add/sub extended register.
// Data processing 3 source.
case 0xA:
case 0xB: DecodeDataProcessing(instr); break;
// 2: Logical immediate.
// Move wide immediate.
case 0x2: DecodeLogical(instr); break;
// 3: Bitfield.
// Extract.
case 0x3: DecodeBitfieldExtract(instr); break;
// 4: Unconditional branch immediate.
// Exception generation.
// Compare and branch immediate.
// 5: Compare and branch immediate.
// Conditional branch.
// System.
// 6,7: Unconditional branch.
// Test and branch immediate.
case 0x4:
case 0x5:
case 0x6:
case 0x7: DecodeBranchSystemException(instr); break;
// 8,9: Load/store register pair post-index.
// Load register literal.
// Load/store register unscaled immediate.
// Load/store register immediate post-index.
// Load/store register immediate pre-index.
// Load/store register offset.
// Load/store exclusive.
// C,D: Load/store register pair offset.
// Load/store register pair pre-index.
// Load/store register unsigned immediate.
// Advanced SIMD.
case 0x8:
case 0x9:
case 0xC:
case 0xD: DecodeLoadStore(instr); break;
// E: FP fixed point conversion.
// FP integer conversion.
// FP data processing 1 source.
// FP compare.
// FP immediate.
// FP data processing 2 source.
// FP conditional compare.
// FP conditional select.
// Advanced SIMD.
// F: FP data processing 3 source.
// Advanced SIMD.
case 0xE:
case 0xF: DecodeFP(instr); break;
}
}
}
void Decoder::AppendVisitor(DecoderVisitor* new_visitor) {
visitors_.remove(new_visitor);
visitors_.push_front(new_visitor);
}
void Decoder::PrependVisitor(DecoderVisitor* new_visitor) {
visitors_.remove(new_visitor);
visitors_.push_back(new_visitor);
}
void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,
DecoderVisitor* registered_visitor) {
visitors_.remove(new_visitor);
std::list<DecoderVisitor*>::iterator it;
for (it = visitors_.begin(); it != visitors_.end(); it++) {
if (*it == registered_visitor) {
visitors_.insert(it, new_visitor);
return;
}
}
// We reached the end of the list. The last element must be
// registered_visitor.
ASSERT(*it == registered_visitor);
visitors_.insert(it, new_visitor);
}
void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,
DecoderVisitor* registered_visitor) {
visitors_.remove(new_visitor);
std::list<DecoderVisitor*>::iterator it;
for (it = visitors_.begin(); it != visitors_.end(); it++) {
if (*it == registered_visitor) {
it++;
visitors_.insert(it, new_visitor);
return;
}
}
// We reached the end of the list. The last element must be
// registered_visitor.
ASSERT(*it == registered_visitor);
visitors_.push_back(new_visitor);
}
void Decoder::RemoveVisitor(DecoderVisitor* visitor) {
visitors_.remove(visitor);
}
void Decoder::DecodePCRelAddressing(Instruction* instr) {
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);
VisitPCRelAddressing(instr);
}
void Decoder::DecodeBranchSystemException(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0x4) ||
(instr->Bits(27, 24) == 0x5) ||
(instr->Bits(27, 24) == 0x6) ||
(instr->Bits(27, 24) == 0x7) );
switch (instr->Bits(31, 29)) {
case 0:
case 4: {
VisitUnconditionalBranch(instr);
break;
}
case 1:
case 5: {
if (instr->Bit(25) == 0) {
VisitCompareBranch(instr);
} else {
VisitTestBranch(instr);
}
break;
}
case 2: {
if (instr->Bit(25) == 0) {
if ((instr->Bit(24) == 0x1) ||
(instr->Mask(0x01000010) == 0x00000010)) {
VisitUnallocated(instr);
} else {
VisitConditionalBranch(instr);
}
} else {
VisitUnallocated(instr);
}
break;
}
case 6: {
if (instr->Bit(25) == 0) {
if (instr->Bit(24) == 0) {
if ((instr->Bits(4, 2) != 0) ||
(instr->Mask(0x00E0001D) == 0x00200001) ||
(instr->Mask(0x00E0001D) == 0x00400001) ||
(instr->Mask(0x00E0001E) == 0x00200002) ||
(instr->Mask(0x00E0001E) == 0x00400002) ||
(instr->Mask(0x00E0001C) == 0x00600000) ||
(instr->Mask(0x00E0001C) == 0x00800000) ||
(instr->Mask(0x00E0001F) == 0x00A00000) ||
(instr->Mask(0x00C0001C) == 0x00C00000)) {
VisitUnallocated(instr);
} else {
VisitException(instr);
}
} else {
if (instr->Bits(23, 22) == 0) {
const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0);
if ((instr->Bits(21, 19) == 0x4) ||
(masked_003FF0E0 == 0x00033000) ||
(masked_003FF0E0 == 0x003FF020) ||
(masked_003FF0E0 == 0x003FF060) ||
(masked_003FF0E0 == 0x003FF0E0) ||
(instr->Mask(0x00388000) == 0x00008000) ||
(instr->Mask(0x0038E000) == 0x00000000) ||
(instr->Mask(0x0039E000) == 0x00002000) ||
(instr->Mask(0x003AE000) == 0x00002000) ||
(instr->Mask(0x003CE000) == 0x00042000) ||
(instr->Mask(0x003FFFC0) == 0x000320C0) ||
(instr->Mask(0x003FF100) == 0x00032100) ||
(instr->Mask(0x003FF200) == 0x00032200) ||
(instr->Mask(0x003FF400) == 0x00032400) ||
(instr->Mask(0x003FF800) == 0x00032800) ||
(instr->Mask(0x0038F000) == 0x00005000) ||
(instr->Mask(0x0038E000) == 0x00006000)) {
VisitUnallocated(instr);
} else {
VisitSystem(instr);
}
} else {
VisitUnallocated(instr);
}
}
} else {
if ((instr->Bit(24) == 0x1) ||
(instr->Bits(20, 16) != 0x1F) ||
(instr->Bits(15, 10) != 0) ||
(instr->Bits(4, 0) != 0) ||
(instr->Bits(24, 21) == 0x3) ||
(instr->Bits(24, 22) == 0x3)) {
VisitUnallocated(instr);
} else {
VisitUnconditionalBranchToRegister(instr);
}
}
break;
}
case 3:
case 7: {
VisitUnallocated(instr);
break;
}
}
}
void Decoder::DecodeLoadStore(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0x8) ||
(instr->Bits(27, 24) == 0x9) ||
(instr->Bits(27, 24) == 0xC) ||
(instr->Bits(27, 24) == 0xD) );
if (instr->Bit(24) == 0) {
if (instr->Bit(28) == 0) {
if (instr->Bit(29) == 0) {
if (instr->Bit(26) == 0) {
// TODO: VisitLoadStoreExclusive.
VisitUnimplemented(instr);
} else {
DecodeAdvSIMDLoadStore(instr);
}
} else {
if ((instr->Bits(31, 30) == 0x3) ||
(instr->Mask(0xC4400000) == 0x40000000)) {
VisitUnallocated(instr);
} else {
if (instr->Bit(23) == 0) {
if (instr->Mask(0xC4400000) == 0xC0400000) {
VisitUnallocated(instr);
} else {
VisitLoadStorePairNonTemporal(instr);
}
} else {
VisitLoadStorePairPostIndex(instr);
}
}
}
} else {
if (instr->Bit(29) == 0) {
if (instr->Mask(0xC4000000) == 0xC4000000) {
VisitUnallocated(instr);
} else {
VisitLoadLiteral(instr);
}
} else {
if ((instr->Mask(0x84C00000) == 0x80C00000) ||
(instr->Mask(0x44800000) == 0x44800000) ||
(instr->Mask(0x84800000) == 0x84800000)) {
VisitUnallocated(instr);
} else {
if (instr->Bit(21) == 0) {
switch (instr->Bits(11, 10)) {
case 0: {
VisitLoadStoreUnscaledOffset(instr);
break;
}
case 1: {
if (instr->Mask(0xC4C00000) == 0xC0800000) {
VisitUnallocated(instr);
} else {
VisitLoadStorePostIndex(instr);
}
break;
}
case 2: {
// TODO: VisitLoadStoreRegisterOffsetUnpriv.
VisitUnimplemented(instr);
break;
}
case 3: {
if (instr->Mask(0xC4C00000) == 0xC0800000) {
VisitUnallocated(instr);
} else {
VisitLoadStorePreIndex(instr);
}
break;
}
}
} else {
if (instr->Bits(11, 10) == 0x2) {
if (instr->Bit(14) == 0) {
VisitUnallocated(instr);
} else {
VisitLoadStoreRegisterOffset(instr);
}
} else {
VisitUnallocated(instr);
}
}
}
}
}
} else {
if (instr->Bit(28) == 0) {
if (instr->Bit(29) == 0) {
VisitUnallocated(instr);
} else {
if ((instr->Bits(31, 30) == 0x3) ||
(instr->Mask(0xC4400000) == 0x40000000)) {
VisitUnallocated(instr);
} else {
if (instr->Bit(23) == 0) {
VisitLoadStorePairOffset(instr);
} else {
VisitLoadStorePairPreIndex(instr);
}
}
}
} else {
if (instr->Bit(29) == 0) {
VisitUnallocated(instr);
} else {
if ((instr->Mask(0x84C00000) == 0x80C00000) ||
(instr->Mask(0x44800000) == 0x44800000) ||
(instr->Mask(0x84800000) == 0x84800000)) {
VisitUnallocated(instr);
} else {
VisitLoadStoreUnsignedOffset(instr);
}
}
}
}
}
void Decoder::DecodeLogical(Instruction* instr) {
ASSERT(instr->Bits(27, 24) == 0x2);
if (instr->Mask(0x80400000) == 0x00400000) {
VisitUnallocated(instr);
} else {
if (instr->Bit(23) == 0) {
VisitLogicalImmediate(instr);
} else {
if (instr->Bits(30, 29) == 0x1) {
VisitUnallocated(instr);
} else {
VisitMoveWideImmediate(instr);
}
}
}
}
void Decoder::DecodeBitfieldExtract(Instruction* instr) {
ASSERT(instr->Bits(27, 24) == 0x3);
if ((instr->Mask(0x80400000) == 0x80000000) ||
(instr->Mask(0x80400000) == 0x00400000) ||
(instr->Mask(0x80008000) == 0x00008000)) {
VisitUnallocated(instr);
} else if (instr->Bit(23) == 0) {
if ((instr->Mask(0x80200000) == 0x00200000) ||
(instr->Mask(0x60000000) == 0x60000000)) {
VisitUnallocated(instr);
} else {
VisitBitfield(instr);
}
} else {
if ((instr->Mask(0x60200000) == 0x00200000) ||
(instr->Mask(0x60000000) != 0x00000000)) {
VisitUnallocated(instr);
} else {
VisitExtract(instr);
}
}
}
void Decoder::DecodeAddSubImmediate(Instruction* instr) {
ASSERT(instr->Bits(27, 24) == 0x1);
if (instr->Bit(23) == 1) {
VisitUnallocated(instr);
} else {
VisitAddSubImmediate(instr);
}
}
void Decoder::DecodeDataProcessing(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0xA) ||
(instr->Bits(27, 24) == 0xB) );
if (instr->Bit(24) == 0) {
if (instr->Bit(28) == 0) {
if (instr->Mask(0x80008000) == 0x00008000) {
VisitUnallocated(instr);
} else {
VisitLogicalShifted(instr);
}
} else {
switch (instr->Bits(23, 21)) {
case 0: {
if (instr->Mask(0x0000FC00) != 0) {
VisitUnallocated(instr);
} else {
VisitAddSubWithCarry(instr);
}
break;
}
case 2: {
if ((instr->Bit(29) == 0) ||
(instr->Mask(0x00000410) != 0)) {
VisitUnallocated(instr);
} else {
if (instr->Bit(11) == 0) {
VisitConditionalCompareRegister(instr);
} else {
VisitConditionalCompareImmediate(instr);
}
}
break;
}
case 4: {
if (instr->Mask(0x20000800) != 0x00000000) {
VisitUnallocated(instr);
} else {
VisitConditionalSelect(instr);
}
break;
}
case 6: {
if (instr->Bit(29) == 0x1) {
VisitUnallocated(instr);
} else {
if (instr->Bit(30) == 0) {
if ((instr->Bit(15) == 0x1) ||
(instr->Bits(15, 11) == 0) ||
(instr->Bits(15, 12) == 0x1) ||
(instr->Bits(15, 12) == 0x3) ||
(instr->Bits(15, 13) == 0x3) ||
(instr->Mask(0x8000EC00) == 0x00004C00) ||
(instr->Mask(0x8000E800) == 0x80004000) ||
(instr->Mask(0x8000E400) == 0x80004000)) {
VisitUnallocated(instr);
} else {
VisitDataProcessing2Source(instr);
}
} else {
if ((instr->Bit(13) == 1) ||
(instr->Bits(20, 16) != 0) ||
(instr->Bits(15, 14) != 0) ||
(instr->Mask(0xA01FFC00) == 0x00000C00) ||
(instr->Mask(0x201FF800) == 0x00001800)) {
VisitUnallocated(instr);
} else {
VisitDataProcessing1Source(instr);
}
}
break;
}
}
case 1:
case 3:
case 5:
case 7: VisitUnallocated(instr); break;
}
}
} else {
if (instr->Bit(28) == 0) {
if (instr->Bit(21) == 0) {
if ((instr->Bits(23, 22) == 0x3) ||
(instr->Mask(0x80008000) == 0x00008000)) {
VisitUnallocated(instr);
} else {
VisitAddSubShifted(instr);
}
} else {
if ((instr->Mask(0x00C00000) != 0x00000000) ||
(instr->Mask(0x00001400) == 0x00001400) ||
(instr->Mask(0x00001800) == 0x00001800)) {
VisitUnallocated(instr);
} else {
VisitAddSubExtended(instr);
}
}
} else {
if ((instr->Bit(30) == 0x1) ||
(instr->Bits(30, 29) == 0x1) ||
(instr->Mask(0xE0600000) == 0x00200000) ||
(instr->Mask(0xE0608000) == 0x00400000) ||
(instr->Mask(0x60608000) == 0x00408000) ||
(instr->Mask(0x60E00000) == 0x00E00000) ||
(instr->Mask(0x60E00000) == 0x00800000) ||
(instr->Mask(0x60E00000) == 0x00600000)) {
VisitUnallocated(instr);
} else {
VisitDataProcessing3Source(instr);
}
}
}
}
void Decoder::DecodeFP(Instruction* instr) {
ASSERT((instr->Bits(27, 24) == 0xE) ||
(instr->Bits(27, 24) == 0xF) );
if (instr->Bit(28) == 0) {
DecodeAdvSIMDDataProcessing(instr);
} else {
if (instr->Bit(29) == 1) {
VisitUnallocated(instr);
} else {
if (instr->Bits(31, 30) == 0x3) {
VisitUnallocated(instr);
} else if (instr->Bits(31, 30) == 0x1) {
DecodeAdvSIMDDataProcessing(instr);
} else {
if (instr->Bit(24) == 0) {
if (instr->Bit(21) == 0) {
if ((instr->Bit(23) == 1) ||
(instr->Bit(18) == 1) ||
(instr->Mask(0x80008000) == 0x00000000) ||
(instr->Mask(0x000E0000) == 0x00000000) ||
(instr->Mask(0x000E0000) == 0x000A0000) ||
(instr->Mask(0x00160000) == 0x00000000) ||
(instr->Mask(0x00160000) == 0x00120000)) {
VisitUnallocated(instr);
} else {
VisitFPFixedPointConvert(instr);
}
} else {
if (instr->Bits(15, 10) == 32) {
VisitUnallocated(instr);
} else if (instr->Bits(15, 10) == 0) {
if ((instr->Bits(23, 22) == 0x3) ||
(instr->Mask(0x000E0000) == 0x000A0000) ||
(instr->Mask(0x000E0000) == 0x000C0000) ||
(instr->Mask(0x00160000) == 0x00120000) ||
(instr->Mask(0x00160000) == 0x00140000) ||
(instr->Mask(0x20C40000) == 0x00800000) ||
(instr->Mask(0x20C60000) == 0x00840000) ||
(instr->Mask(0xA0C60000) == 0x80060000) ||
(instr->Mask(0xA0C60000) == 0x00860000) ||
(instr->Mask(0xA0C60000) == 0x00460000) ||
(instr->Mask(0xA0CE0000) == 0x80860000) ||
(instr->Mask(0xA0CE0000) == 0x804E0000) ||
(instr->Mask(0xA0CE0000) == 0x000E0000) ||
(instr->Mask(0xA0D60000) == 0x00160000) ||
(instr->Mask(0xA0D60000) == 0x80560000) ||
(instr->Mask(0xA0D60000) == 0x80960000)) {
VisitUnallocated(instr);
} else {
VisitFPIntegerConvert(instr);
}
} else if (instr->Bits(14, 10) == 16) {
const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000);
if ((instr->Mask(0x80180000) != 0) ||
(masked_A0DF8000 == 0x00020000) ||
(masked_A0DF8000 == 0x00030000) ||
(masked_A0DF8000 == 0x00068000) ||
(masked_A0DF8000 == 0x00428000) ||
(masked_A0DF8000 == 0x00430000) ||
(masked_A0DF8000 == 0x00468000) ||
(instr->Mask(0xA0D80000) == 0x00800000) ||
(instr->Mask(0xA0DE0000) == 0x00C00000) ||
(instr->Mask(0xA0DF0000) == 0x00C30000) ||
(instr->Mask(0xA0DC0000) == 0x00C40000)) {
VisitUnallocated(instr);
} else {
VisitFPDataProcessing1Source(instr);
}
} else if (instr->Bits(13, 10) == 8) {
if ((instr->Bits(15, 14) != 0) ||
(instr->Bits(2, 0) != 0) ||
(instr->Mask(0x80800000) != 0x00000000)) {
VisitUnallocated(instr);
} else {
VisitFPCompare(instr);
}
} else if (instr->Bits(12, 10) == 4) {
if ((instr->Bits(9, 5) != 0) ||
(instr->Mask(0x80800000) != 0x00000000)) {
VisitUnallocated(instr);
} else {
VisitFPImmediate(instr);
}
} else {
if (instr->Mask(0x80800000) != 0x00000000) {
VisitUnallocated(instr);
} else {
switch (instr->Bits(11, 10)) {
case 1: {
VisitFPConditionalCompare(instr);
break;
}
case 2: {
if ((instr->Bits(15, 14) == 0x3) ||
(instr->Mask(0x00009000) == 0x00009000) ||
(instr->Mask(0x0000A000) == 0x0000A000)) {
VisitUnallocated(instr);
} else {
VisitFPDataProcessing2Source(instr);
}
break;
}
case 3: {
VisitFPConditionalSelect(instr);
break;
}
default: UNREACHABLE();
}
}
}
}
} else {
// Bit 30 == 1 has been handled earlier.
ASSERT(instr->Bit(30) == 0);
if (instr->Mask(0xA0800000) != 0) {
VisitUnallocated(instr);
} else {
VisitFPDataProcessing3Source(instr);
}
}
}
}
}
}
void Decoder::DecodeAdvSIMDLoadStore(Instruction* instr) {
// TODO: Implement Advanced SIMD load/store instruction decode.
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);
VisitUnimplemented(instr);
}
#define DEFINE_VISITOR_CALLERS(A) \
void Decoder::Visit##A(Instruction *instr) { \
ASSERT(instr->Mask(A##FMask) == A##Fixed); \
std::list<DecoderVisitor*>::iterator it; \
for (it = visitors_.begin(); it != visitors_.end(); it++) { \
(*it)->Visit##A(instr); \
} \
}
VISITOR_LIST(DEFINE_VISITOR_CALLERS)
#undef DEFINE_VISITOR_CALLERS
} // namespace vixl

View File

@@ -0,0 +1,198 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_A64_DECODER_A64_H_
#define VIXL_A64_DECODER_A64_H_
#include <list>
#include "globals.h"
#include "a64/instructions-a64.h"
// List macro containing all visitors needed by the decoder class.
#define VISITOR_LIST(V) \
V(PCRelAddressing) \
V(AddSubImmediate) \
V(LogicalImmediate) \
V(MoveWideImmediate) \
V(Bitfield) \
V(Extract) \
V(UnconditionalBranch) \
V(UnconditionalBranchToRegister) \
V(CompareBranch) \
V(TestBranch) \
V(ConditionalBranch) \
V(System) \
V(Exception) \
V(LoadStorePairPostIndex) \
V(LoadStorePairOffset) \
V(LoadStorePairPreIndex) \
V(LoadStorePairNonTemporal) \
V(LoadLiteral) \
V(LoadStoreUnscaledOffset) \
V(LoadStorePostIndex) \
V(LoadStorePreIndex) \
V(LoadStoreRegisterOffset) \
V(LoadStoreUnsignedOffset) \
V(LogicalShifted) \
V(AddSubShifted) \
V(AddSubExtended) \
V(AddSubWithCarry) \
V(ConditionalCompareRegister) \
V(ConditionalCompareImmediate) \
V(ConditionalSelect) \
V(DataProcessing1Source) \
V(DataProcessing2Source) \
V(DataProcessing3Source) \
V(FPCompare) \
V(FPConditionalCompare) \
V(FPConditionalSelect) \
V(FPImmediate) \
V(FPDataProcessing1Source) \
V(FPDataProcessing2Source) \
V(FPDataProcessing3Source) \
V(FPIntegerConvert) \
V(FPFixedPointConvert) \
V(Unallocated) \
V(Unimplemented)
namespace vixl {
// The Visitor interface. Disassembler and simulator (and other tools)
// must provide implementations for all of these functions.
class DecoderVisitor {
public:
#define DECLARE(A) virtual void Visit##A(Instruction* instr) = 0;
VISITOR_LIST(DECLARE)
#undef DECLARE
virtual ~DecoderVisitor() {}
private:
// Visitors are registered in a list.
std::list<DecoderVisitor*> visitors_;
friend class Decoder;
};
class Decoder: public DecoderVisitor {
public:
Decoder() {}
// Top-level instruction decoder function. Decodes an instruction and calls
// the visitor functions registered with the Decoder class.
void Decode(Instruction *instr);
// Register a new visitor class with the decoder.
// Decode() will call the corresponding visitor method from all registered
// visitor classes when decoding reaches the leaf node of the instruction
// decode tree.
// Visitors are called in the order.
// A visitor can only be registered once.
// Registering an already registered visitor will update its position.
//
// d.AppendVisitor(V1);
// d.AppendVisitor(V2);
// d.PrependVisitor(V2); // Move V2 at the start of the list.
// d.InsertVisitorBefore(V3, V2);
// d.AppendVisitor(V4);
// d.AppendVisitor(V4); // No effect.
//
// d.Decode(i);
//
// will call in order visitor methods in V3, V2, V1, V4.
void AppendVisitor(DecoderVisitor* visitor);
void PrependVisitor(DecoderVisitor* visitor);
void InsertVisitorBefore(DecoderVisitor* new_visitor,
DecoderVisitor* registered_visitor);
void InsertVisitorAfter(DecoderVisitor* new_visitor,
DecoderVisitor* registered_visitor);
// Remove a previously registered visitor class from the list of visitors
// stored by the decoder.
void RemoveVisitor(DecoderVisitor* visitor);
#define DECLARE(A) void Visit##A(Instruction* instr);
VISITOR_LIST(DECLARE)
#undef DECLARE
private:
// Decode the PC relative addressing instruction, and call the corresponding
// visitors.
// On entry, instruction bits 27:24 = 0x0.
void DecodePCRelAddressing(Instruction* instr);
// Decode the add/subtract immediate instruction, and call the correspoding
// visitors.
// On entry, instruction bits 27:24 = 0x1.
void DecodeAddSubImmediate(Instruction* instr);
// Decode the branch, system command, and exception generation parts of
// the instruction tree, and call the corresponding visitors.
// On entry, instruction bits 27:24 = {0x4, 0x5, 0x6, 0x7}.
void DecodeBranchSystemException(Instruction* instr);
// Decode the load and store parts of the instruction tree, and call
// the corresponding visitors.
// On entry, instruction bits 27:24 = {0x8, 0x9, 0xC, 0xD}.
void DecodeLoadStore(Instruction* instr);
// Decode the logical immediate and move wide immediate parts of the
// instruction tree, and call the corresponding visitors.
// On entry, instruction bits 27:24 = 0x2.
void DecodeLogical(Instruction* instr);
// Decode the bitfield and extraction parts of the instruction tree,
// and call the corresponding visitors.
// On entry, instruction bits 27:24 = 0x3.
void DecodeBitfieldExtract(Instruction* instr);
// Decode the data processing parts of the instruction tree, and call the
// corresponding visitors.
// On entry, instruction bits 27:24 = {0x1, 0xA, 0xB}.
void DecodeDataProcessing(Instruction* instr);
// Decode the floating point parts of the instruction tree, and call the
// corresponding visitors.
// On entry, instruction bits 27:24 = {0xE, 0xF}.
void DecodeFP(Instruction* instr);
// Decode the Advanced SIMD (NEON) load/store part of the instruction tree,
// and call the corresponding visitors.
// On entry, instruction bits 29:25 = 0x6.
void DecodeAdvSIMDLoadStore(Instruction* instr);
// Decode the Advanced SIMD (NEON) data processing part of the instruction
// tree, and call the corresponding visitors.
// On entry, instruction bits 27:25 = 0x7.
void DecodeAdvSIMDDataProcessing(Instruction* instr);
};
} // namespace vixl
#endif // VIXL_A64_DECODER_A64_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_A64_DISASM_A64_H
#define VIXL_A64_DISASM_A64_H
#include "globals.h"
#include "utils.h"
#include "instructions-a64.h"
#include "decoder-a64.h"
namespace vixl {
class Disassembler: public DecoderVisitor {
public:
Disassembler();
Disassembler(char* text_buffer, int buffer_size);
virtual ~Disassembler();
char* GetOutput();
// Declare all Visitor functions.
#define DECLARE(A) void Visit##A(Instruction* instr);
VISITOR_LIST(DECLARE)
#undef DECLARE
protected:
virtual void ProcessOutput(Instruction* instr);
private:
void Format(Instruction* instr, const char* mnemonic, const char* format);
void Substitute(Instruction* instr, const char* string);
int SubstituteField(Instruction* instr, const char* format);
int SubstituteRegisterField(Instruction* instr, const char* format);
int SubstituteImmediateField(Instruction* instr, const char* format);
int SubstituteLiteralField(Instruction* instr, const char* format);
int SubstituteBitfieldImmediateField(Instruction* instr, const char* format);
int SubstituteShiftField(Instruction* instr, const char* format);
int SubstituteExtendField(Instruction* instr, const char* format);
int SubstituteConditionField(Instruction* instr, const char* format);
int SubstitutePCRelAddressField(Instruction* instr, const char* format);
int SubstituteBranchTargetField(Instruction* instr, const char* format);
int SubstituteLSRegOffsetField(Instruction* instr, const char* format);
int SubstitutePrefetchField(Instruction* instr, const char* format);
inline bool RdIsZROrSP(Instruction* instr) const {
return (instr->Rd() == kZeroRegCode);
}
inline bool RnIsZROrSP(Instruction* instr) const {
return (instr->Rn() == kZeroRegCode);
}
inline bool RmIsZROrSP(Instruction* instr) const {
return (instr->Rm() == kZeroRegCode);
}
inline bool RaIsZROrSP(Instruction* instr) const {
return (instr->Ra() == kZeroRegCode);
}
bool IsMovzMovnImm(unsigned reg_size, uint64_t value);
void ResetOutput();
void AppendToOutput(const char* string, ...);
char* buffer_;
uint32_t buffer_pos_;
uint32_t buffer_size_;
bool own_buffer_;
};
class PrintDisassembler: public Disassembler {
public:
explicit PrintDisassembler(FILE* stream) : stream_(stream) { }
~PrintDisassembler() { }
protected:
virtual void ProcessOutput(Instruction* instr);
private:
FILE *stream_;
};
} // namespace vixl
#endif // VIXL_A64_DISASM_A64_H

View File

@@ -0,0 +1,238 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "a64/instructions-a64.h"
#include "a64/assembler-a64.h"
namespace vixl {
static uint64_t RotateRight(uint64_t value,
unsigned int rotate,
unsigned int width) {
ASSERT(width <= 64);
rotate &= 63;
return ((value & ((1UL << rotate) - 1UL)) << (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);
for (unsigned i = width; i < reg_size; i *= 2) {
result |= (result << i);
}
return result;
}
// Logical immediates can't encode zero, so a return value of zero is used to
// indicate a failure case. Specifically, where the constraints on imm_s are
// not met.
uint64_t Instruction::ImmLogical() {
unsigned reg_size = SixtyFourBits() ? kXRegSize : kWRegSize;
int64_t n = BitN();
int64_t imm_s = ImmSetBits();
int64_t imm_r = ImmRotate();
// An integer is constructed from the n, imm_s and imm_r bits according to
// the following table:
//
// N imms immr size S R
// 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr)
// 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr)
// 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr)
// 0 110sss xxxrrr 8 UInt(sss) UInt(rrr)
// 0 1110ss xxxxrr 4 UInt(ss) UInt(rr)
// 0 11110s xxxxxr 2 UInt(s) UInt(r)
// (s bits must not be all set)
//
// A pattern is constructed of size bits, where the least significant S+1
// bits are set. The pattern is rotated right by R, and repeated across a
// 32 or 64-bit value, depending on destination register width.
//
if (n == 1) {
if (imm_s == 0x3F) {
return 0;
}
uint64_t bits = (1UL << (imm_s + 1)) - 1;
return RotateRight(bits, imm_r, 64);
} else {
if ((imm_s >> 1) == 0x1F) {
return 0;
}
for (int width = 0x20; width >= 0x2; width >>= 1) {
if ((imm_s & width) == 0) {
int mask = width - 1;
if ((imm_s & mask) == mask) {
return 0;
}
uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1;
return RepeatBitsAcrossReg(reg_size,
RotateRight(bits, imm_r & mask, width),
width);
}
}
}
UNREACHABLE();
return 0;
}
float Instruction::ImmFP32() {
// ImmFP: abcdefgh (8 bits)
// Single: aBbb.bbbc.defg.h000.0000.0000.0000.0000 (32 bits)
// where B is b ^ 1
uint32_t bits = ImmFP();
uint32_t bit7 = (bits >> 7) & 0x1;
uint32_t bit6 = (bits >> 6) & 0x1;
uint32_t bit5_to_0 = bits & 0x3f;
uint32_t result = (bit7 << 31) | ((32 - bit6) << 25) | (bit5_to_0 << 19);
return rawbits_to_float(result);
}
double Instruction::ImmFP64() {
// ImmFP: abcdefgh (8 bits)
// Double: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
// 0000.0000.0000.0000.0000.0000.0000.0000 (64 bits)
// where B is b ^ 1
uint32_t bits = ImmFP();
uint64_t bit7 = (bits >> 7) & 0x1;
uint64_t bit6 = (bits >> 6) & 0x1;
uint64_t bit5_to_0 = bits & 0x3f;
uint64_t result = (bit7 << 63) | ((256 - bit6) << 54) | (bit5_to_0 << 48);
return rawbits_to_double(result);
}
LSDataSize CalcLSPairDataSize(LoadStorePairOp op) {
switch (op) {
case STP_x:
case LDP_x:
case STP_d:
case LDP_d: return LSDoubleWord;
default: return LSWord;
}
}
Instruction* Instruction::ImmPCOffsetTarget() {
ptrdiff_t offset;
if (IsPCRelAddressing()) {
// PC-relative addressing. Only ADR is supported.
offset = ImmPCRel();
} else {
// All PC-relative branches.
ASSERT(BranchType() != UnknownBranchType);
// Relative branch offsets are instruction-size-aligned.
offset = ImmBranch() << kInstructionSizeLog2;
}
return this + offset;
}
inline int Instruction::ImmBranch() const {
switch (BranchType()) {
case CondBranchType: return ImmCondBranch();
case UncondBranchType: return ImmUncondBranch();
case CompareBranchType: return ImmCmpBranch();
case TestBranchType: return ImmTestBranch();
default: UNREACHABLE();
}
return 0;
}
void Instruction::SetImmPCOffsetTarget(Instruction* target) {
if (IsPCRelAddressing()) {
SetPCRelImmTarget(target);
} else {
SetBranchImmTarget(target);
}
}
void Instruction::SetPCRelImmTarget(Instruction* target) {
// ADRP is not supported, so 'this' must point to an ADR instruction.
ASSERT(Mask(PCRelAddressingMask) == ADR);
Instr imm = Assembler::ImmPCRelAddress(target - this);
SetInstructionBits(Mask(~ImmPCRel_mask) | imm);
}
void Instruction::SetBranchImmTarget(Instruction* target) {
ASSERT(((target - this) & 3) == 0);
Instr branch_imm = 0;
uint32_t imm_mask = 0;
int offset = (target - this) >> kInstructionSizeLog2;
switch (BranchType()) {
case CondBranchType: {
branch_imm = Assembler::ImmCondBranch(offset);
imm_mask = ImmCondBranch_mask;
break;
}
case UncondBranchType: {
branch_imm = Assembler::ImmUncondBranch(offset);
imm_mask = ImmUncondBranch_mask;
break;
}
case CompareBranchType: {
branch_imm = Assembler::ImmCmpBranch(offset);
imm_mask = ImmCmpBranch_mask;
break;
}
case TestBranchType: {
branch_imm = Assembler::ImmTestBranch(offset);
imm_mask = ImmTestBranch_mask;
break;
}
default: UNREACHABLE();
}
SetInstructionBits(Mask(~imm_mask) | branch_imm);
}
void Instruction::SetImmLLiteral(Instruction* source) {
ASSERT(((source - this) & 3) == 0);
int offset = (source - this) >> kLiteralEntrySizeLog2;
Instr imm = Assembler::ImmLLiteral(offset);
Instr mask = ImmLLiteral_mask;
SetInstructionBits(Mask(~mask) | imm);
}
} // namespace vixl

View File

@@ -0,0 +1,344 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_A64_INSTRUCTIONS_A64_H_
#define VIXL_A64_INSTRUCTIONS_A64_H_
#include "globals.h"
#include "utils.h"
#include "a64/constants-a64.h"
namespace vixl {
// ISA constants. --------------------------------------------------------------
typedef uint32_t Instr;
const unsigned kInstructionSize = 4;
const unsigned kInstructionSizeLog2 = 2;
const unsigned kLiteralEntrySize = 4;
const unsigned kLiteralEntrySizeLog2 = 2;
const unsigned kMaxLoadLiteralRange = 1 * MBytes;
const unsigned kWRegSize = 32;
const unsigned kWRegSizeLog2 = 5;
const unsigned kWRegSizeInBytes = kWRegSize / 8;
const unsigned kXRegSize = 64;
const unsigned kXRegSizeLog2 = 6;
const unsigned kXRegSizeInBytes = kXRegSize / 8;
const unsigned kSRegSize = 32;
const unsigned kSRegSizeLog2 = 5;
const unsigned kSRegSizeInBytes = kSRegSize / 8;
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 kLinkRegCode = 30;
const unsigned kZeroRegCode = 31;
const unsigned kSPRegInternalCode = 63;
const unsigned kRegCodeMask = 0x1f;
// AArch64 floating-point specifics. These match IEEE-754.
const unsigned kDoubleMantissaBits = 52;
const unsigned kDoubleExponentBits = 11;
const unsigned kFloatMantissaBits = 23;
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);
// 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 float kFP32SignallingNaN = rawbits_to_float(0x7f800001);
// A similar value, but as a quiet NaN.
static const double kFP64QuietNaN = rawbits_to_double(0x7ff800007fc00001ULL);
static const float kFP32QuietNaN = rawbits_to_float(0x7fc00001);
enum LSDataSize {
LSByte = 0,
LSHalfword = 1,
LSWord = 2,
LSDoubleWord = 3
};
LSDataSize CalcLSPairDataSize(LoadStorePairOp op);
enum ImmBranchType {
UnknownBranchType = 0,
CondBranchType = 1,
UncondBranchType = 2,
CompareBranchType = 3,
TestBranchType = 4
};
enum AddrMode {
Offset,
PreIndex,
PostIndex
};
enum FPRounding {
// The first four values are encodable directly by FPCR<RMode>.
FPTieEven = 0x0,
FPPositiveInfinity = 0x1,
FPNegativeInfinity = 0x2,
FPZero = 0x3,
// The final rounding mode is only available when explicitly specified by the
// instruction (such as with fcvta). It cannot be set in FPCR.
FPTieAway
};
enum Reg31Mode {
Reg31IsStackPointer,
Reg31IsZeroRegister
};
// Instructions. ---------------------------------------------------------------
class Instruction {
public:
inline Instr InstructionBits() const {
return *(reinterpret_cast<const Instr*>(this));
}
inline void SetInstructionBits(Instr new_instr) {
*(reinterpret_cast<Instr*>(this)) = new_instr;
}
inline int Bit(int pos) const {
return (InstructionBits() >> pos) & 1;
}
inline uint32_t Bits(int msb, int lsb) const {
return unsigned_bitextract_32(msb, lsb, InstructionBits());
}
inline int32_t SignedBits(int msb, int lsb) const {
int32_t bits = *(reinterpret_cast<const int32_t*>(this));
return signed_bitextract_32(msb, lsb, bits);
}
inline Instr Mask(uint32_t mask) const {
return InstructionBits() & mask;
}
#define DEFINE_GETTER(Name, HighBit, LowBit, Func) \
inline int64_t Name() const { return Func(HighBit, LowBit); }
INSTRUCTION_FIELDS_LIST(DEFINE_GETTER)
#undef DEFINE_GETTER
// ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST),
// formed from ImmPCRelLo and ImmPCRelHi.
int ImmPCRel() const {
int const offset = ((ImmPCRelHi() << ImmPCRelLo_width) | ImmPCRelLo());
int const width = ImmPCRelLo_width + ImmPCRelHi_width;
return signed_bitextract_32(width-1, 0, offset);
}
uint64_t ImmLogical();
float ImmFP32();
double ImmFP64();
inline LSDataSize SizeLSPair() const {
return CalcLSPairDataSize(
static_cast<LoadStorePairOp>(Mask(LoadStorePairMask)));
}
// Helpers.
inline bool IsCondBranchImm() const {
return Mask(ConditionalBranchFMask) == ConditionalBranchFixed;
}
inline bool IsUncondBranchImm() const {
return Mask(UnconditionalBranchFMask) == UnconditionalBranchFixed;
}
inline bool IsCompareBranch() const {
return Mask(CompareBranchFMask) == CompareBranchFixed;
}
inline bool IsTestBranch() const {
return Mask(TestBranchFMask) == TestBranchFixed;
}
inline bool IsPCRelAddressing() const {
return Mask(PCRelAddressingFMask) == PCRelAddressingFixed;
}
inline bool IsLogicalImmediate() const {
return Mask(LogicalImmediateFMask) == LogicalImmediateFixed;
}
inline bool IsAddSubImmediate() const {
return Mask(AddSubImmediateFMask) == AddSubImmediateFixed;
}
inline bool IsAddSubExtended() const {
return Mask(AddSubExtendedFMask) == AddSubExtendedFixed;
}
inline bool IsLoadOrStore() const {
return Mask(LoadStoreAnyFMask) == LoadStoreAnyFixed;
}
inline bool IsMovn() const {
return (Mask(MoveWideImmediateMask) == MOVN_x) ||
(Mask(MoveWideImmediateMask) == MOVN_w);
}
// Indicate whether Rd can be the stack pointer or the zero register. This
// does not check that the instruction actually has an Rd field.
inline Reg31Mode RdMode() const {
// The following instructions use sp or wsp as Rd:
// Add/sub (immediate) when not setting the flags.
// Add/sub (extended) when not setting the flags.
// Logical (immediate) when not setting the flags.
// Otherwise, r31 is the zero register.
if (IsAddSubImmediate() || IsAddSubExtended()) {
if (Mask(AddSubSetFlagsBit)) {
return Reg31IsZeroRegister;
} else {
return Reg31IsStackPointer;
}
}
if (IsLogicalImmediate()) {
// Of the logical (immediate) instructions, only ANDS (and its aliases)
// can set the flags. The others can all write into sp.
// Note that some logical operations are not available to
// immediate-operand instructions, so we have to combine two masks here.
if (Mask(LogicalImmediateMask & LogicalOpMask) == ANDS) {
return Reg31IsZeroRegister;
} else {
return Reg31IsStackPointer;
}
}
return Reg31IsZeroRegister;
}
// Indicate whether Rn can be the stack pointer or the zero register. This
// does not check that the instruction actually has an Rn field.
inline Reg31Mode RnMode() const {
// The following instructions use sp or wsp as Rn:
// All loads and stores.
// Add/sub (immediate).
// Add/sub (extended).
// Otherwise, r31 is the zero register.
if (IsLoadOrStore() || IsAddSubImmediate() || IsAddSubExtended()) {
return Reg31IsStackPointer;
}
return Reg31IsZeroRegister;
}
inline ImmBranchType BranchType() const {
if (IsCondBranchImm()) {
return CondBranchType;
} else if (IsUncondBranchImm()) {
return UncondBranchType;
} else if (IsCompareBranch()) {
return CompareBranchType;
} else if (IsTestBranch()) {
return TestBranchType;
} else {
return UnknownBranchType;
}
}
// Find the target of this instruction. 'this' may be a branch or a
// PC-relative addressing instruction.
Instruction* ImmPCOffsetTarget();
// Patch a PC-relative offset to refer to 'target'. 'this' may be a branch or
// a PC-relative addressing instruction.
void SetImmPCOffsetTarget(Instruction* target);
// Patch a literal load instruction to load from 'source'.
void SetImmLLiteral(Instruction* source);
inline uint8_t* LiteralAddress() {
int offset = ImmLLiteral() << kLiteralEntrySizeLog2;
return reinterpret_cast<uint8_t*>(this) + offset;
}
inline uint32_t Literal32() {
uint32_t literal;
memcpy(&literal, LiteralAddress(), sizeof(literal));
return literal;
}
inline uint64_t Literal64() {
uint64_t literal;
memcpy(&literal, LiteralAddress(), sizeof(literal));
return literal;
}
inline float LiteralFP32() {
return rawbits_to_float(Literal32());
}
inline double LiteralFP64() {
return rawbits_to_double(Literal64());
}
inline Instruction* NextInstruction() {
return this + kInstructionSize;
}
inline Instruction* InstructionAtOffset(int64_t offset) {
ASSERT(IsWordAligned(this + offset));
return this + offset;
}
template<typename T> static inline Instruction* Cast(T src) {
return reinterpret_cast<Instruction*>(src);
}
private:
inline int ImmBranch() const;
void SetPCRelImmTarget(Instruction* target);
void SetBranchImmTarget(Instruction* target);
};
} // namespace vixl
#endif // VIXL_A64_INSTRUCTIONS_A64_H_

65
disas/libvixl/globals.h Normal file
View File

@@ -0,0 +1,65 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_GLOBALS_H
#define VIXL_GLOBALS_H
// Get the standard printf format macros for C99 stdint types.
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include "platform.h"
typedef uint8_t byte;
const int KBytes = 1024;
const int MBytes = 1024 * KBytes;
#define 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()
#else
#define ASSERT(condition) ((void) 0)
#define CHECK(condition) assert(condition)
#define UNIMPLEMENTED() ((void) 0)
#define UNREACHABLE() ((void) 0)
#endif
template <typename T> inline void USE(T) {}
#define ALIGNMENT_EXCEPTION() printf("ALIGNMENT EXCEPTION\t"); ABORT()
#endif // VIXL_GLOBALS_H

43
disas/libvixl/platform.h Normal file
View File

@@ -0,0 +1,43 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PLATFORM_H
#define PLATFORM_H
// Define platform specific functionalities.
namespace vixl {
#ifdef USE_SIMULATOR
// 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.
}
#endif
} // namespace vixl
#endif

126
disas/libvixl/utils.cc Normal file
View File

@@ -0,0 +1,126 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "utils.h"
#include <stdio.h>
namespace vixl {
uint32_t float_to_rawbits(float value) {
uint32_t bits = 0;
memcpy(&bits, &value, 4);
return bits;
}
uint64_t double_to_rawbits(double value) {
uint64_t bits = 0;
memcpy(&bits, &value, 8);
return bits;
}
float rawbits_to_float(uint32_t bits) {
float value = 0.0;
memcpy(&value, &bits, 4);
return value;
}
double rawbits_to_double(uint64_t bits) {
double value = 0.0;
memcpy(&value, &bits, 8);
return value;
}
int CountLeadingZeros(uint64_t value, int width) {
ASSERT((width == 32) || (width == 64));
int count = 0;
uint64_t bit_test = 1UL << (width - 1);
while ((count < width) && ((bit_test & value) == 0)) {
count++;
bit_test >>= 1;
}
return count;
}
int CountLeadingSignBits(int64_t value, int width) {
ASSERT((width == 32) || (width == 64));
if (value >= 0) {
return CountLeadingZeros(value, width) - 1;
} else {
return CountLeadingZeros(~value, width) - 1;
}
}
int CountTrailingZeros(uint64_t value, int width) {
ASSERT((width == 32) || (width == 64));
int count = 0;
while ((count < width) && (((value >> count) & 1) == 0)) {
count++;
}
return count;
}
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));
// Mask out unused bits to ensure that they are not counted.
value &= (0xffffffffffffffffULL >> (64-width));
// Add up the set bits.
// The algorithm works by adding pairs of bit fields together iteratively,
// where the size of each bit field doubles each time.
// An example for an 8-bit value:
// Bits: h g f e d c b a
// \ | \ | \ | \ |
// value = h+g f+e d+c b+a
// \ | \ |
// 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);
return value;
}
} // namespace vixl

126
disas/libvixl/utils.h Normal file
View File

@@ -0,0 +1,126 @@
// Copyright 2013, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_UTILS_H
#define VIXL_UTILS_H
#include <string.h>
#include "globals.h"
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);
return (-limit <= x) && (x < limit);
}
inline bool is_uintn(unsigned n, int64_t x) {
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));
}
#define INT_1_TO_63_LIST(V) \
V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) \
V(9) V(10) V(11) V(12) V(13) V(14) V(15) V(16) \
V(17) V(18) V(19) V(20) V(21) V(22) V(23) V(24) \
V(25) V(26) V(27) V(28) V(29) V(30) V(31) V(32) \
V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \
V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) \
V(49) V(50) V(51) V(52) V(53) V(54) V(55) V(56) \
V(57) V(58) V(59) V(60) V(61) V(62) V(63)
#define DECLARE_IS_INT_N(N) \
inline bool is_int##N(int64_t x) { return is_intn(N, x); }
#define DECLARE_IS_UINT_N(N) \
inline bool is_uint##N(int64_t x) { return is_uintn(N, x); }
#define DECLARE_TRUNCATE_TO_INT_N(N) \
inline int truncate_to_int##N(int x) { return truncate_to_intn(N, x); }
INT_1_TO_63_LIST(DECLARE_IS_INT_N)
INT_1_TO_63_LIST(DECLARE_IS_UINT_N)
INT_1_TO_63_LIST(DECLARE_TRUNCATE_TO_INT_N)
#undef DECLARE_IS_INT_N
#undef DECLARE_IS_UINT_N
#undef DECLARE_TRUNCATE_TO_INT_N
// Bit field extraction.
inline uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x) {
return (x >> lsb) & ((1 << (1 + msb - lsb)) - 1);
}
inline uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x) {
return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1);
}
inline int32_t signed_bitextract_32(int msb, int lsb, int32_t x) {
return (x << (31 - msb)) >> (lsb + 31 - msb);
}
inline int64_t signed_bitextract_64(int msb, int lsb, int64_t x) {
return (x << (63 - msb)) >> (lsb + 63 - msb);
}
// 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.
int CountLeadingZeros(uint64_t value, int width);
int CountLeadingSignBits(int64_t value, int width);
int CountTrailingZeros(uint64_t value, int width);
int CountSetBits(uint64_t value, int width);
// Pointer alignment
// 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)
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));
uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
size_t align_step = (alignment - pointer_raw) % alignment;
ASSERT((pointer_raw + align_step) % alignment == 0);
return reinterpret_cast<T>(pointer_raw + align_step);
}
} // namespace vixl
#endif // VIXL_UTILS_H

View File

@@ -225,6 +225,45 @@ Data:
"timestamp": { "seconds": 1368697518, "microseconds": 326866 } } "timestamp": { "seconds": 1368697518, "microseconds": 326866 } }
} }
QUORUM_FAILURE
--------------
Emitted by the Quorum block driver if it fails to establish a quorum.
Data:
- "reference": device name if defined else node name.
- "sector-num": Number of the first sector of the failed read operation.
- "sector-count": Failed read operation sector count.
Example:
{ "event": "QUORUM_FAILURE",
"data": { "reference": "usr1", "sector-num": 345435, "sector-count": 5 },
"timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
QUORUM_REPORT_BAD
-----------------
Emitted to report a corruption of a Quorum file.
Data:
- "error": Error message (json-string, optional)
Only present on failure. This field contains a human-readable
error message. There are no semantics other than that the
block layer reported an error and clients should not try to
interpret the error string.
- "node-name": The graph node name of the block driver state.
- "sector-num": Number of the first sector of the failed read operation.
- "sector-count": Failed read operation sector count.
Example:
{ "event": "QUORUM_REPORT_BAD",
"data": { "node-name": "1.raw", "sector-num": 345435, "sector-count": 5 },
"timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
RESET RESET
----- -----

View File

@@ -66,7 +66,7 @@ bulk-phase round of the migration and can be enabled for extremely
high-performance RDMA hardware using the following command: high-performance RDMA hardware using the following command:
QEMU Monitor Command: QEMU Monitor Command:
$ migrate_set_capability x-rdma-pin-all on # disabled by default $ migrate_set_capability rdma-pin-all on # disabled by default
Performing this action will cause all 8GB to be pinned, so if that's Performing this action will cause all 8GB to be pinned, so if that's
not what you want, then please ignore this step altogether. not what you want, then please ignore this step altogether.
@@ -93,12 +93,12 @@ $ migrate_set_speed 40g # or whatever is the MAX of your RDMA device
Next, on the destination machine, add the following to the QEMU command line: Next, on the destination machine, add the following to the QEMU command line:
qemu ..... -incoming x-rdma:host:port qemu ..... -incoming rdma:host:port
Finally, perform the actual migration on the source machine: Finally, perform the actual migration on the source machine:
QEMU Monitor Command: QEMU Monitor Command:
$ migrate -d x-rdma:host:port $ migrate -d rdma:host:port
PERFORMANCE PERFORMANCE
=========== ===========
@@ -120,8 +120,8 @@ For example, in the same 8GB RAM example with all 8GB of memory in
active use and the VM itself is completely idle using the same 40 gbps active use and the VM itself is completely idle using the same 40 gbps
infiniband link: infiniband link:
1. x-rdma-pin-all disabled total time: approximately 7.5 seconds @ 9.5 Gbps 1. rdma-pin-all disabled total time: approximately 7.5 seconds @ 9.5 Gbps
2. x-rdma-pin-all enabled total time: approximately 4 seconds @ 26 Gbps 2. rdma-pin-all enabled total time: approximately 4 seconds @ 26 Gbps
These numbers would of course scale up to whatever size virtual machine These numbers would of course scale up to whatever size virtual machine
you have to migrate using RDMA. you have to migrate using RDMA.
@@ -407,18 +407,14 @@ socket is broken during a non-RDMA based migration.
TODO: TODO:
===== =====
1. 'migrate x-rdma:host:port' and '-incoming x-rdma' options will be 1. Currently, 'ulimit -l' mlock() limits as well as cgroups swap limits
renamed to 'rdma' after the experimental phase of this work has
completed upstream.
2. Currently, 'ulimit -l' mlock() limits as well as cgroups swap limits
are not compatible with infinband memory pinning and will result in are not compatible with infinband memory pinning and will result in
an aborted migration (but with the source VM left unaffected). an aborted migration (but with the source VM left unaffected).
3. Use of the recent /proc/<pid>/pagemap would likely speed up 2. Use of the recent /proc/<pid>/pagemap would likely speed up
the use of KSM and ballooning while using RDMA. the use of KSM and ballooning while using RDMA.
4. Also, some form of balloon-device usage tracking would also 3. Also, some form of balloon-device usage tracking would also
help alleviate some issues. help alleviate some issues.
5. Move UNREGISTER requests to a separate thread. 4. Use LRU to provide more fine-grained direction of UNREGISTER
6. Use LRU to provide more fine-grained direction of UNREGISTER
requests for unpinning memory in an overcommitted environment. requests for unpinning memory in an overcommitted environment.
7. Expose UNREGISTER support to the user by way of workload-specific 5. Expose UNREGISTER support to the user by way of workload-specific
hints about application behavior. hints about application behavior.

View File

@@ -214,6 +214,42 @@ The "ust" backend uses the LTTng Userspace Tracer library. There are no
monitor commands built into QEMU, instead UST utilities should be used to list, monitor commands built into QEMU, instead UST utilities should be used to list,
enable/disable, and dump traces. enable/disable, and dump traces.
Package lttng-tools is required for userspace tracing. You must ensure that the
current user belongs to the "tracing" group, or manually launch the
lttng-sessiond daemon for the current user prior to running any instance of
QEMU.
While running an instrumented QEMU, LTTng should be able to list all available
events:
lttng list -u
Create tracing session:
lttng create mysession
Enable events:
lttng enable-event qemu:g_malloc -u
Where the events can either be a comma-separated list of events, or "-a" to
enable all tracepoint events. Start and stop tracing as needed:
lttng start
lttng stop
View the trace:
lttng view
Destroy tracing session:
lttng destroy
Babeltrace can be used at any later time to view the trace:
babeltrace $HOME/lttng-traces/mysession-<date>-<time>
=== SystemTap === === SystemTap ===
The "dtrace" backend uses DTrace sdt probes but has only been tested with The "dtrace" backend uses DTrace sdt probes but has only been tested with

960
dump.c

File diff suppressed because it is too large Load Diff

222
exec.c
View File

@@ -17,9 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/ */
#include "config.h" #include "config.h"
#ifdef _WIN32 #ifndef _WIN32
#include <windows.h>
#else
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
@@ -138,6 +136,7 @@ typedef struct subpage_t {
static void io_mem_init(void); static void io_mem_init(void);
static void memory_map_init(void); static void memory_map_init(void);
static void tcg_commit(MemoryListener *listener);
static MemoryRegion io_mem_watch; static MemoryRegion io_mem_watch;
#endif #endif
@@ -325,7 +324,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
hwaddr *plen, bool resolve_subpage) hwaddr *plen, bool resolve_subpage)
{ {
MemoryRegionSection *section; MemoryRegionSection *section;
Int128 diff, diff_page; Int128 diff;
section = address_space_lookup_region(d, addr, resolve_subpage); section = address_space_lookup_region(d, addr, resolve_subpage);
/* Compute offset within MemoryRegionSection */ /* Compute offset within MemoryRegionSection */
@@ -334,13 +333,23 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
/* Compute offset within MemoryRegion */ /* Compute offset within MemoryRegion */
*xlat = addr + section->offset_within_region; *xlat = addr + section->offset_within_region;
diff_page = int128_make64(((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr);
diff = int128_sub(section->mr->size, int128_make64(addr)); diff = int128_sub(section->mr->size, int128_make64(addr));
diff = int128_min(diff, diff_page);
*plen = int128_get64(int128_min(diff, int128_make64(*plen))); *plen = int128_get64(int128_min(diff, int128_make64(*plen)));
return section; return section;
} }
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
if (memory_region_is_ram(mr)) {
return !(is_write && mr->readonly);
}
if (memory_region_is_romd(mr)) {
return !is_write;
}
return false;
}
MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
hwaddr *xlat, hwaddr *plen, hwaddr *xlat, hwaddr *plen,
bool is_write) bool is_write)
@@ -351,7 +360,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
hwaddr len = *plen; hwaddr len = *plen;
for (;;) { for (;;) {
section = address_space_translate_internal(as->dispatch, addr, &addr, &len, true); section = address_space_translate_internal(as->dispatch, addr, &addr, plen, true);
mr = section->mr; mr = section->mr;
if (!mr->iommu_ops) { if (!mr->iommu_ops) {
@@ -370,6 +379,11 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
as = iotlb.target_as; as = iotlb.target_as;
} }
if (memory_access_is_direct(mr, is_write)) {
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
len = MIN(page, len);
}
*plen = len; *plen = len;
*xlat = addr; *xlat = addr;
return mr; return mr;
@@ -438,6 +452,22 @@ CPUState *qemu_get_cpu(int index)
return NULL; return NULL;
} }
#if !defined(CONFIG_USER_ONLY)
void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as)
{
/* We only support one address space per cpu at the moment. */
assert(cpu->as == as);
if (cpu->tcg_as_listener) {
memory_listener_unregister(cpu->tcg_as_listener);
} else {
cpu->tcg_as_listener = g_new0(MemoryListener, 1);
}
cpu->tcg_as_listener->commit = tcg_commit;
memory_listener_register(cpu->tcg_as_listener, as);
}
#endif
void cpu_exec_init(CPUArchState *env) void cpu_exec_init(CPUArchState *env)
{ {
CPUState *cpu = ENV_GET_CPU(env); CPUState *cpu = ENV_GET_CPU(env);
@@ -457,6 +487,7 @@ void cpu_exec_init(CPUArchState *env)
QTAILQ_INIT(&env->breakpoints); QTAILQ_INIT(&env->breakpoints);
QTAILQ_INIT(&env->watchpoints); QTAILQ_INIT(&env->watchpoints);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
cpu->as = &address_space_memory;
cpu->thread_id = qemu_get_thread_id(); cpu->thread_id = qemu_get_thread_id();
#endif #endif
QTAILQ_INSERT_TAIL(&cpus, cpu, node); QTAILQ_INSERT_TAIL(&cpus, cpu, node);
@@ -488,7 +519,8 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
{ {
hwaddr phys = cpu_get_phys_page_debug(cpu, pc); hwaddr phys = cpu_get_phys_page_debug(cpu, pc);
if (phys != -1) { if (phys != -1) {
tb_invalidate_phys_addr(phys | (pc & ~TARGET_PAGE_MASK)); tb_invalidate_phys_addr(cpu->as,
phys | (pc & ~TARGET_PAGE_MASK));
} }
} }
#endif #endif
@@ -780,7 +812,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
iotlb |= PHYS_SECTION_ROM; iotlb |= PHYS_SECTION_ROM;
} }
} else { } else {
iotlb = section - address_space_memory.dispatch->map.sections; iotlb = section - section->address_space->dispatch->map.sections;
iotlb += xlat; iotlb += xlat;
} }
@@ -876,6 +908,7 @@ static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *secti
if (!(existing->mr->subpage)) { if (!(existing->mr->subpage)) {
subpage = subpage_init(d->as, base); subpage = subpage_init(d->as, base);
subsection.address_space = d->as;
subsection.mr = &subpage->iomem; subsection.mr = &subpage->iomem;
phys_page_set(d, base >> TARGET_PAGE_BITS, 1, phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
phys_section_add(&d->map, &subsection)); phys_section_add(&d->map, &subsection));
@@ -1577,9 +1610,9 @@ static uint64_t watch_mem_read(void *opaque, hwaddr addr,
{ {
check_watchpoint(addr & ~TARGET_PAGE_MASK, ~(size - 1), BP_MEM_READ); check_watchpoint(addr & ~TARGET_PAGE_MASK, ~(size - 1), BP_MEM_READ);
switch (size) { switch (size) {
case 1: return ldub_phys(addr); case 1: return ldub_phys(&address_space_memory, addr);
case 2: return lduw_phys(addr); case 2: return lduw_phys(&address_space_memory, addr);
case 4: return ldl_phys(addr); case 4: return ldl_phys(&address_space_memory, addr);
default: abort(); default: abort();
} }
} }
@@ -1590,13 +1623,13 @@ static void watch_mem_write(void *opaque, hwaddr addr,
check_watchpoint(addr & ~TARGET_PAGE_MASK, ~(size - 1), BP_MEM_WRITE); check_watchpoint(addr & ~TARGET_PAGE_MASK, ~(size - 1), BP_MEM_WRITE);
switch (size) { switch (size) {
case 1: case 1:
stb_phys(addr, val); stb_phys(&address_space_memory, addr, val);
break; break;
case 2: case 2:
stw_phys(addr, val); stw_phys(&address_space_memory, addr, val);
break; break;
case 4: case 4:
stl_phys(addr, val); stl_phys(&address_space_memory, addr, val);
break; break;
default: abort(); default: abort();
} }
@@ -1721,6 +1754,7 @@ static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
static uint16_t dummy_section(PhysPageMap *map, MemoryRegion *mr) static uint16_t dummy_section(PhysPageMap *map, MemoryRegion *mr)
{ {
MemoryRegionSection section = { MemoryRegionSection section = {
.address_space = &address_space_memory,
.mr = mr, .mr = mr,
.offset_within_address_space = 0, .offset_within_address_space = 0,
.offset_within_region = 0, .offset_within_region = 0,
@@ -1730,10 +1764,9 @@ static uint16_t dummy_section(PhysPageMap *map, MemoryRegion *mr)
return phys_section_add(map, &section); return phys_section_add(map, &section);
} }
MemoryRegion *iotlb_to_region(hwaddr index) MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index)
{ {
return address_space_memory.dispatch->map.sections[ return as->dispatch->map.sections[index & ~TARGET_PAGE_MASK].mr;
index & ~TARGET_PAGE_MASK].mr;
} }
static void io_mem_init(void) static void io_mem_init(void)
@@ -1793,6 +1826,11 @@ static void tcg_commit(MemoryListener *listener)
CPU_FOREACH(cpu) { CPU_FOREACH(cpu) {
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
/* FIXME: Disentangle the cpu.h circular files deps so we can
directly get the right CPU from listener. */
if (cpu->tcg_as_listener != listener) {
continue;
}
tlb_flush(env, 1); tlb_flush(env, 1);
} }
} }
@@ -1813,10 +1851,6 @@ static MemoryListener core_memory_listener = {
.priority = 1, .priority = 1,
}; };
static MemoryListener tcg_memory_listener = {
.commit = tcg_commit,
};
void address_space_init_dispatch(AddressSpace *as) void address_space_init_dispatch(AddressSpace *as)
{ {
as->dispatch = NULL; as->dispatch = NULL;
@@ -1852,9 +1886,6 @@ static void memory_map_init(void)
address_space_init(&address_space_io, system_io, "I/O"); address_space_init(&address_space_io, system_io, "I/O");
memory_listener_register(&core_memory_listener, &address_space_memory); memory_listener_register(&core_memory_listener, &address_space_memory);
if (tcg_enabled()) {
memory_listener_register(&tcg_memory_listener, &address_space_memory);
}
} }
MemoryRegion *get_system_memory(void) MemoryRegion *get_system_memory(void)
@@ -1925,18 +1956,6 @@ static void invalidate_and_set_dirty(hwaddr addr,
xen_modified_memory(addr, length); xen_modified_memory(addr, length);
} }
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
if (memory_region_is_ram(mr)) {
return !(is_write && mr->readonly);
}
if (memory_region_is_romd(mr)) {
return !is_write;
}
return false;
}
static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
{ {
unsigned access_size_max = mr->ops->valid.max_access_size; unsigned access_size_max = mr->ops->valid.max_access_size;
@@ -2081,7 +2100,7 @@ enum write_rom_type {
FLUSH_CACHE, FLUSH_CACHE,
}; };
static inline void cpu_physical_memory_write_rom_internal( static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type) hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
{ {
hwaddr l; hwaddr l;
@@ -2091,8 +2110,7 @@ static inline void cpu_physical_memory_write_rom_internal(
while (len > 0) { while (len > 0) {
l = len; l = len;
mr = address_space_translate(&address_space_memory, mr = address_space_translate(as, addr, &addr1, &l, true);
addr, &addr1, &l, true);
if (!(memory_region_is_ram(mr) || if (!(memory_region_is_ram(mr) ||
memory_region_is_romd(mr))) { memory_region_is_romd(mr))) {
@@ -2118,10 +2136,10 @@ static inline void cpu_physical_memory_write_rom_internal(
} }
/* used for ROM loading : can write in RAM and ROM */ /* used for ROM loading : can write in RAM and ROM */
void cpu_physical_memory_write_rom(hwaddr addr, void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
const uint8_t *buf, int len) const uint8_t *buf, int len)
{ {
cpu_physical_memory_write_rom_internal(addr, buf, len, WRITE_DATA); cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA);
} }
void cpu_flush_icache_range(hwaddr start, int len) void cpu_flush_icache_range(hwaddr start, int len)
@@ -2136,7 +2154,8 @@ void cpu_flush_icache_range(hwaddr start, int len)
return; return;
} }
cpu_physical_memory_write_rom_internal(start, NULL, len, FLUSH_CACHE); cpu_physical_memory_write_rom_internal(&address_space_memory,
start, NULL, len, FLUSH_CACHE);
} }
typedef struct { typedef struct {
@@ -2327,7 +2346,7 @@ void cpu_physical_memory_unmap(void *buffer, hwaddr len,
} }
/* warning: addr must be aligned */ /* warning: addr must be aligned */
static inline uint32_t ldl_phys_internal(hwaddr addr, static inline uint32_t ldl_phys_internal(AddressSpace *as, hwaddr addr,
enum device_endian endian) enum device_endian endian)
{ {
uint8_t *ptr; uint8_t *ptr;
@@ -2336,8 +2355,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
hwaddr l = 4; hwaddr l = 4;
hwaddr addr1; hwaddr addr1;
mr = address_space_translate(&address_space_memory, addr, &addr1, &l, mr = address_space_translate(as, addr, &addr1, &l, false);
false);
if (l < 4 || !memory_access_is_direct(mr, false)) { if (l < 4 || !memory_access_is_direct(mr, false)) {
/* I/O case */ /* I/O case */
io_mem_read(mr, addr1, &val, 4); io_mem_read(mr, addr1, &val, 4);
@@ -2370,23 +2388,23 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
return val; return val;
} }
uint32_t ldl_phys(hwaddr addr) uint32_t ldl_phys(AddressSpace *as, hwaddr addr)
{ {
return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN); return ldl_phys_internal(as, addr, DEVICE_NATIVE_ENDIAN);
} }
uint32_t ldl_le_phys(hwaddr addr) uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr)
{ {
return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN); return ldl_phys_internal(as, addr, DEVICE_LITTLE_ENDIAN);
} }
uint32_t ldl_be_phys(hwaddr addr) uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr)
{ {
return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN); return ldl_phys_internal(as, addr, DEVICE_BIG_ENDIAN);
} }
/* warning: addr must be aligned */ /* warning: addr must be aligned */
static inline uint64_t ldq_phys_internal(hwaddr addr, static inline uint64_t ldq_phys_internal(AddressSpace *as, hwaddr addr,
enum device_endian endian) enum device_endian endian)
{ {
uint8_t *ptr; uint8_t *ptr;
@@ -2395,7 +2413,7 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
hwaddr l = 8; hwaddr l = 8;
hwaddr addr1; hwaddr addr1;
mr = address_space_translate(&address_space_memory, addr, &addr1, &l, mr = address_space_translate(as, addr, &addr1, &l,
false); false);
if (l < 8 || !memory_access_is_direct(mr, false)) { if (l < 8 || !memory_access_is_direct(mr, false)) {
/* I/O case */ /* I/O case */
@@ -2429,31 +2447,31 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
return val; return val;
} }
uint64_t ldq_phys(hwaddr addr) uint64_t ldq_phys(AddressSpace *as, hwaddr addr)
{ {
return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN); return ldq_phys_internal(as, addr, DEVICE_NATIVE_ENDIAN);
} }
uint64_t ldq_le_phys(hwaddr addr) uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr)
{ {
return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN); return ldq_phys_internal(as, addr, DEVICE_LITTLE_ENDIAN);
} }
uint64_t ldq_be_phys(hwaddr addr) uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr)
{ {
return ldq_phys_internal(addr, DEVICE_BIG_ENDIAN); return ldq_phys_internal(as, addr, DEVICE_BIG_ENDIAN);
} }
/* XXX: optimize */ /* XXX: optimize */
uint32_t ldub_phys(hwaddr addr) uint32_t ldub_phys(AddressSpace *as, hwaddr addr)
{ {
uint8_t val; uint8_t val;
cpu_physical_memory_read(addr, &val, 1); address_space_rw(as, addr, &val, 1, 0);
return val; return val;
} }
/* warning: addr must be aligned */ /* warning: addr must be aligned */
static inline uint32_t lduw_phys_internal(hwaddr addr, static inline uint32_t lduw_phys_internal(AddressSpace *as, hwaddr addr,
enum device_endian endian) enum device_endian endian)
{ {
uint8_t *ptr; uint8_t *ptr;
@@ -2462,7 +2480,7 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
hwaddr l = 2; hwaddr l = 2;
hwaddr addr1; hwaddr addr1;
mr = address_space_translate(&address_space_memory, addr, &addr1, &l, mr = address_space_translate(as, addr, &addr1, &l,
false); false);
if (l < 2 || !memory_access_is_direct(mr, false)) { if (l < 2 || !memory_access_is_direct(mr, false)) {
/* I/O case */ /* I/O case */
@@ -2496,32 +2514,32 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
return val; return val;
} }
uint32_t lduw_phys(hwaddr addr) uint32_t lduw_phys(AddressSpace *as, hwaddr addr)
{ {
return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN); return lduw_phys_internal(as, addr, DEVICE_NATIVE_ENDIAN);
} }
uint32_t lduw_le_phys(hwaddr addr) uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr)
{ {
return lduw_phys_internal(addr, DEVICE_LITTLE_ENDIAN); return lduw_phys_internal(as, addr, DEVICE_LITTLE_ENDIAN);
} }
uint32_t lduw_be_phys(hwaddr addr) uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr)
{ {
return lduw_phys_internal(addr, DEVICE_BIG_ENDIAN); return lduw_phys_internal(as, addr, DEVICE_BIG_ENDIAN);
} }
/* warning: addr must be aligned. The ram page is not masked as dirty /* warning: addr must be aligned. The ram page is not masked as dirty
and the code inside is not invalidated. It is useful if the dirty and the code inside is not invalidated. It is useful if the dirty
bits are used to track modified PTEs */ bits are used to track modified PTEs */
void stl_phys_notdirty(hwaddr addr, uint32_t val) void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
uint8_t *ptr; uint8_t *ptr;
MemoryRegion *mr; MemoryRegion *mr;
hwaddr l = 4; hwaddr l = 4;
hwaddr addr1; hwaddr addr1;
mr = address_space_translate(&address_space_memory, addr, &addr1, &l, mr = address_space_translate(as, addr, &addr1, &l,
true); true);
if (l < 4 || !memory_access_is_direct(mr, true)) { if (l < 4 || !memory_access_is_direct(mr, true)) {
io_mem_write(mr, addr1, val, 4); io_mem_write(mr, addr1, val, 4);
@@ -2544,7 +2562,8 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
} }
/* warning: addr must be aligned */ /* warning: addr must be aligned */
static inline void stl_phys_internal(hwaddr addr, uint32_t val, static inline void stl_phys_internal(AddressSpace *as,
hwaddr addr, uint32_t val,
enum device_endian endian) enum device_endian endian)
{ {
uint8_t *ptr; uint8_t *ptr;
@@ -2552,7 +2571,7 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val,
hwaddr l = 4; hwaddr l = 4;
hwaddr addr1; hwaddr addr1;
mr = address_space_translate(&address_space_memory, addr, &addr1, &l, mr = address_space_translate(as, addr, &addr1, &l,
true); true);
if (l < 4 || !memory_access_is_direct(mr, true)) { if (l < 4 || !memory_access_is_direct(mr, true)) {
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
@@ -2584,30 +2603,31 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val,
} }
} }
void stl_phys(hwaddr addr, uint32_t val) void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
stl_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN); stl_phys_internal(as, addr, val, DEVICE_NATIVE_ENDIAN);
} }
void stl_le_phys(hwaddr addr, uint32_t val) void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
stl_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN); stl_phys_internal(as, addr, val, DEVICE_LITTLE_ENDIAN);
} }
void stl_be_phys(hwaddr addr, uint32_t val) void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
stl_phys_internal(addr, val, DEVICE_BIG_ENDIAN); stl_phys_internal(as, addr, val, DEVICE_BIG_ENDIAN);
} }
/* XXX: optimize */ /* XXX: optimize */
void stb_phys(hwaddr addr, uint32_t val) void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
uint8_t v = val; uint8_t v = val;
cpu_physical_memory_write(addr, &v, 1); address_space_rw(as, addr, &v, 1, 1);
} }
/* warning: addr must be aligned */ /* warning: addr must be aligned */
static inline void stw_phys_internal(hwaddr addr, uint32_t val, static inline void stw_phys_internal(AddressSpace *as,
hwaddr addr, uint32_t val,
enum device_endian endian) enum device_endian endian)
{ {
uint8_t *ptr; uint8_t *ptr;
@@ -2615,8 +2635,7 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val,
hwaddr l = 2; hwaddr l = 2;
hwaddr addr1; hwaddr addr1;
mr = address_space_translate(&address_space_memory, addr, &addr1, &l, mr = address_space_translate(as, addr, &addr1, &l, true);
true);
if (l < 2 || !memory_access_is_direct(mr, true)) { if (l < 2 || !memory_access_is_direct(mr, true)) {
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) { if (endian == DEVICE_LITTLE_ENDIAN) {
@@ -2647,38 +2666,38 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val,
} }
} }
void stw_phys(hwaddr addr, uint32_t val) void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN); stw_phys_internal(as, addr, val, DEVICE_NATIVE_ENDIAN);
} }
void stw_le_phys(hwaddr addr, uint32_t val) void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN); stw_phys_internal(as, addr, val, DEVICE_LITTLE_ENDIAN);
} }
void stw_be_phys(hwaddr addr, uint32_t val) void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val)
{ {
stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN); stw_phys_internal(as, addr, val, DEVICE_BIG_ENDIAN);
} }
/* XXX: optimize */ /* XXX: optimize */
void stq_phys(hwaddr addr, uint64_t val) void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val)
{ {
val = tswap64(val); val = tswap64(val);
cpu_physical_memory_write(addr, &val, 8); address_space_rw(as, addr, (void *) &val, 8, 1);
} }
void stq_le_phys(hwaddr addr, uint64_t val) void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val)
{ {
val = cpu_to_le64(val); val = cpu_to_le64(val);
cpu_physical_memory_write(addr, &val, 8); address_space_rw(as, addr, (void *) &val, 8, 1);
} }
void stq_be_phys(hwaddr addr, uint64_t val) void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val)
{ {
val = cpu_to_be64(val); val = cpu_to_be64(val);
cpu_physical_memory_write(addr, &val, 8); address_space_rw(as, addr, (void *) &val, 8, 1);
} }
/* virtual memory access for debug (includes writing to ROM) */ /* virtual memory access for debug (includes writing to ROM) */
@@ -2699,10 +2718,11 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
if (l > len) if (l > len)
l = len; l = len;
phys_addr += (addr & ~TARGET_PAGE_MASK); phys_addr += (addr & ~TARGET_PAGE_MASK);
if (is_write) if (is_write) {
cpu_physical_memory_write_rom(phys_addr, buf, l); cpu_physical_memory_write_rom(cpu->as, phys_addr, buf, l);
else } else {
cpu_physical_memory_rw(phys_addr, buf, l, is_write); address_space_rw(cpu->as, phys_addr, buf, l, 0);
}
len -= l; len -= l;
buf += l; buf += l;
addr += l; addr += l;

View File

@@ -2372,6 +2372,17 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
} }
} }
/* Zero plus something non-zero : just return the something */ /* Zero plus something non-zero : just return the something */
if (flags & float_muladd_halve_result) {
if (cExp == 0) {
normalizeFloat32Subnormal(cSig, &cExp, &cSig);
}
/* Subtract one to halve, and one again because roundAndPackFloat32
* wants one less than the true exponent.
*/
cExp -= 2;
cSig = (cSig | 0x00800000) << 7;
return roundAndPackFloat32(cSign ^ signflip, cExp, cSig STATUS_VAR);
}
return packFloat32(cSign ^ signflip, cExp, cSig); return packFloat32(cSign ^ signflip, cExp, cSig);
} }
@@ -2408,6 +2419,9 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
/* Throw out the special case of c being an exact zero now */ /* Throw out the special case of c being an exact zero now */
shift64RightJamming(pSig64, 32, &pSig64); shift64RightJamming(pSig64, 32, &pSig64);
pSig = pSig64; pSig = pSig64;
if (flags & float_muladd_halve_result) {
pExp--;
}
return roundAndPackFloat32(zSign, pExp - 1, return roundAndPackFloat32(zSign, pExp - 1,
pSig STATUS_VAR); pSig STATUS_VAR);
} }
@@ -2472,6 +2486,10 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
zSig64 <<= shiftcount; zSig64 <<= shiftcount;
zExp -= shiftcount; zExp -= shiftcount;
} }
if (flags & float_muladd_halve_result) {
zExp--;
}
shift64RightJamming(zSig64, 32, &zSig64); shift64RightJamming(zSig64, 32, &zSig64);
return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR); return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR);
} }
@@ -4088,6 +4106,17 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
} }
} }
/* Zero plus something non-zero : just return the something */ /* Zero plus something non-zero : just return the something */
if (flags & float_muladd_halve_result) {
if (cExp == 0) {
normalizeFloat64Subnormal(cSig, &cExp, &cSig);
}
/* Subtract one to halve, and one again because roundAndPackFloat64
* wants one less than the true exponent.
*/
cExp -= 2;
cSig = (cSig | 0x0010000000000000ULL) << 10;
return roundAndPackFloat64(cSign ^ signflip, cExp, cSig STATUS_VAR);
}
return packFloat64(cSign ^ signflip, cExp, cSig); return packFloat64(cSign ^ signflip, cExp, cSig);
} }
@@ -4123,6 +4152,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
if (!cSig) { if (!cSig) {
/* Throw out the special case of c being an exact zero now */ /* Throw out the special case of c being an exact zero now */
shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1); shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1);
if (flags & float_muladd_halve_result) {
pExp--;
}
return roundAndPackFloat64(zSign, pExp - 1, return roundAndPackFloat64(zSign, pExp - 1,
pSig1 STATUS_VAR); pSig1 STATUS_VAR);
} }
@@ -4159,6 +4191,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
zExp--; zExp--;
} }
shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1); shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1);
if (flags & float_muladd_halve_result) {
zExp--;
}
return roundAndPackFloat64(zSign, zExp, zSig1 STATUS_VAR); return roundAndPackFloat64(zSign, zExp, zSig1 STATUS_VAR);
} else { } else {
/* Subtraction */ /* Subtraction */
@@ -4209,6 +4244,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
zExp -= (shiftcount + 64); zExp -= (shiftcount + 64);
} }
} }
if (flags & float_muladd_halve_result) {
zExp--;
}
return roundAndPackFloat64(zSign, zExp, zSig0 STATUS_VAR); return roundAndPackFloat64(zSign, zExp, zSig0 STATUS_VAR);
} }
} }

16
hmp.c
View File

@@ -881,7 +881,7 @@ void hmp_balloon(Monitor *mon, const QDict *qdict)
Error *errp = NULL; Error *errp = NULL;
qmp_balloon(value, &errp); qmp_balloon(value, &errp);
if (error_is_set(&errp)) { if (errp) {
monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp)); monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp));
error_free(errp); error_free(errp);
} }
@@ -1118,7 +1118,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
} }
qmp_change(device, target, !!arg, arg, &err); qmp_change(device, target, !!arg, arg, &err);
if (error_is_set(&err) && if (err &&
error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) { error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
error_free(err); error_free(err);
monitor_read_block_device_key(mon, device, NULL, NULL); monitor_read_block_device_key(mon, device, NULL, NULL);
@@ -1234,7 +1234,8 @@ static void hmp_migrate_status_cb(void *opaque)
MigrationInfo *info; MigrationInfo *info;
info = qmp_query_migrate(NULL); info = qmp_query_migrate(NULL);
if (!info->has_status || strcmp(info->status, "active") == 0) { if (!info->has_status || strcmp(info->status, "active") == 0 ||
strcmp(info->status, "setup") == 0) {
if (info->has_disk) { if (info->has_disk) {
int progress; int progress;
@@ -1310,8 +1311,11 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
const char *file = qdict_get_str(qdict, "filename"); const char *file = qdict_get_str(qdict, "filename");
bool has_begin = qdict_haskey(qdict, "begin"); bool has_begin = qdict_haskey(qdict, "begin");
bool has_length = qdict_haskey(qdict, "length"); bool has_length = qdict_haskey(qdict, "length");
/* kdump-compressed format is not supported for HMP */
bool has_format = false;
int64_t begin = 0; int64_t begin = 0;
int64_t length = 0; int64_t length = 0;
enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
char *prot; char *prot;
if (has_begin) { if (has_begin) {
@@ -1324,7 +1328,7 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
prot = g_strconcat("file:", file, NULL); prot = g_strconcat("file:", file, NULL);
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length, qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
&errp); has_format, dump_format, &errp);
hmp_handle_error(mon, &errp); hmp_handle_error(mon, &errp);
g_free(prot); g_free(prot);
} }
@@ -1335,12 +1339,12 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
QemuOpts *opts; QemuOpts *opts;
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err); opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
if (error_is_set(&err)) { if (err) {
goto out; goto out;
} }
netdev_add(opts, &err); netdev_add(opts, &err);
if (error_is_set(&err)) { if (err) {
qemu_opts_del(opts); qemu_opts_del(opts);
} }

View File

@@ -38,10 +38,6 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
}); });
v9fs_path_unlock(s); v9fs_path_unlock(s);
} }
/* The ioctl may not be supported depending on the path */
if (err == -ENOTTY) {
err = 0;
}
return err; return err;
} }

View File

@@ -582,6 +582,7 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir,
static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
mode_t st_mode, uint64_t *st_gen) mode_t st_mode, uint64_t *st_gen)
{ {
#ifdef FS_IOC_GETVERSION
int err; int err;
V9fsFidOpenState fid_open; V9fsFidOpenState fid_open;
@@ -590,7 +591,8 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
* We can get fd for regular files and directories only * We can get fd for regular files and directories only
*/ */
if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
return 0; errno = ENOTTY;
return -1;
} }
err = handle_open(ctx, path, O_RDONLY, &fid_open); err = handle_open(ctx, path, O_RDONLY, &fid_open);
if (err < 0) { if (err < 0) {
@@ -599,6 +601,10 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
handle_close(ctx, &fid_open); handle_close(ctx, &fid_open);
return err; return err;
#else
errno = ENOTTY;
return -1;
#endif
} }
static int handle_init(FsContext *ctx) static int handle_init(FsContext *ctx)

View File

@@ -1068,8 +1068,8 @@ err_out:
static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
mode_t st_mode, uint64_t *st_gen) mode_t st_mode, uint64_t *st_gen)
{ {
int err;
#ifdef FS_IOC_GETVERSION #ifdef FS_IOC_GETVERSION
int err;
V9fsFidOpenState fid_open; V9fsFidOpenState fid_open;
/* /*
@@ -1077,7 +1077,8 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
* We can get fd for regular files and directories only * We can get fd for regular files and directories only
*/ */
if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
return 0; errno = ENOTTY;
return -1;
} }
err = local_open(ctx, path, O_RDONLY, &fid_open); err = local_open(ctx, path, O_RDONLY, &fid_open);
if (err < 0) { if (err < 0) {
@@ -1085,10 +1086,11 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
} }
err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
local_close(ctx, &fid_open); local_close(ctx, &fid_open);
#else
err = -ENOTTY;
#endif
return err; return err;
#else
errno = ENOTTY;
return -1;
#endif
} }
static int local_init(FsContext *ctx) static int local_init(FsContext *ctx)

View File

@@ -1086,7 +1086,8 @@ static int proxy_ioc_getversion(FsContext *fs_ctx, V9fsPath *path,
* we can get fd for regular files and directories only * we can get fd for regular files and directories only
*/ */
if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
return 0; errno = ENOTTY;
return -1;
} }
err = v9fs_request(fs_ctx->private, T_GETVERSION, st_gen, "s", path); err = v9fs_request(fs_ctx->private, T_GETVERSION, st_gen, "s", path);
if (err < 0) { if (err < 0) {

View File

@@ -1080,10 +1080,18 @@ static void v9fs_getattr(void *opaque)
/* fill st_gen if requested and supported by underlying fs */ /* fill st_gen if requested and supported by underlying fs */
if (request_mask & P9_STATS_GEN) { if (request_mask & P9_STATS_GEN) {
retval = v9fs_co_st_gen(pdu, &fidp->path, stbuf.st_mode, &v9stat_dotl); retval = v9fs_co_st_gen(pdu, &fidp->path, stbuf.st_mode, &v9stat_dotl);
if (retval < 0) { switch (retval) {
case 0:
/* we have valid st_gen: update result mask */
v9stat_dotl.st_result_mask |= P9_STATS_GEN;
break;
case -EINTR:
/* request cancelled, e.g. by Tflush */
goto out; goto out;
default:
/* failed to get st_gen: not fatal, ignore */
break;
} }
v9stat_dotl.st_result_mask |= P9_STATS_GEN;
} }
retval = pdu_marshal(pdu, offset, "A", &v9stat_dotl); retval = pdu_marshal(pdu, offset, "A", &v9stat_dotl);
if (retval < 0) { if (retval < 0) {

View File

@@ -12,6 +12,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += i2c/
devices-dirs-$(CONFIG_SOFTMMU) += ide/ devices-dirs-$(CONFIG_SOFTMMU) += ide/
devices-dirs-$(CONFIG_SOFTMMU) += input/ devices-dirs-$(CONFIG_SOFTMMU) += input/
devices-dirs-$(CONFIG_SOFTMMU) += intc/ devices-dirs-$(CONFIG_SOFTMMU) += intc/
devices-dirs-$(CONFIG_IPACK) += ipack/
devices-dirs-$(CONFIG_SOFTMMU) += isa/ devices-dirs-$(CONFIG_SOFTMMU) += isa/
devices-dirs-$(CONFIG_SOFTMMU) += misc/ devices-dirs-$(CONFIG_SOFTMMU) += misc/
devices-dirs-$(CONFIG_SOFTMMU) += net/ devices-dirs-$(CONFIG_SOFTMMU) += net/

View File

@@ -46,13 +46,15 @@
# define ACPI_PCIHP_DPRINTF(format, ...) do { } while (0) # define ACPI_PCIHP_DPRINTF(format, ...) do { } while (0)
#endif #endif
#define PCI_HOTPLUG_ADDR 0xae00 #define ACPI_PCI_HOTPLUG_STATUS 2
#define PCI_HOTPLUG_SIZE 0x0014 #define ACPI_PCIHP_ADDR 0xae00
#define PCI_UP_BASE 0xae00 #define ACPI_PCIHP_SIZE 0x0014
#define PCI_DOWN_BASE 0xae04 #define ACPI_PCIHP_LEGACY_SIZE 0x000f
#define PCI_EJ_BASE 0xae08 #define PCI_UP_BASE 0x0000
#define PCI_RMV_BASE 0xae0c #define PCI_DOWN_BASE 0x0004
#define PCI_SEL_BASE 0xae10 #define PCI_EJ_BASE 0x0008
#define PCI_RMV_BASE 0x000c
#define PCI_SEL_BASE 0x0010
typedef struct AcpiPciHpFind { typedef struct AcpiPciHpFind {
int bsel; int bsel;
@@ -104,19 +106,19 @@ static PCIBus *acpi_pcihp_find_hotplug_bus(AcpiPciHpState *s, int bsel)
static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev) static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
{ {
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
DeviceClass *dc = DEVICE_GET_CLASS(dev);
/* /*
* ACPI doesn't allow hotplug of bridge devices. Don't allow * ACPI doesn't allow hotplug of bridge devices. Don't allow
* hot-unplug of bridge devices unless they were added by hotplug * hot-unplug of bridge devices unless they were added by hotplug
* (and so, not described by acpi). * (and so, not described by acpi).
*/ */
return (pc->is_bridge && !dev->qdev.hotplugged) || pc->no_hotplug; return (pc->is_bridge && !dev->qdev.hotplugged) || !dc->hotpluggable;
} }
static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots) static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
{ {
BusChild *kid, *next; BusChild *kid, *next;
int slot = ffs(slots) - 1; int slot = ffs(slots) - 1;
bool slot_free = true;
PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel); PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
if (!bus) { if (!bus) {
@@ -125,21 +127,17 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo
/* Mark request as complete */ /* Mark request as complete */
s->acpi_pcihp_pci_status[bsel].down &= ~(1U << slot); s->acpi_pcihp_pci_status[bsel].down &= ~(1U << slot);
s->acpi_pcihp_pci_status[bsel].up &= ~(1U << slot);
QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) { QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
DeviceState *qdev = kid->child; DeviceState *qdev = kid->child;
PCIDevice *dev = PCI_DEVICE(qdev); PCIDevice *dev = PCI_DEVICE(qdev);
if (PCI_SLOT(dev->devfn) == slot) { if (PCI_SLOT(dev->devfn) == slot) {
if (acpi_pcihp_pc_no_hotplug(s, dev)) { if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
slot_free = false;
} else {
object_unparent(OBJECT(qdev)); object_unparent(OBJECT(qdev));
} }
} }
} }
if (slot_free) {
s->acpi_pcihp_pci_status[bsel].device_present &= ~(1U << slot);
}
} }
static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel) static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
@@ -153,7 +151,6 @@ static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
} }
s->acpi_pcihp_pci_status[bsel].hotplug_enable = ~0; s->acpi_pcihp_pci_status[bsel].hotplug_enable = ~0;
s->acpi_pcihp_pci_status[bsel].device_present = 0;
if (!bus) { if (!bus) {
return; return;
@@ -166,8 +163,6 @@ static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
if (acpi_pcihp_pc_no_hotplug(s, pdev)) { if (acpi_pcihp_pc_no_hotplug(s, pdev)) {
s->acpi_pcihp_pci_status[bsel].hotplug_enable &= ~(1U << slot); s->acpi_pcihp_pci_status[bsel].hotplug_enable &= ~(1U << slot);
} }
s->acpi_pcihp_pci_status[bsel].device_present |= (1U << slot);
} }
} }
@@ -185,40 +180,47 @@ void acpi_pcihp_reset(AcpiPciHpState *s)
acpi_pcihp_update(s); acpi_pcihp_update(s);
} }
static void enable_device(AcpiPciHpState *s, unsigned bsel, int slot) void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
DeviceState *dev, Error **errp)
{ {
s->acpi_pcihp_pci_status[bsel].device_present |= (1U << slot); PCIDevice *pdev = PCI_DEVICE(dev);
} int slot = PCI_SLOT(pdev->devfn);
int bsel = acpi_pcihp_get_bsel(pdev->bus);
static void disable_device(AcpiPciHpState *s, unsigned bsel, int slot)
{
s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
}
int acpi_pcihp_device_hotplug(AcpiPciHpState *s, PCIDevice *dev,
PCIHotplugState state)
{
int slot = PCI_SLOT(dev->devfn);
int bsel = acpi_pcihp_get_bsel(dev->bus);
if (bsel < 0) { if (bsel < 0) {
return -1; error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
return;
} }
/* Don't send event when device is enabled during qemu machine creation: /* Don't send event when device is enabled during qemu machine creation:
* it is present on boot, no hotplug event is necessary. We do send an * it is present on boot, no hotplug event is necessary. We do send an
* event when the device is disabled later. */ * event when the device is disabled later. */
if (state == PCI_COLDPLUG_ENABLED) { if (!dev->hotplugged) {
s->acpi_pcihp_pci_status[bsel].device_present |= (1U << slot); return;
return 0;
} }
if (state == PCI_HOTPLUG_ENABLED) { s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
enable_device(s, bsel, slot);
} else { ar->gpe.sts[0] |= ACPI_PCI_HOTPLUG_STATUS;
disable_device(s, bsel, slot); acpi_update_sci(ar, irq);
}
void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
DeviceState *dev, Error **errp)
{
PCIDevice *pdev = PCI_DEVICE(dev);
int slot = PCI_SLOT(pdev->devfn);
int bsel = acpi_pcihp_get_bsel(pdev->bus);
if (bsel < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
return;
} }
return 0; s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
ar->gpe.sts[0] |= ACPI_PCI_HOTPLUG_STATUS;
acpi_update_sci(ar, irq);
} }
static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size) static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
@@ -232,26 +234,26 @@ static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
} }
switch (addr) { switch (addr) {
case PCI_UP_BASE - PCI_HOTPLUG_ADDR: case PCI_UP_BASE:
/* Manufacture an "up" value to cause a device check on any hotplug val = s->acpi_pcihp_pci_status[bsel].up;
* slot with a device. Extra device checks are harmless. */ if (!s->legacy_piix) {
val = s->acpi_pcihp_pci_status[bsel].device_present & s->acpi_pcihp_pci_status[bsel].up = 0;
s->acpi_pcihp_pci_status[bsel].hotplug_enable; }
ACPI_PCIHP_DPRINTF("pci_up_read %" PRIu32 "\n", val); ACPI_PCIHP_DPRINTF("pci_up_read %" PRIu32 "\n", val);
break; break;
case PCI_DOWN_BASE - PCI_HOTPLUG_ADDR: case PCI_DOWN_BASE:
val = s->acpi_pcihp_pci_status[bsel].down; val = s->acpi_pcihp_pci_status[bsel].down;
ACPI_PCIHP_DPRINTF("pci_down_read %" PRIu32 "\n", val); ACPI_PCIHP_DPRINTF("pci_down_read %" PRIu32 "\n", val);
break; break;
case PCI_EJ_BASE - PCI_HOTPLUG_ADDR: case PCI_EJ_BASE:
/* No feature defined yet */ /* No feature defined yet */
ACPI_PCIHP_DPRINTF("pci_features_read %" PRIu32 "\n", val); ACPI_PCIHP_DPRINTF("pci_features_read %" PRIu32 "\n", val);
break; break;
case PCI_RMV_BASE - PCI_HOTPLUG_ADDR: case PCI_RMV_BASE:
val = s->acpi_pcihp_pci_status[bsel].hotplug_enable; val = s->acpi_pcihp_pci_status[bsel].hotplug_enable;
ACPI_PCIHP_DPRINTF("pci_rmv_read %" PRIu32 "\n", val); ACPI_PCIHP_DPRINTF("pci_rmv_read %" PRIu32 "\n", val);
break; break;
case PCI_SEL_BASE - PCI_HOTPLUG_ADDR: case PCI_SEL_BASE:
val = s->hotplug_select; val = s->hotplug_select;
ACPI_PCIHP_DPRINTF("pci_sel_read %" PRIu32 "\n", val); ACPI_PCIHP_DPRINTF("pci_sel_read %" PRIu32 "\n", val);
default: default:
@@ -266,7 +268,7 @@ static void pci_write(void *opaque, hwaddr addr, uint64_t data,
{ {
AcpiPciHpState *s = opaque; AcpiPciHpState *s = opaque;
switch (addr) { switch (addr) {
case PCI_EJ_BASE - PCI_HOTPLUG_ADDR: case PCI_EJ_BASE:
if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) { if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
break; break;
} }
@@ -274,7 +276,7 @@ static void pci_write(void *opaque, hwaddr addr, uint64_t data,
ACPI_PCIHP_DPRINTF("pciej write %" HWADDR_PRIx " <== %" PRIu64 "\n", ACPI_PCIHP_DPRINTF("pciej write %" HWADDR_PRIx " <== %" PRIu64 "\n",
addr, data); addr, data);
break; break;
case PCI_SEL_BASE - PCI_HOTPLUG_ADDR: case PCI_SEL_BASE:
s->hotplug_select = data; s->hotplug_select = data;
ACPI_PCIHP_DPRINTF("pcisel write %" HWADDR_PRIx " <== %" PRIu64 "\n", ACPI_PCIHP_DPRINTF("pcisel write %" HWADDR_PRIx " <== %" PRIu64 "\n",
addr, data); addr, data);
@@ -294,13 +296,26 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
}; };
void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus, void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus,
MemoryRegion *address_space_io) MemoryRegion *address_space_io, bool bridges_enabled)
{ {
uint16_t io_size = ACPI_PCIHP_SIZE;
s->root= root_bus; s->root= root_bus;
s->legacy_piix = !bridges_enabled;
if (s->legacy_piix) {
unsigned *bus_bsel = g_malloc(sizeof *bus_bsel);
io_size = ACPI_PCIHP_LEGACY_SIZE;
*bus_bsel = ACPI_PCIHP_BSEL_DEFAULT;
object_property_add_uint32_ptr(OBJECT(root_bus), ACPI_PCIHP_PROP_BSEL,
bus_bsel, NULL);
}
memory_region_init_io(&s->io, NULL, &acpi_pcihp_io_ops, s, memory_region_init_io(&s->io, NULL, &acpi_pcihp_io_ops, s,
"acpi-pci-hotplug", "acpi-pci-hotplug", io_size);
PCI_HOTPLUG_SIZE); memory_region_add_subregion(address_space_io, ACPI_PCIHP_ADDR, &s->io);
memory_region_add_subregion(address_space_io, PCI_HOTPLUG_ADDR, &s->io);
} }
const VMStateDescription vmstate_acpi_pcihp_pci_status = { const VMStateDescription vmstate_acpi_pcihp_pci_status = {

View File

@@ -32,6 +32,7 @@
#include "hw/acpi/piix4.h" #include "hw/acpi/piix4.h"
#include "hw/acpi/pcihp.h" #include "hw/acpi/pcihp.h"
#include "hw/acpi/cpu_hotplug.h" #include "hw/acpi/cpu_hotplug.h"
#include "hw/hotplug.h"
//#define DEBUG //#define DEBUG
@@ -44,15 +45,6 @@
#define GPE_BASE 0xafe0 #define GPE_BASE 0xafe0
#define GPE_LEN 4 #define GPE_LEN 4
#define PCI_HOTPLUG_ADDR 0xae00
#define PCI_HOTPLUG_SIZE 0x000f
#define PCI_UP_BASE 0xae00
#define PCI_DOWN_BASE 0xae04
#define PCI_EJ_BASE 0xae08
#define PCI_RMV_BASE 0xae0c
#define PIIX4_PCI_HOTPLUG_STATUS 2
struct pci_status { struct pci_status {
uint32_t up; /* deprecated, maintained for migration compatibility */ uint32_t up; /* deprecated, maintained for migration compatibility */
uint32_t down; uint32_t down;
@@ -80,13 +72,6 @@ typedef struct PIIX4PMState {
Notifier machine_ready; Notifier machine_ready;
Notifier powerdown_notifier; Notifier powerdown_notifier;
/* for legacy pci hotplug (compatible with qemu 1.6 and older) */
MemoryRegion io_pci;
struct pci_status pci0_status;
uint32_t pci0_hotplug_enable;
uint32_t pci0_slot_device_present;
/* for new pci hotplug (with PCI2PCI bridge support) */
AcpiPciHpState acpi_pci_hotplug; AcpiPciHpState acpi_pci_hotplug;
bool use_acpi_pci_hotplug; bool use_acpi_pci_hotplug;
@@ -170,17 +155,6 @@ static void pm_write_config(PCIDevice *d,
} }
} }
static void vmstate_pci_status_pre_save(void *opaque)
{
struct pci_status *pci0_status = opaque;
PIIX4PMState *s = container_of(pci0_status, PIIX4PMState, pci0_status);
/* We no longer track up, so build a safe value for migrating
* to a version that still does... of course these might get lost
* by an old buggy implementation, but we try. */
pci0_status->up = s->pci0_slot_device_present & s->pci0_hotplug_enable;
}
static int vmstate_acpi_post_load(void *opaque, int version_id) static int vmstate_acpi_post_load(void *opaque, int version_id)
{ {
PIIX4PMState *s = opaque; PIIX4PMState *s = opaque;
@@ -216,10 +190,9 @@ static const VMStateDescription vmstate_pci_status = {
.version_id = 1, .version_id = 1,
.minimum_version_id = 1, .minimum_version_id = 1,
.minimum_version_id_old = 1, .minimum_version_id_old = 1,
.pre_save = vmstate_pci_status_pre_save,
.fields = (VMStateField []) { .fields = (VMStateField []) {
VMSTATE_UINT32(up, struct pci_status), VMSTATE_UINT32(up, struct AcpiPciHpPciStatus),
VMSTATE_UINT32(down, struct pci_status), VMSTATE_UINT32(down, struct AcpiPciHpPciStatus),
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
} }
}; };
@@ -256,7 +229,8 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
qemu_get_be16s(f, &temp); qemu_get_be16s(f, &temp);
} }
ret = vmstate_load_state(f, &vmstate_pci_status, &s->pci0_status, 1); ret = vmstate_load_state(f, &vmstate_pci_status,
&s->acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT], 1);
return ret; return ret;
} }
@@ -294,70 +268,18 @@ static const VMStateDescription vmstate_acpi = {
VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState),
VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
VMSTATE_STRUCT_TEST(pci0_status, PIIX4PMState, VMSTATE_STRUCT_TEST(
vmstate_test_no_use_acpi_pci_hotplug, acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT],
2, vmstate_pci_status, PIIX4PMState,
struct pci_status), vmstate_test_no_use_acpi_pci_hotplug,
2, vmstate_pci_status,
struct AcpiPciHpPciStatus),
VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
vmstate_test_use_acpi_pci_hotplug), vmstate_test_use_acpi_pci_hotplug),
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
} }
}; };
static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
{
BusChild *kid, *next;
BusState *bus = qdev_get_parent_bus(DEVICE(s));
int slot = ffs(slots) - 1;
bool slot_free = true;
/* Mark request as complete */
s->pci0_status.down &= ~(1U << slot);
QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
DeviceState *qdev = kid->child;
PCIDevice *dev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
if (PCI_SLOT(dev->devfn) == slot) {
if (pc->no_hotplug) {
slot_free = false;
} else {
object_unparent(OBJECT(qdev));
}
}
}
if (slot_free) {
s->pci0_slot_device_present &= ~(1U << slot);
}
}
static void piix4_update_hotplug(PIIX4PMState *s)
{
BusState *bus = qdev_get_parent_bus(DEVICE(s));
BusChild *kid, *next;
/* Execute any pending removes during reset */
while (s->pci0_status.down) {
acpi_piix_eject_slot(s, s->pci0_status.down);
}
s->pci0_hotplug_enable = ~0;
s->pci0_slot_device_present = 0;
QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
DeviceState *qdev = kid->child;
PCIDevice *pdev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
int slot = PCI_SLOT(pdev->devfn);
if (pc->no_hotplug) {
s->pci0_hotplug_enable &= ~(1U << slot);
}
s->pci0_slot_device_present |= (1U << slot);
}
}
static void piix4_reset(void *opaque) static void piix4_reset(void *opaque)
{ {
PIIX4PMState *s = opaque; PIIX4PMState *s = opaque;
@@ -377,11 +299,7 @@ static void piix4_reset(void *opaque)
pci_conf[0x5B] = 0x02; pci_conf[0x5B] = 0x02;
} }
pm_io_space_update(s); pm_io_space_update(s);
if (s->use_acpi_pci_hotplug) { acpi_pcihp_reset(&s->acpi_pci_hotplug);
acpi_pcihp_reset(&s->acpi_pci_hotplug);
} else {
piix4_update_hotplug(s);
}
} }
static void piix4_pm_powerdown_req(Notifier *n, void *opaque) static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
@@ -392,24 +310,26 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
acpi_pm1_evt_power_down(&s->ar); acpi_pm1_evt_power_down(&s->ar);
} }
static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev, static void piix4_pci_device_plug_cb(HotplugHandler *hotplug_dev,
PCIHotplugState state) DeviceState *dev, Error **errp)
{ {
PIIX4PMState *s = PIIX4_PM(qdev); PIIX4PMState *s = PIIX4_PM(hotplug_dev);
int ret = acpi_pcihp_device_hotplug(&s->acpi_pci_hotplug, dev, state); acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, errp);
if (ret < 0) {
return ret;
}
s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
acpi_update_sci(&s->ar, s->irq);
return 0;
} }
static void piix4_update_bus_hotplug(PCIBus *bus, void *opaque) static void piix4_pci_device_unplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
PIIX4PMState *s = PIIX4_PM(hotplug_dev);
acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
errp);
}
static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque)
{ {
PIIX4PMState *s = opaque; PIIX4PMState *s = opaque;
pci_bus_hotplug(bus, piix4_acpi_pci_hotplug, DEVICE(s));
qbus_set_hotplug_handler(BUS(pci_bus), DEVICE(s), &error_abort);
} }
static void piix4_pm_machine_ready(Notifier *n, void *opaque) static void piix4_pm_machine_ready(Notifier *n, void *opaque)
@@ -428,6 +348,8 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque)
if (s->use_acpi_pci_hotplug) { if (s->use_acpi_pci_hotplug) {
pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s); pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s);
} else {
piix4_update_bus_hotplug(d->bus, s);
} }
} }
@@ -517,9 +439,9 @@ Object *piix4_pm_find(void)
return o; return o;
} }
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq smi_irq, qemu_irq sci_irq, qemu_irq smi_irq,
int kvm_enabled, FWCfgState *fw_cfg) int kvm_enabled, FWCfgState *fw_cfg)
{ {
DeviceState *dev; DeviceState *dev;
PIIX4PMState *s; PIIX4PMState *s;
@@ -545,52 +467,6 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
return s->smb.smbus; return s->smb.smbus;
} }
static Property piix4_pm_properties[] = {
DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
use_acpi_pci_hotplug, true),
DEFINE_PROP_END_OF_LIST(),
};
static void piix4_pm_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->no_hotplug = 1;
k->init = piix4_pm_initfn;
k->config_write = pm_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
k->revision = 0x03;
k->class_id = PCI_CLASS_BRIDGE_OTHER;
dc->desc = "PM";
dc->vmsd = &vmstate_acpi;
dc->props = piix4_pm_properties;
/*
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
}
static const TypeInfo piix4_pm_info = {
.name = TYPE_PIIX4_PM,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PIIX4PMState),
.class_init = piix4_pm_class_init,
};
static void piix4_pm_register_types(void)
{
type_register_static(&piix4_pm_info);
}
type_init(piix4_pm_register_types)
static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width) static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width)
{ {
PIIX4PMState *s = opaque; PIIX4PMState *s = opaque;
@@ -621,60 +497,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
.endianness = DEVICE_LITTLE_ENDIAN, .endianness = DEVICE_LITTLE_ENDIAN,
}; };
static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
{
PIIX4PMState *s = opaque;
uint32_t val = 0;
switch (addr) {
case PCI_UP_BASE - PCI_HOTPLUG_ADDR:
/* Manufacture an "up" value to cause a device check on any hotplug
* slot with a device. Extra device checks are harmless. */
val = s->pci0_slot_device_present & s->pci0_hotplug_enable;
PIIX4_DPRINTF("pci_up_read %" PRIu32 "\n", val);
break;
case PCI_DOWN_BASE - PCI_HOTPLUG_ADDR:
val = s->pci0_status.down;
PIIX4_DPRINTF("pci_down_read %" PRIu32 "\n", val);
break;
case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
/* No feature defined yet */
PIIX4_DPRINTF("pci_features_read %" PRIu32 "\n", val);
break;
case PCI_RMV_BASE - PCI_HOTPLUG_ADDR:
val = s->pci0_hotplug_enable;
break;
default:
break;
}
return val;
}
static void pci_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
switch (addr) {
case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
acpi_piix_eject_slot(opaque, (uint32_t)data);
PIIX4_DPRINTF("pciej write %" HWADDR_PRIx " <== %" PRIu64 "\n",
addr, data);
break;
default:
break;
}
}
static const MemoryRegionOps piix4_pci_ops = {
.read = pci_read,
.write = pci_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4,
},
};
static void piix4_cpu_added_req(Notifier *n, void *opaque) static void piix4_cpu_added_req(Notifier *n, void *opaque)
{ {
PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier); PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
@@ -684,9 +506,6 @@ static void piix4_cpu_added_req(Notifier *n, void *opaque)
acpi_update_sci(&s->ar, s->irq); acpi_update_sci(&s->ar, s->irq);
} }
static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
PCIHotplugState state);
static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s) PCIBus *bus, PIIX4PMState *s)
{ {
@@ -694,15 +513,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
"acpi-gpe0", GPE_LEN); "acpi-gpe0", GPE_LEN);
memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe); memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
if (s->use_acpi_pci_hotplug) { acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent); s->use_acpi_pci_hotplug);
} else {
memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s,
"acpi-pci-hotplug", PCI_HOTPLUG_SIZE);
memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR,
&s->io_pci);
pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s));
}
AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu, AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
PIIX4_CPU_HOTPLUG_IO_BASE); PIIX4_CPU_HOTPLUG_IO_BASE);
@@ -710,39 +522,55 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
qemu_register_cpu_added_notifier(&s->cpu_added_notifier); qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
} }
static void enable_device(PIIX4PMState *s, int slot) static Property piix4_pm_properties[] = {
DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
use_acpi_pci_hotplug, true),
DEFINE_PROP_END_OF_LIST(),
};
static void piix4_pm_class_init(ObjectClass *klass, void *data)
{ {
s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; DeviceClass *dc = DEVICE_CLASS(klass);
s->pci0_slot_device_present |= (1U << slot); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
k->init = piix4_pm_initfn;
k->config_write = pm_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
k->revision = 0x03;
k->class_id = PCI_CLASS_BRIDGE_OTHER;
dc->desc = "PM";
dc->vmsd = &vmstate_acpi;
dc->props = piix4_pm_properties;
/*
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->hotpluggable = false;
hc->plug = piix4_pci_device_plug_cb;
hc->unplug = piix4_pci_device_unplug_cb;
} }
static void disable_device(PIIX4PMState *s, int slot) static const TypeInfo piix4_pm_info = {
{ .name = TYPE_PIIX4_PM,
s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; .parent = TYPE_PCI_DEVICE,
s->pci0_status.down |= (1U << slot); .instance_size = sizeof(PIIX4PMState),
} .class_init = piix4_pm_class_init,
.interfaces = (InterfaceInfo[]) {
static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, { TYPE_HOTPLUG_HANDLER },
PCIHotplugState state) { }
{
int slot = PCI_SLOT(dev->devfn);
PIIX4PMState *s = PIIX4_PM(qdev);
/* Don't send event when device is enabled during qemu machine creation:
* it is present on boot, no hotplug event is necessary. We do send an
* event when the device is disabled later. */
if (state == PCI_COLDPLUG_ENABLED) {
s->pci0_slot_device_present |= (1U << slot);
return 0;
} }
};
if (state == PCI_HOTPLUG_ENABLED) { static void piix4_pm_register_types(void)
enable_device(s, slot); {
} else { type_register_static(&piix4_pm_info);
disable_device(s, slot);
}
acpi_update_sci(&s->ar, s->irq);
return 0;
} }
type_init(piix4_pm_register_types)

View File

@@ -161,8 +161,9 @@ static void clipper_init(QEMUMachineInitArgs *args)
load_image_targphys(initrd_filename, initrd_base, load_image_targphys(initrd_filename, initrd_base,
ram_size - initrd_base); ram_size - initrd_base);
stq_phys(param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL); stq_phys(&address_space_memory,
stq_phys(param_offset + 0x108, initrd_size); param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL);
stq_phys(&address_space_memory, param_offset + 0x108, initrd_size);
} }
} }
} }

View File

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

View File

@@ -31,6 +31,13 @@ static void aw_a10_init(Object *obj)
object_initialize(&s->timer, sizeof(s->timer), TYPE_AW_A10_PIT); object_initialize(&s->timer, sizeof(s->timer), TYPE_AW_A10_PIT);
qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default()); qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
object_initialize(&s->emac, sizeof(s->emac), TYPE_AW_EMAC);
qdev_set_parent_bus(DEVICE(&s->emac), sysbus_get_default());
if (nd_table[0].used) {
qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
}
} }
static void aw_a10_realize(DeviceState *dev, Error **errp) static void aw_a10_realize(DeviceState *dev, Error **errp)
@@ -76,6 +83,15 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(sysbusdev, 4, s->irq[67]); sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
sysbus_connect_irq(sysbusdev, 5, s->irq[68]); sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
return;
}
sysbusdev = SYS_BUS_DEVICE(&s->emac);
sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE);
sysbus_connect_irq(sysbusdev, 0, s->irq[55]);
serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s->irq[1], serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s->irq[1],
115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
} }

View File

@@ -16,6 +16,7 @@
#include "elf.h" #include "elf.h"
#include "sysemu/device_tree.h" #include "sysemu/device_tree.h"
#include "qemu/config-file.h" #include "qemu/config-file.h"
#include "exec/address-spaces.h"
/* Kernel boot protocol is specified in the kernel docs /* Kernel boot protocol is specified in the kernel docs
* Documentation/arm/Booting and Documentation/arm64/booting.txt * Documentation/arm/Booting and Documentation/arm64/booting.txt
@@ -169,7 +170,7 @@ static void default_reset_secondary(ARMCPU *cpu,
{ {
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
stl_phys_notdirty(info->smp_bootreg_addr, 0); stl_phys_notdirty(&address_space_memory, info->smp_bootreg_addr, 0);
env->regs[15] = info->smp_loader_start; env->regs[15] = info->smp_loader_start;
} }
@@ -179,7 +180,7 @@ static inline bool have_dtb(const struct arm_boot_info *info)
} }
#define WRITE_WORD(p, value) do { \ #define WRITE_WORD(p, value) do { \
stl_phys_notdirty(p, value); \ stl_phys_notdirty(&address_space_memory, p, value); \
p += 4; \ p += 4; \
} while (0) } while (0)

View File

@@ -36,10 +36,17 @@ static void cubieboard_init(QEMUMachineInitArgs *args)
Error *err = NULL; Error *err = NULL;
s->a10 = AW_A10(object_new(TYPE_AW_A10)); s->a10 = AW_A10(object_new(TYPE_AW_A10));
object_property_set_int(OBJECT(&s->a10->emac), 1, "phy-addr", &err);
if (err != NULL) {
error_report("Couldn't set phy address: %s", error_get_pretty(err));
exit(1);
}
object_property_set_bool(OBJECT(s->a10), true, "realized", &err); object_property_set_bool(OBJECT(s->a10), true, "realized", &err);
if (err != NULL) { if (err != NULL) {
error_report("Couldn't realize Allwinner A10: %s\n", error_report("Couldn't realize Allwinner A10: %s",
error_get_pretty(err)); error_get_pretty(err));
exit(1); exit(1);
} }

View File

@@ -326,7 +326,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
busdev = SYS_BUS_DEVICE(dev); busdev = SYS_BUS_DEVICE(dev);
sysbus_connect_irq(busdev, 0, i2c_irq); sysbus_connect_irq(busdev, 0, i2c_irq);
sysbus_mmio_map(busdev, 0, addr); sysbus_mmio_map(busdev, 0, addr);
s->i2c_if[n] = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
} }

View File

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

View File

@@ -92,8 +92,6 @@
#define MP_ETH_CRDP3 0x4AC #define MP_ETH_CRDP3 0x4AC
#define MP_ETH_CTDP0 0x4E0 #define MP_ETH_CTDP0 0x4E0
#define MP_ETH_CTDP1 0x4E4 #define MP_ETH_CTDP1 0x4E4
#define MP_ETH_CTDP2 0x4E8
#define MP_ETH_CTDP3 0x4EC
/* MII PHY access */ /* MII PHY access */
#define MP_ETH_SMIR_DATA 0x0000FFFF #define MP_ETH_SMIR_DATA 0x0000FFFF
@@ -308,7 +306,7 @@ static uint64_t mv88w8618_eth_read(void *opaque, hwaddr offset,
case MP_ETH_CRDP0 ... MP_ETH_CRDP3: case MP_ETH_CRDP0 ... MP_ETH_CRDP3:
return s->rx_queue[(offset - MP_ETH_CRDP0)/4]; return s->rx_queue[(offset - MP_ETH_CRDP0)/4];
case MP_ETH_CTDP0 ... MP_ETH_CTDP3: case MP_ETH_CTDP0 ... MP_ETH_CTDP1:
return s->tx_queue[(offset - MP_ETH_CTDP0)/4]; return s->tx_queue[(offset - MP_ETH_CTDP0)/4];
default: default:
@@ -362,7 +360,7 @@ static void mv88w8618_eth_write(void *opaque, hwaddr offset,
s->cur_rx[(offset - MP_ETH_CRDP0)/4] = value; s->cur_rx[(offset - MP_ETH_CRDP0)/4] = value;
break; break;
case MP_ETH_CTDP0 ... MP_ETH_CTDP3: case MP_ETH_CTDP0 ... MP_ETH_CTDP1:
s->tx_queue[(offset - MP_ETH_CTDP0)/4] = value; s->tx_queue[(offset - MP_ETH_CTDP0)/4] = value;
break; break;
} }
@@ -632,7 +630,7 @@ static int musicpal_lcd_init(SysBusDevice *sbd)
"musicpal-lcd", MP_LCD_SIZE); "musicpal-lcd", MP_LCD_SIZE);
sysbus_init_mmio(sbd, &s->iomem); sysbus_init_mmio(sbd, &s->iomem);
s->con = graphic_console_init(dev, &musicpal_gfx_ops, s); s->con = graphic_console_init(dev, 0, &musicpal_gfx_ops, s);
qemu_console_resize(s->con, 128*3, 64*3); qemu_console_resize(s->con, 128*3, 64*3);
qdev_init_gpio_in(dev, musicpal_lcd_gpio_brightness_in, 3); qdev_init_gpio_in(dev, musicpal_lcd_gpio_brightness_in, 3);
@@ -1593,7 +1591,7 @@ static void musicpal_init(QEMUMachineInitArgs *args)
DeviceState *key_dev; DeviceState *key_dev;
DeviceState *wm8750_dev; DeviceState *wm8750_dev;
SysBusDevice *s; SysBusDevice *s;
i2c_bus *i2c; I2CBus *i2c;
int i; int i;
unsigned long flash_size; unsigned long flash_size;
DriveInfo *dinfo; DriveInfo *dinfo;
@@ -1687,7 +1685,7 @@ static void musicpal_init(QEMUMachineInitArgs *args)
dev = sysbus_create_simple(TYPE_MUSICPAL_GPIO, MP_GPIO_BASE, dev = sysbus_create_simple(TYPE_MUSICPAL_GPIO, MP_GPIO_BASE,
pic[MP_GPIO_IRQ]); pic[MP_GPIO_IRQ]);
i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL); i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);
i2c = (i2c_bus *)qdev_get_child_bus(i2c_dev, "i2c"); i2c = (I2CBus *)qdev_get_child_bus(i2c_dev, "i2c");
lcd_dev = sysbus_create_simple(TYPE_MUSICPAL_LCD, MP_LCD_BASE, NULL); lcd_dev = sysbus_create_simple(TYPE_MUSICPAL_LCD, MP_LCD_BASE, NULL);
key_dev = sysbus_create_simple(TYPE_MUSICPAL_KEY, -1, NULL); key_dev = sysbus_create_simple(TYPE_MUSICPAL_KEY, -1, NULL);

View File

@@ -202,7 +202,7 @@ static void n8x0_i2c_setup(struct n800_s *s)
{ {
DeviceState *dev; DeviceState *dev;
qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO); qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO);
i2c_bus *i2c = omap_i2c_bus(s->mpu->i2c[0]); I2CBus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
/* Attach a menelaus PM chip */ /* Attach a menelaus PM chip */
dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR); dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR);

View File

@@ -224,27 +224,24 @@ static const VMStateDescription vmstate_pxa2xx_cm = {
} }
}; };
static int pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri, static uint64_t pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri)
uint64_t *value)
{ {
PXA2xxState *s = (PXA2xxState *)ri->opaque; PXA2xxState *s = (PXA2xxState *)ri->opaque;
*value = s->clkcfg; return s->clkcfg;
return 0;
} }
static int pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value) uint64_t value)
{ {
PXA2xxState *s = (PXA2xxState *)ri->opaque; PXA2xxState *s = (PXA2xxState *)ri->opaque;
s->clkcfg = value & 0xf; s->clkcfg = value & 0xf;
if (value & 2) { if (value & 2) {
printf("%s: CPU frequency change attempt\n", __func__); printf("%s: CPU frequency change attempt\n", __func__);
} }
return 0;
} }
static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value) uint64_t value)
{ {
PXA2xxState *s = (PXA2xxState *)ri->opaque; PXA2xxState *s = (PXA2xxState *)ri->opaque;
static const char *pwrmode[8] = { static const char *pwrmode[8] = {
@@ -275,11 +272,11 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
goto message; goto message;
case 3: case 3:
s->cpu->env.uncached_cpsr = s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC;
ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
s->cpu->env.cp15.c1_sys = 0; s->cpu->env.cp15.c1_sys = 0;
s->cpu->env.cp15.c1_coproc = 0; s->cpu->env.cp15.c1_coproc = 0;
s->cpu->env.cp15.c2_base0 = 0; s->cpu->env.cp15.ttbr0_el1 = 0;
s->cpu->env.cp15.c3 = 0; s->cpu->env.cp15.c3 = 0;
s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */ s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */ s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
@@ -310,36 +307,29 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
printf("%s: machine entered %s mode\n", __func__, printf("%s: machine entered %s mode\n", __func__,
pwrmode[value & 7]); pwrmode[value & 7]);
} }
return 0;
} }
static int pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri, static uint64_t pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri)
uint64_t *value)
{ {
PXA2xxState *s = (PXA2xxState *)ri->opaque; PXA2xxState *s = (PXA2xxState *)ri->opaque;
*value = s->pmnc; return s->pmnc;
return 0;
} }
static int pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value) uint64_t value)
{ {
PXA2xxState *s = (PXA2xxState *)ri->opaque; PXA2xxState *s = (PXA2xxState *)ri->opaque;
s->pmnc = value; s->pmnc = value;
return 0;
} }
static int pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri, static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
uint64_t *value)
{ {
PXA2xxState *s = (PXA2xxState *)ri->opaque; PXA2xxState *s = (PXA2xxState *)ri->opaque;
if (s->pmnc & 1) { if (s->pmnc & 1) {
*value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
} else { } else {
*value = 0; return 0;
} }
return 0;
} }
static const ARMCPRegInfo pxa_cp_reginfo[] = { static const ARMCPRegInfo pxa_cp_reginfo[] = {
@@ -1222,8 +1212,14 @@ static const TypeInfo pxa2xx_rtc_sysbus_info = {
}; };
/* I2C Interface */ /* I2C Interface */
typedef struct {
I2CSlave i2c; #define TYPE_PXA2XX_I2C_SLAVE "pxa2xx-i2c-slave"
#define PXA2XX_I2C_SLAVE(obj) \
OBJECT_CHECK(PXA2xxI2CSlaveState, (obj), TYPE_PXA2XX_I2C_SLAVE)
typedef struct PXA2xxI2CSlaveState {
I2CSlave parent_obj;
PXA2xxI2CState *host; PXA2xxI2CState *host;
} PXA2xxI2CSlaveState; } PXA2xxI2CSlaveState;
@@ -1238,7 +1234,7 @@ struct PXA2xxI2CState {
MemoryRegion iomem; MemoryRegion iomem;
PXA2xxI2CSlaveState *slave; PXA2xxI2CSlaveState *slave;
i2c_bus *bus; I2CBus *bus;
qemu_irq irq; qemu_irq irq;
uint32_t offset; uint32_t offset;
uint32_t region_size; uint32_t region_size;
@@ -1268,7 +1264,7 @@ static void pxa2xx_i2c_update(PXA2xxI2CState *s)
/* These are only stubs now. */ /* These are only stubs now. */
static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event) static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
{ {
PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c); PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
PXA2xxI2CState *s = slave->host; PXA2xxI2CState *s = slave->host;
switch (event) { switch (event) {
@@ -1292,10 +1288,12 @@ static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
static int pxa2xx_i2c_rx(I2CSlave *i2c) static int pxa2xx_i2c_rx(I2CSlave *i2c)
{ {
PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c); PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
PXA2xxI2CState *s = slave->host; PXA2xxI2CState *s = slave->host;
if ((s->control & (1 << 14)) || !(s->control & (1 << 6)))
if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
return 0; return 0;
}
if (s->status & (1 << 0)) { /* RWM */ if (s->status & (1 << 0)) { /* RWM */
s->status |= 1 << 6; /* set ITE */ s->status |= 1 << 6; /* set ITE */
@@ -1307,10 +1305,12 @@ static int pxa2xx_i2c_rx(I2CSlave *i2c)
static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data) static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data)
{ {
PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c); PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
PXA2xxI2CState *s = slave->host; PXA2xxI2CState *s = slave->host;
if ((s->control & (1 << 14)) || !(s->control & (1 << 6)))
if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
return 1; return 1;
}
if (!(s->status & (1 << 0))) { /* RWM */ if (!(s->status & (1 << 0))) { /* RWM */
s->status |= 1 << 7; /* set IRF */ s->status |= 1 << 7; /* set IRF */
@@ -1325,6 +1325,7 @@ static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
unsigned size) unsigned size)
{ {
PXA2xxI2CState *s = (PXA2xxI2CState *) opaque; PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;
I2CSlave *slave;
addr -= s->offset; addr -= s->offset;
switch (addr) { switch (addr) {
@@ -1333,7 +1334,8 @@ static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
case ISR: case ISR:
return s->status | (i2c_bus_busy(s->bus) << 2); return s->status | (i2c_bus_busy(s->bus) << 2);
case ISAR: case ISAR:
return s->slave->i2c.address; slave = I2C_SLAVE(s->slave);
return slave->address;
case IDBR: case IDBR:
return s->data; return s->data;
case IBMR: case IBMR:
@@ -1408,7 +1410,7 @@ static void pxa2xx_i2c_write(void *opaque, hwaddr addr,
break; break;
case ISAR: case ISAR:
i2c_set_slave_address(&s->slave->i2c, value & 0x7f); i2c_set_slave_address(I2C_SLAVE(s->slave), value & 0x7f);
break; break;
case IDBR: case IDBR:
@@ -1432,7 +1434,7 @@ static const VMStateDescription vmstate_pxa2xx_i2c_slave = {
.minimum_version_id = 1, .minimum_version_id = 1,
.minimum_version_id_old = 1, .minimum_version_id_old = 1,
.fields = (VMStateField []) { .fields = (VMStateField []) {
VMSTATE_I2C_SLAVE(i2c, PXA2xxI2CSlaveState), VMSTATE_I2C_SLAVE(parent_obj, PXA2xxI2CSlaveState),
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
} }
}; };
@@ -1448,7 +1450,7 @@ static const VMStateDescription vmstate_pxa2xx_i2c = {
VMSTATE_UINT8(ibmr, PXA2xxI2CState), VMSTATE_UINT8(ibmr, PXA2xxI2CState),
VMSTATE_UINT8(data, PXA2xxI2CState), VMSTATE_UINT8(data, PXA2xxI2CState),
VMSTATE_STRUCT_POINTER(slave, PXA2xxI2CState, VMSTATE_STRUCT_POINTER(slave, PXA2xxI2CState,
vmstate_pxa2xx_i2c_slave, PXA2xxI2CSlaveState *), vmstate_pxa2xx_i2c_slave, PXA2xxI2CSlaveState),
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
} }
}; };
@@ -1470,7 +1472,7 @@ static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
} }
static const TypeInfo pxa2xx_i2c_slave_info = { static const TypeInfo pxa2xx_i2c_slave_info = {
.name = "pxa2xx-i2c-slave", .name = TYPE_PXA2XX_I2C_SLAVE,
.parent = TYPE_I2C_SLAVE, .parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(PXA2xxI2CSlaveState), .instance_size = sizeof(PXA2xxI2CSlaveState),
.class_init = pxa2xx_i2c_slave_class_init, .class_init = pxa2xx_i2c_slave_class_init,
@@ -1482,7 +1484,7 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
DeviceState *dev; DeviceState *dev;
SysBusDevice *i2c_dev; SysBusDevice *i2c_dev;
PXA2xxI2CState *s; PXA2xxI2CState *s;
i2c_bus *i2cbus; I2CBus *i2cbus;
dev = qdev_create(NULL, TYPE_PXA2XX_I2C); dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
qdev_prop_set_uint32(dev, "size", region_size + 1); qdev_prop_set_uint32(dev, "size", region_size + 1);
@@ -1496,8 +1498,8 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
s = PXA2XX_I2C(i2c_dev); s = PXA2XX_I2C(i2c_dev);
/* FIXME: Should the slave device really be on a separate bus? */ /* FIXME: Should the slave device really be on a separate bus? */
i2cbus = i2c_init_bus(dev, "dummy"); i2cbus = i2c_init_bus(dev, "dummy");
dev = i2c_create_slave(i2cbus, "pxa2xx-i2c-slave", 0); dev = i2c_create_slave(i2cbus, TYPE_PXA2XX_I2C_SLAVE, 0);
s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE(dev)); s->slave = PXA2XX_I2C_SLAVE(dev);
s->slave->host = s; s->slave->host = s;
return s; return s;
@@ -1518,7 +1520,7 @@ static int pxa2xx_i2c_initfn(SysBusDevice *sbd)
return 0; return 0;
} }
i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s) I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
{ {
return s->bus; return s->bus;
} }

View File

@@ -217,20 +217,17 @@ static const int pxa2xx_cp_reg_map[0x10] = {
[0xa] = ICPR2, [0xa] = ICPR2,
}; };
static int pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri, static uint64_t pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri)
uint64_t *value)
{ {
int offset = pxa2xx_cp_reg_map[ri->crn]; int offset = pxa2xx_cp_reg_map[ri->crn];
*value = pxa2xx_pic_mem_read(ri->opaque, offset, 4); return pxa2xx_pic_mem_read(ri->opaque, offset, 4);
return 0;
} }
static int pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value) uint64_t value)
{ {
int offset = pxa2xx_cp_reg_map[ri->crn]; int offset = pxa2xx_cp_reg_map[ri->crn];
pxa2xx_pic_mem_write(ri->opaque, offset, value, 4); pxa2xx_pic_mem_write(ri->opaque, offset, value, 4);
return 0;
} }
#define REGINFO_FOR_PIC_CP(NAME, CRN) \ #define REGINFO_FOR_PIC_CP(NAME, CRN) \

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