Compare commits

..

310 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
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
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
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
282 changed files with 11294 additions and 2689 deletions

3
.gitignore vendored
View File

@@ -66,6 +66,9 @@ libuser
*.cp
*.dvi
*.exe
*.dll
*.so
*.mo
*.fn
*.ky
*.log

View File

@@ -726,7 +726,7 @@ F: vl.c
Human Monitor (HMP)
M: Luiz Capitulino <lcapitulino@redhat.com>
S: Supported
S: Maintained
F: monitor.c
F: hmp.c
F: hmp-commands.hx
@@ -758,7 +758,7 @@ T: git git://github.com/bonzini/qemu.git nbd-next
QAPI
M: Luiz Capitulino <lcapitulino@redhat.com>
M: Michael Roth <mdroth@linux.vnet.ibm.com>
S: Supported
S: Maintained
F: qapi/
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
M: Luiz Capitulino <lcapitulino@redhat.com>
S: Supported
S: Maintained
F: qmp.c
F: monitor.c
F: qmp-commands.hx

View File

@@ -127,13 +127,29 @@ defconfig:
ifneq ($(wildcard config-host.mak),)
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
endif
ifeq ($(CONFIG_SMARTCARD_NSS),y)
include $(SRC_PATH)/libcacard/Makefile
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-timestamp: config-host.mak
@@ -143,6 +159,7 @@ qemu-options.def: $(SRC_PATH)/qemu-options.hx
SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES))
$(SOFTMMU_SUBDIR_RULES): $(block-obj-y)
$(SOFTMMU_SUBDIR_RULES): config-all-devices.mak
subdir-%:
@@ -192,6 +209,9 @@ Makefile: $(version-obj-y) $(version-lobj-y)
libqemustub.a: $(stub-obj-y)
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
@@ -247,6 +267,8 @@ clean:
rm -f qemu-options.def
find . -name '*.[oda]' -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 fsdev/*.pod
rm -rf .libs */.libs
@@ -298,7 +320,7 @@ ifdef INSTALL_BLOBS
BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
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-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
@@ -354,6 +376,12 @@ install-datadir install-localstatedir
ifneq ($(TOOLS),)
$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
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),)
$(INSTALL_DIR) "$(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 += coroutine-$(CONFIG_COROUTINE_BACKEND).o
block-obj-m = block/
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
# 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.
@@ -41,7 +43,7 @@ libcacard-y += libcacard/vcardt.o
# single QEMU executable should support all CPUs and machines.
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 += qdev-monitor.o device-hotplug.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.
qga-obj-y = qga/ qapi-types.o qapi-visit.o
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)/
endif
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h
endif # CONFIG_SOFTMMU
@@ -139,13 +137,26 @@ endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure.
%/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
dummy := $(call unnest-vars,.., \
block-obj-y \
block-obj-m \
common-obj-y \
common-obj-m)
all-obj-y = $(obj-y)
all-obj-y += $(addprefix ../, $(common-obj-y))
# Now restore 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
LIBS+=-lm

View File

@@ -122,7 +122,6 @@ static void check_guest_throttling(void);
#define RAM_SAVE_FLAG_XBZRLE 0x40
/* 0x80 is reserved in migration.h start with 0x100 next */
static struct defconfig_file {
const char *filename;
/* Indicates it is an user config file (disabled by -no-user-config) */
@@ -133,6 +132,7 @@ static struct defconfig_file {
{ NULL }, /* end of list */
};
static const uint8_t ZERO_TARGET_PAGE[TARGET_PAGE_SIZE];
int qemu_read_default_config_files(bool userconfig)
{
@@ -273,6 +273,34 @@ static size_t save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
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
static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
@@ -329,18 +357,6 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
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
ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr,
ram_addr_t start)
@@ -512,6 +528,7 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
} else {
int ret;
uint8_t *p;
bool send_async = true;
int cont = (block == last_sent_block) ?
RAM_SAVE_FLAG_CONTINUE : 0;
@@ -522,6 +539,7 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
ret = ram_control_save_page(f, block->offset,
offset, TARGET_PAGE_SIZE, &bytes_sent);
current_addr = block->offset + offset;
if (ret != RAM_SAVE_CONTROL_NOT_SUPP) {
if (ret != RAM_SAVE_CONTROL_DELAYED) {
if (bytes_sent > 0) {
@@ -536,19 +554,35 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
RAM_SAVE_FLAG_COMPRESS);
qemu_put_byte(f, 0);
bytes_sent++;
/* Must let xbzrle know, otherwise a previous (now 0'd) cached
* page would be stale
*/
xbzrle_cache_zero_page(current_addr);
} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
current_addr = block->offset + offset;
bytes_sent = save_xbzrle_page(f, p, current_addr, block,
offset, cont, 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);
/* Can't send this cached data async, since the cache page
* might get updated before it gets to the wire
*/
send_async = false;
}
}
/* XBZRLE overflow or normal page */
if (bytes_sent == -1) {
bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
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;
acct_info.norm_pages++;
}

View File

@@ -566,7 +566,7 @@ CharDriverState *chr_baum_init(void)
BaumDriverState *baum;
CharDriverState *chr;
brlapi_handle_t *handle;
#ifdef CONFIG_SDL
#if defined(CONFIG_SDL) && SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
SDL_SysWMinfo info;
#endif
int tty;
@@ -595,7 +595,7 @@ CharDriverState *chr_baum_init(void)
goto fail;
}
#ifdef CONFIG_SDL
#if defined(CONFIG_SDL) && SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
memset(&info, 0, sizeof(info));
SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info))

237
block.c
View File

@@ -547,8 +547,9 @@ int get_tmp_filename(char *filename, int size)
int fd;
const char *tmpdir;
tmpdir = getenv("TMPDIR");
if (!tmpdir)
tmpdir = "/tmp";
if (!tmpdir) {
tmpdir = "/var/tmp";
}
if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) {
return -EOVERFLOW;
}
@@ -955,53 +956,27 @@ free_and_fail:
/*
* 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
* 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
* dictionary, it needs to use QINCREF() before calling bdrv_file_open.
* options is an indirect pointer to a QDict of options to pass to the block
* drivers, or pointer to NULL for an empty set of options. If this function
* takes ownership of the QDict reference, it will set *options to NULL;
* 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,
const char *reference, QDict *options, int flags,
Error **errp)
static int bdrv_file_open(BlockDriverState *bs, const char *filename,
QDict **options, int flags, Error **errp)
{
BlockDriverState *bs = NULL;
BlockDriver *drv;
const char *drvname;
bool allow_protocol_prefix = false;
Error *local_err = NULL;
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_lookup_bs(reference, reference, errp);
if (!bs) {
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 */
if (!filename) {
filename = qdict_get_try_str(options, "filename");
} else if (filename && !qdict_haskey(options, "filename")) {
qdict_put(options, "filename", qstring_from_str(filename));
filename = qdict_get_try_str(*options, "filename");
} else if (filename && !qdict_haskey(*options, "filename")) {
qdict_put(*options, "filename", qstring_from_str(filename));
allow_protocol_prefix = true;
} else {
error_setg(errp, "Can't specify 'file' and 'filename' options at the "
@@ -1011,13 +986,13 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
}
/* Find the right block driver */
drvname = qdict_get_try_str(options, "driver");
drvname = qdict_get_try_str(*options, "driver");
if (drvname) {
drv = bdrv_find_format(drvname);
if (!drv) {
error_setg(errp, "Unknown driver '%s'", drvname);
}
qdict_del(options, "driver");
qdict_del(*options, "driver");
} else if (filename) {
drv = bdrv_find_protocol(filename, allow_protocol_prefix);
if (!drv) {
@@ -1036,46 +1011,30 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
/* Parse the filename and open it */
if (drv->bdrv_parse_filename && filename) {
drv->bdrv_parse_filename(filename, options, &local_err);
drv->bdrv_parse_filename(filename, *options, &local_err);
if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
qdict_del(options, "filename");
qdict_del(*options, "filename");
}
if (!drv->bdrv_file_open) {
ret = bdrv_open(bs, filename, options, flags, drv, &local_err);
options = NULL;
ret = bdrv_open(&bs, filename, NULL, *options, flags, drv, &local_err);
*options = NULL;
} 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) {
error_propagate(errp, local_err);
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;
*pbs = bs;
return 0;
fail:
QDECREF(options);
if (!bs->drv) {
QDECREF(bs->options);
}
bdrv_unref(bs);
return ret;
}
@@ -1115,8 +1074,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
sizeof(backing_filename));
}
bs->backing_hd = bdrv_new("");
if (bs->backing_format[0] != '\0') {
back_drv = bdrv_find_format(bs->backing_format);
}
@@ -1125,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 |
BDRV_O_COPY_ON_READ);
ret = bdrv_open(bs->backing_hd,
*backing_filename ? backing_filename : NULL, options,
assert(bs->backing_hd == NULL);
ret = bdrv_open(&bs->backing_hd,
*backing_filename ? backing_filename : NULL, NULL, options,
back_flags, back_drv, &local_err);
if (ret < 0) {
bdrv_unref(bs->backing_hd);
bs->backing_hd = NULL;
bs->open_flags |= BDRV_O_NO_BACKING;
error_setg(errp, "Could not open backing file: %s",
@@ -1153,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
* 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
* BlockdevRef is given. *pbs will remain unchanged and 0 will be returned.
*
@@ -1166,16 +1119,21 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
* BlockdevRef.
*
* 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,
QDict *options, const char *bdref_key, int flags,
bool force_raw, bool allow_none, Error **errp)
bool allow_none, Error **errp)
{
QDict *image_options;
int ret;
char *bdref_key_dot;
const char *reference;
assert(pbs);
assert(*pbs == NULL);
bdref_key_dot = g_strdup_printf("%s.", bdref_key);
qdict_extract_subqdict(options, &image_options, bdref_key_dot);
g_free(bdref_key_dot);
@@ -1192,30 +1150,7 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename,
goto done;
}
if (filename && !force_raw) {
/* 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);
}
ret = bdrv_open(pbs, filename, reference, image_options, flags, NULL, errp);
done:
qdict_del(options, bdref_key);
@@ -1229,17 +1164,58 @@ done:
* 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
* 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 flags, BlockDriver *drv, Error **errp)
int bdrv_open(BlockDriverState **pbs, const char *filename,
const char *reference, QDict *options, int flags,
BlockDriver *drv, Error **errp)
{
int ret;
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
char tmp_filename[PATH_MAX + 1];
BlockDriverState *file = NULL;
BlockDriverState *file = NULL, *bs;
const char *drvname;
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 */
if (options == NULL) {
options = qdict_new();
@@ -1248,6 +1224,19 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
bs->options = 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 */
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
@@ -1260,12 +1249,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
instead of opening 'filename' directly */
/* Get the required size from the image */
bs1 = bdrv_new("");
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);
if (ret < 0) {
bdrv_unref(bs1);
goto fail;
}
total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
@@ -1322,9 +1310,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
flags |= BDRV_O_ALLOW_RDWR;
}
assert(file == NULL);
ret = bdrv_open_image(&file, filename, options, "file",
bdrv_open_flags(bs, flags | BDRV_O_UNMAP), true, true,
&local_err);
bdrv_open_flags(bs, flags | BDRV_O_UNMAP) |
BDRV_O_PROTOCOL, true, &local_err);
if (ret < 0) {
goto fail;
}
@@ -1377,12 +1366,18 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
}
}
done:
/* Check if any unknown options were used */
if (qdict_size(options) != 0) {
if (options && (qdict_size(options) != 0)) {
const QDictEntry *entry = qdict_first(options);
error_setg(errp, "Block format '%s' used by device '%s' doesn't "
"support the option '%s'", drv->format_name, bs->device_name,
entry->key);
if (flags & BDRV_O_PROTOCOL) {
error_setg(errp, "Block protocol '%s' doesn't support the option "
"'%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;
goto close_and_fail;
@@ -1393,6 +1388,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
bdrv_dev_change_media_cb(bs, true);
}
*pbs = bs;
return 0;
unlink_and_fail:
@@ -1406,13 +1402,24 @@ fail:
QDECREF(bs->options);
QDECREF(options);
bs->options = NULL;
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);
}
return ret;
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);
if (local_err) {
error_propagate(errp, local_err);
@@ -5290,9 +5297,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
back_flags =
flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
bs = bdrv_new("");
ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
bs = NULL;
ret = bdrv_open(&bs, backing_file->value.s, NULL, NULL, back_flags,
backing_drv, &local_err);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not open '%s': %s",
@@ -5300,7 +5306,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
error_get_pretty(local_err));
error_free(local_err);
local_err = NULL;
bdrv_unref(bs);
goto out;
}
bdrv_get_geometry(bs, &size);
@@ -5416,11 +5421,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate)
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
bool perm;
if (!bs->file) {
continue;
}
perm = bdrv_recurse_is_first_non_filter(bs->file, candidate);
perm = bdrv_recurse_is_first_non_filter(bs, candidate);
/* candidate is the first non filter */
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-check.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 += snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
@@ -24,4 +25,15 @@ common-obj-y += commit.o
common-obj-y += mirror.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

@@ -410,8 +410,9 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
s->state = 1;
/* Open the backing file */
assert(bs->file == NULL);
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) {
error_propagate(errp, local_err);
goto out;

View File

@@ -135,16 +135,18 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Open the raw file */
assert(bs->file == NULL);
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) {
error_propagate(errp, local_err);
goto fail;
}
/* Open the test file */
assert(s->test_file == NULL);
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) {
error_propagate(errp, local_err);
s->test_file = NULL;
@@ -171,110 +173,6 @@ static int64_t blkverify_getlength(BlockDriverState *bs)
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,
int64_t sector_num, QEMUIOVector *qiov,
int nb_sectors,
@@ -338,7 +236,7 @@ static void blkverify_aio_cb(void *opaque, int ret)
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) {
blkverify_err(acb, "contents mismatch in sector %" PRId64,
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->buf = qemu_blockalign(bs->file, qiov->size);
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,
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) ||
((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
(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) {

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) {
ret = -EMEDIUMTYPE;
error_setg(errp, "Image not in COW format");
ret = -EINVAL;
goto fail;
}
@@ -82,7 +83,7 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags,
char version[64];
snprintf(version, sizeof(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);
ret = -ENOTSUP;
goto fail;
@@ -346,16 +347,15 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
ret = bdrv_create_file(filename, options, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
return ret;
}
ret = bdrv_file_open(&cow_bs, filename, NULL, NULL, BDRV_O_RDWR,
&local_err);
cow_bs = NULL;
ret = bdrv_open(&cow_bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
return ret;
}

View File

@@ -456,30 +456,27 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
static int inited = 0;
if (flags & BDRV_O_RDWR) {
qerror_report(ERROR_CLASS_GENERIC_ERROR,
"curl block device does not support writes");
error_setg(errp, "curl block device does not support writes");
return -EROFS;
}
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
goto out_noclean;
}
s->readahead_size = qemu_opt_get_size(opts, "readahead", READ_AHEAD_SIZE);
if ((s->readahead_size & 0x1ff) != 0) {
fprintf(stderr, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512\n",
s->readahead_size);
error_setg(errp, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512",
s->readahead_size);
goto out_noclean;
}
file = qemu_opt_get(opts, "url");
if (file == NULL) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "curl block driver requires "
"an 'url' option");
error_setg(errp, "curl block driver requires an 'url' option");
goto out_noclean;
}

View File

@@ -45,11 +45,13 @@ typedef struct GlusterConf {
static void qemu_gluster_gconf_free(GlusterConf *gconf)
{
g_free(gconf->server);
g_free(gconf->volname);
g_free(gconf->image);
g_free(gconf->transport);
g_free(gconf);
if (gconf) {
g_free(gconf->server);
g_free(gconf->volname);
g_free(gconf->image);
g_free(gconf->transport);
g_free(gconf);
}
}
static int parse_volume_options(GlusterConf *gconf, char *path)
@@ -127,7 +129,7 @@ static int qemu_gluster_parseuri(GlusterConf *gconf, const char *filename)
}
/* transport */
if (!strcmp(uri->scheme, "gluster")) {
if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
gconf->transport = g_strdup("tcp");
} else if (!strcmp(uri->scheme, "gluster+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);
} else {
gconf->server = g_strdup(uri->server);
gconf->server = g_strdup(uri->server ? uri->server : "localhost");
gconf->port = uri->port;
}
@@ -175,7 +177,8 @@ out:
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;
int ret;
@@ -183,8 +186,8 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename)
ret = qemu_gluster_parseuri(gconf, filename);
if (ret < 0) {
error_report("Usage: file=gluster[+transport]://[server[:port]]/"
"volname/image[?socket=...]");
error_setg(errp, "Usage: file=gluster[+transport]://[server[:port]]/"
"volname/image[?socket=...]");
errno = -ret;
goto out;
}
@@ -211,9 +214,11 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename)
ret = glfs_init(glfs);
if (ret) {
error_report("Gluster connection failed for server=%s port=%d "
"volume=%s image=%s transport=%s", gconf->server, gconf->port,
gconf->volname, gconf->image, gconf->transport);
error_setg_errno(errp, errno,
"Gluster connection failed for server=%s port=%d "
"volume=%s image=%s transport=%s", gconf->server,
gconf->port, gconf->volname, gconf->image,
gconf->transport);
goto out;
}
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,
int bdrv_flags, Error **errp)
{
BDRVGlusterState *s = bs->opaque;
int open_flags = O_BINARY;
int open_flags = 0;
int ret = 0;
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
QemuOpts *opts;
@@ -283,29 +305,20 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
ret = -EINVAL;
goto out;
}
filename = qemu_opt_get(opts, "filename");
s->glfs = qemu_gluster_init(gconf, filename);
s->glfs = qemu_gluster_init(gconf, filename, errp);
if (!s->glfs) {
ret = -errno;
goto out;
}
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;
}
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
s->fd = glfs_open(s->glfs, gconf->image, open_flags);
if (!s->fd) {
@@ -327,6 +340,96 @@ out:
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
static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs,
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;
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
glfs = qemu_gluster_init(gconf, filename);
glfs = qemu_gluster_init(gconf, filename, errp);
if (!glfs) {
ret = -errno;
ret = -EINVAL;
goto out;
}
@@ -617,6 +720,9 @@ static BlockDriver bdrv_gluster = {
.instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true,
.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_create = qemu_gluster_create,
.bdrv_getlength = qemu_gluster_getlength,
@@ -641,6 +747,9 @@ static BlockDriver bdrv_gluster_tcp = {
.instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true,
.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_create = qemu_gluster_create,
.bdrv_getlength = qemu_gluster_getlength,
@@ -665,6 +774,9 @@ static BlockDriver bdrv_gluster_unix = {
.instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true,
.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_create = qemu_gluster_create,
.bdrv_getlength = qemu_gluster_getlength,
@@ -689,6 +801,9 @@ static BlockDriver bdrv_gluster_rdma = {
.instance_size = sizeof(BDRVGlusterState),
.bdrv_needs_filename = true,
.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_create = qemu_gluster_create,
.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
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {
error_report("iSCSI CheckCondition: %s", iscsi_get_error(iscsi));
iTask->do_retry = 1;
goto out;
}
if (status != SCSI_STATUS_GOOD) {
error_report("iSCSI: Failure. %s", iscsi_get_error(iscsi));
error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));
}
out:
@@ -325,6 +326,7 @@ retry:
}
if (iTask.do_retry) {
iTask.complete = 0;
goto retry;
}
@@ -399,6 +401,7 @@ retry:
}
if (iTask.do_retry) {
iTask.complete = 0;
goto retry;
}
@@ -433,6 +436,7 @@ retry:
}
if (iTask.do_retry) {
iTask.complete = 0;
goto retry;
}
@@ -683,6 +687,7 @@ retry:
scsi_free_scsi_task(iTask.task);
iTask.task = NULL;
}
iTask.complete = 0;
goto retry;
}
@@ -767,6 +772,7 @@ retry:
}
if (iTask.do_retry) {
iTask.complete = 0;
goto retry;
}
@@ -830,24 +836,26 @@ retry:
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) {
scsi_free_scsi_task(iTask.task);
iTask.task = NULL;
}
if (iTask.do_retry) {
iTask.complete = 0;
goto retry;
}
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;
}
@@ -856,7 +864,8 @@ retry:
#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;
QemuOpts *opts;
@@ -865,37 +874,35 @@ static int parse_chap(struct iscsi_context *iscsi, const char *target)
list = qemu_find_opts("iscsi");
if (!list) {
return 0;
return;
}
opts = qemu_opts_find(list, target);
if (opts == NULL) {
opts = QTAILQ_FIRST(&list->head);
if (!opts) {
return 0;
return;
}
}
user = qemu_opt_get(opts, "user");
if (!user) {
return 0;
return;
}
password = qemu_opt_get(opts, "password");
if (!password) {
error_report("CHAP username specified but no password was given");
return -1;
error_setg(errp, "CHAP username specified but no password was given");
return;
}
if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
error_report("Failed to set initiator username and password");
return -1;
error_setg(errp, "Failed to set initiator username and password");
}
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;
QemuOpts *opts;
@@ -928,7 +935,7 @@ static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
} else if (!strcmp(digest, "NONE-CRC32C")) {
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
} 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
static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
{
struct scsi_task *task = NULL;
struct scsi_readcapacity10 *rc10 = NULL;
struct scsi_readcapacity16 *rc16 = NULL;
int ret = 0;
int retries = ISCSI_CMD_RETRIES;
do {
@@ -1006,8 +1012,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
if (task != NULL && task->status == SCSI_STATUS_GOOD) {
rc16 = scsi_datain_unmarshall(task);
if (rc16 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
ret = -EINVAL;
error_setg(errp, "iSCSI: Failed to unmarshall readcapacity16 data.");
} else {
iscsilun->block_size = rc16->block_length;
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) {
rc10 = scsi_datain_unmarshall(task);
if (rc10 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
ret = -EINVAL;
error_setg(errp, "iSCSI: Failed to unmarshall readcapacity10 data.");
} else {
iscsilun->block_size = rc10->block_size;
if (rc10->lba == 0) {
@@ -1035,20 +1039,18 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
}
break;
default:
return 0;
return;
}
} while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION
&& retries-- > 0);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
error_report("iSCSI: failed to send readcapacity10 command.");
ret = -EINVAL;
error_setg(errp, "iSCSI: failed to send readcapacity10 command.");
}
if (task) {
scsi_free_scsi_task(task);
}
return ret;
}
/* TODO Convert to fine grained options */
@@ -1065,35 +1067,41 @@ static QemuOptsList runtime_opts = {
},
};
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi,
int lun, int evpd, int pc) {
int full_size;
struct scsi_task *task = NULL;
task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, 64);
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
int evpd, int pc, void **inq, Error **errp)
{
int full_size;
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) {
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) {
goto fail;
}
}
*inq = scsi_datain_unmarshall(task);
if (*inq == NULL) {
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
goto fail;
}
return task;
return task;
fail:
error_report("iSCSI: Inquiry command failed : %s",
iscsi_get_error(iscsi));
if (task) {
scsi_free_scsi_task(task);
return NULL;
}
return NULL;
error_setg(errp, "iSCSI: Inquiry command failed : %s",
iscsi_get_error(iscsi));
if (task != NULL) {
scsi_free_scsi_task(task);
}
return NULL;
}
/*
@@ -1112,34 +1120,33 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
struct iscsi_url *iscsi_url = NULL;
struct scsi_task *task = NULL;
struct scsi_inquiry_standard *inq = NULL;
struct scsi_inquiry_supported_pages *inq_vpd;
char *initiator_name = NULL;
QemuOpts *opts;
Error *local_err = NULL;
const char *filename;
int ret;
int i, ret;
if ((BDRV_SECTOR_SIZE % 512) != 0) {
error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
"BDRV_SECTOR_SIZE(%lld) is not a multiple "
"of 512", BDRV_SECTOR_SIZE);
error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
"BDRV_SECTOR_SIZE(%lld) is not a multiple "
"of 512", BDRV_SECTOR_SIZE);
return -EINVAL;
}
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
ret = -EINVAL;
goto out;
}
filename = qemu_opt_get(opts, "filename");
iscsi_url = iscsi_parse_full_url(iscsi, filename);
if (iscsi_url == NULL) {
error_report("Failed to parse URL : %s", filename);
error_setg(errp, "Failed to parse URL : %s", filename);
ret = -EINVAL;
goto out;
}
@@ -1150,13 +1157,13 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsi = iscsi_create_context(initiator_name);
if (iscsi == NULL) {
error_report("iSCSI: Failed to create iSCSI context.");
error_setg(errp, "iSCSI: Failed to create iSCSI context.");
ret = -ENOMEM;
goto out;
}
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;
goto out;
}
@@ -1165,21 +1172,22 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
iscsi_url->passwd);
if (ret != 0) {
error_report("Failed to set initiator username and password");
error_setg(errp, "Failed to set initiator username and password");
ret = -EINVAL;
goto out;
}
}
/* check if we got CHAP username/password via the options */
if (parse_chap(iscsi, iscsi_url->target) != 0) {
error_report("iSCSI: Failed to set CHAP user/password");
parse_chap(iscsi, iscsi_url->target, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto out;
}
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;
goto out;
}
@@ -1187,10 +1195,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
/* 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) {
error_report("iSCSI: Failed to connect to LUN : %s",
error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
iscsi_get_error(iscsi));
ret = -EINVAL;
goto out;
@@ -1198,26 +1211,21 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsilun->iscsi = iscsi;
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;
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;
}
bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
@@ -1232,45 +1240,48 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
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;
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;
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS);
if (task == NULL) {
ret = -EINVAL;
goto out;
switch (inq_vpd->pages[i]) {
case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
(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)
/* Set up a timer for sending out iSCSI NOPs */
@@ -1353,14 +1364,16 @@ static int iscsi_reopen_prepare(BDRVReopenState *state,
static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
{
IscsiLun *iscsilun = bs->opaque;
int ret = 0;
Error *local_err = NULL;
if (iscsilun->type != TYPE_DISK) {
return -ENOTSUP;
}
if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
return ret;
iscsi_readcapacity_sync(iscsilun, &local_err);
if (local_err != NULL) {
error_free(local_err);
return -EIO;
}
if (offset > iscsi_getlength(bs)) {

View File

@@ -188,31 +188,28 @@ out:
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;
if (qdict_haskey(options, "path")) {
if (qdict_haskey(options, "host")) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "path and host may not "
"be used at the same time.");
return -EINVAL;
if (qdict_haskey(options, "path") == qdict_haskey(options, "host")) {
if (qdict_haskey(options, "path")) {
error_setg(errp, "path and host may not be used at the same time.");
} else {
error_setg(errp, "one of path and host must be specified.");
}
s->client.is_unix = true;
} else if (qdict_haskey(options, "host")) {
s->client.is_unix = false;
} else {
return -EINVAL;
return;
}
s->client.is_unix = qdict_haskey(options, "path");
s->socket_opts = qemu_opts_create(&socket_optslist, NULL, 0,
&error_abort);
qemu_opts_absorb_qdict(s->socket_opts, options, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -EINVAL;
error_propagate(errp, local_err);
return;
}
if (!qemu_opt_get(s->socket_opts, "port")) {
@@ -223,19 +220,17 @@ static int nbd_config(BDRVNBDState *s, QDict *options, char **export)
if (*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;
int sock;
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 {
sock = tcp_socket_outgoing_opts(s->socket_opts);
sock = inet_connect_opts(s->socket_opts, errp, NULL, NULL);
if (sock >= 0) {
socket_set_nodelay(sock);
}
@@ -256,17 +251,19 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
BDRVNBDState *s = bs->opaque;
char *export = NULL;
int result, sock;
Error *local_err = NULL;
/* Pop the config into our state object. Exit if invalid. */
result = nbd_config(s, options, &export);
if (result != 0) {
return result;
nbd_config(s, options, &export, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return -EINVAL;
}
/* establish TCP connection, return error if it fails
* TODO: Configurable retry-until-timeout behaviour.
*/
sock = nbd_establish_connection(bs);
sock = nbd_establish_connection(bs, errp);
if (sock < 0) {
return sock;
}

View File

@@ -85,7 +85,8 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
(le32_to_cpu(ph.version) != HEADER_VERSION)) {
ret = -EMEDIUMTYPE;
error_setg(errp, "Image not in Parallels format");
ret = -EINVAL;
goto fail;
}

View File

@@ -113,23 +113,26 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
be64_to_cpus(&header.l1_table_offset);
if (header.magic != QCOW_MAGIC) {
ret = -EMEDIUMTYPE;
error_setg(errp, "Image not in qcow format");
ret = -EINVAL;
goto fail;
}
if (header.version != QCOW_VERSION) {
char version[64];
snprintf(version, sizeof(version), "QCOW version %d", header.version);
qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "qcow", version);
error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "qcow", version);
ret = -ENOTSUP;
goto fail;
}
if (header.size <= 1 || header.cluster_bits < 9) {
error_setg(errp, "invalid value in qcow header");
ret = -EINVAL;
goto fail;
}
if (header.crypt_method > QCOW_CRYPT_AES) {
error_setg(errp, "invalid encryption method in qcow header");
ret = -EINVAL;
goto fail;
}
@@ -686,16 +689,15 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
ret = bdrv_create_file(filename, options, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
return ret;
}
ret = bdrv_file_open(&qcow_bs, filename, NULL, NULL, BDRV_O_RDWR,
&local_err);
qcow_bs = NULL;
ret = bdrv_open(&qcow_bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
return ret;
}

View File

@@ -1367,13 +1367,31 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
uint64_t old_offset;
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;
}
/* First remove L2 entries */
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 */
qcow2_free_any_clusters(bs, old_offset, 1, type);

View File

@@ -449,7 +449,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
if (header.magic != QCOW_MAGIC) {
error_setg(errp, "Image is not in qcow2 format");
ret = -EMEDIUMTYPE;
ret = -EINVAL;
goto fail;
}
if (header.version < 2 || header.version > 3) {
@@ -1493,7 +1493,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
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) {
error_propagate(errp, local_err);
return ret;
@@ -1543,7 +1545,8 @@ static int qcow2_create2(const char *filename, int64_t total_size,
goto out;
}
bdrv_close(bs);
bdrv_unref(bs);
bs = NULL;
/*
* And now open the image and make it consistent first (i.e. increase the
@@ -1552,7 +1555,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
*/
BlockDriver* drv = bdrv_find_format("qcow2");
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);
if (ret < 0) {
error_propagate(errp, local_err);
@@ -1599,10 +1602,11 @@ 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 */
ret = bdrv_open(bs, filename, NULL,
ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
drv, &local_err);
if (local_err) {
@@ -1612,7 +1616,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
ret = 0;
out:
bdrv_unref(bs);
if (bs) {
bdrv_unref(bs);
}
return ret;
}

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);
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) {
/* image uses unsupported feature bits */
char buf[64];
snprintf(buf, sizeof(buf), "%" PRIx64,
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);
return -ENOTSUP;
}
@@ -545,7 +546,8 @@ static void bdrv_qed_close(BlockDriverState *bs)
static int qed_create(const char *filename, uint32_t cluster_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 = {
.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;
Error *local_err = NULL;
int ret = 0;
BlockDriverState *bs = NULL;
BlockDriverState *bs;
ret = bdrv_create_file(filename, NULL, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
return ret;
}
ret = bdrv_file_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB, &local_err);
bs = NULL;
ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_PROTOCOL, NULL,
&local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
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,
backing_file, backing_fmt);
backing_file, backing_fmt, errp);
}
typedef struct {

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

@@ -1534,7 +1534,8 @@ static int sd_prealloc(const char *filename)
Error *local_err = NULL;
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) {
qerror_report_err(local_err);
error_free(local_err);
@@ -1695,7 +1696,9 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
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) {
qerror_report_err(local_err);
error_free(local_err);

View File

@@ -395,43 +395,50 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
}
if (header.signature != VDI_SIGNATURE) {
logout("bad vdi signature %08x\n", header.signature);
ret = -EMEDIUMTYPE;
error_setg(errp, "Image not in VDI format (bad signature %08x)", header.signature);
ret = -EINVAL;
goto fail;
} else if (header.version != VDI_VERSION_1_1) {
logout("unsupported version %u.%u\n",
header.version >> 16, header.version & 0xffff);
error_setg(errp, "unsupported VDI image (version %u.%u)",
header.version >> 16, header.version & 0xffff);
ret = -ENOTSUP;
goto fail;
} else if (header.offset_bmap % SECTOR_SIZE != 0) {
/* 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;
goto fail;
} else if (header.offset_data % SECTOR_SIZE != 0) {
/* 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;
goto fail;
} 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;
goto fail;
} 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;
goto fail;
} else if (header.disk_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;
goto fail;
} 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;
goto fail;
} 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;
goto fail;
}

View File

@@ -402,9 +402,10 @@ int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
}
/* 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 *header2;
bool h1_valid = false;
@@ -462,7 +463,6 @@ static int vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s)
} else if (!h1_valid && h2_valid) {
s->curr_header = 1;
} else if (!h1_valid && !h2_valid) {
ret = -EINVAL;
goto fail;
} else {
/* 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) {
s->curr_header = 1;
} else {
ret = -EINVAL;
goto fail;
}
}
vhdx_region_register(s, s->headers[s->curr_header]->log_offset,
s->headers[s->curr_header]->log_length);
ret = 0;
goto exit;
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(header2);
s->headers[0] = NULL;
s->headers[1] = NULL;
exit:
qemu_vfree(buffer);
return ret;
}
@@ -878,7 +873,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
int ret = 0;
uint32_t i;
uint64_t signature;
Error *local_err = NULL;
s->bat = NULL;
s->first_visible_write = true;
@@ -901,8 +896,10 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
* header update */
vhdx_guid_generate(&s->session_guid);
ret = vhdx_parse_header(bs, s);
if (ret < 0) {
vhdx_parse_header(bs, s, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
@@ -1797,7 +1794,9 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
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) {
error_propagate(errp, local_err);
goto exit;

View File

@@ -526,8 +526,34 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
return ret;
}
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
uint64_t desc_offset, Error **errp);
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
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,
BlockDriverState *file,
@@ -546,11 +572,18 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
error_setg_errno(errp, -ret,
"Could not read header from file '%s'",
file->filename);
return -EINVAL;
}
if (header.capacity == 0) {
uint64_t desc_offset = le64_to_cpu(header.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];
snprintf(buf, sizeof(buf), "VMDK version %d",
le32_to_cpu(header.version));
qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "vmdk", buf);
error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bs->device_name, "vmdk", buf);
return -ENOTSUP;
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
/* VMware KB 2064959 explains that version 3 added support for
@@ -622,7 +655,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
}
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;
}
@@ -638,8 +671,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
}
if (bdrv_getlength(file) <
le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE) {
error_report("File truncated, expecting at least %lld bytes",
le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE);
error_setg(errp, "File truncated, expecting at least %lld bytes",
le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE);
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 */
static int vmdk_open_sparse(BlockDriverState *bs,
BlockDriverState *file,
int flags, Error **errp)
BlockDriverState *file, int flags,
char *buf, Error **errp)
{
uint32_t magic;
if (bdrv_pread(file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
return -EIO;
}
magic = be32_to_cpu(magic);
magic = ldl_be_p(buf);
switch (magic) {
case VMDK3_MAGIC:
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);
break;
default:
return -EMEDIUMTYPE;
error_setg(errp, "Image not in VMDK format");
return -EINVAL;
break;
}
}
@@ -776,8 +806,9 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
path_combine(extent_path, sizeof(extent_path),
desc_file_path, fname);
ret = bdrv_file_open(&extent_file, extent_path, NULL, NULL,
bs->open_flags, errp);
extent_file = NULL;
ret = bdrv_open(&extent_file, extent_path, NULL, NULL,
bs->open_flags | BDRV_O_PROTOCOL, NULL, errp);
if (ret) {
return ret;
}
@@ -794,8 +825,14 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
extent->flat_start_offset = flat_offset << 9;
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
/* 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) {
g_free(buf);
bdrv_unref(extent_file);
return ret;
}
@@ -818,29 +855,16 @@ next_line:
return 0;
}
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
uint64_t desc_offset, Error **errp)
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
Error **errp)
{
int ret;
char *buf = NULL;
char ct[128];
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))) {
ret = -EMEDIUMTYPE;
error_setg(errp, "invalid VMDK image descriptor");
ret = -EINVAL;
goto exit;
}
if (strcmp(ct, "monolithicFlat") &&
@@ -856,24 +880,37 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
s->desc_offset = 0;
ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp);
exit:
g_free(buf);
return ret;
}
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
char *buf = NULL;
int ret;
BDRVVmdkState *s = bs->opaque;
uint32_t magic;
if (vmdk_open_sparse(bs, bs->file, flags, errp) == 0) {
s->desc_offset = 0x200;
} else {
ret = vmdk_open_desc_file(bs, flags, 0, errp);
if (ret) {
goto fail;
}
buf = vmdk_read_desc(bs->file, 0, errp);
if (!buf) {
return -EINVAL;
}
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 */
ret = vmdk_parent_open(bs);
if (ret) {
@@ -888,10 +925,11 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vmdk", bs->device_name, "live migration");
migrate_add_blocker(s->migration_blocker);
g_free(buf);
return 0;
fail:
g_free(buf);
g_free(s->create_type);
s->create_type = NULL;
vmdk_free_extents(bs);
@@ -1146,7 +1184,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
break;
case VMDK_OK:
ret = BDRV_BLOCK_DATA;
if (extent->file == bs->file) {
if (extent->file == bs->file && !extent->compressed) {
ret |= BDRV_BLOCK_OFFSET_VALID | offset;
}
@@ -1493,7 +1531,9 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
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) {
error_propagate(errp, local_err);
goto exit;
@@ -1755,10 +1795,10 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
goto exit;
}
if (backing_file) {
BlockDriverState *bs = bdrv_new("");
ret = bdrv_open(bs, backing_file, NULL, BDRV_O_NO_BACKING, NULL, errp);
BlockDriverState *bs = NULL;
ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_NO_BACKING, NULL,
errp);
if (ret != 0) {
bdrv_unref(bs);
goto exit;
}
if (strcmp(bs->drv->format_name, "vmdk")) {
@@ -1831,7 +1871,9 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
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) {
error_setg_errno(errp, -ret, "Could not write description");
goto exit;

View File

@@ -190,7 +190,8 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
if (strncmp(footer->creator, "conectix", 8)) {
ret = -EMEDIUMTYPE;
error_setg(errp, "invalid VPC image");
ret = -EINVAL;
goto fail;
}
disk_type = VHD_FIXED;

View File

@@ -1086,16 +1086,14 @@ DLOG(if (stderr == NULL) {
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
dirname = qemu_opt_get(opts, "dir");
if (!dirname) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "vvfat block driver requires "
"a 'dir' option");
error_setg(errp, "vvfat block driver requires a 'dir' option");
ret = -EINVAL;
goto fail;
}
@@ -1135,8 +1133,7 @@ DLOG(if (stderr == NULL) {
case 12:
break;
default:
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Valid FAT types are only "
"12, 16 and 32");
error_setg(errp, "Valid FAT types are only 12, 16 and 32");
ret = -EINVAL;
goto fail;
}
@@ -2936,15 +2933,13 @@ static int enable_write_target(BDRVVVFATState *s)
goto err;
}
s->qcow = bdrv_new("");
ret = bdrv_open(s->qcow, s->qcow_filename, NULL,
s->qcow = NULL;
ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow,
&local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
bdrv_unref(s->qcow);
goto err;
}

View File

@@ -504,7 +504,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
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) {
error_setg(errp, "could not open disk image %s: %s",
@@ -1330,12 +1330,12 @@ static void external_snapshot_prepare(BlkTransactionState *common,
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
* 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);
/* We will manually add the backing_hd field to the bs later */
if (ret != 0) {
error_propagate(errp, local_err);
}
@@ -1582,7 +1582,7 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
Error *local_err = NULL;
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) {
error_propagate(errp, local_err);
return;
@@ -2018,10 +2018,9 @@ void qmp_drive_backup(const char *device, const char *target,
return;
}
target_bs = bdrv_new("");
ret = bdrv_open(target_bs, target, NULL, flags, drv, &local_err);
target_bs = NULL;
ret = bdrv_open(&target_bs, target, NULL, NULL, flags, drv, &local_err);
if (ret < 0) {
bdrv_unref(target_bs);
error_propagate(errp, local_err);
return;
}
@@ -2162,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
* file.
*/
target_bs = bdrv_new("");
ret = bdrv_open(target_bs, target, NULL, flags | BDRV_O_NO_BACKING, drv,
&local_err);
target_bs = NULL;
ret = bdrv_open(&target_bs, target, NULL, NULL, flags | BDRV_O_NO_BACKING,
drv, &local_err);
if (ret < 0) {
bdrv_unref(target_bs);
error_propagate(errp, local_err);
return;
}

317
configure vendored
View File

@@ -12,7 +12,10 @@ else
fi
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"
# 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_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".
symlink() {
rm -rf "$2"
@@ -172,6 +207,7 @@ fdt=""
netmap="no"
pixman=""
sdl=""
sdlabi="1.2"
virtfs=""
vnc="yes"
sparse="no"
@@ -205,6 +241,9 @@ mingw32="no"
gcov="no"
gcov_tool="gcov"
EXESUF=""
DSOSUF=".so"
LDFLAGS_SHARED="-shared"
modules="no"
prefix="/usr/local"
mandir="\${prefix}/share/man"
datadir="\${prefix}/share"
@@ -245,6 +284,8 @@ libusb=""
usb_redir=""
glx=""
zlib="yes"
lzo="no"
snappy="no"
guest_agent=""
guest_agent_with_vss="no"
vss_win32_sdk=""
@@ -264,6 +305,7 @@ gtkabi="2.0"
tpm="no"
libssh2=""
vhdx=""
quorum="no"
# parse CC options first
for opt do
@@ -325,6 +367,7 @@ query_pkg_config() {
}
pkg_config=query_pkg_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.
ARFLAGS="${ARFLAGS-rv}"
@@ -515,11 +558,10 @@ OpenBSD)
Darwin)
bsd="yes"
darwin="yes"
LDFLAGS_SHARED="-bundle -undefined dynamic_lookup"
if [ "$cpu" = "x86_64" ] ; then
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
LDFLAGS="-arch x86_64 $LDFLAGS"
else
QEMU_CFLAGS="-mdynamic-no-pic $QEMU_CFLAGS"
fi
cocoa="yes"
audio_drv_list="coreaudio"
@@ -610,6 +652,7 @@ fi
if test "$mingw32" = "yes" ; then
EXESUF=".exe"
DSOSUF=".dll"
QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS"
# enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later)
QEMU_CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS"
@@ -676,6 +719,9 @@ for opt do
;;
--disable-debug-info)
;;
--enable-modules)
modules="yes"
;;
--cpu=*)
;;
--target-list=*) target_list="$optarg"
@@ -731,6 +777,8 @@ for opt do
;;
--enable-sdl) sdl="yes"
;;
--with-sdlabi=*) sdlabi="$optarg"
;;
--disable-qom-cast-debug) qom_cast_debug="no"
;;
--enable-qom-cast-debug) qom_cast_debug="yes"
@@ -953,6 +1001,10 @@ for opt do
;;
--disable-zlib-test) zlib="no"
;;
--enable-lzo) lzo="yes"
;;
--enable-snappy) snappy="yes"
;;
--enable-guest-agent) guest_agent="yes"
;;
--disable-guest-agent) guest_agent="no"
@@ -1005,6 +1057,10 @@ for opt do
;;
--disable-vhdx) vhdx="no"
;;
--disable-quorum) quorum="no"
;;
--enable-quorum) quorum="yes"
;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@@ -1131,7 +1187,8 @@ Advanced options (experts only):
--libdir=PATH install libraries in PATH
--sysconfdir=PATH install config in PATH$confsuffix
--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
--disable-debug-tcg disable TCG debugging (default)
--enable-debug-info enable debugging information (default)
@@ -1143,6 +1200,7 @@ Advanced options (experts only):
--disable-werror disable compilation abort on warning
--disable-sdl disable SDL
--enable-sdl enable SDL
--with-sdlabi select preferred SDL ABI 1.2 or 2.0
--disable-gtk disable gtk UI
--enable-gtk enable gtk UI
--disable-virtfs disable VirtFS
@@ -1242,6 +1300,8 @@ Advanced options (experts only):
--enable-libusb enable libusb (for usb passthrough)
--disable-usb-redir disable 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
--enable-guest-agent enable building of the QEMU Guest Agent
--with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent
@@ -1261,6 +1321,8 @@ Advanced options (experts only):
--enable-libssh2 enable ssh block device support
--disable-vhdx disables 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
EOF
@@ -1289,6 +1351,35 @@ else
error_exit "\"$cc\" either does not exist or does not work"
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
# by default. Only enable by default for git builds
z_version=`cut -f3 -d. $source_path/VERSION`
@@ -1346,6 +1437,9 @@ if compile_prog "-Werror -fno-gcse" "" ; then
fi
if test "$static" = "yes" ; then
if test "$modules" = "yes" ; then
error_exit "static and modules are mutually incompatible"
fi
if test "$pie" = "yes" ; then
error_exit "static and pie are mutually incompatible"
else
@@ -1399,6 +1493,32 @@ EOF
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
##########################################
# __sync_fetch_and_and requires at least -march=i486. Many toolchains
# use i686 as default anyway, but for those that don't, an explicit
@@ -1550,7 +1670,43 @@ EOF
"Make sure to have the zlib libs and headers installed."
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
@@ -1804,12 +1960,22 @@ fi
# Look for sdl configuration program (pkg-config or sdl-config). Try
# 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
if $pkg_config sdl --exists; then
sdlconfig="$pkg_config sdl"
if test "`basename $sdl_config`" != $sdlconfigname && ! has ${sdl_config}; then
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'`
elif has ${sdl_config}; then
sdlconfig="$sdl_config"
@@ -1936,6 +2102,30 @@ EOF
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
if test "$vnc" = "yes" -a "$vnc_sasl" != "no" ; then
@@ -2118,13 +2308,21 @@ EOF
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
cat > $TMPC << EOF
#include <inttypes.h>
#include <net/if.h>
#include <net/netmap.h>
#include <net/netmap_user.h>
#if (NETMAP_API < 11) || (NETMAP_API > 15)
#error
#endif
int main(void) { return 0; }
EOF
if compile_prog "" "" ; then
@@ -2318,8 +2516,6 @@ EOF
curl_libs=`$curlconfig --libs 2>/dev/null`
if compile_prog "$curl_cflags" "$curl_libs" ; then
curl=yes
libs_tools="$curl_libs $libs_tools"
libs_softmmu="$curl_libs $libs_softmmu"
else
if test "$curl" = "yes" ; then
feature_not_found "curl" "Install libcurl devel"
@@ -2357,13 +2553,36 @@ if test "$mingw32" = yes; then
else
glib_req_ver=2.12
fi
if $pkg_config --atleast-version=$glib_req_ver gthread-2.0; then
glib_cflags=`$pkg_config --cflags gthread-2.0`
glib_libs=`$pkg_config --libs gthread-2.0`
LIBS="$glib_libs $LIBS"
libs_qga="$glib_libs $libs_qga"
else
error_exit "glib-$glib_req_ver required to compile QEMU"
glib_modules=gthread-2.0
if test "$modules" = yes; then
glib_modules="$glib_modules gmodule-2.0"
fi
for i in $glib_modules; do
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
##########################################
@@ -2474,8 +2693,6 @@ EOF
rbd_libs="-lrbd -lrados"
if compile_prog "" "$rbd_libs" ; then
rbd=yes
libs_tools="$rbd_libs $libs_tools"
libs_softmmu="$rbd_libs $libs_softmmu"
else
if test "$rbd" = "yes" ; then
feature_not_found "rados block device" "Install librbd/ceph devel"
@@ -2492,9 +2709,6 @@ if test "$libssh2" != "no" ; then
libssh2_cflags=`$pkg_config libssh2 --cflags`
libssh2_libs=`$pkg_config libssh2 --libs`
libssh2=yes
libs_tools="$libssh2_libs $libs_tools"
libs_softmmu="$libssh2_libs $libs_softmmu"
QEMU_CFLAGS="$QEMU_CFLAGS $libssh2_cflags"
else
if test "$libssh2" = "yes" ; then
error_exit "libssh2 >= $min_libssh2_version required for --enable-libssh2"
@@ -2540,8 +2754,6 @@ int main(void) { io_setup(0, NULL); io_set_eventfd(NULL, 0); eventfd(0, 0); retu
EOF
if compile_prog "" "-laio" ; then
linux_aio=yes
libs_softmmu="$libs_softmmu -laio"
libs_tools="$libs_tools -laio"
else
if test "$linux_aio" = "yes" ; then
feature_not_found "linux AIO" "Install libaio devel"
@@ -2710,9 +2922,6 @@ if test "$glusterfs" != "no" ; then
glusterfs="yes"
glusterfs_cflags=`$pkg_config --cflags 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
glusterfs_discard="yes"
fi
@@ -3083,11 +3292,9 @@ EOF
libiscsi="yes"
libiscsi_cflags=$($pkg_config --cflags libiscsi)
libiscsi_libs=$($pkg_config --libs libiscsi)
CFLAGS="$CFLAGS $libiscsi_cflags"
LIBS="$LIBS $libiscsi_libs"
elif compile_prog "" "-liscsi" ; then
libiscsi="yes"
LIBS="$LIBS -liscsi"
libiscsi_libs="-liscsi"
else
if test "$libiscsi" = "yes" ; then
feature_not_found "libiscsi" "Install libiscsi devel"
@@ -3688,6 +3895,7 @@ if test "$mingw32" = "yes" ; then
fi
qemu_confdir=$sysconfdir$confsuffix
qemu_moddir=$libdir$confsuffix
qemu_datadir=$datadir$confsuffix
qemu_localedir="$datadir/locale"
@@ -3778,6 +3986,7 @@ echo "Install prefix $prefix"
echo "BIOS directory `eval echo $qemu_datadir`"
echo "binary directory `eval echo $bindir`"
echo "library directory `eval echo $libdir`"
echo "module directory `eval echo $qemu_moddir`"
echo "libexec directory `eval echo $libexecdir`"
echo "include directory `eval echo $includedir`"
echo "config directory `eval echo $sysconfdir`"
@@ -3804,6 +4013,7 @@ echo "python $python"
if test "$slirp" = "yes" ; then
echo "smbd $smbd"
fi
echo "module support $modules"
echo "host CPU $cpu"
echo "host big endian $bigendian"
echo "target list $target_list"
@@ -3893,6 +4103,9 @@ echo "libssh2 support $libssh2"
echo "TPM passthrough $tpm_passthrough"
echo "QOM debugging $qom_cast_debug"
echo "vhdx $vhdx"
echo "Quorum $quorum"
echo "lzo support $lzo"
echo "snappy support $snappy"
if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -3916,6 +4129,7 @@ echo "sysconfdir=$sysconfdir" >> $config_host_mak
echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
echo "qemu_moddir=$qemu_moddir" >> $config_host_mak
if test "$mingw32" = "no" ; then
echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
fi
@@ -4048,6 +4262,12 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
if [ "$docs" = "yes" ] ; then
echo "BUILD_DOCS=yes" >> $config_host_mak
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
echo "CONFIG_SDL=y" >> $config_host_mak
echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak
@@ -4119,8 +4339,9 @@ if test "$bswap_h" = "yes" ; then
echo "CONFIG_MACHINE_BSWAP_H=y" >> $config_host_mak
fi
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_LIBS=$curl_libs" >> $config_host_mak
fi
if test "$brlapi" = "yes" ; then
echo "CONFIG_BRLAPI=y" >> $config_host_mak
@@ -4208,11 +4429,21 @@ if test "$glx" = "yes" ; then
echo "GLX_LIBS=$glx_libs" >> $config_host_mak
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
echo "CONFIG_LIBISCSI=y" >> $config_host_mak
echo "CONFIG_LIBISCSI=m" >> $config_host_mak
if test "$libiscsi_version" = "1.4.0"; then
echo "CONFIG_LIBISCSI_1_4=y" >> $config_host_mak
fi
echo "LIBISCSI_CFLAGS=$libiscsi_cflags" >> $config_host_mak
echo "LIBISCSI_LIBS=$libiscsi_libs" >> $config_host_mak
fi
if test "$libnfs" = "yes" ; then
@@ -4237,7 +4468,9 @@ if test "$qom_cast_debug" = "yes" ; then
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
fi
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
echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
@@ -4280,7 +4513,9 @@ if test "$getauxval" = "yes" ; then
fi
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
if test "$glusterfs_discard" = "yes" ; then
@@ -4292,7 +4527,13 @@ if test "$glusterfs_zerofill" = "yes" ; then
fi
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
if test "$virtio_blk_data_plane" = "yes" ; then
@@ -4423,6 +4664,8 @@ echo "LIBTOOLFLAGS=$LIBTOOLFLAGS" >> $config_host_mak
echo "LIBS+=$LIBS" >> $config_host_mak
echo "LIBS_TOOLS+=$libs_tools" >> $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 "POD2MAN=$POD2MAN" >> $config_host_mak
echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak

View File

@@ -477,7 +477,7 @@ int cpu_exec(CPUArchState *env)
}
#elif defined(TARGET_ARM)
if (interrupt_request & CPU_INTERRUPT_FIQ
&& !(env->uncached_cpsr & CPSR_F)) {
&& !(env->daif & PSTATE_F)) {
env->exception_index = EXCP_FIQ;
cc->do_interrupt(cpu);
next_tb = 0;
@@ -493,7 +493,7 @@ int cpu_exec(CPUArchState *env)
pc contains a magic address. */
if (interrupt_request & CPU_INTERRUPT_HARD
&& ((IS_M(env) && env->regs[15] < 0xfffffff0)
|| !(env->uncached_cpsr & CPSR_I))) {
|| !(env->daif & PSTATE_I))) {
env->exception_index = EXCP_IRQ;
cc->do_interrupt(cpu);
next_tb = 0;

View File

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

View File

@@ -10,6 +10,7 @@ CONFIG_EMPTY_SLOT=y
CONFIG_PCNET_COMMON=y
CONFIG_LANCE=y
CONFIG_TCX=y
CONFIG_CG3=y
CONFIG_SLAVIO=y
CONFIG_CS4231=y
CONFIG_GRLIB=y

View File

@@ -225,6 +225,45 @@ Data:
"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
-----

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:
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
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:
qemu ..... -incoming x-rdma:host:port
qemu ..... -incoming rdma:host:port
Finally, perform the actual migration on the source machine:
QEMU Monitor Command:
$ migrate -d x-rdma:host:port
$ migrate -d rdma:host:port
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
infiniband link:
1. x-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
1. rdma-pin-all disabled total time: approximately 7.5 seconds @ 9.5 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
you have to migrate using RDMA.
@@ -407,18 +407,14 @@ socket is broken during a non-RDMA based migration.
TODO:
=====
1. 'migrate x-rdma:host:port' and '-incoming x-rdma' options will be
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
1. Currently, 'ulimit -l' mlock() limits as well as cgroups swap limits
are not compatible with infinband memory pinning and will result in
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.
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.
5. Move UNREGISTER requests to a separate thread.
6. Use LRU to provide more fine-grained direction of UNREGISTER
4. Use LRU to provide more fine-grained direction of UNREGISTER
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.

960
dump.c

File diff suppressed because it is too large Load Diff

4
exec.c
View File

@@ -17,9 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#ifdef _WIN32
#include <windows.h>
#else
#ifndef _WIN32
#include <sys/types.h>
#include <sys/mman.h>
#endif

5
hmp.c
View File

@@ -1311,8 +1311,11 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
const char *file = qdict_get_str(qdict, "filename");
bool has_begin = qdict_haskey(qdict, "begin");
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 length = 0;
enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
char *prot;
if (has_begin) {
@@ -1325,7 +1328,7 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
prot = g_strconcat("file:", file, NULL);
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
&errp);
has_format, dump_format, &errp);
hmp_handle_error(mon, &errp);
g_free(prot);
}

View File

@@ -92,8 +92,6 @@
#define MP_ETH_CRDP3 0x4AC
#define MP_ETH_CTDP0 0x4E0
#define MP_ETH_CTDP1 0x4E4
#define MP_ETH_CTDP2 0x4E8
#define MP_ETH_CTDP3 0x4EC
/* MII PHY access */
#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:
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];
default:
@@ -362,7 +360,7 @@ static void mv88w8618_eth_write(void *opaque, hwaddr offset,
s->cur_rx[(offset - MP_ETH_CRDP0)/4] = value;
break;
case MP_ETH_CTDP0 ... MP_ETH_CTDP3:
case MP_ETH_CTDP0 ... MP_ETH_CTDP1:
s->tx_queue[(offset - MP_ETH_CTDP0)/4] = value;
break;
}
@@ -632,7 +630,7 @@ static int musicpal_lcd_init(SysBusDevice *sbd)
"musicpal-lcd", MP_LCD_SIZE);
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);
qdev_init_gpio_in(dev, musicpal_lcd_gpio_brightness_in, 3);

View File

@@ -272,11 +272,11 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
goto message;
case 3:
s->cpu->env.uncached_cpsr =
ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC;
s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
s->cpu->env.cp15.c1_sys = 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->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */

View File

@@ -483,7 +483,18 @@ static void qemu_aio_complete(void *opaque, int ret)
ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
ioreq_unmap(ioreq);
ioreq_finish(ioreq);
bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
switch (ioreq->req.operation) {
case BLKIF_OP_WRITE:
case BLKIF_OP_FLUSH_DISKCACHE:
if (!ioreq->req.nr_segments) {
break;
}
case BLKIF_OP_READ:
bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
break;
default:
break;
}
qemu_bh_schedule(ioreq->blkdev->bh);
}
@@ -813,8 +824,8 @@ static int blk_connect(struct XenDevice *xendev)
Error *local_err = NULL;
BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto,
readonly);
if (bdrv_open(blkdev->bs,
blkdev->filename, NULL, qflags, drv, &local_err) != 0)
if (bdrv_open(&blkdev->bs, blkdev->filename, NULL, NULL, qflags,
drv, &local_err) != 0)
{
xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
error_get_pretty(local_err));

View File

@@ -28,6 +28,7 @@ obj-$(CONFIG_OMAP) += omap_lcdc.o
obj-$(CONFIG_PXA2XX) += pxa2xx_lcd.o
obj-$(CONFIG_SM501) += sm501.o
obj-$(CONFIG_TCX) += tcx.o
obj-$(CONFIG_CG3) += cg3.o
obj-$(CONFIG_VGA) += vga.o

View File

@@ -956,7 +956,7 @@ void *s1d13745_init(qemu_irq gpio_int)
s->fb = g_malloc(0x180000);
s->con = graphic_console_init(NULL, &blizzard_ops, s);
s->con = graphic_console_init(NULL, 0, &blizzard_ops, s);
surface = qemu_console_surface(s->con);
switch (surface_bits_per_pixel(surface)) {

385
hw/display/cg3.c Normal file
View File

@@ -0,0 +1,385 @@
/*
* QEMU CG3 Frame buffer
*
* Copyright (c) 2012 Bob Breuer
* Copyright (c) 2013 Mark Cave-Ayland
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "ui/console.h"
#include "hw/sysbus.h"
#include "hw/loader.h"
/* Change to 1 to enable debugging */
#define DEBUG_CG3 0
#define CG3_ROM_FILE "QEMU,cgthree.bin"
#define FCODE_MAX_ROM_SIZE 0x10000
#define CG3_REG_SIZE 0x20
#define CG3_REG_BT458_ADDR 0x0
#define CG3_REG_BT458_COLMAP 0x4
#define CG3_REG_FBC_CTRL 0x10
#define CG3_REG_FBC_STATUS 0x11
#define CG3_REG_FBC_CURSTART 0x12
#define CG3_REG_FBC_CUREND 0x13
#define CG3_REG_FBC_VCTRL 0x14
/* Control register flags */
#define CG3_CR_ENABLE_INTS 0x80
/* Status register flags */
#define CG3_SR_PENDING_INT 0x80
#define CG3_SR_1152_900_76_B 0x60
#define CG3_SR_ID_COLOR 0x01
#define CG3_VRAM_SIZE 0x100000
#define CG3_VRAM_OFFSET 0x800000
#define DPRINTF(fmt, ...) do { \
if (DEBUG_CG3) { \
printf("CG3: " fmt , ## __VA_ARGS__); \
} \
} while (0);
#define TYPE_CG3 "cgthree"
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)
typedef struct CG3State {
SysBusDevice parent_obj;
QemuConsole *con;
qemu_irq irq;
hwaddr prom_addr;
MemoryRegion vram_mem;
MemoryRegion rom;
MemoryRegion reg;
uint32_t vram_size;
int full_update;
uint8_t regs[16];
uint8_t r[256], g[256], b[256];
uint16_t width, height, depth;
uint8_t dac_index, dac_state;
} CG3State;
static void cg3_update_display(void *opaque)
{
CG3State *s = opaque;
DisplaySurface *surface = qemu_console_surface(s->con);
const uint8_t *pix;
uint32_t *data;
uint32_t dval;
int x, y, y_start;
unsigned int width, height;
ram_addr_t page, page_min, page_max;
if (surface_bits_per_pixel(surface) != 32) {
return;
}
width = s->width;
height = s->height;
y_start = -1;
page_min = -1;
page_max = 0;
page = 0;
pix = memory_region_get_ram_ptr(&s->vram_mem);
data = (uint32_t *)surface_data(surface);
for (y = 0; y < height; y++) {
int update = s->full_update;
page = (y * width) & TARGET_PAGE_MASK;
update |= memory_region_get_dirty(&s->vram_mem, page, page + width,
DIRTY_MEMORY_VGA);
if (update) {
if (y_start < 0) {
y_start = y;
}
if (page < page_min) {
page_min = page;
}
if (page > page_max) {
page_max = page;
}
for (x = 0; x < width; x++) {
dval = *pix++;
dval = (s->r[dval] << 16) | (s->g[dval] << 8) | s->b[dval];
*data++ = dval;
}
} else {
if (y_start >= 0) {
dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
y_start = -1;
}
pix += width;
data += width;
}
}
s->full_update = 0;
if (y_start >= 0) {
dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
}
if (page_max >= page_min) {
memory_region_reset_dirty(&s->vram_mem,
page_min, page_max - page_min + TARGET_PAGE_SIZE,
DIRTY_MEMORY_VGA);
}
/* vsync interrupt? */
if (s->regs[0] & CG3_CR_ENABLE_INTS) {
s->regs[1] |= CG3_SR_PENDING_INT;
qemu_irq_raise(s->irq);
}
}
static void cg3_invalidate_display(void *opaque)
{
CG3State *s = opaque;
memory_region_set_dirty(&s->vram_mem, 0, CG3_VRAM_SIZE);
}
static uint64_t cg3_reg_read(void *opaque, hwaddr addr, unsigned size)
{
CG3State *s = opaque;
int val;
switch (addr) {
case CG3_REG_BT458_ADDR:
case CG3_REG_BT458_COLMAP:
val = 0;
break;
case CG3_REG_FBC_CTRL:
val = s->regs[0];
break;
case CG3_REG_FBC_STATUS:
/* monitor ID 6, board type = 1 (color) */
val = s->regs[1] | CG3_SR_1152_900_76_B | CG3_SR_ID_COLOR;
break;
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE:
val = s->regs[addr - 0x10];
break;
default:
qemu_log_mask(LOG_UNIMP,
"cg3: Unimplemented register read "
"reg 0x%" HWADDR_PRIx " size 0x%x\n",
addr, size);
val = 0;
break;
}
DPRINTF("read %02x from reg %" HWADDR_PRIx "\n", val, addr);
return val;
}
static void cg3_reg_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
CG3State *s = opaque;
uint8_t regval;
int i;
DPRINTF("write %" PRIx64 " to reg %" HWADDR_PRIx " size %d\n",
val, addr, size);
switch (addr) {
case CG3_REG_BT458_ADDR:
s->dac_index = val;
s->dac_state = 0;
break;
case CG3_REG_BT458_COLMAP:
/* This register can be written to as either a long word or a byte */
if (size == 1) {
val <<= 24;
}
for (i = 0; i < size; i++) {
regval = val >> 24;
switch (s->dac_state) {
case 0:
s->r[s->dac_index] = regval;
s->dac_state++;
break;
case 1:
s->g[s->dac_index] = regval;
s->dac_state++;
break;
case 2:
s->b[s->dac_index] = regval;
/* Index autoincrement */
s->dac_index = (s->dac_index + 1) & 0xff;
default:
s->dac_state = 0;
break;
}
val <<= 8;
}
s->full_update = 1;
break;
case CG3_REG_FBC_CTRL:
s->regs[0] = val;
break;
case CG3_REG_FBC_STATUS:
if (s->regs[1] & CG3_SR_PENDING_INT) {
/* clear interrupt */
s->regs[1] &= ~CG3_SR_PENDING_INT;
qemu_irq_lower(s->irq);
}
break;
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE:
s->regs[addr - 0x10] = val;
break;
default:
qemu_log_mask(LOG_UNIMP,
"cg3: Unimplemented register write "
"reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
addr, size, val);
break;
}
}
static const MemoryRegionOps cg3_reg_ops = {
.read = cg3_reg_read,
.write = cg3_reg_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 4,
},
};
static const GraphicHwOps cg3_ops = {
.invalidate = cg3_invalidate_display,
.gfx_update = cg3_update_display,
};
static void cg3_realizefn(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
CG3State *s = CG3(dev);
int ret;
char *fcode_filename;
/* FCode ROM */
memory_region_init_ram(&s->rom, NULL, "cg3.prom", FCODE_MAX_ROM_SIZE);
vmstate_register_ram_global(&s->rom);
memory_region_set_readonly(&s->rom, true);
sysbus_init_mmio(sbd, &s->rom);
fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, CG3_ROM_FILE);
if (fcode_filename) {
ret = load_image_targphys(fcode_filename, s->prom_addr,
FCODE_MAX_ROM_SIZE);
if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
error_report("cg3: could not load prom '%s'", CG3_ROM_FILE);
}
}
memory_region_init_io(&s->reg, NULL, &cg3_reg_ops, s, "cg3.reg",
CG3_REG_SIZE);
sysbus_init_mmio(sbd, &s->reg);
memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size);
vmstate_register_ram_global(&s->vram_mem);
sysbus_init_mmio(sbd, &s->vram_mem);
sysbus_init_irq(sbd, &s->irq);
s->con = graphic_console_init(DEVICE(dev), 0, &cg3_ops, s);
qemu_console_resize(s->con, s->width, s->height);
}
static int vmstate_cg3_post_load(void *opaque, int version_id)
{
CG3State *s = opaque;
cg3_invalidate_display(s);
return 0;
}
static const VMStateDescription vmstate_cg3 = {
.name = "cg3",
.version_id = 1,
.minimum_version_id = 1,
.post_load = vmstate_cg3_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT16(height, CG3State),
VMSTATE_UINT16(width, CG3State),
VMSTATE_UINT16(depth, CG3State),
VMSTATE_BUFFER(r, CG3State),
VMSTATE_BUFFER(g, CG3State),
VMSTATE_BUFFER(b, CG3State),
VMSTATE_UINT8(dac_index, CG3State),
VMSTATE_UINT8(dac_state, CG3State),
VMSTATE_END_OF_LIST()
}
};
static void cg3_reset(DeviceState *d)
{
CG3State *s = CG3(d);
/* Initialize palette */
memset(s->r, 0, 256);
memset(s->g, 0, 256);
memset(s->b, 0, 256);
s->dac_state = 0;
s->full_update = 1;
qemu_irq_lower(s->irq);
}
static Property cg3_properties[] = {
DEFINE_PROP_UINT32("vram-size", CG3State, vram_size, -1),
DEFINE_PROP_UINT16("width", CG3State, width, -1),
DEFINE_PROP_UINT16("height", CG3State, height, -1),
DEFINE_PROP_UINT16("depth", CG3State, depth, -1),
DEFINE_PROP_UINT64("prom-addr", CG3State, prom_addr, -1),
DEFINE_PROP_END_OF_LIST(),
};
static void cg3_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = cg3_realizefn;
dc->reset = cg3_reset;
dc->vmsd = &vmstate_cg3;
dc->props = cg3_properties;
}
static const TypeInfo cg3_info = {
.name = TYPE_CG3,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CG3State),
.class_init = cg3_class_init,
};
static void cg3_register_types(void)
{
type_register_static(&cg3_info);
}
type_init(cg3_register_types)

View File

@@ -2917,7 +2917,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp)
cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0,
isa_address_space(isadev),
isa_address_space_io(isadev));
s->con = graphic_console_init(dev, s->hw_ops, s);
s->con = graphic_console_init(dev, 0, s->hw_ops, s);
rom_add_vga(VGABIOS_CIRRUS_FILENAME);
/* XXX ISA-LFB support */
/* FIXME not qdev yet */
@@ -2963,7 +2963,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
vga_common_init(&s->vga, OBJECT(dev));
cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev),
pci_address_space_io(dev));
s->vga.con = graphic_console_init(DEVICE(dev), s->vga.hw_ops, &s->vga);
s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga);
/* setup PCI */

View File

@@ -1917,7 +1917,7 @@ static int exynos4210_fimd_init(SysBusDevice *dev)
memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_fimd_mmio_ops, s,
"exynos4210.fimd", FIMD_REGS_SIZE);
sysbus_init_mmio(dev, &s->iomem);
s->console = graphic_console_init(DEVICE(dev), &exynos4210_fimd_ops, s);
s->console = graphic_console_init(DEVICE(dev), 0, &exynos4210_fimd_ops, s);
return 0;
}

View File

@@ -484,7 +484,7 @@ static void g364fb_init(DeviceState *dev, G364State *s)
{
s->vram = g_malloc0(s->vram_size);
s->con = graphic_console_init(dev, &g364fb_ops, s);
s->con = graphic_console_init(dev, 0, &g364fb_ops, s);
memory_region_init_io(&s->mem_ctrl, NULL, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram",

View File

@@ -271,7 +271,7 @@ static int jazz_led_init(SysBusDevice *dev)
memory_region_init_io(&s->iomem, OBJECT(s), &led_ops, s, "led", 1);
sysbus_init_mmio(dev, &s->iomem);
s->con = graphic_console_init(DEVICE(dev), &jazz_led_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, &jazz_led_ops, s);
return 0;
}

View File

@@ -290,7 +290,7 @@ static int milkymist_vgafb_init(SysBusDevice *dev)
"milkymist-vgafb", R_MAX * 4);
sysbus_init_mmio(dev, &s->regs_region);
s->con = graphic_console_init(DEVICE(dev), &vgafb_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, &vgafb_ops, s);
return 0;
}

View File

@@ -406,7 +406,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
memory_region_init_io(&s->iomem, NULL, &omap_lcdc_ops, s, "omap.lcdc", 0x100);
memory_region_add_subregion(sysmem, base, &s->iomem);
s->con = graphic_console_init(NULL, &omap_ops, s);
s->con = graphic_console_init(NULL, 0, &omap_ops, s);
return s;
}

View File

@@ -464,7 +464,7 @@ static int pl110_initfn(SysBusDevice *sbd)
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq);
qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1);
s->con = graphic_console_init(dev, &pl110_gfx_ops, s);
s->con = graphic_console_init(dev, 0, &pl110_gfx_ops, s);
return 0;
}

View File

@@ -1013,7 +1013,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
"pxa2xx-lcd-controller", 0x00100000);
memory_region_add_subregion(sysmem, base, &s->iomem);
s->con = graphic_console_init(NULL, &pxa2xx_ops, s);
s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
surface = qemu_console_surface(s->con);
switch (surface_bits_per_pixel(surface)) {

View File

@@ -1429,7 +1429,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
return 1;
}
static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
static void qxl_set_mode(PCIQXLDevice *d, unsigned int modenr, int loadvm)
{
pcibus_t start = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
pcibus_t end = d->pci.io_regions[QXL_RAM_RANGE_INDEX].size + start;
@@ -1439,6 +1439,12 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
.mem_start = start,
.mem_end = end
};
if (modenr >= d->modes->n_modes) {
qxl_set_guest_bug(d, "mode number out of range");
return;
}
QXLSurfaceCreate surface = {
.width = mode->x_res,
.height = mode->y_res,
@@ -2063,7 +2069,7 @@ static int qxl_init_primary(PCIDevice *dev)
portio_list_set_flush_coalesced(qxl_vga_port_list);
portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
vga->con = graphic_console_init(DEVICE(dev), &qxl_ops, qxl);
vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
qemu_spice_display_init_common(&qxl->ssd);
rc = qxl_init_common(qxl);
@@ -2088,7 +2094,7 @@ static int qxl_init_secondary(PCIDevice *dev)
qxl->vga.vram_size);
vmstate_register_ram(&qxl->vga.vram, &qxl->pci.qdev);
qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
qxl->vga.con = graphic_console_init(DEVICE(dev), &qxl_ops, qxl);
qxl->vga.con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
return qxl_init_common(qxl);
}

View File

@@ -1449,5 +1449,5 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
}
/* create qemu graphic console */
s->con = graphic_console_init(DEVICE(dev), &sm501_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, &sm501_ops, s);
}

View File

@@ -299,7 +299,7 @@ static int ssd0303_init(I2CSlave *i2c)
{
ssd0303_state *s = SSD0303(i2c);
s->con = graphic_console_init(DEVICE(i2c), &ssd0303_ops, s);
s->con = graphic_console_init(DEVICE(i2c), 0, &ssd0303_ops, s);
qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
return 0;
}

View File

@@ -342,7 +342,7 @@ static int ssd0323_init(SSISlave *dev)
s->col_end = 63;
s->row_end = 79;
s->con = graphic_console_init(DEVICE(dev), &ssd0323_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, &ssd0323_ops, s);
qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);

View File

@@ -587,7 +587,7 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
s->scr_width = 480;
s->scr_height = 640;
s->con = graphic_console_init(NULL, &tc6393xb_gfx_ops, s);
s->con = graphic_console_init(NULL, 0, &tc6393xb_gfx_ops, s);
return s;
}

View File

@@ -602,14 +602,14 @@ static int tcx_init1(SysBusDevice *dev)
&s->vram_mem, vram_offset, size);
sysbus_init_mmio(dev, &s->vram_cplane);
s->con = graphic_console_init(DEVICE(dev), &tcx24_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, &tcx24_ops, s);
} else {
/* THC 8 bit (dummy) */
memory_region_init_io(&s->thc8, OBJECT(s), &dummy_ops, s, "tcx.thc8",
TCX_THC_NREGS_8);
sysbus_init_mmio(dev, &s->thc8);
s->con = graphic_console_init(DEVICE(dev), &tcx_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, &tcx_ops, s);
}
qemu_console_resize(s->con, s->width, s->height);

View File

@@ -135,7 +135,7 @@ int isa_vga_mm_init(hwaddr vram_base,
vga_common_init(&s->vga, NULL);
vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
s->vga.con = graphic_console_init(NULL, s->vga.hw_ops, s);
s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s);
vga_init_vbe(&s->vga, NULL, address_space);
return 0;

View File

@@ -67,7 +67,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
isa_mem_base + 0x000a0000,
vga_io_memory, 1);
memory_region_set_coalescing(vga_io_memory);
s->con = graphic_console_init(DEVICE(dev), s->hw_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
vga_init_vbe(s, OBJECT(dev), isa_address_space(isadev));
/* ROM BIOS */

View File

@@ -151,7 +151,7 @@ static int pci_std_vga_initfn(PCIDevice *dev)
vga_init(s, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev),
true);
s->con = graphic_console_init(DEVICE(dev), s->hw_ops, s);
s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
/* XXX: VGA_RAM_SIZE must be a power of two */
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);

View File

@@ -1199,7 +1199,7 @@ static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s,
s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = g_malloc(s->scratch_size * 4);
s->vga.con = graphic_console_init(dev, &vmsvga_ops, s);
s->vga.con = graphic_console_init(dev, 0, &vmsvga_ops, s);
s->fifo_size = SVGA_FIFO_SIZE;
memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size);

View File

@@ -227,7 +227,8 @@ static const VMStateDescription vmstate_pl330_queue = {
};
struct PL330State {
SysBusDevice busdev;
SysBusDevice parent_obj;
MemoryRegion iomem;
qemu_irq irq_abort;
qemu_irq *irq;
@@ -577,7 +578,7 @@ static inline void pl330_queue_remove_tagged(PL330Queue *s, uint8_t tag)
static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
{
DB_PRINT("ch: %p, flags: %x\n", ch, flags);
DB_PRINT("ch: %p, flags: %" PRIx32 "\n", ch, flags);
ch->fault_type |= flags;
if (ch->state == pl330_chan_fault) {
return;
@@ -600,10 +601,12 @@ static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
* LEN - number of elements in ARGS array
*/
static void pl330_dmaaddh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
static void pl330_dmaadxh(PL330Chan *ch, uint8_t *args, bool ra, bool neg)
{
uint16_t im = (((uint16_t)args[1]) << 8) | ((uint16_t)args[0]);
uint8_t ra = (opcode >> 1) & 1;
uint32_t im = (args[1] << 8) | args[0];
if (neg) {
im |= 0xffffu << 16;
}
if (ch->is_manager) {
pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
@@ -616,6 +619,16 @@ static void pl330_dmaaddh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
}
}
static void pl330_dmaaddh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
{
pl330_dmaadxh(ch, args, extract32(opcode, 1, 1), false);
}
static void pl330_dmaadnh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
{
pl330_dmaadxh(ch, args, extract32(opcode, 1, 1), true);
}
static void pl330_dmaend(PL330Chan *ch, uint8_t opcode,
uint8_t *args, int len)
{
@@ -723,7 +736,8 @@ static void pl330_dmald(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
ch->stall = pl330_queue_put_insn(&ch->parent->read_queue, ch->src,
size, num, inc, 0, ch->tag);
if (!ch->stall) {
DB_PRINT("channel:%d address:%08x size:%d num:%d %c\n",
DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
" num:%" PRId32 " %c\n",
ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
ch->src += inc ? size * num - (ch->src & (size - 1)) : 0;
}
@@ -868,9 +882,10 @@ static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
}
if (ch->parent->inten & (1 << ev_id)) {
ch->parent->int_status |= (1 << ev_id);
DB_PRINT("event interrupt raised %d\n", ev_id);
DB_PRINT("event interrupt raised %" PRId8 "\n", ev_id);
qemu_irq_raise(ch->parent->irq[ev_id]);
}
DB_PRINT("event raised %" PRId8 "\n", ev_id);
ch->parent->ev_status |= (1 << ev_id);
}
@@ -895,7 +910,8 @@ static void pl330_dmast(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
ch->stall = pl330_queue_put_insn(&ch->parent->write_queue, ch->dst,
size, num, inc, 0, ch->tag);
if (!ch->stall) {
DB_PRINT("channel:%d address:%08x size:%d num:%d %c\n",
DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
" num:%" PRId32 " %c\n",
ch->tag, ch->dst, size, num, inc ? 'Y' : 'N');
ch->dst += inc ? size * num - (ch->dst & (size - 1)) : 0;
}
@@ -972,6 +988,7 @@ static void pl330_dmawfe(PL330Chan *ch, uint8_t opcode,
}
}
ch->parent->ev_status &= ~(1 << ev_id);
DB_PRINT("event lowered %" PRIx8 "\n", ev_id);
} else {
ch->stall = 1;
}
@@ -1037,6 +1054,7 @@ static void pl330_dmawmb(PL330Chan *ch, uint8_t opcode,
/* NULL terminated array of the instruction descriptions. */
static const PL330InsnDesc insn_desc[] = {
{ .opcode = 0x54, .opmask = 0xFD, .size = 3, .exec = pl330_dmaaddh, },
{ .opcode = 0x5c, .opmask = 0xFD, .size = 3, .exec = pl330_dmaadnh, },
{ .opcode = 0x00, .opmask = 0xFF, .size = 1, .exec = pl330_dmaend, },
{ .opcode = 0x35, .opmask = 0xFF, .size = 2, .exec = pl330_dmaflushp, },
{ .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago, },
@@ -1108,7 +1126,6 @@ static int pl330_chan_exec(PL330Chan *ch)
ch->state != pl330_chan_waiting_periph &&
ch->state != pl330_chan_at_barrier &&
ch->state != pl330_chan_waiting_event) {
DB_PRINT("%d\n", ch->state);
return 0;
}
ch->stall = 0;
@@ -1155,7 +1172,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
dma_memory_read(&address_space_memory, q->addr, buf, len);
if (PL330_ERR_DEBUG > 1) {
DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
DB_PRINT("PL330 read from memory @%08" PRIx32 " (size = %08x):\n",
q->addr, len);
qemu_hexdump((char *)buf, stderr, "", len);
}
@@ -1187,8 +1204,8 @@ static int pl330_exec_cycle(PL330Chan *channel)
if (fifo_res == PL330_FIFO_OK || q->z) {
dma_memory_write(&address_space_memory, q->addr, buf, len);
if (PL330_ERR_DEBUG > 1) {
DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
q->addr, len);
DB_PRINT("PL330 read from memory @%08" PRIx32
" (size = %08x):\n", q->addr, len);
qemu_hexdump((char *)buf, stderr, "", len);
}
if (q->inc) {
@@ -1277,7 +1294,7 @@ static void pl330_debug_exec(PL330State *s)
args[2] = (s->dbg[1] >> 8) & 0xff;
args[3] = (s->dbg[1] >> 16) & 0xff;
args[4] = (s->dbg[1] >> 24) & 0xff;
DB_PRINT("chan id: %d\n", chan_id);
DB_PRINT("chan id: %" PRIx8 "\n", chan_id);
if (s->dbg[0] & 1) {
ch = &s->chan[chan_id];
} else {
@@ -1311,7 +1328,7 @@ static void pl330_iomem_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
PL330State *s = (PL330State *) opaque;
uint32_t i;
int i;
DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset, (unsigned)value);
@@ -1467,8 +1484,8 @@ static inline uint32_t pl330_iomem_read_imp(void *opaque,
static uint64_t pl330_iomem_read(void *opaque, hwaddr offset,
unsigned size)
{
int ret = pl330_iomem_read_imp(opaque, offset);
DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset, ret);
uint32_t ret = pl330_iomem_read_imp(opaque, offset);
DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset, ret);
return ret;
}
@@ -1554,7 +1571,7 @@ static void pl330_realize(DeviceState *dev, Error **errp)
s->cfg[1] |= 5;
break;
default:
error_setg(errp, "Bad value for i-cache_len property: %d\n",
error_setg(errp, "Bad value for i-cache_len property: %" PRIx8 "\n",
s->i_cache_len);
return;
}
@@ -1589,7 +1606,7 @@ static void pl330_realize(DeviceState *dev, Error **errp)
s->cfg[CFG_CRD] |= 0x4;
break;
default:
error_setg(errp, "Bad value for data_width property: %d\n",
error_setg(errp, "Bad value for data_width property: %" PRIx8 "\n",
s->data_width);
return;
}
@@ -1602,7 +1619,7 @@ static void pl330_realize(DeviceState *dev, Error **errp)
pl330_queue_init(&s->read_queue, s->rd_q_dep, s);
pl330_queue_init(&s->write_queue, s->wr_q_dep, s);
pl330_fifo_init(&s->fifo, s->data_buffer_dep);
pl330_fifo_init(&s->fifo, s->data_width / 4 * s->data_buffer_dep);
}
static Property pl330_properties[] = {

View File

@@ -743,6 +743,7 @@ static void assign_failed_examine(AssignedDevice *dev)
goto fail;
}
driver[r] = 0;
ns = strrchr(driver, '/');
if (!ns) {
goto fail;

View File

@@ -167,7 +167,7 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
return 0;
}
static int pci_piix3_xen_ide_unplug(DeviceState *dev)
int pci_piix3_xen_ide_unplug(DeviceState *dev)
{
PCIIDEState *pci_ide;
DriveInfo *di;
@@ -266,7 +266,6 @@ static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
k->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->unplug = pci_piix3_xen_ide_unplug;
}
static const TypeInfo piix3_ide_xen_info = {

View File

@@ -25,3 +25,4 @@ obj-$(CONFIG_SH4) += sh_intc.o
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_XICS_KVM) += xics_kvm.o
obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
obj-$(CONFIG_S390_FLIC) += s390_flic.o

View File

@@ -3,6 +3,7 @@
*
* Copyright (c) 2012 Linaro Limited
* Written by Peter Maydell
* Save/Restore logic added by Christoffer Dall.
*
* 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
@@ -23,6 +24,20 @@
#include "kvm_arm.h"
#include "gic_internal.h"
//#define DEBUG_GIC_KVM
#ifdef DEBUG_GIC_KVM
static const int debug_gic_kvm = 1;
#else
static const int debug_gic_kvm = 0;
#endif
#define DPRINTF(fmt, ...) do { \
if (debug_gic_kvm) { \
printf("arm_gic: " fmt , ## __VA_ARGS__); \
} \
} while (0)
#define TYPE_KVM_ARM_GIC "kvm-arm-gic"
#define KVM_ARM_GIC(obj) \
OBJECT_CHECK(GICState, (obj), TYPE_KVM_ARM_GIC)
@@ -72,14 +87,419 @@ static void kvm_arm_gic_set_irq(void *opaque, int irq, int level)
kvm_set_irq(kvm_state, kvm_irq, !!level);
}
static bool kvm_arm_gic_can_save_restore(GICState *s)
{
return s->dev_fd >= 0;
}
static void kvm_gic_access(GICState *s, int group, int offset,
int cpu, uint32_t *val, bool write)
{
struct kvm_device_attr attr;
int type;
int err;
cpu = cpu & 0xff;
attr.flags = 0;
attr.group = group;
attr.attr = (((uint64_t)cpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) &
KVM_DEV_ARM_VGIC_CPUID_MASK) |
(((uint64_t)offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) &
KVM_DEV_ARM_VGIC_OFFSET_MASK);
attr.addr = (uintptr_t)val;
if (write) {
type = KVM_SET_DEVICE_ATTR;
} else {
type = KVM_GET_DEVICE_ATTR;
}
err = kvm_device_ioctl(s->dev_fd, type, &attr);
if (err < 0) {
fprintf(stderr, "KVM_{SET/GET}_DEVICE_ATTR failed: %s\n",
strerror(-err));
abort();
}
}
static void kvm_gicd_access(GICState *s, int offset, int cpu,
uint32_t *val, bool write)
{
kvm_gic_access(s, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
offset, cpu, val, write);
}
static void kvm_gicc_access(GICState *s, int offset, int cpu,
uint32_t *val, bool write)
{
kvm_gic_access(s, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
offset, cpu, val, write);
}
#define for_each_irq_reg(_ctr, _max_irq, _field_width) \
for (_ctr = 0; _ctr < ((_max_irq) / (32 / (_field_width))); _ctr++)
/*
* Translate from the in-kernel field for an IRQ value to/from the qemu
* representation.
*/
typedef void (*vgic_translate_fn)(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel);
/* synthetic translate function used for clear/set registers to completely
* clear a setting using a clear-register before setting the remaing bits
* using a set-register */
static void translate_clear(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
if (to_kernel) {
*field = ~0;
} else {
/* does not make sense: qemu model doesn't use set/clear regs */
abort();
}
}
static void translate_enabled(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
if (to_kernel) {
*field = GIC_TEST_ENABLED(irq, cm);
} else {
if (*field & 1) {
GIC_SET_ENABLED(irq, cm);
}
}
}
static void translate_pending(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
if (to_kernel) {
*field = gic_test_pending(s, irq, cm);
} else {
if (*field & 1) {
GIC_SET_PENDING(irq, cm);
/* TODO: Capture is level-line is held high in the kernel */
}
}
}
static void translate_active(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
if (to_kernel) {
*field = GIC_TEST_ACTIVE(irq, cm);
} else {
if (*field & 1) {
GIC_SET_ACTIVE(irq, cm);
}
}
}
static void translate_trigger(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
if (to_kernel) {
*field = (GIC_TEST_EDGE_TRIGGER(irq)) ? 0x2 : 0x0;
} else {
if (*field & 0x2) {
GIC_SET_EDGE_TRIGGER(irq);
}
}
}
static void translate_priority(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
if (to_kernel) {
*field = GIC_GET_PRIORITY(irq, cpu) & 0xff;
} else {
gic_set_priority(s, cpu, irq, *field & 0xff);
}
}
static void translate_targets(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
if (to_kernel) {
*field = s->irq_target[irq] & 0xff;
} else {
s->irq_target[irq] = *field & 0xff;
}
}
static void translate_sgisource(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)
{
if (to_kernel) {
*field = s->sgi_pending[irq][cpu] & 0xff;
} else {
s->sgi_pending[irq][cpu] = *field & 0xff;
}
}
/* Read a register group from the kernel VGIC */
static void kvm_dist_get(GICState *s, uint32_t offset, int width,
int maxirq, vgic_translate_fn translate_fn)
{
uint32_t reg;
int i;
int j;
int irq;
int cpu;
int regsz = 32 / width; /* irqs per kernel register */
uint32_t field;
for_each_irq_reg(i, maxirq, width) {
irq = i * regsz;
cpu = 0;
while ((cpu < s->num_cpu && irq < GIC_INTERNAL) || cpu == 0) {
kvm_gicd_access(s, offset, cpu, &reg, false);
for (j = 0; j < regsz; j++) {
field = extract32(reg, j * width, width);
translate_fn(s, irq + j, cpu, &field, false);
}
cpu++;
}
offset += 4;
}
}
/* Write a register group to the kernel VGIC */
static void kvm_dist_put(GICState *s, uint32_t offset, int width,
int maxirq, vgic_translate_fn translate_fn)
{
uint32_t reg;
int i;
int j;
int irq;
int cpu;
int regsz = 32 / width; /* irqs per kernel register */
uint32_t field;
for_each_irq_reg(i, maxirq, width) {
irq = i * regsz;
cpu = 0;
while ((cpu < s->num_cpu && irq < GIC_INTERNAL) || cpu == 0) {
reg = 0;
for (j = 0; j < regsz; j++) {
translate_fn(s, irq + j, cpu, &field, true);
reg = deposit32(reg, j * width, width, field);
}
kvm_gicd_access(s, offset, cpu, &reg, true);
cpu++;
}
offset += 4;
}
}
static void kvm_arm_gic_put(GICState *s)
{
/* TODO: there isn't currently a kernel interface to set the GIC state */
uint32_t reg;
int i;
int cpu;
int num_cpu;
int num_irq;
if (!kvm_arm_gic_can_save_restore(s)) {
DPRINTF("Cannot put kernel gic state, no kernel interface");
return;
}
/* Note: We do the restore in a slightly different order than the save
* (where the order doesn't matter and is simply ordered according to the
* register offset values */
/*****************************************************************
* Distributor State
*/
/* s->enabled -> GICD_CTLR */
reg = s->enabled;
kvm_gicd_access(s, 0x0, 0, &reg, true);
/* Sanity checking on GICD_TYPER and s->num_irq, s->num_cpu */
kvm_gicd_access(s, 0x4, 0, &reg, false);
num_irq = ((reg & 0x1f) + 1) * 32;
num_cpu = ((reg & 0xe0) >> 5) + 1;
if (num_irq < s->num_irq) {
fprintf(stderr, "Restoring %u IRQs, but kernel supports max %d\n",
s->num_irq, num_irq);
abort();
} else if (num_cpu != s->num_cpu) {
fprintf(stderr, "Restoring %u CPU interfaces, kernel only has %d\n",
s->num_cpu, num_cpu);
/* Did we not create the VCPUs in the kernel yet? */
abort();
}
/* TODO: Consider checking compatibility with the IIDR ? */
/* irq_state[n].enabled -> GICD_ISENABLERn */
kvm_dist_put(s, 0x180, 1, s->num_irq, translate_clear);
kvm_dist_put(s, 0x100, 1, s->num_irq, translate_enabled);
/* s->irq_target[irq] -> GICD_ITARGETSRn
* (restore targets before pending to ensure the pending state is set on
* the appropriate CPU interfaces in the kernel) */
kvm_dist_put(s, 0x800, 8, s->num_irq, translate_targets);
/* irq_state[n].pending + irq_state[n].level -> GICD_ISPENDRn */
kvm_dist_put(s, 0x280, 1, s->num_irq, translate_clear);
kvm_dist_put(s, 0x200, 1, s->num_irq, translate_pending);
/* irq_state[n].active -> GICD_ISACTIVERn */
kvm_dist_put(s, 0x380, 1, s->num_irq, translate_clear);
kvm_dist_put(s, 0x300, 1, s->num_irq, translate_active);
/* irq_state[n].trigger -> GICD_ICFRn */
kvm_dist_put(s, 0xc00, 2, s->num_irq, translate_trigger);
/* s->priorityX[irq] -> ICD_IPRIORITYRn */
kvm_dist_put(s, 0x400, 8, s->num_irq, translate_priority);
/* s->sgi_pending -> ICD_CPENDSGIRn */
kvm_dist_put(s, 0xf10, 8, GIC_NR_SGIS, translate_clear);
kvm_dist_put(s, 0xf20, 8, GIC_NR_SGIS, translate_sgisource);
/*****************************************************************
* CPU Interface(s) State
*/
for (cpu = 0; cpu < s->num_cpu; cpu++) {
/* s->cpu_enabled[cpu] -> GICC_CTLR */
reg = s->cpu_enabled[cpu];
kvm_gicc_access(s, 0x00, cpu, &reg, true);
/* s->priority_mask[cpu] -> GICC_PMR */
reg = (s->priority_mask[cpu] & 0xff);
kvm_gicc_access(s, 0x04, cpu, &reg, true);
/* s->bpr[cpu] -> GICC_BPR */
reg = (s->bpr[cpu] & 0x7);
kvm_gicc_access(s, 0x08, cpu, &reg, true);
/* s->abpr[cpu] -> GICC_ABPR */
reg = (s->abpr[cpu] & 0x7);
kvm_gicc_access(s, 0x1c, cpu, &reg, true);
/* s->apr[n][cpu] -> GICC_APRn */
for (i = 0; i < 4; i++) {
reg = s->apr[i][cpu];
kvm_gicc_access(s, 0xd0 + i * 4, cpu, &reg, true);
}
}
}
static void kvm_arm_gic_get(GICState *s)
{
/* TODO: there isn't currently a kernel interface to get the GIC state */
uint32_t reg;
int i;
int cpu;
if (!kvm_arm_gic_can_save_restore(s)) {
DPRINTF("Cannot get kernel gic state, no kernel interface");
return;
}
/*****************************************************************
* Distributor State
*/
/* GICD_CTLR -> s->enabled */
kvm_gicd_access(s, 0x0, 0, &reg, false);
s->enabled = reg & 1;
/* Sanity checking on GICD_TYPER -> s->num_irq, s->num_cpu */
kvm_gicd_access(s, 0x4, 0, &reg, false);
s->num_irq = ((reg & 0x1f) + 1) * 32;
s->num_cpu = ((reg & 0xe0) >> 5) + 1;
if (s->num_irq > GIC_MAXIRQ) {
fprintf(stderr, "Too many IRQs reported from the kernel: %d\n",
s->num_irq);
abort();
}
/* GICD_IIDR -> ? */
kvm_gicd_access(s, 0x8, 0, &reg, false);
/* Verify no GROUP 1 interrupts configured in the kernel */
for_each_irq_reg(i, s->num_irq, 1) {
kvm_gicd_access(s, 0x80 + (i * 4), 0, &reg, false);
if (reg != 0) {
fprintf(stderr, "Unsupported GICD_IGROUPRn value: %08x\n",
reg);
abort();
}
}
/* Clear all the IRQ settings */
for (i = 0; i < s->num_irq; i++) {
memset(&s->irq_state[i], 0, sizeof(s->irq_state[0]));
}
/* GICD_ISENABLERn -> irq_state[n].enabled */
kvm_dist_get(s, 0x100, 1, s->num_irq, translate_enabled);
/* GICD_ISPENDRn -> irq_state[n].pending + irq_state[n].level */
kvm_dist_get(s, 0x200, 1, s->num_irq, translate_pending);
/* GICD_ISACTIVERn -> irq_state[n].active */
kvm_dist_get(s, 0x300, 1, s->num_irq, translate_active);
/* GICD_ICFRn -> irq_state[n].trigger */
kvm_dist_get(s, 0xc00, 2, s->num_irq, translate_trigger);
/* GICD_IPRIORITYRn -> s->priorityX[irq] */
kvm_dist_get(s, 0x400, 8, s->num_irq, translate_priority);
/* GICD_ITARGETSRn -> s->irq_target[irq] */
kvm_dist_get(s, 0x800, 8, s->num_irq, translate_targets);
/* GICD_CPENDSGIRn -> s->sgi_pending */
kvm_dist_get(s, 0xf10, 8, GIC_NR_SGIS, translate_sgisource);
/*****************************************************************
* CPU Interface(s) State
*/
for (cpu = 0; cpu < s->num_cpu; cpu++) {
/* GICC_CTLR -> s->cpu_enabled[cpu] */
kvm_gicc_access(s, 0x00, cpu, &reg, false);
s->cpu_enabled[cpu] = (reg & 1);
/* GICC_PMR -> s->priority_mask[cpu] */
kvm_gicc_access(s, 0x04, cpu, &reg, false);
s->priority_mask[cpu] = (reg & 0xff);
/* GICC_BPR -> s->bpr[cpu] */
kvm_gicc_access(s, 0x08, cpu, &reg, false);
s->bpr[cpu] = (reg & 0x7);
/* GICC_ABPR -> s->abpr[cpu] */
kvm_gicc_access(s, 0x1c, cpu, &reg, false);
s->abpr[cpu] = (reg & 0x7);
/* GICC_APRn -> s->apr[n][cpu] */
for (i = 0; i < 4; i++) {
kvm_gicc_access(s, 0xd0 + i * 4, cpu, &reg, false);
s->apr[i][cpu] = reg;
}
}
}
static void kvm_arm_gic_reset(DeviceState *dev)
@@ -97,6 +517,7 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
GICState *s = KVM_ARM_GIC(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
int ret;
kgc->parent_realize(dev, errp);
if (error_is_set(errp)) {
@@ -119,13 +540,27 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
for (i = 0; i < s->num_cpu; i++) {
sysbus_init_irq(sbd, &s->parent_irq[i]);
}
/* Try to create the device via the device control API */
s->dev_fd = -1;
ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V2, false);
if (ret >= 0) {
s->dev_fd = ret;
} else if (ret != -ENODEV && ret != -ENOTSUP) {
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
return;
}
/* Distributor */
memory_region_init_reservation(&s->iomem, OBJECT(s),
"kvm-gic_dist", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
kvm_arm_register_device(&s->iomem,
(KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
| KVM_VGIC_V2_ADDR_TYPE_DIST);
| KVM_VGIC_V2_ADDR_TYPE_DIST,
KVM_DEV_ARM_VGIC_GRP_ADDR,
KVM_VGIC_V2_ADDR_TYPE_DIST,
s->dev_fd);
/* CPU interface for current core. Unlike arm_gic, we don't
* provide the "interface for core #N" memory regions, because
* cores with a VGIC don't have those.
@@ -135,7 +570,10 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(sbd, &s->cpuiomem[0]);
kvm_arm_register_device(&s->cpuiomem[0],
(KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
| KVM_VGIC_V2_ADDR_TYPE_CPU);
| KVM_VGIC_V2_ADDR_TYPE_CPU,
KVM_DEV_ARM_VGIC_GRP_ADDR,
KVM_VGIC_V2_ADDR_TYPE_CPU,
s->dev_fd);
}
static void kvm_arm_gic_class_init(ObjectClass *klass, void *data)

View File

@@ -418,7 +418,7 @@ static int exynos4210_combiner_init(SysBusDevice *sbd)
qdev_init_gpio_in(dev, exynos4210_combiner_handler, IIC_NIRQ);
/* Connect SysBusDev irqs to device specific irqs */
for (i = 0; i < IIC_NIRQ; i++) {
for (i = 0; i < IIC_NGRP; i++) {
sysbus_init_irq(sbd, &s->output_irq[i]);
}

View File

@@ -40,7 +40,7 @@
#define GIC_SET_MODEL(irq) s->irq_state[irq].model = true
#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = false
#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level |= (cm)
#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
#define GIC_SET_EDGE_TRIGGER(irq) s->irq_state[irq].edge_trigger = true

322
hw/intc/s390_flic.c Normal file
View File

@@ -0,0 +1,322 @@
/*
* QEMU S390x KVM floating interrupt controller (flic)
*
* Copyright 2014 IBM Corp.
* Author(s): Jens Freimann <jfrei@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
* directory.
*/
#include <sys/ioctl.h>
#include "qemu/error-report.h"
#include "hw/sysbus.h"
#include "sysemu/kvm.h"
#include "migration/qemu-file.h"
#include "hw/s390x/s390_flic.h"
#include "trace.h"
#define FLIC_SAVE_INITIAL_SIZE getpagesize()
#define FLIC_FAILED (-1UL)
#define FLIC_SAVEVM_VERSION 1
void s390_flic_init(void)
{
DeviceState *dev;
int r;
if (kvm_enabled()) {
dev = qdev_create(NULL, "s390-flic");
object_property_add_child(qdev_get_machine(), "s390-flic",
OBJECT(dev), NULL);
r = qdev_init(dev);
if (r) {
error_report("flic: couldn't create qdev");
}
}
}
/**
* flic_get_all_irqs - store all pending irqs in buffer
* @buf: pointer to buffer which is passed to kernel
* @len: length of buffer
* @flic: pointer to flic device state
*
* Returns: -ENOMEM if buffer is too small,
* -EINVAL if attr.group is invalid,
* -EFAULT if copying to userspace failed,
* on success return number of stored interrupts
*/
static int flic_get_all_irqs(KVMS390FLICState *flic,
void *buf, int len)
{
struct kvm_device_attr attr = {
.group = KVM_DEV_FLIC_GET_ALL_IRQS,
.addr = (uint64_t) buf,
.attr = len,
};
int rc;
rc = ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr);
return rc == -1 ? -errno : rc;
}
static void flic_enable_pfault(KVMS390FLICState *flic)
{
struct kvm_device_attr attr = {
.group = KVM_DEV_FLIC_APF_ENABLE,
};
int rc;
rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
if (rc) {
fprintf(stderr, "flic: couldn't enable pfault\n");
}
}
static void flic_disable_wait_pfault(KVMS390FLICState *flic)
{
struct kvm_device_attr attr = {
.group = KVM_DEV_FLIC_APF_DISABLE_WAIT,
};
int rc;
rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
if (rc) {
fprintf(stderr, "flic: couldn't disable pfault\n");
}
}
/** flic_enqueue_irqs - returns 0 on success
* @buf: pointer to buffer which is passed to kernel
* @len: length of buffer
* @flic: pointer to flic device state
*
* Returns: -EINVAL if attr.group is unknown
*/
static int flic_enqueue_irqs(void *buf, uint64_t len,
KVMS390FLICState *flic)
{
int rc;
struct kvm_device_attr attr = {
.group = KVM_DEV_FLIC_ENQUEUE,
.addr = (uint64_t) buf,
.attr = len,
};
rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
return rc ? -errno : 0;
}
/**
* __get_all_irqs - store all pending irqs in buffer
* @flic: pointer to flic device state
* @buf: pointer to pointer to a buffer
* @len: length of buffer
*
* Returns: return value of flic_get_all_irqs
* Note: Retry and increase buffer size until flic_get_all_irqs
* either returns a value >= 0 or a negative error code.
* -ENOMEM is an exception, which means the buffer is too small
* and we should try again. Other negative error codes can be
* -EFAULT and -EINVAL which we ignore at this point
*/
static int __get_all_irqs(KVMS390FLICState *flic,
void **buf, int len)
{
int r;
do {
/* returns -ENOMEM if buffer is too small and number
* of queued interrupts on success */
r = flic_get_all_irqs(flic, *buf, len);
if (r >= 0) {
break;
}
len *= 2;
*buf = g_try_realloc(*buf, len);
if (!buf) {
return -ENOMEM;
}
} while (r == -ENOMEM && len <= KVM_S390_FLIC_MAX_BUFFER);
return r;
}
/**
* kvm_flic_save - Save pending floating interrupts
* @f: QEMUFile containing migration state
* @opaque: pointer to flic device state
*
* Note: Pass buf and len to kernel. Start with one page and
* increase until buffer is sufficient or maxium size is
* reached
*/
static void kvm_flic_save(QEMUFile *f, void *opaque)
{
KVMS390FLICState *flic = opaque;
int len = FLIC_SAVE_INITIAL_SIZE;
void *buf;
int count;
flic_disable_wait_pfault((struct KVMS390FLICState *) opaque);
buf = g_try_malloc0(len);
if (!buf) {
/* Storing FLIC_FAILED into the count field here will cause the
* target system to fail when attempting to load irqs from the
* migration state */
error_report("flic: couldn't allocate memory");
qemu_put_be64(f, FLIC_FAILED);
return;
}
count = __get_all_irqs(flic, &buf, len);
if (count < 0) {
error_report("flic: couldn't retrieve irqs from kernel, rc %d",
count);
/* Storing FLIC_FAILED into the count field here will cause the
* target system to fail when attempting to load irqs from the
* migration state */
qemu_put_be64(f, FLIC_FAILED);
} else {
qemu_put_be64(f, count);
qemu_put_buffer(f, (uint8_t *) buf,
count * sizeof(struct kvm_s390_irq));
}
g_free(buf);
}
/**
* kvm_flic_load - Load pending floating interrupts
* @f: QEMUFile containing migration state
* @opaque: pointer to flic device state
* @version_id: version id for migration
*
* Returns: value of flic_enqueue_irqs, -EINVAL on error
* Note: Do nothing when no interrupts where stored
* in QEMUFile
*/
static int kvm_flic_load(QEMUFile *f, void *opaque, int version_id)
{
uint64_t len = 0;
uint64_t count = 0;
void *buf = NULL;
int r = 0;
if (version_id != FLIC_SAVEVM_VERSION) {
r = -EINVAL;
goto out;
}
flic_enable_pfault((struct KVMS390FLICState *) opaque);
count = qemu_get_be64(f);
len = count * sizeof(struct kvm_s390_irq);
if (count == FLIC_FAILED) {
r = -EINVAL;
goto out;
}
if (count == 0) {
r = 0;
goto out;
}
buf = g_try_malloc0(len);
if (!buf) {
r = -ENOMEM;
goto out;
}
if (qemu_get_buffer(f, (uint8_t *) buf, len) != len) {
r = -EINVAL;
goto out_free;
}
r = flic_enqueue_irqs(buf, len, (struct KVMS390FLICState *) opaque);
out_free:
g_free(buf);
out:
return r;
}
static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
{
KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
struct kvm_create_device cd = {0};
int ret;
flic_state->fd = -1;
if (!kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
trace_flic_no_device_api(errno);
return;
}
cd.type = KVM_DEV_TYPE_FLIC;
ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd);
if (ret < 0) {
trace_flic_create_device(errno);
return;
}
flic_state->fd = cd.fd;
/* Register savevm handler for floating interrupts */
register_savevm(NULL, "s390-flic", 0, 1, kvm_flic_save,
kvm_flic_load, (void *) flic_state);
}
static void kvm_s390_flic_unrealize(DeviceState *dev, Error **errp)
{
KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
unregister_savevm(DEVICE(flic_state), "s390-flic", flic_state);
}
static void kvm_s390_flic_reset(DeviceState *dev)
{
KVMS390FLICState *flic = KVM_S390_FLIC(dev);
struct kvm_device_attr attr = {
.group = KVM_DEV_FLIC_CLEAR_IRQS,
};
int rc = 0;
if (flic->fd == -1) {
return;
}
flic_disable_wait_pfault(flic);
rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
if (rc) {
trace_flic_reset_failed(errno);
}
flic_enable_pfault(flic);
}
static void kvm_s390_flic_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
dc->realize = kvm_s390_flic_realize;
dc->unrealize = kvm_s390_flic_unrealize;
dc->reset = kvm_s390_flic_reset;
}
static const TypeInfo kvm_s390_flic_info = {
.name = TYPE_KVM_S390_FLIC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(KVMS390FLICState),
.class_init = kvm_s390_flic_class_init,
};
static void kvm_s390_flic_register_types(void)
{
type_register_static(&kvm_s390_flic_info);
}
type_init(kvm_s390_flic_register_types)

View File

@@ -32,7 +32,6 @@
#include "sysemu/sysemu.h"
#include "hw/devices.h"
#include "hw/boards.h"
#include "hw/xilinx.h"
#include "sysemu/blockdev.h"
#include "hw/char/serial.h"
#include "exec/address-spaces.h"
@@ -49,6 +48,7 @@
#define NUM_SPI_FLASHES 4
#define SPI_BASEADDR 0x40a00000
#define MEMORY_BASEADDR 0x50000000
#define FLASH_BASEADDR 0x86000000
#define INTC_BASEADDR 0x81800000
@@ -57,6 +57,13 @@
#define AXIENET_BASEADDR 0x82780000
#define AXIDMA_BASEADDR 0x84600000
#define AXIDMA_IRQ1 0
#define AXIDMA_IRQ0 1
#define TIMER_IRQ 2
#define AXIENET_IRQ 3
#define SPI_IRQ 4
#define UART16550_IRQ 5
static void machine_cpu_reset(MicroBlazeCPU *cpu)
{
CPUMBState *env = &cpu->env;
@@ -111,17 +118,27 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
2, 0x89, 0x18, 0x0000, 0x0, 0);
dev = xilinx_intc_create(INTC_BASEADDR, qdev_get_gpio_in(DEVICE(cpu),
MB_CPU_IRQ), 4);
dev = qdev_create(NULL, "xlnx.xps-intc");
qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ));
for (i = 0; i < 32; i++) {
irq[i] = qdev_get_gpio_in(dev, i);
}
serial_mm_init(address_space_mem, UART16550_BASEADDR + 0x1000, 2,
irq[5], 115200, serial_hds[0], DEVICE_LITTLE_ENDIAN);
irq[UART16550_IRQ], 115200, serial_hds[0],
DEVICE_LITTLE_ENDIAN);
/* 2 timers at irq 2 @ 100 Mhz. */
xilinx_timer_create(TIMER_BASEADDR, irq[2], 0, 100 * 1000000);
dev = qdev_create(NULL, "xlnx.xps-timer");
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);
/* axi ethernet and dma initialization. */
qemu_check_nic_model(&nd_table[0], "xlnx.axi-ethernet");
@@ -138,16 +155,30 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
"axistream-connected-target", NULL);
cs = object_property_get_link(OBJECT(dma),
"axistream-control-connected-target", NULL);
xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(ds),
STREAM_SLAVE(cs), 0x82780000, irq[3], 0x1000,
0x1000);
qdev_set_nic_properties(eth0, &nd_table[0]);
qdev_prop_set_uint32(eth0, "rxmem", 0x1000);
qdev_prop_set_uint32(eth0, "txmem", 0x1000);
object_property_set_link(OBJECT(eth0), OBJECT(ds),
"axistream-connected", &error_abort);
object_property_set_link(OBJECT(eth0), OBJECT(cs),
"axistream-control-connected", &error_abort);
qdev_init_nofail(eth0);
sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(eth0), 0, irq[AXIENET_IRQ]);
ds = object_property_get_link(OBJECT(eth0),
"axistream-connected-target", NULL);
cs = object_property_get_link(OBJECT(eth0),
"axistream-control-connected-target", NULL);
xilinx_axidma_init(dma, STREAM_SLAVE(ds), STREAM_SLAVE(cs), 0x84600000,
irq[1], irq[0], 100 * 1000000);
qdev_prop_set_uint32(dma, "freqhz", 100 * 1000000);
object_property_set_link(OBJECT(dma), OBJECT(ds),
"axistream-connected", &error_abort);
object_property_set_link(OBJECT(dma), OBJECT(cs),
"axistream-control-connected", &error_abort);
qdev_init_nofail(dma);
sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dma), 0, irq[AXIDMA_IRQ0]);
sysbus_connect_irq(SYS_BUS_DEVICE(dma), 1, irq[AXIDMA_IRQ1]);
{
SSIBus *spi;
@@ -156,8 +187,8 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES);
qdev_init_nofail(dev);
busdev = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(busdev, 0, 0x40a00000);
sysbus_connect_irq(busdev, 0, irq[4]);
sysbus_mmio_map(busdev, 0, SPI_BASEADDR);
sysbus_connect_irq(busdev, 0, irq[SPI_IRQ]);
spi = (SSIBus *)qdev_get_child_bus(dev, "spi");

View File

@@ -30,7 +30,6 @@
#include "sysemu/sysemu.h"
#include "hw/devices.h"
#include "hw/boards.h"
#include "hw/xilinx.h"
#include "sysemu/blockdev.h"
#include "exec/address-spaces.h"
@@ -48,6 +47,10 @@
#define UARTLITE_BASEADDR 0x84000000
#define ETHLITE_BASEADDR 0x81000000
#define TIMER_IRQ 0
#define ETHLITE_IRQ 1
#define UARTLITE_IRQ 3
static void machine_cpu_reset(MicroBlazeCPU *cpu)
{
CPUMBState *env = &cpu->env;
@@ -93,16 +96,36 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args)
FLASH_SIZE >> 16,
1, 0x89, 0x18, 0x0000, 0x0, 1);
dev = xilinx_intc_create(INTC_BASEADDR, qdev_get_gpio_in(DEVICE(cpu),
MB_CPU_IRQ), 0xA);
dev = qdev_create(NULL, "xlnx.xps-intc");
qdev_prop_set_uint32(dev, "kind-of-intr",
1 << ETHLITE_IRQ | 1 << UARTLITE_IRQ);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ));
for (i = 0; i < 32; i++) {
irq[i] = qdev_get_gpio_in(dev, i);
}
sysbus_create_simple("xlnx.xps-uartlite", UARTLITE_BASEADDR, irq[3]);
sysbus_create_simple("xlnx.xps-uartlite", UARTLITE_BASEADDR,
irq[UARTLITE_IRQ]);
/* 2 timers at irq 2 @ 62 Mhz. */
xilinx_timer_create(TIMER_BASEADDR, irq[0], 0, 62 * 1000000);
xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0);
dev = qdev_create(NULL, "xlnx.xps-timer");
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);
qemu_check_nic_model(&nd_table[0], "xlnx.xps-ethernetlite");
dev = qdev_create(NULL, "xlnx.xps-ethernetlite");
qdev_set_nic_properties(dev, &nd_table[0]);
qdev_prop_set_uint32(dev, "tx-ping-pong", 0);
qdev_prop_set_uint32(dev, "rx-ping-pong", 0);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]);
microblaze_load_kernel(cpu, ddr_base, ram_size,
args->initrd_filename,

View File

@@ -276,7 +276,7 @@ static bool vexpress_cfgctrl_read(arm_sysctl_state *s, unsigned int dcc,
}
break;
case SYS_CFG_OSC:
if (site == SYS_CFG_SITE_MB && device < sizeof(s->mb_clock)) {
if (site == SYS_CFG_SITE_MB && device < ARRAY_SIZE(s->mb_clock)) {
/* motherboard clock */
*val = s->mb_clock[device];
return true;
@@ -324,7 +324,7 @@ static bool vexpress_cfgctrl_write(arm_sysctl_state *s, unsigned int dcc,
switch (function) {
case SYS_CFG_OSC:
if (site == SYS_CFG_SITE_MB && device < sizeof(s->mb_clock)) {
if (site == SYS_CFG_SITE_MB && device < ARRAY_SIZE(s->mb_clock)) {
/* motherboard clock */
s->mb_clock[device] = val;
return true;

View File

@@ -209,6 +209,29 @@ typedef struct VFIOGroup {
QLIST_ENTRY(VFIOGroup) container_next;
} VFIOGroup;
typedef struct VFIORomBlacklistEntry {
uint16_t vendor_id;
uint16_t device_id;
} VFIORomBlacklistEntry;
/*
* List of device ids/vendor ids for which to disable
* option rom loading. This avoids the guest hangs during rom
* execution as noticed with the BCM 57810 card for lack of a
* more better way to handle such issues.
* The user can still override by specifying a romfile or
* rombar=1.
* Please see https://bugs.launchpad.net/qemu/+bug/1284874
* for an analysis of the 57810 card hang. When adding
* a new vendor id/device id combination below, please also add
* your card/environment details and information that could
* help in debugging to the bug tracking this issue
*/
static const VFIORomBlacklistEntry romblacklist[] = {
/* Broadcom BCM 57810 */
{ 0x14e4, 0x168e }
};
#define MSIX_CAP_LENGTH 12
static QLIST_HEAD(, VFIOContainer)
@@ -1197,13 +1220,43 @@ static const MemoryRegionOps vfio_rom_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
static bool vfio_blacklist_opt_rom(VFIODevice *vdev)
{
PCIDevice *pdev = &vdev->pdev;
uint16_t vendor_id, device_id;
int count = 0;
vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID);
device_id = pci_get_word(pdev->config + PCI_DEVICE_ID);
while (count < ARRAY_SIZE(romblacklist)) {
if (romblacklist[count].vendor_id == vendor_id &&
romblacklist[count].device_id == device_id) {
return true;
}
count++;
}
return false;
}
static void vfio_pci_size_rom(VFIODevice *vdev)
{
uint32_t orig, size = cpu_to_le32((uint32_t)PCI_ROM_ADDRESS_MASK);
off_t offset = vdev->config_offset + PCI_ROM_ADDRESS;
DeviceState *dev = DEVICE(vdev);
char name[32];
if (vdev->pdev.romfile || !vdev->pdev.rom_bar) {
/* Since pci handles romfile, just print a message and return */
if (vfio_blacklist_opt_rom(vdev) && vdev->pdev.romfile) {
error_printf("Warning : Device at %04x:%02x:%02x.%x "
"is known to cause system instability issues during "
"option rom execution. "
"Proceeding anyway since user specified romfile\n",
vdev->host.domain, vdev->host.bus, vdev->host.slot,
vdev->host.function);
}
return;
}
@@ -1227,6 +1280,26 @@ static void vfio_pci_size_rom(VFIODevice *vdev)
return;
}
if (vfio_blacklist_opt_rom(vdev)) {
if (dev->opts && qemu_opt_get(dev->opts, "rombar")) {
error_printf("Warning : Device at %04x:%02x:%02x.%x "
"is known to cause system instability issues during "
"option rom execution. "
"Proceeding anyway since user specified non zero value for "
"rombar\n",
vdev->host.domain, vdev->host.bus, vdev->host.slot,
vdev->host.function);
} else {
error_printf("Warning : Rom loading for device at "
"%04x:%02x:%02x.%x has been disabled due to "
"system instability issues. "
"Specify rombar=1 or romfile to force\n",
vdev->host.domain, vdev->host.bus, vdev->host.slot,
vdev->host.function);
return;
}
}
DPRINTF("%04x:%02x:%02x.%x ROM size 0x%x\n", vdev->host.domain,
vdev->host.bus, vdev->host.slot, vdev->host.function, size);
@@ -3681,10 +3754,10 @@ static int vfio_initfn(PCIDevice *pdev)
strncat(path, "iommu_group", sizeof(path) - strlen(path) - 1);
len = readlink(path, iommu_group_path, PATH_MAX);
if (len <= 0) {
len = readlink(path, iommu_group_path, sizeof(path));
if (len <= 0 || len >= sizeof(path)) {
error_report("vfio: error no iommu_group for device");
return -errno;
return len < 0 ? -errno : ENAMETOOLONG;
}
iommu_group_path[len] = 0;

View File

@@ -169,6 +169,7 @@ enum {
};
enum {
INT_SOURCE_BUSY = 0x10,
INT_SOURCE_RXB = 0x4,
INT_SOURCE_TXB = 0x1,
};
@@ -351,8 +352,7 @@ static int open_eth_can_receive(NetClientState *nc)
OpenEthState *s = qemu_get_nic_opaque(nc);
return GET_REGBIT(s, MODER, RXEN) &&
(s->regs[TX_BD_NUM] < 0x80) &&
(rx_desc(s)->len_flags & RXD_E);
(s->regs[TX_BD_NUM] < 0x80);
}
static ssize_t open_eth_receive(NetClientState *nc,
@@ -402,6 +402,12 @@ static ssize_t open_eth_receive(NetClientState *nc,
desc *desc = rx_desc(s);
size_t copy_size = GET_REGBIT(s, MODER, HUGEN) ? 65536 : maxfl;
if (!(desc->len_flags & RXD_E)) {
open_eth_int_source_write(s,
s->regs[INT_SOURCE] | INT_SOURCE_BUSY);
return size;
}
desc->len_flags &= ~(RXD_CF | RXD_M | RXD_OR |
RXD_IS | RXD_DN | RXD_TL | RXD_SF | RXD_CRC | RXD_LC);
@@ -551,6 +557,15 @@ static uint64_t open_eth_reg_read(void *opaque,
return v;
}
static void open_eth_notify_can_receive(OpenEthState *s)
{
NetClientState *nc = qemu_get_queue(s->nic);
if (open_eth_can_receive(nc)) {
qemu_flush_queued_packets(nc);
}
}
static void open_eth_ro(OpenEthState *s, uint32_t val)
{
}
@@ -567,6 +582,7 @@ static void open_eth_moder_host_write(OpenEthState *s, uint32_t val)
if (set & MODER_RXEN) {
s->rx_desc = s->regs[TX_BD_NUM];
open_eth_notify_can_receive(s);
}
if (set & MODER_TXEN) {
s->tx_desc = 0;
@@ -592,6 +608,18 @@ static void open_eth_int_mask_host_write(OpenEthState *s, uint32_t val)
s->regs[INT_SOURCE] & s->regs[INT_MASK]);
}
static void open_eth_tx_bd_num_host_write(OpenEthState *s, uint32_t val)
{
if (val < 0x80) {
bool enable = s->regs[TX_BD_NUM] == 0x80;
s->regs[TX_BD_NUM] = val;
if (enable) {
open_eth_notify_can_receive(s);
}
}
}
static void open_eth_mii_command_host_write(OpenEthState *s, uint32_t val)
{
unsigned fiad = GET_REGFIELD(s, MIIADDRESS, FIAD);
@@ -630,6 +658,7 @@ static void open_eth_reg_write(void *opaque,
[MODER] = open_eth_moder_host_write,
[INT_SOURCE] = open_eth_int_source_host_write,
[INT_MASK] = open_eth_int_mask_host_write,
[TX_BD_NUM] = open_eth_tx_bd_num_host_write,
[MIICOMMAND] = open_eth_mii_command_host_write,
[MIITX_DATA] = open_eth_mii_tx_host_write,
[MIISTATUS] = open_eth_ro,

View File

@@ -176,7 +176,8 @@ static uint64_t stellaris_enet_read(void *opaque, hwaddr offset,
return val;
case 0x14: /* IA0 */
return s->conf.macaddr.a[0] | (s->conf.macaddr.a[1] << 8)
| (s->conf.macaddr.a[2] << 16) | (s->conf.macaddr.a[3] << 24);
| (s->conf.macaddr.a[2] << 16)
| ((uint32_t)s->conf.macaddr.a[3] << 24);
case 0x18: /* IA1 */
return s->conf.macaddr.a[4] | (s->conf.macaddr.a[5] << 8);
case 0x1c: /* THR */

View File

@@ -106,7 +106,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
goto fail;
}
net->nc = backend;
net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
net->dev.backend_features = qemu_has_vnet_hdr(backend) ? 0 :
(1 << VHOST_NET_F_VIRTIO_NET_HDR);
net->backend = r;
@@ -117,8 +117,8 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
if (r < 0) {
goto fail;
}
if (!tap_has_vnet_hdr_len(backend,
sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
if (!qemu_has_vnet_hdr_len(backend,
sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
}
if (~net->dev.features & net->dev.backend_features) {

View File

@@ -325,11 +325,7 @@ static void peer_test_vnet_hdr(VirtIONet *n)
return;
}
if (nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
return;
}
n->has_vnet_hdr = tap_has_vnet_hdr(nc->peer);
n->has_vnet_hdr = qemu_has_vnet_hdr(nc->peer);
}
static int peer_has_vnet_hdr(VirtIONet *n)
@@ -342,7 +338,7 @@ static int peer_has_ufo(VirtIONet *n)
if (!peer_has_vnet_hdr(n))
return 0;
n->has_ufo = tap_has_ufo(qemu_get_queue(n->nic)->peer);
n->has_ufo = qemu_has_ufo(qemu_get_queue(n->nic)->peer);
return n->has_ufo;
}
@@ -361,8 +357,8 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
nc = qemu_get_subqueue(n->nic, i);
if (peer_has_vnet_hdr(n) &&
tap_has_vnet_hdr_len(nc->peer, n->guest_hdr_len)) {
tap_set_vnet_hdr_len(nc->peer, n->guest_hdr_len);
qemu_has_vnet_hdr_len(nc->peer, n->guest_hdr_len)) {
qemu_set_vnet_hdr_len(nc->peer, n->guest_hdr_len);
n->host_hdr_len = n->guest_hdr_len;
}
}
@@ -463,7 +459,7 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
static void virtio_net_apply_guest_offloads(VirtIONet *n)
{
tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
qemu_set_offload(qemu_get_queue(n->nic)->peer,
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
@@ -1544,7 +1540,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
peer_test_vnet_hdr(n);
if (peer_has_vnet_hdr(n)) {
for (i = 0; i < n->max_queues; i++) {
tap_using_vnet_hdr(qemu_get_subqueue(n->nic, i)->peer, true);
qemu_using_vnet_hdr(qemu_get_subqueue(n->nic, i)->peer, true);
}
n->host_hdr_len = sizeof(struct virtio_net_hdr);
} else {

View File

@@ -1290,12 +1290,12 @@ static void vmxnet3_update_features(VMXNET3State *s)
s->lro_supported, rxcso_supported,
s->rx_vlan_stripping);
if (s->peer_has_vhdr) {
tap_set_offload(qemu_get_queue(s->nic)->peer,
rxcso_supported,
s->lro_supported,
s->lro_supported,
0,
0);
qemu_set_offload(qemu_get_queue(s->nic)->peer,
rxcso_supported,
s->lro_supported,
s->lro_supported,
0,
0);
}
}
@@ -1883,11 +1883,9 @@ static NetClientInfo net_vmxnet3_info = {
static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
{
NetClientState *peer = qemu_get_queue(s->nic)->peer;
NetClientState *nc = qemu_get_queue(s->nic);
if ((NULL != peer) &&
(peer->info->type == NET_CLIENT_OPTIONS_KIND_TAP) &&
tap_has_vnet_hdr(peer)) {
if (qemu_has_vnet_hdr(nc->peer)) {
return true;
}
@@ -1935,10 +1933,10 @@ static void vmxnet3_net_init(VMXNET3State *s)
s->lro_supported = false;
if (s->peer_has_vhdr) {
tap_set_vnet_hdr_len(qemu_get_queue(s->nic)->peer,
qemu_set_vnet_hdr_len(qemu_get_queue(s->nic)->peer,
sizeof(struct virtio_net_hdr));
tap_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1);
qemu_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1);
}
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);

View File

@@ -40,11 +40,19 @@
#include "ppc405.h"
#include "sysemu/blockdev.h"
#include "hw/xilinx.h"
#include "qapi/qmp/qerror.h"
#define EPAPR_MAGIC (0x45504150)
#define FLASH_SIZE (16 * 1024 * 1024)
#define INTC_BASEADDR 0x81800000
#define UART16550_BASEADDR 0x83e01003
#define TIMER_BASEADDR 0x83c00000
#define PFLASH_BASEADDR 0xfc000000
#define TIMER_IRQ 3
#define UART16550_IRQ 9
static struct boot_info
{
uint32_t bootstrap_pc;
@@ -204,22 +212,31 @@ static void virtex_init(QEMUMachineInitArgs *args)
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi01_register(0xfc000000, NULL, "virtex.flash", FLASH_SIZE,
pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
dinfo ? dinfo->bdrv : NULL, (64 * 1024),
FLASH_SIZE >> 16,
1, 0x89, 0x18, 0x0000, 0x0, 1);
cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0);
dev = qdev_create(NULL, "xlnx.xps-intc");
qdev_prop_set_uint32(dev, "kind-of-intr", 0);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
for (i = 0; i < 32; i++) {
irq[i] = qdev_get_gpio_in(dev, i);
}
serial_mm_init(address_space_mem, 0x83e01003ULL, 2, irq[9], 115200,
serial_hds[0], DEVICE_LITTLE_ENDIAN);
serial_mm_init(address_space_mem, UART16550_BASEADDR, 2, irq[UART16550_IRQ],
115200, serial_hds[0], DEVICE_LITTLE_ENDIAN);
/* 2 timers at irq 2 @ 62 Mhz. */
xilinx_timer_create(0x83c00000, irq[3], 0, 62 * 1000000);
dev = qdev_create(NULL, "xlnx.xps-timer");
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);
if (kernel_filename) {
uint64_t entry, low, high;

View File

@@ -21,13 +21,13 @@
#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
typedef struct EventTypesBus {
typedef struct SCLPEventsBus {
BusState qbus;
} EventTypesBus;
} SCLPEventsBus;
struct SCLPEventFacility {
EventTypesBus sbus;
DeviceState *qdev;
SysBusDevice parent_obj;
SCLPEventsBus sbus;
/* guest' receive mask */
unsigned int receive_mask;
};
@@ -291,7 +291,7 @@ static void sclp_events_bus_class_init(ObjectClass *klass, void *data)
{
}
static const TypeInfo s390_sclp_events_bus_info = {
static const TypeInfo sclp_events_bus_info = {
.name = TYPE_SCLP_EVENTS_BUS,
.parent = TYPE_BUS,
.class_init = sclp_events_bus_class_init,
@@ -299,7 +299,7 @@ static const TypeInfo s390_sclp_events_bus_info = {
static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code)
{
switch (code) {
switch (code & SCLP_CMD_CODE_MASK) {
case SCLP_CMD_READ_EVENT_DATA:
read_event_data(ef, sccb);
break;
@@ -315,21 +315,26 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code)
}
}
static int init_event_facility(S390SCLPDevice *sdev)
static const VMStateDescription vmstate_event_facility = {
.name = "vmstate-event-facility",
.version_id = 0,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(receive_mask, SCLPEventFacility),
VMSTATE_END_OF_LIST()
}
};
static int init_event_facility(SCLPEventFacility *event_facility)
{
SCLPEventFacility *event_facility;
DeviceState *sdev = DEVICE(event_facility);
DeviceState *quiesce;
event_facility = g_malloc0(sizeof(SCLPEventFacility));
sdev->ef = event_facility;
sdev->sclp_command_handler = command_handler;
sdev->event_pending = event_pending;
/* Spawn a new sclp-events facility */
/* Spawn a new bus for SCLP events */
qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
TYPE_SCLP_EVENTS_BUS, DEVICE(sdev), NULL);
TYPE_SCLP_EVENTS_BUS, sdev, NULL);
event_facility->sbus.qbus.allow_hotplug = 0;
event_facility->qdev = (DeviceState *) sdev;
quiesce = qdev_create(&event_facility->sbus.qbus, "sclpquiesce");
if (!quiesce) {
@@ -346,43 +351,57 @@ static int init_event_facility(S390SCLPDevice *sdev)
static void reset_event_facility(DeviceState *dev)
{
S390SCLPDevice *sdev = SCLP_S390_DEVICE(dev);
SCLPEventFacility *sdev = EVENT_FACILITY(dev);
sdev->ef->receive_mask = 0;
sdev->receive_mask = 0;
}
static void init_event_facility_class(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
S390SCLPDeviceClass *k = SCLP_S390_DEVICE_CLASS(klass);
SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(sbdc);
SCLPEventFacilityClass *k = EVENT_FACILITY_CLASS(dc);
dc->reset = reset_event_facility;
dc->vmsd = &vmstate_event_facility;
k->init = init_event_facility;
k->command_handler = command_handler;
k->event_pending = event_pending;
}
static const TypeInfo s390_sclp_event_facility_info = {
.name = "s390-sclp-event-facility",
.parent = TYPE_DEVICE_S390_SCLP,
.instance_size = sizeof(S390SCLPDevice),
static const TypeInfo sclp_event_facility_info = {
.name = TYPE_SCLP_EVENT_FACILITY,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SCLPEventFacility),
.class_init = init_event_facility_class,
.class_size = sizeof(SCLPEventFacilityClass),
};
static int event_qdev_init(DeviceState *qdev)
static void event_realize(DeviceState *qdev, Error **errp)
{
SCLPEvent *event = DO_UPCAST(SCLPEvent, qdev, qdev);
SCLPEvent *event = SCLP_EVENT(qdev);
SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
return child->init(event);
if (child->init) {
int rc = child->init(event);
if (rc < 0) {
error_setg(errp, "SCLP event initialization failed.");
return;
}
}
}
static int event_qdev_exit(DeviceState *qdev)
static void event_unrealize(DeviceState *qdev, Error **errp)
{
SCLPEvent *event = DO_UPCAST(SCLPEvent, qdev, qdev);
SCLPEvent *event = SCLP_EVENT(qdev);
SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
if (child->exit) {
child->exit(event);
int rc = child->exit(event);
if (rc < 0) {
error_setg(errp, "SCLP event exit failed.");
return;
}
}
return 0;
}
static void event_class_init(ObjectClass *klass, void *data)
@@ -391,11 +410,11 @@ static void event_class_init(ObjectClass *klass, void *data)
dc->bus_type = TYPE_SCLP_EVENTS_BUS;
dc->unplug = qdev_simple_unplug_cb;
dc->init = event_qdev_init;
dc->exit = event_qdev_exit;
dc->realize = event_realize;
dc->unrealize = event_unrealize;
}
static const TypeInfo s390_sclp_event_type_info = {
static const TypeInfo sclp_event_type_info = {
.name = TYPE_SCLP_EVENT,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SCLPEvent),
@@ -406,9 +425,9 @@ static const TypeInfo s390_sclp_event_type_info = {
static void register_types(void)
{
type_register_static(&s390_sclp_events_bus_info);
type_register_static(&s390_sclp_event_facility_info);
type_register_static(&s390_sclp_event_type_info);
type_register_static(&sclp_events_bus_info);
type_register_static(&sclp_event_facility_info);
type_register_static(&sclp_event_type_info);
}
type_init(register_types)

View File

@@ -95,7 +95,8 @@ static int s390_ipl_init(SysBusDevice *dev)
}
return 0;
} else {
kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL,
uint64_t pentry = KERN_IMAGE_START;
kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
NULL, 1, ELF_MACHINE, 0);
if (kernel_size == -1) {
kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
@@ -104,15 +105,19 @@ static int s390_ipl_init(SysBusDevice *dev)
fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
return -1;
}
/* we have to overwrite values in the kernel image, which are "rom" */
strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
/*
* we can not rely on the ELF entry point, since up to 3.2 this
* value was 0x800 (the SALIPL loader) and it wont work. For
* all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
* Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
* kernel parameters here as well. Note: For old kernels (up to 3.2)
* we can not rely on the ELF entry point - it was 0x800 (the SALIPL
* loader) and it won't work. For this case we force it to 0x10000, too.
*/
ipl->start_addr = KERN_IMAGE_START;
if (pentry == KERN_IMAGE_START || pentry == 0x800) {
ipl->start_addr = KERN_IMAGE_START;
/* Overwrite parameters in the kernel image, which are "rom" */
strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
} else {
ipl->start_addr = pentry;
}
}
if (ipl->initrd) {
ram_addr_t initrd_offset;

View File

@@ -13,13 +13,14 @@
#include "exec/address-spaces.h"
#include "s390-virtio.h"
#include "hw/s390x/sclp.h"
#include "hw/s390x/s390_flic.h"
#include "ioinst.h"
#include "css.h"
#include "virtio-ccw.h"
void io_subsystem_reset(void)
{
DeviceState *css, *sclp;
DeviceState *css, *sclp, *flic;
css = DEVICE(object_resolve_path_type("", "virtual-css-bridge", NULL));
if (css) {
@@ -30,6 +31,10 @@ void io_subsystem_reset(void)
if (sclp) {
qdev_reset_all(sclp);
}
flic = DEVICE(object_resolve_path_type("", "s390-flic", NULL));
if (flic) {
qdev_reset_all(flic);
}
}
static int virtio_ccw_hcall_notify(const uint64_t *args)
@@ -99,6 +104,7 @@ static void ccw_init(QEMUMachineInitArgs *args)
s390_sclp_init();
s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
args->initrd_filename, "s390-ccw.img");
s390_flic_init();
/* register hypercalls */
virtio_ccw_register_hcalls();

View File

@@ -26,11 +26,15 @@ void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn)
int s390_virtio_hypercall(CPUS390XState *env)
{
s390_virtio_fn fn = s390_diag500_table[env->regs[1]];
s390_virtio_fn fn;
if (!fn) {
return -EINVAL;
if (env->regs[1] < MAX_DIAG_SUBCODES) {
fn = s390_diag500_table[env->regs[1]];
if (fn) {
env->regs[2] = fn(&env->regs[2]);
return 0;
}
}
return fn(&env->regs[2]);
return -EINVAL;
}

View File

@@ -36,6 +36,7 @@
#include "hw/s390x/s390-virtio-bus.h"
#include "hw/s390x/sclp.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/s390-virtio.h"
//#define DEBUG_S390
@@ -251,6 +252,7 @@ static void s390_init(QEMUMachineInitArgs *args)
s390_sclp_init();
s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
args->initrd_filename, ZIPL_FILENAME);
s390_flic_init();
/* register hypercalls */
s390_virtio_register_hcalls();

View File

@@ -18,11 +18,12 @@
#include "sysemu/sysemu.h"
#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
static inline S390SCLPDevice *get_event_facility(void)
static inline SCLPEventFacility *get_event_facility(void)
{
ObjectProperty *op = object_property_find(qdev_get_machine(),
"s390-sclp-event-facility",
TYPE_SCLP_EVENT_FACILITY,
NULL);
assert(op);
return op->opaque;
@@ -89,9 +90,10 @@ static void sclp_read_cpu_info(SCCB *sccb)
sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
}
static void sclp_execute(SCCB *sccb, uint64_t code)
static void sclp_execute(SCCB *sccb, uint32_t code)
{
S390SCLPDevice *sdev = get_event_facility();
SCLPEventFacility *ef = get_event_facility();
SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
switch (code & SCLP_CMD_CODE_MASK) {
case SCLP_CMDW_READ_SCP_INFO:
@@ -102,12 +104,12 @@ static void sclp_execute(SCCB *sccb, uint64_t code)
sclp_read_cpu_info(sccb);
break;
default:
sdev->sclp_command_handler(sdev->ef, sccb, code);
efc->command_handler(ef, sccb, code);
break;
}
}
int sclp_service_call(uint32_t sccb, uint64_t code)
int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
{
int r = 0;
SCCB work_sccb;
@@ -115,11 +117,16 @@ int sclp_service_call(uint32_t sccb, uint64_t code)
hwaddr sccb_len = sizeof(SCCB);
/* first some basic checks on program checks */
if (env->psw.mask & PSW_MASK_PSTATE) {
r = -PGM_PRIVILEGED;
goto out;
}
if (cpu_physical_memory_is_io(sccb)) {
r = -PGM_ADDRESSING;
goto out;
}
if (sccb & ~0x7ffffff8ul) {
if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
|| (sccb & ~0x7ffffff8UL) != 0) {
r = -PGM_SPECIFICATION;
goto out;
}
@@ -151,11 +158,13 @@ out:
void sclp_service_interrupt(uint32_t sccb)
{
S390SCLPDevice *sdev = get_event_facility();
SCLPEventFacility *ef = get_event_facility();
SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
uint32_t param = sccb & ~3;
/* Indicate whether an event is still pending */
param |= sdev->event_pending(sdev->ef) ? 1 : 0;
param |= efc->event_pending(ef) ? 1 : 0;
if (!param) {
/* No need to send an interrupt, there's nothing to be notified about */
@@ -168,47 +177,9 @@ void sclp_service_interrupt(uint32_t sccb)
void s390_sclp_init(void)
{
DeviceState *dev = qdev_create(NULL, "s390-sclp-event-facility");
DeviceState *dev = qdev_create(NULL, TYPE_SCLP_EVENT_FACILITY);
object_property_add_child(qdev_get_machine(), "s390-sclp-event-facility",
object_property_add_child(qdev_get_machine(), TYPE_SCLP_EVENT_FACILITY,
OBJECT(dev), NULL);
qdev_init_nofail(dev);
}
static int s390_sclp_dev_init(SysBusDevice *dev)
{
int r;
S390SCLPDevice *sdev = (S390SCLPDevice *)dev;
S390SCLPDeviceClass *sclp = SCLP_S390_DEVICE_GET_CLASS(dev);
r = sclp->init(sdev);
if (!r) {
assert(sdev->event_pending);
assert(sdev->sclp_command_handler);
}
return r;
}
static void s390_sclp_device_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *dc = SYS_BUS_DEVICE_CLASS(klass);
dc->init = s390_sclp_dev_init;
}
static const TypeInfo s390_sclp_device_info = {
.name = TYPE_DEVICE_S390_SCLP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(S390SCLPDevice),
.class_init = s390_sclp_device_class_init,
.class_size = sizeof(S390SCLPDeviceClass),
.abstract = true,
};
static void s390_sclp_register_types(void)
{
type_register_static(&s390_sclp_device_info);
}
type_init(s390_sclp_register_types)

View File

@@ -909,7 +909,7 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
case VERIFY_16:
if ((buf[1] & 2) == 0) {
cmd->xfer = 0;
} else if ((buf[1] & 4) == 1) {
} else if ((buf[1] & 4) != 0) {
cmd->xfer = 1;
}
cmd->xfer *= dev->blocksize;
@@ -1367,6 +1367,11 @@ const struct SCSISense sense_code_WRITE_PROTECTED = {
.key = DATA_PROTECT, .asc = 0x27, .ascq = 0x00
};
/* Data Protection, Space Allocation Failed Write Protect */
const struct SCSISense sense_code_SPACE_ALLOC_FAILED = {
.key = DATA_PROTECT, .asc = 0x27, .ascq = 0x07
};
/*
* scsi_build_sense
*

View File

@@ -75,6 +75,8 @@ struct SCSIDiskState
bool media_event;
bool eject_request;
uint64_t wwn;
uint64_t port_wwn;
uint16_t port_index;
uint64_t max_unmap_size;
QEMUBH *bh;
char *version;
@@ -428,6 +430,9 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
case EINVAL:
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
break;
case ENOSPC:
scsi_check_condition(r, SENSE_CODE(SPACE_ALLOC_FAILED));
break;
default:
scsi_check_condition(r, SENSE_CODE(IO_ERROR));
break;
@@ -617,6 +622,24 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
stq_be_p(&outbuf[buflen], s->wwn);
buflen += 8;
}
if (s->port_wwn) {
outbuf[buflen++] = 0x61; // SAS / Binary
outbuf[buflen++] = 0x93; // PIV / Target port / NAA
outbuf[buflen++] = 0; // reserved
outbuf[buflen++] = 8;
stq_be_p(&outbuf[buflen], s->port_wwn);
buflen += 8;
}
if (s->port_index) {
outbuf[buflen++] = 0x61; // SAS / Binary
outbuf[buflen++] = 0x94; // PIV / Target port / relative target port
outbuf[buflen++] = 0; // reserved
outbuf[buflen++] = 4;
stw_be_p(&outbuf[buflen + 2], s->port_index);
buflen += 4;
}
break;
}
case 0xb0: /* block limits */
@@ -2536,6 +2559,8 @@ static Property scsi_hd_properties[] = {
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
SCSI_DISK_F_DPOFUA, false),
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE),
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
@@ -2584,6 +2609,8 @@ static const TypeInfo scsi_hd_info = {
static Property scsi_cd_properties[] = {
DEFINE_SCSI_DISK_PROPERTIES(),
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2647,6 +2674,8 @@ static Property scsi_disk_properties[] = {
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
SCSI_DISK_F_DPOFUA, false),
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE),
DEFINE_PROP_END_OF_LIST(),

View File

@@ -37,8 +37,6 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
#include <scsi/sg.h>
#include "block/scsi.h"
#define SCSI_SENSE_BUF_SIZE 96
#define SG_ERR_DRIVER_TIMEOUT 0x06
#define SG_ERR_DRIVER_SENSE 0x08

View File

@@ -60,7 +60,6 @@
#define VSCSI_MAX_SECTORS 4096
#define VSCSI_REQ_LIMIT 24
#define SCSI_SENSE_BUF_SIZE 96
#define SRP_RSP_SENSE_DATA_LEN 18
typedef union vscsi_crq {

View File

@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include "hw/sysbus.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "hw/sparc/sun4m.h"
#include "hw/timer/m48t59.h"
@@ -561,6 +562,31 @@ static void tcx_init(hwaddr addr, int vram_size, int width,
}
}
static void cg3_init(hwaddr addr, qemu_irq irq, int vram_size, int width,
int height, int depth)
{
DeviceState *dev;
SysBusDevice *s;
dev = qdev_create(NULL, "cgthree");
qdev_prop_set_uint32(dev, "vram-size", vram_size);
qdev_prop_set_uint16(dev, "width", width);
qdev_prop_set_uint16(dev, "height", height);
qdev_prop_set_uint16(dev, "depth", depth);
qdev_prop_set_uint64(dev, "prom-addr", addr);
qdev_init_nofail(dev);
s = SYS_BUS_DEVICE(dev);
/* FCode ROM */
sysbus_mmio_map(s, 0, addr);
/* DAC */
sysbus_mmio_map(s, 1, addr + 0x400000ULL);
/* 8-bit plane */
sysbus_mmio_map(s, 2, addr + 0x800000ULL);
sysbus_connect_irq(s, 0, irq);
}
/* NCR89C100/MACIO Internal ID register */
#define TYPE_MACIO_ID_REGISTER "macio_idreg"
@@ -914,13 +940,43 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
slavio_irq[16], iommu, &ledma_irq, 1);
if (graphic_depth != 8 && graphic_depth != 24) {
fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
error_report("Unsupported depth: %d", graphic_depth);
exit (1);
}
num_vsimms = 0;
if (num_vsimms == 0) {
tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
graphic_depth);
if (vga_interface_type == VGA_CG3) {
if (graphic_depth != 8) {
error_report("Unsupported depth: %d", graphic_depth);
exit(1);
}
if (!(graphic_width == 1024 && graphic_height == 768) &&
!(graphic_width == 1152 && graphic_height == 900)) {
error_report("Unsupported resolution: %d x %d", graphic_width,
graphic_height);
exit(1);
}
/* sbus irq 5 */
cg3_init(hwdef->tcx_base, slavio_irq[11], 0x00100000,
graphic_width, graphic_height, graphic_depth);
} else {
/* If no display specified, default to TCX */
if (graphic_depth != 8 && graphic_depth != 24) {
error_report("Unsupported depth: %d", graphic_depth);
exit(1);
}
if (!(graphic_width == 1024 && graphic_height == 768)) {
error_report("Unsupported resolution: %d x %d",
graphic_width, graphic_height);
exit(1);
}
tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
graphic_depth);
}
}
for (i = num_vsimms; i < MAX_VSIMMS; i++) {

View File

@@ -320,6 +320,7 @@ static uint64_t icp_pit_read(void *opaque, hwaddr offset,
n = offset >> 8;
if (n > 2) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad timer %d\n", __func__, n);
return 0;
}
return arm_timer_read(s->timer[n], offset & 0xff);
@@ -334,6 +335,7 @@ static void icp_pit_write(void *opaque, hwaddr offset,
n = offset >> 8;
if (n > 2) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad timer %d\n", __func__, n);
return;
}
arm_timer_write(s->timer[n], offset & 0xff, value);

View File

@@ -51,7 +51,7 @@ typedef struct CPUTimerState {
ptimer_state *timer;
uint32_t count, counthigh, reached;
/* processor only */
uint32_t running;
uint32_t run;
uint64_t limit;
} CPUTimerState;
@@ -177,7 +177,7 @@ static uint64_t slavio_timer_mem_readl(void *opaque, hwaddr addr,
// only available in processor counter/timer
// read start/stop status
if (timer_index > 0) {
ret = t->running;
ret = t->run;
} else {
ret = 0;
}
@@ -260,16 +260,15 @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
case TIMER_STATUS:
if (slavio_timer_is_user(tc)) {
// start/stop user counter
if ((val & 1) && !t->running) {
if (val & 1) {
trace_slavio_timer_mem_writel_status_start(timer_index);
ptimer_run(t->timer, 0);
t->running = 1;
} else if (!(val & 1) && t->running) {
} else {
trace_slavio_timer_mem_writel_status_stop(timer_index);
ptimer_stop(t->timer);
t->running = 0;
}
}
t->run = val & 1;
break;
case TIMER_MODE:
if (timer_index == 0) {
@@ -284,8 +283,9 @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
if (val & processor) { // counter -> user timer
qemu_irq_lower(curr_timer->irq);
// counters are always running
ptimer_stop(curr_timer->timer);
curr_timer->running = 0;
if (!curr_timer->run) {
ptimer_stop(curr_timer->timer);
}
// user timer limit is always the same
curr_timer->limit = TIMER_MAX_COUNT64;
ptimer_set_limit(curr_timer->timer,
@@ -296,13 +296,8 @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
s->cputimer_mode |= processor;
trace_slavio_timer_mem_writel_mode_user(timer_index);
} else { // user timer -> counter
// stop the user timer if it is running
if (curr_timer->running) {
ptimer_stop(curr_timer->timer);
}
// start the counter
ptimer_run(curr_timer->timer, 0);
curr_timer->running = 1;
// clear this processors user timer bit in config
// register
s->cputimer_mode &= ~processor;
@@ -340,7 +335,7 @@ static const VMStateDescription vmstate_timer = {
VMSTATE_UINT32(count, CPUTimerState),
VMSTATE_UINT32(counthigh, CPUTimerState),
VMSTATE_UINT32(reached, CPUTimerState),
VMSTATE_UINT32(running, CPUTimerState),
VMSTATE_UINT32(run , CPUTimerState),
VMSTATE_PTIMER(timer, CPUTimerState),
VMSTATE_END_OF_LIST()
}
@@ -373,7 +368,7 @@ static void slavio_timer_reset(DeviceState *d)
ptimer_set_limit(curr_timer->timer,
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
ptimer_run(curr_timer->timer, 0);
curr_timer->running = 1;
curr_timer->run = 1;
}
}
s->cputimer_mode = 0;

View File

@@ -98,7 +98,7 @@ static void puv3_load_kernel(const char *kernel_filename)
}
/* cheat curses that we have a graphic console, only under ocd console */
graphic_console_init(NULL, &no_ops, NULL);
graphic_console_init(NULL, 0, &no_ops, NULL);
}
static void puv3_init(QEMUMachineInitArgs *args)

View File

@@ -27,6 +27,7 @@
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/ide.h"
#include "hw/pci/pci.h"
#include "hw/irq.h"
#include "hw/xen/xen_common.h"
@@ -110,7 +111,7 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *o)
if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
PCI_CLASS_STORAGE_IDE
&& strcmp(d->name, "xen-pci-passthrough") != 0) {
qdev_unplug(DEVICE(d), NULL);
pci_piix3_xen_ide_unplug(DEVICE(d));
}
}

View File

@@ -40,6 +40,7 @@
#include "xtensa_bootparam.h"
typedef struct LxBoardDesc {
hwaddr flash_base;
size_t flash_size;
size_t flash_sector_size;
size_t sram_size;
@@ -219,7 +220,7 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
dinfo = drive_get(IF_PFLASH, 0, 0);
if (dinfo) {
flash = pflash_cfi01_register(0xf8000000,
flash = pflash_cfi01_register(board->flash_base,
NULL, "lx60.io.flash", board->flash_size,
dinfo->bdrv, board->flash_sector_size,
board->flash_size / board->flash_sector_size,
@@ -265,7 +266,9 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
MemoryRegion *flash_io = g_malloc(sizeof(*flash_io));
memory_region_init_alias(flash_io, NULL, "lx60.flash",
flash_mr, 0, board->flash_size);
flash_mr, 0,
board->flash_size < 0x02000000 ?
board->flash_size : 0x02000000);
memory_region_add_subregion(system_memory, 0xfe000000,
flash_io);
}
@@ -275,7 +278,8 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
static void xtensa_lx60_init(QEMUMachineInitArgs *args)
{
static const LxBoardDesc lx60_board = {
.flash_size = 0x400000,
.flash_base = 0xf8000000,
.flash_size = 0x00400000,
.flash_sector_size = 0x10000,
.sram_size = 0x20000,
};
@@ -285,13 +289,36 @@ static void xtensa_lx60_init(QEMUMachineInitArgs *args)
static void xtensa_lx200_init(QEMUMachineInitArgs *args)
{
static const LxBoardDesc lx200_board = {
.flash_size = 0x1000000,
.flash_base = 0xf8000000,
.flash_size = 0x01000000,
.flash_sector_size = 0x20000,
.sram_size = 0x2000000,
};
lx_init(&lx200_board, args);
}
static void xtensa_ml605_init(QEMUMachineInitArgs *args)
{
static const LxBoardDesc ml605_board = {
.flash_base = 0xf8000000,
.flash_size = 0x02000000,
.flash_sector_size = 0x20000,
.sram_size = 0x2000000,
};
lx_init(&ml605_board, args);
}
static void xtensa_kc705_init(QEMUMachineInitArgs *args)
{
static const LxBoardDesc kc705_board = {
.flash_base = 0xf0000000,
.flash_size = 0x08000000,
.flash_sector_size = 0x20000,
.sram_size = 0x2000000,
};
lx_init(&kc705_board, args);
}
static QEMUMachine xtensa_lx60_machine = {
.name = "lx60",
.desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
@@ -306,10 +333,26 @@ static QEMUMachine xtensa_lx200_machine = {
.max_cpus = 4,
};
static QEMUMachine xtensa_ml605_machine = {
.name = "ml605",
.desc = "ml605 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
.init = xtensa_ml605_init,
.max_cpus = 4,
};
static QEMUMachine xtensa_kc705_machine = {
.name = "kc705",
.desc = "kc705 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
.init = xtensa_kc705_init,
.max_cpus = 4,
};
static void xtensa_lx_machines_init(void)
{
qemu_register_machine(&xtensa_lx60_machine);
qemu_register_machine(&xtensa_lx200_machine);
qemu_register_machine(&xtensa_ml605_machine);
qemu_register_machine(&xtensa_kc705_machine);
}
machine_init(xtensa_lx_machines_init);

View File

@@ -102,6 +102,9 @@ typedef enum {
#define BDRV_O_CHECK 0x1000 /* open solely for consistency check */
#define BDRV_O_ALLOW_RDWR 0x2000 /* allow reopen to change from r/o to r/w */
#define BDRV_O_UNMAP 0x4000 /* execute guest UNMAP/TRIM operations */
#define BDRV_O_PROTOCOL 0x8000 /* if no block driver is explicitly given:
select an appropriate protocol driver,
ignoring the format layer */
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
@@ -183,15 +186,13 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
int bdrv_parse_cache_flags(const char *mode, int *flags);
int bdrv_parse_discard_flags(const char *mode, int *flags);
int bdrv_file_open(BlockDriverState **pbs, const char *filename,
const char *reference, QDict *options, int flags,
Error **errp);
int bdrv_open_image(BlockDriverState **pbs, const char *filename,
QDict *options, const char *bdref_key, int flags,
bool force_raw, bool allow_none, Error **errp);
bool allow_none, Error **errp);
int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp);
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
int flags, BlockDriver *drv, Error **errp);
int bdrv_open(BlockDriverState **pbs, const char *filename,
const char *reference, QDict *options, int flags,
BlockDriver *drv, Error **errp);
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
BlockDriverState *bs, int flags);
int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);

View File

@@ -62,12 +62,6 @@ enum {
#define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024)
ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
int tcp_socket_incoming(const char *address, uint16_t port);
int tcp_socket_incoming_spec(const char *address_and_port);
int tcp_socket_outgoing_opts(QemuOpts *opts);
int unix_socket_outgoing(const char *path);
int unix_socket_incoming(const char *path);
int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
off_t *size, size_t *blocksize);
int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize);

View File

@@ -17,6 +17,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
int pci_piix3_xen_ide_unplug(DeviceState *dev);
void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
/* ide-mmio.c */

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